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,430 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* vault-mirror.mjs — JSONL-to-Markdown mirror for the Meta-Vault (Issue #14).
|
|
4
|
+
*
|
|
5
|
+
* Reads a JSONL file (one JSON object per line), produces Markdown notes with
|
|
6
|
+
* valid vaultFrontmatterSchema frontmatter, and writes them into the vault.
|
|
7
|
+
*
|
|
8
|
+
* CLI usage:
|
|
9
|
+
* node vault-mirror.mjs --vault-dir <path> --source <jsonl-path> --kind <learning|session>
|
|
10
|
+
* [--dry-run] [--strict-schema] [--no-commit] [--force]
|
|
11
|
+
* [--session-id <id>]
|
|
12
|
+
* [--quality-min-narrative-chars <int>] (sessions only; default 400)
|
|
13
|
+
* [--quality-min-confidence <float>] (learnings only; default 0.5)
|
|
14
|
+
*
|
|
15
|
+
* Exit codes:
|
|
16
|
+
* 0 — success (including idempotent no-op)
|
|
17
|
+
* 1 — validation error (malformed JSON line, bad slug, etc.)
|
|
18
|
+
* 2 — filesystem error
|
|
19
|
+
*
|
|
20
|
+
* Output: one JSON line per action on stdout:
|
|
21
|
+
* {"action":"created|updated|skipped-noop|skipped-handwritten|skipped-collision-resolved|skipped-invalid|skipped-quality-low","path":"...","kind":"...","id":"..."}
|
|
22
|
+
*
|
|
23
|
+
* Idempotency rules:
|
|
24
|
+
* 1. File does not exist → create.
|
|
25
|
+
* 2. File exists, has _generator marker, id matches → overwrite only if updated would advance; else skipped-noop.
|
|
26
|
+
* 3. File exists, lacks _generator → skip (hand-written). Log to stderr.
|
|
27
|
+
* 4. File exists, has _generator, id differs → collision-disambiguate by appending -<first8 of uuid>.
|
|
28
|
+
*
|
|
29
|
+
* Quality gate (PRD F1.2):
|
|
30
|
+
* Learnings with confidence < --quality-min-confidence emit `skipped-quality-low`.
|
|
31
|
+
* Sessions with rendered-narrative length < --quality-min-narrative-chars emit
|
|
32
|
+
* `skipped-quality-low`. Quality gate runs BEFORE --force; --force does NOT
|
|
33
|
+
* bypass the filter. Quality-skipped entries emit `path: null` and an
|
|
34
|
+
* additional `reason` field describing the violated threshold.
|
|
35
|
+
*
|
|
36
|
+
* Excluded sidecars (#502 + #506):
|
|
37
|
+
* vault-mirror operates EXCLUSIVELY on JSONL sources passed via --source.
|
|
38
|
+
* The following cross-session sidecars MUST NEVER be mirrored into the
|
|
39
|
+
* vault, even if a future refactor adds directory-walking. They live under
|
|
40
|
+
* `.orchestrator/` deliberately so they survive a session close without
|
|
41
|
+
* being copied into `50-sessions/`:
|
|
42
|
+
* - `.orchestrator/pending-dream.md` (auto-dream sidecar, PRD F2.2 / #502)
|
|
43
|
+
* - `.orchestrator/dialectic-pending.md` (auto-dialectic sidecar, PRD F2.5 / #506)
|
|
44
|
+
* The next session consumes these via `/memory-cleanup --apply-pending`
|
|
45
|
+
* and `/evolve --dialectic --apply`, respectively — vault-mirror has no
|
|
46
|
+
* role in their lifecycle.
|
|
47
|
+
*
|
|
48
|
+
* Part of session-orchestrator vault-mirror (Issue #14).
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
import { spawnSync } from 'node:child_process';
|
|
52
|
+
import { existsSync } from 'node:fs';
|
|
53
|
+
import { resolve } from 'node:path';
|
|
54
|
+
import { createInterface } from 'node:readline';
|
|
55
|
+
import { createReadStream } from 'node:fs';
|
|
56
|
+
import { pathToFileURL } from 'node:url';
|
|
57
|
+
|
|
58
|
+
import { processLearning, processSession } from './lib/vault-mirror/process.mjs';
|
|
59
|
+
import { autoCommitVaultMirror } from './lib/vault-mirror/auto-commit.mjs';
|
|
60
|
+
import { parseColumnFlags, CliFlagError } from './lib/cli-flags.mjs';
|
|
61
|
+
import { resolveRepoNamespace } from './lib/vault-mirror/namespace.mjs';
|
|
62
|
+
import { resolveCanonicalSuffixes } from './lib/named-vault-resolver.mjs';
|
|
63
|
+
import { loadOwnerConfig } from './lib/owner-yaml.mjs';
|
|
64
|
+
|
|
65
|
+
// ── Canonical-vault helpers (#600 D2 / #607 D2) ────────────────────────────────
|
|
66
|
+
// These are module-level (above the CLI bootstrap) so the module is import-safe
|
|
67
|
+
// for unit tests: importing scripts/vault-mirror.mjs from vitest pulls in these
|
|
68
|
+
// exported helpers WITHOUT running the CLI (the CLI bootstrap + main() are gated
|
|
69
|
+
// behind an import.meta.url entry-guard at the bottom). The canonical-vault
|
|
70
|
+
// guard usage lives in main(); see the rationale block there.
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Resolve the canonical vault suffix from an env override, defaulting to
|
|
74
|
+
* `/agents/vault` when the override is missing or blank (whitespace-only).
|
|
75
|
+
* Pure helper so the empty-/whitespace-string fallback is unit-testable without
|
|
76
|
+
* mutating process.env (#607 D2). Returns the TRIMMED override when set, so a
|
|
77
|
+
* value like `" gitlab.example.com/agents/vault "` matches as expected.
|
|
78
|
+
* @param {string|undefined} envValue
|
|
79
|
+
* @returns {string}
|
|
80
|
+
*/
|
|
81
|
+
export function _resolveCanonicalSuffix(envValue) {
|
|
82
|
+
return envValue && envValue.trim() ? envValue.trim() : '/agents/vault';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Kept for documentation; the guard now uses resolveCanonicalSuffixes() which
|
|
86
|
+
// generalises this to N suffixes. The `_` prefix satisfies the no-unused-vars rule.
|
|
87
|
+
const _CANONICAL_VAULT_SUFFIX = _resolveCanonicalSuffix(
|
|
88
|
+
process.env.VAULT_MIRROR_CANONICAL_SUFFIX,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Normalize a git remote URL to a host/path tail for canonical-suffix matching
|
|
93
|
+
* (#607 D2 — exported for unit tests). Strips `.git`, the `git@host:` / scheme
|
|
94
|
+
* prefixes, and trailing slashes.
|
|
95
|
+
* @param {string} url
|
|
96
|
+
* @returns {string}
|
|
97
|
+
*/
|
|
98
|
+
export function _normalizeRemote(url) {
|
|
99
|
+
return String(url ?? '')
|
|
100
|
+
.trim()
|
|
101
|
+
.replace(/\.git$/, '')
|
|
102
|
+
.replace(/^git@([^:]+):/, '$1/')
|
|
103
|
+
.replace(/^[a-z]+:\/\//, '')
|
|
104
|
+
.replace(/\/+$/, '');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ── CLI argument parsing ──────────────────────────────────────────────────────
|
|
108
|
+
//
|
|
109
|
+
// Migrated to scripts/lib/cli-flags.mjs (#510). Behaviour changes vs prior
|
|
110
|
+
// hand-rolled getArg() parser:
|
|
111
|
+
// - Unknown flags now exit 1 instead of being SILENTLY IGNORED. This is an
|
|
112
|
+
// intentional uniform reject policy per #510 — grep-verified that no
|
|
113
|
+
// current caller passes unknown flags (3 invocation sites: session-end
|
|
114
|
+
// Phase 1, evolve Phase, vault-mirror SKILL examples; all use known flags
|
|
115
|
+
// only). See W2 STATUS for the grep evidence.
|
|
116
|
+
// Behaviour explicitly preserved:
|
|
117
|
+
// - Wet-run is the DEFAULT (omitting --dry-run → live write). This script
|
|
118
|
+
// stays divergent from the other 3 migration scripts on purpose; flipping
|
|
119
|
+
// it to dry-run-default would break every existing invocation in
|
|
120
|
+
// skills/session-end/, skills/evolve/, and skills/vault-mirror/.
|
|
121
|
+
// - --help / -h prints to stdout and exits 0 BEFORE any required-flag check.
|
|
122
|
+
// - Int/float coercion for --quality-min-* (strict — string input → exit 1).
|
|
123
|
+
|
|
124
|
+
// Entry-guard (#607 D2): run the CLI bootstrap (arg parsing, validation, and
|
|
125
|
+
// main()) ONLY when this file is invoked directly as a subprocess
|
|
126
|
+
// (`node vault-mirror.mjs ...`). When imported from a unit test, argv belongs to
|
|
127
|
+
// the test runner — parsing it would spuriously process.exit. The exported
|
|
128
|
+
// helpers above are unaffected by this guard.
|
|
129
|
+
const _isDirectInvocation =
|
|
130
|
+
Boolean(process.argv[1]) && import.meta.url === pathToFileURL(process.argv[1]).href;
|
|
131
|
+
|
|
132
|
+
if (_isDirectInvocation) {
|
|
133
|
+
let parsedFlags;
|
|
134
|
+
try {
|
|
135
|
+
parsedFlags = parseColumnFlags({
|
|
136
|
+
knownBool: {
|
|
137
|
+
help: { short: 'h', default: false },
|
|
138
|
+
'dry-run': false,
|
|
139
|
+
'strict-schema': false,
|
|
140
|
+
'no-commit': false,
|
|
141
|
+
force: false,
|
|
142
|
+
},
|
|
143
|
+
knownString: {
|
|
144
|
+
'vault-dir': null,
|
|
145
|
+
source: null,
|
|
146
|
+
kind: null,
|
|
147
|
+
'session-id': null,
|
|
148
|
+
'vault-name': null,
|
|
149
|
+
'quality-min-narrative-chars': null,
|
|
150
|
+
'quality-min-confidence': null,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
} catch (err) {
|
|
154
|
+
if (err instanceof CliFlagError) {
|
|
155
|
+
process.stderr.write(`vault-mirror: ${err.message}\n`);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
throw err;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const flagValues = parsedFlags.values;
|
|
162
|
+
|
|
163
|
+
// --help support: print usage and exit 0 (no other validation runs).
|
|
164
|
+
if (flagValues.help === true) {
|
|
165
|
+
process.stdout.write(
|
|
166
|
+
[
|
|
167
|
+
'Usage: node vault-mirror.mjs --vault-dir <path> --source <jsonl-path> --kind <learning|session>',
|
|
168
|
+
' [--dry-run] [--strict-schema] [--no-commit] [--force]',
|
|
169
|
+
' [--session-id <id>]',
|
|
170
|
+
' [--quality-min-narrative-chars <int>]',
|
|
171
|
+
' [--quality-min-confidence <float>]',
|
|
172
|
+
'',
|
|
173
|
+
'Options:',
|
|
174
|
+
' --vault-dir <path> Absolute path to the Meta-Vault root (required).',
|
|
175
|
+
' --source <path> Path to a JSONL file to mirror (required).',
|
|
176
|
+
' --kind <learning|session> Entry kind to process (required).',
|
|
177
|
+
' --dry-run Parse + render but write nothing.',
|
|
178
|
+
' --strict-schema Abort with exit 1 if any entry was skipped-invalid.',
|
|
179
|
+
' --no-commit Suppress the auto-commit phase (default if --session-id is omitted).',
|
|
180
|
+
' --force Re-render existing notes even when updated would not advance.',
|
|
181
|
+
' NOTE: --force does NOT bypass the quality gate (PRD F1.2).',
|
|
182
|
+
' --session-id <id> Opt-in: also auto-commit mirror artifacts on success.',
|
|
183
|
+
' --vault-name <name> Override the repo-derived namespace segment in the vault.',
|
|
184
|
+
' When set, mirrors write under <vault-name>/ instead of the',
|
|
185
|
+
' git-derived repo identifier. Maps to vault-integration.vault-name',
|
|
186
|
+
' in Session Config. Sanitised to a lowercase kebab slug.',
|
|
187
|
+
' --quality-min-narrative-chars <int> Sessions: minimum rendered-narrative length (default 400).',
|
|
188
|
+
' Entries below the threshold emit "skipped-quality-low".',
|
|
189
|
+
' --quality-min-confidence <float> Learnings: minimum confidence threshold (default 0.5).',
|
|
190
|
+
' Entries below the threshold emit "skipped-quality-low".',
|
|
191
|
+
'',
|
|
192
|
+
'See skills/vault-mirror/SKILL.md for full action semantics.',
|
|
193
|
+
'',
|
|
194
|
+
].join('\n'),
|
|
195
|
+
);
|
|
196
|
+
process.exit(0);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const vaultDir = flagValues['vault-dir'];
|
|
200
|
+
const source = flagValues.source;
|
|
201
|
+
const kind = flagValues.kind;
|
|
202
|
+
const dryRun = flagValues['dry-run'] === true;
|
|
203
|
+
const strictSchema = flagValues['strict-schema'] === true;
|
|
204
|
+
const noCommit = flagValues['no-commit'] === true;
|
|
205
|
+
const force = flagValues.force === true;
|
|
206
|
+
const sessionIdArg = flagValues['session-id'];
|
|
207
|
+
const vaultName = flagValues['vault-name'] ?? null;
|
|
208
|
+
|
|
209
|
+
// Quality-gate thresholds (PRD F1.2). Parse as numbers; reject malformed input
|
|
210
|
+
// loudly so CI cannot accidentally pass a string ("400px") and silently fall
|
|
211
|
+
// back to NaN comparisons (NaN < anything === false → quality gate disabled).
|
|
212
|
+
const QUALITY_MIN_NARRATIVE_DEFAULT = 400;
|
|
213
|
+
const QUALITY_MIN_CONFIDENCE_DEFAULT = 0.5;
|
|
214
|
+
|
|
215
|
+
function parseIntFlag(name, raw, fallback) {
|
|
216
|
+
if (raw === undefined || raw === null) return fallback;
|
|
217
|
+
const n = Number.parseInt(raw, 10);
|
|
218
|
+
if (!Number.isFinite(n) || String(n) !== String(raw).trim()) {
|
|
219
|
+
process.stderr.write(`vault-mirror: invalid integer for ${name}: "${raw}"\n`);
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
return n;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function parseFloatFlag(name, raw, fallback) {
|
|
226
|
+
if (raw === undefined || raw === null) return fallback;
|
|
227
|
+
const n = Number.parseFloat(raw);
|
|
228
|
+
if (!Number.isFinite(n)) {
|
|
229
|
+
process.stderr.write(`vault-mirror: invalid number for ${name}: "${raw}"\n`);
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
232
|
+
return n;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const qualityMinNarrativeChars = parseIntFlag(
|
|
236
|
+
'--quality-min-narrative-chars',
|
|
237
|
+
flagValues['quality-min-narrative-chars'],
|
|
238
|
+
QUALITY_MIN_NARRATIVE_DEFAULT,
|
|
239
|
+
);
|
|
240
|
+
const qualityMinConfidence = parseFloatFlag(
|
|
241
|
+
'--quality-min-confidence',
|
|
242
|
+
flagValues['quality-min-confidence'],
|
|
243
|
+
QUALITY_MIN_CONFIDENCE_DEFAULT,
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
if (!vaultDir || !source || !kind) {
|
|
247
|
+
process.stderr.write(
|
|
248
|
+
'Usage: node vault-mirror.mjs --vault-dir <path> --source <jsonl-path> --kind <learning|session> [--dry-run] [--strict-schema] [--no-commit] [--force] [--session-id <id>] [--quality-min-narrative-chars <int>] [--quality-min-confidence <float>]\n',
|
|
249
|
+
);
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (kind !== 'learning' && kind !== 'session') {
|
|
254
|
+
process.stderr.write(`vault-mirror: invalid --kind "${kind}" (expected learning or session)\n`);
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ── Canonical Meta-Vault guard (#600 D2) ───────────────────────────────────────
|
|
259
|
+
//
|
|
260
|
+
// vault-dir-drift proximate cause: the existsSync(vaultDir) check below passes for
|
|
261
|
+
// ANY directory that happens to exist on disk. When a stray wrong-target path
|
|
262
|
+
// existed (e.g. a typo'd vault location), mirror writes succeeded SILENTLY into
|
|
263
|
+
// it — the wrong vault accumulated notes and the real Meta-Vault drifted.
|
|
264
|
+
//
|
|
265
|
+
// Defense: probe the vault-dir's git origin and refuse to mirror unless its URL
|
|
266
|
+
// ends with the canonical-vault path suffix (default `/agents/vault`; override
|
|
267
|
+
// via env VAULT_MIRROR_CANONICAL_SUFFIX, e.g. `<host>/agents/vault` for a strict
|
|
268
|
+
// host-qualified check). A wrong vault is a WHOLE-RUN failure (process.exit(2)),
|
|
269
|
+
// not a per-entry skip — mirroring even one note into the wrong place is the bug.
|
|
270
|
+
//
|
|
271
|
+
// `git remote get-url origin` exit codes (probed): 128 = not a git repo,
|
|
272
|
+
// 2 = git repo without an origin remote, 0 = prints the URL. Any non-zero exit or
|
|
273
|
+
// a non-matching URL fails closed.
|
|
274
|
+
//
|
|
275
|
+
// The VAULT_MIRROR_SKIP_CANONICAL_CHECK=1 escape hatch is load-bearing for the
|
|
276
|
+
// test suite: vault-mirror's own tests mirror into non-git tmp dirs and must
|
|
277
|
+
// bypass this network-of-trust check. It is NOT documented as an operator flag —
|
|
278
|
+
// production callers (session-end Phase 3.7, evolve) always target the real vault.
|
|
279
|
+
// Apply the same trim-as-truthy-probe pattern as #601 getConfinementRoot: a
|
|
280
|
+
// whitespace-only env override would otherwise short-circuit `||` and yield a
|
|
281
|
+
// meaningless suffix. Fail-safe (a non-matching suffix only widens rejection),
|
|
282
|
+
// but the bug class is recurring — fix at the source. The helpers + the
|
|
283
|
+
// CANONICAL_VAULT_SUFFIX const live near the top of the module (just after the
|
|
284
|
+
// imports) so they are import-safe and unit-testable; see _resolveCanonicalSuffix
|
|
285
|
+
// / _normalizeRemote there (#607 D2).
|
|
286
|
+
|
|
287
|
+
// ── Main ──────────────────────────────────────────────────────────────────────
|
|
288
|
+
|
|
289
|
+
async function main() {
|
|
290
|
+
if (!existsSync(resolve(vaultDir))) {
|
|
291
|
+
process.stderr.write(`vault-mirror: vault-dir not found: ${vaultDir}\n`);
|
|
292
|
+
process.exit(2);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (process.env.VAULT_MIRROR_SKIP_CANONICAL_CHECK !== '1') {
|
|
296
|
+
const res = spawnSync('git', ['-C', resolve(vaultDir), 'remote', 'get-url', 'origin'], {
|
|
297
|
+
encoding: 'utf8',
|
|
298
|
+
});
|
|
299
|
+
const canonicalSuffixes = resolveCanonicalSuffixes({
|
|
300
|
+
ownerConfig: loadOwnerConfig().config,
|
|
301
|
+
env: process.env,
|
|
302
|
+
});
|
|
303
|
+
const ok = res.status === 0 && canonicalSuffixes.some((s) => _normalizeRemote(res.stdout).endsWith(s));
|
|
304
|
+
if (!ok) {
|
|
305
|
+
const got = res.status === 0 ? res.stdout.trim() : 'no git origin';
|
|
306
|
+
process.stderr.write(
|
|
307
|
+
`vault-mirror: refusing to mirror — "${vaultDir}" is not the canonical Meta-Vault (expected git origin ending in one of: ${canonicalSuffixes.join(', ')}; got ${got})\n`,
|
|
308
|
+
);
|
|
309
|
+
process.exit(2);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (!existsSync(resolve(source))) {
|
|
314
|
+
process.stderr.write(`vault-mirror: source file not found: ${source}\n`);
|
|
315
|
+
process.exit(2);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const rl = createInterface({
|
|
319
|
+
input: createReadStream(resolve(source), 'utf8'),
|
|
320
|
+
crlfDelay: Infinity,
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Collect all lines first, then process sequentially to avoid mkdirSync/writeFileSync races
|
|
324
|
+
const lines = [];
|
|
325
|
+
for await (const line of rl) {
|
|
326
|
+
lines.push(line);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
let lineNum = 0;
|
|
330
|
+
let skippedInvalidCount = 0;
|
|
331
|
+
const ctx = {
|
|
332
|
+
vaultDir,
|
|
333
|
+
dryRun,
|
|
334
|
+
kind,
|
|
335
|
+
force,
|
|
336
|
+
vaultName,
|
|
337
|
+
qualityMinNarrativeChars,
|
|
338
|
+
qualityMinConfidence,
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
for (const line of lines) {
|
|
342
|
+
lineNum++;
|
|
343
|
+
const trimmed = line.trim();
|
|
344
|
+
if (!trimmed) continue;
|
|
345
|
+
|
|
346
|
+
let entry;
|
|
347
|
+
try {
|
|
348
|
+
entry = JSON.parse(trimmed);
|
|
349
|
+
} catch (err) {
|
|
350
|
+
process.stderr.write(`vault-mirror: malformed JSON on line ${lineNum}: ${err.message}\n`);
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
try {
|
|
355
|
+
if (kind === 'learning') {
|
|
356
|
+
await processLearning(entry, lineNum, ctx);
|
|
357
|
+
} else {
|
|
358
|
+
await processSession(entry, lineNum, ctx);
|
|
359
|
+
}
|
|
360
|
+
} catch (err) {
|
|
361
|
+
// Validation errors (missing required fields) → per-entry skip, not a global failure
|
|
362
|
+
if (err.message.startsWith('vault-mirror:')) {
|
|
363
|
+
process.stderr.write(`${err.message}\n`);
|
|
364
|
+
const entryId = entry?.id ?? entry?.session_id ?? null;
|
|
365
|
+
process.stdout.write(
|
|
366
|
+
JSON.stringify({ action: 'skipped-invalid', path: null, kind, id: entryId }) + '\n',
|
|
367
|
+
);
|
|
368
|
+
skippedInvalidCount++;
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
// #718: discriminate genuine filesystem/system errors (which must still
|
|
372
|
+
// abort the whole run — a partially-written vault is worse than a loud
|
|
373
|
+
// failure) from mapper crashes on malformed producer data (a native
|
|
374
|
+
// TypeError/RangeError thrown while rendering ONE record, e.g. a shape
|
|
375
|
+
// the mapper didn't defensively guard). Node system errors always carry
|
|
376
|
+
// a non-empty `err.code` (EACCES/ENOSPC/EROFS/ENOENT/...) and/or
|
|
377
|
+
// `err.syscall` — a plain TypeError/RangeError from JS-level property
|
|
378
|
+
// access has neither, so this check is a reliable discriminator even in
|
|
379
|
+
// --dry-run mode (no writes happen, so a mapper crash there can only be
|
|
380
|
+
// a data-shape defect, never a real FS error).
|
|
381
|
+
const isSystemError =
|
|
382
|
+
(typeof err.code === 'string' && err.code.length > 0) || Boolean(err.syscall);
|
|
383
|
+
if (!isSystemError) {
|
|
384
|
+
process.stderr.write(
|
|
385
|
+
`vault-mirror: mapper crash on line ${lineNum} (${err.message}) — record skipped\n`,
|
|
386
|
+
);
|
|
387
|
+
const entryId = entry?.id ?? entry?.session_id ?? null;
|
|
388
|
+
process.stdout.write(
|
|
389
|
+
JSON.stringify({
|
|
390
|
+
action: 'skipped-invalid',
|
|
391
|
+
path: null,
|
|
392
|
+
kind,
|
|
393
|
+
id: entryId,
|
|
394
|
+
reason: 'mapper-crash',
|
|
395
|
+
}) + '\n',
|
|
396
|
+
);
|
|
397
|
+
skippedInvalidCount++;
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
// Unexpected filesystem errors → fatal
|
|
401
|
+
process.stderr.write(`vault-mirror: filesystem error on line ${lineNum}: ${err.message}\n`);
|
|
402
|
+
process.exit(2);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// --strict-schema: abort with exit 1 when any entry was skipped-invalid.
|
|
407
|
+
// Useful in CI to catch producer-side schema drift early (issue #249).
|
|
408
|
+
if (strictSchema && skippedInvalidCount > 0) {
|
|
409
|
+
process.stdout.write(
|
|
410
|
+
JSON.stringify({ action: 'strict-schema-abort', skipped: skippedInvalidCount, kind }) + '\n',
|
|
411
|
+
);
|
|
412
|
+
process.stderr.write(
|
|
413
|
+
`vault-mirror: --strict-schema: ${skippedInvalidCount} entries failed validation — exiting 1\n`,
|
|
414
|
+
);
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Auto-commit phase (issue #31): commit mirror artifacts so they don't pile up.
|
|
419
|
+
// Opt-in: triggers only when --session-id is provided. Callers (session-end, evolve)
|
|
420
|
+
// pass it explicitly; bare invocations stay quiet to preserve legacy behaviour.
|
|
421
|
+
if (!dryRun && !noCommit && sessionIdArg) {
|
|
422
|
+
autoCommitVaultMirror(resolve(vaultDir), sessionIdArg, resolveRepoNamespace({ vaultName }));
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
main().catch((err) => {
|
|
427
|
+
process.stderr.write(`vault-mirror: unexpected error: ${err.message}\n`);
|
|
428
|
+
process.exit(2);
|
|
429
|
+
});
|
|
430
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Bootstrap Gate
|
|
2
|
+
|
|
3
|
+
> Single source of truth for the bootstrap gate check.
|
|
4
|
+
> Referenced by: plan, session-start, wave-executor, session-end, discovery, evolve.
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
8
|
+
Every session-orchestrator skill runs this gate check silently at the start of Phase 0. When the gate is open, execution continues with zero overhead. When the gate is closed, the bootstrap skill is invoked before any other work begins.
|
|
9
|
+
|
|
10
|
+
<HARD-GATE>
|
|
11
|
+
If GATE_CLOSED, you MUST invoke `skills/bootstrap/SKILL.md`. Do NOT:
|
|
12
|
+
- Fall back to "pragmatic paths"
|
|
13
|
+
- Create files, directories, or code without running bootstrap first
|
|
14
|
+
- Interpret the user's request as permission to skip structure setup
|
|
15
|
+
- Rationalize that "the user clearly wants X, so structure can come later"
|
|
16
|
+
- Proceed to Phase 1 of any skill while the gate is closed
|
|
17
|
+
|
|
18
|
+
There is no bypass. There is no exception for urgent requests, demo repos, or spike work.
|
|
19
|
+
The ONLY valid next action when GATE_CLOSED is invoking the bootstrap skill and waiting for it to complete.
|
|
20
|
+
</HARD-GATE>
|
|
21
|
+
|
|
22
|
+
## Gate Check Algorithm
|
|
23
|
+
|
|
24
|
+
Execute these three checks in order. Any single failure = GATE_CLOSED.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
1. Read $REPO_ROOT/CLAUDE.md (or AGENTS.md on Codex CLI / Pi).
|
|
28
|
+
- If the file does not exist → GATE_CLOSED (reason: no-claude-md)
|
|
29
|
+
- If the file is zero-length (empty) → GATE_CLOSED (reason: no-claude-md)
|
|
30
|
+
|
|
31
|
+
2. Grep the config file for the exact string "## Session Config".
|
|
32
|
+
- If the section heading is absent → GATE_CLOSED (reason: no-session-config)
|
|
33
|
+
|
|
34
|
+
3. Read $REPO_ROOT/.orchestrator/bootstrap.lock.
|
|
35
|
+
- If the file does not exist → GATE_CLOSED (reason: no-bootstrap-lock)
|
|
36
|
+
- If the file is not valid YAML → GATE_CLOSED (reason: invalid-lock)
|
|
37
|
+
- If the file lacks the key "version" → GATE_CLOSED (reason: no-bootstrap-lock)
|
|
38
|
+
- If the file lacks the key "tier" → GATE_CLOSED (reason: no-bootstrap-lock)
|
|
39
|
+
|
|
40
|
+
All three pass → GATE_OPEN. Return silently. No output, no logging.
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Implementation (Bash reference)
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
47
|
+
|
|
48
|
+
# Detect config file by platform
|
|
49
|
+
if [[ -f "$REPO_ROOT/AGENTS.md" && ( "${SO_PLATFORM:-}" == "codex" || "${SO_PLATFORM:-}" == "pi" ) ]]; then
|
|
50
|
+
CONFIG_FILE="$REPO_ROOT/AGENTS.md"
|
|
51
|
+
else
|
|
52
|
+
CONFIG_FILE="$REPO_ROOT/CLAUDE.md"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Check 1: config file exists and non-empty
|
|
56
|
+
if [[ ! -s "$CONFIG_FILE" ]]; then
|
|
57
|
+
GATE_STATUS="CLOSED"; GATE_REASON="no-claude-md"
|
|
58
|
+
# Check 2: Session Config section present
|
|
59
|
+
elif ! grep -q "^## Session Config" "$CONFIG_FILE"; then
|
|
60
|
+
GATE_STATUS="CLOSED"; GATE_REASON="no-session-config"
|
|
61
|
+
# Check 3: bootstrap.lock exists and has required keys
|
|
62
|
+
elif [[ ! -f "$REPO_ROOT/.orchestrator/bootstrap.lock" ]]; then
|
|
63
|
+
GATE_STATUS="CLOSED"; GATE_REASON="no-bootstrap-lock"
|
|
64
|
+
elif ! grep -q "^version:" "$REPO_ROOT/.orchestrator/bootstrap.lock" \
|
|
65
|
+
|| ! grep -q "^tier:" "$REPO_ROOT/.orchestrator/bootstrap.lock"; then
|
|
66
|
+
GATE_STATUS="CLOSED"; GATE_REASON="invalid-lock"
|
|
67
|
+
else
|
|
68
|
+
GATE_STATUS="OPEN"
|
|
69
|
+
fi
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Gate Result Handling
|
|
73
|
+
|
|
74
|
+
**GATE_OPEN:** Continue immediately with the skill's original Phase 0 / Phase 1. No message to the user.
|
|
75
|
+
|
|
76
|
+
**GATE_CLOSED:** Read `skills/bootstrap/SKILL.md` and execute the bootstrap flow completely. Do not proceed to the original skill until bootstrap reports completion and `.orchestrator/bootstrap.lock` exists with valid `version` and `tier` keys. Then re-run the gate check once to confirm, and continue.
|
|
77
|
+
|
|
78
|
+
## `.orchestrator/bootstrap.lock` Schema
|
|
79
|
+
|
|
80
|
+
The lock file is committed to git. It is a permanent, per-repo marker — not session-ephemeral.
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
# .orchestrator/bootstrap.lock
|
|
84
|
+
version: 1
|
|
85
|
+
tier: fast | standard | deep
|
|
86
|
+
archetype: static-html | node-minimal | nextjs-minimal | python-uv | <baseline-archetype> | null
|
|
87
|
+
timestamp: 2026-04-16T09:30:00Z # ISO 8601 UTC, set at bootstrap time
|
|
88
|
+
source: projects-baseline | plugin-template | claude-init
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
| Field | Required | Description |
|
|
92
|
+
|-------|----------|-------------|
|
|
93
|
+
| `version` | yes | Lock file schema version. Currently always `1`. |
|
|
94
|
+
| `tier` | yes | Bootstrap intensity used: `fast`, `standard`, or `deep`. |
|
|
95
|
+
| `archetype` | yes | Template archetype applied. `null` for Fast tier (no stack). |
|
|
96
|
+
| `timestamp` | yes | ISO 8601 UTC timestamp of when bootstrap ran. |
|
|
97
|
+
| `source` | yes | How CLAUDE.md was generated: `projects-baseline` (private path), `plugin-template` (public path, Codex/Cursor), or `claude-init` (public path, Claude Code). |
|
|
98
|
+
|
|
99
|
+
**Why a dedicated lock file, not STATE.md:** STATE.md is session-ephemeral and reset between sessions. The bootstrap marker is a one-time, permanent repository property. `bootstrap.lock` is committed to git and persists across all sessions and users.
|
|
100
|
+
|
|
101
|
+
## Idempotency
|
|
102
|
+
|
|
103
|
+
A repo that has already been bootstrapped passes the gate on every subsequent invocation with zero overhead. The gate check reads three files and performs two grep operations — negligible cost.
|
|
104
|
+
|
|
105
|
+
`/bootstrap --retroactive` exists for repos that predate the gate (have `CLAUDE.md` + Session Config but no `bootstrap.lock`). It writes the lock without re-scaffolding. Documented in `commands/bootstrap.md`.
|
|
106
|
+
|
|
107
|
+
## Auto-Skill Dispatch (opt-in, default: off)
|
|
108
|
+
|
|
109
|
+
When the gate is OPEN and Session Config has `auto-skill-dispatch: true`, the calling skill SHOULD invoke `skills/using-orchestrator/SKILL.md` once before its Phase 1 to detect implicit slash-command intent in the user's first message. The meta-skill is a no-op when the flag is `false` (default), so call sites without the flag see zero behavior change.
|
|
110
|
+
|
|
111
|
+
Cross-reference: `skills/using-orchestrator/SKILL.md`.
|