@khoavu882/doflow 2.0.0-beta.4 → 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 -3
- 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 +7 -17
- 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-bash-guard.sh +7 -17
- package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
- package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
- package/core/harnesses/claude/hooks/session-end.sh +23 -10
- package/core/harnesses/claude/hooks/session-start.sh +5 -3
- package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
- package/core/harnesses/claude/hooks/stop-check.sh +5 -3
- package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
- package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
- 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/mcp-tool-guard.sh +7 -15
- package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
- package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
- package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
- package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
- package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
- package/core/harnesses/codex/hooks/session-start.sh +5 -3
- package/core/harnesses/codex/hooks/stop-check.sh +6 -5
- package/core/harnesses/codex/hooks/subagent-audit.sh +18 -6
- package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
- 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 +21 -5
- package/core/harnesses/kiro/hooks/pre-bash-guard.sh +21 -5
- package/core/harnesses/kiro/hooks/pre-implement-gate.sh +21 -5
- package/core/harnesses/kiro/hooks/session-start.sh +12 -5
- package/core/harnesses/kiro/hooks/stop-check.sh +22 -30
- package/core/harnesses/pi/extensions/doflow-guard.js +167 -0
- package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -12
- package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
- package/core/harnesses/shared/hooks/bridge/bridge.sh +277 -0
- package/core/harnesses/shared/hooks/bridge/envelope.jq +129 -0
- package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
- package/core/harnesses/shared/hooks/bridge/respond.sh +70 -0
- package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
- package/core/harnesses/shared/hooks/policies/capture-failure.sh +51 -16
- package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
- package/core/harnesses/shared/hooks/policies/contract.sh +78 -0
- package/core/harnesses/shared/hooks/policies/deny-json.sh +35 -9
- 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 +65 -40
- package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +48 -35
- package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +284 -33
- package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +180 -110
- package/core/harnesses/shared/hooks/policies/session-context.sh +66 -7
- package/core/harnesses/shared/hooks/policies/stop-check.sh +61 -23
- package/core/harnesses/shared/hooks/policies/subagent-audit.sh +39 -6
- package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
- package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +97 -159
- package/core/harnesses/shared/hooks/stream-hook-runner.js +114 -187
- package/core/harnesses/shared/locator/doflow-run +2 -3
- package/core/registry/advice.json +3 -3
- package/core/registry/assets.json +72 -80
- package/core/registry/capabilities.json +12 -0
- package/core/registry/contracts.json +60 -33
- 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 +1542 -277
- package/core/registry/lifecycle.json +2837 -37
- 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 +701 -30
- 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 +154 -35
- 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 +24 -23
- 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 +17 -59
- 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 +28 -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 +7 -9
- package/core/shared/skills/do-plan/SKILL.md +29 -19
- 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 +226 -113
- package/src/adapters/claude/index.js +39 -5
- package/src/adapters/codex/agents.js +25 -15
- package/src/adapters/codex/hooks.js +40 -5
- package/src/adapters/codex/index.js +100 -22
- package/src/adapters/codex/native-projection.js +6 -2
- package/src/adapters/copilot/index.js +58 -23
- package/src/adapters/copy-tree.js +294 -48
- 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 +38 -13
- package/src/adapters/opencode/index.js +8 -8
- package/src/adapters/pi/hooks.js +120 -0
- package/src/adapters/pi/index.js +48 -16
- package/src/adapters/resolve-source.js +26 -2
- package/src/cli/commands/install.js +3 -2
- 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 +3 -2
- package/src/cli/index.js +338 -33
- package/src/cli/runtime-commands.js +243 -52
- 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 +74 -0
- package/src/lifecycle/hook-step.js +61 -0
- package/src/lifecycle/hook-tier.js +160 -0
- package/src/lifecycle/index.js +434 -86
- package/src/lifecycle/retired-harnesses.js +318 -0
- package/src/lifecycle/view.js +35 -15
- package/src/registry/index.js +686 -32
- 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 +514 -0
- 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 +27 -12
- package/src/runtime/cli-result.js +11 -4
- package/src/runtime/cli.js +221 -277
- package/src/runtime/config-home.js +42 -0
- package/src/runtime/context/arbitrate.js +767 -0
- package/src/runtime/context/budget.js +203 -0
- package/src/runtime/context/compose.js +1367 -0
- package/src/runtime/context/delivery-store.js +100 -0
- package/src/runtime/context/emission-rules.js +118 -0
- package/src/runtime/context/identity.js +227 -0
- package/src/runtime/context/mandatory.js +594 -0
- package/src/runtime/context/pointer.js +142 -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 +1106 -245
- 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-fields.js +39 -0
- package/src/runtime/evidence-ledger.js +41 -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 +77 -10
- 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 +3 -3
- 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 +127 -16
- package/src/runtime/research-request.js +50 -25
- package/src/runtime/retrieval-plan.js +402 -73
- package/src/runtime/retrieval-record.js +293 -0
- 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 +63 -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 +290 -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 +202 -56
- package/src/runtime/task-sources.js +147 -0
- package/src/runtime/task-state.js +440 -65
- 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/.antigravity-plugin/hooks.json +0 -39
- 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 -21
- package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
- package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -21
- package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
- package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -22
- 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 -5
- package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
- package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
- package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
- package/core/harnesses/shared/hooks/hooks.json +0 -47
- 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 -210
- package/src/adapters/gemini/index.js +0 -390
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
|
|
3
|
+
_DOFLOW_SRC=${0//\\//}; case $_DOFLOW_SRC in */*) _DOFLOW_POLDIR=${_DOFLOW_SRC%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
|
|
2
4
|
# pre-implementation-gate.sh — Canonical Policy Library: PreToolUse(Edit|Write|...)
|
|
3
5
|
# backstop for the doflow implement gate. The HARD half of the one enforced
|
|
4
6
|
# gate (the other half is the prompt-level do-prereqs.sh inside
|
|
@@ -21,28 +23,20 @@
|
|
|
21
23
|
# - edit target is under agent-docs/ -> allow (editing the artifacts themselves)
|
|
22
24
|
# - edit target outside the repo -> allow
|
|
23
25
|
# It reads files with jq and lists checkouts with one git call; it never runs
|
|
24
|
-
# the DoFlow runtime.
|
|
26
|
+
# the DoFlow runtime. Missing or malformed v1 input is denied as out of step; other faults follow IC-011.
|
|
25
27
|
#
|
|
26
28
|
# Canonical Policy Script Contract (design.md §4):
|
|
27
29
|
# env DOFLOW_PROJECT_DIR (repo root, if the front door sets it),
|
|
28
30
|
# DOFLOW_AGENT (harness id, informational only here),
|
|
29
|
-
# CLAUDE_CONFIG_DIR / CLAUDE_PROJECT_DIR /
|
|
31
|
+
# CLAUDE_CONFIG_DIR / CLAUDE_PROJECT_DIR / CODEX_HOME
|
|
30
32
|
# (each already read by the harness-specific dispatcher this policy
|
|
31
33
|
# replaces — kept so an unmodified front door still resolves its own
|
|
32
34
|
# harness's do-paths.sh resolver)
|
|
33
|
-
# stdin a
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
# tool_input.command; Kiro: field names undocumented) — this script
|
|
37
|
-
# reads the union of known shapes rather than assuming one, since a
|
|
38
|
-
# native front door (Claude/Codex/Kiro) execs this script directly
|
|
39
|
-
# with no payload translation of its own.
|
|
40
|
-
# exit 0 = allow, non-zero = deny with the reason on stderr. A front door
|
|
41
|
-
# translates this into whatever JSON/exit-code shape its harness
|
|
42
|
-
# natively expects — this script never speaks a harness-specific
|
|
43
|
-
# decision shape.
|
|
35
|
+
# stdin a native payload encoded as envelope v1 by the lifecycle bridge.
|
|
36
|
+
# exit exit 2 + doflow_decide deny = deny; other faults per IC-011. A front
|
|
37
|
+
# door translates this into its native response shape.
|
|
44
38
|
#
|
|
45
|
-
# Reconciliation note (022-normalize-hooks, Phase A): claude/
|
|
39
|
+
# Reconciliation note (022-normalize-hooks, Phase A): claude/codex/kiro
|
|
46
40
|
# each shipped a separately-adapted copy of this gate; antigravity's copy
|
|
47
41
|
# additionally never depended on a do-paths.sh resolver at all — it computed
|
|
48
42
|
# feature_dir itself from the current branch name and checked the three
|
|
@@ -58,74 +52,71 @@
|
|
|
58
52
|
|
|
59
53
|
set -uo pipefail
|
|
60
54
|
|
|
61
|
-
command -v jq >/dev/null 2>&1 || exit 0 # no jq -> cannot evaluate -> allow
|
|
62
|
-
|
|
63
55
|
INPUT=$(cat)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
# A host adapter that has already decoded its native event sends
|
|
67
|
-
# {"doflow_event": {"operation": "edit", "paths": [..], "projectRoot": "..", "taskId": ".."}}
|
|
68
|
-
# and this policy consumes it verbatim. The union decoder below remains the
|
|
69
|
-
# fallback for front doors that still forward raw native payloads; per-harness
|
|
70
|
-
# knowledge belongs in those adapters, and each one that starts sending the
|
|
71
|
-
# envelope retires its share of the union.
|
|
72
|
-
ENVELOPE_ROOT=""
|
|
73
|
-
ENVELOPE_TASK=""
|
|
74
|
-
ENVELOPE_OP=$(printf '%s' "$INPUT" | jq -r '.doflow_event.operation // empty' 2>/dev/null)
|
|
75
|
-
if [ -n "$ENVELOPE_OP" ]; then
|
|
76
|
-
[ "$ENVELOPE_OP" = "edit" ] || exit 0 # only edits are gated
|
|
77
|
-
FILES=$(printf '%s' "$INPUT" | jq -r '.doflow_event.paths[]? // empty' 2>/dev/null | sed '/^$/d' | sort -u)
|
|
78
|
-
[ -n "$FILES" ] || exit 0
|
|
79
|
-
ENVELOPE_ROOT=$(printf '%s' "$INPUT" | jq -r '.doflow_event.projectRoot // empty' 2>/dev/null)
|
|
80
|
-
ENVELOPE_TASK=$(printf '%s' "$INPUT" | jq -r '.doflow_event.taskId // empty' 2>/dev/null)
|
|
56
|
+
if [ -f "$_DOFLOW_POLDIR/contract.sh" ]; then
|
|
57
|
+
. "$_DOFLOW_POLDIR/contract.sh"
|
|
81
58
|
else
|
|
59
|
+
doflow_decision_init() { :; }
|
|
60
|
+
doflow_decide() { :; }
|
|
61
|
+
doflow_read_envelope() { DF_ENV_CLASS=missing; DF_ENV_CODE=contract-missing; }
|
|
62
|
+
( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure pre-implementation-gate contract-missing ) >/dev/null 2>&1 || true
|
|
63
|
+
if [[ "${DOFLOW_AGENT:-}" =~ ^[a-z]+$ ]]; then
|
|
64
|
+
printf '[pre-implementation-gate] DoFlow hooks out of step; run: doflow update -t %s\n' "$DOFLOW_AGENT" >&2
|
|
65
|
+
else
|
|
66
|
+
printf '[pre-implementation-gate] DoFlow hooks out of step; run: doflow update\n' >&2
|
|
67
|
+
fi
|
|
68
|
+
doflow_decide deny contract-missing
|
|
69
|
+
exit 2
|
|
70
|
+
fi
|
|
71
|
+
doflow_decision_init pre-implementation-gate 1
|
|
72
|
+
command -v jq >/dev/null 2>&1 || {
|
|
73
|
+
doflow_decide error dependency-missing:jq
|
|
74
|
+
( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure pre-implementation-gate dependency-missing:jq ) >/dev/null 2>&1 || true
|
|
75
|
+
exit 0
|
|
76
|
+
}
|
|
82
77
|
|
|
83
|
-
#
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
tool=$(printf '%s' "$INPUT" | jq -r "${field} // empty" 2>/dev/null)
|
|
87
|
-
[ -n "$tool" ] && break
|
|
88
|
-
done
|
|
89
|
-
|
|
90
|
-
is_patch_tool=false
|
|
91
|
-
case "$tool" in
|
|
92
|
-
Edit|Write|MultiEdit|edit_file|write_file|create_file|replace_file|replace) ;;
|
|
93
|
-
write_to_file|replace_file_content|multi_replace_file_content) ;;
|
|
94
|
-
apply_patch) is_patch_tool=true ;;
|
|
95
|
-
*) exit 0 ;;
|
|
96
|
-
esac
|
|
97
|
-
|
|
98
|
-
# ── Candidate files to gate ────────────────────────────────────────────────────
|
|
99
|
-
# Normal edit tools: one file, from the union of field names harnesses use.
|
|
100
|
-
# apply_patch (Codex): the tool has no file_path field at all — the paths are
|
|
101
|
-
# embedded in a unified diff under tool_input.command.
|
|
102
|
-
FILES=""
|
|
103
|
-
if [ "$is_patch_tool" = true ]; then
|
|
104
|
-
PATCH=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
105
|
-
[ -n "$PATCH" ] || exit 0
|
|
106
|
-
# "#" (not the original codex script's "|") is the sed delimiter here: BSD
|
|
107
|
-
# sed (macOS, no GNU coreutils) misparses "s|...(Add|Update|Delete)...|...|"
|
|
108
|
-
# because it splits on every unescaped "|", including the ones meant as ERE
|
|
109
|
-
# alternation inside the pattern — a portability bug in the source script
|
|
110
|
-
# this reconciliation fixes rather than ports, since it silently broke
|
|
111
|
-
# apply_patch parsing under this exact invocation on any non-GNU-sed host.
|
|
112
|
-
FILES=$(printf '%s\n' "$PATCH" | sed -nE \
|
|
78
|
+
# Parse v1 apply_patch paths using the shared parser.
|
|
79
|
+
parse_patch_paths() {
|
|
80
|
+
printf '%s\n' "$1" | sed -nE \
|
|
113
81
|
-e 's#^\*\*\* (Add|Update|Delete) File: (.+)$#\2#p' \
|
|
114
82
|
-e 's#^\+\+\+ (a/|b/)?(.+)$#\2#p' \
|
|
115
|
-
| sed '/^\/dev\/null$/d' | sort -u
|
|
116
|
-
|
|
83
|
+
| sed '/^\/dev\/null$/d' | sort -u
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
DF_ENV_CLASS=missing DF_ENV_CODE=envelope-missing
|
|
87
|
+
doflow_read_envelope || true
|
|
88
|
+
|
|
89
|
+
# ── Envelope v1 ───────────────────────────────────────────────────────────────
|
|
90
|
+
ENVELOPE_ROOT=""
|
|
91
|
+
ENVELOPE_TASK=""
|
|
92
|
+
if [ "$DF_ENV_CLASS" = v1 ]; then
|
|
93
|
+
ENVELOPE_OP=$DF_ENV_OP
|
|
94
|
+
[ "$ENVELOPE_OP" = "edit" ] || exit 0 # only edits are gated
|
|
95
|
+
FILES=$DF_ENV_PATHS
|
|
96
|
+
ENVELOPE_ROOT=$DF_ENV_ROOT
|
|
97
|
+
ENVELOPE_TASK=$DF_ENV_TASK
|
|
98
|
+
if [ -z "$FILES" ] && [ -z "$DF_ENV_PATCH" ]; then
|
|
99
|
+
doflow_decide unsupported edit-without-target
|
|
100
|
+
( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure pre-implementation-gate edit-without-target ) >/dev/null 2>&1 || true
|
|
101
|
+
exit 0
|
|
102
|
+
fi
|
|
103
|
+
if [ -z "$FILES" ] && [ -n "$DF_ENV_PATCH" ]; then
|
|
104
|
+
FILES=$(parse_patch_paths "$DF_ENV_PATCH")
|
|
105
|
+
[ -n "$FILES" ] || exit 0
|
|
106
|
+
fi
|
|
107
|
+
elif [ "$DF_ENV_CLASS" = unsupported ]; then
|
|
108
|
+
doflow_decide unsupported envelope-version
|
|
109
|
+
( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure pre-implementation-gate unsupported:envelope-version ) >/dev/null 2>&1 || true
|
|
110
|
+
exit 0
|
|
117
111
|
else
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
FILES="$file"
|
|
112
|
+
if [ "${DF_ENV_CODE:-envelope-missing}" != contract-missing ]; then
|
|
113
|
+
( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure pre-implementation-gate envelope-missing ) >/dev/null 2>&1 || true
|
|
114
|
+
fi
|
|
115
|
+
if [[ "${DOFLOW_AGENT:-}" =~ ^[a-z]+$ ]]; then printf '[pre-implementation-gate] DoFlow hooks out of step; run: doflow update -t %s\n' "$DOFLOW_AGENT" >&2; else printf '[pre-implementation-gate] DoFlow hooks out of step; run: doflow update\n' >&2; fi
|
|
116
|
+
doflow_decide deny "${DF_ENV_CODE:-envelope-missing}"
|
|
117
|
+
exit 2
|
|
125
118
|
fi
|
|
126
119
|
|
|
127
|
-
fi # end legacy union decoder
|
|
128
|
-
|
|
129
120
|
# ── Resolve repo root ───────────────────────────────────────────────────────
|
|
130
121
|
# DOFLOW_PROJECT_DIR (explicit) beats the envelope's projectRoot beats git discovery.
|
|
131
122
|
ROOT="${DOFLOW_PROJECT_DIR:-$ENVELOPE_ROOT}"
|
|
@@ -149,13 +140,11 @@ RESOLVER_CANDIDATES=(
|
|
|
149
140
|
"$ROOT/.doflow/scripts/doflow/bash/do-paths.sh"
|
|
150
141
|
"$ROOT/.claude/scripts/doflow/bash/do-paths.sh"
|
|
151
142
|
"$ROOT/.codex/scripts/doflow/bash/do-paths.sh"
|
|
152
|
-
"$ROOT/.gemini/scripts/doflow/bash/do-paths.sh"
|
|
153
143
|
"$ROOT/.kiro/scripts/doflow/bash/do-paths.sh"
|
|
154
144
|
"$HOME/.doflow/scripts/doflow/bash/do-paths.sh"
|
|
155
145
|
"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/scripts/doflow/bash/do-paths.sh"
|
|
156
146
|
"${CLAUDE_PROJECT_DIR:-}/.claude/scripts/doflow/bash/do-paths.sh"
|
|
157
147
|
"${CODEX_HOME:-$HOME/.codex}/scripts/doflow/bash/do-paths.sh"
|
|
158
|
-
"${GEMINI_CONFIG_DIR:-$HOME/.gemini}/scripts/doflow/bash/do-paths.sh"
|
|
159
148
|
"$HOME/.kiro/scripts/doflow/bash/do-paths.sh"
|
|
160
149
|
)
|
|
161
150
|
|
|
@@ -173,11 +162,14 @@ has_plan=""
|
|
|
173
162
|
if [ -n "$RESOLVER" ]; then
|
|
174
163
|
json=$("$RESOLVER" --json 2>/dev/null) || json=""
|
|
175
164
|
if [ -n "$json" ]; then
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
165
|
+
# One jq run for all five fields, one per line (none of them can hold a newline).
|
|
166
|
+
{
|
|
167
|
+
IFS= read -r feature_dir
|
|
168
|
+
IFS= read -r repo_root
|
|
169
|
+
IFS= read -r has_requirement
|
|
170
|
+
IFS= read -r has_design
|
|
171
|
+
IFS= read -r has_plan
|
|
172
|
+
} < <(printf '%s' "$json" | jq -r '(.feature_dir // ""), (.repo_root // ""), (.has_requirement // false), (.has_design // false), (.has_plan // false)' 2>/dev/null) || true
|
|
181
173
|
fi
|
|
182
174
|
fi
|
|
183
175
|
|
|
@@ -257,18 +249,41 @@ real_path() {
|
|
|
257
249
|
repo_real=$(cd -P "$repo_root" 2>/dev/null && pwd) || repo_real="$repo_root"
|
|
258
250
|
|
|
259
251
|
# Only source files inside this repo are gated: edits to doflow artifacts are
|
|
260
|
-
# always allowed,
|
|
252
|
+
# always allowed, an absolute path elsewhere is not this repo's, and neither is a
|
|
253
|
+
# path git ignores.
|
|
261
254
|
GATED=false
|
|
262
255
|
while IFS= read -r file; do
|
|
263
256
|
[ -z "$file" ] && continue
|
|
264
|
-
|
|
257
|
+
# A ".." segment can lead out of agent-docs (agent-docs/../src/x), so such a path is judged by
|
|
258
|
+
# its real path below, never by the text before the "..".
|
|
259
|
+
case "/$file/" in
|
|
260
|
+
*/../*) ;;
|
|
261
|
+
*) case "$file" in *"/agent-docs/"*|agent-docs/*) continue ;; esac ;;
|
|
262
|
+
esac
|
|
263
|
+
check="$file"
|
|
265
264
|
case "$file" in
|
|
266
265
|
/*)
|
|
267
266
|
real=$(real_path "$file") || real="$file"
|
|
268
|
-
case "$real" in *"/agent-docs/"*) continue ;; esac
|
|
267
|
+
case "/$real/" in */../*) ;; *) case "$real" in *"/agent-docs/"*) continue ;; esac ;; esac
|
|
269
268
|
case "$real" in "$repo_real"/*) ;; *) continue ;; esac
|
|
269
|
+
check="$real"
|
|
270
|
+
;;
|
|
271
|
+
*)
|
|
272
|
+
real=$(real_path "$repo_root/$file") || real="$repo_root/$file"
|
|
273
|
+
# real_path folds a ".." only through directories that exist, so one left in it is not folded.
|
|
274
|
+
case "/$file/" in */../*) case "/$real/" in */../*) ;; *) case "${real#"$repo_real"}/" in */agent-docs/*) continue ;; esac ;; esac ;; esac
|
|
270
275
|
;;
|
|
271
276
|
esac
|
|
277
|
+
# A path git ignores (a local config file such as .mcp.json) is not source. check-ignore
|
|
278
|
+
# without --no-index answers "not ignored" for a tracked file, so tracked source stays gated.
|
|
279
|
+
# The skip never applies to DoFlow's own state or gate artifacts: .doflow/ is gitignored, and
|
|
280
|
+
# skipping it would let an edit forge a readiness record. Any `.doflow` or `agent-docs/doflow`
|
|
281
|
+
# segment of the real path, or of the path as written (a `..` the resolver could not fold), keeps it gated.
|
|
282
|
+
# The same holds for the do-paths.sh resolver the gate runs (any RESOLVER_CANDIDATES path, whichever
|
|
283
|
+
# harness directory holds it, ignored or not): rewriting it can make the gate find no feature.
|
|
284
|
+
case "/$file/" in */.doflow/*|*/agent-docs/doflow/*|*/../*|*/scripts/doflow/bash/do-paths.sh/) GATED=true; break ;; esac
|
|
285
|
+
case "${real#"$repo_real"}/" in */.doflow/*|*/agent-docs/doflow/*|*/scripts/doflow/bash/do-paths.sh/) GATED=true; break ;; esac
|
|
286
|
+
git -C "$repo_root" check-ignore -q -- "$check" 2>/dev/null && continue
|
|
272
287
|
GATED=true
|
|
273
288
|
break
|
|
274
289
|
done <<< "$FILES"
|
|
@@ -314,25 +329,71 @@ checkouts() {
|
|
|
314
329
|
return 0
|
|
315
330
|
}
|
|
316
331
|
|
|
317
|
-
#
|
|
318
|
-
|
|
319
|
-
|
|
332
|
+
# Whether two files hold the same bytes.
|
|
333
|
+
same_bytes() {
|
|
334
|
+
if command -v cmp >/dev/null 2>&1; then cmp -s "$1" "$2"; else [ "$(cat "$1")" = "$(cat "$2")" ]; fi
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
# Whether the flat record $1 of a namespaced task may be read as feature $2's
|
|
338
|
+
# (115 D-3): it names that feature (featureSlug on a run, slug on a readiness
|
|
339
|
+
# record) or none. A file that does not parse names nobody.
|
|
340
|
+
flat_is_ours() {
|
|
341
|
+
local named
|
|
342
|
+
named=$(jq -r '[.featureSlug, .slug] | map(select(type == "string" and . != "")) | first // empty' "$1" 2>/dev/null) || return 1
|
|
343
|
+
[ -z "$named" ] || [ "$named" = "$2" ]
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
# The task's record of store $2 (readiness | orchestration) under checkout $1,
|
|
347
|
+
# keyed by feature $3 as the runtime keys it (115 C-1): <store>/<feature>/<id>.json
|
|
348
|
+
# for a task id other than the feature's slug, else the flat file; the flat file
|
|
349
|
+
# of a namespaced task only when it is this feature's or names none. Sets HIT.
|
|
350
|
+
HIT=""
|
|
351
|
+
record_in() {
|
|
352
|
+
local store="$1/.doflow/state/$2"
|
|
353
|
+
HIT=""
|
|
354
|
+
if [ -n "$3" ] && [ "$3" != "$task_id" ]; then
|
|
355
|
+
if [ -f "$store/$3/$task_id.json" ]; then HIT="$store/$3/$task_id.json"; return 0; fi
|
|
356
|
+
[ -f "$store/$task_id.json" ] && flat_is_ours "$store/$task_id.json" "$3" && HIT="$store/$task_id.json"
|
|
357
|
+
return 0
|
|
358
|
+
fi
|
|
359
|
+
[ -f "$store/$task_id.json" ] && HIT="$store/$task_id.json"
|
|
360
|
+
return 0
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
# The task's readiness record, keyed by feature $1. From a linked worktree the
|
|
364
|
+
# main checkout's comes first, since every record lives there (115 IC-004), and
|
|
365
|
+
# a copy at the same path here with other bytes refuses (C-3). Else this
|
|
366
|
+
# checkout's, else exactly one other checkout's; held in two or more others it
|
|
367
|
+
# cannot be told which is meant -> allow.
|
|
320
368
|
FOUND=""
|
|
321
369
|
find_state() {
|
|
322
|
-
local
|
|
370
|
+
local root count=0 copy
|
|
323
371
|
FOUND=""
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
372
|
+
if [ -f "$repo_root/.git" ]; then
|
|
373
|
+
checkouts
|
|
374
|
+
if [ -n "$MAIN" ]; then
|
|
375
|
+
record_in "$MAIN" readiness "$1"
|
|
376
|
+
if [ -n "$HIT" ]; then
|
|
377
|
+
copy="$repo_root${HIT#"$MAIN"}"
|
|
378
|
+
if [ -f "$copy" ] && ! same_bytes "$copy" "$HIT"; then
|
|
379
|
+
printf "doflow gate readiness-before-implementation: task '%s' has a readiness record in this worktree (%s) that differs from the main checkout's (%s). Next: keep one of the two and remove the other, then re-run. Nothing was changed.\n" "$task_id" "$copy" "$HIT" >&2
|
|
380
|
+
doflow_decide deny readiness-store-conflict
|
|
381
|
+
exit 2
|
|
382
|
+
fi
|
|
383
|
+
FOUND="$HIT"
|
|
384
|
+
return 0
|
|
385
|
+
fi
|
|
386
|
+
fi
|
|
387
|
+
fi
|
|
388
|
+
record_in "$repo_root" readiness "$1"
|
|
389
|
+
if [ -n "$HIT" ]; then FOUND="$HIT"; return 0; fi
|
|
327
390
|
checkouts
|
|
328
391
|
for root in ${OTHERS[@]+"${OTHERS[@]}"}; do
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
done
|
|
333
|
-
[ -n "$hit" ] || continue
|
|
392
|
+
[ "$root" = "$MAIN" ] && continue
|
|
393
|
+
record_in "$root" readiness "$1"
|
|
394
|
+
[ -n "$HIT" ] || continue
|
|
334
395
|
count=$((count + 1))
|
|
335
|
-
FOUND="$
|
|
396
|
+
FOUND="$HIT"
|
|
336
397
|
done
|
|
337
398
|
[ "$count" -le 1 ] || exit 0
|
|
338
399
|
}
|
|
@@ -348,18 +409,26 @@ run_feature() {
|
|
|
348
409
|
return 0
|
|
349
410
|
}
|
|
350
411
|
|
|
412
|
+
# The feature the task's records are keyed by, as the runtime keys them
|
|
413
|
+
# (featureSlugFor): a task id that names a feature folder in this checkout is
|
|
414
|
+
# its own feature, else the branch's.
|
|
415
|
+
run_key="$slug"
|
|
416
|
+
[ -d "$repo_root/agent-docs/doflow/$task_id" ] && run_key="$task_id"
|
|
417
|
+
|
|
351
418
|
# The task's run: this checkout's, else the one other checkout's run of the same
|
|
352
419
|
# feature. A run with the same id for another feature is a different task.
|
|
353
420
|
find_run() {
|
|
354
|
-
local
|
|
421
|
+
local root count=0
|
|
355
422
|
FOUND=""
|
|
356
|
-
|
|
423
|
+
record_in "$repo_root" orchestration "$run_key"
|
|
424
|
+
if [ -n "$HIT" ]; then FOUND="$HIT"; return 0; fi
|
|
357
425
|
checkouts
|
|
358
426
|
for root in ${OTHERS[@]+"${OTHERS[@]}"}; do
|
|
359
|
-
|
|
360
|
-
[
|
|
427
|
+
record_in "$root" orchestration "$run_key"
|
|
428
|
+
[ -n "$HIT" ] || continue
|
|
429
|
+
[ "$(run_feature "$HIT")" = "$run_key" ] || continue
|
|
361
430
|
count=$((count + 1))
|
|
362
|
-
FOUND="$
|
|
431
|
+
FOUND="$HIT"
|
|
363
432
|
done
|
|
364
433
|
[ "$count" -le 1 ] || exit 0
|
|
365
434
|
}
|
|
@@ -384,13 +453,14 @@ PLANNED=false
|
|
|
384
453
|
# plan.md all exist. Classes that cannot be a feature skip this check.
|
|
385
454
|
if [ "$exempt" = false ] && [ -n "$FEATURE_ROOT" ] && [ "$PLANNED" = false ]; then
|
|
386
455
|
echo "[pre-implementation-gate] doflow gate: feature $feature_dir is missing requirement.md, design.md, or plan.md — run /do-brainstorm, /do-design, then /do-plan before editing source. (Edits under agent-docs/ are always allowed; skip the flow by removing the feature dir.)" >&2
|
|
456
|
+
doflow_decide deny missing-artifacts
|
|
387
457
|
exit 2
|
|
388
458
|
fi
|
|
389
459
|
|
|
390
460
|
# ── Readiness ────────────────────────────────────────────────────────────────
|
|
391
461
|
# The workflow registry the installed runtime reads: beside this policy in an
|
|
392
462
|
# install, the source tree's own, the project's install, the global install.
|
|
393
|
-
POLICY_DIR=$
|
|
463
|
+
POLICY_DIR=$_DOFLOW_POLDIR
|
|
394
464
|
REGISTRY=""
|
|
395
465
|
for candidate in \
|
|
396
466
|
"${POLICY_DIR:+$POLICY_DIR/../../../runtime/core/registry/workflows.json}" \
|
|
@@ -452,13 +522,10 @@ if [ -n "$RUN" ]; then
|
|
|
452
522
|
fi
|
|
453
523
|
|
|
454
524
|
# The record, where the runtime looks: under the feature's namespace (the run's
|
|
455
|
-
# own feature when it recorded one), then flat;
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
else
|
|
460
|
-
find_state ".doflow/state/readiness/$task_id.json"
|
|
461
|
-
fi
|
|
525
|
+
# own feature when it recorded one), then flat; the main checkout first from a
|
|
526
|
+
# linked worktree, else this checkout first.
|
|
527
|
+
record_slug="${run_slug:-$run_key}"
|
|
528
|
+
find_state "$record_slug"
|
|
462
529
|
record_state=""; record_class=""; record_at=""
|
|
463
530
|
if [ -n "$FOUND" ]; then
|
|
464
531
|
record_info=$(jq -r '(.state // ""), (.taskClass // ""), (.evaluatedAt // "")' "$FOUND" 2>/dev/null) || exit 0
|
|
@@ -480,16 +547,19 @@ gate="doflow gate readiness-before-implementation: task '$task_id'"
|
|
|
480
547
|
rest="Next: $next, then gather what it lists until it reports READY. Nothing was changed."
|
|
481
548
|
if [ -z "$FOUND" ]; then
|
|
482
549
|
printf "%s has no readiness record for the '%s' template. %s\n" "$gate" "$STAGE_TEMPLATE" "$rest" >&2
|
|
550
|
+
doflow_decide deny readiness-missing
|
|
483
551
|
exit 2
|
|
484
552
|
fi
|
|
485
553
|
if [ "$record_state" != READY ]; then
|
|
486
554
|
printf "%s was last evaluated %s at %s against the '%s' template, not READY. %s\n" \
|
|
487
555
|
"$gate" "$record_state" "$record_at" "$STAGE_TEMPLATE" "$rest" >&2
|
|
556
|
+
doflow_decide deny readiness-not-ready
|
|
488
557
|
exit 2
|
|
489
558
|
fi
|
|
490
559
|
if [ "$record_class" != "$STAGE_TEMPLATE" ]; then
|
|
491
560
|
printf "%s has a READY record for the '%s' template, and this stage needs '%s'. %s\n" \
|
|
492
561
|
"$gate" "$record_class" "$STAGE_TEMPLATE" "$rest" >&2
|
|
562
|
+
doflow_decide deny readiness-wrong-template
|
|
493
563
|
exit 2
|
|
494
564
|
fi
|
|
495
565
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
|
|
3
|
+
_DOFLOW_SRC=${0//\\//}; case $_DOFLOW_SRC in */*) _DOFLOW_POLDIR=${_DOFLOW_SRC%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
|
|
2
4
|
# session-context.sh — Canonical Policy Library: SessionStart guard policy
|
|
3
5
|
#
|
|
4
6
|
# Fires when a harness starts a new session. Captures git state into a
|
|
@@ -11,29 +13,85 @@
|
|
|
11
13
|
# Canonical Policy Script Contract (design.md §4):
|
|
12
14
|
# env DOFLOW_PROJECT_DIR, DOFLOW_AGENT (both optional here; DOFLOW_AGENT
|
|
13
15
|
# only affects the "last_agent" field recorded in meta.json)
|
|
14
|
-
# stdin the
|
|
15
|
-
#
|
|
16
|
+
# stdin envelope v1 from the native SessionStart payload, including
|
|
17
|
+
# the session_id and cwd fields used by this policy.
|
|
16
18
|
# exit this policy never denies — it always exits 0 (side-effect only)
|
|
17
19
|
#
|
|
18
20
|
# Depends on lib.sh (require_jq, json_field, ensure_session_dir,
|
|
19
21
|
# ensure_project_dir, cwd_hash, run_with_timeout, $SESSIONS_LOG) being
|
|
20
22
|
# discoverable next to this script when it runs — a front door invoking this
|
|
21
23
|
# canonical script is responsible for making lib.sh resolvable via
|
|
22
|
-
#
|
|
24
|
+
# the sibling lib.sh, exactly as every harness's own SessionStart script
|
|
23
25
|
# already required before this policy moved to a shared location.
|
|
24
26
|
|
|
25
27
|
set -euo pipefail
|
|
26
28
|
# shellcheck source=lib.sh
|
|
27
|
-
source "$
|
|
28
|
-
require_jq
|
|
29
|
-
|
|
29
|
+
source "$_DOFLOW_POLDIR/lib.sh"
|
|
30
30
|
INPUT=$(cat)
|
|
31
|
-
|
|
31
|
+
POLICY_DIR=$_DOFLOW_POLDIR
|
|
32
|
+
if [ -f "$POLICY_DIR/contract.sh" ]; then
|
|
33
|
+
# shellcheck source=contract.sh
|
|
34
|
+
source "$POLICY_DIR/contract.sh"
|
|
35
|
+
doflow_decision_init session-context 1
|
|
36
|
+
else
|
|
37
|
+
doflow_decision_init() { :; }
|
|
38
|
+
doflow_decide() { :; }
|
|
39
|
+
( . "$POLICY_DIR/capture-failure.sh"; doflow_capture_failure session-context contract-missing ) >/dev/null 2>&1 || true
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
43
|
+
doflow_decide error dependency-missing:jq
|
|
44
|
+
( . "$POLICY_DIR/capture-failure.sh"; doflow_capture_failure session-context dependency-missing:jq ) >/dev/null 2>&1 || true
|
|
45
|
+
fi
|
|
46
|
+
require_jq
|
|
47
|
+
SESSION_ID="" ENVELOPE_CLASS=missing
|
|
48
|
+
{ IFS= read -r -d '' ENVELOPE_CLASS; IFS= read -r -d '' SESSION_ID; } < <(
|
|
49
|
+
printf '%s' "$INPUT" | jq -j 'if ((. | type) != "object") or ((.doflow_event | type) != "object") or ((.doflow_event | has("version")) | not) then "missing" elif ((.doflow_event.version | type) == "number") and .doflow_event.version == 1 then "v1" else "unsupported" end, "\u0000", (.session_id // "" | if type == "string" then rtrimstr("\n") else tojson end), "\u0000"' 2>/dev/null
|
|
50
|
+
) || true
|
|
51
|
+
ENVELOPE_CLASS=${ENVELOPE_CLASS:-missing}
|
|
52
|
+
if [ ! -f "$POLICY_DIR/contract.sh" ]; then ENVELOPE_CLASS=missing; fi
|
|
53
|
+
if [ "$ENVELOPE_CLASS" = unsupported ] || [ "$ENVELOPE_CLASS" = missing ]; then
|
|
54
|
+
code=envelope-version
|
|
55
|
+
[ "$ENVELOPE_CLASS" = missing ] && code=envelope-missing
|
|
56
|
+
[ -f "$POLICY_DIR/contract.sh" ] || code=contract-missing
|
|
57
|
+
doflow_decide unsupported "$code"
|
|
58
|
+
if [ -f "$POLICY_DIR/contract.sh" ]; then
|
|
59
|
+
( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure session-context "$code" ) >/dev/null 2>&1 || true
|
|
60
|
+
fi
|
|
61
|
+
exit 0
|
|
62
|
+
fi
|
|
32
63
|
CWD=$(json_field "$INPUT" ".cwd")
|
|
33
64
|
|
|
65
|
+
package_verify_async() {
|
|
66
|
+
local home="${HOME:-}" lock run config_dir detach=""
|
|
67
|
+
[ -n "$home" ] || return 0
|
|
68
|
+
lock="$home/.doflow/doflow.lock"
|
|
69
|
+
[ -f "$lock" ] || return 0
|
|
70
|
+
jq -e '(.packages // []) | length > 0' "$lock" >/dev/null 2>&1 || return 0
|
|
71
|
+
config_dir="${CLAUDE_CONFIG_DIR:-$home/.claude}"
|
|
72
|
+
command -v setsid >/dev/null 2>&1 && detach="setsid"
|
|
73
|
+
for run in \
|
|
74
|
+
"$home/.doflow/scripts/doflow/bin/doflow-run" \
|
|
75
|
+
"$config_dir/scripts/doflow/bin/doflow-run"
|
|
76
|
+
do
|
|
77
|
+
[ -x "$run" ] || continue
|
|
78
|
+
( cd "$home/.doflow" 2>/dev/null && nohup $detach "$run" package --action verify </dev/null >/dev/null 2>&1 ) >/dev/null 2>&1 3>&- 5>&- &
|
|
79
|
+
return 0
|
|
80
|
+
done
|
|
81
|
+
return 0
|
|
82
|
+
}
|
|
83
|
+
|
|
34
84
|
# Guard: if we can't determine the session, nothing to do
|
|
35
85
|
[[ -z "$SESSION_ID" ]] && exit 0
|
|
36
86
|
|
|
87
|
+
# No config home (lib.sh leaves the state paths empty): no session store to write, but the
|
|
88
|
+
# storage upkeep still starts (086 IC-010).
|
|
89
|
+
if [[ -z "$SESSION_DIR" ]]; then
|
|
90
|
+
package_verify_async
|
|
91
|
+
storage_upkeep_async "$CWD"
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
37
95
|
SESSION_PATH=$(ensure_session_dir "$SESSION_ID")
|
|
38
96
|
|
|
39
97
|
# Clean up stale injected flag from a prior crashed session
|
|
@@ -137,5 +195,6 @@ fi
|
|
|
137
195
|
mkdir -p "$(dirname "$SESSIONS_LOG")"
|
|
138
196
|
echo "$TIMESTAMP START $SESSION_ID ${CWD:-unknown}" >> "$SESSIONS_LOG"
|
|
139
197
|
|
|
198
|
+
package_verify_async
|
|
140
199
|
storage_upkeep_async "$CWD"
|
|
141
200
|
exit 0
|