session-orchestrator 3.16.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/.claude-plugin/marketplace.json +29 -0
- package/.claude-plugin/plugin.json +18 -0
- package/.codex-plugin/agents/explorer.toml +14 -0
- package/.codex-plugin/agents/session-reviewer.toml +23 -0
- package/.codex-plugin/agents/wave-worker.toml +15 -0
- package/.codex-plugin/config.toml +20 -0
- package/.codex-plugin/plugin.json +37 -0
- package/.cursor/rules/000-session-orchestrator.mdc +73 -0
- package/.cursor/rules/010-session-workflow.mdc +170 -0
- package/.cursor/rules/020-quality-gates.mdc +128 -0
- package/.cursor/rules/030-wave-execution.mdc +216 -0
- package/.cursor/rules/040-discovery.mdc +242 -0
- package/.cursor/rules/050-plan.mdc +235 -0
- package/.cursor/rules/060-evolve.mdc +232 -0
- package/.cursor/rules/070-gitlab-ops.mdc +246 -0
- package/.cursor/rules/080-ecosystem-health.mdc +145 -0
- package/.mcp.json +8 -0
- package/CHANGELOG.md +1544 -0
- package/LICENSE +21 -0
- package/NOTICE +64 -0
- package/README.md +242 -0
- package/SECURITY.md +90 -0
- package/agents/AGENTS.md +136 -0
- package/agents/analyst.md +99 -0
- package/agents/architect-reviewer.md +93 -0
- package/agents/code-implementer.md +106 -0
- package/agents/db-specialist.md +104 -0
- package/agents/dialectic-deriver.md +139 -0
- package/agents/docs-writer.md +113 -0
- package/agents/eval-judge.md +146 -0
- package/agents/memory-proposal-collector.md +297 -0
- package/agents/qa-strategist.md +102 -0
- package/agents/schemas/analyst.schema.json +46 -0
- package/agents/schemas/architect-reviewer.schema.json +50 -0
- package/agents/schemas/code-implementer.schema.json +61 -0
- package/agents/schemas/db-specialist.schema.json +80 -0
- package/agents/schemas/docs-writer.schema.json +56 -0
- package/agents/schemas/persona-panel-sidecar.schema.json +245 -0
- package/agents/schemas/qa-strategist.schema.json +46 -0
- package/agents/schemas/security-reviewer.schema.json +86 -0
- package/agents/schemas/session-reviewer.schema.json +69 -0
- package/agents/schemas/test-writer.schema.json +69 -0
- package/agents/schemas/ui-developer.schema.json +90 -0
- package/agents/schemas/ux-evaluator.schema.json +51 -0
- package/agents/security-reviewer.md +236 -0
- package/agents/session-reviewer.md +201 -0
- package/agents/skill-applied-judge.md +122 -0
- package/agents/test-writer.md +123 -0
- package/agents/ui-developer.md +109 -0
- package/agents/ux-evaluator.md +161 -0
- package/assets/icon.svg +11 -0
- package/assets/og-card.png +0 -0
- package/assets/og-card.svg +47 -0
- package/commands/autopilot-multi.md +74 -0
- package/commands/autopilot.md +80 -0
- package/commands/bootstrap.md +56 -0
- package/commands/brainstorm.md +48 -0
- package/commands/close.md +24 -0
- package/commands/debug.md +36 -0
- package/commands/discovery.md +32 -0
- package/commands/dispatcher.md +59 -0
- package/commands/eval.md +28 -0
- package/commands/evolve.md +10 -0
- package/commands/go.md +41 -0
- package/commands/grill.md +45 -0
- package/commands/harness-audit.md +26 -0
- package/commands/memory-cleanup.md +25 -0
- package/commands/persona-panel.md +121 -0
- package/commands/plan.md +15 -0
- package/commands/portfolio.md +97 -0
- package/commands/reconcile.md +23 -0
- package/commands/repo-audit.md +24 -0
- package/commands/session.md +30 -0
- package/commands/spinout.md +15 -0
- package/commands/sunset-review.md +27 -0
- package/commands/templates-ack.md +96 -0
- package/commands/test.md +97 -0
- package/docs/README.md +105 -0
- package/docs/USER-GUIDE.md +1403 -0
- package/docs/ci-setup.md +81 -0
- package/docs/codex-setup.md +142 -0
- package/docs/components.md +74 -0
- package/docs/cursor-setup.md +104 -0
- package/docs/events-schema.md +81 -0
- package/docs/migration-v3.md +148 -0
- package/docs/owner-config-schema.md +154 -0
- package/docs/persona-panel.md +433 -0
- package/docs/pi-setup.md +115 -0
- package/docs/plugin-architecture-v3.md +296 -0
- package/docs/pm-skills-marketplace.md +114 -0
- package/docs/policy-cache-validation-2026-04-28.md +118 -0
- package/docs/rule-authoring.md +316 -0
- package/docs/session-config-reference.md +1439 -0
- package/docs/session-config-template.md +961 -0
- package/docs/vault-docs-architecture.md +297 -0
- package/hooks/_lib/lock-bootstrap.mjs +272 -0
- package/hooks/_lib/lock-reconcile.mjs +93 -0
- package/hooks/_lib/profile-gate.mjs +95 -0
- package/hooks/_lib/transcript-history.mjs +211 -0
- package/hooks/agent-teams-h3-test.sh +362 -0
- package/hooks/config-protection.mjs +0 -0
- package/hooks/cwd-change-restore.mjs +131 -0
- package/hooks/enforce-commands.mjs +179 -0
- package/hooks/enforce-scope.mjs +273 -0
- package/hooks/hooks-codex.json +60 -0
- package/hooks/hooks-cursor.json +15 -0
- package/hooks/hooks-pi.json +115 -0
- package/hooks/hooks.json +215 -0
- package/hooks/loop-guard.mjs +260 -0
- package/hooks/on-session-end.mjs +217 -0
- package/hooks/on-session-start.mjs +660 -0
- package/hooks/on-stop.mjs +294 -0
- package/hooks/operator-steer.mjs +64 -0
- package/hooks/post-edit-validate.mjs +225 -0
- package/hooks/post-subagent-discovery-validator.mjs +398 -0
- package/hooks/post-tool-batch-wave-signal.mjs +328 -0
- package/hooks/post-tool-failure-corrective-context.mjs +248 -0
- package/hooks/post-tooluse-frontend-slop.mjs +184 -0
- package/hooks/pre-bash-destructive-guard.mjs +515 -0
- package/hooks/pre-bash-memory-propose-audit.mjs +206 -0
- package/hooks/pre-bash-staging-fence.mjs +223 -0
- package/hooks/pre-bash-templates-first.mjs +404 -0
- package/hooks/run-node.sh +72 -0
- package/hooks/skill-invocation-telemetry.mjs +99 -0
- package/hooks/subagent-telemetry.mjs +249 -0
- package/hooks/wave-scope-commit-guard.mjs +191 -0
- package/monitors/monitors.json +14 -0
- package/output-styles/finding-report.md +48 -0
- package/output-styles/session-report.md +53 -0
- package/output-styles/wave-summary.md +38 -0
- package/package.json +94 -0
- package/pi/extensions/session-orchestrator.ts +25 -0
- package/pi/prompts/autopilot-multi.md +12 -0
- package/pi/prompts/autopilot.md +12 -0
- package/pi/prompts/bootstrap.md +12 -0
- package/pi/prompts/brainstorm.md +12 -0
- package/pi/prompts/close.md +11 -0
- package/pi/prompts/debug.md +12 -0
- package/pi/prompts/discovery.md +12 -0
- package/pi/prompts/dispatcher.md +12 -0
- package/pi/prompts/eval.md +12 -0
- package/pi/prompts/evolve.md +12 -0
- package/pi/prompts/go.md +12 -0
- package/pi/prompts/grill.md +12 -0
- package/pi/prompts/harness-audit.md +12 -0
- package/pi/prompts/memory-cleanup.md +12 -0
- package/pi/prompts/persona-panel.md +12 -0
- package/pi/prompts/plan.md +12 -0
- package/pi/prompts/portfolio.md +12 -0
- package/pi/prompts/reconcile.md +12 -0
- package/pi/prompts/repo-audit.md +12 -0
- package/pi/prompts/session.md +12 -0
- package/pi/prompts/spinout.md +12 -0
- package/pi/prompts/sunset-review.md +12 -0
- package/pi/prompts/templates-ack.md +12 -0
- package/pi/prompts/test.md +12 -0
- package/rules/_index.md +51 -0
- package/rules/always-on/commit-discipline.md +26 -0
- package/rules/always-on/npm-quality-gates.md +26 -0
- package/rules/always-on/parallel-sessions.md +43 -0
- package/rules/opt-in-domain/prompt-caching.md +270 -0
- package/rules/opt-in-stack/backend-data.md +188 -0
- package/rules/opt-in-stack/backend.md +390 -0
- package/rules/opt-in-stack/frontend.md +98 -0
- package/rules/opt-in-stack/security-web.md +194 -0
- package/rules/opt-in-stack/swift.md +65 -0
- package/scripts/archive-closed-prds.mjs +416 -0
- package/scripts/autopilot-multi.mjs +802 -0
- package/scripts/autopilot.mjs +383 -0
- package/scripts/backfill-abandoned-sessions.mjs +265 -0
- package/scripts/backfill-learnings-expires.mjs +196 -0
- package/scripts/backfill-learnings.mjs +203 -0
- package/scripts/backfill-sessions.mjs +282 -0
- package/scripts/check-doc-consistency.sh +279 -0
- package/scripts/check-package-manager.mjs +445 -0
- package/scripts/ci/assert-vitest-green.mjs +267 -0
- package/scripts/codex-install.mjs +435 -0
- package/scripts/compute-grounding-injection.sh +186 -0
- package/scripts/cursor-install.mjs +113 -0
- package/scripts/dialectic-deriver.mjs +573 -0
- package/scripts/emit-event.mjs +160 -0
- package/scripts/emit-session.mjs +212 -0
- package/scripts/eval-session.mjs +262 -0
- package/scripts/export-hw-learnings.mjs +437 -0
- package/scripts/gc-stale-worktrees.mjs +666 -0
- package/scripts/generate-pi-prompts.mjs +127 -0
- package/scripts/harness-audit.mjs +287 -0
- package/scripts/lib/agent-frontmatter.mjs +266 -0
- package/scripts/lib/agent-output-schema.mjs +166 -0
- package/scripts/lib/agent-status.mjs +303 -0
- package/scripts/lib/ajv-loader.mjs +34 -0
- package/scripts/lib/auto-dialectic.mjs +382 -0
- package/scripts/lib/auto-dream.mjs +471 -0
- package/scripts/lib/autonomy/suitability.mjs +212 -0
- package/scripts/lib/autopilot/dep-graph.mjs +417 -0
- package/scripts/lib/autopilot/durable-telemetry.mjs +121 -0
- package/scripts/lib/autopilot/flags.mjs +104 -0
- package/scripts/lib/autopilot/kill-switches.mjs +174 -0
- package/scripts/lib/autopilot/loop.mjs +320 -0
- package/scripts/lib/autopilot/mr-draft.mjs +520 -0
- package/scripts/lib/autopilot/multi-killswitch.mjs +184 -0
- package/scripts/lib/autopilot/recent-runs.mjs +106 -0
- package/scripts/lib/autopilot/stall-sampler.mjs +97 -0
- package/scripts/lib/autopilot/telemetry.mjs +224 -0
- package/scripts/lib/autopilot/worktree-pipeline.mjs +605 -0
- package/scripts/lib/autopilot-telemetry.mjs +11 -0
- package/scripts/lib/autopilot.mjs +39 -0
- package/scripts/lib/backlog-scan.mjs +179 -0
- package/scripts/lib/bootstrap-lock-freshness.mjs +260 -0
- package/scripts/lib/bootstrap-lock-refresh.mjs +186 -0
- package/scripts/lib/build-live-signals.mjs +150 -0
- package/scripts/lib/ci-status-banner.mjs +425 -0
- package/scripts/lib/claude-md-budget-lint.mjs +246 -0
- package/scripts/lib/cli-flags.mjs +158 -0
- package/scripts/lib/codex/plugin-contract.mjs +610 -0
- package/scripts/lib/cold-start-detector.mjs +240 -0
- package/scripts/lib/command-blocker.mjs +458 -0
- package/scripts/lib/common.mjs +333 -0
- package/scripts/lib/config/auto-dream.mjs +77 -0
- package/scripts/lib/config/block-header.mjs +94 -0
- package/scripts/lib/config/broken-window.mjs +114 -0
- package/scripts/lib/config/coercers.mjs +248 -0
- package/scripts/lib/config/cold-start.mjs +92 -0
- package/scripts/lib/config/config-protection.mjs +120 -0
- package/scripts/lib/config/cross-repo.mjs +104 -0
- package/scripts/lib/config/custom-phases.mjs +213 -0
- package/scripts/lib/config/dialectic.mjs +92 -0
- package/scripts/lib/config/discovery-validator.mjs +75 -0
- package/scripts/lib/config/dispatcher-autonomy-capture.mjs +240 -0
- package/scripts/lib/config/dispatcher-autonomy.mjs +152 -0
- package/scripts/lib/config/docs-orchestrator.mjs +90 -0
- package/scripts/lib/config/docs-staleness.mjs +96 -0
- package/scripts/lib/config/drift-check.mjs +155 -0
- package/scripts/lib/config/eval.mjs +130 -0
- package/scripts/lib/config/events-rotation.mjs +74 -0
- package/scripts/lib/config/evolve.mjs +308 -0
- package/scripts/lib/config/frontend-slop-hook.mjs +104 -0
- package/scripts/lib/config/gitlab-portfolio.mjs +150 -0
- package/scripts/lib/config/handover-gate.mjs +106 -0
- package/scripts/lib/config/host-paths.mjs +76 -0
- package/scripts/lib/config/io.mjs +54 -0
- package/scripts/lib/config/loop-guard.mjs +117 -0
- package/scripts/lib/config/memory.mjs +150 -0
- package/scripts/lib/config/persona-gate-wave.mjs +258 -0
- package/scripts/lib/config/reconcile.mjs +205 -0
- package/scripts/lib/config/section-extractor.mjs +100 -0
- package/scripts/lib/config/skill-evolution.mjs +112 -0
- package/scripts/lib/config/slopcheck.mjs +99 -0
- package/scripts/lib/config/state-md-lock.mjs +83 -0
- package/scripts/lib/config/templates-first.mjs +94 -0
- package/scripts/lib/config/test.mjs +113 -0
- package/scripts/lib/config/vault-integration.mjs +201 -0
- package/scripts/lib/config/vault-mirror-quality.mjs +99 -0
- package/scripts/lib/config/vault-staleness.mjs +84 -0
- package/scripts/lib/config/vault-sync.mjs +96 -0
- package/scripts/lib/config/verification-auto-fix.mjs +84 -0
- package/scripts/lib/config/wave-reviewers.mjs +133 -0
- package/scripts/lib/config-schema.mjs +345 -0
- package/scripts/lib/config.mjs +474 -0
- package/scripts/lib/convergence-monitor.mjs +389 -0
- package/scripts/lib/coordinator-snapshot.mjs +371 -0
- package/scripts/lib/crypto-digest-utils.mjs +91 -0
- package/scripts/lib/discovery/helpers.mjs +127 -0
- package/scripts/lib/discovery/triage-state.mjs +279 -0
- package/scripts/lib/dispatcher/cli.mjs +257 -0
- package/scripts/lib/dispatcher/enumerate.mjs +243 -0
- package/scripts/lib/dispatcher/rank.mjs +363 -0
- package/scripts/lib/ecosystem-health.mjs +224 -0
- package/scripts/lib/ecosystem-wizard/ci-detector.mjs +18 -0
- package/scripts/lib/ecosystem-wizard/config-parser.mjs +54 -0
- package/scripts/lib/ecosystem-wizard/config-writer.mjs +287 -0
- package/scripts/lib/ecosystem-wizard/package-manager-detector.mjs +42 -0
- package/scripts/lib/ecosystem-wizard/wizard-prompt.mjs +246 -0
- package/scripts/lib/ecosystem-wizard.mjs +48 -0
- package/scripts/lib/env-check.mjs +89 -0
- package/scripts/lib/eval/engine.mjs +605 -0
- package/scripts/lib/eval/judge.mjs +433 -0
- package/scripts/lib/eval/report.mjs +367 -0
- package/scripts/lib/eval/schema.mjs +618 -0
- package/scripts/lib/eval/session-resolve.mjs +137 -0
- package/scripts/lib/eval/sink.mjs +77 -0
- package/scripts/lib/events-rotation.mjs +86 -0
- package/scripts/lib/events-schema.mjs +81 -0
- package/scripts/lib/events.mjs +80 -0
- package/scripts/lib/evolve/autonomy-verdict.mjs +461 -0
- package/scripts/lib/evolve/autopilot-effectiveness.mjs +293 -0
- package/scripts/lib/exclusivity-matrix.mjs +68 -0
- package/scripts/lib/fetch-baseline.mjs +311 -0
- package/scripts/lib/file-lock.mjs +512 -0
- package/scripts/lib/frontend-detect/detect.mjs +138 -0
- package/scripts/lib/frontend-detect/rules.mjs +295 -0
- package/scripts/lib/frontmatter-guard.mjs +241 -0
- package/scripts/lib/gates/echo-stub-detect.mjs +39 -0
- package/scripts/lib/gates/gate-baseline.mjs +42 -0
- package/scripts/lib/gates/gate-full.mjs +85 -0
- package/scripts/lib/gates/gate-helpers.mjs +231 -0
- package/scripts/lib/gates/gate-incremental.mjs +76 -0
- package/scripts/lib/gates/gate-per-file.mjs +55 -0
- package/scripts/lib/gitlab-ops/stale-mr-sweep.mjs +447 -0
- package/scripts/lib/gitlab-portfolio/aggregator.mjs +383 -0
- package/scripts/lib/gitlab-portfolio/cli.mjs +428 -0
- package/scripts/lib/gitlab-portfolio/markdown-writer.mjs +289 -0
- package/scripts/lib/gitlab-portfolio/vcs-detect.mjs +182 -0
- package/scripts/lib/handover-gate.mjs +222 -0
- package/scripts/lib/hardening.mjs +43 -0
- package/scripts/lib/hardware-pattern-detector.mjs +238 -0
- package/scripts/lib/harness-audit/categories/category1.mjs +123 -0
- package/scripts/lib/harness-audit/categories/category2.mjs +145 -0
- package/scripts/lib/harness-audit/categories/category3.mjs +143 -0
- package/scripts/lib/harness-audit/categories/category4.mjs +202 -0
- package/scripts/lib/harness-audit/categories/category5.mjs +152 -0
- package/scripts/lib/harness-audit/categories/category6.mjs +211 -0
- package/scripts/lib/harness-audit/categories/category7.mjs +125 -0
- package/scripts/lib/harness-audit/categories/category8.mjs +328 -0
- package/scripts/lib/harness-audit/categories/category9.mjs +294 -0
- package/scripts/lib/harness-audit/categories/helpers.mjs +165 -0
- package/scripts/lib/harness-audit/categories.mjs +19 -0
- package/scripts/lib/historical-guard.mjs +15 -0
- package/scripts/lib/host-identity.mjs +262 -0
- package/scripts/lib/instruction-budget-guard.mjs +332 -0
- package/scripts/lib/io.mjs +304 -0
- package/scripts/lib/issue-close-strip-labels.mjs +161 -0
- package/scripts/lib/language-mappers/README.md +57 -0
- package/scripts/lib/language-mappers/index.mjs +165 -0
- package/scripts/lib/language-mappers/markdown.mjs +149 -0
- package/scripts/lib/language-mappers/python.mjs +249 -0
- package/scripts/lib/language-mappers/swift.mjs +201 -0
- package/scripts/lib/language-mappers/typescript.mjs +433 -0
- package/scripts/lib/learnings/expiry-sweep.mjs +164 -0
- package/scripts/lib/learnings/filters.mjs +43 -0
- package/scripts/lib/learnings/io.mjs +255 -0
- package/scripts/lib/learnings/schema.mjs +518 -0
- package/scripts/lib/learnings/surface.mjs +207 -0
- package/scripts/lib/learnings.mjs +42 -0
- package/scripts/lib/lock-reaper.mjs +648 -0
- package/scripts/lib/locks/index.mjs +31 -0
- package/scripts/lib/locks/lock-body.mjs +62 -0
- package/scripts/lib/locks/staging-fence-lock.mjs +267 -0
- package/scripts/lib/locks/state-md-lock.mjs +351 -0
- package/scripts/lib/loop-readiness-banner.mjs +144 -0
- package/scripts/lib/memory-banner.mjs +478 -0
- package/scripts/lib/memory-cleanup/worktree-sweep.mjs +108 -0
- package/scripts/lib/memory-cleanup-stamp.mjs +56 -0
- package/scripts/lib/memory-paths.mjs +31 -0
- package/scripts/lib/memory-proposals/collector.mjs +334 -0
- package/scripts/lib/memory-proposals/schema.mjs +289 -0
- package/scripts/lib/memory-proposals/sink.mjs +507 -0
- package/scripts/lib/memory-proposals/store.mjs +441 -0
- package/scripts/lib/mission-status-schema.mjs +114 -0
- package/scripts/lib/mode-selector/alternatives.mjs +64 -0
- package/scripts/lib/mode-selector/constants.mjs +29 -0
- package/scripts/lib/mode-selector/context-pressure.mjs +157 -0
- package/scripts/lib/mode-selector/rationale.mjs +55 -0
- package/scripts/lib/mode-selector/scoring.mjs +221 -0
- package/scripts/lib/mode-selector-accuracy.mjs +121 -0
- package/scripts/lib/mode-selector.mjs +160 -0
- package/scripts/lib/multi-provider-build/providers.mjs +64 -0
- package/scripts/lib/multi-provider-build/templating.mjs +130 -0
- package/scripts/lib/named-baseline-resolver.mjs +233 -0
- package/scripts/lib/named-vault-resolver.mjs +433 -0
- package/scripts/lib/owner-config/coerce.mjs +29 -0
- package/scripts/lib/owner-config/constants.mjs +21 -0
- package/scripts/lib/owner-config/defaults.mjs +50 -0
- package/scripts/lib/owner-config/error.mjs +19 -0
- package/scripts/lib/owner-config/index.mjs +13 -0
- package/scripts/lib/owner-config/merge.mjs +52 -0
- package/scripts/lib/owner-config/validate.mjs +259 -0
- package/scripts/lib/owner-config-banner.mjs +126 -0
- package/scripts/lib/owner-config-loader.mjs +159 -0
- package/scripts/lib/owner-config.example.yaml +72 -0
- package/scripts/lib/owner-config.mjs +28 -0
- package/scripts/lib/owner-interview.mjs +243 -0
- package/scripts/lib/owner-yaml.mjs +571 -0
- package/scripts/lib/package-manager.mjs +160 -0
- package/scripts/lib/path-utils.mjs +217 -0
- package/scripts/lib/peer-cards/merger.mjs +310 -0
- package/scripts/lib/peer-cards/reader.mjs +125 -0
- package/scripts/lib/peer-cards/schema.mjs +230 -0
- package/scripts/lib/peer-cards/staleness-banner.mjs +86 -0
- package/scripts/lib/peer-cards/writer.mjs +138 -0
- package/scripts/lib/peer-discovery.mjs +200 -0
- package/scripts/lib/persona-panel/catalog-loader.mjs +577 -0
- package/scripts/lib/persona-panel/consolidator.mjs +370 -0
- package/scripts/lib/persona-panel/persona-runner.mjs +375 -0
- package/scripts/lib/persona-panel/threshold.mjs +130 -0
- package/scripts/lib/pi-hook-bridge.mjs +328 -0
- package/scripts/lib/platform.mjs +266 -0
- package/scripts/lib/playwright-driver/runner.mjs +297 -0
- package/scripts/lib/plugin-root.mjs +210 -0
- package/scripts/lib/pre-dispatch-check.mjs +126 -0
- package/scripts/lib/product-repo-detect.mjs +121 -0
- package/scripts/lib/profiles/registry.mjs +176 -0
- package/scripts/lib/profiles/schema.mjs +209 -0
- package/scripts/lib/qg-command-drift-banner.mjs +88 -0
- package/scripts/lib/quality-gate/diagnostics.mjs +92 -0
- package/scripts/lib/quality-gate.mjs +536 -0
- package/scripts/lib/quality-gates-cache.mjs +228 -0
- package/scripts/lib/quality-gates-policy.mjs +95 -0
- package/scripts/lib/recommendations-v0.mjs +156 -0
- package/scripts/lib/reconcile/eligibility.mjs +203 -0
- package/scripts/lib/reconcile/emitter.mjs +244 -0
- package/scripts/lib/reconcile/engine.mjs +412 -0
- package/scripts/lib/reconcile/idempotency.mjs +239 -0
- package/scripts/lib/reconcile/renderer.mjs +211 -0
- package/scripts/lib/reconcile/writer.mjs +293 -0
- package/scripts/lib/reconcile-nudge-banner.mjs +284 -0
- package/scripts/lib/resource-probe/evaluate.mjs +190 -0
- package/scripts/lib/resource-probe/parsers.mjs +181 -0
- package/scripts/lib/resource-probe/probe-platform.mjs +300 -0
- package/scripts/lib/resource-probe.mjs +95 -0
- package/scripts/lib/rule-loader.mjs +552 -0
- package/scripts/lib/rules-sync.mjs +439 -0
- package/scripts/lib/scope-gate.mjs +496 -0
- package/scripts/lib/session-close-backfill.mjs +539 -0
- package/scripts/lib/session-discovery.mjs +256 -0
- package/scripts/lib/session-end/phase-skip.mjs +357 -0
- package/scripts/lib/session-end/worktree-cleanup.mjs +112 -0
- package/scripts/lib/session-id.mjs +362 -0
- package/scripts/lib/session-lock.mjs +703 -0
- package/scripts/lib/session-registry.mjs +355 -0
- package/scripts/lib/session-schema/aliases.mjs +71 -0
- package/scripts/lib/session-schema/constants.mjs +115 -0
- package/scripts/lib/session-schema/normalizer.mjs +66 -0
- package/scripts/lib/session-schema/timestamps.mjs +64 -0
- package/scripts/lib/session-schema/validator.mjs +453 -0
- package/scripts/lib/session-schema.mjs +71 -0
- package/scripts/lib/session-token-rollup.mjs +137 -0
- package/scripts/lib/sessions-staleness-banner.mjs +247 -0
- package/scripts/lib/skill-evolution/blast-radius-classifier.mjs +114 -0
- package/scripts/lib/skill-evolution/candidate-intake.mjs +270 -0
- package/scripts/lib/skill-evolution/config-validation-gate.mjs +279 -0
- package/scripts/lib/skill-evolution/engine.mjs +719 -0
- package/scripts/lib/skill-evolution/idempotency.mjs +279 -0
- package/scripts/lib/skill-evolution/mr-opener.mjs +507 -0
- package/scripts/lib/skill-health/join.mjs +181 -0
- package/scripts/lib/skill-health/score.mjs +123 -0
- package/scripts/lib/skill-invocations-schema.mjs +214 -0
- package/scripts/lib/skill-judge.mjs +348 -0
- package/scripts/lib/skill-judgments-schema.mjs +264 -0
- package/scripts/lib/slopcheck.mjs +501 -0
- package/scripts/lib/soul-resolve.mjs +118 -0
- package/scripts/lib/spiral-carryover.mjs +495 -0
- package/scripts/lib/state-md/body-sections.mjs +851 -0
- package/scripts/lib/state-md/frontmatter-mutators.mjs +453 -0
- package/scripts/lib/state-md/mission-status.mjs +247 -0
- package/scripts/lib/state-md/recommendations.mjs +57 -0
- package/scripts/lib/state-md/yaml-parser.mjs +234 -0
- package/scripts/lib/state-md-peer-guard.mjs +232 -0
- package/scripts/lib/state-md.mjs +53 -0
- package/scripts/lib/subagents-schema.mjs +309 -0
- package/scripts/lib/sunset/walker.mjs +1192 -0
- package/scripts/lib/test-runner/artifact-paths.mjs +94 -0
- package/scripts/lib/test-runner/fingerprint.mjs +33 -0
- package/scripts/lib/test-runner/issue-reconcile.mjs +770 -0
- package/scripts/lib/tmux-layout/layouts.mjs +224 -0
- package/scripts/lib/tmux-layout/telemetry-stats.mjs +100 -0
- package/scripts/lib/tmux-layout/telemetry.mjs +88 -0
- package/scripts/lib/tmux-layout/tmux-shell.mjs +82 -0
- package/scripts/lib/tmux-layout/vcs-detector.mjs +88 -0
- package/scripts/lib/validate/check-agents.mjs +457 -0
- package/scripts/lib/validate/check-codex-plugin.mjs +37 -0
- package/scripts/lib/validate/check-commands.mjs +148 -0
- package/scripts/lib/validate/check-component-paths.mjs +112 -0
- package/scripts/lib/validate/check-dead-bridge.mjs +180 -0
- package/scripts/lib/validate/check-hooks-symmetry.mjs +258 -0
- package/scripts/lib/validate/check-json-files.mjs +116 -0
- package/scripts/lib/validate/check-owner-leakage.mjs +1011 -0
- package/scripts/lib/validate/check-path-utils-canary.mjs +175 -0
- package/scripts/lib/validate/check-peekaboo-driver-canary.mjs +201 -0
- package/scripts/lib/validate/check-pi-package.mjs +110 -0
- package/scripts/lib/validate/check-pi-prompts.mjs +43 -0
- package/scripts/lib/validate/check-playwright-mcp-canary.mjs +154 -0
- package/scripts/lib/validate/check-plugin-json.mjs +96 -0
- package/scripts/lib/validate/check-plugin-monitors.mjs +206 -0
- package/scripts/lib/validate/check-plugin-schema.mjs +137 -0
- package/scripts/lib/validate/check-rules.mjs +143 -0
- package/scripts/lib/validate/check-session-plan-routing.mjs +154 -0
- package/scripts/lib/validate/check-test-fixture-shapes.mjs +280 -0
- package/scripts/lib/validate/check-unicode-safety.mjs +533 -0
- package/scripts/lib/validate/confidential-names.mjs +169 -0
- package/scripts/lib/validate/dead-bridge-corpus.mjs +141 -0
- package/scripts/lib/validate/dead-bridge-detectors.mjs +568 -0
- package/scripts/lib/validate/tier-inference.mjs +100 -0
- package/scripts/lib/validate-vendored-rules.mjs +519 -0
- package/scripts/lib/vault-archive.mjs +404 -0
- package/scripts/lib/vault-backfill/glab.mjs +164 -0
- package/scripts/lib/vault-backfill/manifest.mjs +75 -0
- package/scripts/lib/vault-backfill/template.mjs +130 -0
- package/scripts/lib/vault-consolidate-fs.mjs +331 -0
- package/scripts/lib/vault-migration-rules.mjs +155 -0
- package/scripts/lib/vault-mirror/auto-commit.mjs +203 -0
- package/scripts/lib/vault-mirror/namespace.mjs +152 -0
- package/scripts/lib/vault-mirror/process.mjs +567 -0
- package/scripts/lib/vault-mirror/pseudonym-map.mjs +164 -0
- package/scripts/lib/vault-mirror/render-learnings.mjs +201 -0
- package/scripts/lib/vault-mirror/render-sessions.mjs +367 -0
- package/scripts/lib/vault-mirror/render.mjs +8 -0
- package/scripts/lib/vault-mirror/utils.mjs +217 -0
- package/scripts/lib/vault-relocation-rules.mjs +555 -0
- package/scripts/lib/vault-repo-backfill.mjs +235 -0
- package/scripts/lib/vault-staleness-banner.mjs +142 -0
- package/scripts/lib/vault-status/board-writer.mjs +769 -0
- package/scripts/lib/vault-status/narrative-mirror.mjs +544 -0
- package/scripts/lib/vault-sync-baseline.mjs +152 -0
- package/scripts/lib/wave-context.mjs +29 -0
- package/scripts/lib/wave-executor/pool.mjs +248 -0
- package/scripts/lib/wave-resource-gate.mjs +204 -0
- package/scripts/lib/wave-sizing.mjs +75 -0
- package/scripts/lib/webhook-url.mjs +105 -0
- package/scripts/lib/workspace.mjs +198 -0
- package/scripts/lib/worktree/constants.mjs +35 -0
- package/scripts/lib/worktree/index.mjs +17 -0
- package/scripts/lib/worktree/lifecycle.mjs +287 -0
- package/scripts/lib/worktree/listing.mjs +118 -0
- package/scripts/lib/worktree/meta.mjs +64 -0
- package/scripts/lib/worktree-freshness.mjs +313 -0
- package/scripts/lib/worktree.mjs +15 -0
- package/scripts/lifecycle-sim-v6.mjs +347 -0
- package/scripts/lock-reaper.mjs +185 -0
- package/scripts/mcp-server.sh +241 -0
- package/scripts/measure-policy-cache-effectiveness.mjs +427 -0
- package/scripts/memory-propose.mjs +464 -0
- package/scripts/migrate-cold-start-seed.mjs +404 -0
- package/scripts/migrate-learnings-jsonl.mjs +189 -0
- package/scripts/migrate-legacy-learnings.sh +61 -0
- package/scripts/migrate-sessions-jsonl.mjs +448 -0
- package/scripts/migrate-subagents-jsonl.mjs +196 -0
- package/scripts/migrate-vault-paths.mjs +796 -0
- package/scripts/parse-config.mjs +149 -0
- package/scripts/pi-install.mjs +117 -0
- package/scripts/print-applicable-rules.mjs +247 -0
- package/scripts/promote-vault-strict.mjs +496 -0
- package/scripts/relocate-vault-corpus.mjs +1178 -0
- package/scripts/run-migrate-v2-cross-repo.mjs +385 -0
- package/scripts/run-quality-gate.mjs +216 -0
- package/scripts/spikes/h3-agent-teams/preflight.sh +53 -0
- package/scripts/spikes/h3-agent-teams/run-h3.sh +112 -0
- package/scripts/spikes/h3-agent-teams/setup.sh +137 -0
- package/scripts/spikes/h3-agent-teams/toggle.sh +38 -0
- package/scripts/sweep-expired-learnings.mjs +135 -0
- package/scripts/sync-vault-schema.mjs +376 -0
- package/scripts/tests/fixtures/fetch-baseline/sample-rule.md +8 -0
- package/scripts/tmux-layout.mjs +245 -0
- package/scripts/token-audit.sh +191 -0
- package/scripts/typecheck.mjs +42 -0
- package/scripts/upload-social-preview.mjs +316 -0
- package/scripts/validate-config.mjs +46 -0
- package/scripts/validate-plugin-manifests.mjs +163 -0
- package/scripts/validate-plugin.mjs +264 -0
- package/scripts/validate-wave-scope.mjs +289 -0
- package/scripts/vault-backfill.mjs +404 -0
- package/scripts/vault-consolidate.mjs +596 -0
- package/scripts/vault-integration-watcher.mjs +394 -0
- package/scripts/vault-mirror.mjs +430 -0
- package/skills/_shared/bootstrap-gate.md +111 -0
- package/skills/_shared/config-reading.md +226 -0
- package/skills/_shared/instruction-file-resolution.md +79 -0
- package/skills/_shared/model-selection.md +64 -0
- package/skills/_shared/monitor-patterns.md +300 -0
- package/skills/_shared/parallel-aware-auq.md +121 -0
- package/skills/_shared/parallel-aware-preamble.md +185 -0
- package/skills/_shared/platform-tools.md +96 -0
- package/skills/_shared/state-ownership.md +221 -0
- package/skills/architecture/DEEPENING.md +37 -0
- package/skills/architecture/INTERFACE-DESIGN.md +44 -0
- package/skills/architecture/LANGUAGE.md +53 -0
- package/skills/architecture/SKILL.md +92 -0
- package/skills/autopilot/SKILL.md +419 -0
- package/skills/bootstrap/SKILL.md +592 -0
- package/skills/bootstrap/STATE.md.template +24 -0
- package/skills/bootstrap/_shared-template.md +243 -0
- package/skills/bootstrap/deep-template.md +659 -0
- package/skills/bootstrap/fast-template.md +251 -0
- package/skills/bootstrap/intensity-heuristic.md +80 -0
- package/skills/bootstrap/public-fallback.md +342 -0
- package/skills/bootstrap/standard-template.md +736 -0
- package/skills/bootstrap/templates/agents/project-code-review.md +18 -0
- package/skills/bootstrap/templates/agents/project-discovery.md +18 -0
- package/skills/bootstrap/templates/agents/project-quality-gate.md +18 -0
- package/skills/brainstorm/SKILL.md +268 -0
- package/skills/brainstorm/soul.md +49 -0
- package/skills/claude-md-drift-check/SKILL.md +186 -0
- package/skills/claude-md-drift-check/checker.mjs +1380 -0
- package/skills/claude-md-drift-check/checker.sh +37 -0
- package/skills/claude-md-drift-check/package.json +16 -0
- package/skills/convergence-monitoring/README.md +39 -0
- package/skills/convergence-monitoring/SIGNALS.md +246 -0
- package/skills/convergence-monitoring/SKILL.md +285 -0
- package/skills/daily/SKILL.md +222 -0
- package/skills/daily/generate.sh +92 -0
- package/skills/daily/templates/daily.md.tpl +36 -0
- package/skills/debug/SKILL.md +188 -0
- package/skills/debug/soul.md +35 -0
- package/skills/discovery/SKILL.md +567 -0
- package/skills/discovery/issue-templates.md +237 -0
- package/skills/discovery/probes/docs-staleness.mjs +195 -0
- package/skills/discovery/probes/frontend-slop.mjs +186 -0
- package/skills/discovery/probes/ssot-code-diff.mjs +310 -0
- package/skills/discovery/probes/supply-chain-slopcheck.mjs +440 -0
- package/skills/discovery/probes/vault-narrative-staleness.mjs +355 -0
- package/skills/discovery/probes/vault-staleness.mjs +272 -0
- package/skills/discovery/probes-arch.md +252 -0
- package/skills/discovery/probes-audit.md +95 -0
- package/skills/discovery/probes-code.md +329 -0
- package/skills/discovery/probes-docs.md +76 -0
- package/skills/discovery/probes-feature.md +150 -0
- package/skills/discovery/probes-infra.md +138 -0
- package/skills/discovery/probes-intro.md +25 -0
- package/skills/discovery/probes-session.md +495 -0
- package/skills/discovery/probes-supply-chain.md +94 -0
- package/skills/discovery/probes-ui.md +147 -0
- package/skills/discovery/probes-vault.md +64 -0
- package/skills/discovery/slop-patterns.md +115 -0
- package/skills/dispatcher/SKILL.md +173 -0
- package/skills/docs-orchestrator/SKILL.md +362 -0
- package/skills/docs-orchestrator/audience-mapping.md +140 -0
- package/skills/domain-model/ADR-FORMAT.md +47 -0
- package/skills/domain-model/CONTEXT-FORMAT.md +77 -0
- package/skills/domain-model/SKILL.md +85 -0
- package/skills/ecosystem-health/SKILL.md +119 -0
- package/skills/ecosystem-health/wizard.md +193 -0
- package/skills/eval/SKILL.md +293 -0
- package/skills/eval/rubric-v1.md +218 -0
- package/skills/evolve/SKILL.md +546 -0
- package/skills/frontmatter-guard/SKILL.md +126 -0
- package/skills/gitlab-ops/SKILL.md +368 -0
- package/skills/gitlab-portfolio/SKILL.md +196 -0
- package/skills/grill/SKILL.md +185 -0
- package/skills/grill/soul.md +55 -0
- package/skills/hook-development/SKILL.md +413 -0
- package/skills/mcp-builder/SKILL.md +260 -0
- package/skills/memory-cleanup/SKILL.md +310 -0
- package/skills/mode-selector/SKILL.md +226 -0
- package/skills/peekaboo-driver/SKILL.md +237 -0
- package/skills/peekaboo-driver/soul.md +32 -0
- package/skills/persona-panel/SKILL.md +365 -0
- package/skills/persona-panel/persona-format.md +205 -0
- package/skills/persona-panel/presets/designer-lens.md +87 -0
- package/skills/persona-panel/presets/engineer-lens.md +88 -0
- package/skills/persona-panel/presets/pm-lens.md +86 -0
- package/skills/plan/SKILL.md +496 -0
- package/skills/plan/mode-feature.md +141 -0
- package/skills/plan/mode-new.md +297 -0
- package/skills/plan/mode-retro.md +271 -0
- package/skills/plan/prd-feature-template.md +132 -0
- package/skills/plan/prd-full-template.md +151 -0
- package/skills/plan/prd-reviewer-prompt.md +103 -0
- package/skills/plan/retro-template.md +75 -0
- package/skills/plan/soul.md +62 -0
- package/skills/playwright-driver/SKILL.md +226 -0
- package/skills/playwright-driver/soul.md +30 -0
- package/skills/quality-gates/SKILL.md +212 -0
- package/skills/reconcile/SKILL.md +324 -0
- package/skills/repo-audit/SKILL.md +272 -0
- package/skills/session-end/SKILL.md +1044 -0
- package/skills/session-end/discovery-scan.md +37 -0
- package/skills/session-end/drift-operations.md +97 -0
- package/skills/session-end/learning-patterns.md +78 -0
- package/skills/session-end/metrics-collection.md +175 -0
- package/skills/session-end/phase-3-2-docs-verification.md +148 -0
- package/skills/session-end/phase-3-6-tail.md +344 -0
- package/skills/session-end/phase-3-7a-recommendations.md +86 -0
- package/skills/session-end/plan-verification.md +288 -0
- package/skills/session-end/session-metrics-write.md +223 -0
- package/skills/session-end/vault-operations.md +50 -0
- package/skills/session-end/verification-checklist.md +20 -0
- package/skills/session-plan/SKILL.md +554 -0
- package/skills/session-plan/wave-template.md +37 -0
- package/skills/session-start/SKILL.md +1043 -0
- package/skills/session-start/phase-2-5-docs-planning.md +119 -0
- package/skills/session-start/phase-4-5-resource-health.md +49 -0
- package/skills/session-start/phase-7-1-premise-check.md +47 -0
- package/skills/session-start/phase-7-5-mode-selector.md +237 -0
- package/skills/session-start/phase-8-5-express-path.md +61 -0
- package/skills/session-start/presentation-format.md +81 -0
- package/skills/session-start/soul.md +57 -0
- package/skills/skill-creator/SKILL.md +168 -0
- package/skills/spinout/SKILL.md +76 -0
- package/skills/sunset-review/SKILL.md +96 -0
- package/skills/test-runner/SKILL.md +362 -0
- package/skills/test-runner/rubric-v1.md +388 -0
- package/skills/test-runner/soul.md +46 -0
- package/skills/tmux-layout/SKILL.md +104 -0
- package/skills/ubiquitous-language/SKILL.md +97 -0
- package/skills/using-orchestrator/SKILL.md +144 -0
- package/skills/vault-mirror/SKILL.md +234 -0
- package/skills/vault-sync/SKILL.md +319 -0
- package/skills/vault-sync/package-lock.json +40 -0
- package/skills/vault-sync/package.json +11 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/90-archive/bad-archived.md +8 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/live-note.md +8 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/bad-type.md +8 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/good-note.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/.obsidian/config.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/01-projects/foo/projects-baseline.md +10 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/03-daily/daily-2026-04-13.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/README.md +3 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/hello-world.md +11 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/has-dangling.md +9 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/real-target.md +8 -0
- package/skills/vault-sync/tests/fixtures/empty-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/missing-field-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/missing-field-vault/missing-id.md +7 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/03-daily/daily-2026-04-13.md +9 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/nested-tags-note.md +11 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/README.md +3 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_MOC.md +3 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/_MOC.md +11 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/hello-world.md +11 -0
- package/skills/vault-sync/tests/schema-drift.test.mjs +133 -0
- package/skills/vault-sync/validator.mjs +658 -0
- package/skills/vault-sync/validator.sh +55 -0
- package/skills/wave-executor/SKILL.md +496 -0
- package/skills/wave-executor/circuit-breaker.md +169 -0
- package/skills/wave-executor/wave-loop.md +1043 -0
- package/skills/write-executable-plan/SKILL.md +237 -0
- package/skills/write-executable-plan/plan-template.md +154 -0
- package/templates/_minimal/CLAUDE.md.tmpl +41 -0
- package/templates/_minimal/README.md.tmpl +15 -0
- package/templates/_minimal/gitignore.tmpl +47 -0
- package/templates/_shared/harte-regeln.md +16 -0
- package/templates/_shared/loop.md +90 -0
- package/templates/_shared/rules/parallel-sessions.md +77 -0
- package/templates/nextjs-minimal/README.md +30 -0
- package/templates/nextjs-minimal/app/layout.tsx +18 -0
- package/templates/nextjs-minimal/app/page.tsx +7 -0
- package/templates/nextjs-minimal/eslint.config.mjs +16 -0
- package/templates/nextjs-minimal/next.config.mjs +4 -0
- package/templates/nextjs-minimal/package.json +27 -0
- package/templates/nextjs-minimal/tsconfig.json +23 -0
- package/templates/node-minimal/README.md +33 -0
- package/templates/node-minimal/eslint.config.mjs +10 -0
- package/templates/node-minimal/package.json +21 -0
- package/templates/node-minimal/src/index.ts +1 -0
- package/templates/node-minimal/tests/sanity.test.ts +5 -0
- package/templates/node-minimal/tsconfig.json +17 -0
- package/templates/personas/README.md +150 -0
- package/templates/personas/accounting-compliance.v1.md +120 -0
- package/templates/personas/accounting-tax-advisor.v1.md +116 -0
- package/templates/personas/buyer-p1-cto.v1.md +125 -0
- package/templates/personas/buyer-p2-kanzlei.v1.md +134 -0
- package/templates/personas/buyer-p3-build.v1.md +130 -0
- package/templates/personas/buyer-p4-tech-veto.v1.md +130 -0
- package/templates/personas/buyer-p5-solo.v1.md +132 -0
- package/templates/personas/buyer-p6-ld.v1.md +130 -0
- package/templates/personas/klima-ai-expert.v1.md +114 -0
- package/templates/personas/klima-physicist.v1.md +117 -0
- package/templates/python-uv/README.md +28 -0
- package/templates/python-uv/pyproject.toml +32 -0
- package/templates/python-uv/src/__PROJECT_NAME__/__init__.py +0 -0
- package/templates/python-uv/src/__PROJECT_NAME__/main.py +6 -0
- package/templates/python-uv/tests/test_sanity.py +2 -0
- package/templates/static-html/README.md +19 -0
- package/templates/static-html/index.html +15 -0
- package/templates/static-html/script.js +1 -0
- package/templates/static-html/styles.css +26 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Vault & Docs Architecture — Umbrella Narrative
|
|
2
|
+
|
|
3
|
+
**Audience:** Plugin contributors (Dev). New contributors who need to understand
|
|
4
|
+
how the four documentation skills, one orchestrator skill, one agent, and two
|
|
5
|
+
discovery probes fit together — what fires when, who owns which file, and how
|
|
6
|
+
to recover when something breaks.
|
|
7
|
+
|
|
8
|
+
**Status:** Living document. Tracks Epic #229 (Vault & Docs Orchestration).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Purpose
|
|
13
|
+
|
|
14
|
+
The session-orchestrator plugin treats documentation as a first-class side
|
|
15
|
+
effect of every session, not a manual afterthought. Three problems motivate
|
|
16
|
+
the layer:
|
|
17
|
+
|
|
18
|
+
- **Cross-session memory loss.** A session ends, the chat closes, the next
|
|
19
|
+
session starts cold. Without a structured place to land decisions, status
|
|
20
|
+
changes, and learnings, every session re-discovers context. The Meta-Vault
|
|
21
|
+
(`~/Projects/vault`) is that place. Source: "Vault & Docs Orchestration" (#229; archived in the private Meta-Vault)
|
|
22
|
+
Section 1 ("Why" — 14 active projects, daily multi-session workflow).
|
|
23
|
+
- **Audience-specific documentation rotting in parallel.** READMEs,
|
|
24
|
+
`CLAUDE.md`, and Vault narratives drift independently because nothing
|
|
25
|
+
reminds the session to update them in lock-step with the diff. Source:
|
|
26
|
+
"Vault & Docs Orchestration" (#229; archived in the private Meta-Vault) Section 1 (no
|
|
27
|
+
Docs-Planning step in session-start; doku only touched in session-end Phase 3.1).
|
|
28
|
+
- **Operational telemetry without a home.** Wave outcomes, learnings, and
|
|
29
|
+
session metrics are JSONL on disk; humans need them as Markdown notes
|
|
30
|
+
cross-linked into the Vault graph. Source: `skills/vault-mirror/SKILL.md`
|
|
31
|
+
("Purpose" — converts JSONL into vault-conformant Markdown).
|
|
32
|
+
|
|
33
|
+
The architecture below ties these three concerns together with deliberate
|
|
34
|
+
non-overlap: each component owns a narrow slice of the documentation surface,
|
|
35
|
+
and the lifecycle hooks ensure the slices are written, validated, and
|
|
36
|
+
mirrored at the right phase.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 2. Architecture Diagram
|
|
41
|
+
|
|
42
|
+
Data flow within a single `/session feature → /go → /close` cycle:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
46
|
+
│ user invokes: /session feature → /go → /close │
|
|
47
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
48
|
+
↓
|
|
49
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
50
|
+
│ session-start │
|
|
51
|
+
│ Phase 2.5 docs-orchestrator (opt-in) │
|
|
52
|
+
│ └─ audience detection → docs-tasks block in STATE.md │
|
|
53
|
+
│ Source: skills/session-start/phase-2-5-docs-planning.md │
|
|
54
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
55
|
+
↓
|
|
56
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
57
|
+
│ session-plan │
|
|
58
|
+
│ Step 1.5 docs-writer added to agent registry │
|
|
59
|
+
│ Step 1.8 Docs-classified tasks → docs-writer assignment │
|
|
60
|
+
│ Source: skills/docs-orchestrator/SKILL.md (Invocation) │
|
|
61
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
62
|
+
↓
|
|
63
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
64
|
+
│ wave-executor │
|
|
65
|
+
│ dispatches docs-writer agent with the canonical four sources: │
|
|
66
|
+
│ diff │ git-log │ session-memory │ affected-files │
|
|
67
|
+
│ Source: agents/docs-writer.md (Inputs) │
|
|
68
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
69
|
+
↓
|
|
70
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
71
|
+
│ code/diff lands; tests run; metrics written │
|
|
72
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
73
|
+
↓
|
|
74
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
75
|
+
│ session-end │
|
|
76
|
+
│ Phase 2.1 vault-sync (frontmatter + wiki-link gate) │
|
|
77
|
+
│ Phase 2.2 claude-md-drift (5 narrative drift checks) │
|
|
78
|
+
│ Phase 2.3 vault-staleness (opt-in: stale projects) │
|
|
79
|
+
│ Phase 3.2 docs-verify (per-task ok/partial/gap) │
|
|
80
|
+
│ Phase 3.7 vault-mirror (sessions.jsonl → 50-sessions/) │
|
|
81
|
+
│ Source: skills/session-end/SKILL.md (phase markers) │
|
|
82
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
83
|
+
↓
|
|
84
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
85
|
+
│ Meta-Vault (~/Projects/vault) │
|
|
86
|
+
│ 01-projects/<slug>/ ← context.md / decisions.md / people.md │
|
|
87
|
+
│ (docs-writer, Vault audience) │
|
|
88
|
+
│ 01-projects/<slug>/ ← _overview.md (vault-mirror, no humans) │
|
|
89
|
+
│ 03-daily/YYYY-MM-DD.md (daily skill, idempotent) │
|
|
90
|
+
│ 40-learnings/<slug>.md (vault-mirror, evolve hook) │
|
|
91
|
+
│ 50-sessions/<id>.md (vault-mirror, session-end Phase 3.7) │
|
|
92
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
93
|
+
↓
|
|
94
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
95
|
+
│ /discovery vault — on-demand staleness probes │
|
|
96
|
+
│ vault-staleness.mjs + vault-narrative-staleness.mjs │
|
|
97
|
+
│ Source: skills/discovery/probes-vault.md │
|
|
98
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 3. Component Table
|
|
104
|
+
|
|
105
|
+
| Component | Owner | Trigger | Input | Output | Audience |
|
|
106
|
+
|-----------|-------|---------|-------|--------|----------|
|
|
107
|
+
| `vault-sync` | `skills/vault-sync/SKILL.md` | session-end Phase 2.1 (hard gate) | `VAULT_DIR/**/*.md` frontmatter + wiki-links | JSON report (`status`, `errors`, `warnings`) on stdout, exit code 0/1/2 | Dev (validation) |
|
|
108
|
+
| `claude-md-drift-check` | `skills/claude-md-drift-check/SKILL.md` | session-end Phase 2.2 (opt-in gate) | `CLAUDE.md`, `_meta/**/*.md` | JSON report with 5 named checks (path-resolver, project-count-sync, issue-reference-freshness, session-file-existence, command-count) | Dev (validation) |
|
|
109
|
+
| `vault-staleness` probes | `skills/discovery/probes-vault.md` + `skills/discovery/probes/vault-staleness.mjs` | `/discovery vault` (on-demand) and session-end Phase 2.3 (opt-in close-time gate) | `VAULT_DIR/01-projects/*/` `_overview.md` + narrative files | JSONL findings under `.orchestrator/metrics/vault-staleness.jsonl` and `vault-narrative-staleness.jsonl` | Vault/Ops (telemetry) |
|
|
110
|
+
| `docs-orchestrator` | `skills/docs-orchestrator/SKILL.md` | session-start Phase 2.5, session-plan Step 1.5/1.8, session-end Phase 3.2 (all gated on `enabled: true`) | Session scope + Session Config audience list | `docs-tasks` block in STATE.md (write side); `### Documentation Coverage` block in final report (verify side) | All three (User / Dev / Vault) |
|
|
111
|
+
| `docs-writer` agent | `agents/docs-writer.md` | Dispatched by `wave-executor` for each `Docs`-classified task | `diff`, `git-log`, `session-memory`, `affected-files` | Audience-targeted Markdown writes (Edit/Write); `[docs-orchestrator] Docs task complete` report line | All three (per task) |
|
|
112
|
+
| `daily` | `skills/daily/SKILL.md` | User-invocable (`/daily`), idempotent | `VAULT_DIR/03-daily/`, `templates/daily.md.tpl` | `<vault>/03-daily/YYYY-MM-DD.md` (created or no-op) | Vault/Ops (PKM anchor) |
|
|
113
|
+
| `vault-mirror` | `skills/vault-mirror/SKILL.md` + `scripts/vault-mirror.mjs` | session-end Phase 3.7 (sessions); evolve Phase 3.5 (learnings) | `.orchestrator/metrics/sessions.jsonl`, `.orchestrator/metrics/learnings.jsonl` | `<vault>/50-sessions/<id>.md`, `<vault>/40-learnings/<slug>.md` (`_generator` marker `session-orchestrator-vault-mirror@1`) | Vault/Ops (telemetry → Markdown) |
|
|
114
|
+
| `vault-backfill` CLI | `scripts/vault-backfill.mjs` | Manual, also surfaced via `/plan retro vault-backfill` sub-mode | `vault-integration.gitlab-groups` config + GitLab API | `.vault.yaml` per repo + Vault stub directories | Vault/Ops (one-shot migration) |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 4. Audience Model
|
|
119
|
+
|
|
120
|
+
Three audiences, three documentation surfaces. The split is enforced by
|
|
121
|
+
`skills/docs-orchestrator/audience-mapping.md` (Audiences & File Patterns
|
|
122
|
+
table), which is the **single source of truth** for which files belong to
|
|
123
|
+
which audience. Never inline this table elsewhere — always cross-link.
|
|
124
|
+
|
|
125
|
+
- **User** — external/internal users of the repo. Targets: `README.md`,
|
|
126
|
+
`docs/user/**/*.md`, `docs/getting-started.md`, `examples/**/*.md`. Source:
|
|
127
|
+
`skills/docs-orchestrator/audience-mapping.md` § Audiences & File Patterns.
|
|
128
|
+
- **Dev** — contributors to the repo, including future Claude sessions.
|
|
129
|
+
Targets: `CLAUDE.md`, `docs/dev/**/*.md`, `docs/adr/**/*.md`. Source: same.
|
|
130
|
+
- **Vault/Ops** — strategic continuity across sessions. Targets:
|
|
131
|
+
`<vault>/01-projects/<slug>/context.md`, `decisions.md`, `people.md`.
|
|
132
|
+
Source: same.
|
|
133
|
+
|
|
134
|
+
The Session Config field `docs-orchestrator.audiences` accepts any subset of
|
|
135
|
+
`[user, dev, vault]`; narrowing it (e.g., `[user, dev]` on a project without a
|
|
136
|
+
Vault) suppresses Vault-targeted docs without disabling the orchestrator
|
|
137
|
+
entirely. Source: `docs/session-config-reference.md` § Docs Orchestrator.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 5. Source-Cited Content Rule
|
|
142
|
+
|
|
143
|
+
The `docs-writer` agent operates under a **hallucination ban**: every
|
|
144
|
+
substantive paragraph must trace to one of the canonical four sources, or
|
|
145
|
+
carry an inline `<!-- REVIEW: source needed -->` marker. The four sources are
|
|
146
|
+
defined once and reused everywhere:
|
|
147
|
+
|
|
148
|
+
1. **diff** — `git diff $SESSION_START_REF..HEAD`
|
|
149
|
+
2. **git-log** — `git log $SESSION_START_REF..HEAD --format="%H %s%n%b"`
|
|
150
|
+
3. **session-memory** — `~/.claude/projects/<project>/memory/session-*.md` and
|
|
151
|
+
`.orchestrator/` outputs
|
|
152
|
+
4. **affected-files** — files in the wave-scope `allowedPaths` block
|
|
153
|
+
|
|
154
|
+
Source: `agents/docs-writer.md` § Inputs / Source Citation Rules and
|
|
155
|
+
`skills/docs-orchestrator/SKILL.md` Phase 4 (Source Grounding).
|
|
156
|
+
|
|
157
|
+
The `<!-- REVIEW: source needed -->` marker is **load-bearing**: it signals
|
|
158
|
+
to the human reviewer that a section needs verification before the next
|
|
159
|
+
release. The agent is explicitly forbidden from removing the marker to make
|
|
160
|
+
output appear cleaner. Source: `skills/docs-orchestrator/SKILL.md` Phase 5
|
|
161
|
+
("Sourceless content").
|
|
162
|
+
|
|
163
|
+
**Hard guard in Phase 4:** if ALL four source blocks are empty or absent in
|
|
164
|
+
the dispatched task prompt, the docs-writer aborts rather than producing
|
|
165
|
+
silent REVIEW-marker-only output. Source:
|
|
166
|
+
`skills/docs-orchestrator/SKILL.md` Phase 4 step 1.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 6. Non-Overlap Discipline
|
|
171
|
+
|
|
172
|
+
Three forbidden cross-writes are enforced by the architecture, not just by
|
|
173
|
+
convention:
|
|
174
|
+
|
|
175
|
+
- **`<vault>/01-projects/*/_overview.md` is owned by `vault-mirror`.** The
|
|
176
|
+
file is regenerated from JSONL metrics on every session-end Phase 3.7. A
|
|
177
|
+
second writer would corrupt the metrics-derived content or introduce human
|
|
178
|
+
prose that vault-mirror's next run overwrites silently. Source:
|
|
179
|
+
`skills/docs-orchestrator/audience-mapping.md` § Non-Overlap (vault-mirror
|
|
180
|
+
row) and `skills/vault-mirror/SKILL.md` § Idempotency (the `_generator`
|
|
181
|
+
marker `session-orchestrator-vault-mirror@1` is the discriminator).
|
|
182
|
+
- **`<vault>/03-daily/YYYY-MM-DD.md` is owned by `daily`.** Idempotent by
|
|
183
|
+
design — re-running `/daily` opens the existing note, never overwrites.
|
|
184
|
+
Source: `skills/daily/SKILL.md` § Idempotency Guarantee. A second writer
|
|
185
|
+
would corrupt the day's scratch notes. Source:
|
|
186
|
+
`skills/docs-orchestrator/audience-mapping.md` § Non-Overlap (daily row).
|
|
187
|
+
- **`CLAUDE.md` may be remediated by `docs-writer` (Dev audience), but
|
|
188
|
+
`claude-md-drift-check` only diagnoses it.** The two skills must not run
|
|
189
|
+
on `CLAUDE.md` in parallel within the same wave. Source:
|
|
190
|
+
`skills/docs-orchestrator/audience-mapping.md` § Non-Overlap
|
|
191
|
+
(claude-md-drift-check row).
|
|
192
|
+
|
|
193
|
+
The forbidden patterns are checked in `skills/docs-orchestrator/SKILL.md`
|
|
194
|
+
Phase 3 with an abort-on-match guard before any write occurs.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 7. Lifecycle
|
|
199
|
+
|
|
200
|
+
Concrete answer to "when does each component fire":
|
|
201
|
+
|
|
202
|
+
| Phase | Skill / Probe | Gating |
|
|
203
|
+
|-------|---------------|--------|
|
|
204
|
+
| `/session` start, Phase 2.5 | `docs-orchestrator` audience detection | `docs-orchestrator.enabled: true` |
|
|
205
|
+
| `/session` start, Phase 4.5 | resource-health probe | always (env-aware) |
|
|
206
|
+
| session-plan Step 1.5/1.8 | `docs-writer` registered + Docs role classified | `docs-orchestrator.enabled: true` |
|
|
207
|
+
| `/go` waves | `docs-writer` agent dispatched per Docs task | task present in plan |
|
|
208
|
+
| `/close` Phase 2.1 | `vault-sync` validator | `vault-sync.enabled: true` (hard gate by mode) |
|
|
209
|
+
| `/close` Phase 2.2 | `claude-md-drift-check` | `drift-check.enabled: true` |
|
|
210
|
+
| `/close` Phase 2.3 | `vault-staleness` + `vault-narrative-staleness` probes | `vault-staleness.enabled: true` |
|
|
211
|
+
| `/close` Phase 3.2 | `docs-orchestrator` verification | `docs-orchestrator.enabled: true` AND `docs-tasks` block present |
|
|
212
|
+
| `/close` Phase 3.7 | `vault-mirror` (sessions) | `vault-integration.enabled: true` AND `mode != off` |
|
|
213
|
+
| evolve Phase 3.5 | `vault-mirror` (learnings) | same as above |
|
|
214
|
+
| `/discovery vault` | `vault-staleness` probes (on-demand) | `.vault.yaml` present OR `vault-integration.enabled: true` |
|
|
215
|
+
| `/daily` | `daily` skill | user-invocable; no Session Config gate |
|
|
216
|
+
|
|
217
|
+
Sources: `skills/session-end/SKILL.md` (Phase markers), `docs/session-config-reference.md`
|
|
218
|
+
(per-skill enabled-flag semantics), `skills/discovery/probes-vault.md` (probe
|
|
219
|
+
activation rules).
|
|
220
|
+
|
|
221
|
+
The **opt-in default** is the design contract: when no Session Config block
|
|
222
|
+
is present for a given skill, that skill's hook short-circuits silently —
|
|
223
|
+
zero overhead. Source: "Vault & Docs Orchestration" (#229; archived in the private Meta-Vault)
|
|
224
|
+
Section 5 (Risk: "Marketplace-Kompatibilität — alle neuen Config-Felder
|
|
225
|
+
opt-in mit sicherem Default → zero-impact für bestehende Plugin-User").
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 8. Failure Modes & Escape Hatches
|
|
230
|
+
|
|
231
|
+
| What breaks | Symptom | Recovery |
|
|
232
|
+
|-------------|---------|----------|
|
|
233
|
+
| `vault-sync` finds invalid frontmatter, `mode: hard` | session-end Phase 2.1 blocks `/close` | Fix the offending file, re-run `/close`. Or temporarily set `vault-sync.mode: warn` to unblock and file an issue. Source: `skills/vault-sync/SKILL.md` § "How session-end invokes it" (exit 1 → block). |
|
|
234
|
+
| `claude-md-drift-check` finds stale issue refs, `mode: hard` | Phase 2.2 blocks `/close` | Update CLAUDE.md to reflect actual state, or set `drift-check.mode: warn`. Source: `skills/claude-md-drift-check/SKILL.md` § "Session-End Phase 2.2". |
|
|
235
|
+
| `vault-staleness` probe finds stale projects, `mode: strict` | Phase 2.3 blocks `/close` with interactive override | Run `/discovery vault` to triage; update narrative files, or use the AskUserQuestion override (logged to STATE.md). Source: `docs/session-config-reference.md` § Vault Staleness ("Mode behavior" table). |
|
|
236
|
+
| `docs-writer` cannot find a source for a section | Section is written with `<!-- REVIEW: source needed -->` | Human review before next release; do NOT remove the marker. Source: `skills/docs-orchestrator/SKILL.md` Phase 5. |
|
|
237
|
+
| `docs-writer` is dispatched with **all four** source blocks empty | Agent aborts with `docs-writer: no grounding sources available` | Coordinator surfaces the failure; fix the task spec to include at least one source. Source: `skills/docs-orchestrator/SKILL.md` Phase 4 step 1 (Hard guard). |
|
|
238
|
+
| `vault-mirror` finds a hand-written file at the target path | `skipped-handwritten` action emitted; file untouched | Intentional safety: human files are never overwritten. If the file should be regenerated, delete it manually. Source: `skills/vault-mirror/SKILL.md` § Idempotency item 4. |
|
|
239
|
+
| Session Config block absent | All hooks skip silently | Default behavior. To enable, add the relevant block per `docs/session-config-reference.md`. |
|
|
240
|
+
| `docs-orchestrator.mode: off` | Phase 2.5 / 3.2 read config but skip all execution | Lighter than `enabled: false` (config still parsed). Useful during onboarding. Source: `skills/docs-orchestrator/SKILL.md` § "Session Config Reference". |
|
|
241
|
+
| Repo lacks `.vault.yaml` but `vault-integration.enabled: true` | vault-sync warns "kein .vault.yaml gefunden" but does not block | Run `scripts/vault-backfill.mjs` (dry-run default) to generate. Source: "Vault & Docs Orchestration" (#229; archived in the private Meta-Vault) § Edge Cases. |
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## 9. Future Direction
|
|
246
|
+
|
|
247
|
+
**Epic #229 (Vault & Docs Orchestration) is in-progress.** Closed slices to
|
|
248
|
+
date (per CLAUDE.md "Current State"):
|
|
249
|
+
|
|
250
|
+
- docs-orchestrator skill + docs-writer agent (foundation #230, hooks #233 /
|
|
251
|
+
#234 / #235, config #236).
|
|
252
|
+
- vault-staleness probes + Phase 2.3 integration (#232, #242).
|
|
253
|
+
- vault-backfill CLI + `/plan retro vault-backfill` sub-mode (#241).
|
|
254
|
+
- vault-mirror auto-commit phase via `--session-id` (GH#31).
|
|
255
|
+
|
|
256
|
+
Source: `CLAUDE.md` § "Current State" and "Vault & Docs Orchestration" (#229; archived in the private Meta-Vault)
|
|
257
|
+
§ Sub-Epic A/B/C tracking lists.
|
|
258
|
+
|
|
259
|
+
**Open work:** Sub-Epic B (projects-baseline `setup-project.sh` Vault auto-
|
|
260
|
+
provisioning) lives in a sibling repo and ships independently. CLAUDE.md
|
|
261
|
+
narrative-sync remediation across consumer repos remains a recurring
|
|
262
|
+
maintenance load. Source: "Vault & Docs Orchestration" (#229; archived in the private Meta-Vault)
|
|
263
|
+
§ Sub-Epic B.
|
|
264
|
+
|
|
265
|
+
**Explicit non-goals** — these are not on the roadmap:
|
|
266
|
+
|
|
267
|
+
- **Team-Vault sharing.** Today single-user-local under
|
|
268
|
+
`~/Projects/vault`. Team sharing requires its own infra (sync, permissions,
|
|
269
|
+
conflict resolution) and is a separate epic.
|
|
270
|
+
- **Two-way sync (Vault → Repo).** Today one-way (Repo → Vault via
|
|
271
|
+
`.vault.yaml` + Clank). Reversal would break the ownership model.
|
|
272
|
+
- **LLM-autogenerated User-Docs without source.** docs-writer writes only
|
|
273
|
+
from the canonical four sources. Sourceless sections get
|
|
274
|
+
`<!-- REVIEW: source needed -->`, never invented content.
|
|
275
|
+
- **Full ADR autogeneration.** ADRs remain human-authored decisions;
|
|
276
|
+
docs-writer may suggest skeletons but never commits autonomously.
|
|
277
|
+
- **Migration of historical 50-sessions / 40-learnings entries.** vault-mirror
|
|
278
|
+
is forward-compatible only.
|
|
279
|
+
|
|
280
|
+
Source: "Vault & Docs Orchestration" (#229; archived in the private Meta-Vault) § Out-of-Scope.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## See Also
|
|
285
|
+
|
|
286
|
+
- `docs/session-config-reference.md` — authoritative config reference for all
|
|
287
|
+
fields mentioned above (Vault Sync, CLAUDE.md Drift Check, Vault
|
|
288
|
+
Integration, Vault Staleness, Docs Orchestrator).
|
|
289
|
+
- "Vault & Docs Orchestration" (#229; archived in the private Meta-Vault) — PRD for the umbrella
|
|
290
|
+
epic, including layering diagram and ownership table this document
|
|
291
|
+
derives from.
|
|
292
|
+
- `skills/docs-orchestrator/audience-mapping.md` — single source of truth
|
|
293
|
+
for audience → file-pattern mapping and non-overlap rules.
|
|
294
|
+
- `agents/docs-writer.md` — the sole agent permitted to write audience-
|
|
295
|
+
targeted documentation within a session.
|
|
296
|
+
- `CLAUDE.md` § "Current State" — running ledger of which umbrella-epic
|
|
297
|
+
slices have shipped.
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lock-bootstrap.mjs — mechanical session.lock writer for the SessionStart hook.
|
|
3
|
+
*
|
|
4
|
+
* Epic #583 P3 closes the D1 wiring gap: until P3, `acquire()` from
|
|
5
|
+
* scripts/lib/session-lock.mjs had no mechanical caller in the
|
|
6
|
+
* /session or /deep flow (only the autopilot-multi pipeline called it).
|
|
7
|
+
* The lock was written only when the coordinator-LLM happened to invoke
|
|
8
|
+
* Phase 1.2 prose — silent skip → discoverActiveSessions() returns empty →
|
|
9
|
+
* parallel-session AUQ never fires.
|
|
10
|
+
*
|
|
11
|
+
* This helper is invoked from hooks/on-session-start.mjs once per session.
|
|
12
|
+
* It is intentionally best-effort: every failure path swallows its error
|
|
13
|
+
* so the hook stays non-blocking (the hook's contract is informational-only;
|
|
14
|
+
* a write failure here must NEVER break session-start).
|
|
15
|
+
*
|
|
16
|
+
* Schema v2 (Epic #583 D4 #587):
|
|
17
|
+
* {
|
|
18
|
+
* session_id: string, // semantic OR UUID — whatever resolveSessionId returned
|
|
19
|
+
* semantic_session_id: string, // ALWAYS the semantic form (closes D4)
|
|
20
|
+
* started_at: ISO,
|
|
21
|
+
* last_heartbeat: ISO, // basis for liveness; replaces PID-liveness checks
|
|
22
|
+
* mode: string, // "deep"|"feature"|"housekeeping"|"session"|...
|
|
23
|
+
* pid: number, // forensics only — DO NOT use for liveness (D2/D4)
|
|
24
|
+
* host: string,
|
|
25
|
+
* ttl_hours: number,
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* The current scripts/lib/session-lock.mjs (pre-I3) writes the v1 shape
|
|
29
|
+
* (no last_heartbeat, no semantic_session_id). This helper layers v2 fields
|
|
30
|
+
* on top via an atomic tmp+rename overwrite — when I3 ships its v2 schema,
|
|
31
|
+
* this helper's overlay becomes a no-op (the field is already there) and
|
|
32
|
+
* everything continues to work.
|
|
33
|
+
*
|
|
34
|
+
* @module hooks/_lib/lock-bootstrap
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import fs from 'node:fs';
|
|
38
|
+
import path from 'node:path';
|
|
39
|
+
import { writeJsonAtomicSync } from '../../scripts/lib/io.mjs';
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Bootstrap the session.lock for this hook invocation.
|
|
43
|
+
*
|
|
44
|
+
* Best-effort: every internal failure is swallowed, the helper returns null
|
|
45
|
+
* instead of throwing. Callers (the SessionStart hook) wrap this in a
|
|
46
|
+
* try/catch anyway, but the helper itself never propagates.
|
|
47
|
+
*
|
|
48
|
+
* @param {object} opts
|
|
49
|
+
* @param {string} opts.repoRoot — absolute path to the repository root.
|
|
50
|
+
* @param {string} opts.sessionId — the resolved session id (semantic OR UUID).
|
|
51
|
+
* @param {string} [opts.semanticSessionId] — the semantic form, ALWAYS surfaced
|
|
52
|
+
* even when sessionId is a UUID (closes D4 issue #587). When omitted, the
|
|
53
|
+
* field is populated by mirroring sessionId.
|
|
54
|
+
* @param {string} opts.mode — session mode (e.g. "deep", "feature").
|
|
55
|
+
* @param {number} [opts.ttlHours=4] — lock TTL in hours.
|
|
56
|
+
* @param {Function} [opts._acquireImpl] — DI for tests (defaults to importing acquire from session-lock.mjs).
|
|
57
|
+
* @param {Function} [opts._forceAcquireImpl] — DI for tests (defaults to importing forceAcquire from session-lock.mjs).
|
|
58
|
+
* @param {Function} [opts._emitEventImpl] — DI for tests (defaults to importing emitEvent from events.mjs).
|
|
59
|
+
* @returns {Promise<object|null>} the enriched v2 lock body on success, null on any failure.
|
|
60
|
+
*/
|
|
61
|
+
export async function bootstrapLock({
|
|
62
|
+
repoRoot,
|
|
63
|
+
sessionId,
|
|
64
|
+
semanticSessionId,
|
|
65
|
+
mode,
|
|
66
|
+
ttlHours = 4,
|
|
67
|
+
_acquireImpl,
|
|
68
|
+
_forceAcquireImpl,
|
|
69
|
+
_emitEventImpl,
|
|
70
|
+
} = {}) {
|
|
71
|
+
// Sanity-check required inputs. Anything missing → bail silently.
|
|
72
|
+
if (typeof repoRoot !== 'string' || repoRoot.length === 0) return null;
|
|
73
|
+
if (typeof sessionId !== 'string' || sessionId.length === 0) return null;
|
|
74
|
+
if (typeof mode !== 'string' || mode.length === 0) return null;
|
|
75
|
+
|
|
76
|
+
// Resolve DI shims at call time so test mocks can replace the imports.
|
|
77
|
+
let acquireFn = _acquireImpl;
|
|
78
|
+
let forceAcquireFn = _forceAcquireImpl;
|
|
79
|
+
if (!acquireFn || !forceAcquireFn) {
|
|
80
|
+
try {
|
|
81
|
+
const lockMod = await import('../../scripts/lib/session-lock.mjs');
|
|
82
|
+
acquireFn = acquireFn ?? lockMod.acquire;
|
|
83
|
+
forceAcquireFn = forceAcquireFn ?? lockMod.forceAcquire;
|
|
84
|
+
} catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Step 1: try to acquire. If a fresh acquire succeeds, we are done.
|
|
90
|
+
// If a stale-PID-dead/-alive lock exists, force-overwrite it (the prior
|
|
91
|
+
// session has died; we own the worktree now).
|
|
92
|
+
// If the existing lock has the same sessionId, force-overwrite so the
|
|
93
|
+
// last_heartbeat gets refreshed.
|
|
94
|
+
let acquireResult;
|
|
95
|
+
try {
|
|
96
|
+
// quiet: true suppresses the unknown-mode stderr WARN in acquire() (#592 MED-2).
|
|
97
|
+
// The hook is informational-only and tests assert stderr is empty.
|
|
98
|
+
acquireResult = acquireFn({ sessionId, mode, ttlHours, repoRoot, quiet: true });
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!acquireResult || typeof acquireResult !== 'object') return null;
|
|
104
|
+
|
|
105
|
+
const shouldForce =
|
|
106
|
+
acquireResult.ok !== true && (
|
|
107
|
+
acquireResult.reason === 'stale-pid-dead' ||
|
|
108
|
+
acquireResult.reason === 'stale-pid-alive' ||
|
|
109
|
+
(acquireResult.reason === 'active' &&
|
|
110
|
+
acquireResult.existingLock &&
|
|
111
|
+
acquireResult.existingLock.session_id === sessionId)
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
if (!acquireResult.ok && shouldForce) {
|
|
115
|
+
try {
|
|
116
|
+
acquireResult = forceAcquireFn({ sessionId, mode, ttlHours, repoRoot });
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Any other non-ok reason (parallel-conflict, fs-error, other-session-active)
|
|
123
|
+
// → bail without enriching. The hook stays non-blocking.
|
|
124
|
+
//
|
|
125
|
+
// Issue #590 Item 1: before bailing, record a durable conflict signal for the
|
|
126
|
+
// FOREIGN-active case — reason 'active' where the existing lock belongs to a
|
|
127
|
+
// DIFFERENT session than ours (the same-session case was already force-refreshed
|
|
128
|
+
// above via shouldForce). Without this, the operator gets no signal that a
|
|
129
|
+
// parallel session owns the worktree. We persist the foreign session_id into
|
|
130
|
+
// current-session.json for forensics/operator visibility. Best-effort: any FS
|
|
131
|
+
// failure is swallowed and the bail proceeds. The return contract is unchanged —
|
|
132
|
+
// bootstrapLock STILL returns null on this path.
|
|
133
|
+
if (!acquireResult || acquireResult.ok !== true) {
|
|
134
|
+
if (
|
|
135
|
+
acquireResult &&
|
|
136
|
+
acquireResult.reason === 'active' &&
|
|
137
|
+
acquireResult.existingLock &&
|
|
138
|
+
typeof acquireResult.existingLock.session_id === 'string' &&
|
|
139
|
+
acquireResult.existingLock.session_id.length > 0 &&
|
|
140
|
+
acquireResult.existingLock.session_id !== sessionId
|
|
141
|
+
) {
|
|
142
|
+
recordConflictSignal(repoRoot, acquireResult.existingLock.session_id);
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Step 2: enrich the lock with v2 fields (last_heartbeat + semantic_session_id).
|
|
148
|
+
// We re-read the file fresh (acquire() just wrote it) and overlay the new
|
|
149
|
+
// fields, then atomically tmp+rename. When I3 lands and acquire() writes the
|
|
150
|
+
// v2 shape natively, this overlay becomes idempotent (already-present fields
|
|
151
|
+
// get overwritten with identical values).
|
|
152
|
+
const lockFile = path.join(repoRoot, '.orchestrator', 'session.lock');
|
|
153
|
+
let baseLock;
|
|
154
|
+
try {
|
|
155
|
+
const raw = fs.readFileSync(lockFile, 'utf8');
|
|
156
|
+
baseLock = JSON.parse(raw);
|
|
157
|
+
if (typeof baseLock !== 'object' || baseLock === null) return null;
|
|
158
|
+
} catch {
|
|
159
|
+
// Lock vanished between write and read — best-effort, return null.
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const startedAt = typeof baseLock.started_at === 'string'
|
|
164
|
+
? baseLock.started_at
|
|
165
|
+
: new Date().toISOString();
|
|
166
|
+
|
|
167
|
+
const enriched = {
|
|
168
|
+
...baseLock,
|
|
169
|
+
// last_heartbeat is the basis for liveness — set to started_at on bootstrap
|
|
170
|
+
// so an immediate liveness check (< ttl_hours from now) succeeds.
|
|
171
|
+
last_heartbeat: startedAt,
|
|
172
|
+
// semantic_session_id is ALWAYS the semantic form, even when session_id is
|
|
173
|
+
// a UUID-v4 (closes D4 #587). Fallback to mirroring session_id if no
|
|
174
|
+
// semantic was provided.
|
|
175
|
+
semantic_session_id:
|
|
176
|
+
typeof semanticSessionId === 'string' && semanticSessionId.length > 0
|
|
177
|
+
? semanticSessionId
|
|
178
|
+
: (typeof baseLock.session_id === 'string' ? baseLock.session_id : sessionId),
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
{
|
|
182
|
+
const w = writeJsonAtomicSync(lockFile, enriched, { tmpPrefix: '.session.lock.boot.tmp' });
|
|
183
|
+
if (!w.ok) {
|
|
184
|
+
// Failed to overwrite — base lock is still on disk, so we degrade
|
|
185
|
+
// gracefully. Return null so the caller logs no spurious success.
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Step 3: best-effort observability breadcrumb. Failures are swallowed
|
|
191
|
+
// so a missing events module never breaks the hook.
|
|
192
|
+
try {
|
|
193
|
+
let emitFn = _emitEventImpl;
|
|
194
|
+
if (!emitFn) {
|
|
195
|
+
const eventsMod = await import('../../scripts/lib/events.mjs');
|
|
196
|
+
emitFn = eventsMod.emitEvent;
|
|
197
|
+
}
|
|
198
|
+
if (typeof emitFn === 'function') {
|
|
199
|
+
await emitFn('orchestrator.session.lock.acquired', {
|
|
200
|
+
session_id: enriched.session_id,
|
|
201
|
+
semantic_session_id: enriched.semantic_session_id,
|
|
202
|
+
mode: enriched.mode,
|
|
203
|
+
pid: enriched.pid,
|
|
204
|
+
host: enriched.host,
|
|
205
|
+
ttl_hours: enriched.ttl_hours,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
} catch { /* observability is best-effort */ }
|
|
209
|
+
|
|
210
|
+
return enriched;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Record a foreign-session conflict signal into current-session.json (Issue #590
|
|
215
|
+
* Item 1). When bootstrapLock detects that a DIFFERENT session already owns the
|
|
216
|
+
* worktree lock, it persists the colliding session_id (plus a forensic timestamp)
|
|
217
|
+
* so the operator and downstream skills have a durable record of the collision —
|
|
218
|
+
* the previous behaviour bailed silently with no signal whatsoever.
|
|
219
|
+
*
|
|
220
|
+
* Uses an atomic read-modify-write (read → merge → tmp+rename) that PRESERVES
|
|
221
|
+
* every existing field (`session_id`, `semantic_session_id`, `pid`, `source`,
|
|
222
|
+
* `timestamp`, and any concurrently-appended `cwd_changes` / `corrective_context`
|
|
223
|
+
* / `last_batch` arrays). It never overwrites the whole file — it overlays only
|
|
224
|
+
* the two conflict fields on top of whatever is currently on disk.
|
|
225
|
+
*
|
|
226
|
+
* Best-effort: any FS error (missing file, parse failure, write race) is swallowed
|
|
227
|
+
* so the SessionStart hook stays non-blocking. The conflict signal is a forensic
|
|
228
|
+
* breadcrumb, not a correctness requirement.
|
|
229
|
+
*
|
|
230
|
+
* Lost-update window (Issue #596, deep-6 R2 MED — ACCEPTED): the read→merge→write
|
|
231
|
+
* is not lock-serialised. recordConflictSignal's only caller is the SessionStart hook
|
|
232
|
+
* (on-session-start.mjs), which runs it early — well before the slow detectPeers phase.
|
|
233
|
+
* That hook is async:true, so strict ordering vs the corrective_context/cwd_changes/
|
|
234
|
+
* last_batch writers (PostToolUse/CwdChanged/PostToolBatch) is not MECHANICALLY
|
|
235
|
+
* guaranteed; but in practice recordConflictSignal completes in a few ms, long before
|
|
236
|
+
* any tool-triggered hook can fire. Crucially, the conflict_* fields have zero readers
|
|
237
|
+
* (forensic-only), so even a lost update is harmless. The real anti-stomp guard is
|
|
238
|
+
* state.lock/PSA-005, not this advisory file.
|
|
239
|
+
*
|
|
240
|
+
* @param {string} repoRoot — absolute path to the repository root.
|
|
241
|
+
* @param {string} foreignSessionId — the session_id of the lock holder we collided with.
|
|
242
|
+
*/
|
|
243
|
+
function recordConflictSignal(repoRoot, foreignSessionId) {
|
|
244
|
+
try {
|
|
245
|
+
const sessionFile = path.join(repoRoot, '.orchestrator', 'current-session.json');
|
|
246
|
+
|
|
247
|
+
// Read-modify-write: start from whatever is on disk (or {} when absent /
|
|
248
|
+
// unparseable) so concurrently-written fields survive the overlay.
|
|
249
|
+
let current = {};
|
|
250
|
+
try {
|
|
251
|
+
const raw = fs.readFileSync(sessionFile, 'utf8');
|
|
252
|
+
const parsed = JSON.parse(raw);
|
|
253
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
254
|
+
current = parsed;
|
|
255
|
+
}
|
|
256
|
+
} catch {
|
|
257
|
+
// File absent or unparseable — start from an empty object. The conflict
|
|
258
|
+
// signal is still worth recording even if the session file was not yet written.
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const merged = {
|
|
262
|
+
...current,
|
|
263
|
+
conflict_with_session_id: foreignSessionId,
|
|
264
|
+
conflict_detected_at: new Date().toISOString(),
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// Best-effort atomic write — return value swallowed intentionally.
|
|
268
|
+
writeJsonAtomicSync(sessionFile, merged, { tmpPrefix: '.current-session.conflict.tmp' });
|
|
269
|
+
} catch {
|
|
270
|
+
// Best-effort — any failure is swallowed; the caller still returns null.
|
|
271
|
+
}
|
|
272
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lock-reconcile.mjs — root-cause reconciliation fallback for the SessionEnd hook.
|
|
3
|
+
*
|
|
4
|
+
* Extracted (Issue #748) from the inline reconciliation branch that used to live
|
|
5
|
+
* in `hooks/on-session-end.mjs`'s `main()` — that branch was only reachable via
|
|
6
|
+
* a subprocess spawn in tests, so its behaviour could only be verified through
|
|
7
|
+
* events.jsonl side effects, never asserted in-process. This module is the
|
|
8
|
+
* importable, DI-testable seam; `on-session-end.mjs` now just calls it.
|
|
9
|
+
*
|
|
10
|
+
* Context (Epic #724 Wave 3 — "ended logged but lock survived"): neither the
|
|
11
|
+
* UUID nor the semantic id matched the recorded lock (a rotated harness UUID
|
|
12
|
+
* racing ahead of current-session.json's semantic bridge), but the lease is
|
|
13
|
+
* already dead. Reconcile now via the same reaper the SessionStart hook uses
|
|
14
|
+
* (Epic #724 C7), instead of leaving the orphaned lease for the next
|
|
15
|
+
* session-start to discover. Safe by construction: reapRepoLock() never
|
|
16
|
+
* touches a live lease, a cross-host lease, or a lease whose recorded PID is
|
|
17
|
+
* still alive on this host.
|
|
18
|
+
*
|
|
19
|
+
* Best-effort by design, mirroring hooks/_lib/lock-bootstrap.mjs: every
|
|
20
|
+
* internal failure is swallowed so the SessionEnd hook stays non-blocking (the
|
|
21
|
+
* hook's contract is informational-only; a reconciliation failure here must
|
|
22
|
+
* NEVER break session teardown).
|
|
23
|
+
*
|
|
24
|
+
* @module hooks/_lib/lock-reconcile
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { isLockLive } from '../../scripts/lib/session-lock.mjs';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Attempt a best-effort reconciliation of a dead, orphaned session.lock that
|
|
31
|
+
* neither ownership check (UUID nor semantic id) matched. No-op when `lock`
|
|
32
|
+
* is missing or still live (isLockLive) — mirrors the `else if (!isLockLive(lock))`
|
|
33
|
+
* guard this function replaces at the call site.
|
|
34
|
+
*
|
|
35
|
+
* Never throws. Any failure resolving the DI defaults, calling reapRepoLock,
|
|
36
|
+
* or emitting the breadcrumb event is swallowed.
|
|
37
|
+
*
|
|
38
|
+
* @param {object} opts
|
|
39
|
+
* @param {string} opts.repoRoot — absolute path to the repository root.
|
|
40
|
+
* @param {string|null} opts.sessionId — the ending session's id (UUID or semantic).
|
|
41
|
+
* @param {object} opts.lock — the recorded lock the caller already read via readLock().
|
|
42
|
+
* @param {Function} [opts._reapRepoLockImpl] — DI for tests (defaults to importing
|
|
43
|
+
* reapRepoLock from scripts/lib/lock-reaper.mjs).
|
|
44
|
+
* @param {Function} [opts._emitEventImpl] — DI for tests (defaults to importing
|
|
45
|
+
* emitEvent from scripts/lib/events.mjs).
|
|
46
|
+
* @returns {Promise<void>}
|
|
47
|
+
*/
|
|
48
|
+
export async function attemptLockReconciliation({
|
|
49
|
+
repoRoot,
|
|
50
|
+
sessionId,
|
|
51
|
+
lock,
|
|
52
|
+
_reapRepoLockImpl,
|
|
53
|
+
_emitEventImpl,
|
|
54
|
+
} = {}) {
|
|
55
|
+
// Mirrors the caller's original `else if (!isLockLive(lock))` guard — a
|
|
56
|
+
// missing or still-live lock is never reconciled.
|
|
57
|
+
if (!lock || typeof lock !== 'object' || isLockLive(lock)) return;
|
|
58
|
+
|
|
59
|
+
// Resolve DI shims at call time so test mocks can replace the imports.
|
|
60
|
+
let reapFn = _reapRepoLockImpl;
|
|
61
|
+
if (!reapFn) {
|
|
62
|
+
try {
|
|
63
|
+
const reaperMod = await import('../../scripts/lib/lock-reaper.mjs');
|
|
64
|
+
reapFn = reaperMod.reapRepoLock;
|
|
65
|
+
} catch {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let emitFn = _emitEventImpl;
|
|
71
|
+
if (!emitFn) {
|
|
72
|
+
try {
|
|
73
|
+
const eventsMod = await import('../../scripts/lib/events.mjs');
|
|
74
|
+
emitFn = eventsMod.emitEvent;
|
|
75
|
+
} catch {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const reapResult = await reapFn({
|
|
82
|
+
repoRoot,
|
|
83
|
+
currentSessionId: sessionId,
|
|
84
|
+
dryRun: false,
|
|
85
|
+
reapMode: 'auto-session-end',
|
|
86
|
+
});
|
|
87
|
+
await emitFn('orchestrator.session.lock.reconcile_attempted', {
|
|
88
|
+
session_id: sessionId,
|
|
89
|
+
action: reapResult?.action ?? 'unknown',
|
|
90
|
+
reason: reapResult?.reason ?? null,
|
|
91
|
+
});
|
|
92
|
+
} catch { /* best-effort — reconciliation must never block teardown */ }
|
|
93
|
+
}
|