@opengsd/gsd-core 1.17.0 → 1.19.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-advisor-researcher.compact.md +1 -1
- package/agents/gsd-advisor-researcher.md +1 -1
- package/agents/gsd-assumptions-analyzer.compact.md +1 -1
- package/agents/gsd-assumptions-analyzer.md +1 -1
- package/agents/gsd-code-fixer.compact.md +3 -3
- package/agents/gsd-code-fixer.md +5 -4
- package/agents/gsd-code-reviewer.compact.md +1 -1
- package/agents/gsd-code-reviewer.md +1 -1
- package/agents/gsd-codebase-mapper.compact.md +1 -1
- package/agents/gsd-codebase-mapper.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-doc-verifier.compact.md +4 -4
- package/agents/gsd-doc-verifier.md +4 -3
- package/agents/gsd-doc-writer.compact.md +23 -5
- package/agents/gsd-doc-writer.md +19 -6
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +7 -3
- package/agents/gsd-integration-checker.compact.md +1 -1
- package/agents/gsd-integration-checker.md +1 -1
- package/agents/gsd-nyquist-auditor.compact.md +1 -1
- package/agents/gsd-nyquist-auditor.md +1 -1
- package/agents/gsd-phase-researcher.md +1 -1
- package/agents/gsd-plan-checker.md +2 -1
- package/agents/gsd-planner.md +5 -4
- package/agents/gsd-project-researcher.compact.md +1 -1
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +5 -5
- package/agents/gsd-research-synthesizer.md +5 -5
- package/agents/gsd-roadmapper.compact.md +1 -1
- package/agents/gsd-roadmapper.md +1 -1
- package/agents/gsd-security-auditor.compact.md +1 -1
- package/agents/gsd-security-auditor.md +1 -1
- package/agents/gsd-ui-auditor.compact.md +1 -1
- package/agents/gsd-ui-auditor.md +1 -1
- package/agents/gsd-ui-checker.compact.md +1 -1
- package/agents/gsd-ui-checker.md +1 -1
- package/agents/gsd-ui-researcher.compact.md +13 -1
- package/agents/gsd-ui-researcher.md +28 -1
- package/agents/gsd-verifier.md +2 -2
- package/bin/install.js +460 -105
- package/commands/gsd/code-review.md +8 -0
- package/commands/gsd/pause-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +124 -18
- 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-ledger.cjs +25 -0
- package/gsd-core/bin/lib/capability-lock.cjs +41 -8
- package/gsd-core/bin/lib/capability-registry.cjs +162 -74
- package/gsd-core/bin/lib/capability-source.cjs +3 -1
- package/gsd-core/bin/lib/capability-state.cjs +20 -11
- package/gsd-core/bin/lib/capability-validator.cjs +23 -4
- package/gsd-core/bin/lib/commands.cjs +5 -1
- 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 +34 -0
- package/gsd-core/bin/lib/decision-coverage-support.cjs +93 -0
- package/gsd-core/bin/lib/gate-context-drift.cjs +8 -3
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +21 -1
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +19 -1
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +134 -13
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +23 -3
- package/gsd-core/bin/lib/gate-predicate.cjs +8 -12
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +114 -18
- package/gsd-core/bin/lib/gate-ui-safety.cjs +23 -5
- package/gsd-core/bin/lib/git-info-exclude.cjs +57 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +18 -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 +76 -5
- package/gsd-core/bin/lib/install-effort-resolver.cjs +2 -2
- package/gsd-core/bin/lib/install-engine.cjs +246 -32
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +4 -3
- package/gsd-core/bin/lib/install-profiles.cjs +14 -7
- package/gsd-core/bin/lib/installer-migration-report.cjs +2 -0
- package/gsd-core/bin/lib/markdown-line-diff.cjs +147 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +113 -0
- 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 +43 -1
- 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-id.cjs +21 -4
- package/gsd-core/bin/lib/phase-lifecycle.cjs +37 -4
- package/gsd-core/bin/lib/phase.cjs +235 -37
- package/gsd-core/bin/lib/planning-snapshot.cjs +3 -1
- package/gsd-core/bin/lib/planning-workspace.cjs +18 -0
- package/gsd-core/bin/lib/pristine-baseline.cjs +11 -3
- package/gsd-core/bin/lib/read-only-git-env.cjs +58 -0
- package/gsd-core/bin/lib/report-parser.cjs +57 -1
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +35 -2
- package/gsd-core/bin/lib/review-lane-invocation.cjs +40 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +33 -4
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +20 -1
- package/gsd-core/bin/lib/roadmap-parser.cjs +12 -0
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +39 -2
- package/gsd-core/bin/lib/roadmap.cjs +89 -30
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +428 -16
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +8 -4
- package/gsd-core/bin/lib/runtime-homes.cjs +18 -0
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +60 -16
- package/gsd-core/bin/lib/shell-command-projection.cjs +123 -16
- package/gsd-core/bin/lib/smart-entry.cjs +37 -16
- package/gsd-core/bin/lib/state-contract.cjs +29 -9
- package/gsd-core/bin/lib/state-document.cjs +47 -5
- package/gsd-core/bin/lib/state-transition.cjs +150 -34
- package/gsd-core/bin/lib/state.cjs +140 -88
- package/gsd-core/bin/lib/surface.cjs +9 -0
- package/gsd-core/bin/lib/task-command-router.cjs +7 -28
- package/gsd-core/bin/lib/task-content-resolution.cjs +46 -1
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +5 -0
- package/gsd-core/bin/lib/tdd-test-files.cjs +42 -0
- package/gsd-core/bin/lib/verification.cjs +96 -9
- package/gsd-core/bin/lib/verify.cjs +38 -1
- 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/references/agent-contracts.md +1 -1
- package/gsd-core/references/agent-skills-bootstrap.md +26 -7
- package/gsd-core/references/git-integration.md +14 -3
- package/gsd-core/references/loop-hook-dispatch.md +13 -6
- package/gsd-core/references/planner-reversibility.md +18 -4
- package/gsd-core/references/planner-verify-command-grounding.md +18 -0
- package/gsd-core/references/planning-config.md +2 -0
- package/gsd-core/references/tdd.md +5 -4
- package/gsd-core/references/verifier-phase-gates.md +8 -1
- 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/add-backlog.md +10 -2
- package/gsd-core/workflows/add-phase.md +5 -1
- package/gsd-core/workflows/add-tests.md +5 -1
- package/gsd-core/workflows/add-todo.md +5 -1
- package/gsd-core/workflows/ai-integration-phase.md +5 -1
- package/gsd-core/workflows/audit-fix.md +2 -1
- package/gsd-core/workflows/audit-milestone.md +21 -9
- package/gsd-core/workflows/autonomous/templates/minimal-context.md +41 -0
- package/gsd-core/workflows/autonomous.md +52 -64
- package/gsd-core/workflows/check-todos.md +5 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +10 -1
- package/gsd-core/workflows/code-review-fix.md +5 -1
- package/gsd-core/workflows/code-review.md +66 -8
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +5 -1
- 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 +64 -157
- package/gsd-core/workflows/debug.md +5 -1
- package/gsd-core/workflows/diagnose-issues.md +34 -6
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -1
- package/gsd-core/workflows/discuss-phase/modes/power.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +44 -5
- package/gsd-core/workflows/discuss-phase-power.md +19 -2
- package/gsd-core/workflows/discuss-phase.md +11 -11
- package/gsd-core/workflows/docs-update/detail/elaboration.md +7 -6
- package/gsd-core/workflows/docs-update.md +27 -5
- package/gsd-core/workflows/edit-phase.md +5 -1
- package/gsd-core/workflows/eval-review.md +11 -3
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +5 -1
- 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 +19 -8
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +21 -3
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +18 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +7 -3
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +11 -2
- package/gsd-core/workflows/execute-phase.md +46 -11
- package/gsd-core/workflows/execute-plan.md +8 -4
- package/gsd-core/workflows/extract-learnings.md +6 -2
- package/gsd-core/workflows/forensics.md +5 -1
- package/gsd-core/workflows/health.md +2 -1
- package/gsd-core/workflows/import.md +6 -2
- package/gsd-core/workflows/insert-phase.md +5 -1
- package/gsd-core/workflows/manager.md +10 -2
- package/gsd-core/workflows/map-codebase.md +5 -1
- package/gsd-core/workflows/milestone-summary.md +10 -2
- package/gsd-core/workflows/new-milestone.md +13 -5
- package/gsd-core/workflows/new-project.md +9 -5
- package/gsd-core/workflows/next.md +8 -4
- package/gsd-core/workflows/pause-work.md +3 -3
- package/gsd-core/workflows/plan-phase/steps/auto-advance-check.md +70 -0
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +7 -3
- package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +6 -2
- package/gsd-core/workflows/plan-phase.md +54 -86
- package/gsd-core/workflows/plan-review-convergence.md +17 -5
- package/gsd-core/workflows/plant-seed.md +8 -4
- package/gsd-core/workflows/progress.md +6 -2
- 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-batch.md +5 -1
- package/gsd-core/workflows/quick.md +23 -8
- package/gsd-core/workflows/remove-phase.md +5 -1
- package/gsd-core/workflows/resume-project.md +5 -1
- package/gsd-core/workflows/review.md +22 -15
- package/gsd-core/workflows/scan.md +5 -1
- package/gsd-core/workflows/section-manifest.json +5 -0
- package/gsd-core/workflows/secure-phase.md +6 -2
- package/gsd-core/workflows/settings.md +4 -3
- package/gsd-core/workflows/ship.md +16 -14
- package/gsd-core/workflows/spec-phase.md +3 -6
- package/gsd-core/workflows/thread.md +10 -2
- package/gsd-core/workflows/transition.md +5 -1
- package/gsd-core/workflows/ui-phase.md +5 -1
- package/gsd-core/workflows/ui-review.md +6 -2
- package/gsd-core/workflows/ultraplan-phase.md +5 -1
- package/gsd-core/workflows/update.md +5 -1
- package/gsd-core/workflows/validate-phase.md +6 -2
- package/gsd-core/workflows/verify-work/detail/elaboration.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -1
- package/gsd-core/workflows/verify-work.md +15 -6
- package/hooks/dist/gsd-agent-isolation-guard.js +14 -2
- package/hooks/dist/gsd-cursor-subagent-start.js +8 -3
- package/hooks/dist/gsd-path-export.js +95 -0
- package/hooks/dist/gsd-secret-read-guard.js +244 -53
- package/hooks/dist/gsd-statusline.js +35 -2
- package/hooks/dist/gsd-validate-commit.sh +27 -5
- package/hooks/dist/gsd-windsurf-pre-write.js +28 -1
- package/hooks/dist/gsd-workflow-guard.js +1 -1
- package/hooks/dist/gsd-worktree-path-guard.js +28 -1
- 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 +14 -2
- package/hooks/gsd-cursor-subagent-start.js +8 -3
- package/hooks/gsd-path-export.js +95 -0
- package/hooks/gsd-secret-read-guard.js +244 -53
- package/hooks/gsd-statusline.js +35 -2
- package/hooks/gsd-validate-commit.sh +27 -5
- package/hooks/gsd-windsurf-pre-write.js +28 -1
- package/hooks/gsd-workflow-guard.js +1 -1
- package/hooks/gsd-worktree-path-guard.js +28 -1
- package/hooks/hooks.json +1 -0
- package/hooks/lib/isolation-sentinel.js +44 -0
- package/hooks/managed-hooks-registry.cjs +1 -0
- package/package.json +13 -6
- 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 +769 -0
- package/pi/package-agents/gsd-code-reviewer.md +402 -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 +894 -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 +51 -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/audit-workflow-script-paths.cjs +1 -1
- package/scripts/build-hooks.js +4 -0
- package/scripts/command-contract-helpers.cjs +1 -1
- package/scripts/diagnose-windows-spawn-watcher.cjs +317 -0
- package/scripts/docs-guard-registry.cjs +22 -7
- package/scripts/gen-health-docs.cjs +13 -1
- package/scripts/gen-pi-package-skills.cjs +217 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +19 -0
- package/scripts/lib/platform-conformance-tier.generated.cjs +41 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +3 -3
- package/scripts/lint-phase-arg-assignment.cjs +2 -2
- package/scripts/lint-retired-runtime-name.cjs +5 -0
- package/scripts/lint-workflow-shellcheck-baseline.json +16 -16
- package/scripts/npm-audit-baseline.cjs +41 -7
- package/scripts/release-tarball-smoke.cjs +1 -0
- 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/skills/gsd-code-review/SKILL.md +8 -0
- package/skills/gsd-pause-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
|
@@ -30,6 +30,7 @@ exports.applyPreserveWhenUnchanged = applyPreserveWhenUnchanged;
|
|
|
30
30
|
exports.applyStatePreservation = applyStatePreservation;
|
|
31
31
|
exports.transitionCore = transitionCore;
|
|
32
32
|
exports.sliceCurrentPositionSection = sliceCurrentPositionSection;
|
|
33
|
+
exports.isStatePastPhase = isStatePastPhase;
|
|
33
34
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
34
35
|
const frontmatter = require("./frontmatter.cjs");
|
|
35
36
|
const state_document_cjs_1 = require("./state-document.cjs");
|
|
@@ -37,6 +38,9 @@ const state_document_cjs_2 = require("./state-document.cjs");
|
|
|
37
38
|
const markdown_sectionizer_cjs_1 = require("./markdown-sectionizer.cjs");
|
|
38
39
|
const phase_lifecycle_cjs_1 = require("./phase-lifecycle.cjs");
|
|
39
40
|
const pattern_cjs_1 = require("./pattern.cjs");
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- phase-id.cjs is an export= CommonJS module
|
|
42
|
+
const phaseIdMod = require("./phase-id.cjs");
|
|
43
|
+
const { comparePhaseNum } = phaseIdMod;
|
|
40
44
|
// #4129: the completion-ratio kernel for the resync-arm ratchet's percent
|
|
41
45
|
// (planning-scope's SCOPE — state-document's own dependency, no cycle here:
|
|
42
46
|
// state-document never imports this module).
|
|
@@ -643,18 +647,24 @@ function mergeResyncProgressRatchet(curatedRecord, derivedRecord) {
|
|
|
643
647
|
merged[key] = value;
|
|
644
648
|
}
|
|
645
649
|
}
|
|
646
|
-
|
|
647
|
-
const recomputed = (0, state_document_cjs_2.computeProgressPercent)((0, state_document_cjs_2.toFiniteNumber)(merged.completed_plans), (0, state_document_cjs_2.toFiniteNumber)(merged.total_plans), (0, state_document_cjs_2.toFiniteNumber)(merged.completed_phases), (0, state_document_cjs_2.toFiniteNumber)(merged.total_phases), planningScopeMod.SCOPE.COMPLETE);
|
|
648
|
-
// Same verbatim rule for percent: assign only when the recomputed value
|
|
649
|
-
// numerically differs, so a string-spelled derived percent ("67") is not
|
|
650
|
-
// churned into a number-spelled 67 (phantom-divergence noise, not a
|
|
651
|
-
// change).
|
|
652
|
-
if (recomputed !== null && recomputed !== (0, state_document_cjs_2.toFiniteNumber)(merged.percent)) {
|
|
653
|
-
merged.percent = recomputed;
|
|
654
|
-
}
|
|
655
|
-
}
|
|
650
|
+
recomputeMergedProgressPercent(merged, derivedRecord);
|
|
656
651
|
return merged;
|
|
657
652
|
}
|
|
653
|
+
/**
|
|
654
|
+
* Make `merged.percent` the progress computation over the counters `merged` actually carries (#5619,
|
|
655
|
+
* #4129). Only when the derived side measured a percent: a derivation that withheld one (an incomplete
|
|
656
|
+
* scope, #1761/#3217) stays withheld, never invented. Same verbatim rule as the counters: assign only
|
|
657
|
+
* when the recomputed value numerically differs, so a string-spelled derived percent ("67") is not
|
|
658
|
+
* churned into a number-spelled 67 (phantom-divergence noise, not a change).
|
|
659
|
+
*/
|
|
660
|
+
function recomputeMergedProgressPercent(merged, derivedRecord) {
|
|
661
|
+
if ((0, state_document_cjs_2.toFiniteNumber)(derivedRecord.percent) === null)
|
|
662
|
+
return;
|
|
663
|
+
const recomputed = (0, state_document_cjs_2.computeProgressPercent)((0, state_document_cjs_2.toFiniteNumber)(merged.completed_plans), (0, state_document_cjs_2.toFiniteNumber)(merged.total_plans), (0, state_document_cjs_2.toFiniteNumber)(merged.completed_phases), (0, state_document_cjs_2.toFiniteNumber)(merged.total_phases), planningScopeMod.SCOPE.COMPLETE);
|
|
664
|
+
if (recomputed !== null && recomputed !== (0, state_document_cjs_2.toFiniteNumber)(merged.percent)) {
|
|
665
|
+
merged.percent = recomputed;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
658
668
|
/**
|
|
659
669
|
* Executor for `preservation: 'preserve-always'` (ADR-3408 §8.1). Only
|
|
660
670
|
* `progress` carries this policy today. Preserves #3242/#1446/#2440/#2969
|
|
@@ -719,18 +729,23 @@ function applyPreserveAlways(field, cls, ctx) {
|
|
|
719
729
|
// completed after the plan count grew) — ratcheting UP only, never
|
|
720
730
|
// deriving downward (preserves the #3242 curated-progress protection
|
|
721
731
|
// for cases unrelated to plan-count growth, e.g. a deleted SUMMARY).
|
|
722
|
-
// percent
|
|
723
|
-
// disk
|
|
724
|
-
//
|
|
732
|
+
// percent is recomputed over the counters actually written (#5619): the
|
|
733
|
+
// disk-derived percent is only coherent with the DERIVED counters, and a
|
|
734
|
+
// stale curated percent would be incoherent against the ratcheted-up
|
|
735
|
+
// completed counts (e.g. 54/54 at 93%).
|
|
725
736
|
const ratchetUpKeys = new Set(['completed_plans', 'completed_phases']);
|
|
726
737
|
for (const [key, value] of Object.entries(curatedRecord)) {
|
|
727
738
|
if (key === 'total_plans' || key === 'total_phases' || key === 'percent')
|
|
728
739
|
continue;
|
|
729
740
|
if (ratchetUpKeys.has(key)) {
|
|
730
|
-
|
|
731
|
-
|
|
741
|
+
// Frontmatter scalars arrive as STRINGS ("2", not 2): coerce through
|
|
742
|
+
// `toFiniteNumber`, never a `typeof === 'number'` test (#5619 — that
|
|
743
|
+
// test made both sides -Infinity and the ratchet unreachable).
|
|
744
|
+
const derivedNum = (0, state_document_cjs_2.toFiniteNumber)(derivedRecord[key]) ?? -Infinity;
|
|
745
|
+
const curatedNum = (0, state_document_cjs_2.toFiniteNumber)(value) ?? -Infinity;
|
|
732
746
|
// Take the derived value only when it ratchets up (strictly
|
|
733
|
-
// greater — #2969's `>` not `>=`); else keep curated
|
|
747
|
+
// greater — #2969's `>` not `>=`); else keep curated, with its
|
|
748
|
+
// spelling, on a tie too.
|
|
734
749
|
if (derivedNum > curatedNum)
|
|
735
750
|
continue;
|
|
736
751
|
merged[key] = value;
|
|
@@ -740,6 +755,7 @@ function applyPreserveAlways(field, cls, ctx) {
|
|
|
740
755
|
}
|
|
741
756
|
}
|
|
742
757
|
}
|
|
758
|
+
recomputeMergedProgressPercent(merged, derivedRecord);
|
|
743
759
|
next = merged;
|
|
744
760
|
}
|
|
745
761
|
else {
|
|
@@ -876,7 +892,36 @@ exports.STATE_MD_SECTIONS = {
|
|
|
876
892
|
* Phases 2–7 add cases for the remaining 9 intent kinds. A missing case is
|
|
877
893
|
* a compile-time error (the function would not return on that path).
|
|
878
894
|
*/
|
|
895
|
+
/**
|
|
896
|
+
* The transitions that rewrite single-line body fields (`Status:`, `Current focus:`, `Plan:` …) with
|
|
897
|
+
* plain line-anchored patterns. Those patterns match a fenced EXAMPLE of a field as readily as the
|
|
898
|
+
* live line (#5460), so these run over the document body with fenced blocks hidden.
|
|
899
|
+
* `milestone*`, `prune` and `rebuild` restructure sections or re-derive the document and are not
|
|
900
|
+
* field-by-field writers.
|
|
901
|
+
*/
|
|
902
|
+
const FENCE_MASKED_TRANSITIONS = new Set([
|
|
903
|
+
'beginPhase', 'advancePlan', 'completePhase', 'plannedPhase', 'patch', 'update', 'sync',
|
|
904
|
+
]);
|
|
879
905
|
function transitionCore(content, intent, deps) {
|
|
906
|
+
if (!FENCE_MASKED_TRANSITIONS.has(intent.kind))
|
|
907
|
+
return transitionCoreUnmasked(content, intent, deps);
|
|
908
|
+
// Only the body is masked: a fence opener inside a frontmatter block scalar must not swallow the
|
|
909
|
+
// closing `---` (the frontmatter is not where the live fields are written).
|
|
910
|
+
const body = stripFrontmatter(content);
|
|
911
|
+
if (!content.endsWith(body))
|
|
912
|
+
return transitionCoreUnmasked(content, intent, deps);
|
|
913
|
+
const prefix = content.slice(0, content.length - body.length);
|
|
914
|
+
const fenceMask = (0, markdown_sectionizer_cjs_1.maskFences)(body);
|
|
915
|
+
const result = transitionCoreUnmasked(prefix + fenceMask.masked, intent, deps);
|
|
916
|
+
const restored = fenceMask.restore(result.content);
|
|
917
|
+
// Cannot happen short of a writer bug (a transition dropped or duplicated a placeholder line); a
|
|
918
|
+
// refusal is the one outcome that cannot report a rewrite that did not land.
|
|
919
|
+
if (restored === null) {
|
|
920
|
+
throw new Error(`${intent.kind}: fenced code blocks could not be restored after the edit; refusing to write STATE.md`);
|
|
921
|
+
}
|
|
922
|
+
return { ...result, content: restored };
|
|
923
|
+
}
|
|
924
|
+
function transitionCoreUnmasked(content, intent, deps) {
|
|
880
925
|
switch (intent.kind) {
|
|
881
926
|
case 'beginPhase':
|
|
882
927
|
return beginPhaseCore(content, intent, deps);
|
|
@@ -922,6 +967,8 @@ function transitionCore(content, intent, deps) {
|
|
|
922
967
|
*/
|
|
923
968
|
function beginPhaseCore(content, intent, deps) {
|
|
924
969
|
const updated = [];
|
|
970
|
+
// #4945: a re-entry whose earlier plans already have summaries starts at the first plan still to run.
|
|
971
|
+
const startPlan = intent.startPlan && intent.startPlan > 0 ? Math.floor(intent.startPlan) : 1;
|
|
925
972
|
// #1255: body-field replacements operate on body only (frontmatter stripped),
|
|
926
973
|
// not on the full content. The YAML `status:` key matches `^Status:\s*`
|
|
927
974
|
// before the body pipe-table row if full content is passed.
|
|
@@ -977,7 +1024,7 @@ function beginPhaseCore(content, intent, deps) {
|
|
|
977
1024
|
if (intent.phaseName) {
|
|
978
1025
|
tryField('Current Phase Name', intent.phaseName);
|
|
979
1026
|
}
|
|
980
|
-
tryField('Current Plan',
|
|
1027
|
+
tryField('Current Plan', String(startPlan));
|
|
981
1028
|
if (intent.planCount) {
|
|
982
1029
|
tryField('Total Plans in Phase', String(intent.planCount));
|
|
983
1030
|
}
|
|
@@ -996,14 +1043,21 @@ function beginPhaseCore(content, intent, deps) {
|
|
|
996
1043
|
// end-of-line (inert here since `.` never crosses line terminators
|
|
997
1044
|
// without `/s`, which is not set).
|
|
998
1045
|
const focusPattern = /^([ \t]*\*\*Current focus:\*\*[ \t]*)(.*)$/im;
|
|
999
|
-
|
|
1000
|
-
|
|
1046
|
+
const focusMatch = focusPattern.exec(body);
|
|
1047
|
+
if (focusMatch) {
|
|
1048
|
+
// #4945: a value an author wrapped onto further lines is replaced whole, so its tail is not
|
|
1049
|
+
// left behind under the new value. The lines that count are the ones `state validate` already
|
|
1050
|
+
// reports as a field's continuation (stops at a blank line, a heading, a list item, a table
|
|
1051
|
+
// row, a fence or a sibling field). An empty first line has no value to continue.
|
|
1052
|
+
const valueEnd = focusMatch.index + focusMatch[0].length;
|
|
1053
|
+
const end = focusMatch[2].trim() === '' ? valueEnd : (0, state_document_cjs_2.fieldContinuationEnd)(body, valueEnd);
|
|
1054
|
+
body = body.slice(0, focusMatch.index) + focusMatch[1] + focusLabel + body.slice(end);
|
|
1001
1055
|
updated.push('Current focus');
|
|
1002
1056
|
}
|
|
1003
1057
|
// ## Current Position section mutation (#1104, #1365).
|
|
1004
1058
|
// `locateCurrentPosition` (fence-aware, tokenizeHeadings-based) locates
|
|
1005
1059
|
// the section; mirrors state.cts:2261-2324 byte-for-behaviour.
|
|
1006
|
-
body = mutateCurrentPositionFirstTime(body, intent, today, updated);
|
|
1060
|
+
body = mutateCurrentPositionFirstTime(body, { ...intent, startPlan }, today, updated);
|
|
1007
1061
|
}
|
|
1008
1062
|
else {
|
|
1009
1063
|
// Resume path: only update Last activity timestamp in Current Position
|
|
@@ -1095,7 +1149,9 @@ function mutateCurrentPositionFirstTime(body, intent, today, updated) {
|
|
|
1095
1149
|
const span = locateCurrentPosition(body);
|
|
1096
1150
|
if (span === null)
|
|
1097
1151
|
return body;
|
|
1098
|
-
|
|
1152
|
+
// #5460: the section's fenced examples are hidden while the live lines are rewritten.
|
|
1153
|
+
const fenceMask = (0, markdown_sectionizer_cjs_1.maskFences)(body.slice(span.start, span.end));
|
|
1154
|
+
let sectionBody = fenceMask.masked;
|
|
1099
1155
|
// Phase line — inline first, then pipe-table fallback (#1257).
|
|
1100
1156
|
const phaseLabel = `${intent.phaseNumber}${intent.phaseName ? ` (${intent.phaseName})` : ''} — EXECUTING`;
|
|
1101
1157
|
if (/^Phase:/m.test(sectionBody)) {
|
|
@@ -1107,7 +1163,7 @@ function mutateCurrentPositionFirstTime(body, intent, today, updated) {
|
|
|
1107
1163
|
sectionBody = replaced;
|
|
1108
1164
|
}
|
|
1109
1165
|
// Plan line.
|
|
1110
|
-
const planValue =
|
|
1166
|
+
const planValue = `${intent.startPlan} of ${intent.planCount || '?'}`;
|
|
1111
1167
|
if (/^Plan:/m.test(sectionBody)) {
|
|
1112
1168
|
sectionBody = sectionBody.replace(/^Plan:.*$/m, `Plan: ${planValue}`);
|
|
1113
1169
|
}
|
|
@@ -1137,8 +1193,11 @@ function mutateCurrentPositionFirstTime(body, intent, today, updated) {
|
|
|
1137
1193
|
if (replaced !== null)
|
|
1138
1194
|
sectionBody = replaced;
|
|
1139
1195
|
}
|
|
1196
|
+
const restored = fenceMask.restore(sectionBody);
|
|
1197
|
+
if (restored === null)
|
|
1198
|
+
return body;
|
|
1140
1199
|
updated.push('Current Position');
|
|
1141
|
-
return body.slice(0, span.start) +
|
|
1200
|
+
return body.slice(0, span.start) + restored + body.slice(span.end);
|
|
1142
1201
|
}
|
|
1143
1202
|
/**
|
|
1144
1203
|
* Resume ## Current Position mutation: only update Last activity line
|
|
@@ -1149,7 +1208,8 @@ function mutateCurrentPositionResume(body, intent, today, updated) {
|
|
|
1149
1208
|
const span = locateCurrentPosition(body);
|
|
1150
1209
|
if (span === null)
|
|
1151
1210
|
return body;
|
|
1152
|
-
|
|
1211
|
+
const fenceMask = (0, markdown_sectionizer_cjs_1.maskFences)(body.slice(span.start, span.end));
|
|
1212
|
+
let sectionBody = fenceMask.masked;
|
|
1153
1213
|
const resumeActivity = `Last activity: ${today} — Phase ${intent.phaseNumber} execution resumed (wave continue)`;
|
|
1154
1214
|
if (/^Last activity:/im.test(sectionBody)) {
|
|
1155
1215
|
sectionBody = sectionBody.replace(/^Last activity:.*$/im, resumeActivity);
|
|
@@ -1164,7 +1224,10 @@ function mutateCurrentPositionResume(body, intent, today, updated) {
|
|
|
1164
1224
|
updated.push('Last activity (resume)');
|
|
1165
1225
|
}
|
|
1166
1226
|
}
|
|
1167
|
-
|
|
1227
|
+
const restored = fenceMask.restore(sectionBody);
|
|
1228
|
+
if (restored === null)
|
|
1229
|
+
return body;
|
|
1230
|
+
return body.slice(0, span.start) + restored + body.slice(span.end);
|
|
1168
1231
|
}
|
|
1169
1232
|
const PLAN_SHAPE_N = /^(\d+)(?:\s.*)?$/;
|
|
1170
1233
|
const PLAN_SHAPE_N_OF_M = /^(\d+)\s+of\s+(\d+)(?:\s.*)?$/;
|
|
@@ -1221,7 +1284,8 @@ function mutateCurrentPositionForAdvance(content, fields, statusDefaults, lastAc
|
|
|
1221
1284
|
const span = locateCurrentPosition(content);
|
|
1222
1285
|
if (span === null)
|
|
1223
1286
|
return content;
|
|
1224
|
-
|
|
1287
|
+
const fenceMask = (0, markdown_sectionizer_cjs_1.maskFences)(content.slice(span.start, span.end));
|
|
1288
|
+
let sectionBody = fenceMask.masked;
|
|
1225
1289
|
let mutated = false;
|
|
1226
1290
|
// #3395: Phase is always replaced when a caller passes it — system-derived,
|
|
1227
1291
|
// not executor-authored (same rule as Plan below). plannedPhaseCore uses
|
|
@@ -1334,7 +1398,10 @@ function mutateCurrentPositionForAdvance(content, fields, statusDefaults, lastAc
|
|
|
1334
1398
|
}
|
|
1335
1399
|
if (!mutated)
|
|
1336
1400
|
return content;
|
|
1337
|
-
|
|
1401
|
+
const restored = fenceMask.restore(sectionBody);
|
|
1402
|
+
if (restored === null)
|
|
1403
|
+
return content;
|
|
1404
|
+
return content.slice(0, span.start) + restored + content.slice(span.end);
|
|
1338
1405
|
}
|
|
1339
1406
|
// ----------------------------------------------------------------------------
|
|
1340
1407
|
// advancePlan — intent implementation (Phase 2)
|
|
@@ -1633,6 +1700,29 @@ function nextPhaseWording(disk) {
|
|
|
1633
1700
|
return { status: 'Ready to plan', currentPlan: 'Not started', stoppedAt: 'ready to plan' };
|
|
1634
1701
|
}
|
|
1635
1702
|
}
|
|
1703
|
+
/**
|
|
1704
|
+
* #5165: is STATE.md already positioned PAST phase `phaseNum`? True when its
|
|
1705
|
+
* current phase (frontmatter `current_phase`, else the body `Current Phase` /
|
|
1706
|
+
* `Phase` field's leading phase token) compares greater than `phaseNum`.
|
|
1707
|
+
* Re-completing a phase STATE has already moved past must not rewind the
|
|
1708
|
+
* position; the caller combines this with "the phase is already complete in
|
|
1709
|
+
* ROADMAP.md" so a first-time out-of-order completion (#2028) still
|
|
1710
|
+
* transitions. An unparseable or absent current phase is "not past".
|
|
1711
|
+
*/
|
|
1712
|
+
function isStatePastPhase(content, phaseNum, sourcePath) {
|
|
1713
|
+
const fm = extractFrontmatter(content, sourcePath);
|
|
1714
|
+
const fromFm = fm['current_phase'];
|
|
1715
|
+
let raw = typeof fromFm === 'string' || typeof fromFm === 'number' ? String(fromFm) : null;
|
|
1716
|
+
if (raw === null || raw.trim() === '') {
|
|
1717
|
+
const body = stripFrontmatter(content);
|
|
1718
|
+
raw = (0, state_document_cjs_1.stateExtractField)(body, 'Current Phase') || (0, state_document_cjs_1.stateExtractField)(body, 'Phase') || null;
|
|
1719
|
+
}
|
|
1720
|
+
// `Phase 4` / `phase 4 of 9` name phase 4 as surely as `4 of 9` does.
|
|
1721
|
+
const m = raw === null ? null : /^\s*(?:phase\s+)?(\d+(?:\.\d+)*)/i.exec(raw);
|
|
1722
|
+
if (!m)
|
|
1723
|
+
return false;
|
|
1724
|
+
return comparePhaseNum(m[1], String(phaseNum)) > 0;
|
|
1725
|
+
}
|
|
1636
1726
|
/**
|
|
1637
1727
|
* Apply a `completePhase` transition to STATE.md content.
|
|
1638
1728
|
*
|
|
@@ -1660,6 +1750,12 @@ function completePhaseCore(content, intent, deps) {
|
|
|
1660
1750
|
const updated = [];
|
|
1661
1751
|
const today = deps.clock.localToday();
|
|
1662
1752
|
const nextWording = nextPhaseWording(intent.isLastPhase ? null : intent.nextPhaseDisk ?? null);
|
|
1753
|
+
// #5165: the milestone the caller resolved (ROADMAP-bound identity first) wins;
|
|
1754
|
+
// else the milestone STATE asserts. It scopes the roadmap-derived counters
|
|
1755
|
+
// below to that milestone's Progress-table rows, the same milestone
|
|
1756
|
+
// `phase complete` scopes its frontmatter progress to.
|
|
1757
|
+
const currentMilestone = (0, phase_lifecycle_cjs_1.milestoneVersionOf)(intent.milestone)
|
|
1758
|
+
?? (0, phase_lifecycle_cjs_1.milestoneVersionOf)(extractFrontmatter(content, deps.sourcePath)['milestone']);
|
|
1663
1759
|
// Consult the field-classification table for the frontmatter keys this
|
|
1664
1760
|
// transition touches (same guard beginPhaseCore applies). A missing row is a
|
|
1665
1761
|
// substrate defect — fail loudly rather than silently re-encoding policy.
|
|
@@ -1798,15 +1894,27 @@ function completePhaseCore(content, intent, deps) {
|
|
|
1798
1894
|
// Only runs when a Completed Phases field exists (the existing guard).
|
|
1799
1895
|
const completedRaw = (0, state_document_cjs_1.stateExtractField)(body, 'Completed Phases');
|
|
1800
1896
|
if (completedRaw !== null) {
|
|
1801
|
-
|
|
1897
|
+
const recordedCompleted = parseInt(completedRaw, 10);
|
|
1898
|
+
let newCompleted = recordedCompleted;
|
|
1802
1899
|
let derivedTotalPhases = null;
|
|
1803
1900
|
const roadmapContent = deps.roadmapProvider ? deps.roadmapProvider() : null;
|
|
1804
1901
|
if (roadmapContent) {
|
|
1805
|
-
const derived = (0, phase_lifecycle_cjs_1.deriveProgressFromRoadmap)(roadmapContent);
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1902
|
+
const derived = (0, phase_lifecycle_cjs_1.deriveProgressFromRoadmap)(roadmapContent, currentMilestone);
|
|
1903
|
+
// #4901: completed counters only ratchet up, like the frontmatter twin
|
|
1904
|
+
// (applyAuthoritativeProgressSubkeys, completedOnlyRaise). A derivation
|
|
1905
|
+
// that lands BELOW the recorded counter read a narrower scope than the
|
|
1906
|
+
// counter spans (e.g. the first `## Progress` section of a multi-milestone
|
|
1907
|
+
// roadmap), so its total is just as suspect: keep the recorded counter and
|
|
1908
|
+
// fall back to the recorded Total Phases for the percent below.
|
|
1909
|
+
const derivedLowered = derived.completedPhases !== null
|
|
1910
|
+
&& Number.isFinite(recordedCompleted)
|
|
1911
|
+
&& derived.completedPhases < recordedCompleted;
|
|
1912
|
+
if (!derivedLowered) {
|
|
1913
|
+
if (derived.completedPhases !== null)
|
|
1914
|
+
newCompleted = derived.completedPhases;
|
|
1915
|
+
if (derived.totalPhases !== null)
|
|
1916
|
+
derivedTotalPhases = derived.totalPhases;
|
|
1917
|
+
}
|
|
1810
1918
|
}
|
|
1811
1919
|
// #3057 B9: only mark 'Completed Phases' updated when the text actually
|
|
1812
1920
|
// changed. `stateReplaceField` returns the full (re-)substituted content
|
|
@@ -1912,8 +2020,16 @@ function plannedPhaseCore(content, intent, deps) {
|
|
|
1912
2020
|
// Phase is system-derived, always replaced (Knuth invariant does not apply);
|
|
1913
2021
|
// Status / Last activity stay template-aware.
|
|
1914
2022
|
const beforePos = body;
|
|
2023
|
+
// #5369: with no --name the label reuses the curated frontmatter name (when it is a real one), so the
|
|
2024
|
+
// body line and the frontmatter agree on it (the #3834 reassert keeps that name in frontmatter). A
|
|
2025
|
+
// status fragment a pre-fix write left there is never copied back into the name slot.
|
|
2026
|
+
const curatedName = existingFm['current_phase_name'];
|
|
2027
|
+
const labelName = intent.phaseName
|
|
2028
|
+
?? (typeof curatedName === 'string' && curatedName.trim() !== '' && !phaseIdMod.isPlannedPhaseStatusPhrase(curatedName)
|
|
2029
|
+
? curatedName.trim()
|
|
2030
|
+
: null);
|
|
1915
2031
|
body = mutateCurrentPositionForAdvance(body, {
|
|
1916
|
-
phase: `${intent.phaseNumber}${
|
|
2032
|
+
phase: `${intent.phaseNumber}${labelName ? ` (${labelName})` : ''} — READY TO EXECUTE`,
|
|
1917
2033
|
status: 'Ready to execute',
|
|
1918
2034
|
lastActivity: `${today} — Phase ${intent.phaseNumber} planning complete`,
|
|
1919
2035
|
}, statusDefaults, lastActivityDefaults);
|