@khoavu882/doflow 2.0.0-beta.5 → 2.0.0
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 +12 -11
- package/bin/doflow.js +21 -11
- 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/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/session-end.sh +23 -10
- package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
- package/core/harnesses/claude/settings/settings.json +18 -0
- 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/lib.sh +44 -25
- 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/session-end.impl.sh +23 -10
- package/core/harnesses/codex/hooks/subagent-audit.sh +1 -0
- package/core/harnesses/copilot/hooks/doflow-lib.sh +93 -0
- package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-pre-bash-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 +57 -0
- package/core/harnesses/kiro/agents/doflow.json +1 -1
- package/core/harnesses/kiro/hooks/lib.sh +26 -6
- package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +1 -0
- package/core/harnesses/kiro/hooks/pre-bash-guard.sh +1 -0
- package/core/harnesses/kiro/hooks/pre-implement-gate.sh +1 -0
- 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 +8 -0
- package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +0 -1
- package/core/harnesses/shared/hooks/bridge/bridge.sh +102 -9
- 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 +10 -2
- package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
- package/core/harnesses/shared/hooks/policies/capture-failure.sh +48 -15
- 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 +2 -11
- 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-tool-guard.sh +3 -2
- package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +213 -12
- package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +114 -38
- package/core/harnesses/shared/hooks/policies/session-context.sh +30 -1
- package/core/harnesses/shared/hooks/policies/stop-check.sh +20 -9
- package/core/harnesses/shared/hooks/policies/subagent-audit.sh +5 -2
- 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 +47 -8
- 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 +32 -0
- package/core/registry/gates.json +32 -0
- package/core/registry/guidance-caps.json +40 -0
- package/core/registry/harnesses.json +1442 -363
- package/core/registry/lifecycle.json +485 -304
- 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/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 +276 -0
- package/core/registry/storage.json +679 -31
- package/core/registry/telemetry.json +236 -0
- package/core/registry/transcripts.json +142 -0
- package/core/registry/verification.json +76 -1
- 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 +1 -2
- 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 +48 -4
- package/core/shared/scripts/doflow/bin/doflow-run +149 -34
- package/core/shared/skills/do/SKILL.md +12 -10
- 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 +20 -74
- package/core/shared/skills/do-brainstorm/references/handoff_branches.md +35 -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 +41 -144
- 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 +18 -17
- package/core/shared/skills/do-diagnose/SKILL.md +14 -4
- package/core/shared/skills/do-document/SKILL.md +11 -1
- package/core/shared/skills/do-document/references/deep_research.md +1 -2
- package/core/shared/skills/do-document/references/embedded-research.md +18 -6
- package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
- package/core/shared/skills/do-execute-plan/SKILL.md +15 -58
- 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 +13 -1
- 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 +8 -9
- package/core/shared/skills/do-flow/references/task_classes.md +2 -2
- package/core/shared/skills/do-git/SKILL.md +4 -0
- package/core/shared/skills/do-implement/SKILL.md +4 -7
- package/core/shared/skills/do-plan/SKILL.md +26 -15
- 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/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 +24 -4
- package/src/adapters/codex/agents.js +25 -15
- package/src/adapters/codex/index.js +48 -13
- package/src/adapters/codex/native-projection.js +6 -2
- package/src/adapters/copilot/index.js +58 -23
- package/src/adapters/copy-tree.js +290 -44
- 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 +21 -2
- package/src/cli/commands/ui.js +99 -0
- package/src/cli/commands/update.js +2 -1
- package/src/cli/index.js +322 -29
- package/src/cli/runtime-commands.js +209 -57
- 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 +20 -3
- 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 +492 -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/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 +154 -78
- 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 +34 -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 +565 -17
- package/src/runtime/history-compactor.js +13 -3
- package/src/runtime/implementation-gate.js +277 -22
- 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 +16 -6
- package/src/runtime/lifecycle/event-store.js +8 -6
- package/src/runtime/lifecycle/followup.js +6 -1
- package/src/runtime/lifecycle/overview.js +24 -1
- 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 +477 -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/facts.js +479 -0
- package/src/runtime/roadmap/gates.js +270 -0
- package/src/runtime/roadmap/loop.js +1636 -0
- package/src/runtime/roadmap/merge.js +381 -0
- package/src/runtime/roadmap/rows.js +1113 -0
- package/src/runtime/roadmap/seed.js +951 -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 +47 -11
- 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 +374 -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/verification/check-key.js +628 -0
- package/src/runtime/verification/contract-runner.js +546 -11
- package/src/runtime/verification/engine.js +499 -9
- 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 +288 -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 +578 -63
- 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/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/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
|
@@ -52,8 +52,9 @@ const { TASK_CLASS_BUDGETS, resolveBudget, getRegisteredHarnessIds, getRegistere
|
|
|
52
52
|
const { createDeliveryEntry, readDeliveryEntry, recordDelivery, makeTokenRecord } = require('./context/delivery-store.js');
|
|
53
53
|
const { boundedAcquire } = require('./task-state.js');
|
|
54
54
|
const pointerTools = require('./context/pointer.js');
|
|
55
|
+
const { arbitrate, emitContext } = require('./context/arbitrate.js');
|
|
55
56
|
const { updateTaskState } = require('./task-state.js');
|
|
56
|
-
const {
|
|
57
|
+
const { taskRecord } = require('./task-scope.js');
|
|
57
58
|
|
|
58
59
|
let correctiveTrimFallbackCount = 0;
|
|
59
60
|
function getCorrectiveTrimFallbackCount() { return correctiveTrimFallbackCount; }
|
|
@@ -114,6 +115,8 @@ function sourcesChanged(root , sources )
|
|
|
114
115
|
|
|
115
116
|
function classifyStoreFailure(error ) {
|
|
116
117
|
if (error?.code === 'store-locked' || error?.message === 'store-locked') return 'store-locked';
|
|
118
|
+
// Another writer reclaimed the lock mid-write; nothing was recorded and the store is intact.
|
|
119
|
+
if (error?.code === 'lock-lost') return 'lock-lost';
|
|
117
120
|
if (error?.code === 'store-unreadable') return 'store-unreadable';
|
|
118
121
|
if (['EACCES', 'EROFS', 'EPERM', 'ENOSPC'].includes(error?.code)) return 'store-unwritable';
|
|
119
122
|
return 'store-unwritable';
|
|
@@ -126,10 +129,9 @@ function profileRetention(harnessId , profiles )
|
|
|
126
129
|
}
|
|
127
130
|
|
|
128
131
|
function appendPointerExpansion({ projectRoot, taskId, slug, key, expansion, fsImpl = fs } ) {
|
|
129
|
-
const
|
|
130
|
-
const file = path.join(dir, `${taskId}.json`);
|
|
132
|
+
const { file, seed } = taskRecord({ projectRoot, store: 'delivery', taskId, slug, fsImpl });
|
|
131
133
|
updateTaskState({
|
|
132
|
-
fsImpl, file,
|
|
134
|
+
fsImpl, file, prepare: seed,
|
|
133
135
|
acquire: (impl , target ) => boundedAcquire(impl, target, { retries: 3, waitMs: 5 }),
|
|
134
136
|
build(disk ) {
|
|
135
137
|
const deliveries = Array.isArray(disk?.deliveries) ? disk.deliveries : [];
|
|
@@ -366,8 +368,12 @@ class ContextPackCompiler {
|
|
|
366
368
|
const selfRefWidth = Math.max(budgetOverrides.selfRefWidth ?? this.options.selfRefWidth ?? 0, reservedHarnessWidth);
|
|
367
369
|
const longestHarnessId = registeredHarnessIds.reduce((longest , id ) => id.length > longest.length ? id : longest, 'unstated');
|
|
368
370
|
const envelopeBudget = {
|
|
369
|
-
|
|
371
|
+
maxBytes: resolvedBudget.maxBytes,
|
|
372
|
+
source: resolvedBudget.source,
|
|
370
373
|
harness: { ...resolvedBudget.harness, id: longestHarnessId },
|
|
374
|
+
capacity: { value: null, basis: 'unknown:values belong to 085 (A-19)' },
|
|
375
|
+
toolResultLimitBytes: null,
|
|
376
|
+
...(resolvedBudget.startupTokens ? { startupTokens: resolvedBudget.startupTokens } : {}),
|
|
371
377
|
};
|
|
372
378
|
|
|
373
379
|
const { envelopeMd, envelopeJson } = computeEnvelopes({
|
|
@@ -478,7 +484,7 @@ class ContextPackCompiler {
|
|
|
478
484
|
taskClass: effectiveTaskClass,
|
|
479
485
|
compiledAt: new Date().toISOString(),
|
|
480
486
|
mode: bare ? 'bare' : (paramMode || 'full'),
|
|
481
|
-
budget:
|
|
487
|
+
budget: envelopeBudget,
|
|
482
488
|
overflow: isOverflow ? {
|
|
483
489
|
cause,
|
|
484
490
|
mandatoryBytes: packMandatoryBytes,
|
|
@@ -874,7 +880,11 @@ class ContextPackCompiler {
|
|
|
874
880
|
* @param {string} [options.objective]
|
|
875
881
|
* @param {boolean} [options.json=false]
|
|
876
882
|
* @param {string} [options.stateRoot]
|
|
883
|
+
* @param {string} [options.sourceRoot] the checkout the verb runs in (default stateRoot)
|
|
877
884
|
* @param {string} [options.slug] feature slug, when the task id is not the feature's own
|
|
885
|
+
* @param {string|null} [options.explicitSlug] the `--slug` the caller typed, if any (default `slug`).
|
|
886
|
+
* Only this selects a run for the stage-pack link: a branch-derived `slug` still keys the delivery
|
|
887
|
+
* store, but the branch name alone never picks a run (docs/specs/orchestrator-context-modes.md).
|
|
878
888
|
* @returns {number} exit code
|
|
879
889
|
*/
|
|
880
890
|
function handleContextPackCommand({
|
|
@@ -883,7 +893,9 @@ function handleContextPackCommand({
|
|
|
883
893
|
objective,
|
|
884
894
|
json = false,
|
|
885
895
|
stateRoot,
|
|
896
|
+
sourceRoot,
|
|
886
897
|
slug,
|
|
898
|
+
explicitSlug,
|
|
887
899
|
mandatoryFile,
|
|
888
900
|
harness = null,
|
|
889
901
|
maxBytes,
|
|
@@ -895,6 +907,9 @@ function handleContextPackCommand({
|
|
|
895
907
|
profiles = null,
|
|
896
908
|
} = {}) {
|
|
897
909
|
const root = stateRoot || process.cwd();
|
|
910
|
+
// 115 IC-004/IC-007: records live under `root`; the feature folder, its plan and pointers, and the
|
|
911
|
+
// source files a delivery hashes are read in the checkout the verb runs in.
|
|
912
|
+
const source = sourceRoot || root;
|
|
898
913
|
const effectiveTaskClass = (!taskClass || typeof taskClass !== 'string' || taskClass.trim() === '') ? 'feature' : taskClass.trim();
|
|
899
914
|
|
|
900
915
|
// IC-001 Usage errors
|
|
@@ -934,10 +949,8 @@ function handleContextPackCommand({
|
|
|
934
949
|
|
|
935
950
|
const budget = resolveBudget({ taskClass: effectiveTaskClass, maxBytes: parsedMaxBytes, harnessFlag: harness, profiles });
|
|
936
951
|
|
|
937
|
-
const feature = resolveFeature({ projectRoot:
|
|
952
|
+
const feature = resolveFeature({ projectRoot: source, slug: slug || null });
|
|
938
953
|
|
|
939
|
-
let sinceEntry = null;
|
|
940
|
-
let deltaRefused = null;
|
|
941
954
|
let deltaExpansions = [];
|
|
942
955
|
if (parsedMaxBytes !== undefined) {
|
|
943
956
|
if (!baseBudget) {
|
|
@@ -947,24 +960,16 @@ function handleContextPackCommand({
|
|
|
947
960
|
deltaExpansions.push({ at: new Date().toISOString(), kind: 'cap-raised', target: null, reason, bytesAdded: null });
|
|
948
961
|
}
|
|
949
962
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
if (!sinceEntry) deltaRefused = 'since-unknown';
|
|
954
|
-
else if (sourcesChanged(root, sinceEntry.sources || {})) deltaRefused = 'sources-changed';
|
|
955
|
-
else if (!budget.harness?.id) deltaRefused = 'harness-unstated';
|
|
956
|
-
else if (retention?.value !== 'supported') deltaRefused = 'retention-unproven';
|
|
957
|
-
if (deltaRefused) {
|
|
958
|
-
deltaExpansions.push({ at: new Date().toISOString(), kind: 'delta-widened', target: null, reason: deltaRefused, bytesAdded: null });
|
|
959
|
-
}
|
|
960
|
-
}
|
|
963
|
+
const basis = resolveDeltaBasis({ root, source, taskId, slug, since: expand ? null : since, budget, profiles });
|
|
964
|
+
const { sinceEntry, deltaRefused, retention } = basis;
|
|
965
|
+
if (basis.expansion) deltaExpansions.push(basis.expansion);
|
|
961
966
|
|
|
962
967
|
if (expand) {
|
|
963
968
|
const prior = readDeliveryEntry({ projectRoot: root, taskId, slug, packDigest: since });
|
|
964
969
|
if (!prior) return usageError('context-pack', `Unknown digest '${since}'`, json);
|
|
965
970
|
const pointer = (prior.pointers || []).find((candidate ) => candidate.id === expand);
|
|
966
971
|
if (!pointer) return usageError('context-pack', `Unknown pointer '${expand}' in digest '${since}'`, json);
|
|
967
|
-
const current = pointerTools.readPointerSlice({ projectRoot:
|
|
972
|
+
const current = pointerTools.readPointerSlice({ projectRoot: source, pointer });
|
|
968
973
|
if (!current) return usageError('context-pack', `Unknown pointer '${expand}' in digest '${since}'`, json);
|
|
969
974
|
const compiler = new ContextPackCompiler();
|
|
970
975
|
const pack = compiler.compileContextPack({ taskId, taskClass: effectiveTaskClass, objective: '', mandatory: { fields: {}, provenance: {} }, budget,
|
|
@@ -1018,55 +1023,7 @@ function handleContextPackCommand({
|
|
|
1018
1023
|
return finishRuntime(EXIT.OK);
|
|
1019
1024
|
}
|
|
1020
1025
|
|
|
1021
|
-
let
|
|
1022
|
-
let reqPath = 'requirement.md';
|
|
1023
|
-
if (!feature.error && feature.featureDir) {
|
|
1024
|
-
reqPath = feature.paths?.requirement
|
|
1025
|
-
? path.resolve(feature.repoRoot || root, feature.paths.requirement)
|
|
1026
|
-
: path.join(feature.featureDir, 'intention', 'requirement.md');
|
|
1027
|
-
try {
|
|
1028
|
-
if (fs.existsSync(reqPath)) {
|
|
1029
|
-
reqText = fs.readFileSync(reqPath, 'utf8');
|
|
1030
|
-
}
|
|
1031
|
-
} catch {
|
|
1032
|
-
reqText = null;
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
let taskStories = [];
|
|
1037
|
-
if (!feature.error && feature.featureDir && taskId) {
|
|
1038
|
-
let planPath = null;
|
|
1039
|
-
if (feature.paths?.plan) {
|
|
1040
|
-
planPath = path.resolve(feature.repoRoot || root, feature.paths.plan);
|
|
1041
|
-
} else {
|
|
1042
|
-
const nestedPlan = path.join(feature.featureDir, 'plan', 'plan.md');
|
|
1043
|
-
const flatPlan = path.join(feature.featureDir, 'plan.md');
|
|
1044
|
-
if (fs.existsSync(nestedPlan)) planPath = nestedPlan;
|
|
1045
|
-
else if (fs.existsSync(flatPlan)) planPath = flatPlan;
|
|
1046
|
-
}
|
|
1047
|
-
if (planPath && fs.existsSync(planPath)) {
|
|
1048
|
-
try {
|
|
1049
|
-
const planText = fs.readFileSync(planPath, 'utf8');
|
|
1050
|
-
const { parsePlan } = require('./scaffold/artifacts.js');
|
|
1051
|
-
const parsedPlan = parsePlan(planText);
|
|
1052
|
-
const matchedTask = (parsedPlan.tasks || []).find(
|
|
1053
|
-
(t ) => t.id === taskId || t.id.toLowerCase() === taskId.toLowerCase()
|
|
1054
|
-
);
|
|
1055
|
-
if (matchedTask && Array.isArray(matchedTask.stories)) {
|
|
1056
|
-
taskStories = matchedTask.stories;
|
|
1057
|
-
}
|
|
1058
|
-
} catch {
|
|
1059
|
-
taskStories = [];
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
let mandatory = extractMandatory({
|
|
1065
|
-
text: reqText,
|
|
1066
|
-
path: reqPath,
|
|
1067
|
-
featureError: feature.error ? (feature.message || feature.error) : null,
|
|
1068
|
-
taskStories,
|
|
1069
|
-
});
|
|
1026
|
+
let mandatory = gatherMandatory({ root: source, taskId, feature });
|
|
1070
1027
|
|
|
1071
1028
|
if (mandatoryFile) {
|
|
1072
1029
|
try {
|
|
@@ -1088,6 +1045,34 @@ function handleContextPackCommand({
|
|
|
1088
1045
|
}
|
|
1089
1046
|
}
|
|
1090
1047
|
|
|
1048
|
+
const { pack, output } = deliverPack({
|
|
1049
|
+
root, source, taskId, slug, effectiveTaskClass, objective, mandatory, budget, harness, parsedMaxBytes, bare, noRecord,
|
|
1050
|
+
json, reason, since, sinceEntry, deltaRefused, deltaExpansions, expand, retention, feature,
|
|
1051
|
+
});
|
|
1052
|
+
// Issue #9 stage 3: a recorded delivery is named on the run stage active now (best effort, never fails the verb).
|
|
1053
|
+
if (pack.delivery?.recorded === true) {
|
|
1054
|
+
try {
|
|
1055
|
+
require('./workflow-orchestrator.js').recordStagePack({ stateRoot: root, sourceRoot: source, taskId, slug: (explicitSlug === undefined ? slug : explicitSlug) || null, digest: pack.delivery.packDigest,
|
|
1056
|
+
checkout: !feature.error && feature.paths?.repo_root ? { repoRoot: feature.paths.repo_root, branch: feature.paths.branch || null } : null });
|
|
1057
|
+
} catch { /* an unrecorded link is unknown, not a failure */ }
|
|
1058
|
+
}
|
|
1059
|
+
if (console.log !== nativeConsoleLog) {
|
|
1060
|
+
console.log(output);
|
|
1061
|
+
} else {
|
|
1062
|
+
process.stdout.write(output);
|
|
1063
|
+
}
|
|
1064
|
+
return finishRuntime(pack.exitCode);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* The context-pack verb's compile, fit, render and delivery-record steps for a full or delta pack,
|
|
1069
|
+
* with no output: `handleContextPackCommand()` prints the result and `packForEmission()` hands it
|
|
1070
|
+
* to `emitContext()`. Returns the final pack and its rendered text in the requested form.
|
|
1071
|
+
*/
|
|
1072
|
+
function deliverPack({
|
|
1073
|
+
root, source = root, taskId, slug, effectiveTaskClass, objective, mandatory, budget, harness, parsedMaxBytes, bare, noRecord,
|
|
1074
|
+
json, reason, since, sinceEntry, deltaRefused, deltaExpansions, expand, retention, feature,
|
|
1075
|
+
} ) {
|
|
1091
1076
|
const ledger = new EvidenceLedger({ repoRoot: root, slug });
|
|
1092
1077
|
ledger.load(taskId);
|
|
1093
1078
|
const claims = new ClaimsManager({ evidenceLedger: ledger, repoRoot: root, slug });
|
|
@@ -1115,11 +1100,11 @@ function handleContextPackCommand({
|
|
|
1115
1100
|
deltaSinceEntry: since && !deltaRefused && !expand ? sinceEntry : null,
|
|
1116
1101
|
deltaRefused,
|
|
1117
1102
|
expand,
|
|
1118
|
-
pointers: pointerTools.collectPointers({ projectRoot:
|
|
1103
|
+
pointers: pointerTools.collectPointers({ projectRoot: source, feature }),
|
|
1119
1104
|
evidenceLedger: ledger,
|
|
1120
1105
|
claimsManager: claims,
|
|
1121
1106
|
researchRequests,
|
|
1122
|
-
decisions: loadLiveDecisions({ projectRoot:
|
|
1107
|
+
decisions: loadLiveDecisions({ projectRoot: source, slug: slug || null }),
|
|
1123
1108
|
});
|
|
1124
1109
|
|
|
1125
1110
|
let deliverySources = null;
|
|
@@ -1136,7 +1121,7 @@ function handleContextPackCommand({
|
|
|
1136
1121
|
pack.omissions = pack.mode === 'bare' ? pack.omissions : compose.groupOmissions(pack.deliveryOmissions, !noRecord);
|
|
1137
1122
|
}
|
|
1138
1123
|
if (!noRecord) {
|
|
1139
|
-
deliverySources = hashSourceFiles(
|
|
1124
|
+
deliverySources = hashSourceFiles(source, pack.relevantFiles || []);
|
|
1140
1125
|
deliveryRetention = retention?.value === 'supported' || retention?.value === 'unsupported'
|
|
1141
1126
|
? { status: retention.value, basis: `declared:${retention.source || 'profile'}` }
|
|
1142
1127
|
: { status: 'unknown', basis: retention?.unverified || 'contextProfile.retention is unverified' };
|
|
@@ -1260,18 +1245,109 @@ function handleContextPackCommand({
|
|
|
1260
1245
|
pack.packEnd.bytes = emittedBytes;
|
|
1261
1246
|
pack.size.totalBytes = emittedBytes;
|
|
1262
1247
|
}
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1248
|
+
return { pack, output };
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
/** The delta basis of a `since` digest: its delivery entry, or why a delta was refused (widened to full). */
|
|
1252
|
+
function resolveDeltaBasis({ root, source = root, taskId, slug, since, budget, profiles } ) {
|
|
1253
|
+
const retention = profileRetention(budget.harness?.id || null, profiles);
|
|
1254
|
+
let sinceEntry = null;
|
|
1255
|
+
let deltaRefused = null;
|
|
1256
|
+
let expansion = null;
|
|
1257
|
+
if (since) {
|
|
1258
|
+
sinceEntry = readDeliveryEntry({ projectRoot: root, taskId, slug, packDigest: since });
|
|
1259
|
+
if (!sinceEntry) deltaRefused = 'since-unknown';
|
|
1260
|
+
else if (sourcesChanged(source, sinceEntry.sources || {})) deltaRefused = 'sources-changed';
|
|
1261
|
+
else if (!budget.harness?.id) deltaRefused = 'harness-unstated';
|
|
1262
|
+
else if (retention?.value !== 'supported') deltaRefused = 'retention-unproven';
|
|
1263
|
+
if (deltaRefused) {
|
|
1264
|
+
expansion = { at: new Date().toISOString(), kind: 'delta-widened', target: null, reason: deltaRefused, bytesAdded: null };
|
|
1265
|
+
}
|
|
1267
1266
|
}
|
|
1268
|
-
return
|
|
1267
|
+
return { sinceEntry, deltaRefused, retention, expansion };
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
/** The mandatory fields of a task from its feature's requirement.md and the task's plan stories. */
|
|
1271
|
+
function gatherMandatory({ root, taskId, feature } ) {
|
|
1272
|
+
let reqText = null;
|
|
1273
|
+
let reqPath = 'requirement.md';
|
|
1274
|
+
if (!feature.error && feature.featureDir) {
|
|
1275
|
+
reqPath = feature.paths?.requirement
|
|
1276
|
+
? path.resolve(feature.repoRoot || root, feature.paths.requirement)
|
|
1277
|
+
: path.join(feature.featureDir, 'intention', 'requirement.md');
|
|
1278
|
+
try {
|
|
1279
|
+
if (fs.existsSync(reqPath)) {
|
|
1280
|
+
reqText = fs.readFileSync(reqPath, 'utf8');
|
|
1281
|
+
}
|
|
1282
|
+
} catch {
|
|
1283
|
+
reqText = null;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
let taskStories = [];
|
|
1288
|
+
if (!feature.error && feature.featureDir && taskId) {
|
|
1289
|
+
let planPath = null;
|
|
1290
|
+
if (feature.paths?.plan) {
|
|
1291
|
+
planPath = path.resolve(feature.repoRoot || root, feature.paths.plan);
|
|
1292
|
+
} else {
|
|
1293
|
+
const nestedPlan = path.join(feature.featureDir, 'plan', 'plan.md');
|
|
1294
|
+
const flatPlan = path.join(feature.featureDir, 'plan.md');
|
|
1295
|
+
if (fs.existsSync(nestedPlan)) planPath = nestedPlan;
|
|
1296
|
+
else if (fs.existsSync(flatPlan)) planPath = flatPlan;
|
|
1297
|
+
}
|
|
1298
|
+
if (planPath && fs.existsSync(planPath)) {
|
|
1299
|
+
try {
|
|
1300
|
+
const planText = fs.readFileSync(planPath, 'utf8');
|
|
1301
|
+
const { parsePlan } = require('./scaffold/artifacts.js');
|
|
1302
|
+
const parsedPlan = parsePlan(planText);
|
|
1303
|
+
const matchedTask = (parsedPlan.tasks || []).find(
|
|
1304
|
+
(t ) => t.id === taskId || t.id.toLowerCase() === taskId.toLowerCase()
|
|
1305
|
+
);
|
|
1306
|
+
if (matchedTask && Array.isArray(matchedTask.stories)) {
|
|
1307
|
+
taskStories = matchedTask.stories;
|
|
1308
|
+
}
|
|
1309
|
+
} catch {
|
|
1310
|
+
taskStories = [];
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
return extractMandatory({
|
|
1316
|
+
text: reqText,
|
|
1317
|
+
path: reqPath,
|
|
1318
|
+
featureError: feature.error ? (feature.message || feature.error) : null,
|
|
1319
|
+
taskStories,
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
/**
|
|
1324
|
+
* 078 IC-001: the context pack `emitContext()` delivers on `launch` and `delta`, compiled by
|
|
1325
|
+
* compileContextPack() through the verb's own steps, with `maxBytes` as the budget and `since` the
|
|
1326
|
+
* unit's last delivered pack digest (a delta when its entry qualifies, else widened to full).
|
|
1327
|
+
* `noRecord` (peek) leaves the delivery store untouched. Rendered as markdown.
|
|
1328
|
+
*/
|
|
1329
|
+
function packForEmission({ root, stateRoot = root, taskId = 'default', taskClass = 'feature', slug = null, harness = null, maxBytes, since = null, noRecord = false, env = process.env } ) {
|
|
1330
|
+
const budget = resolveBudget({ taskClass, maxBytes, harnessFlag: harness, env });
|
|
1331
|
+
const feature = resolveFeature({ projectRoot: root, slug: slug || null });
|
|
1332
|
+
// 115 C-2: the delivery record goes where `context-pack` puts it, under the state root; the feature
|
|
1333
|
+
// folder, the plan and the hashed source files are read in `root`, the checkout emitting.
|
|
1334
|
+
const basis = resolveDeltaBasis({ root: stateRoot, source: root, taskId, slug, since, budget, profiles: null });
|
|
1335
|
+
return deliverPack({
|
|
1336
|
+
root: stateRoot, source: root, taskId, slug, effectiveTaskClass: taskClass, objective: undefined, mandatory: gatherMandatory({ root, taskId, feature }),
|
|
1337
|
+
budget, harness, parsedMaxBytes: maxBytes, bare: false, noRecord, json: false, reason: null, since,
|
|
1338
|
+
sinceEntry: basis.sinceEntry, deltaRefused: basis.deltaRefused, deltaExpansions: basis.expansion ? [basis.expansion] : [],
|
|
1339
|
+
expand: null, retention: basis.retention, feature,
|
|
1340
|
+
});
|
|
1269
1341
|
}
|
|
1270
1342
|
|
|
1271
1343
|
module.exports = {
|
|
1344
|
+
classifyStoreFailure,
|
|
1272
1345
|
ContextPackCompiler,
|
|
1346
|
+
arbitrate,
|
|
1347
|
+
emitContext,
|
|
1273
1348
|
TASK_CLASS_BUDGETS,
|
|
1274
1349
|
handleContextPackCommand,
|
|
1275
1350
|
loadLiveDecisions,
|
|
1351
|
+
packForEmission,
|
|
1276
1352
|
getCorrectiveTrimFallbackCount,
|
|
1277
1353
|
};
|
|
@@ -30,7 +30,12 @@ const REF_RE = /^[A-Za-z]+-?[0-9]+$/;
|
|
|
30
30
|
const DEC_RE = /^DEC-[0-9]{3,}$/;
|
|
31
31
|
const STAGES = ['discovery', 'design', 'planning', 'implementation', 'verification', 'review'];
|
|
32
32
|
/** Channel -> who decided. The caller names the channel; `decidedBy` follows from it. */
|
|
33
|
-
const CHANNEL_DECIDED_BY = { question: 'user', gate: 'user', prompt: 'user', default: 'agent', resolution: 'agent' };
|
|
33
|
+
const CHANNEL_DECIDED_BY = { question: 'user', gate: 'user', prompt: 'user', default: 'agent', resolution: 'agent', policy: 'autopilot' };
|
|
34
|
+
/** IC-005: `policy` records an evaluated gate, never a caller's claimed identity, so only the
|
|
35
|
+
* in-process `orchestrate decide-gate --policy` path writes it; every caller-facing path refuses it. */
|
|
36
|
+
const RESERVED_CHANNEL = 'policy';
|
|
37
|
+
const CHANNEL_RESERVED = `channel-reserved: ${RESERVED_CHANNEL} is set only by orchestrate decide-gate --policy`;
|
|
38
|
+
const isReservedChannel = (channel ) => typeof channel === 'string' && channel.trim() === RESERVED_CHANNEL;
|
|
34
39
|
const ITEM_KEYS = ['topic', 'statement', 'channel', 'stage', 'rationale', 'supersedes', 'refs', 'source'];
|
|
35
40
|
const REQUIRED_KEYS = ['topic', 'statement', 'channel', 'stage', 'rationale'];
|
|
36
41
|
|
|
@@ -204,7 +209,7 @@ function normalizeItem(raw , label ) {
|
|
|
204
209
|
}
|
|
205
210
|
const channel = raw.channel.trim();
|
|
206
211
|
if (!Object.prototype.hasOwnProperty.call(CHANNEL_DECIDED_BY, channel)) {
|
|
207
|
-
throw new DecisionUsageError(`${label}: channel '${channel}' must be one of ${Object.keys(CHANNEL_DECIDED_BY).join(', ')}`);
|
|
212
|
+
throw new DecisionUsageError(`${label}: channel '${channel}' must be one of ${Object.keys(CHANNEL_DECIDED_BY).filter((c) => c !== RESERVED_CHANNEL).join(', ')}`);
|
|
208
213
|
}
|
|
209
214
|
const stage = raw.stage.trim();
|
|
210
215
|
if (!STAGES.includes(stage)) throw new DecisionUsageError(`${label}: stage '${stage}' must be one of ${STAGES.join(', ')}`);
|
|
@@ -406,16 +411,17 @@ function runDecision({ action = 'list', projectRoot, slug = null, flags = {}, no
|
|
|
406
411
|
let resolved = null;
|
|
407
412
|
try {
|
|
408
413
|
if (!VALID_ACTIONS.includes(act)) throw new DecisionUsageError(`unknown --action '${action}'. Valid: ${VALID_ACTIONS.join(', ')}`);
|
|
414
|
+
if (isReservedChannel(flags.channel)) throw new DecisionUsageError(CHANNEL_RESERVED);
|
|
409
415
|
const feature = resolveActiveFeature({ projectRoot, slug });
|
|
410
416
|
if (feature.error) throw new DecisionUsageError(feature.message);
|
|
411
|
-
resolved = { featureDir: feature.
|
|
417
|
+
resolved = { featureDir: feature.featureFolder, slug: feature.paths.feature_slug };
|
|
412
418
|
let result ;
|
|
413
419
|
if (act === 'init') {
|
|
414
420
|
result = initRegister({ ...resolved, fsImpl });
|
|
415
421
|
} else if (act === 'list') {
|
|
416
422
|
result = listDecisions({ ...resolved, all: Boolean(flags.all), fsImpl });
|
|
417
423
|
} else if (act === 'compact') {
|
|
418
|
-
result = compactDecisions({ ...resolved, repoRoot: feature.
|
|
424
|
+
result = compactDecisions({ ...resolved, repoRoot: feature.featureRoot, paths: feature.paths, now, fsImpl });
|
|
419
425
|
} else {
|
|
420
426
|
let items ;
|
|
421
427
|
if (flags.batch) {
|
|
@@ -430,6 +436,7 @@ function runDecision({ action = 'list', projectRoot, slug = null, flags = {}, no
|
|
|
430
436
|
}
|
|
431
437
|
items = [single];
|
|
432
438
|
}
|
|
439
|
+
if (Array.isArray(items) && items.some((item ) => isReservedChannel(item?.channel))) throw new DecisionUsageError(CHANNEL_RESERVED);
|
|
433
440
|
result = addDecisions({ ...resolved, items, now, fsImpl });
|
|
434
441
|
}
|
|
435
442
|
return { exitCode: result.finding ? 1 : 0, result };
|
|
@@ -489,5 +496,7 @@ module.exports = {
|
|
|
489
496
|
archiveFile,
|
|
490
497
|
STAGES,
|
|
491
498
|
CHANNEL_DECIDED_BY,
|
|
499
|
+
CHANNEL_RESERVED,
|
|
500
|
+
isReservedChannel,
|
|
492
501
|
STATEMENT_MAX,
|
|
493
502
|
};
|