kdd-gates
其他 活跃维护

kdd-gates

MauricioPerera/kdd-gates

是面向数据挖掘的KDD方法论门控插件,可集成到现有数据挖掘工作流设置多节点校验规则,自动对齐KDD标准流程步骤,无需人工干预即可完成合规校验,降低知识发现项目的流程管理成本。

0
Stars 标星
0
Forks 分支
0
Watchers 关注
0
Open Issues
JavaScript
主要语言
MIT
开源协议
21 KB
仓库大小
29 天前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:MauricioPerera/kdd-gates
git clone https://github.com/MauricioPerera/kdd-gates.git
git clone git@github.com:MauricioPerera/kdd-gates.git
README.md master

kdd-gates

Plugin de composición para DeepSeek Harness (dsh) que expone los gates deterministas de la metodología KDD (Knowledge-Driven Development) como Tools nativas del modelo: kdd_validate, kdd_seal, kdd_perimeter, kdd_preflight.

No reimplementa la lógica de KDD — es un envoltorio delgado que llama a los scripts Python de la propia plantilla KDD (scripts/*.py) sobre el repoRoot que le pases.

Requisito

El repo destino (repoRoot) tiene que tener la plantilla KDD instalada: carpetas scripts/, knowledge/, .agents/. Sin eso, las tools fallan (no hay nada que ejecutar).

Si el proyecto no la tiene todavía, instanciala desde una copia de la plantilla:

python scripts/init_project.py --repo-dir <tu-proyecto> --apply --name "Nombre del proyecto"

Esto borra los artefactos de ejemplo y deja el tooling de KDD listo — a partir de ahí el proyecto es independiente de la plantilla original.

Instalación

  1. Dependencias locales (el plugin corre desde su propia carpeta, necesita su propio node_modules):

    cd kdd-gates
    npm install

    (@deepseek-ai/dsh-tools y @deepseek-ai/dsh-sandbox, mismas versiones que el dsh instalado — ver package.json.)

  2. Montarlo en el perfil de dsh (~/.dsh/profiles/<perfil>/cordis.patch.yml):

    - insert:
       - id: kdd-gates
         name: 'file:///C:/ruta/a/kdd-gates/host.js'
  3. Reiniciar el proceso de dsh para que cargue el plugin.

Tools

kdd_validate

Corre los 2 gates core de Nivel 1: validate_contracts + validate_okf. Rápido (segundos), sin subprocesos anidados.

Parámetro Tipo Requerido Descripción
repoRoot string sí Ruta absoluta del repo KDD.
contractsDir string no Default knowledge/contracts.
okfDir string no Default knowledge.

kdd_seal

Sella el oráculo: devuelve el SHA256 (normalizado LF) de un archivo de tests, para pegar en tests_sha256 del contrato.

Parámetro Tipo Requerido
repoRoot string sí
testsPath string sí (ruta del archivo de tests, relativa al repo)

kdd_perimeter

Gate de perímetro: compara archivos cambiados contra el touch_only de un contrato. Detecta OUT_OF_PERIMETER y TESTS_TOUCHED.

Parámetro Tipo Requerido
repoRoot string sí
contract string sí (ej. knowledge/contracts/mi-tarea.md)
changedFiles array\<string> sí (ej. salida de git diff --name-only)

kdd_preflight

Dry-run de los 19 gates completos (18 Nivel 1 + validate_attestation) en una sola pasada.

Parámetro Tipo Requerido Descripción
repoRoot string sí
sandboxPermissions string enum ["danger-full-access"] no Escala el sandbox para el gate validate_test_commands (ver abajo). Pide aprobación real al usuario.
justification string no Obligatorio junto con sandboxPermissions.
run_in_background boolean no Corre como job (job_output/job_kill genéricos de dsh) en vez de bloquear la llamada.

Por qué validate_test_commands suele fallar sin escalar: ese gate corre la suite de tests propia del repo, que necesita escribir en %TEMP% y capturar salida de subprocesos — ambas cosas denegadas por el sandbox workspace-write. No es un defecto del repo ni de este plugin: es el límite de seguridad esperado. Con sandboxPermissions: "danger-full-access" + justification, ese gate puntual se reintenta con acceso completo (el resto de los 18 gates siempre corre sin escalar — ver "Decisiones de diseño").

Guía de flujo para el modelo

El plugin inyecta una sección de system prompt (visible para el modelo, no para vos) que enseña el orden correcto de la metodología — oráculo primero, sellar, contrato, validar, implementar, verificar, perímetro — así el agente no necesita que se lo expliquen en cada tarea. Se activa automáticamente al montar el plugin, sin importar qué agent preset esté en uso.

Forzar la separación implementador/validador con un subagente restringido

La regla central de KDD ("el agente que implementa nunca es el mismo que decide si está bien") normalmente depende solo de que el modelo la respete — es guía de system prompt, no una restricción real. Se puede hacer cumplir mecánicamente montando una segunda instancia de @deepseek-ai/dsh-tool-subagent con un toolFilter que le niegue las 5 tools de este plugin al hijo delegado. No es un plugin nuevo — es config sobre un paquete que ya viene con dsh — así que vive directo en cordis.patch.yml, no en este repo:

- insert:
    - id: tool-subagent-kdd-implementer
      name: '@deepseek-ai/dsh-tool-subagent'
      config:
        provider: spawn          # hijo fresco, sin historial del padre — el contrato
                                  # escrito es la interfaz, no la memoria conversacional
        toolName: kdd_delegate_implementer
        backgroundMode: one-shot
        toolFilter:
          deny:
            - kdd_validate
            - kdd_seal
            - kdd_perimeter
            - kdd_preflight
            - kdd_scaffold       # si tenés kdd-scaffold montado también
        persona: >-
          You are a KDD implementer subagent. You write code to satisfy a task
          contract's frozen oracle — you never decide whether it's correct. The
          kdd_* gate tools are not available to you by design. Implement the
          target, run the contract's test_command yourself as a sanity check,
          and report back — the delegating agent runs the real gates.

Por qué deny y no allow: un allow-list exige enumerar cada tool genérica que el implementador va a necesitar (edición de archivos, shell, búsqueda...) — fácil de romper por omisión. deny solo bloquea las tools de decisión, deja todo lo demás intacto.

Trampa real encontrada al verificarlo: toolFilter.deny con el nombre de una tool que no está montada en ese momento (ej. kdd_scaffold sin el plugin kdd-scaffold cargado) hace que tools.restrict() explote al arrancar la delegación, con Error: tools.restrict() names unknown global tool "kdd_scaffold". El deny-list tiene que coincidir exactamente con qué plugins están montados en el mismo perfil.

Verificado: delegando una tarea al subagente y pidiéndole que reporte textualmente su lista de tools disponibles, confirmó que ninguna de las 5 tools KDD aparece — no pudo ni intentar llamarlas.

Decisiones de diseño (por qué está armado así)

  • Schemas 100% tipados (string/array/boolean, nunca oneOf ni type:"json" sin tipo de nivel superior) — este deployment tiene un bug conocido del materializador de argumentos que pierde parámetros sin tipo explícito con ciertos modelos (discussion). Evitarlo en el diseño es más simple que depender de que esté parcheado.
  • kdd_preflight usa ctx.shell, no ctx.subprocess.spawn directo. preflight.py lanza sus propios subprocesos anidados (uno por gate); el spawn directo se cuelga indefinidamente en Windows para ese patrón — probado con argv plano y con cmd.exe de por medio, ninguno funcionó. ctx.shell (el mismo servicio detrás de la tool pwsh del agente) sí. Reportado como bug aparte: discussion #4796. El wrapper vive en safe-shell.js (runNested(shell, opts)), separado de host.js, para que una tool nueva que necesite el mismo patrón lo reuse en vez de reimplementarlo inline.
  • El preflight completo siempre corre sin escalar, y si se pidió escalada, validate_test_commands se corre aparte, llamando directo a validate_test_commands.run_all(..., timeout=300) (su API pública) en vez de por main() (que fija 120s sin exponerlo). Escalar el árbol anidado completo de preflight.py de una sola vez se cuelga por una causa que no se aisló; separar las dos corridas evita el problema sin tocar ningún archivo de KDD.
  • El temp para validate_test_commands vive fuera del repo (%TEMP%/kdd-preflight-tmp, borrado y recreado antes de cada corrida). Ponerlo dentro del repo (<repoRoot>/.kdd-tmp) causó una recursión real: un test que copia el repo entero (shutil.copytree) terminaba copiando corridas anteriores sin limpiar, cada una con su propio .kdd-tmp adentro, anidándose sin fin.
  • La escalada de sandbox pasa por el servicio real de aprobación (ctx.approval, el mismo que usa dsh-tool-pwsh) — nunca hay bypass silencioso: sin sandboxPermissions + justification explícitos en la llamada, el preflight corre con la política estándar.

Estado verificado

  • Ciclo KDD completo (oráculo → sello → contrato → kdd_validate → implementación → kdd_perimeter positivo y negativo) probado de punta a punta contra la plantilla y contra un proyecto instanciado con init_project.py --apply — mismo resultado en ambos.
  • kdd_preflight: 19/19 con escalada, reproducible.