@khoavu882/doflow 2.0.0-beta.5 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -16
- package/bin/doflow.js +22 -12
- package/core/.antigravity-plugin/plugin.json +1 -2
- package/core/.claude-plugin/plugin.json +1 -1
- package/core/.codex-plugin/plugin.json +1 -1
- package/core/.plugin/plugin.json +1 -1
- package/core/harnesses/claude/hooks/lib.sh +43 -24
- package/core/harnesses/claude/hooks/mcp-tool-guard.sh +4 -1
- package/core/harnesses/claude/hooks/permission-audit.sh +3 -0
- package/core/harnesses/claude/hooks/post-compact.sh +35 -32
- package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
- package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
- package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
- package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
- package/core/harnesses/claude/hooks/pre-implement-gate.sh +4 -1
- package/core/harnesses/claude/hooks/session-end.sh +23 -10
- package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
- package/core/harnesses/claude/settings/settings.json +26 -9
- package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
- package/core/harnesses/codex/agents/core-implementer.toml +1 -0
- package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
- package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
- package/core/harnesses/codex/agents/research-writer.toml +1 -1
- package/core/harnesses/codex/agents/reviewer.toml +10 -0
- package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
- package/core/harnesses/codex/agents/system-architect.toml +1 -1
- package/core/harnesses/codex/hooks/hooks.json +0 -10
- package/core/harnesses/codex/hooks/lib.sh +44 -25
- package/core/harnesses/codex/hooks/mcp-tool-guard.sh +4 -1
- package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
- package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
- package/core/harnesses/codex/hooks/pre-implement-gate.sh +4 -1
- package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
- package/core/harnesses/codex/hooks/subagent-audit.sh +1 -0
- package/core/harnesses/copilot/hooks/doflow-lib.sh +94 -0
- package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow.json +51 -0
- package/core/harnesses/kiro/agents/doflow.json +1 -11
- package/core/harnesses/kiro/hooks/doflow.json +0 -10
- package/core/harnesses/kiro/hooks/lib.sh +26 -6
- package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +8 -3
- package/core/harnesses/kiro/hooks/pre-implement-gate.sh +8 -3
- package/core/harnesses/kiro/hooks/session-start.sh +1 -0
- package/core/harnesses/kiro/hooks/stop-check.sh +1 -0
- package/core/harnesses/pi/extensions/doflow-guard.js +11 -2
- package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +1 -2
- package/core/harnesses/shared/hooks/adapters/antigravity.js +1 -1
- package/core/harnesses/shared/hooks/bridge/bridge.sh +126 -23
- package/core/harnesses/shared/hooks/bridge/envelope.jq +87 -18
- package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
- package/core/harnesses/shared/hooks/bridge/respond.sh +16 -2
- package/core/harnesses/shared/hooks/policies/capture-failure.sh +49 -16
- package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
- package/core/harnesses/shared/hooks/policies/contract.sh +3 -0
- package/core/harnesses/shared/hooks/policies/deny-json.sh +20 -7
- package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
- package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
- package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
- package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
- package/core/harnesses/shared/hooks/policies/lib.sh +63 -40
- package/core/harnesses/shared/hooks/policies/mcp-policy.conf +1 -1
- package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +7 -8
- package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +132 -57
- package/core/harnesses/shared/hooks/policies/session-context.sh +30 -1
- package/core/harnesses/shared/hooks/policies/stop-check.sh +27 -15
- package/core/harnesses/shared/hooks/policies/subagent-audit.sh +6 -3
- package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
- package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +60 -155
- package/core/harnesses/shared/hooks/stream-hook-runner.js +58 -20
- package/core/harnesses/shared/locator/doflow-run +2 -3
- package/core/registry/advice.json +3 -3
- package/core/registry/assets.json +55 -82
- package/core/registry/capabilities.json +12 -0
- package/core/registry/contracts.json +58 -31
- package/core/registry/contribution-points.json +35 -0
- package/core/registry/gates.json +32 -0
- package/core/registry/guidance-caps.json +40 -0
- package/core/registry/harnesses.json +1445 -366
- package/core/registry/intake.json +53 -0
- package/core/registry/lifecycle.json +599 -996
- package/core/registry/mcp.json +5 -1
- package/core/registry/models.json +7 -1
- package/core/registry/package-templates/README.md +19 -0
- package/core/registry/package-templates/agent/files/agent.md +9 -0
- package/core/registry/package-templates/agent/template.json +4 -0
- package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
- package/core/registry/package-templates/capability-provider/template.json +11 -0
- package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
- package/core/registry/package-templates/debate-preset/template.json +4 -0
- package/core/registry/package-templates/intake-category/files/category.json +8 -0
- package/core/registry/package-templates/intake-category/template.json +4 -0
- package/core/registry/package-templates/review-preset/files/preset.json +30 -0
- package/core/registry/package-templates/review-preset/template.json +4 -0
- package/core/registry/package-templates/skill/files/SKILL.md +8 -0
- package/core/registry/package-templates/skill/template.json +4 -0
- package/core/registry/package-templates/worker/files/worker.json +92 -0
- package/core/registry/package-templates/worker/template.json +11 -0
- package/core/registry/packages/doflow/doflow-package.json +15 -0
- package/core/registry/packages/doflow/presets/debate-3.json +26 -0
- package/core/registry/protocols.json +61 -0
- package/core/registry/routes.json +17 -0
- package/core/registry/rules.json +431 -0
- package/core/registry/settings.json +272 -0
- package/core/registry/storage.json +687 -31
- package/core/registry/telemetry.json +236 -0
- package/core/registry/transcripts.json +142 -0
- package/core/registry/verification.json +76 -6
- package/core/registry/workflows.json +55 -0
- package/core/shared/agent-specs/core-implementer.md +3 -0
- package/core/shared/agent-specs/delivery-lead.md +68 -0
- package/core/shared/agent-specs/quality-guardian.md +5 -1
- package/core/shared/agent-specs/research-writer.md +10 -3
- package/core/shared/agent-specs/reviewer.md +53 -0
- package/core/shared/agent-specs/spec-analyst.md +5 -6
- package/core/shared/agent-specs/system-architect.md +5 -1
- package/core/shared/guidance/DOFLOW_CORE.md +1 -5
- package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
- package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
- package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
- package/core/shared/guidance/pointers/codex.md +1 -4
- package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
- package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
- package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
- package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
- package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
- package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
- package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
- package/core/shared/guidance/references/ORCHESTRATION.md +3 -2
- package/core/shared/guidance/references/WORKFLOW_HANDOFF.md +19 -1
- package/core/shared/guidance/rules/RULES.md +45 -0
- package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
- package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
- package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
- package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
- package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
- package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
- package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
- package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
- package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
- package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
- package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
- package/core/shared/scripts/doflow/bash/validate-artifacts.sh +49 -5
- package/core/shared/scripts/doflow/bin/doflow-run +152 -34
- package/core/shared/skills/do/SKILL.md +14 -12
- package/core/shared/skills/do/references/advice_calls.md +26 -0
- package/core/shared/skills/do/references/pm_routing.md +1 -2
- package/core/shared/skills/do/references/program_mode.md +31 -0
- package/core/shared/skills/do-brainstorm/SKILL.md +45 -97
- package/core/shared/skills/do-brainstorm/references/handoff_branches.md +36 -0
- package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
- package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
- package/core/shared/skills/do-code-review/SKILL.md +48 -148
- package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
- package/core/shared/skills/do-code-review/references/tools.md +90 -0
- package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
- package/core/shared/skills/do-design/SKILL.md +23 -20
- package/core/shared/skills/do-diagnose/SKILL.md +18 -6
- package/core/shared/skills/do-document/SKILL.md +12 -1
- package/core/shared/skills/do-document/references/deep_research.md +1 -2
- package/core/shared/skills/do-document/references/embedded-research.md +19 -7
- package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
- package/core/shared/skills/do-execute-plan/SKILL.md +19 -60
- package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
- package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
- package/core/shared/skills/do-execute-plan/references/readiness_gate.md +26 -1
- package/core/shared/skills/do-execute-plan/references/run_position.md +16 -2
- package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
- package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
- package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
- package/core/shared/skills/do-flow/SKILL.md +10 -11
- package/core/shared/skills/do-flow/references/task_classes.md +5 -5
- package/core/shared/skills/do-git/SKILL.md +4 -0
- package/core/shared/skills/do-implement/SKILL.md +13 -14
- package/core/shared/skills/do-plan/SKILL.md +34 -20
- package/core/shared/skills/do-test/SKILL.md +7 -4
- package/core/shared/templates/doflow/constitution-template.md +9 -3
- package/core/shared/templates/doflow/data-model-template.md +1 -1
- package/core/shared/templates/doflow/design-template.md +113 -16
- package/core/shared/templates/doflow/plan-template.md +11 -10
- package/core/shared/templates/doflow/question-log-template.md +14 -2
- package/core/shared/templates/doflow/requirement-template.md +1 -1
- package/core/shared/workflows/do-flow-chain.md +2 -0
- package/core/worker-evidence/antigravity/checks.json +14 -0
- package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
- package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
- package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
- package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
- package/core/worker-evidence/codex/checks.json +38 -0
- package/package.json +10 -6
- package/src/adapters/antigravity/index.js +143 -66
- package/src/adapters/claude/index.js +46 -5
- package/src/adapters/codex/agents.js +25 -15
- package/src/adapters/codex/hooks.js +39 -3
- package/src/adapters/codex/index.js +61 -13
- package/src/adapters/codex/native-projection.js +6 -2
- package/src/adapters/copilot/index.js +58 -23
- package/src/adapters/copy-tree.js +291 -46
- package/src/adapters/guidance-manifest.js +71 -0
- package/src/adapters/guidance-pointer.js +19 -0
- package/src/adapters/hook-commands.js +6 -10
- package/src/adapters/index.js +1 -0
- package/src/adapters/kiro/index.js +23 -12
- package/src/adapters/opencode/index.js +8 -8
- package/src/adapters/pi/hooks.js +2 -1
- package/src/adapters/pi/index.js +14 -7
- package/src/adapters/resolve-source.js +26 -2
- package/src/cli/commands/install.js +2 -1
- package/src/cli/commands/reconcile.js +53 -9
- package/src/cli/commands/remove.js +2 -2
- package/src/cli/commands/rollback.js +6 -3
- package/src/cli/commands/self-update.js +18 -9
- package/src/cli/commands/status.js +22 -3
- package/src/cli/commands/ui.js +99 -0
- package/src/cli/commands/update.js +2 -1
- package/src/cli/index.js +337 -32
- package/src/cli/runtime-commands.js +220 -60
- package/src/cli/shared.js +0 -2
- package/src/helper/git.js +1 -1
- package/src/helper/guardrails.js +1 -1
- package/src/helper/marker-merge.js +31 -13
- package/src/helper/package-ids.js +37 -0
- package/src/helper/semver.js +94 -0
- package/src/install/backup.js +105 -15
- package/src/install/context.js +1 -1
- package/src/install/targets.js +31 -16
- package/src/lifecycle/coverage.js +4 -16
- package/src/lifecycle/hook-tier.js +160 -0
- package/src/lifecycle/index.js +412 -78
- package/src/lifecycle/retired-harnesses.js +318 -0
- package/src/lifecycle/view.js +35 -15
- package/src/registry/index.js +551 -26
- package/src/registry/worker-ids.js +45 -0
- package/src/release/build-package.js +0 -3
- package/src/release/docs-blocks.js +472 -0
- package/src/release/preflight.js +425 -0
- package/src/release/rehearse.js +401 -0
- package/src/release/release-workflow.js +733 -0
- package/src/release/sync-plugin-versions.js +43 -7
- package/src/runtime/advice/bench-gate.js +25 -0
- package/src/runtime/advice/cli.js +59 -16
- package/src/runtime/advice/client.js +32 -9
- package/src/runtime/advice/config.js +98 -133
- package/src/runtime/advice/doctor.js +1 -1
- package/src/runtime/advice/elevation.js +97 -0
- package/src/runtime/advice/endpoint-guard.js +9 -3
- package/src/runtime/advice/mode.js +37 -0
- package/src/runtime/advice/record.js +18 -5
- package/src/runtime/advice/registry.js +4 -1
- package/src/runtime/advice/shadow-config.js +229 -0
- package/src/runtime/advice/shadow-dispatcher.js +276 -0
- package/src/runtime/brief-rules.js +81 -0
- package/src/runtime/brief-tools.js +111 -34
- package/src/runtime/candidate.js +20 -11
- package/src/runtime/capabilities/executor.js +450 -0
- package/src/runtime/capabilities/loopback.js +41 -0
- package/src/runtime/capabilities/sanitizer.js +88 -0
- package/src/runtime/capability-router.js +135 -3
- package/src/runtime/checkouts.js +73 -11
- package/src/runtime/claims.js +13 -7
- package/src/runtime/cli.js +196 -19
- package/src/runtime/config-home.js +42 -0
- package/src/runtime/context/arbitrate.js +767 -0
- package/src/runtime/context/delivery-store.js +4 -6
- package/src/runtime/context/emission-rules.js +118 -0
- package/src/runtime/context/identity.js +227 -0
- package/src/runtime/context/pointer.js +67 -12
- package/src/runtime/context/primary-command.js +117 -0
- package/src/runtime/context/primary.js +344 -0
- package/src/runtime/context/summary-store.js +655 -0
- package/src/runtime/context-pack.js +158 -79
- package/src/runtime/decision-register.js +13 -4
- package/src/runtime/dispatch/admission.js +392 -0
- package/src/runtime/dispatch/attempt-end.js +274 -0
- package/src/runtime/dispatch/command.js +628 -0
- package/src/runtime/dispatch/controls.js +904 -0
- package/src/runtime/dispatch/envelope.js +276 -0
- package/src/runtime/dispatch/grants.js +310 -0
- package/src/runtime/dispatch/integrate.js +617 -0
- package/src/runtime/dispatch/loop.js +1835 -0
- package/src/runtime/dispatch/store.js +352 -0
- package/src/runtime/dispatch/verify-run.js +201 -0
- package/src/runtime/evidence-ledger.js +52 -7
- package/src/runtime/failure/capture.js +3 -1
- package/src/runtime/failure/cli.js +25 -9
- package/src/runtime/failure/home.js +57 -30
- package/src/runtime/failure/store.js +7 -2
- package/src/runtime/feature-pointer.js +174 -0
- package/src/runtime/feature-resolve.js +13 -2
- package/src/runtime/fleet/command.js +77 -0
- package/src/runtime/fleet/projects.js +178 -0
- package/src/runtime/fleet/tree.js +383 -0
- package/src/runtime/freshness.js +33 -3
- package/src/runtime/git-memo.js +46 -0
- package/src/runtime/guidance/ablation.js +427 -0
- package/src/runtime/health.js +624 -18
- package/src/runtime/history-compactor.js +13 -3
- package/src/runtime/implementation-gate.js +281 -26
- package/src/runtime/intake/engine.js +677 -0
- package/src/runtime/intake/index.js +136 -0
- package/src/runtime/intake/manifest.js +140 -0
- package/src/runtime/intake/taxonomy.js +206 -0
- package/src/runtime/inventory/coverage.js +1 -1
- package/src/runtime/inventory/index.js +1 -1
- package/src/runtime/inventory/precedence.js +2 -2
- package/src/runtime/inventory/siblings.js +6 -4
- package/src/runtime/knowledge/code-corpus.js +277 -0
- package/src/runtime/knowledge/code-lexical.js +130 -0
- package/src/runtime/knowledge/code-retrieval.js +307 -0
- package/src/runtime/knowledge/code-validation.js +106 -0
- package/src/runtime/knowledge/gp3-gate.js +74 -0
- package/src/runtime/knowledge/graph-adapter.js +288 -0
- package/src/runtime/knowledge/graph-fallback.js +394 -0
- package/src/runtime/knowledge/hybrid.js +136 -8
- package/src/runtime/knowledge/retrieval.js +34 -1
- package/src/runtime/knowledge/rtk-compress.js +77 -0
- package/src/runtime/knowledge/semble-bridge.py +106 -0
- package/src/runtime/knowledge/semble-lifecycle.js +114 -0
- package/src/runtime/knowledge/semble-provider.js +365 -0
- package/src/runtime/lifecycle/cli.js +88 -10
- package/src/runtime/lifecycle/event-store.js +8 -6
- package/src/runtime/lifecycle/followup.js +38 -7
- package/src/runtime/lifecycle/overview.js +26 -2
- package/src/runtime/lifecycle/report-store.js +8 -10
- package/src/runtime/lifecycle/retention.js +95 -31
- package/src/runtime/lifecycle/root.js +9 -1
- package/src/runtime/lifecycle/status.js +34 -17
- package/src/runtime/lifecycle/store-upkeep.js +56 -7
- package/src/runtime/mask.js +134 -7
- package/src/runtime/mcp-consultations.js +40 -6
- package/src/runtime/model-router.js +79 -7
- package/src/runtime/models/catalogue.js +191 -0
- package/src/runtime/models/command.js +153 -0
- package/src/runtime/off-words.js +12 -0
- package/src/runtime/outcome.js +2 -2
- package/src/runtime/packages/command.js +1009 -0
- package/src/runtime/packages/contributions.js +116 -0
- package/src/runtime/packages/digest.js +132 -0
- package/src/runtime/packages/fetch.js +182 -0
- package/src/runtime/packages/grants.js +192 -0
- package/src/runtime/packages/index-file.js +134 -0
- package/src/runtime/packages/instruction.js +90 -0
- package/src/runtime/packages/manifest.js +331 -0
- package/src/runtime/packages/points.js +487 -0
- package/src/runtime/packages/programs.js +216 -0
- package/src/runtime/packages/scaffold.js +277 -0
- package/src/runtime/packages/source.js +90 -0
- package/src/runtime/packages/state.js +164 -0
- package/src/runtime/packages/store.js +449 -0
- package/src/runtime/packages/tar.js +106 -0
- package/src/runtime/packages/view.js +406 -0
- package/src/runtime/plan-check.js +59 -0
- package/src/runtime/plan-content.js +324 -0
- package/src/runtime/policy-init.js +118 -0
- package/src/runtime/profiles/doctor.js +96 -0
- package/src/runtime/profiles/resolve.js +244 -0
- package/src/runtime/profiles/rollback.js +254 -0
- package/src/runtime/profiles/sampler.js +41 -0
- package/src/runtime/readiness-record.js +16 -11
- package/src/runtime/readiness.js +46 -5
- package/src/runtime/research-request.js +50 -25
- package/src/runtime/retrieval-plan.js +10 -30
- package/src/runtime/retrieval-record.js +75 -5
- package/src/runtime/review/command.js +246 -0
- package/src/runtime/review/dominance.js +68 -0
- package/src/runtime/review/findings.js +434 -0
- package/src/runtime/review/identity.js +255 -0
- package/src/runtime/review/protocol-command.js +109 -0
- package/src/runtime/review/protocols.js +405 -0
- package/src/runtime/review/resolve-protocol.js +302 -0
- package/src/runtime/review/start.js +530 -0
- package/src/runtime/roadmap/attendance.js +137 -0
- package/src/runtime/roadmap/facts.js +479 -0
- package/src/runtime/roadmap/gates.js +273 -0
- package/src/runtime/roadmap/loop.js +1719 -0
- package/src/runtime/roadmap/merge.js +390 -0
- package/src/runtime/roadmap/rows.js +1122 -0
- package/src/runtime/roadmap/seed.js +1063 -0
- package/src/runtime/roadmap/worktree-cleanup.js +147 -0
- package/src/runtime/rules-report.js +336 -0
- package/src/runtime/scaffold/artifacts.js +60 -9
- package/src/runtime/scaffold/generate.js +21 -9
- package/src/runtime/settings/autopilot.js +106 -0
- package/src/runtime/settings/cli.js +280 -0
- package/src/runtime/settings/config-write.js +314 -0
- package/src/runtime/settings/files.js +271 -0
- package/src/runtime/settings/legacy.js +154 -0
- package/src/runtime/settings/lexical.js +56 -0
- package/src/runtime/settings/prepared-run.js +269 -0
- package/src/runtime/settings/project-layers.js +118 -0
- package/src/runtime/settings/refs.js +288 -0
- package/src/runtime/settings/registry.js +553 -0
- package/src/runtime/settings/resolve.js +713 -0
- package/src/runtime/settings/shared.js +37 -0
- package/src/runtime/settings/worker-billing.js +107 -0
- package/src/runtime/settings/write.js +269 -0
- package/src/runtime/slot-command.js +78 -0
- package/src/runtime/slots.js +671 -0
- package/src/runtime/source-version.js +1 -0
- package/src/runtime/state-root.js +217 -0
- package/src/runtime/storage/cli.js +12 -5
- package/src/runtime/storage/engine.js +9 -2
- package/src/runtime/storage/registry.js +14 -1
- package/src/runtime/storage/roots.js +66 -16
- package/src/runtime/storage/rules.js +82 -10
- package/src/runtime/storage/upkeep.js +10 -2
- package/src/runtime/storage/work-status.js +245 -26
- package/src/runtime/task-attempts.js +589 -69
- package/src/runtime/task-classifier.js +85 -14
- package/src/runtime/task-graph.js +373 -0
- package/src/runtime/task-run.js +778 -0
- package/src/runtime/task-scope.js +176 -55
- package/src/runtime/task-sources.js +147 -0
- package/src/runtime/task-state.js +373 -64
- package/src/runtime/team/admission.js +301 -0
- package/src/runtime/team/envelope.js +324 -0
- package/src/runtime/team/review-guard.js +156 -0
- package/src/runtime/trace/analyze.js +427 -0
- package/src/runtime/trace/baseline.js +770 -0
- package/src/runtime/trace/ledger.js +63 -140
- package/src/runtime/trace/otlp-export.js +568 -0
- package/src/runtime/trace/otlp-map.js +481 -0
- package/src/runtime/trace/spans.js +745 -0
- package/src/runtime/trace/telemetry.js +225 -0
- package/src/runtime/trace/views.js +1 -0
- package/src/runtime/transcripts/command.js +98 -0
- package/src/runtime/transcripts/cursor.js +326 -0
- package/src/runtime/transcripts/read.js +126 -0
- package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
- package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
- package/src/runtime/transcripts/readers/copilot-events.js +90 -0
- package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
- package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
- package/src/runtime/transcripts/registry.js +161 -0
- package/src/runtime/transcripts/stats.js +161 -0
- package/src/runtime/verb-view.js +267 -0
- package/src/runtime/verification/check-key.js +628 -0
- package/src/runtime/verification/contract-runner.js +546 -11
- package/src/runtime/verification/engine.js +499 -54
- package/src/runtime/verification/impact.js +617 -0
- package/src/runtime/verification/inflight.js +205 -0
- package/src/runtime/verification/registry.js +176 -0
- package/src/runtime/verification/reuse.js +184 -0
- package/src/runtime/verification/telemetry-emit.js +254 -0
- package/src/runtime/verification/test-selection.js +67 -7
- package/src/runtime/worker/active.js +90 -0
- package/src/runtime/worker/cancel.js +222 -0
- package/src/runtime/worker/catalogue.js +122 -0
- package/src/runtime/worker/command.js +677 -0
- package/src/runtime/worker/evidence.js +288 -0
- package/src/runtime/worker/launch.js +256 -0
- package/src/runtime/worker/models.js +137 -0
- package/src/runtime/worker/parsers.js +218 -0
- package/src/runtime/worker/probes/index.js +706 -0
- package/src/runtime/worker/process-tree.js +415 -0
- package/src/runtime/worker/quota.js +43 -0
- package/src/runtime/worker/readiness.js +713 -0
- package/src/runtime/worker/run-store.js +166 -0
- package/src/runtime/worker/supervisor.js +541 -0
- package/src/runtime/worker/worktree-check.js +252 -0
- package/src/runtime/workflow-engine.js +5 -1
- package/src/runtime/workflow-orchestrator.js +610 -67
- package/src/runtime/worktree.js +149 -22
- package/src/state/index.js +1 -1
- package/src/state/lockfile.js +64 -10
- package/src/state/run-lock.js +1 -1
- package/types/node-commonjs.d.ts +106 -7
- package/core/harnesses/claude/hooks/pre-bash-guard.sh +0 -10
- package/core/harnesses/codex/hooks/pre-bash-guard.sh +0 -10
- package/core/harnesses/gemini/hooks/hooks.json +0 -77
- package/core/harnesses/gemini/hooks/lib.sh +0 -302
- package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -10
- package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
- package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -10
- package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
- package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -10
- package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
- package/core/harnesses/gemini/hooks/session-end.sh +0 -5
- package/core/harnesses/gemini/hooks/session-start.sh +0 -7
- package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
- package/core/harnesses/kiro/hooks/pre-bash-guard.sh +0 -24
- package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +0 -91
- package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +0 -378
- package/core/shared/guidance/FLAGS.md +0 -25
- package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
- package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
- package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
- package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
- package/src/adapters/gemini/hooks.js +0 -251
- package/src/adapters/gemini/index.js +0 -429
package/src/runtime/cli.js
CHANGED
|
@@ -9,12 +9,14 @@ const { CapabilityRouter } = require('./capability-router.js');
|
|
|
9
9
|
const { EvidenceLedger } = require('./evidence-ledger.js');
|
|
10
10
|
const { ClaimsManager } = require('./claims.js');
|
|
11
11
|
const { measureTreeState } = require('./source-version.js');
|
|
12
|
-
const {
|
|
12
|
+
const { fileRootFor } = require('./freshness.js');
|
|
13
|
+
const { toEvidence, parseLocator, validateEvidenceItem, EVIDENCE_REFUSED_FIELDS } = require('./candidate.js');
|
|
13
14
|
const { sourceModeLookup } = require('./retrieval-plan.js');
|
|
14
15
|
const { evaluateTaskReadiness } = require('./readiness.js');
|
|
15
|
-
const { writeReadinessRecord } = require('./readiness-record.js');
|
|
16
|
+
const { writeReadinessRecord, readReadinessRecord } = require('./readiness-record.js');
|
|
17
|
+
const { resolveTaskScope } = require('./task-scope.js');
|
|
16
18
|
const { parseDeclaredScope } = require('./verification/scope-bound.js');
|
|
17
|
-
const { loadRegistry } = require('../registry/index.js');
|
|
19
|
+
const { loadRegistry, agentToolScopeView } = require('../registry/index.js');
|
|
18
20
|
const { REPO_ROOT } = require('../helper/repo-root.js');
|
|
19
21
|
// One definition of the exit and usage helpers (design §4.2); `finish` is the local spelling of `finishRuntime`.
|
|
20
22
|
const { finishRuntime: finish, usageError } = require('./cli-result.js');
|
|
@@ -30,9 +32,10 @@ function handleCapabilitiesCommand({ json = false, check = false, repoRoot }
|
|
|
30
32
|
const root = repoRoot || REPO_ROOT;
|
|
31
33
|
const router = new CapabilityRouter({ repoRoot: root });
|
|
32
34
|
const report = router.getAllCapabilitiesHealth(check);
|
|
35
|
+
const agentToolScope = agentToolScopeView(loadRegistry({ repoRoot: root, sources: 'skip' }));
|
|
33
36
|
|
|
34
37
|
if (json) {
|
|
35
|
-
console.log(JSON.stringify({ capabilities: report }, null, 2));
|
|
38
|
+
console.log(JSON.stringify({ capabilities: report, agentToolScope }, null, 2));
|
|
36
39
|
return;
|
|
37
40
|
}
|
|
38
41
|
|
|
@@ -60,7 +63,36 @@ function handleCapabilitiesCommand({ json = false, check = false, repoRoot }
|
|
|
60
63
|
);
|
|
61
64
|
}
|
|
62
65
|
console.log('═'.repeat(78));
|
|
63
|
-
console.log(`Mode: ${check ? 'Deep Smoke Check' : 'Fast Presence Check'} · Total Capabilities: ${report.length}
|
|
66
|
+
console.log(`Mode: ${check ? 'Deep Smoke Check' : 'Fast Presence Check'} · Total Capabilities: ${report.length}`);
|
|
67
|
+
console.log('\nAgent tool scope per harness (unenforced: no tool field is projected):');
|
|
68
|
+
for (const row of agentToolScope) console.log(` ${row.harness.padEnd(14)}${row.status === 'native' ? `native ${row.field}` : `unenforced ${row.reason}`}`);
|
|
69
|
+
console.log('');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Fills `profile` with the caller-stated inputs the task's last readiness record for this template
|
|
74
|
+
* holds and this call did not pass. Returns the profile keys it filled.
|
|
75
|
+
* @returns {Array<string>}
|
|
76
|
+
*/
|
|
77
|
+
function carriedInputs({ profile, taskClass, taskId, slug, state } ) {
|
|
78
|
+
const keyOf = { verificationPlan: 'verificationPlan', scope: 'scopeClear', invariants: 'invariants' };
|
|
79
|
+
let prior = null;
|
|
80
|
+
try {
|
|
81
|
+
const scope = resolveTaskScope({ projectRoot: state, taskId, slug });
|
|
82
|
+
const read = readReadinessRecord({ stateRoot: state, taskId, slug: scope.slug || slug || null });
|
|
83
|
+
if (read.status === 'found' && read.record && read.record.taskClass === taskClass) prior = read.record;
|
|
84
|
+
} catch {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
const filled = [];
|
|
88
|
+
for (const [inputKey, profileKey] of Object.entries(keyOf)) {
|
|
89
|
+
const value = prior && prior.inputs && prior.inputs[inputKey];
|
|
90
|
+
if (profile[profileKey ] === undefined && typeof value === 'string' && value.trim() !== '') {
|
|
91
|
+
profile[profileKey ] = value;
|
|
92
|
+
filled.push(profileKey );
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return filled;
|
|
64
96
|
}
|
|
65
97
|
|
|
66
98
|
/**
|
|
@@ -107,11 +139,16 @@ function handleReadinessCommand({
|
|
|
107
139
|
if (typeof scopeClear === 'string' && scopeClear.trim() !== '') profile.scopeClear = scopeClear;
|
|
108
140
|
if (typeof invariants === 'string' && invariants.trim() !== '') profile.invariants = invariants;
|
|
109
141
|
if (userDecisionPending) profile.userDecisionPending = true;
|
|
142
|
+
// An input not passed this call is the one the task's last evaluation for this template stated, so
|
|
143
|
+
// a bare re-check after evidence changes does not discard the scope and plan a READY verdict rested
|
|
144
|
+
// on. Passing an input replaces it. Ceiling: an input can be replaced but not dropped, and
|
|
145
|
+
// `--user-decision-pending` is never carried.
|
|
146
|
+
const carried = carriedInputs({ profile, taskClass, taskId, slug, state });
|
|
110
147
|
const callerAsserted = Object.keys(profile).filter((k) => k !== 'taskId' && k !== 'taskClass');
|
|
111
148
|
|
|
112
149
|
let report;
|
|
113
150
|
try {
|
|
114
|
-
report = evaluateTaskReadiness({ taskProfile: profile, repoRoot: root, projectRoot: state, treeRoot: sourceRoot || state, mode });
|
|
151
|
+
report = evaluateTaskReadiness({ taskProfile: profile, repoRoot: root, projectRoot: state, treeRoot: sourceRoot || state, sourceRoot: sourceRoot || state, mode });
|
|
115
152
|
} catch (error ) {
|
|
116
153
|
return usageError('readiness', error.message, json, error);
|
|
117
154
|
}
|
|
@@ -139,7 +176,7 @@ function handleReadinessCommand({
|
|
|
139
176
|
};
|
|
140
177
|
|
|
141
178
|
if (json) {
|
|
142
|
-
console.log(JSON.stringify({ ...report, callerAsserted, record: recorded, declaredScope }, null, 2));
|
|
179
|
+
console.log(JSON.stringify({ ...report, callerAsserted, carriedFromLastRecord: carried, record: recorded, declaredScope }, null, 2));
|
|
143
180
|
reportNotRecorded();
|
|
144
181
|
return finish(exitCode);
|
|
145
182
|
}
|
|
@@ -164,6 +201,7 @@ function handleReadinessCommand({
|
|
|
164
201
|
// Named, not hidden: these requirements were satisfied because the caller said so, and a
|
|
165
202
|
// verdict that mixes measured and stated inputs must say which is which.
|
|
166
203
|
console.log(`Caller-stated: ${callerAsserted.join(', ')} (asserted on the command line, not established by evidence)`);
|
|
204
|
+
if (carried.length > 0) console.log(`Carried: ${carried.join(', ')} (stated by the last evaluation of this task; pass the flag to replace it)`);
|
|
167
205
|
}
|
|
168
206
|
console.log('─'.repeat(70));
|
|
169
207
|
console.log('Requirements Breakdown:');
|
|
@@ -241,6 +279,30 @@ function readEvidenceBatch(batchPath , taskId , root , slug = n
|
|
|
241
279
|
throw new Error('a batch must be a JSON array of evidence items, or an object with an `evidence` array');
|
|
242
280
|
}
|
|
243
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Refuses an evidence item whose file locator names a directory, whatever its provenance: a locator
|
|
284
|
+
* points into a file. An absence item has no locator, and a locator that does not parse is left to
|
|
285
|
+
* `toEvidence`, which names what is wrong with it.
|
|
286
|
+
* @throws {Error} naming the locator
|
|
287
|
+
*/
|
|
288
|
+
function refuseDirectoryLocator(raw , sourceRoot , root ) {
|
|
289
|
+
if (!raw || typeof raw !== 'object' || raw.absence || raw.locator === undefined) return;
|
|
290
|
+
let locator;
|
|
291
|
+
try {
|
|
292
|
+
locator = parseLocator(raw.locator);
|
|
293
|
+
} catch {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
if (!locator.file) return;
|
|
297
|
+
let isDirectory = false;
|
|
298
|
+
try {
|
|
299
|
+
isDirectory = fs.statSync(path.resolve(fileRootFor(sourceRoot, root, locator), locator.file)).isDirectory();
|
|
300
|
+
} catch { /* missing or unreadable: the resolver judges that */ }
|
|
301
|
+
if (isDirectory) {
|
|
302
|
+
throw new Error(`the locator '${locator.file}' is a directory, and a directory is not a valid locator; name a file (path[:line])`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
244
306
|
/**
|
|
245
307
|
* The `--action add` arm: validate the whole batch, then write it.
|
|
246
308
|
* @returns {number} exit code
|
|
@@ -268,10 +330,8 @@ function addEvidence({ ledger, root, sourceRoot = root, attemptRoot, taskId, ite
|
|
|
268
330
|
|
|
269
331
|
// The whole batch is validated before any of it is written. A half-written stage batch is worse
|
|
270
332
|
// than a rejected one: the half that landed looks complete to every later reader.
|
|
271
|
-
|
|
272
|
-
const
|
|
273
|
-
const absenceTreeState = hasAbsence && path.resolve(sourceRoot) !== path.resolve(root)
|
|
274
|
-
? measureTreeState(sourceRoot) : null;
|
|
333
|
+
// The tree observed is the checkout the verb runs in (115 IC-007), one measurement for every item.
|
|
334
|
+
const treeState = measureTreeState(sourceRoot);
|
|
275
335
|
const providerFreshness = new Map();
|
|
276
336
|
let sourceModeOf = null;
|
|
277
337
|
const validated = [];
|
|
@@ -280,7 +340,8 @@ function addEvidence({ ledger, root, sourceRoot = root, attemptRoot, taskId, ite
|
|
|
280
340
|
if (raw && raw.absence && !sourceModeOf) {
|
|
281
341
|
sourceModeOf = sourceModeLookup(new CapabilityRouter({ repoRoot: REPO_ROOT }).capabilities);
|
|
282
342
|
}
|
|
283
|
-
|
|
343
|
+
refuseDirectoryLocator(raw, sourceRoot, root);
|
|
344
|
+
validated.push(toEvidence({ item: raw }, { taskId, root, treeState, probeRoot: sourceRoot, sourceRoot, attemptRoot, slug, providerFreshness, sourceModeOf }));
|
|
284
345
|
} catch (error ) {
|
|
285
346
|
const where = raws.length > 1 ? `batch item ${index + 1} of ${raws.length}: ` : '';
|
|
286
347
|
return usageError('evidence', `${where}${error.message}`, json, error);
|
|
@@ -318,8 +379,7 @@ function addEvidence({ ledger, root, sourceRoot = root, attemptRoot, taskId, ite
|
|
|
318
379
|
}
|
|
319
380
|
console.log('─'.repeat(78));
|
|
320
381
|
console.log(`Wrote ${written.length} item(s) to ${stateFile}`);
|
|
321
|
-
|
|
322
|
-
console.log(`Commit at observation: ${observedTree.gitCommit || (observedTree.prefix !== null ? 'not measured' : 'not a git worktree — freshness cannot expire by diff')}`);
|
|
382
|
+
console.log(`Commit at observation: ${treeState.gitCommit || (treeState.prefix !== null ? 'not measured' : 'not a git worktree — freshness cannot expire by diff')}`);
|
|
323
383
|
console.log('═'.repeat(78) + '\n');
|
|
324
384
|
return finish(0);
|
|
325
385
|
}
|
|
@@ -361,28 +421,69 @@ function supersedeEvidence({ ledger, taskId, evidenceId, replacedBy, json }
|
|
|
361
421
|
return finish(0);
|
|
362
422
|
}
|
|
363
423
|
|
|
424
|
+
/**
|
|
425
|
+
* The `--action retire --stale` arm: retire every active item the ledger classes stale right now,
|
|
426
|
+
* judged the way readiness judges them (the tree the verb runs in). Items are retired without a
|
|
427
|
+
* replacement and the reason is recorded on each; fresh items are not touched.
|
|
428
|
+
* @returns {number} exit code
|
|
429
|
+
*/
|
|
430
|
+
function retireStaleEvidence({ ledger, root, sourceRoot, taskId, slug, stale, json } ) {
|
|
431
|
+
if (!stale) {
|
|
432
|
+
return usageError('evidence', '--action retire retires every stale item and needs --stale; '
|
|
433
|
+
+ 'to retire one item, point it at its replacement with --action supersede', json);
|
|
434
|
+
}
|
|
435
|
+
// Staleness is derived, never stored by a read: classify on a separate copy so the ledger being
|
|
436
|
+
// saved changes only the items retired here.
|
|
437
|
+
const { FreshnessValidator } = require('./freshness.js');
|
|
438
|
+
const probe = new EvidenceLedger({ repoRoot: root, slug });
|
|
439
|
+
let retired ;
|
|
440
|
+
try {
|
|
441
|
+
probe.load(taskId);
|
|
442
|
+
new FreshnessValidator({ repoRoot: root, treeRoot: sourceRoot, sourceRoot }).validateLedgerFreshness(probe);
|
|
443
|
+
const staleItems = probe.getAllEvidence().filter((item ) => item.taskId === taskId
|
|
444
|
+
&& item.freshness?.status === 'STALE' && item.status !== 'superseded');
|
|
445
|
+
for (const item of staleItems) {
|
|
446
|
+
ledger.retireEvidence(item.id, `stale: ${item.freshness.staleReason || 'marked stale'}`);
|
|
447
|
+
}
|
|
448
|
+
retired = staleItems.map((item ) => ledger.getEvidence(item.id));
|
|
449
|
+
if (retired.length > 0) ledger.save(taskId);
|
|
450
|
+
} catch (error ) {
|
|
451
|
+
return usageError('evidence', error.message, json, error);
|
|
452
|
+
}
|
|
453
|
+
const ids = retired.map((item ) => item.id);
|
|
454
|
+
if (json) {
|
|
455
|
+
console.log(JSON.stringify({ action: 'retire', taskId, retired: ids.length, ids, evidence: retired }, null, 2));
|
|
456
|
+
return finish(0);
|
|
457
|
+
}
|
|
458
|
+
console.log(ids.length === 0
|
|
459
|
+
? `Evidence [Task: ${taskId}]: no stale items to retire.`
|
|
460
|
+
: `Evidence [Task: ${taskId}]: retired ${ids.length} stale item(s):\n${retired.map((item ) => ` ${item.id} ${item.retiredReason}`).join('\n')}`);
|
|
461
|
+
return finish(0);
|
|
462
|
+
}
|
|
463
|
+
|
|
364
464
|
/**
|
|
365
465
|
* Handles `doflow evidence` — record a stage's evidence batch, retire a stale item, or query
|
|
366
466
|
* what is recorded.
|
|
367
467
|
*
|
|
368
468
|
* @param {Object} options
|
|
369
469
|
* @param {string} [options.taskId='default']
|
|
370
|
-
* @param {'list'|'status'|'add'|'supersede'} [options.action='list']
|
|
470
|
+
* @param {'list'|'status'|'add'|'supersede'|'retire'} [options.action='list']
|
|
371
471
|
* @param {Object} [options.item] single-item write, assembled from flags by bin/doflow.js
|
|
372
472
|
* @param {string} [options.batchPath] `add`: a JSON batch file, or `-` for stdin
|
|
373
473
|
* @param {string} [options.evidenceId] `supersede`: the item to retire
|
|
374
474
|
* @param {string} [options.replacedBy] `supersede`: the item that replaces it
|
|
475
|
+
* @param {boolean} [options.stale] `retire`: retire every item the ledger classes stale
|
|
375
476
|
* @param {boolean} [options.json=false]
|
|
376
477
|
* @param {string} [options.repoRoot]
|
|
377
478
|
* @param {string} [options.stateRoot]
|
|
378
479
|
* @returns {number} exit code
|
|
379
480
|
*/
|
|
380
|
-
function handleEvidenceCommand({ taskId = 'default', action = 'list', item = null, batchPath = null, evidenceId = null, replacedBy = null, json = false, repoRoot, stateRoot, sourceRoot, attemptRoot, slug = null } = {}) {
|
|
481
|
+
function handleEvidenceCommand({ taskId = 'default', action = 'list', item = null, batchPath = null, evidenceId = null, replacedBy = null, stale = false, json = false, repoRoot, stateRoot, sourceRoot, attemptRoot, slug = null } = {}) {
|
|
381
482
|
// See handleReadinessCommand: evidence is the caller's project state, not DoFlow package state.
|
|
382
483
|
const root = stateRoot || repoRoot || process.cwd();
|
|
383
484
|
const isQuery = action === 'list' || action === 'status';
|
|
384
|
-
if (!isQuery && action !== 'add' && action !== 'supersede') {
|
|
385
|
-
return usageError('evidence', `unknown --action '${action}'. Valid: list, add, supersede`, json);
|
|
485
|
+
if (!isQuery && action !== 'add' && action !== 'supersede' && action !== 'retire') {
|
|
486
|
+
return usageError('evidence', `unknown --action '${action}'. Valid: list, add, supersede, retire`, json);
|
|
386
487
|
}
|
|
387
488
|
// A write argument on a read action is the defect this verb was reported for: it used to accept
|
|
388
489
|
// append-shaped flags, ignore them, and print the (unchanged) ledger as if the write had landed.
|
|
@@ -390,7 +491,7 @@ function handleEvidenceCommand({ taskId = 'default', action = 'list', item = nul
|
|
|
390
491
|
return usageError('evidence', 'these are write arguments and this action only reads — re-run with --action add', json);
|
|
391
492
|
}
|
|
392
493
|
|
|
393
|
-
const ledger = new EvidenceLedger({ repoRoot: root });
|
|
494
|
+
const ledger = new EvidenceLedger({ repoRoot: root, slug });
|
|
394
495
|
try {
|
|
395
496
|
ledger.load(taskId);
|
|
396
497
|
} catch (error ) {
|
|
@@ -399,6 +500,7 @@ function handleEvidenceCommand({ taskId = 'default', action = 'list', item = nul
|
|
|
399
500
|
|
|
400
501
|
if (action === 'add') return addEvidence({ ledger, root, sourceRoot: sourceRoot || root, attemptRoot, taskId, item, batchPath, json, slug });
|
|
401
502
|
if (action === 'supersede') return supersedeEvidence({ ledger, taskId, evidenceId, replacedBy, json });
|
|
503
|
+
if (action === 'retire') return retireStaleEvidence({ ledger, root, sourceRoot: sourceRoot || root, taskId, slug, stale, json });
|
|
402
504
|
|
|
403
505
|
const items = ledger.queryEvidence({ taskId });
|
|
404
506
|
|
|
@@ -428,10 +530,85 @@ function handleEvidenceCommand({ taskId = 'default', action = 'list', item = nul
|
|
|
428
530
|
return finish(0);
|
|
429
531
|
}
|
|
430
532
|
|
|
533
|
+
const EMIT_NUDGES = ['nudge', 'suppress', 'none'];
|
|
534
|
+
const EMIT_MAX_BYTES = /^[1-9][0-9]{0,9}$/;
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* 078 IC-005: `doflow-run context-emit`, a thin wrapper over emitContext(). Identity is read from
|
|
538
|
+
* the environment alone (IC-007); no flag sets it. Exits 0 emitted or silent, 2 usage (including a
|
|
539
|
+
* launch without a launched identity, or an invalid identity value), 3 refused.
|
|
540
|
+
*/
|
|
541
|
+
function handleContextEmitCommand({ event, cwd, session, harness, nudge, maxBytes, taskId, slug, stateRoot, peek = false, json = false, env = process.env } = {}) {
|
|
542
|
+
// Required on use: context-pack.ts loads the whole pack compiler, which no other verb here needs.
|
|
543
|
+
const { emitContext } = require('./context-pack.js');
|
|
544
|
+
const { resolveIdentity } = require('./context/identity.js');
|
|
545
|
+
if (typeof cwd !== 'string' || cwd === '') return usageError('context-emit', '--cwd <dir> is required', json);
|
|
546
|
+
const dir = path.resolve(cwd);
|
|
547
|
+
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) return usageError('context-emit', `--cwd '${cwd}' is not a directory`, json);
|
|
548
|
+
if (nudge !== undefined && !EMIT_NUDGES.includes(nudge)) return usageError('context-emit', `--nudge must be one of ${EMIT_NUDGES.join(', ')}`, json);
|
|
549
|
+
if (maxBytes !== undefined && !EMIT_MAX_BYTES.test(String(maxBytes))) return usageError('context-emit', '--max-bytes must be a positive integer', json);
|
|
550
|
+
const sessionId = typeof session === 'string' ? session : '';
|
|
551
|
+
const identity = resolveIdentity(env, { cwd: dir, sessionId });
|
|
552
|
+
if (identity.diagnostics.includes('identity-invalid')) {
|
|
553
|
+
return usageError('context-emit', 'DOFLOW_RUN_ID or DOFLOW_LINEAGE_ID holds an invalid value', json);
|
|
554
|
+
}
|
|
555
|
+
let result ;
|
|
556
|
+
try {
|
|
557
|
+
result = emitContext({
|
|
558
|
+
event, identity, cwd: dir, sessionId, env, peek: peek === true,
|
|
559
|
+
...(harness ? { harness } : {}),
|
|
560
|
+
...(nudge ? { nudge } : {}),
|
|
561
|
+
...(maxBytes !== undefined ? { maxBytes: Number(maxBytes) } : {}),
|
|
562
|
+
...(taskId ? { taskId } : {}),
|
|
563
|
+
...(slug ? { slug } : {}),
|
|
564
|
+
...(stateRoot ? { stateRoot } : {}),
|
|
565
|
+
});
|
|
566
|
+
} catch (error ) {
|
|
567
|
+
if (error?.code === 'USAGE_ERROR') return usageError('context-emit', error.message.replace(/^emitContext: /, ''), json);
|
|
568
|
+
throw error;
|
|
569
|
+
}
|
|
570
|
+
if (json) {
|
|
571
|
+
console.log(JSON.stringify({ v: 1, event, identity, decision: result.decision, text: result.text, pack: result.pack, committed: result.committed }));
|
|
572
|
+
} else if (result.text !== null) {
|
|
573
|
+
process.stdout.write(result.text.endsWith('\n') ? result.text : `${result.text}\n`);
|
|
574
|
+
}
|
|
575
|
+
return finish(result.decision.reason === 'refused:mandatory-over-budget' ? 3 : 0);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* 078 IC-013: `doflow-run context-grant`, a thin wrapper over grantSummary(). The source scope
|
|
580
|
+
* defaults to the caller's identity. Exits 0 created, 1 not found or already granted, 2 usage,
|
|
581
|
+
* 3 over budget (refused before any write).
|
|
582
|
+
*/
|
|
583
|
+
function handleContextGrantCommand({ summary, toRun, toLineage, fromWorktree, fromRun, fromLineage, maxBytes, json = false, env = process.env } = {}) {
|
|
584
|
+
const { grantSummary } = require('./context/summary-store.js');
|
|
585
|
+
let granted ;
|
|
586
|
+
try {
|
|
587
|
+
granted = grantSummary({
|
|
588
|
+
summary, toRun, toLineage, env,
|
|
589
|
+
...(fromWorktree ? { fromWorktree: path.resolve(fromWorktree) } : {}),
|
|
590
|
+
...(fromRun ? { fromRun } : {}),
|
|
591
|
+
...(fromLineage ? { fromLineage } : {}),
|
|
592
|
+
...(maxBytes !== undefined ? { maxBytes } : {}),
|
|
593
|
+
});
|
|
594
|
+
} catch (error ) {
|
|
595
|
+
if (error?.name !== 'SummaryStoreError') throw error;
|
|
596
|
+
if (error.exitCode === 2) return usageError('context-grant', error.message, json);
|
|
597
|
+
if (json) console.log(JSON.stringify({ v: 1, ok: false, error: error.code, summary: error.message }));
|
|
598
|
+
else console.error(`doflow context-grant: ${error.message}`);
|
|
599
|
+
return finish(error.exitCode);
|
|
600
|
+
}
|
|
601
|
+
if (json) console.log(JSON.stringify({ v: 1, ok: true, ...granted }));
|
|
602
|
+
else console.log(`granted ${granted.summaryId} (${granted.bytes} B) -> ${granted.path}`);
|
|
603
|
+
return finish(0);
|
|
604
|
+
}
|
|
605
|
+
|
|
431
606
|
module.exports = {
|
|
432
607
|
handleCapabilitiesCommand,
|
|
433
608
|
handleReadinessCommand,
|
|
434
609
|
handleEvidenceCommand,
|
|
610
|
+
handleContextEmitCommand,
|
|
611
|
+
handleContextGrantCommand,
|
|
435
612
|
// Exported for bin/doflow.js, which refuses the same names as command-line flags, and for the
|
|
436
613
|
// tests that pin the write boundary.
|
|
437
614
|
EVIDENCE_SCORE_FIELDS,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The per-machine config home (086 IC-003, DD-7): the one place Node code asks where `<home>/doflow`
|
|
7
|
+
* lives. `XDG_CONFIG_HOME` when it is set, non-empty and absolute, else `$HOME/.config` when `HOME` is
|
|
8
|
+
* set, non-empty and absolute, else no config home. A relative or empty value is ignored, never read
|
|
9
|
+
* against the working directory. It reads the `HOME` variable and never `os.homedir()`, so Node and
|
|
10
|
+
* the shell blocks (`doflow_config_home` in `doflow-run`, `policies/lib.sh`, ...) agree on every
|
|
11
|
+
* environment, and an unset HOME is "no home" rather than the account's home.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const path = require('node:path');
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
function configHome(env = process.env) {
|
|
28
|
+
const ignored = [];
|
|
29
|
+
const usable = (name ) => {
|
|
30
|
+
const value = env[name];
|
|
31
|
+
if (typeof value !== 'string' || value === '') return null;
|
|
32
|
+
if (path.isAbsolute(value)) return value;
|
|
33
|
+
ignored.push(name);
|
|
34
|
+
return null;
|
|
35
|
+
};
|
|
36
|
+
const xdg = usable('XDG_CONFIG_HOME');
|
|
37
|
+
const home = usable('HOME');
|
|
38
|
+
const base = xdg !== null ? xdg : home !== null ? path.join(home, '.config') : null;
|
|
39
|
+
return { base, dir: base === null ? null : path.join(base, 'doflow'), ignored };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = { configHome };
|