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,296 @@
|
|
|
1
|
+
# Plugin Architecture (v3.0)
|
|
2
|
+
|
|
3
|
+
Contributor guide for the v3.x codebase. Covers layering, hook anatomy, shared-lib catalog, testing patterns, CI flow, coding conventions, and the `zx`-vs-stdlib heuristic.
|
|
4
|
+
|
|
5
|
+
Target audience: anyone writing a new hook, adding a shared lib, or extending a skill with Node-side logic. Skill authors writing pure Markdown do not need this guide — see [`CONTRIBUTING.md`](../CONTRIBUTING.md) instead.
|
|
6
|
+
|
|
7
|
+
## 1. Layering
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
11
|
+
│ Editor runtime (Claude Code / Codex / Cursor IDE) │
|
|
12
|
+
│ → reads hooks.json, invokes hooks on events │
|
|
13
|
+
├─────────────────────────────────────────────────────────────┤
|
|
14
|
+
│ hooks/*.mjs │
|
|
15
|
+
│ PreToolUse, PostToolUse, SessionStart, Stop, │
|
|
16
|
+
│ SubagentStop — Node processes, stdin JSON in, │
|
|
17
|
+
│ single-line JSON out (exit 0 = allow, 2 = deny) │
|
|
18
|
+
├─────────────────────────────────────────────────────────────┤
|
|
19
|
+
│ scripts/lib/*.mjs │
|
|
20
|
+
│ Shared helpers — io, platform, path-utils, config, │
|
|
21
|
+
│ events, worktree, hardening, common │
|
|
22
|
+
├─────────────────────────────────────────────────────────────┤
|
|
23
|
+
│ Node 24+ stdlib + zx 8 │
|
|
24
|
+
│ fs.promises, path, os, url, crypto, fetch, │
|
|
25
|
+
│ application logic in ESM; POSIX shell only for run-node │
|
|
26
|
+
└─────────────────────────────────────────────────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Skills (`skills/**/*.md`) sit outside this stack — they are instructions for the agent, not code. When a skill needs logic (config parsing, file I/O, subprocess spawning), it invokes a `scripts/lib/*.mjs` module via `node -e` or delegates to a hook.
|
|
30
|
+
|
|
31
|
+
Codex installation is also layered through public APIs rather than private files. `scripts/codex-install.mjs` validates the tracked manifest and hook contract, calls `codex plugin marketplace add`, calls `codex plugin add`, and verifies the result with `codex plugin list --available --json`. A configured marketplace, an installed+enabled plugin, and trusted/executing hooks are separate postconditions; only the operator can grant the last one in a fresh task through `/hooks`.
|
|
32
|
+
|
|
33
|
+
The installer repeats `plugin add` on every run so the installed bundle refreshes after local changes. Explicit invalidation comes from the committed `.codex-plugin/plugin.json` version format `<package-version>+codex.<YYYYMMDDHHmmss>`. The contract validator checks the base and UTC timestamp; the installer never mutates the tracked version.
|
|
34
|
+
|
|
35
|
+
## 2. Hook Anatomy
|
|
36
|
+
|
|
37
|
+
Every hook follows the same I/O contract, enforced by `scripts/lib/io.mjs`.
|
|
38
|
+
|
|
39
|
+
### Template
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
#!/usr/bin/env node
|
|
43
|
+
// hooks/example.mjs
|
|
44
|
+
import { readStdin, emitAllow, emitDeny, emitWarn } from '../scripts/lib/io.mjs';
|
|
45
|
+
|
|
46
|
+
async function main() {
|
|
47
|
+
const input = await readStdin(); // parses JSON stdin with 5s timeout + 1 MB guard
|
|
48
|
+
const event = JSON.parse(input);
|
|
49
|
+
|
|
50
|
+
// Read the event payload. Shape depends on the hook type —
|
|
51
|
+
// PreToolUse has { tool_name, tool_input }, SessionStart has { session_id, … }, etc.
|
|
52
|
+
const { tool_name, tool_input } = event;
|
|
53
|
+
|
|
54
|
+
if (tool_name === 'Bash' && looksDangerous(tool_input.command)) {
|
|
55
|
+
emitDeny('Blocked by example policy', { reason: 'dangerous-pattern' });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
emitAllow();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Top-level try/catch prevents exit code 1 from propagating to the editor.
|
|
63
|
+
main().catch((err) => {
|
|
64
|
+
emitDeny(`Hook crashed: ${err.message}`, { fatal: true });
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Contract
|
|
69
|
+
|
|
70
|
+
| Direction | Format |
|
|
71
|
+
|-----------|--------|
|
|
72
|
+
| stdin | Single JSON object from the editor. Type depends on hook event. |
|
|
73
|
+
| stdout | Exactly one line of JSON. `{ "decision": "allow" }`, `{ "decision": "deny", "reason": "…" }`, or `{ "decision": "warn", "message": "…" }`. |
|
|
74
|
+
| exit code | `0` on allow / warn. `2` on deny. **Never exit `1`** — the editor treats that as a hook crash and blocks conservatively. |
|
|
75
|
+
| stderr | Only for debugging. Not surfaced to the user. |
|
|
76
|
+
|
|
77
|
+
Always wrap `main()` in a top-level `.catch` that calls `emitDeny` — an unhandled exception would otherwise exit 1.
|
|
78
|
+
|
|
79
|
+
### Registering the hook
|
|
80
|
+
|
|
81
|
+
Edit `hooks/hooks.json`. Each entry maps an event matcher to the Node command, routed through the `run-node.sh` resolver shim (GH#53 — the harness hook shell does not source `~/.zshrc`, so a bare `node` may be unresolvable even when it works in your terminal):
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"hooks": {
|
|
86
|
+
"PreToolUse": [
|
|
87
|
+
{ "matcher": "Bash", "hooks": [ { "type": "command", "command": "sh \"$CLAUDE_PLUGIN_ROOT/hooks/run-node.sh\" \"$CLAUDE_PLUGIN_ROOT/hooks/example.mjs\"" } ] }
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Use the harness-native root variable: `$CLAUDE_PLUGIN_ROOT` for Claude Code, `${PLUGIN_ROOT}` inside Codex hook manifests, `$CURSOR_RULES_DIR` for Cursor, and `$PI_PLUGIN_ROOT` for Pi. Never hard-code absolute paths, and never register a bare `node ...` command (the wiring guard in `tests/hooks/run-node-shim.test.mjs` fails on it).
|
|
94
|
+
|
|
95
|
+
Codex's validated wrapper is intentionally exact:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"type": "command",
|
|
100
|
+
"command": "SO_PLATFORM=codex CODEX_PLUGIN_ROOT=\"${PLUGIN_ROOT}\" sh \"${PLUGIN_ROOT}/hooks/run-node.sh\" \"${PLUGIN_ROOT}/hooks/on-session-start.mjs\""
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`${PLUGIN_ROOT}` is Codex-native. `CODEX_PLUGIN_ROOT` is a compatibility export for shared root resolution, and `SO_PLATFORM=codex` takes precedence in handlers that receive multiple harness signals.
|
|
105
|
+
|
|
106
|
+
`hooks/hooks-codex.json` is not a copy of the Claude hook file. It contains the six Codex project event slots (`SessionStart`, `PreToolUse`, `PostToolUse`, `SubagentStart`, `SubagentStop`, `Stop`). `SessionEnd`, `PostToolUseFailure`, `PostToolBatch`, and `CwdChanged` are Claude-only and rejected by the Codex contract. Edit-related Claude handlers are also rejected because they do not understand Codex's canonical `apply_patch` payload; keep them absent until a real adapter exists.
|
|
107
|
+
|
|
108
|
+
Hook registration still does not establish trust. After install or refresh, test in a fresh Codex task and use `/hooks` to inspect and approve the bundle. No installer or validation script may write or bypass that operator decision.
|
|
109
|
+
|
|
110
|
+
## 3. Shared Lib Catalog
|
|
111
|
+
|
|
112
|
+
Under `scripts/lib/`. Each module is a focused concern and exports only what callers need.
|
|
113
|
+
|
|
114
|
+
| Module | 1-liner | Key exports |
|
|
115
|
+
|--------|---------|-------------|
|
|
116
|
+
| **`io.mjs`** | Hook stdin/stdout helpers matching the Claude Code contract | `readStdin`, `emitAllow`, `emitDeny`, `emitWarn`, `emitSystemMessage` |
|
|
117
|
+
| **`platform.mjs`** | OS + editor detection | `SO_OS`, `SO_IS_WINDOWS`, `SO_IS_WSL`, `SO_PATH_SEP`, `SO_STATE_DIR`, `detectPlatform()` |
|
|
118
|
+
| **`path-utils.mjs`** | CWE-23-safe path helpers (null-byte rejection, UNC block, cross-drive escape, locale-stable casing) | `normalizeForMatching`, `isWithin`, `CWE_23_ATTACK_PATTERNS` |
|
|
119
|
+
| **`config.mjs`** | CRLF-tolerant Session Config parser (originally parse-config.sh in v2; byte-exact parity preserved) | `parseSessionConfig`, `readConfigFile`, `getConfigValue` |
|
|
120
|
+
| **`config-schema.mjs`** | Plain-JS validator; validates the 7 mandatory Session Config fields (3 required strings + 4 typed fields) | `validateSessionConfig` (internal `REQUIRED_STRING_FIELDS` constant covers the 3 required strings — not exported) |
|
|
121
|
+
| **`events.mjs`** | Append to `.orchestrator/metrics/events.jsonl` + optional webhook POST | `emitEvent`, `appendEvent` |
|
|
122
|
+
| **`worktree.mjs`** | zx-based git worktree helpers with cross-platform paths | `createWorktree`, `removeWorktree`, `listWorktrees`, `cleanupAllWorktrees` |
|
|
123
|
+
| **`hardening.mjs`** | Scope + command enforcement primitives | `findScopeFile`, `getEnforcementLevel`, `pathMatchesPattern`, `commandMatchesBlocked` |
|
|
124
|
+
| **`common.mjs`** | Grab-bag utilities | `makeTmpPath`, `utcTimestamp`, `readJson`, `writeJson`, `appendJsonl` |
|
|
125
|
+
| **`state-md.mjs`** | Hand-rolled YAML-subset STATE.md parser (never throws) | `parseStateMd`, `serializeStateMd`, `touchUpdatedField` |
|
|
126
|
+
| **`host-identity.mjs`** | Device fingerprint + SSH detection (v3.1 resource-awareness) | `getHostIdentity`, `isSshSession` |
|
|
127
|
+
| **`resource-probe.mjs`** | Live RAM/CPU/process snapshot (v3.1) | `probe`, `evaluate` |
|
|
128
|
+
| **`pre-dispatch-check.mjs`** | Worktree overlap guard before agent dispatch (v3.1) | `checkOverlap` |
|
|
129
|
+
| **`package-manager.mjs`** | Lockfile-based package-manager detection | `detectPackageManager`, `defaultCommands` |
|
|
130
|
+
| **`quality-gates-policy.mjs`** | JSON-Schema policy loader for test/typecheck/lint | `loadQualityGatesPolicy`, `resolveCommand` |
|
|
131
|
+
|
|
132
|
+
### Import example
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
import { readJson, writeJson } from '../scripts/lib/common.mjs';
|
|
136
|
+
import { SO_IS_WINDOWS } from '../scripts/lib/platform.mjs';
|
|
137
|
+
|
|
138
|
+
const cfg = await readJson('.orchestrator/policy/blocked-commands.json');
|
|
139
|
+
cfg.updated = new Date().toISOString();
|
|
140
|
+
await writeJson('.orchestrator/policy/blocked-commands.json', cfg);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
All shared libs are ES modules. Import with explicit `.mjs` extensions — Node's ESM loader does not resolve bare specifiers for relative paths.
|
|
144
|
+
|
|
145
|
+
## 4. Testing Patterns
|
|
146
|
+
|
|
147
|
+
Tests live under `tests/` and are run by `npm test` (vitest).
|
|
148
|
+
|
|
149
|
+
### Directory layout
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
tests/
|
|
153
|
+
├── lib/ # unit tests for scripts/lib/*.mjs
|
|
154
|
+
├── hooks/ # unit tests for hooks/*.mjs
|
|
155
|
+
├── integration/ # cross-component tests (hook-smoke, parse-config-validator, etc.)
|
|
156
|
+
└── fixtures/ # fixture inputs (CLAUDE.md variants, event payloads, …)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Stdin mocking for hooks
|
|
160
|
+
|
|
161
|
+
Hooks read JSON from stdin. The pattern is to spawn the hook as a subprocess and pipe the payload:
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
import { spawn } from 'node:child_process';
|
|
165
|
+
import { fileURLToPath } from 'node:url';
|
|
166
|
+
import { resolve } from 'node:path';
|
|
167
|
+
|
|
168
|
+
function runHook(hookPath, payload) {
|
|
169
|
+
return new Promise((resolveResult) => {
|
|
170
|
+
const proc = spawn('node', [hookPath], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
171
|
+
let stdout = '';
|
|
172
|
+
let stderr = '';
|
|
173
|
+
proc.stdout.on('data', (d) => (stdout += d));
|
|
174
|
+
proc.stderr.on('data', (d) => (stderr += d));
|
|
175
|
+
proc.on('close', (code) => resolveResult({ code, stdout, stderr }));
|
|
176
|
+
proc.stdin.end(JSON.stringify(payload));
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Usage
|
|
181
|
+
const hookPath = resolve(fileURLToPath(import.meta.url), '../../../hooks/example.mjs');
|
|
182
|
+
const { code, stdout } = await runHook(hookPath, { tool_name: 'Bash', tool_input: { command: 'ls' } });
|
|
183
|
+
expect(code).toBe(0);
|
|
184
|
+
expect(JSON.parse(stdout).decision).toBe('allow');
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
`tests/integration/hook-smoke.test.mjs` is the canonical reference for this pattern.
|
|
188
|
+
|
|
189
|
+
### OS-conditional tests
|
|
190
|
+
|
|
191
|
+
Use `skipIf` / `runIf` with `process.platform`:
|
|
192
|
+
|
|
193
|
+
```js
|
|
194
|
+
import { describe, it, skipIf } from 'vitest';
|
|
195
|
+
|
|
196
|
+
describe('symlink escape on posix only', () => {
|
|
197
|
+
skipIf(process.platform === 'win32')('rejects symlinks outside scope', async () => {
|
|
198
|
+
// posix-specific test body
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Spawn helper
|
|
204
|
+
|
|
205
|
+
For lib tests that invoke real subprocesses (e.g., parity checks against the legacy Bash versions), use the helper in `tests/_spawn-helper.mjs` which handles Windows shell quoting and timeouts.
|
|
206
|
+
|
|
207
|
+
## 5. CI Flow
|
|
208
|
+
|
|
209
|
+
`.github/workflows/test.yml` runs the full suite on every push and PR across three OSes.
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
matrix:
|
|
213
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
214
|
+
node: [20]
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
`fail-fast: false` so a Windows-only flake does not mask an Ubuntu regression. Each job:
|
|
218
|
+
|
|
219
|
+
1. Checkouts (SHA-pinned `actions/checkout`).
|
|
220
|
+
2. Installs `jq` via the OS package manager.
|
|
221
|
+
3. `npm ci` — reproducible install from lockfile.
|
|
222
|
+
4. `npm run lint` — ESLint v9 + Prettier.
|
|
223
|
+
5. `npm run typecheck` — `node --check scripts/lib/*.mjs` (syntactic-only; there is no TypeScript yet).
|
|
224
|
+
6. `npm test` — vitest run.
|
|
225
|
+
|
|
226
|
+
### Debugging Windows-only failures
|
|
227
|
+
|
|
228
|
+
1. Reproduce locally if possible (Windows VM, GitHub Actions runner image, or a Windows-native dev box).
|
|
229
|
+
2. Check line endings — v3 ships `.gitattributes` with explicit LF rules, but a pre-v3 checkout may have CRLF. Run `git config core.autocrlf false && git rm --cached -r . && git reset --hard`.
|
|
230
|
+
3. Inspect paths — Node on Windows uses `\`, but many libs normalize to `/`. `scripts/lib/path-utils.mjs:normalizeForMatching` is the canonical normalizer.
|
|
231
|
+
4. Check tmpdir — `os.tmpdir()` on Windows returns `C:\Users\…\Temp`, which trips tests that hard-coded `/tmp`.
|
|
232
|
+
5. Read the CI logs: `gh run view --log <run-id>` or download the artifact from the Actions tab.
|
|
233
|
+
|
|
234
|
+
## 6. Coding Conventions
|
|
235
|
+
|
|
236
|
+
Enforced by ESLint v9 + Prettier. See `eslint.config.js` and `.prettierrc`.
|
|
237
|
+
|
|
238
|
+
- **ES modules only.** Every new Node file uses `.mjs`, `import`/`export`, top-level `await`. No CommonJS (`require`, `module.exports`).
|
|
239
|
+
- **Single quotes, 100-column width, LF line endings.** Prettier handles this automatically — `npm run lint:fix` fixes offenders in place.
|
|
240
|
+
- **`_`-prefix for intentionally-unused variables.** `no-unused-vars` allows `_`-prefixed names (including destructure patterns). Example: `const [_status, stdout] = await run(cmd);`.
|
|
241
|
+
- **Path handling.** Never concatenate path strings with `+` or `\``. Always `path.join(...)`. For path comparisons, go through `path-utils.mjs:normalizeForMatching`.
|
|
242
|
+
- **Subprocess spawning.** Prefer `zx`'s `$` tag for shell-like commands (handles quoting). For untrusted input, pass arguments via `child_process.spawn` arg arrays, not concatenated shell strings.
|
|
243
|
+
- **Error handling.** Hooks: top-level `.catch` → `emitDeny`. Libs: throw with context (`throw new Error('parseConfig: missing field X')`) and let the caller decide. Never swallow errors silently except on best-effort cleanup paths, and warn to stderr when you do.
|
|
244
|
+
- **No `console.log` in libs or hooks.** `stdout` is reserved for the hook I/O contract. Diagnostics go to `stderr` or `events.jsonl` via `events.mjs`.
|
|
245
|
+
- **`===` / `!==` always.** `==`/`!=` is banned (`eqeqeq`).
|
|
246
|
+
- **No `var`.** `const` by default, `let` when reassignment is genuinely needed.
|
|
247
|
+
- **Tests are `.test.mjs` or `.spec.mjs`.** vitest picks them up automatically under `tests/`.
|
|
248
|
+
|
|
249
|
+
## 7. When to use zx vs. Node stdlib
|
|
250
|
+
|
|
251
|
+
Rule of thumb:
|
|
252
|
+
|
|
253
|
+
| Use zx (`$`, `nothrow`) | Use Node stdlib |
|
|
254
|
+
|------------------------|-----------------|
|
|
255
|
+
| Spawning external commands (`git`, `glab`, `gh`, `npm`) | Reading/writing files |
|
|
256
|
+
| Shell-like composition (pipes, redirection) | Parsing JSON |
|
|
257
|
+
| Cross-platform quoting (zx handles spaces, quotes) | HTTP requests (`fetch`) |
|
|
258
|
+
| Commands that may fail and whose failure you want to inspect (`nothrow`) | Timers, signals, crypto |
|
|
259
|
+
|
|
260
|
+
Example — **good zx usage**:
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
import { $, nothrow } from 'zx';
|
|
264
|
+
|
|
265
|
+
const { stdout: branch } = await $`git rev-parse --abbrev-ref HEAD`;
|
|
266
|
+
const { exitCode } = await nothrow($`git worktree remove ${tmpDir}`);
|
|
267
|
+
if (exitCode !== 0) {
|
|
268
|
+
// best-effort cleanup; don't crash
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Example — **use stdlib instead**:
|
|
273
|
+
|
|
274
|
+
```js
|
|
275
|
+
// BAD — zx for a pure file read
|
|
276
|
+
const { stdout } = await $`cat ${path}`;
|
|
277
|
+
|
|
278
|
+
// GOOD — use fs
|
|
279
|
+
import { readFile } from 'node:fs/promises';
|
|
280
|
+
const content = await readFile(path, 'utf-8');
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Reasons to prefer stdlib when possible:
|
|
284
|
+
|
|
285
|
+
- **Speed.** Spawning a shell to `cat` a file is ~100× slower than `fs.readFile`.
|
|
286
|
+
- **Windows portability.** `cat` is absent on stock Windows; `readFile` is universal.
|
|
287
|
+
- **Error messages.** `ENOENT` from stdlib is more precise than a shell exit code.
|
|
288
|
+
|
|
289
|
+
Reasons zx wins when it does:
|
|
290
|
+
|
|
291
|
+
- **Git + CLI tooling.** `git`, `glab`, `gh` have rich output formats and exit-code semantics that zx preserves.
|
|
292
|
+
- **Quote handling.** zx's `$` template literal handles argument quoting on Windows and POSIX consistently. `child_process.exec` with concatenated strings does not.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
Questions or gaps? Open an issue at [session-orchestrator](https://github.com/Kanevry/session-orchestrator/issues) with label `area:docs`.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# `phuryn/pm-skills` — Install-Alongside Guidance
|
|
2
|
+
|
|
3
|
+
> Companion doc for the 2026-07-05 `phuryn/pm-skills` evaluation (Epic #750,
|
|
4
|
+
> issue #761). Verdict: **crib the proven techniques, don't vendor the
|
|
5
|
+
> marketplace.** The cribbed techniques already live natively in `/grill`,
|
|
6
|
+
> `/brainstorm`, `/plan`, and the `/discovery` `feature` scope (see § Overlap
|
|
7
|
+
> table below). This doc is for the narrower case where a *product* repo
|
|
8
|
+
> wants the full `phuryn/pm-skills` roster installed side-by-side.
|
|
9
|
+
|
|
10
|
+
## When to install alongside
|
|
11
|
+
|
|
12
|
+
`phuryn/pm-skills` (68-skill PM marketplace, MIT license, Claude-Code-shaped)
|
|
13
|
+
is worth installing **in addition to** this plugin when a repo has a genuine,
|
|
14
|
+
recurring PM-workflow need that produces standalone artifacts this plugin
|
|
15
|
+
does not generate:
|
|
16
|
+
|
|
17
|
+
- **Product-heavy repos** — Ventures-produkt-repos, client MVPs with an
|
|
18
|
+
active PM/product-owner role — that run discovery interviews, maintain a
|
|
19
|
+
roadmap document, or keep persona/Opportunity-Solution-Tree artifacts as
|
|
20
|
+
living deliverables (not one-off planning inputs).
|
|
21
|
+
- The team wants those artifacts as their own documents (roadmap.md,
|
|
22
|
+
personas.md, OST diagrams) rather than folded into a PRD or an interrogation
|
|
23
|
+
transcript.
|
|
24
|
+
- Cursor-IDE parity is not a requirement for that repo — `phuryn/pm-skills`
|
|
25
|
+
targets Claude-Code-shaped skills with no guarantee of cross-platform
|
|
26
|
+
support.
|
|
27
|
+
|
|
28
|
+
## When NOT to install alongside
|
|
29
|
+
|
|
30
|
+
- **Infrastructure / tooling repos** (this repo is the reference case). The
|
|
31
|
+
evidence-based slice of PM discipline — assumption interrogation,
|
|
32
|
+
divergent ideation, opportunity ranking, and evidence-anchored
|
|
33
|
+
feature-intent findings — is already native here:
|
|
34
|
+
- `/grill` — kill-assumption operationalization (Fails-if / Evidence-this-week
|
|
35
|
+
/ Kill-criterion / Cheapest-test) + pre-mortem Tiger/Paper-Tiger/Elephant
|
|
36
|
+
taxonomy, part of the Six Tactics in `skills/grill/soul.md`.
|
|
37
|
+
- `/brainstorm` — three-lens (PM / Designer / Engineer) divergent ideation
|
|
38
|
+
pass plus Mom-Test interview discipline, in `skills/brainstorm/SKILL.md`.
|
|
39
|
+
- `/plan` — Opportunity Score ranking, Impact×Risk 2×2 triage, and an
|
|
40
|
+
optional job-story format, in `skills/plan/SKILL.md` / `mode-feature.md`.
|
|
41
|
+
- `/discovery feature` — grounded, grep-verified intent-drift and
|
|
42
|
+
stubbed/dead-feature probes (`skills/discovery/probes-feature.md`),
|
|
43
|
+
routing judgment-based PM work (OST, personas, market-sizing) out to
|
|
44
|
+
`/brainstorm`/`/plan` rather than treating it as a verified finding.
|
|
45
|
+
- A second, un-integrated 68-skill roster would not participate in this
|
|
46
|
+
plugin's session-config, quality gates, or `/discovery` verification
|
|
47
|
+
pipeline (PSA-006) — see § Warnings below.
|
|
48
|
+
|
|
49
|
+
## How to install
|
|
50
|
+
|
|
51
|
+
`phuryn/pm-skills` follows the same Claude Code plugin-marketplace mechanism
|
|
52
|
+
this plugin itself ships through (see `README.md` § Install):
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
/plugin marketplace add phuryn/pm-skills
|
|
56
|
+
/plugin install <skill-name>@phuryn
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Consult the `phuryn/pm-skills` repository (github.com/phuryn/pm-skills) for
|
|
60
|
+
the exact marketplace slug and the current skill roster — this doc does not
|
|
61
|
+
duplicate that upstream README. Install only the specific skills a repo
|
|
62
|
+
needs (roadmap, persona, OST artifact generation) rather than the full
|
|
63
|
+
roster, to limit auto-dispatch noise (see § Warnings).
|
|
64
|
+
|
|
65
|
+
## Overlap / Abgrenzung
|
|
66
|
+
|
|
67
|
+
| Capability | Overlap with this plugin | Where it lives | Verdict |
|
|
68
|
+
|---|---|---|---|
|
|
69
|
+
| Assumption interrogation / red-teaming a plan | `strategy-red-team`-class pm-skills ↔ `/grill` | `skills/grill/soul.md` (Six Tactics, kill-assumption workup, pre-mortem) | Overlap — prefer `/grill` (session/gate-integrated, codebase-grounded) |
|
|
70
|
+
| Divergent ideation / brainstorming | `brainstorm-ideas-*`-class pm-skills ↔ `/brainstorm` | `skills/brainstorm/SKILL.md` (three-lens PM/Designer/Engineer pass, Mom-Test) | Overlap — prefer `/brainstorm` (HARD-GATE + PRD hand-off already wired) |
|
|
71
|
+
| PRD generation / feature scoping / prioritization | `create-prd`-class pm-skills ↔ `/plan feature` | `skills/plan/SKILL.md`, `mode-feature.md` (Opportunity Score, 2×2 risk triage, job-story option) | Overlap — prefer `/plan` (researched Q&A engine, issue creation, appetite/scope discipline already wired) |
|
|
72
|
+
| Documented-vs-enforced intent auditing | No pm-skills equivalent | `/discovery feature` (`skills/discovery/probes-feature.md`) | Unique to this plugin — grep-verified, not judgment-based |
|
|
73
|
+
| Roadmap documents, stakeholder maps, persona trees as standalone artifacts | No equivalent here — this plugin folds personas/roadmap input into PRDs, not standalone living documents | `phuryn/pm-skills` | Unique to pm-skills — install alongside if a repo needs these as first-class artifacts |
|
|
74
|
+
| Opportunity Solution Tree (OST) as a maintained document | No equivalent here (OST reasoning is routed out of `/discovery`'s verified pipeline per its Non-Goals) | `phuryn/pm-skills` | Unique to pm-skills |
|
|
75
|
+
| Market-sizing / competitive-landscape docs | No equivalent here | `phuryn/pm-skills` | Unique to pm-skills |
|
|
76
|
+
|
|
77
|
+
Rule of thumb: where a technique overlaps, this plugin's version wins because
|
|
78
|
+
it is wired into session lifecycle, quality gates, and issue creation.
|
|
79
|
+
Where the artifact is a standalone PM document this plugin was never
|
|
80
|
+
designed to produce, `phuryn/pm-skills` fills a real gap — install it
|
|
81
|
+
alongside for those repos only.
|
|
82
|
+
|
|
83
|
+
## Warnings
|
|
84
|
+
|
|
85
|
+
- **Roster size → auto-dispatch noise.** Installing the full 68-skill roster
|
|
86
|
+
alongside this plugin's own skill catalog increases the surface
|
|
87
|
+
`auto-skill-dispatch` phrase-matching has to disambiguate against. Prefer
|
|
88
|
+
installing only the specific skills a repo actually uses.
|
|
89
|
+
- **Claude Code only.** `phuryn/pm-skills` is Claude-Code-shaped with no
|
|
90
|
+
Cursor IDE (or Codex CLI / Pi) parity guarantee. This plugin maintains
|
|
91
|
+
cross-platform support (see `README.md` § Install) — a repo that also runs
|
|
92
|
+
Cursor sessions loses parity the moment it depends on a pm-skills-only
|
|
93
|
+
workflow.
|
|
94
|
+
- **No session-config or gate integration.** pm-skills artifacts do not
|
|
95
|
+
participate in this plugin's Session Config, quality gates, or
|
|
96
|
+
`/discovery` PSA-006 verification discipline. Treat its output as an
|
|
97
|
+
independent artifact stream, not something `/close` or the wave-executor
|
|
98
|
+
will track.
|
|
99
|
+
- **Sunset risk.** An installed-but-rarely-used skill from the roster is a
|
|
100
|
+
`sunset-review` candidate within a session or two — install narrowly, or
|
|
101
|
+
expect churn.
|
|
102
|
+
|
|
103
|
+
## See Also
|
|
104
|
+
|
|
105
|
+
- `README.md` § Install — the plugin-marketplace install mechanism this doc
|
|
106
|
+
reuses.
|
|
107
|
+
- `skills/grill/soul.md`, `skills/brainstorm/SKILL.md`, `skills/plan/SKILL.md`
|
|
108
|
+
— the native crib targets (Six Tactics, three-lens ideation, Opportunity
|
|
109
|
+
Score/2×2/job-story).
|
|
110
|
+
- `skills/discovery/probes-feature.md` — the grep-verified intent-drift and
|
|
111
|
+
stubbed-dead-feature probes that keep evidence-based PM findings inside
|
|
112
|
+
the verified pipeline.
|
|
113
|
+
- Epic #750 / issue #761 — the evaluation and companion-doc tracking issue
|
|
114
|
+
this document closes.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Policy-Cache Effectiveness Validation (#266)
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-04-28
|
|
4
|
+
**Issue:** #266 — [Follow-up #250] Validate policy-cache effectiveness under Claude Code subprocess-per-call hook model
|
|
5
|
+
**Measurement script:** `scripts/measure-policy-cache-effectiveness.mjs`
|
|
6
|
+
**Environment:** Darwin 25.3.0, Node.js v24.13.1
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Background
|
|
11
|
+
|
|
12
|
+
Issue #250 introduced `scripts/lib/quality-gates-cache.mjs` — a JSONL file-based cache that persists quality-gate Baseline results to `.orchestrator/metrics/baseline-results.jsonl`. The concern raised in #266 was that under Claude Code's subprocess-per-call hook model (each hook invocation spawns a fresh Node.js process), any *in-process* memoisation would be useless because process memory is discarded after every hook run.
|
|
13
|
+
|
|
14
|
+
Two cache layers were audited:
|
|
15
|
+
|
|
16
|
+
| Module | Mechanism | Claim |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `quality-gates-cache.mjs` | Append-only JSONL on disk | Baseline results persist across waves |
|
|
19
|
+
| `quality-gates-policy.mjs` | Synchronous `fs.readFileSync` | No caching claim — reads the policy file fresh every call |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Findings
|
|
24
|
+
|
|
25
|
+
### 1. Baseline-Result Cache (`quality-gates-cache.mjs`)
|
|
26
|
+
|
|
27
|
+
**Cache mechanism:** JSONL file — reads and writes `.orchestrator/metrics/baseline-results.jsonl` on every call. There is **no in-process memoisation**. The file is the cache.
|
|
28
|
+
|
|
29
|
+
**Subprocess-per-call model (8 subprocesses):**
|
|
30
|
+
|
|
31
|
+
| Metric | Value |
|
|
32
|
+
|---|---|
|
|
33
|
+
| Hit rate | 100% (8/8) |
|
|
34
|
+
| Mean call time (self-reported) | 0.456 ms |
|
|
35
|
+
| Median call time | 0.453 ms |
|
|
36
|
+
| Persists across subprocess boundaries | **Yes** |
|
|
37
|
+
|
|
38
|
+
**Multi-call-in-process model (5 calls, same process):**
|
|
39
|
+
|
|
40
|
+
| Call | Time |
|
|
41
|
+
|---|---|
|
|
42
|
+
| Cold (#1) | 0.220 ms |
|
|
43
|
+
| Warm mean (#2–5) | 0.065 ms |
|
|
44
|
+
| Hit rate | 100% |
|
|
45
|
+
|
|
46
|
+
**Conclusion:** The cache is fully effective under the subprocess-per-call model. Because persistence is file-based (JSONL), each new subprocess reads the same on-disk record and gets a cache hit as long as the validity criteria are met (`session_start_ref` match, `dependency_hash` match, TTL, all-pass results). The 3.4× speedup from cold→warm in a single process (0.220 ms → 0.065 ms) is from OS page-cache, not module-level memoisation.
|
|
47
|
+
|
|
48
|
+
**The issue concern is a non-issue:** The cache was never designed around in-process memory. It deliberately uses disk I/O for cross-process durability.
|
|
49
|
+
|
|
50
|
+
### 2. Policy File Loader (`quality-gates-policy.mjs`)
|
|
51
|
+
|
|
52
|
+
**Cache mechanism:** None. Every call reads `.orchestrator/policy/quality-gates.json` synchronously via `fs.readFileSync`. No in-process memoisation, no file-based cache.
|
|
53
|
+
|
|
54
|
+
**Subprocess-per-call model (8 subprocesses, no policy file present):**
|
|
55
|
+
|
|
56
|
+
| Metric | Value |
|
|
57
|
+
|---|---|
|
|
58
|
+
| Policy found | 0/8 (no `quality-gates.json` in test repo) |
|
|
59
|
+
| Mean call time | 0.098 ms |
|
|
60
|
+
| Median call time | 0.096 ms |
|
|
61
|
+
|
|
62
|
+
**Multi-call-in-process model (5 calls):**
|
|
63
|
+
|
|
64
|
+
| Call | Time |
|
|
65
|
+
|---|---|
|
|
66
|
+
| Cold (#1) | 0.044 ms |
|
|
67
|
+
| Warm mean (#2–5) | 0.003 ms |
|
|
68
|
+
|
|
69
|
+
**Conclusion:** The 14.7× in-process speedup (0.044 ms → 0.003 ms) is entirely from OS page-cache. This module makes **no caching claims** — it is a policy *loader*, not a policy *cache*. At sub-0.1 ms per call even in the subprocess model, adding memoisation would provide no measurable benefit to hook latency.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Subprocess-Per-Call Hook Model Analysis
|
|
74
|
+
|
|
75
|
+
Claude Code spawns a fresh Node.js process for each hook event. The process startup overhead (Node.js bootstrap, ESM import chain) is **not measured here** — the timings above are for the module logic only, excluding the ~50–100 ms Node.js startup cost that dominates hook wall-clock time.
|
|
76
|
+
|
|
77
|
+
**Critical finding:** The `quality-gates-cache.mjs` module is called from `skills/wave-executor/wave-loop.md` inside the coordinator session (a long-running Claude Code process), **not** from hook handlers. This means the subprocess-per-call concern does not apply to the primary usage of this cache. The cache is invoked as an LLM-directed inline script call within the coordinator's context, not as a Claude Code hook.
|
|
78
|
+
|
|
79
|
+
Hook handlers (`hooks/*.mjs`) do not import `quality-gates-cache.mjs` at all. They handle scope enforcement, destructive-command guarding, and session events — none of which use the baseline-result cache.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Raw Numbers (2026-04-28T06:42:22Z)
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"config": { "subprocessCount": 8, "inprocessCount": 5 },
|
|
88
|
+
"cache_subprocess_hitRate": 1.0,
|
|
89
|
+
"cache_subprocess_medianMs": 0.453,
|
|
90
|
+
"cache_subprocess_meanMs": 0.455,
|
|
91
|
+
"cache_inprocess_coldMs": 0.220,
|
|
92
|
+
"cache_inprocess_warmMeanMs": 0.065,
|
|
93
|
+
"policy_subprocess_medianMs": 0.096,
|
|
94
|
+
"policy_inprocess_coldMs": 0.044,
|
|
95
|
+
"policy_inprocess_warmMeanMs": 0.003
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Recommendation: KEEP (no changes needed)
|
|
102
|
+
|
|
103
|
+
1. **`quality-gates-cache.mjs` — KEEP as-is.** The file-based JSONL design is the correct choice for a subprocess-hostile environment. It achieves 100% hit-rate across fresh subprocesses when the validity criteria are met. Sub-millisecond call latency is negligible relative to the quality-gate commands it short-circuits (typecheck + test = typically 10–60 seconds).
|
|
104
|
+
|
|
105
|
+
2. **`quality-gates-policy.mjs` — KEEP as-is.** Not a cache, does not claim to be one. The 0.096 ms per-call cost in the subprocess model is acceptable. Adding in-process memoisation would only benefit callers that invoke it multiple times in a single process, and the current warm-path latency (0.003 ms from OS page-cache) is already negligible.
|
|
106
|
+
|
|
107
|
+
3. **No action on issue #266's concern** that "the cache may not survive between calls." It does survive, by design. The misconception is that the cache is in-process memory — it is not. The JSONL file persists until TTL expiry (7 days), session-ref changes, or dependency hash changes.
|
|
108
|
+
|
|
109
|
+
4. **Optional future improvement (low priority):** An mtime-based shortcut in `loadLatestBaselineResult` could skip the full JSONL parse on repeated reads within a session if the file mtime hasn't changed. Current latency (~0.5 ms/call) does not justify this complexity.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Files
|
|
114
|
+
|
|
115
|
+
- `scripts/measure-policy-cache-effectiveness.mjs` — instrumentation script (supports `--json`, `--subprocess-count`, `--inprocess-count`, `--repo-root`)
|
|
116
|
+
- `docs/policy-cache-validation-2026-04-28.md` — this document
|
|
117
|
+
- `tests/scripts/measure-policy-cache-effectiveness.test.mjs` — smoke test (script runs, emits valid JSON)
|
|
118
|
+
- `skills/quality-gates/SKILL.md` — `§ Baseline Cache (#258)` — citation updated with validation reference
|