@opengsd/gsd-core 1.18.0 → 1.20.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 +1 -1
- package/.claude-plugin/plugin.json +2 -1
- package/.opencode/plugins/gsd-core.js +2 -3
- package/agents/gsd-code-fixer.compact.md +7 -7
- package/agents/gsd-code-fixer.md +13 -7
- package/agents/gsd-code-reviewer.compact.md +49 -8
- package/agents/gsd-code-reviewer.md +53 -14
- package/agents/gsd-executor.md +8 -4
- package/agents/gsd-verifier.md +1 -1
- package/bin/install.js +422 -103
- package/commands/gsd/update.md +5 -2
- package/gsd-core/bin/gsd-tools.cjs +179 -30
- package/gsd-core/bin/lib/agent-install-check.cjs +29 -3
- package/gsd-core/bin/lib/args-terminator.cjs +114 -0
- package/gsd-core/bin/lib/broken-windows.cjs +59 -1
- package/gsd-core/bin/lib/capability-lifecycle.cjs +1 -12
- package/gsd-core/bin/lib/capability-lock.cjs +13 -2
- package/gsd-core/bin/lib/capability-registry.cjs +376 -103
- package/gsd-core/bin/lib/capability-state.cjs +14 -8
- package/gsd-core/bin/lib/capability-validator.cjs +32 -0
- package/gsd-core/bin/lib/commands.cjs +27 -17
- package/gsd-core/bin/lib/config-loader.cjs +13 -3
- package/gsd-core/bin/lib/config.cjs +256 -58
- package/gsd-core/bin/lib/core-utils.cjs +45 -0
- package/gsd-core/bin/lib/decision-coverage-support.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +21 -3
- package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +2 -2
- package/gsd-core/bin/lib/gate-context-drift.cjs +9 -4
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +6 -1
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +6 -1
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +134 -13
- package/gsd-core/bin/lib/gate-phase-context.cjs +7 -8
- package/gsd-core/bin/lib/gate-schema-drift.cjs +1 -1
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +63 -22
- package/gsd-core/bin/lib/gate-ui-safety.cjs +23 -5
- package/gsd-core/bin/lib/git-info-exclude.cjs +52 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +31 -12
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +9 -7
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +3 -3
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +4 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +52 -1
- package/gsd-core/bin/lib/host-integration.cjs +13 -6
- package/gsd-core/bin/lib/init.cjs +245 -68
- package/gsd-core/bin/lib/install-engine.cjs +246 -32
- package/gsd-core/bin/lib/install-profiles.cjs +9 -4
- package/gsd-core/bin/lib/installer-migration-report.cjs +2 -0
- package/gsd-core/bin/lib/io.cjs +6 -0
- package/gsd-core/bin/lib/markdown-line-diff.cjs +147 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +147 -1
- package/gsd-core/bin/lib/markdown-table.cjs +23 -0
- package/gsd-core/bin/lib/mcp-server.cjs +8 -5
- package/gsd-core/bin/lib/milestone-lock.cjs +8 -1
- package/gsd-core/bin/lib/milestone-release-map.cjs +244 -0
- package/gsd-core/bin/lib/milestone-release-tags.cjs +440 -0
- package/gsd-core/bin/lib/milestone.cjs +61 -51
- package/gsd-core/bin/lib/model-catalog.cjs +8 -0
- package/gsd-core/bin/lib/normalize-test-command.cjs +67 -0
- package/gsd-core/bin/lib/phase-entry-grammar.cjs +119 -0
- package/gsd-core/bin/lib/phase-id-display.cjs +2 -0
- package/gsd-core/bin/lib/phase-id.cjs +629 -38
- package/gsd-core/bin/lib/phase-lifecycle.cjs +12 -44
- package/gsd-core/bin/lib/phase-locator.cjs +328 -19
- package/gsd-core/bin/lib/phase.cjs +3066 -653
- package/gsd-core/bin/lib/planning-document.cjs +26 -5
- package/gsd-core/bin/lib/planning-inspect.cjs +27 -35
- package/gsd-core/bin/lib/planning-snapshot.cjs +15 -8
- package/gsd-core/bin/lib/planning-workspace.cjs +21 -3
- package/gsd-core/bin/lib/pristine-baseline.cjs +11 -3
- package/gsd-core/bin/lib/read-only-git-env.cjs +79 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +2 -2
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +57 -2
- package/gsd-core/bin/lib/review-lane-invocation.cjs +125 -18
- package/gsd-core/bin/lib/review-lane-runner.cjs +33 -4
- package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +11 -9
- package/gsd-core/bin/lib/roadmap-parser.cjs +735 -137
- package/gsd-core/bin/lib/roadmap-progress.cjs +136 -0
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +47 -7
- package/gsd-core/bin/lib/roadmap.cjs +383 -123
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +381 -14
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +8 -4
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +60 -16
- package/gsd-core/bin/lib/shell-command-projection.cjs +151 -19
- package/gsd-core/bin/lib/smart-entry.cjs +35 -11
- package/gsd-core/bin/lib/state-contract.cjs +39 -15
- package/gsd-core/bin/lib/state-document.cjs +344 -27
- package/gsd-core/bin/lib/state-transition.cjs +156 -32
- package/gsd-core/bin/lib/state.cjs +527 -186
- package/gsd-core/bin/lib/surface.cjs +9 -0
- package/gsd-core/bin/lib/task-command-router.cjs +5 -25
- package/gsd-core/bin/lib/task-content-resolution.cjs +46 -1
- package/gsd-core/bin/lib/template.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +3 -2
- package/gsd-core/bin/lib/vendor/re2js.cjs +863 -577
- package/gsd-core/bin/lib/vendor/re2js.d.cts +284 -219
- package/gsd-core/bin/lib/verification.cjs +96 -9
- package/gsd-core/bin/lib/verify.cjs +4 -2
- package/gsd-core/bin/lib/workstream-inventory.cjs +26 -20
- package/gsd-core/bin/lib/worktree-safety.cjs +22 -1
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +1 -0
- package/gsd-core/bin/verify-reapply-patches.cjs +411 -10
- package/gsd-core/references/cicd-review-patterns.md +45 -0
- package/gsd-core/references/git-integration.md +11 -0
- package/gsd-core/references/loop-hook-dispatch.md +13 -6
- package/gsd-core/references/necessity-review.md +48 -0
- package/gsd-core/references/planning-config.md +2 -0
- package/gsd-core/references/tdd.md +2 -2
- package/gsd-core/templates/DEBUG.md +16 -0
- package/gsd-core/templates/config.json +2 -1
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/audit-fix.md +2 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +10 -1
- package/gsd-core/workflows/code-review-fix.md +46 -5
- package/gsd-core/workflows/code-review.md +64 -7
- package/gsd-core/workflows/complete-milestone/steps/project-md-evolution-review.md +145 -0
- package/gsd-core/workflows/complete-milestone/steps/release-map.md +80 -0
- package/gsd-core/workflows/complete-milestone.md +37 -150
- package/gsd-core/workflows/diagnose-issues.md +29 -5
- package/gsd-core/workflows/discuss-phase/modes/power.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +33 -2
- package/gsd-core/workflows/discuss-phase-power.md +19 -2
- package/gsd-core/workflows/discuss-phase.md +6 -10
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +13 -7
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +7 -2
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +11 -2
- package/gsd-core/workflows/execute-phase.md +10 -6
- package/gsd-core/workflows/execute-plan.md +1 -1
- package/gsd-core/workflows/health.md +2 -1
- package/gsd-core/workflows/import.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +2 -2
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +13 -9
- package/gsd-core/workflows/plan-phase.md +14 -14
- package/gsd-core/workflows/pr-branch.md +2 -0
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -1
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +8 -1
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +2 -1
- package/gsd-core/workflows/quick.md +1 -1
- package/gsd-core/workflows/reapply-patches.md +104 -0
- package/gsd-core/workflows/review.md +70 -154
- package/gsd-core/workflows/section-manifest.json +5 -0
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/settings-advanced.md +57 -9
- package/gsd-core/workflows/settings.md +1 -0
- package/gsd-core/workflows/ship.md +15 -4
- package/gsd-core/workflows/spec-phase.md +3 -6
- package/gsd-core/workflows/verify-work.md +4 -3
- package/hooks/dist/gsd-agent-isolation-guard.js +11 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
- package/hooks/dist/gsd-graphify-update.sh +6 -0
- package/hooks/dist/gsd-path-export.js +95 -0
- package/hooks/dist/gsd-secret-read-guard.js +172 -39
- package/hooks/dist/gsd-statusline.js +37 -3
- package/hooks/dist/gsd-windsurf-pre-write.js +29 -2
- package/hooks/dist/gsd-workflow-guard.js +3 -2
- package/hooks/dist/gsd-worktree-path-guard.js +29 -2
- package/hooks/dist/lib/git-probe.js +16 -0
- package/hooks/dist/lib/isolation-sentinel.js +44 -0
- package/hooks/dist/managed-hooks-registry.cjs +1 -0
- package/hooks/gsd-agent-isolation-guard.js +11 -1
- package/hooks/gsd-cursor-subagent-start.js +6 -2
- package/hooks/gsd-graphify-update.sh +6 -0
- package/hooks/gsd-path-export.js +95 -0
- package/hooks/gsd-secret-read-guard.js +172 -39
- package/hooks/gsd-statusline.js +37 -3
- package/hooks/gsd-windsurf-pre-write.js +29 -2
- package/hooks/gsd-workflow-guard.js +3 -2
- package/hooks/gsd-worktree-path-guard.js +29 -2
- package/hooks/hooks.json +1 -0
- package/hooks/lib/git-probe.js +16 -0
- package/hooks/lib/isolation-sentinel.js +44 -0
- package/hooks/managed-hooks-registry.cjs +1 -0
- package/package.json +15 -8
- package/pi/gsd.cjs +1047 -10
- package/pi/package-agents/gsd-advisor-researcher.md +113 -0
- package/pi/package-agents/gsd-ai-researcher.md +111 -0
- package/pi/package-agents/gsd-assumptions-analyzer.md +110 -0
- package/pi/package-agents/gsd-code-fixer.md +774 -0
- package/pi/package-agents/gsd-code-reviewer.md +441 -0
- package/pi/package-agents/gsd-codebase-mapper.md +850 -0
- package/pi/package-agents/gsd-debug-session-manager.md +416 -0
- package/pi/package-agents/gsd-debugger.md +1274 -0
- package/pi/package-agents/gsd-doc-classifier.md +269 -0
- package/pi/package-agents/gsd-doc-synthesizer.md +259 -0
- package/pi/package-agents/gsd-doc-verifier.md +212 -0
- package/pi/package-agents/gsd-doc-writer.md +626 -0
- package/pi/package-agents/gsd-dom-verifier.md +164 -0
- package/pi/package-agents/gsd-domain-researcher.md +144 -0
- package/pi/package-agents/gsd-eval-auditor.md +185 -0
- package/pi/package-agents/gsd-eval-planner.md +149 -0
- package/pi/package-agents/gsd-executor.md +898 -0
- package/pi/package-agents/gsd-framework-selector.md +159 -0
- package/pi/package-agents/gsd-integration-checker.md +476 -0
- package/pi/package-agents/gsd-intel-updater.md +338 -0
- package/pi/package-agents/gsd-mempalace-curator.md +49 -0
- package/pi/package-agents/gsd-nyquist-auditor.md +200 -0
- package/pi/package-agents/gsd-pattern-mapper.md +340 -0
- package/pi/package-agents/gsd-phase-researcher.md +897 -0
- package/pi/package-agents/gsd-plan-checker.md +1077 -0
- package/pi/package-agents/gsd-planner.md +1003 -0
- package/pi/package-agents/gsd-project-researcher.md +611 -0
- package/pi/package-agents/gsd-research-synthesizer.md +259 -0
- package/pi/package-agents/gsd-roadmapper.md +779 -0
- package/pi/package-agents/gsd-security-auditor.md +171 -0
- package/pi/package-agents/gsd-ui-auditor.md +581 -0
- package/pi/package-agents/gsd-ui-checker.md +417 -0
- package/pi/package-agents/gsd-ui-researcher.md +469 -0
- package/pi/package-agents/gsd-user-profiler.md +174 -0
- package/pi/package-agents/gsd-verifier.md +963 -0
- package/pi/package-agents/manifest.json +39 -0
- package/pi/package-skills/gsd-add-tests/SKILL.md +39 -0
- package/pi/package-skills/gsd-ai-integration-phase/SKILL.md +36 -0
- package/pi/package-skills/gsd-audit-fix/SKILL.md +34 -0
- package/pi/package-skills/gsd-audit-milestone/SKILL.md +40 -0
- package/pi/package-skills/gsd-audit-uat/SKILL.md +26 -0
- package/pi/package-skills/gsd-autonomous/SKILL.md +52 -0
- package/pi/package-skills/gsd-capture/SKILL.md +68 -0
- package/pi/package-skills/gsd-cleanup/SKILL.md +25 -0
- package/pi/package-skills/gsd-code-review/SKILL.md +71 -0
- package/pi/package-skills/gsd-complete-milestone/SKILL.md +147 -0
- package/pi/package-skills/gsd-config/SKILL.md +60 -0
- package/pi/package-skills/gsd-debug/SKILL.md +64 -0
- package/pi/package-skills/gsd-discuss-phase/SKILL.md +74 -0
- package/pi/package-skills/gsd-docs-update/SKILL.md +50 -0
- package/pi/package-skills/gsd-eval-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-execute-phase/SKILL.md +62 -0
- package/pi/package-skills/gsd-explore/SKILL.md +26 -0
- package/pi/package-skills/gsd-extract-learnings/SKILL.md +25 -0
- package/pi/package-skills/gsd-fast/SKILL.md +33 -0
- package/pi/package-skills/gsd-forensics/SKILL.md +59 -0
- package/pi/package-skills/gsd-graphify/SKILL.md +210 -0
- package/pi/package-skills/gsd-health/SKILL.md +36 -0
- package/pi/package-skills/gsd-help/SKILL.md +37 -0
- package/pi/package-skills/gsd-import/SKILL.md +46 -0
- package/pi/package-skills/gsd-inbox/SKILL.md +42 -0
- package/pi/package-skills/gsd-ingest-docs/SKILL.md +43 -0
- package/pi/package-skills/gsd-manager/SKILL.md +46 -0
- package/pi/package-skills/gsd-map-codebase/SKILL.md +85 -0
- package/pi/package-skills/gsd-mempalace-capture/SKILL.md +111 -0
- package/pi/package-skills/gsd-mempalace-recall/SKILL.md +111 -0
- package/pi/package-skills/gsd-milestone-summary/SKILL.md +54 -0
- package/pi/package-skills/gsd-mvp-phase/SKILL.md +45 -0
- package/pi/package-skills/gsd-new-milestone/SKILL.md +49 -0
- package/pi/package-skills/gsd-new-project/SKILL.md +49 -0
- package/pi/package-skills/gsd-next/SKILL.md +34 -0
- package/pi/package-skills/gsd-ns-context/SKILL.md +31 -0
- package/pi/package-skills/gsd-ns-ideate/SKILL.md +30 -0
- package/pi/package-skills/gsd-ns-manage/SKILL.md +42 -0
- package/pi/package-skills/gsd-ns-project/SKILL.md +34 -0
- package/pi/package-skills/gsd-ns-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-ns-workflow/SKILL.md +44 -0
- package/pi/package-skills/gsd-onboard/SKILL.md +46 -0
- package/pi/package-skills/gsd-pause-work/SKILL.md +48 -0
- package/pi/package-skills/gsd-phase/SKILL.md +61 -0
- package/pi/package-skills/gsd-plan-phase/SKILL.md +62 -0
- package/pi/package-skills/gsd-plan-review-convergence/SKILL.md +63 -0
- package/pi/package-skills/gsd-pr-branch/SKILL.md +31 -0
- package/pi/package-skills/gsd-profile-user/SKILL.md +48 -0
- package/pi/package-skills/gsd-progress/SKILL.md +51 -0
- package/pi/package-skills/gsd-quick/SKILL.md +179 -0
- package/pi/package-skills/gsd-quick-batch/SKILL.md +114 -0
- package/pi/package-skills/gsd-resume-work/SKILL.md +31 -0
- package/pi/package-skills/gsd-review/SKILL.md +50 -0
- package/pi/package-skills/gsd-review-backlog/SKILL.md +65 -0
- package/pi/package-skills/gsd-secure-phase/SKILL.md +37 -0
- package/pi/package-skills/gsd-settings/SKILL.md +30 -0
- package/pi/package-skills/gsd-ship/SKILL.md +27 -0
- package/pi/package-skills/gsd-sketch/SKILL.md +56 -0
- package/pi/package-skills/gsd-spec-phase/SKILL.md +63 -0
- package/pi/package-skills/gsd-spike/SKILL.md +53 -0
- package/pi/package-skills/gsd-stats/SKILL.md +22 -0
- package/pi/package-skills/gsd-surface/SKILL.md +177 -0
- package/pi/package-skills/gsd-thread/SKILL.md +29 -0
- package/pi/package-skills/gsd-ui-phase/SKILL.md +35 -0
- package/pi/package-skills/gsd-ui-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-ultraplan-phase/SKILL.md +38 -0
- package/pi/package-skills/gsd-undo/SKILL.md +38 -0
- package/pi/package-skills/gsd-update/SKILL.md +54 -0
- package/pi/package-skills/gsd-validate-phase/SKILL.md +37 -0
- package/pi/package-skills/gsd-verify-work/SKILL.md +41 -0
- package/pi/package-skills/gsd-workspace/SKILL.md +57 -0
- package/pi/package-skills/gsd-workstreams/SKILL.md +73 -0
- package/scripts/build-hooks.js +4 -0
- package/scripts/ci-next-health.cjs +246 -23
- package/scripts/command-contract-helpers.cjs +1 -1
- package/scripts/docs-guard-registry.cjs +22 -7
- package/scripts/gen-features.cjs +14 -2
- package/scripts/gen-health-docs.cjs +13 -1
- package/scripts/gen-pi-package-skills.cjs +217 -0
- package/scripts/lib/drift-scan.cjs +27 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +17 -1
- package/scripts/lib/platform-conformance-tier.generated.cjs +37 -1
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +3 -3
- package/scripts/lint-phase-enumeration-drift.cjs +8 -4
- package/scripts/lint-retired-runtime-name.cjs +5 -0
- package/scripts/lint-roadmap-progress-drift.cjs +421 -0
- package/scripts/mutation-matrix.cjs +23 -1
- package/scripts/npm-audit-baseline.cjs +41 -7
- package/scripts/reviewed-or-maintainer-policy.cjs +181 -0
- package/scripts/select-docs-guards.cjs +1 -1
- package/scripts/self-test-report-policy.cjs +350 -0
- package/scripts/sync-next-version.cjs +38 -6
- package/skills/gsd-update/SKILL.md +5 -2
- package/vscode/package.json +1 -1
- package/scripts/diagnose-validate-commit-in-tier.cjs +0 -270
- package/scripts/diagnose-validate-commit-phases.cjs +0 -348
- package/scripts/xtrace-phase-timing.cjs +0 -205
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
*/
|
|
43
43
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
44
44
|
const healthDiagnosticMod = require("../health-diagnostic-types.cjs");
|
|
45
|
-
const { SEVERITY, adviseRemedy } = healthDiagnosticMod;
|
|
45
|
+
const { SEVERITY, REMEDY_ACTION, REMEDY_RISK, adviseRemedy } = healthDiagnosticMod;
|
|
46
46
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
47
47
|
const validateMod = require("../validate.cjs");
|
|
48
48
|
// #612: `isPhaseDirName` is the convention-SELECTED shape test wrapping
|
|
@@ -54,14 +54,20 @@ const validateMod = require("../validate.cjs");
|
|
|
54
54
|
const { isPhaseDirName } = validateMod;
|
|
55
55
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
56
56
|
const phaseIdMod = require("../phase-id.cjs");
|
|
57
|
-
const { extractPhaseToken, normalizePhaseName, comparePhaseNum } = phaseIdMod;
|
|
57
|
+
const { extractPhaseToken, normalizePhaseName, phaseKeyFromDir, comparePhaseNum } = phaseIdMod;
|
|
58
58
|
// #5060: the Phase Status Module owns the status-label ladder.
|
|
59
59
|
const phase_status_cjs_1 = require("../phase-status.cjs");
|
|
60
|
+
// #5291: W030 asks whether a raw report status has a known repair. The lookup is
|
|
61
|
+
// a pure read of a frozen table, so `check` stays free of ambient I/O (§8.1 rule 1).
|
|
62
|
+
const verification_cjs_1 = require("../verification.cjs");
|
|
60
63
|
// ─── W005 — phase directory doesn't follow NN-name format (verify.cts:1893-1902) ─
|
|
61
64
|
function checkW005(snapshot) {
|
|
62
65
|
const diagnostics = [];
|
|
66
|
+
const context = snapshot.directoryContext ?? phaseIdMod.phaseDirectoryContext(snapshot.config.value ?? {}, '', snapshot.roadmapDeclaredPhases.value.map(({ phaseId }) => phaseId));
|
|
63
67
|
for (const name of snapshot.phaseDirs.value) {
|
|
64
|
-
|
|
68
|
+
const custom = snapshot.phaseIdConvention === 'bracket' ? null : phaseIdMod.customPhaseQuery(name, context);
|
|
69
|
+
const owner = custom && phaseIdMod.customDirectoryOwner(name, custom);
|
|
70
|
+
if (!owner && !isPhaseDirName(name, snapshot.phaseIdConvention)) {
|
|
65
71
|
diagnostics.push({
|
|
66
72
|
code: 'W005',
|
|
67
73
|
severity: SEVERITY.WARNING,
|
|
@@ -74,17 +80,18 @@ function checkW005(snapshot) {
|
|
|
74
80
|
}
|
|
75
81
|
// ─── W023 — phase directories collide on normalized key (verify.cts:1904-1950) ─
|
|
76
82
|
//
|
|
77
|
-
// Groups
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
// `comparePhaseNum` + a `localeCompare` tiebreak, mirroring
|
|
83
|
+
// Groups directories by the canonical identity owner, preserving recorded
|
|
84
|
+
// custom IDs instead of collapsing their shared token prefixes. Sorted with
|
|
85
|
+
// contextual `comparePhaseNum` + a `localeCompare` tiebreak, mirroring
|
|
81
86
|
// `verify.cts:1930-1932`'s deterministic-output rationale. See the file-level
|
|
82
87
|
// comment for the disclosed "described" fidelity reduction.
|
|
83
88
|
function checkW023(snapshot) {
|
|
89
|
+
const context = snapshot.directoryContext;
|
|
84
90
|
const groups = new Map();
|
|
85
91
|
for (const name of snapshot.phaseDirs.value) {
|
|
86
|
-
const
|
|
87
|
-
|
|
92
|
+
const key = context?.phaseNaming === 'custom'
|
|
93
|
+
? phaseKeyFromDir(name, undefined, context)
|
|
94
|
+
: normalizePhaseName(extractPhaseToken(name));
|
|
88
95
|
const list = groups.get(key);
|
|
89
96
|
if (list)
|
|
90
97
|
list.push(name);
|
|
@@ -98,7 +105,7 @@ function checkW023(snapshot) {
|
|
|
98
105
|
continue;
|
|
99
106
|
const described = dirs
|
|
100
107
|
.slice()
|
|
101
|
-
.sort((a, b) => comparePhaseNum(a, b) || String(a).localeCompare(String(b)))
|
|
108
|
+
.sort((a, b) => comparePhaseNum(a, b, context) || String(a).localeCompare(String(b)))
|
|
102
109
|
.map((d) => {
|
|
103
110
|
const phase = phaseByDir.get(d);
|
|
104
111
|
const plans = phase ? phase.planCount : 0;
|
|
@@ -174,11 +181,21 @@ function checkW030(snapshot) {
|
|
|
174
181
|
const invalid = phase.verificationStatusError;
|
|
175
182
|
if (!invalid)
|
|
176
183
|
continue;
|
|
184
|
+
// #5291: a KNOWN legacy status is repairable (rewritten to its closed-set
|
|
185
|
+
// equivalent, original kept in `legacy_status`); any other value has no
|
|
186
|
+
// mapping and keeps the advise-only remedy — it stays refused.
|
|
187
|
+
const target = (0, verification_cjs_1.legacyStatusRepairTarget)(invalid.rawStatus);
|
|
177
188
|
diagnostics.push({
|
|
178
189
|
code: 'W030',
|
|
179
190
|
severity: SEVERITY.WARNING,
|
|
180
191
|
message: `Phase ${phase.dir}: ${invalid.message}`,
|
|
181
|
-
remedy:
|
|
192
|
+
remedy: target === null
|
|
193
|
+
? adviseRemedy('Set the report frontmatter `status` to one of passed | gaps_found | human_needed, or delete the report and re-run the phase verification')
|
|
194
|
+
: {
|
|
195
|
+
action: REMEDY_ACTION.REPAIR_VERIFICATION_STATUS,
|
|
196
|
+
risk: REMEDY_RISK.NONE,
|
|
197
|
+
args: { file: invalid.file, from: invalid.rawStatus, to: target },
|
|
198
|
+
},
|
|
182
199
|
});
|
|
183
200
|
}
|
|
184
201
|
return diagnostics;
|
|
@@ -217,7 +234,9 @@ const RULES = [
|
|
|
217
234
|
code: 'W030',
|
|
218
235
|
severity: SEVERITY.WARNING,
|
|
219
236
|
description: 'Phase verification report status is outside the closed set',
|
|
220
|
-
|
|
237
|
+
// #5291: repairable per finding — a KNOWN legacy status (`pass_with_caveats`)
|
|
238
|
+
// is rewritten by `--repair`; any other value stays advise-only.
|
|
239
|
+
repairable: true,
|
|
221
240
|
check: checkW030,
|
|
222
241
|
},
|
|
223
242
|
];
|
|
@@ -104,7 +104,7 @@ const planningScopeMod = require("../planning-scope.cjs");
|
|
|
104
104
|
const { SCOPE } = planningScopeMod;
|
|
105
105
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
106
106
|
const phaseIdMod = require("../phase-id.cjs");
|
|
107
|
-
const { matchPhaseDirs,
|
|
107
|
+
const { matchPhaseDirs, phaseLookupQuery, extractPhaseToken, isSentinelPhaseId, isSentinelPhaseDir } = phaseIdMod;
|
|
108
108
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
109
109
|
const validateMod = require("../validate.cjs");
|
|
110
110
|
const { phaseVariants } = validateMod;
|
|
@@ -116,7 +116,7 @@ const { phaseVariants } = validateMod;
|
|
|
116
116
|
* does the roadmap claim, for W007) call this — one matcher, reused, per the
|
|
117
117
|
* file-level comment.
|
|
118
118
|
*/
|
|
119
|
-
function dirsForPhase(dirs, phaseId, convention) {
|
|
119
|
+
function dirsForPhase(dirs, phaseId, convention, directoryContext) {
|
|
120
120
|
// #612: `convention` reaches BOTH operands of this pairing or it pairs
|
|
121
121
|
// nothing. The phases come from a bracket-aware heading scan and the dirs
|
|
122
122
|
// from a bracket-aware disk scan, so a convention-less selector here leaves
|
|
@@ -125,7 +125,7 @@ function dirsForPhase(dirs, phaseId, convention) {
|
|
|
125
125
|
// disk" AND every bracket directory reads as unclaimed. `matchPhaseDirs`
|
|
126
126
|
// forwards it to its primary `phaseTokenMatches`; handed nothing it is
|
|
127
127
|
// byte-identical, so no legacy repo's pairing changes.
|
|
128
|
-
const canonical = matchPhaseDirs(dirs,
|
|
128
|
+
const canonical = matchPhaseDirs(dirs, phaseLookupQuery(phaseId, directoryContext), convention, undefined, directoryContext).matches;
|
|
129
129
|
if (canonical.length > 0)
|
|
130
130
|
return canonical;
|
|
131
131
|
// Bug 2 (#3309 W006/W007 migration cluster, found while fixing the
|
|
@@ -187,6 +187,7 @@ function checkW006(snapshot) {
|
|
|
187
187
|
return [];
|
|
188
188
|
const dirs = snapshot.allPhaseDirNames.value;
|
|
189
189
|
const convention = snapshot.phaseIdConvention;
|
|
190
|
+
const directoryContext = snapshot.directoryContext ?? phaseIdMod.phaseDirectoryContext(snapshot.config.value ?? {}, '', snapshot.roadmapDeclaredPhases.value.map(({ phaseId }) => phaseId));
|
|
190
191
|
const archivedTokens = new Set(snapshot.archivedPhaseTokens.value);
|
|
191
192
|
// No separate scope guard: `roadmapSentinelPhaseTokens` and
|
|
192
193
|
// `roadmapDeclaredPhases` are produced by ONE builder call
|
|
@@ -219,7 +220,7 @@ function checkW006(snapshot) {
|
|
|
219
220
|
// not change its result.
|
|
220
221
|
if (sentinelTokens.has(phaseId) || isSentinelPhaseId(phaseId))
|
|
221
222
|
continue;
|
|
222
|
-
if (dirsForPhase(dirs, phaseId, convention).length > 0)
|
|
223
|
+
if (dirsForPhase(dirs, phaseId, convention, directoryContext).length > 0)
|
|
223
224
|
continue;
|
|
224
225
|
// Bug 1 (#3309 W006/W007 migration cluster): a phase whose ONLY
|
|
225
226
|
// directory lives under a milestone archive
|
|
@@ -247,10 +248,10 @@ function checkW006(snapshot) {
|
|
|
247
248
|
// ─── W007 — an on-disk phase directory has no matching ROADMAP entry ──────
|
|
248
249
|
// (verify.cts:2086-2101)
|
|
249
250
|
/** Every directory in `dirs` that ANY declared roadmap phase resolves to. */
|
|
250
|
-
function computeClaimedDirs(dirs, declaredPhases, convention) {
|
|
251
|
+
function computeClaimedDirs(dirs, declaredPhases, convention, directoryContext) {
|
|
251
252
|
const claimed = new Set();
|
|
252
253
|
for (const { phaseId } of declaredPhases) {
|
|
253
|
-
for (const dir of dirsForPhase(dirs, phaseId, convention))
|
|
254
|
+
for (const dir of dirsForPhase(dirs, phaseId, convention, directoryContext))
|
|
254
255
|
claimed.add(dir);
|
|
255
256
|
}
|
|
256
257
|
return claimed;
|
|
@@ -261,7 +262,8 @@ function checkW007(snapshot) {
|
|
|
261
262
|
return [];
|
|
262
263
|
const dirs = snapshot.allPhaseDirNames.value;
|
|
263
264
|
const convention = snapshot.phaseIdConvention;
|
|
264
|
-
const
|
|
265
|
+
const directoryContext = snapshot.directoryContext ?? phaseIdMod.phaseDirectoryContext(snapshot.config.value ?? {}, '', snapshot.roadmapDeclaredPhases.value.map(({ phaseId }) => phaseId));
|
|
266
|
+
const claimedDirs = computeClaimedDirs(dirs, snapshot.roadmapDeclaredPhases.value, convention, directoryContext);
|
|
265
267
|
const diagnostics = [];
|
|
266
268
|
for (const dirName of dirs) {
|
|
267
269
|
// `extractPhaseToken` is the phase-id.cts owner `PHASE_TOKEN_FROM_DIR_RE`
|
|
@@ -46,7 +46,7 @@ const healthDiagnosticMod = require("../health-diagnostic-types.cjs");
|
|
|
46
46
|
const { SEVERITY, adviseRemedy } = healthDiagnosticMod;
|
|
47
47
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
48
48
|
const phaseIdMod = require("../phase-id.cjs");
|
|
49
|
-
const { getMilestoneFromPhaseId, matchPhaseDirs,
|
|
49
|
+
const { getMilestoneFromPhaseId, matchPhaseDirs, phaseLookupQuery, extractPhaseToken, PHASE_NUMBER_TOKEN_SOURCE } = phaseIdMod;
|
|
50
50
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- the single owner of the persisted status vocabulary
|
|
51
51
|
const stateDocumentMod = require("../state-document.cjs");
|
|
52
52
|
const { normalizeStateStatus } = stateDocumentMod;
|
|
@@ -332,8 +332,8 @@ const RULE_W026 = {
|
|
|
332
332
|
// field's own doc comment on `PlanningSnapshot` for why
|
|
333
333
|
// `roadmapDeclaredPhases`'s `milestone` attribution is the wrong fit).
|
|
334
334
|
const unstarted = [];
|
|
335
|
+
const directoryContext = snapshot.directoryContext ?? phaseIdMod.phaseDirectoryContext(snapshot.config.value ?? {}, '', snapshot.currentMilestoneRoadmapPhaseIds.value);
|
|
335
336
|
for (const phaseId of snapshot.currentMilestoneRoadmapPhaseIds.value) {
|
|
336
|
-
const normalized = normalizePhaseName(phaseId);
|
|
337
337
|
// `allPhaseDirNames` — every directory under `phases/`, UNWINDOWED by
|
|
338
338
|
// ROADMAP-declaration membership — mirrors the original's own
|
|
339
339
|
// unwindowed `phaseDirNames2` (`verify.cts:2372-2382`, a direct
|
|
@@ -346,7 +346,7 @@ const RULE_W026 = {
|
|
|
346
346
|
// moved the read onto the shared selector; the convention rides along,
|
|
347
347
|
// since the selector's primary match IS the `phaseTokenMatches` call this
|
|
348
348
|
// line used to make directly.
|
|
349
|
-
const hasDirectory = matchPhaseDirs(snapshot.allPhaseDirNames.value,
|
|
349
|
+
const hasDirectory = matchPhaseDirs(snapshot.allPhaseDirNames.value, phaseLookupQuery(phaseId, directoryContext), snapshot.phaseIdConvention, undefined, directoryContext).matches.length > 0;
|
|
350
350
|
if (!hasDirectory)
|
|
351
351
|
unstarted.push(phaseId);
|
|
352
352
|
}
|
|
@@ -38,6 +38,10 @@ const REMEDY_ACTION = Object.freeze({
|
|
|
38
38
|
ADD_NYQUIST_KEY: 'addNyquistKey',
|
|
39
39
|
ADD_AI_INTEGRATION_PHASE_KEY: 'addAiIntegrationPhaseKey',
|
|
40
40
|
BACKFILL_MILESTONES: 'backfillMilestones',
|
|
41
|
+
// #5291: rewrite a KNOWN legacy verification `status` (W030) to its closed-set
|
|
42
|
+
// equivalent, keeping the original in `legacy_status`. Per-finding: only
|
|
43
|
+
// emitted when the raw value has a mapping; every other W030 stays ADVISE.
|
|
44
|
+
REPAIR_VERIFICATION_STATUS: 'repairVerificationStatus',
|
|
41
45
|
// §8.3 rule 5 — every non-repairable finding's `fix` string becomes an
|
|
42
46
|
// ADVISE payload; ADVISE never acts, only describes.
|
|
43
47
|
ADVISE: 'advise',
|
|
@@ -118,6 +118,9 @@ const { getMilestoneInfo } = roadmapParserMod;
|
|
|
118
118
|
const stateMod = require("./state.cjs");
|
|
119
119
|
const { writeStateMd, assertVerificationReportsReadable } = stateMod;
|
|
120
120
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
121
|
+
const verificationMod = require("./verification.cjs");
|
|
122
|
+
const { repairLegacyVerificationStatus } = verificationMod;
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
121
124
|
const frontmatter = require("./frontmatter.cjs");
|
|
122
125
|
const { extractFrontmatter } = frontmatter;
|
|
123
126
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -252,9 +255,27 @@ function computeMissingMilestoneVersions(milestonesArchiveDir, milestonesPath) {
|
|
|
252
255
|
* shape, collapsed to one seam here since every case now shares one
|
|
253
256
|
* caller).
|
|
254
257
|
*/
|
|
255
|
-
function runRepairAction(cwd, action, paths) {
|
|
258
|
+
function runRepairAction(cwd, action, paths, args = {}) {
|
|
256
259
|
const { rootBase, configPath, statePath, milestonesPath, milestonesArchiveDir } = paths;
|
|
257
260
|
switch (action) {
|
|
261
|
+
case REMEDY_ACTION.REPAIR_VERIFICATION_STATUS: {
|
|
262
|
+
// #5291: the report path comes from the finding's own remedy args, not
|
|
263
|
+
// from user input; `repairLegacyVerificationStatus` re-verifies that it is
|
|
264
|
+
// a report contained in its phase directory before it writes a byte.
|
|
265
|
+
const file = typeof args['file'] === 'string' ? args['file'] : '';
|
|
266
|
+
if (file === '')
|
|
267
|
+
return { success: false, error: 'no report path on the finding' };
|
|
268
|
+
const repaired = repairLegacyVerificationStatus(file);
|
|
269
|
+
if (!repaired.ok)
|
|
270
|
+
return { success: false, error: repaired.reason };
|
|
271
|
+
return {
|
|
272
|
+
success: true,
|
|
273
|
+
path: node_path_1.default.relative(cwd, file).split(node_path_1.default.sep).join('/'),
|
|
274
|
+
detail: repaired.legacyStatusKept
|
|
275
|
+
? `status ${repaired.from} -> ${repaired.to}; the report's existing legacy_status was left as it was`
|
|
276
|
+
: `status ${repaired.from} -> ${repaired.to}; original kept as legacy_status`,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
258
279
|
case REMEDY_ACTION.CREATE_CONFIG:
|
|
259
280
|
case REMEDY_ACTION.RESET_CONFIG: {
|
|
260
281
|
(0, shell_command_projection_cjs_1.platformWriteSync)(configPath, JSON.stringify(defaultConfigPayload(), null, 2));
|
|
@@ -390,6 +411,34 @@ function applyRepairs(cwd, diagnostics, repair, backfill) {
|
|
|
390
411
|
const refused = [];
|
|
391
412
|
const details = [];
|
|
392
413
|
const paths = repairPaths(cwd);
|
|
414
|
+
// #5291: a legacy-status repair is the CURE for the refusal the pre-check
|
|
415
|
+
// below enforces, so it runs first (a report edit is its only write and it
|
|
416
|
+
// validates its own target); the pre-check then sees the repaired reports.
|
|
417
|
+
const statusRepairs = new Set();
|
|
418
|
+
if (repair) {
|
|
419
|
+
for (const diagnostic of diagnostics) {
|
|
420
|
+
const { remedy, code } = diagnostic;
|
|
421
|
+
if (remedy.action !== REMEDY_ACTION.REPAIR_VERIFICATION_STATUS || remedy.risk === REMEDY_RISK.DESTRUCTIVE)
|
|
422
|
+
continue;
|
|
423
|
+
statusRepairs.add(diagnostic);
|
|
424
|
+
try {
|
|
425
|
+
const outcome = runRepairAction(cwd, remedy.action, paths, remedy.args);
|
|
426
|
+
details.push({
|
|
427
|
+
code,
|
|
428
|
+
action: remedy.action,
|
|
429
|
+
success: outcome.success,
|
|
430
|
+
...(outcome.path ? { path: outcome.path } : {}),
|
|
431
|
+
...(outcome.detail ? { detail: outcome.detail } : {}),
|
|
432
|
+
...(outcome.error ? { error: outcome.error } : {}),
|
|
433
|
+
});
|
|
434
|
+
if (outcome.success)
|
|
435
|
+
applied.push(code);
|
|
436
|
+
}
|
|
437
|
+
catch (err) {
|
|
438
|
+
details.push({ code, action: remedy.action, success: false, error: err instanceof Error ? err.message : String(err) });
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
393
442
|
// #5118 (no write before the error): a requested REGENERATE_STATE rewrites
|
|
394
443
|
// STATE.md from every phase's report and throws on one whose `status` is
|
|
395
444
|
// outside the closed set — but other repairs in the SAME run (config,
|
|
@@ -411,6 +460,8 @@ function applyRepairs(cwd, diagnostics, repair, backfill) {
|
|
|
411
460
|
const { remedy, code } = diagnostic;
|
|
412
461
|
if (remedy.action === REMEDY_ACTION.ADVISE)
|
|
413
462
|
continue;
|
|
463
|
+
if (statusRepairs.has(diagnostic))
|
|
464
|
+
continue;
|
|
414
465
|
const requested = remedy.action === REMEDY_ACTION.BACKFILL_MILESTONES ? repair || backfill : repair;
|
|
415
466
|
if (!requested)
|
|
416
467
|
continue;
|
|
@@ -620,7 +620,7 @@ function hookEventSurfaceFor(hookEvents) {
|
|
|
620
620
|
// event subset (imperative hosts' extension API). They are not the same thing.
|
|
621
621
|
//
|
|
622
622
|
// Values are documentation-sourced (ADR-1239 §research): OpenCode ~25 plugin
|
|
623
|
-
// events (session/tool/file/permission); pi
|
|
623
|
+
// events (session/tool/file/permission); pi 41 fine-grained extension events (pi 1.3.0);
|
|
624
624
|
// 'none' = the host exposes no extension surface and the engine owns the bus
|
|
625
625
|
// (VS Code). Declarative hosts (no plugin API) do not set `extensionEvents`.
|
|
626
626
|
// OpenCode's plugin event surface (ADR-1239 §research; ~25 documented events,
|
|
@@ -655,11 +655,13 @@ const EXTENSION_EVENT_SURFACES = Object.freeze({
|
|
|
655
655
|
'pre_gateway_dispatch', 'pre_approval_request',
|
|
656
656
|
'transform_tool_result',
|
|
657
657
|
]),
|
|
658
|
-
//
|
|
659
|
-
//
|
|
660
|
-
//
|
|
661
|
-
//
|
|
662
|
-
//
|
|
658
|
+
// pi's real ExtensionAPI event vocabulary: the 41 `on(event: "...")` overloads
|
|
659
|
+
// declared by pi 1.3.0 (@earendil-works/pi-coding-agent
|
|
660
|
+
// dist/core/extensions/types.d.ts, sourceCommit 71023aec15, #5557). #2102
|
|
661
|
+
// Stage 2 declared the first 30 from pi.dev prose; the last 11 on the final
|
|
662
|
+
// row group were added when the host's own declarations were read. The
|
|
663
|
+
// pi.dev extensions page lists a lossy subset (it omits session_before_compact,
|
|
664
|
+
// which pi/gsd.cjs binds), so the type declarations are the source of truth.
|
|
663
665
|
pi: Object.freeze([
|
|
664
666
|
'session_start', 'project_trust', 'resources_discover', 'input',
|
|
665
667
|
'before_agent_start', 'agent_start', 'message_start', 'message_update',
|
|
@@ -669,6 +671,11 @@ const EXTENSION_EVENT_SURFACES = Object.freeze({
|
|
|
669
671
|
'session_before_switch', 'session_shutdown', 'session_before_fork',
|
|
670
672
|
'session_info_changed', 'session_before_compact', 'session_compact',
|
|
671
673
|
'session_before_tree', 'session_tree', 'thinking_level_select', 'model_select',
|
|
674
|
+
// Added in pi 1.3.0 (#5557):
|
|
675
|
+
'agent_before_settle', 'agent_settled', 'before_provider_headers',
|
|
676
|
+
'cache_warming_decision', 'context_with_system', 'mcp_servers_change',
|
|
677
|
+
'provider_stream_event', 'session_compact_failed', 'ui_prompt_end',
|
|
678
|
+
'ui_prompt_start', 'user_bash',
|
|
672
679
|
]),
|
|
673
680
|
none: Object.freeze([]),
|
|
674
681
|
});
|