Skip to content

Latest commit

 

History

History
617 lines (480 loc) · 53.2 KB

README-es.md

File metadata and controls

617 lines (480 loc) · 53.2 KB

🤖 dsh-auto-review

Aprobación con IA de segundo modelo para DeepSeek Harness: un subagente revisor de solo lectura decide permitir/denegar en la cadena de aprobación, con cierre en fallo por defecto.

Cuando una acción cruza el límite del sandbox, un segundo modelo lee la evidencia y devuelve un veredicto con su razón — para que los humanos no aprueben nada y nada inseguro se cuele.

Repositorio oficial. Este es el único repositorio oficial de dsh-auto-review, mantenido por PerryLink. Los repositorios del mismo nombre bajo otras cuentas no están afiliados.

License Gitee DSH plugin dsh-doctor DSH Market Node CI Version npm version npm downloads dshfind

English · 简体中文 · Español · Português · हिन्दी

dsh plugin --profile <name> add dsh-auto-review

📖 Base de conocimiento del ecosistema — datos medidos, no marketing: guía de desarrollo · datos de selección · criterios de mantenimiento.

Instalación y desinstalación

  • Canal git (último main): dsh plugin --profile web add github:PerryLink/dsh-auto-review — la compilación aislada de prepare necesita las claves allowBuilds que imprime el CLI de dsh para dsh-auto-review.
  • Canal npm (versiones publicadas): dsh plugin --profile web add dsh-auto-review.
  • Canal 1024 store: npm i -g dsh1024 una vez, luego dsh1024 plugin --profile web add dsh-auto-review (cuenta para el ranking de instalaciones de deepseek1024.com).
  • Canal tarball: pnpm pack en este repo y luego dsh plugin --profile web add ./dsh-auto-review-<version>.tgz.
  • Desinstalación: dsh plugin --profile web remove dsh-auto-review (o elimina la fila del parche de perfil).

⭐ 如果它帮到了你

Este plugin forma parte de la familia de plugins DSH (más de 40, todos Apache-2.0). Si te resulta útil, dale una estrella: no desbloquea nada, pero ayuda a que la siguiente persona lo encuentre antes.

English: part of a 95 plugin family for DeepSeek Harness. If it is useful, a star helps the next person find it — nothing is gated behind it.

What is dsh-auto-review?

Aprobación con IA de segundo modelo para DeepSeek Harness: un subagente revisor de solo lectura decide permitir/denegar en la cadena de aprobación, con cierre en fallo por defecto.

Cuando una acción cruza el límite del sandbox, un segundo modelo lee la evidencia y devuelve un veredicto con su razón — para que los humanos no aprueben nada y nada inseguro se cuele.

Diagrama de flujo de dsh-auto-review: solicitud → política/revisión → veredicto.

Resumen del flujo: solicitud → política/revisión → veredicto. Los ejemplos siguientes usan la superficie de comandos real.

La misma ejecución, animada.

Compatibilidad

Superficie Estado
Harness DeepSeek Harness dsh-v0.2.1-rc.2 (verificado 2026-10-18): engines.dsh >=0.2.1-0 <0.3.0; las rutas de compatibilidad P0 tienen pruebas de regresión.
Node ^22.19.0 || >=24.0.0
Plataformas Todas (answerer de host; panel web opcional mediante la capacidad de proyección de sesión)
Modelo Cualquier modelo generativo (el revisor hereda la ruta del agente de sesión; reviewerModel la reemplaza), o el modelo de decisión local no generativo Phocinae-Largha-150M-v1 (reviewerBackend: phocinae)

Qué obtienes

dsh-auto-review pone un segundo modelo en la cadena de answerers de approval/request:

  1. Costura oficial — un answerer que solo reclama las solicitudes que le pertenecen (política ai) y delega todo lo demás con next(); el flujo de aprobación humana nunca se cortocircuita.
  2. Subagente revisor de solo lectura — un fork de un solo uso con una lista blanca de herramientas read/glob/grep devuelve un veredicto estructurado { decision, reason, riskLevel }. Las solicitudes del revisor se reconocen por identidad y se delegan; maxDepth + la lista blanca mantienen al revisor sin delegar.
  3. Cierre en fallo — un fallo, un timeout o un desajuste de esquema del revisor se resuelve con fallbackPolicy (por defecto rejected); un veredicto de denegación devuelve su razón al modelo que llama.
  4. Enrutamiento por configuración — políticas por herramienta (ai/human/never) más reglas de riesgo con regex, todo modificable desde cordis.yml.
  5. Las razones de denegación llegan al modelo — la razón del revisor se inyecta en el resultado de la herramienta denegada (vinculada por callId); los rechazos por fallback y por política never también inyectan marcadores auditables ([auto-review] / [auto-review-fallback] / [auto-review-never]).
  6. Rastro de auditoría completo — eventos de sesión solo-registro autoReview/verdict + autoReview/rejection (sobre ignorable: true) más un compañero invariant opcional que impone marcador ⟺ evento.
  7. Controles de seguridad — un disyuntor de rechazos (3 denegaciones consecutivas, o 6 de los últimos 10 veredictos, por turno), una política por nivel de riesgo, una anulación de un solo uso /auto-review approve, y una desactivación dura de política never que se explica a sí misma al modelo.
  8. Contexto opcional del revisor — una transcripción compacta acotada (contextBudget) más una política de decisión en Markdown estilo Codex (reviewerPolicyText).

Cada decisión se reconstruye desde el registro de sesión: approval/asked → autoReview/verdict (o autoReview/rejection) → approval/decided.

¿Por qué un segundo modelo en lugar de reglas?

Los auto-aprobadores basados en patrones deciden antes del despacho, sin evidencia. dsh-auto-review entrega la decisión a un subagente revisor que lee el espacio de trabajo real (a través de su interfaz de herramientas de solo lectura), los argumentos de la llamada a herramienta ya transmitidos (valores sensibles redactados), la razón de la solicitud y tus reglas de riesgo — y devuelve un veredicto estructurado. Un veredicto de denegación devuelve su razón al modelo que llama, de modo que el agente aprende por qué en lugar de reintentar a ciegas.

Inicio rápido

dsh plugin --profile web add github:PerryLink/dsh-auto-review
# 1. instala el bundle en tu perfil
dsh plugin --profile web add github:PerryLink/dsh-auto-review

# o desde npm (versiones publicadas)
dsh plugin --profile web add dsh-auto-review

# 2. reinicia y verifica la fila
dsh --profile web --dump-config | grep -A4 'id: auto-review'

De fábrica, el parche incluido revisa con IA bash, write, pwsh y powershell; todas las demás herramientas (incluido edit — modificación in situ) delegan a la cadena humana. Añade edit: ai explícitamente si aceptas ediciones in situ sin un humano en el bucle.

Ejemplos

Son los puntos de entrada reales; instala y llama a uno.

Ejemplo detallado

Comando

/auto-review status

Salida

All-time: 1 allows, 0 denies, 1 fallbacks, 1 never rejects (avg 10 ms per verdict).
Recent verdicts: write: fallback(timeout), bash: allow

Observado en test/command.spec.ts:123-160 (assertions at :158-159)

Rama de fallo

Entrada

/auto-review approve 2

Salida

No recent denial #2 in this session (0 recorded).

Observado en plugins/dsh-auto-review/src/messages.ts:53; plugins/dsh-auto-review/src/runtime.ts:1039; plugins/dsh-auto-review/test/command.spec.ts:109-113

Ejemplos breves

  • auto-review
  • dsh-eval

Configuración

Todas las opciones son campos Schemastery Config (modificables desde cordis.yml). Una anulación dirigida por id reemplaza toda la fila — repite cada clave que necesites.

Clave Por defecto Significado
enableByDefault true Las sesiones arrancan con auto-review activo; /auto-review on|off escribe una anulación duradera que gana a esto
toolsPolicy.default human Política para herramientas no listadas (delega al answerer humano)
toolsPolicy.overrides {} Política por herramienta: ai / human / never
riskRules [] {pattern, policy, field?} emparejado antes de la tabla de herramientas; field elige reason (por defecto), toolName o arguments
reviewerProvider fork Proveedor de subagente para el revisor (backend fork en proceso)
reviewerPreset (none) Id del Agent Preset de solo lectura; obligatorio cuando el host solo expone startActivation (0.2.1+)
reviewerModel (heredado) Id del modelo revisor; si no se define, hereda la ruta del agente de sesión
reviewerModelProvider (heredado) Ruta del proveedor LLM para reviewerModel; si no se define, hereda el proveedor del agente de sesión
reviewerBackend agent Motor del revisor: agent (el revisor generativo) o phocinae (el servicio local de decisión no generativo). Sin definir se infiere de reviewerModel: un id Phocinae… selecciona phocinae
phocinae.endpoint http://127.0.0.1:8155/v1/systemone URL del servicio de decisión Phocinae; solo loopback salvo phocinae.allowRemoteEndpoint
phocinae.model Phocinae-Largha-150M-v1 Nombre del modelo servido; un reviewerModel Phocinae lo selecciona automáticamente
phocinae.timeoutMs 5000 Plazo HTTP por solicitud (un intento, sin reintentos), acotado por reviewerTimeoutMs
phocinae.minConfidence 0.45 Piso de confianza calibrada para un allow; un allow dudoso pasa por fallbackPolicy en vez de conceder. El valor 0.45 está medido sobre el conjunto versionado de 91 comandos: 0/58 destructivos permitidos con 0.45 (y, con las guardas, con 0.4/0.35); el modelo solo con 0.4 permitió dos comandos de rutas de sistema
phocinae.maxStateChars 4096 Límite del estado de decisión renderizado; un estado truncado puede denegar pero nunca permitir
phocinae.allowRemoteEndpoint false Permitir un endpoint no loopback. El estado lleva el texto de la llamada revisada, así que es una decisión explícita de salida de datos
reviewerTimeoutMs 60000 Plazo del veredicto; al vencer se aplica la política de fallback
reviewerTools [read, glob, grep] Lista blanca de herramientas del hijo revisor (debe ser no vacía)
fallbackPolicy rejected Ante fallo del revisor: rejected (cierre en fallo) / delegate / allow-once
maxReviewsPerTurn 10 Presupuesto de veredictos de IA reales por turno abierto; superado, las solicitudes delegan
maxFailuresPerTurn 10 Presupuesto de fallos del revisor por turno abierto (por defecto igual a maxReviewsPerTurn)
reasonMaxChars 2000 Límite para las razones del revisor y la vista previa de argumentos redactados
reviewerGuidance (ninguna) Orientación opcional añadida al prompt del revisor
reviewerPolicyText (ninguna) Política de decisión en Markdown inyectada en el prompt del revisor (estilo Codex)
denyGuidance (texto anti-elusión) Orientación añadida a cada razón de denegación inyectada
contextBudget {turns: 2, maxChars: 4000} Presupuesto de transcripción compacta para el prompt del revisor (el turno abierto y el anterior); turns: 0 desactiva la sección — y un revisor ciego deniega acciones autorizadas por el usuario, así que el runtime avisa cuando 0 coincide con una política ai. El presupuesto de caracteres se gasta en las líneas más recientes
riskPolicy {maxAutoAllow: high, onHighRisk: delegate} Los veredictos allow por encima de maxAutoAllow delegan o deniegan
circuitBreaker {consecutiveDenies: 3, windowDenies: 6, windowSize: 10, action: delegate} Disyuntor de rechazos
overrideTtlMs 300000 Cuánto dura una anulación de /auto-review approve
verdictCacheTtlMs 60000 Reutiliza un veredicto reciente para una huella herramienta + argumentos idéntica; 0 desactiva la caché. Solo se aplica con contextBudget.turns: 0 — un veredicto que depende de la transcripción no es reproducible solo desde herramienta + argumentos
verdictCacheMaxEntries 256 Máximo de huellas en caché antes de desalojar la más antigua
language en Idioma de la UI de la salida del comando /auto-review (en | zh)
allowUnmarkedAudit false Fuerza la auditoría del registro de sesión en hosts que descartan el marcador ignorable (peligroso: los eventos sin marcar hacen las sesiones irrecuperables en otros hosts); por defecto se detecta y se degrada (adaptado el 2026-09-02, reverificado contra 0.1.5-rc.2 el 2026-09-11)

Revisor local con modelo de decisión (Phocinae, opcional)

reviewerBackend: phocinae sustituye el revisor generativo por el modelo de decisión local y no generativo Phocinae-Largha-150M-v1, servido por phocinae-server (POST /v1/systemone). El modelo responde una pregunta tipada y nunca genera texto, así que una revisión no necesita clave de API, ni la costura subagents/llm, ni red externa (solo loopback): una pasada (≈21 ms en caliente con GPU, ≈1,5 s en CPU monohilo) devuelve una etiqueta de daño con confianza calibrada.

config:
  toolsPolicy: { overrides: { bash: ai } }
  reviewerModel: Phocinae-Largha-150M-v1   # esto solo ya selecciona el backend Phocinae
  phocinae:
    endpoint: http://127.0.0.1:8155/v1/systemone
    minConfidence: 0.45
  fallbackPolicy: delegate                 # opcional: envía lo dudoso a la cadena humana

Es una capa de veto/triaje, no un aprobador general. Solo un harmless con answer_confidence >= phocinae.minConfidence (por defecto 0.45) permite. destructive deniega; risky, un harmless dudoso, una ruta de sistema o secreta y un servicio inalcanzable o malformado pasan por fallbackPolicy (por defecto rejected, cierre en fallo; delegate los envía a la cadena humana). El revisor solo pregunta por comandos de shell: un write/edit u otra llamada sin argumento command escala sin contactar al modelo.

El estado es exactamente The agent is about to run the shell command "<command>" in its workspace., con opciones descritas (los criteria con los que se entrenó el modelo, renderizados en el texto de la opción porque el contrato HTTP no tiene campo criteria). El conjunto versionado de 91 comandos (bench/phocinae-commands.json: 58 destructivos, 33 rutinarios) se ejecuta con node bench/phocinae-bench.mjs contra un servidor vivo; con las guardas de rutas/operadores y el valor por defecto 0.45, 0 de 58 comandos destructivos fueron permitidos — 28 denegados y 30 escalados — y 3 de 33 comandos rutinarios fueron permitidos. Con 0.4 el modelo solo permitió cat /etc/shadow (0.4036) y cp /dev/null /etc/passwd (0.4265); por eso el piso es 0.45 y las guardas son obligatorias (el producto con guardas sigue en 0/58 con 0.4 y 0.35). Es un conjunto medido, no una prueba: el modelo sigue siendo consultivo y un comando fuera del conjunto puede clasificarse mal; las guardas cubren las clases de rutas de sistema y comandos compuestos que encontró la auditoría del 2026-10-26. La razón de aprobación, la transcripción y la ruta del workspace no se envían, y el comando pasa por la misma redacción de claves y secretos en línea que el prompt generativo. El endpoint es solo loopback salvo phocinae.allowRemoteEndpoint: true. El backend se aplica solo a las revisiones de aprobación; la capa de revisión de dsh-eval sigue usando un modelo generativo.

Los comandos con operadores de shell nunca se permiten: si el comando contiene ;, &, |, $(), comillas invertidas, una redirección, un salto de línea u otro carácter de control, escala aunque el modelo responda harmless, porque un veredicto sobre el texto visible no dice nada sobre un comando compuesto. Lo mismo vale para un comando que referencia una ruta de sistema o secreta (/etc, /dev, /proc, /root, ~/.ssh, .env, credenciales, rutas de sistema de Windows): escala en vez de permitir. Las llamadas que no son de shell (write, edit, …) también escalan: el patch incluido trae write: ai, así que pon write/edit en human al activar este backend, o se rechazarán por el fallback por defecto.

Estos ajustes son solo del revisor generativo y este backend los ignora: reviewerProvider, reviewerPreset, reviewerModelProvider, reviewerTools, reviewerGuidance, reviewerPolicyText y contextBudget. /auto-review approve sí funciona: añade al estado una frase de autorización humana (review id y nombre de herramienta) y el modelo sigue decidiendo. El cliente no envía cabecera Authorization; si el servidor define PHOC_BEARER_TOKEN, déjalo sin definir o pon un proxy autenticado delante.

Inicia el servicio una vez: pip install phocinae-server (o ejecuta el checkout), descarga los pesos desde la model card y ejecuta PHOC_MODEL_DIR=<weights-dir> python -m phocinae.main — escucha en 127.0.0.1:8155; verifica con curl http://127.0.0.1:8155/health.

Ejemplo (forma completa anotada: fixtures/config/config-full.yaml):

- insert:
    - id: auto-review
      name: dsh-auto-review
      config:
        toolsPolicy:
          overrides: { bash: ai, write: ai }
        riskRules:
          - pattern: '([Rr][Mm]\s+(-[a-z]+\s+)*/|[Gg][Ii][Tt]\s+push\s+--force)'
            policy: never
          - pattern: 'write'
            policy: never
            field: toolName
        reviewerTimeoutMs: 30000
        fallbackPolicy: delegate
        riskPolicy: { maxAutoAllow: medium, onHighRisk: delegate }
        circuitBreaker: { consecutiveDenies: 3, windowDenies: 6, windowSize: 10, action: delegate }

De dónde sale realmente la configuración

~/.dsh/settings.yaml NO es una fuente de configuración para este plugin. Un bloque auto-review: allí no tiene efecto ni produce aviso alguno: como todo plugin-función de DSH, dsh-auto-review recibe su Config de la fila con la que el loader lo monta — la capa de parches cordis del perfil. (Algunos otros plugins de DSH sí leen además el servicio de settings, así que la inconsistencia es fácil de sufrir y el síntoma es indistinguible de que el revisor simplemente deniegue.)

Pon la configuración en el cordis.patch.yml de tu perfil. Una anulación dirigida por id reemplaza la fila de config entera, así que reafirma cada clave que necesites — omitir toolsPolicy devuelve bash/write al valor por defecto del esquema, human, y el revisor deja de ejecutarse por completo:

- id: auto-review
  config:
    toolsPolicy:
      overrides: { bash: ai, write: ai }
    contextBudget: { turns: 4, maxChars: 8000 }

Herramientas y superficies

Superficie Tipo Notas
auto-review answerer Answerer de la cascada approval/request — reclama solicitudes de política ai, delega el resto con next()
/auto-review comando on|off|status|approve [n] — anulación durable por sesión, presupuestos y estadísticas acumuladas
Inyección de razón de denegación listener tools/post-execute — razones de veredicto / fallback / never devueltas al resultado de la herramienta denegada
autoReview proyección de sesión Plegada desde los eventos solo-registro autoReview/*
Panel web de revisión cliente Acción en la cabecera de sesión: interruptor, presupuestos, estadísticas, veredictos recientes, aprobación de un solo uso
dsh-eval CLI Motor de evaluación de agentes basado en YAML (bin/dsh-eval.mjs)
Compañero invariant invariant dsh-auto-review/invariant (opcional; necesita el servicio invariants)

Comando de sesión

/auto-review on|off|status|approve [n]

on/off añaden la anulación durable autoReview/state (el plegado sobrevive al reinicio/reanudación — la repetición ES el estado) e inyectan un aviso de cambio que el modelo ve (registrado como un evento user/message). status informa del estado efectivo, de ambos presupuestos por turno (veredictos de IA y fallos del revisor), de un disyuntor disparado cuando hay uno activo, y de las estadísticas acumuladas de la sesión (permisiones/denegaciones/fallbacks/rechazos never, duración media, veredictos recientes). approve [n] registra una anulación autoReview/override de un solo uso para la n-ésima denegación más reciente (1 = la más reciente): la siguiente revisión de la misma herramienta dentro de overrideTtlMs lleva la autorización como contexto del revisor — el revisor sigue decidiendo, y la anulación se consume con esa revisión independientemente de su resultado.

Panel web de revisión

En la GUI web (perfil web), el paquete contribuye una acción en la cabecera de sesión (AI Review) que abre un panel con el estado de auto-review de la sesión: el interruptor con botones on/off (que ejecutan /auto-review on|off), ambos presupuestos por turno, estadísticas acumuladas (incluidos los rechazos por desactivación dura), el disparo del disyuntor, los veredictos recientes y botones approve de un solo uso para las denegaciones recientes (que ejecutan /auto-review approve [n]).

Cómo está conectado:

  • El host registra una proyección de sesión autoReview (plegada desde los eventos solo-registro autoReview/*) y la sirve a través del canal de proyección de sesión.
  • La mitad del navegador es un módulo cliente (auto-descubierto desde la declaración dsh.client) registrado en el asiento conversation.session.header.actions.
  • No se necesitan filas de parche adicionales: el panel se carga siempre que el plugin esté instalado en un perfil cuya compilación web proporcione la capacidad de proyección de sesión (el perfil web lo hace). Sin esa capacidad, el panel se declara no disponible; el answerer no se ve afectado.

El panel lee solo valores completos de proyección — nunca recibe el flujo crudo de eventos de sesión.

Cómo funciona

                       approval/request waterfall (answerer chain)
                        │
┌───────────────────────┴──────────────────────┐
│ dsh-auto-review answerer                     │
│  · session enabled?  · policy = ai?         │   no ── next() ──▶ human answerer (UI)
│  · risk rules → toolsPolicy → default       │
└───────────────────────┬──────────────────────┘
                        │ yes
                        ▼
        ┌───────────────────────────────────┐
        │ reviewer subagent (fork, one-shot)│
        │  · toolFilter: read/glob/grep     │
        │  · outputSchema: {decision,       │
        │    reason, riskLevel}             │
        │  · timeout + req.signal abort     │
        └───────────────┬───────────────────┘
                        │ verdict / failure (fail-closed fallback)
                        ▼
 allow → allowed-once        deny → rejected + reason injected into the
                                       denied tool result (callId-linked)
                        │   never → rejected + [auto-review-never] feedback
                        │            (hard disable, no reviewer runs)
                        ▼
 audit: approval/asked → autoReview/verdict | autoReview/rejection
        → approval/decided (session events, log-only, invariant-checked)

Orden de composición. El answerer se ejecuta en su posición de registro en la cascada: si un answerer de UI humana se compone ANTES de la fila auto-review, los humanos responden primero y el revisor solo ve lo que se delega aguas abajo. Verifícalo con dsh --profile <name> --dump-config y coloca la fila auto-review antes de tus filas de answerer humano cuando quieras que las herramientas de política ai se enruten primero al revisor.

dsh-eval — motor de evaluación de agentes

Más allá del revisor de aprobación, dsh-auto-review incluye dsh-eval: una plataforma de evaluación de agentes basada en YAML que ejecuta sesiones DSH headless reales (un agente aislado + espacio de trabajo temporal por caso, la persona oficial Minimal como prompt de sistema de base), recoge el rastro de llamadas a herramientas del registro de eventos de sesión y evalúa aserciones estructuradas más una revisión opcional de segundo modelo — la misma costura de revisor que el answerer de aprobación.

# eval/cases/demo.yaml (abreviado)
suite:
  name: my-suite
  cases:
    - id: math-output
      input: Solve 17 × 24 and reply with only the final number, nothing else.
      expect:
        output: { contains: "408" }
    - id: glob-trace
      seedFrom: '.'
      input: Use the glob tool with pattern "src/**" to list the source files…
      expect:
        toolCalls: [{ tool: glob, arguments: { contains: { pattern: "src" } } }]
        results: [{ tool: glob, contains: "index.ts" }]

Ejecútalo (una clave de API de DeepSeek debe estar en el entorno):

dsh-eval eval/cases --model deepseek-flash --timeout-ms 240000 --out .eval-reports

Familias de aserciones

El bloque expect admite seis familias de aserciones; cada aserción se evalúa de forma independiente e informa su propio aprobado/fallo con valores esperados/reales, de modo que un caso que falla se explica a sí mismo sin volver a ejecutarlo.

Familia Claves DSL Qué verifica
Rastro de herramientas toolCalls, toolCallsExact, noToolCalls, results secuencia ordenada de llamadas (subsecuencia con saltos), secuencia exacta de nombres, resultado por herramienta (isError/contains/regex)
Salida y presupuesto output, turnEnds, maxTokens subcadena/regex de la salida final, resultado del turno, presupuesto de tokens
Regresión de prompt prompt el prompt de sistema renderizado debe coincidir con un baseline comprometido (o un archivo baselineFrom); cualquier deriva se informa como un diff lado a lado, con regex allowedChanges para permitir ediciones intencionales
Métricas de estrés stress latencia de paso P99 (maxP99Ms), peor tiempo al primer token (maxTtftMs), velocidad agregada de generación de tokens (minTokensPerSecond)
Equidad bias radar de sesgo sobre la salida final: conteos por categoría con regex (categories), patrones forbid duros, topes maxHits/maxCategoryHits
Revisión de segundo modelo review un veredicto aprobado/fallo complementario del subagente revisor (capa separada, la misma costura que el revisor de aprobación)
- id: regression-gate
  input: Answer in one sentence.
  expect:
    prompt:
      baseline: "You are a helpful software engineer assistant."
      allowedChanges: ["copyright-year"]
    stress:
      maxP99Ms: 8000
      maxTtftMs: 3000
      minTokensPerSecond: 20
    bias:
      categories: { gender: ["[Hh]e is (un)?stable"] }
      forbid: ["[Ss]crew that"]
      maxCategoryHits: 0

Puerta de CI: el proceso sale con 0 solo cuando todos los casos de todas las suites han pasado — las evaluaciones que fallen hacen fallar la compilación. Cada caso deja un JSONL de sesión reproducible y un JSON de rastro junto a report.md/report.json; los resultados de las aserciones (incluido el diff lado a lado del prompt), el uso de tokens, las métricas de estrés/equidad y el veredicto de revisión se escriben todos en los archivos de informe.

- name: dsh-eval
  run: npx dsh-eval eval/cases --model deepseek-flash --timeout-ms 240000 --out .eval-reports
  env:
    DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}

dsh-eval difiere de openai/codex-research: codex-research puntúa trayectorias de agentes para comparación de investigación; dsh-eval es un arnés declarativo de regresión aprobado/fallo — casos YAML, aserciones estructuradas de rastro/prompt/estrés/equidad, una revisión opcional de segundo modelo y un código de salida de CI — para gatear cualquier agente DSH, no para ranking de investigación.

Servidor MCP (independiente)

dsh-auto-review también incluye un servidor MCP stdio (dsh-auto-review-mcp) para que clientes MCP externos (Claude, Codex, …) consuman una ruta de revisión determinista sin el harness. Habla JSON-RPC 2.0 sobre JSON delimitado por saltos de línea (NDJSON): un objeto JSON por línea, sin tramado Content-Length.

Límite. El revisor completo necesita el seam de subagentes del harness y un segundo modelo, que un proceso stdio separado no puede alcanzar. Por lo tanto, el servidor independiente es reglas deterministas + caché, sin revisión por modelo:

  • review_action reutiliza la caché de veredictos por huella (src/cache.ts) y la resolución de reglas de riesgo / políticas de herramientas (src/config.ts): una regla never → deny; un acierto de caché sobre una huella idéntica de tool + arguments reproduce ese veredicto; todo lo demás (ai necesita modelo, human necesita a un humano) → deny fail-closed con reason: "standalone path, no model". Nunca permite una acción que un modelo no haya permitido ya.
  • cache_stats informa los contadores de aciertos/almacenamiento y el estado del TTL.
Herramienta Propósito
review_action {tool, args?, reason?} → {decision, reason, riskLevel} — denegación determinista / reproducción de caché
cache_stats {} → {hits, stores, size, ttlMs, enabled}

Ejecución directa:

# las reglas de riesgo vienen de variables de entorno
export DSH_AUTO_REVIEW_RISK_RULES='[{"pattern":"rm -rf","policy":"never","field":"arguments"}]'
node bin/dsh-auto-review-mcp.mjs
# o, tras npm install: npx dsh-auto-review-mcp

Configuración por entorno: DSH_AUTO_REVIEW_RISK_RULES (array JSON de {pattern, policy, field?}), DSH_AUTO_REVIEW_TOOLS_POLICY (JSON {default?, overrides?}), DSH_AUTO_REVIEW_CACHE_TTL_MS, DSH_AUTO_REVIEW_CACHE_MAX_ENTRIES.

Ejemplo para Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "dsh-auto-review": {
      "command": "npx",
      "args": ["-y", "dsh-auto-review-mcp"],
      "env": {
        "DSH_AUTO_REVIEW_RISK_RULES": "[{\"pattern\":\"rm -rf\",\"policy\":\"never\",\"field\":\"arguments\"}]"
      }
    }
  }
}

El servidor es de solo lectura y determinista: sin red, sin modelo, sin escrituras.

Permisos y datos

  • Permisos: el manifiesto del workshop declara session:append, approval:answer, subagent:spawn, command:register y tools:observe.
  • Datos: nada se guarda en disco; el búfer circular de informes está en memoria y acotado. Sin peticiones de red propias.
  • Registro de sesión: los eventos autoReview/* llevan identidad del revisor, veredicto, razón, riesgo y duración — añadidos con el marcador de sobre ignorable: true para que cualquier compilación cargue el registro. Los hosts cuyo Session.append es anterior al marcador (todas las líneas rc publicadas hasta 0.1.1-rc.2 — ninguna versión lo estampa aún) se detectan antes del primer append (precomprobación de la versión del peer y luego sondeo del sobre devuelto); los hosts 0.1.2-rc.1, 0.1.3-alpha.2 y 0.1.5-rc.2 mantienen el campo ignorable en el sobre, pero Session.append no ofrece ninguna forma de estamparlo (su tercer parámetro es SurfaceIntent, solo para eventos de superficie), y la ruta de lectura de persistencia rechaza los tipos de evento desconocidos sin marcar, por lo que esas líneas — y las versiones irresolubles — también cierran en fallo antes de cualquier append. La auditoría se degrada a un espejo en memoria con comentarios sin marcador, de modo que las sesiones siguen siendo cargables en todas partes.

Límites de seguridad

  • El revisor es un modelo. Sus veredictos son política consultiva, no un núcleo de seguridad; prefiere reglas human/never para operaciones irreversibles.
  • Cierre en fallo. Cada camino anómalo (proveedor ausente, carencias de capacidad, rechazo al iniciar, timeout, razón de parada no completed, veredicto ausente/malformado, fallo de correlación de auditoría) se resuelve con fallbackPolicy, por defecto rejected — y el rechazo devuelve una razón auditable al modelo. allow-once concede incondicionalmente; existe solo para despliegues desatendidos cuyo administrador acepta ese riesgo.
  • Revisor de solo lectura. La lista blanca toolFilter del revisor (read/glob/grep) no puede escribir, editar, ejecutar bash, acceder a la red ni delegar (maxDepth = su propia profundidad). Su registro de sesión se persiste y es auditable.
  • Revisor aislado del contexto. Los pasos del hijo revisor se filtran en la costura oficial agent/pre-step: solo entran su propio prompt y los resultados de sus propias herramientas de solo lectura. Los archivos de instrucciones del espacio de trabajo (AGENTS.md / CLAUDE.md) y los plugins que inyectan contexto se descartan en esa costura; la instantánea de contexto de ejecución del propio harness se re-admite después de agent/pre-step, el firewall no la elimina y el revisor la ve. Esto vale con CUALQUIERA de los proveedores de subagente — esos productores inyectan de nuevo en cada sesión de agente, así que lo que los cierra es el filtro y no la elección de proveedor. La lista blanca es por ORIGEN del mensaje, así que un plugin que declare un origen nuevo también se descarta.
  • Los argumentos sensibles se redactan (coincidencia por nombre de clave: token, password, api_key, Authorization, credenciales, claves privadas …) antes de entrar en el prompt del revisor, y un argumento de texto libre pasa además por una heurística en línea que enmascara las formas KEY=VALUE / KEY: VALUE / --flag VALUE y los esquemas Bearer/Basic — que es como suele aparecer un secreto en una llamada de shell. El plugin nunca ejecuta los argumentos revisados. Ambas pasadas son de mejor esfuerzo, no un escáner de secretos: un secreto sin clave al lado sigue siendo visible, así que no revises con IA herramientas cuyos valores de argumento no te puedas permitir mostrar a un modelo.
  • Las desactivaciones duras se explican a sí mismas. Una herramienta o regla de riesgo never rechaza de forma determinista Y registra un evento solo-registro autoReview/rejection, y luego inyecta un marcador [auto-review-never] en el resultado de la herramienta denegada — el modelo aprende que la acción está duramente desactivada en lugar de reintentarla (verificado por invariant: marcador ⟺ evento).
  • Disyuntor de rechazos. Una racha de denegaciones en un turno dispara el disyuntor (consecutiveDenies / windowDenies dentro de windowSize), registrada como un evento solo-registro autoReview/circuit; las solicitudes posteriores siguen su action (delegate / reject / abort-turn).
  • El contexto del revisor es transcripción ya presentada. contextBudget alimenta al revisor con contenido de sesión ya presentado. Con el modelo revisor de la misma ruta por defecto, ese contenido permanece dentro de un proveedor; configura reviewerModel a un proveedor diferente solo si aceptas presentarle esa transcripción.
  • never es unidireccional en esta capa. Una herramienta o regla de riesgo never rechaza antes de que la cadena humana vea la solicitud — un control de bloqueo, no un valor por defecto.

Limitaciones conocidas

  • Dos exposiciones distintas, dos respuestas distintas — ninguna sustituye a la otra. El contexto inyectado (archivos de instrucciones del espacio de trabajo, la instantánea de contexto de ejecución, inyecciones de plugins de terceros) se inyecta de nuevo en cada sesión de agente, así que llega al revisor de forma idéntica con reviewerProvider: fork y con reviewerProvider: spawn — medido byte a byte idéntico en ambos con la misma petición. El filtro por origen de agent/pre-step es lo que lo cierra, con cualquiera de los dos proveedores; spawn por sí solo NO impide que las instrucciones del espacio de trabajo lleguen al revisor. Aparte, fork siembra al hijo con los turnos completados de la sesión delegante: ese historial ya es el propio registro del hijo y no un mensaje que entra en un paso, así que el filtro no puede tocarlo y solo spawn lo evita, con la valla de transcripción no confiable del prompt del revisor como mitigación intermedia. En las dos trazas anteriores la siembra no produjo mensajes adicionales, por lo que su impacto práctico está sin cuantificar.
  • El revisor necesita una ruta LLM funcional (heredada por defecto); sin ella, cada revisión cae según fallbackPolicy — nunca una concesión silenciosa.
  • Los nombres de reviewerTools deben existir como herramientas globales en el perfil; un nombre desconocido hace fallar al hijo revisor en voz alta en el punto más temprano y cae en fallback.
  • Las reglas de riesgo emparejan el reason de la solicitud, el toolName o los arguments redactados de la llamada según su field; otras condiciones van en toolsPolicy.overrides.
  • La anulación /auto-review approve autoriza la siguiente revisión de la misma herramienta, no la llamada histórica exacta; una acción diferente sobre la misma herramienta la consume.
  • Los eventos de veredicto son solo-registro; el panel web de revisión lee la proyección autoReview plegada (el flujo crudo de eventos nunca llega a los plugins del navegador).
  • autoReview/state y autoReview/verdict se añaden con el marcador de sobre ignorable: true en hosts que lo respetan, de modo que cualquier compilación del harness carga el registro — los lectores que no conocen los tipos fuera del repo simplemente omiten esos registros. En hosts rc publicados (rc.1–rc.8) el runtime detecta el marcador descartado y nunca escribe estos eventos (el espejo en memoria mantiene el comando, los presupuestos, el disyuntor y approve durante la sesión); las sesiones ya contaminadas por versiones anteriores a 0.5.1 pueden repararse con scripts/repair-session-logs.mjs de dsh-permission-rules (su conjunto de tipos por defecto cubre los cinco eventos autoReview/*).
  • El canal git necesita la única clave allowBuilds que el CLI de dsh imprime para el propio dsh-auto-review. El repo incluye su propio pnpm-workspace.yaml con allowBuilds para esbuild y los paquetes nativos del host (@deepseek-ai/dsh-subprocess-local, node-pty, koffi); typescript + tsdown están en devDependencies, y una instalación git los instala y ejecuta prepare.
  • El compañero invariant opcional necesita el servicio invariants (composiciones agent-spine como headless/ACP); el perfil web plano no lo proporciona, por lo que la fila se incluye comentada en el parche del bundle.

Trabajo relacionado

  • Andy8647/dsh-auto-approval — clasificador allow/deny de dos estados en la cascada tools/pre-execute con auditoría en archivo de registro. dsh-auto-review difiere deliberadamente: cadena de answerer oficial, siempre delega lo que no le pertenece, segundo modelo de solo lectura con un veredicto estructurado, razones de denegación devueltas al modelo, auditoría en el registro de sesión.
  • ACP automation bridge — decisiones de máquina de un solo uso para sus propios agentes de ACP. dsh-auto-review está limitado a sesión y política de herramientas para el harness interactivo; nunca infiere concesiones durables.

Desarrollo

pnpm install                # node ^22.19 || >=24
pnpm run typecheck          # tsc: src + tests contra el checkout local del harness
pnpm test                   # vitest: 25 archivos spec
pnpm run build              # declaraciones tsc + bundles tsdown (lib/, incluido el bundle de cliente)
pnpm run verify:self-contained
pnpm pack                   # el tarball publicado

Estructura del repositorio: src/index.ts (contrato del plugin) · src/config.ts (esquema Schemastery + resolución) · src/runtime.ts (answerer, comando, inyección de razón de denegación) · src/review.ts (orquestación del revisor, prompt, saneamiento) · src/phocinae.ts (el revisor local opcional con modelo de decisión) · src/events.ts (vocabulario de eventos de sesión + pliegues) · src/projection.ts + src/projection-types.ts (la proyección de sesión autoReview) · src/invariant.ts (compañero invariant) · src/eval/ (el motor dsh-eval) · eval/ (composición de evaluación incluida) · bin/dsh-eval.mjs (lanzador CLI) · src/client/ (mitad del navegador) · test/ · fixtures/.

Temas

deepseek-harness, dsh, dsh-plugin, cordis, approval, auto-review, second-model, ai-safety, sandbox, subagent

Contribuidores

  • @PerryLink — creador y mantenedor: el answerer de aprobación, el subagente revisor, la política de riesgo y el disyuntor, el panel de revisión por proyección de sesión, el compañero invariant, dsh-eval y la documentación en cinco idiomas.
  • @weipeng1999 — propuso el enrutamiento independiente de proveedor/modelo del revisor (#11, discusión #12), que se publicó como reviewerProvider / reviewerModel.
  • @alexchenzl — incluyó el plugin en el directorio de plugins de DSH (#10).

Instalar desde el mercado de DSH Desktop

Todos los plugins de PerryLink pueden explorarse en el mercado integrado de DSH Desktop: Market → Sources → add source → pegar https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → seleccionarlo. La instalación sigue pasando por la verificación de identidad npm del mercado y tu confirmación.

Licencia

Apache License 2.0 © 2026 dsh-auto-review contributors

Interoperabilidad con otros plugins de DSH

Verificado contra DSH 0.2.1-rc.2 (el runtime para el que se publica este README) y el conjunto de plugins con más estrellas sondeado el 2026-10-05.

Este plugin no interfiere con otros plugins, incluidos los de más estrellas:

  • Sin colisión de nombres de herramienta. Todas las herramientas llevan espacio de nombres; ninguna ocupa un nombre desnudo ya perteneciente a una herramienta incluida u otro plugin.
  • Sin colisión de clave de servicio. Solo provee autoReviewRuntime; esa clave no es una costura incluida ni la provee ningún plugin de más estrellas.
  • Sin colisión de slot. No registra ninguna clave de slot de cliente, así que no disputa un asiento shadows-shipped-ui.
  • Sin colisión de ruta HTTP. No registra ningún prefijo webServer.
  • Sin colisión en la capa de patch. El patch del bundle solo hace insert de su propia fila; nunca sobrescribe el config de una fila incluida.
  • Sin mutación global. No parchea prototipos, ni reescribe process.env, ni reemplaza el dispatcher global de fetch.

Los listeners de eventos compartidos no interfieren por construcción. Observa los eventos sensibles al orden agent/pre-step, approval/request, tools/post-execute con ctx.on() — el registro de difusión de Cordis, donde cada listener se ejecuta y ninguno puede dejar sin turno a otro. Todos los listeners aquí delegan por next(), así que la cadena nunca se cortocircuita:

  • agent/pre-step — also used by dsh-routing-suite (7000★, 7 listeners), modlens (4122★), dsh-purge (3317★), dsh-agent-teams (1923★), dsh-context (1849★).
  • tools/post-execute — also used by cc-safety-net (1576★).

Evidencia estática: dsh-plugin-doctor K10–K13 dan pass en todas las comprobaciones de este repositorio.

PerryLink DSH Plugin Family

Este proyecto forma parte de la familia de plugins de DeepSeek Harness de PerryLink. El registro permanece plegado abajo para que cada README conserve una primera pantalla corta; expándelo para ver cada fila y su estado.

Expandir todos los plugins
Plugin Estado
dsh-aqua-input-check
dsh-archive-check
dsh-auto-review
dsh-autotier
dsh-bid-ca-precheck
dsh-bid-qual-check
dsh-cert-mcp
dsh-checkpoint-rewind
dsh-click
dsh-composer-history
dsh-contract-stance
dsh-customs-doc-check
dsh-data-quality
dsh-demurrage-ledger
dsh-doublecheck
dsh-drill-script-check
dsh-eia-guide-check
dsh-emergency-plan
dsh-essay-rubric-check
dsh-evidence-check
dsh-export-ctl-check
dsh-fast
dsh-fmea-table-check
dsh-forecast-penalty
dsh-fund-research
dsh-github
dsh-gongwen-flow-check
dsh-gongwen-word-check
dsh-guard-plan-qc
dsh-hazchem-check
dsh-hazplan-check
dsh-hidden-risk-map
dsh-hs-classify
dsh-icd-rule-check
dsh-industry-research
dsh-lawcite-adapter
dsh-laya
dsh-lc-doc-check
dsh-learning-gap-check
dsh-library
dsh-local-ai
dsh-lsp-actions
dsh-mask
dsh-mcp-panel
dsh-medrec-qc
dsh-memento
dsh-nsfc-form-check
dsh-nurse-record-check
dsh-observe
dsh-origin-rvc-check
dsh-ota-review-check
dsh-output-styles
dsh-paper-doc-adapter
dsh-permission-rules
dsh-permit-report-check
dsh-pipeline-check
dsh-pleading-draft
dsh-plugin-doctor
dsh-plugin-guide
dsh-plugin-kit
dsh-plugin-upgrade
dsh-policy-brief-draft
dsh-power-loss-split
dsh-power-ticket-check
dsh-ppap-check
dsh-protest-deadline
dsh-railway-window
dsh-repair-order-qc
dsh-research-report
dsh-review-reply-check
dsh-rulefile-check
dsh-safety-brief-check
dsh-score
dsh-session-sync
dsh-site-log-check
dsh-skill-pack-security
dsh-soe-decision-check
dsh-soilwater-check
dsh-sop-sync-check
dsh-spc-gbt-adapter
dsh-talk
dsh-tender-extract
dsh-tender-matrix
dsh-test-drive
dsh-ticktick
dsh-translate
dsh-warranty-calc
dsh-budget 🧊 CONGELADO — ver el README del repositorio
dsh-claude-move 🧊 CONGELADO — ver el README del repositorio
dsh-defend 🧊 CONGELADO — ver el README del repositorio
dsh-draw 🧊 CONGELADO — ver el README del repositorio
dsh-reach 🧊 CONGELADO — ver el README del repositorio
dsh-background-agents 🚫 RETIRADO — ver el README del repositorio
dsh-session-pin 🚫 RETIRADO — ver el README del repositorio
dsh-team-rooms 🚫 RETIRADO — ver el README del repositorio