@opengsd/gsd-core 1.11.0 → 1.13.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 +1 -1
- package/.opencode/plugins/gsd-core.js +12 -0
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-dom-verifier.md +169 -0
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +78 -42
- package/agents/gsd-framework-selector.md +1 -3
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +0 -1
- package/agents/gsd-pattern-mapper.md +11 -0
- package/agents/gsd-phase-researcher.md +3 -1
- package/agents/gsd-plan-checker.md +91 -112
- package/agents/gsd-planner.md +20 -4
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.md +2 -2
- package/agents/gsd-roadmapper.md +15 -11
- package/agents/gsd-ui-checker.md +82 -7
- package/agents/gsd-ui-researcher.md +70 -3
- package/agents/gsd-verifier.md +24 -2
- package/bin/install.js +847 -200
- package/commands/gsd/discuss-phase.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/import.md +1 -1
- package/commands/gsd/ns-workflow.md +2 -1
- package/commands/gsd/phase.md +1 -1
- package/commands/gsd/quick-batch.md +105 -0
- package/commands/gsd/quick.md +8 -4
- package/commands/gsd/surface.md +18 -8
- package/gsd-core/bin/gsd-tools.cjs +761 -100
- package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
- package/gsd-core/bin/lib/adr-parser.cjs +13 -7
- package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
- package/gsd-core/bin/lib/api-coverage.cjs +30 -9
- package/gsd-core/bin/lib/artifacts.cjs +2 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
- package/gsd-core/bin/lib/audit.cjs +163 -41
- package/gsd-core/bin/lib/broken-windows.cjs +306 -28
- package/gsd-core/bin/lib/capability-activation.cjs +27 -0
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +785 -144
- package/gsd-core/bin/lib/capability-state.cjs +25 -4
- package/gsd-core/bin/lib/capability-validator.cjs +321 -18
- package/gsd-core/bin/lib/capability-writer.cjs +14 -4
- package/gsd-core/bin/lib/check-command-router.cjs +229 -6
- package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/clusters.cjs +1 -0
- package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
- package/gsd-core/bin/lib/command-aliases.cjs +16 -0
- package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
- package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
- package/gsd-core/bin/lib/commands.cjs +877 -54
- package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
- package/gsd-core/bin/lib/config-loader.cjs +121 -29
- package/gsd-core/bin/lib/config.cjs +92 -2
- package/gsd-core/bin/lib/configuration.cjs +129 -37
- package/gsd-core/bin/lib/core-utils.cjs +118 -14
- package/gsd-core/bin/lib/decisions.cjs +213 -1
- package/gsd-core/bin/lib/edge-probe.cjs +23 -2
- package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
- package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
- package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +975 -326
- package/gsd-core/bin/lib/gap-checker.cjs +41 -8
- package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
- package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
- package/gsd-core/bin/lib/host-integration.cjs +96 -11
- package/gsd-core/bin/lib/init-command-router.cjs +132 -21
- package/gsd-core/bin/lib/init.cjs +252 -56
- package/gsd-core/bin/lib/install-engine.cjs +252 -15
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
- package/gsd-core/bin/lib/install-profiles.cjs +100 -18
- package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
- package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
- package/gsd-core/bin/lib/intel.cjs +101 -26
- package/gsd-core/bin/lib/io.cjs +195 -15
- package/gsd-core/bin/lib/learnings.cjs +85 -14
- package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
- package/gsd-core/bin/lib/loop-resolver.cjs +14 -8
- package/gsd-core/bin/lib/markdown-table.cjs +175 -4
- package/gsd-core/bin/lib/milestone.cjs +112 -7
- package/gsd-core/bin/lib/model-catalog.cjs +177 -19
- package/gsd-core/bin/lib/model-resolver.cjs +10 -28
- package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
- package/gsd-core/bin/lib/phase-command-router.cjs +13 -6
- package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
- package/gsd-core/bin/lib/phase-id.cjs +321 -13
- package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
- package/gsd-core/bin/lib/phase-locator.cjs +138 -17
- package/gsd-core/bin/lib/phase.cjs +1175 -115
- package/gsd-core/bin/lib/plan-document.cjs +273 -0
- package/gsd-core/bin/lib/plan-scan.cjs +13 -2
- package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +165 -34
- package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
- package/gsd-core/bin/lib/probe-core.cjs +4 -1
- package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
- package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
- package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
- package/gsd-core/bin/lib/quick-batch.cjs +840 -0
- package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +62 -14
- package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
- package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
- package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
- package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
- package/gsd-core/bin/lib/roadmap.cjs +248 -64
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
- package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
- package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
- package/gsd-core/bin/lib/shell-command-projection.cjs +75 -8
- package/gsd-core/bin/lib/smart-entry.cjs +19 -31
- package/gsd-core/bin/lib/spec-section.cjs +12 -7
- package/gsd-core/bin/lib/state-command-router.cjs +47 -18
- package/gsd-core/bin/lib/state-contract.cjs +359 -0
- package/gsd-core/bin/lib/state-document.cjs +216 -5
- package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
- package/gsd-core/bin/lib/state-transition.cjs +850 -145
- package/gsd-core/bin/lib/state.cjs +1629 -287
- package/gsd-core/bin/lib/surface.cjs +33 -10
- package/gsd-core/bin/lib/task-command-router.cjs +111 -1
- package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
- package/gsd-core/bin/lib/teams-status.cjs +4 -1
- package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
- package/gsd-core/bin/lib/uat.cjs +2542 -387
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
- package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
- package/gsd-core/bin/lib/unusable-input.cjs +13 -0
- package/gsd-core/bin/lib/update-context.cjs +6 -2
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +230 -12
- package/gsd-core/bin/lib/vendor/README.md +43 -5
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +287 -13
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
- package/gsd-core/bin/lib/verify.cjs +441 -56
- package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
- package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
- package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
- package/gsd-core/bin/lib/worktree-safety.cjs +185 -21
- package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
- package/gsd-core/bin/shared/exit-codes.json +8 -0
- package/gsd-core/bin/shared/exit-codes.sh +20 -0
- package/gsd-core/bin/shared/model-catalog.json +8 -1
- package/gsd-core/bin/verify-reapply-patches.cjs +70 -3
- package/gsd-core/references/agent-contracts.md +6 -5
- package/gsd-core/references/api-coverage.md +24 -2
- package/gsd-core/references/autonomous-smart-discuss.md +3 -3
- package/gsd-core/references/checkpoints.md +37 -19
- package/gsd-core/references/decimal-phase-calculation.md +5 -5
- package/gsd-core/references/edge-probe.md +17 -5
- package/gsd-core/references/execute-mvp-tdd.md +18 -18
- package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
- package/gsd-core/references/execute-phase-response-language.md +6 -0
- package/gsd-core/references/execute-phase-wave-guard.md +11 -9
- package/gsd-core/references/executor-examples.md +42 -0
- package/gsd-core/references/failing-direction.md +78 -0
- package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-integration.md +5 -5
- package/gsd-core/references/git-planning-commit.md +3 -3
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +22 -0
- package/gsd-core/references/model-profiles.md +1 -1
- package/gsd-core/references/mvp-concepts.md +2 -2
- package/gsd-core/references/nyquist-compliance.md +74 -0
- package/gsd-core/references/offer-next.md +3 -5
- package/gsd-core/references/phase-argument-parsing.md +3 -3
- package/gsd-core/references/plan-checker-examples.md +41 -0
- package/gsd-core/references/planner-antipatterns.md +25 -0
- package/gsd-core/references/planner-chunked.md +5 -1
- package/gsd-core/references/planner-coupling.md +42 -0
- package/gsd-core/references/planner-failing-direction.md +53 -0
- package/gsd-core/references/planner-human-verify-mode.md +15 -1
- package/gsd-core/references/planner-quick-batch.md +71 -0
- package/gsd-core/references/planner-reviews.md +47 -0
- package/gsd-core/references/planner-revision.md +76 -3
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +39 -9
- package/gsd-core/references/response-language-directive.md +9 -0
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/revision-loop.md +118 -11
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/tdd.md +15 -12
- package/gsd-core/references/ui-brand.md +65 -21
- package/gsd-core/references/ui-consideration-probe.md +1 -1
- package/gsd-core/references/universal-anti-patterns.md +2 -2
- package/gsd-core/references/verifier-evidence-gate.md +160 -0
- package/gsd-core/references/verify-command-path-resolvability.md +42 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +11 -11
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/SECURITY.md +3 -3
- package/gsd-core/templates/UI-SPEC.md +25 -3
- package/gsd-core/templates/VALIDATION.md +3 -3
- package/gsd-core/templates/phase-prompt.md +7 -0
- package/gsd-core/templates/state.md +7 -0
- package/gsd-core/templates/verification-report.md +5 -0
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +3 -1
- package/gsd-core/workflows/add-phase.md +5 -3
- package/gsd-core/workflows/add-tests.md +4 -9
- package/gsd-core/workflows/add-todo.md +2 -2
- package/gsd-core/workflows/ai-integration-phase.md +5 -10
- package/gsd-core/workflows/analyze-dependencies.md +2 -0
- package/gsd-core/workflows/audit-fix.md +14 -3
- package/gsd-core/workflows/audit-milestone.md +11 -9
- package/gsd-core/workflows/audit-uat.md +19 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +12 -26
- package/gsd-core/workflows/check-todos.md +2 -2
- package/gsd-core/workflows/cleanup.md +3 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
- package/gsd-core/workflows/code-review-fix.md +3 -1
- package/gsd-core/workflows/code-review.md +192 -69
- package/gsd-core/workflows/complete-milestone.md +28 -14
- package/gsd-core/workflows/debug.md +6 -4
- package/gsd-core/workflows/diagnose-issues.md +17 -7
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
- package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
- package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
- package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
- package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
- package/gsd-core/workflows/discuss-phase-power.md +2 -0
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/do.md +46 -19
- package/gsd-core/workflows/docs-update.md +6 -5
- package/gsd-core/workflows/edit-phase.md +3 -1
- package/gsd-core/workflows/eval-review.md +5 -10
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -11
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +29 -5
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +4 -2
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
- package/gsd-core/workflows/execute-phase.md +68 -66
- package/gsd-core/workflows/execute-plan.md +25 -20
- package/gsd-core/workflows/explore.md +3 -1
- package/gsd-core/workflows/extract-learnings.md +3 -1
- package/gsd-core/workflows/fast.md +8 -2
- package/gsd-core/workflows/forensics.md +3 -1
- package/gsd-core/workflows/graduation.md +6 -6
- package/gsd-core/workflows/health.md +4 -7
- package/gsd-core/workflows/help/modes/brief.md +2 -0
- package/gsd-core/workflows/help/modes/default.md +2 -0
- package/gsd-core/workflows/help/modes/full.md +12 -0
- package/gsd-core/workflows/help/modes/topic.md +2 -0
- package/gsd-core/workflows/help.md +2 -0
- package/gsd-core/workflows/import.md +17 -14
- package/gsd-core/workflows/inbox.md +5 -6
- package/gsd-core/workflows/ingest-docs.md +45 -12
- package/gsd-core/workflows/insert-phase.md +7 -5
- package/gsd-core/workflows/list-phase-assumptions.md +2 -0
- package/gsd-core/workflows/list-seeds.md +7 -3
- package/gsd-core/workflows/list-workspaces.md +3 -1
- package/gsd-core/workflows/manager.md +15 -26
- package/gsd-core/workflows/map-codebase.md +3 -1
- package/gsd-core/workflows/milestone-summary.md +3 -1
- package/gsd-core/workflows/mvp-phase.md +3 -3
- package/gsd-core/workflows/new-milestone.md +10 -22
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +17 -29
- package/gsd-core/workflows/new-workspace.md +2 -2
- package/gsd-core/workflows/next.md +4 -2
- package/gsd-core/workflows/node-repair.md +2 -0
- package/gsd-core/workflows/note.md +2 -0
- package/gsd-core/workflows/onboard.md +1 -1
- package/gsd-core/workflows/pause-work.md +20 -5
- package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
- package/gsd-core/workflows/plan-phase.md +251 -54
- package/gsd-core/workflows/plan-review-convergence.md +148 -19
- package/gsd-core/workflows/plant-seed.md +3 -3
- package/gsd-core/workflows/pr-branch.md +195 -51
- package/gsd-core/workflows/profile-user.md +17 -15
- package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
- package/gsd-core/workflows/progress.md +52 -15
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
- package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
- package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
- package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
- package/gsd-core/workflows/quick-batch.md +203 -0
- package/gsd-core/workflows/quick.md +33 -32
- package/gsd-core/workflows/reapply-patches.md +2 -0
- package/gsd-core/workflows/remove-phase.md +6 -4
- package/gsd-core/workflows/remove-workspace.md +3 -3
- package/gsd-core/workflows/resume-project.md +14 -14
- package/gsd-core/workflows/review.md +404 -21
- package/gsd-core/workflows/scan.md +3 -1
- package/gsd-core/workflows/section-manifest.json +12 -0
- package/gsd-core/workflows/secure-phase.md +3 -3
- package/gsd-core/workflows/session-report.md +2 -0
- package/gsd-core/workflows/settings-advanced.md +9 -9
- package/gsd-core/workflows/settings-integrations.md +66 -32
- package/gsd-core/workflows/settings.md +4 -6
- package/gsd-core/workflows/ship.md +22 -16
- package/gsd-core/workflows/sketch-wrap-up.md +13 -17
- package/gsd-core/workflows/sketch.md +13 -19
- package/gsd-core/workflows/smart-entry.md +4 -6
- package/gsd-core/workflows/spec-phase.md +31 -4
- package/gsd-core/workflows/spike-wrap-up.md +9 -11
- package/gsd-core/workflows/spike.md +21 -32
- package/gsd-core/workflows/stats.md +4 -2
- package/gsd-core/workflows/sync-skills.md +13 -5
- package/gsd-core/workflows/thread.md +13 -7
- package/gsd-core/workflows/transition.md +7 -5
- package/gsd-core/workflows/ui-phase.md +36 -21
- package/gsd-core/workflows/ui-review.md +7 -11
- package/gsd-core/workflows/ultraplan-phase.md +7 -13
- package/gsd-core/workflows/undo.md +9 -17
- package/gsd-core/workflows/update.md +47 -48
- package/gsd-core/workflows/validate-phase.md +3 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
- package/gsd-core/workflows/verify-work.md +106 -21
- package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
- package/hooks/dist/gsd-check-update-worker.js +19 -2
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +302 -22
- package/hooks/dist/gsd-cursor-post-tool.js +3 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
- package/hooks/dist/gsd-cursor-session-start.js +2 -1
- package/hooks/dist/gsd-cursor-stop.js +2 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
- package/hooks/dist/gsd-graphify-update.sh +22 -18
- package/hooks/dist/gsd-node-runner.sh +77 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +46 -12
- package/hooks/dist/gsd-read-guard.js +18 -7
- package/hooks/dist/gsd-read-injection-scanner.js +22 -13
- package/hooks/dist/gsd-secret-read-guard.js +1079 -0
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +222 -29
- package/hooks/dist/gsd-validate-commit.sh +523 -12
- package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
- package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
- package/hooks/dist/gsd-workflow-guard.js +36 -17
- package/hooks/dist/gsd-worktree-path-guard.js +36 -21
- package/hooks/dist/gsd-write-guard.js +35 -25
- package/hooks/dist/lib/cli-exit.js +560 -0
- package/hooks/dist/lib/exit-code-registry.js +98 -0
- package/hooks/dist/lib/git-cmd.js +210 -1
- package/hooks/dist/lib/git-probe.js +84 -0
- package/hooks/dist/lib/hook-exit.js +81 -0
- package/hooks/dist/lib/injection-patterns.js +36 -6
- package/hooks/dist/managed-hooks-registry.cjs +4 -0
- package/hooks/gsd-agent-isolation-guard.js +77 -38
- package/hooks/gsd-check-update-worker.js +19 -2
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +302 -22
- package/hooks/gsd-cursor-post-tool.js +3 -1
- package/hooks/gsd-cursor-pre-tool.js +3 -1
- package/hooks/gsd-cursor-session-start.js +2 -1
- package/hooks/gsd-cursor-stop.js +2 -1
- package/hooks/gsd-cursor-subagent-start.js +28 -23
- package/hooks/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/gsd-ensure-canonical-path.js +2 -1
- package/hooks/gsd-graphify-update.sh +22 -18
- package/hooks/gsd-node-runner.sh +77 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +46 -12
- package/hooks/gsd-read-guard.js +18 -7
- package/hooks/gsd-read-injection-scanner.js +22 -13
- package/hooks/gsd-secret-read-guard.js +1079 -0
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +222 -29
- package/hooks/gsd-validate-commit.sh +523 -12
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +36 -17
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/hooks.json +6 -0
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-cmd.js +210 -1
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/lib/injection-patterns.js +36 -6
- package/hooks/managed-hooks-registry.cjs +4 -0
- package/package.json +14 -9
- package/scripts/base64-scan.sh +74 -12
- package/scripts/build-hooks.js +12 -0
- package/scripts/check-glossary-refs.cjs +77 -15
- package/scripts/check-mutation-score-ratchet.cjs +156 -0
- package/scripts/ci-check-job-near-cap.cjs +49 -0
- package/scripts/ci-pr-mergeability.cjs +262 -0
- package/scripts/ci-test-scope.cjs +52 -12
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/docs-guard-registry.cjs +406 -0
- package/scripts/gen-capability-registry.cjs +8 -6
- package/scripts/gen-exit-code-docs.cjs +318 -0
- package/scripts/gen-exit-code-registry.cjs +891 -0
- package/scripts/gen-features.cjs +836 -0
- package/scripts/gen-hooks-cli-exit.cjs +239 -0
- package/scripts/gen-install-tree-fixtures.cjs +2 -2
- package/scripts/gen-loop-host-contract.cjs +189 -4
- package/scripts/gen-scripts-cli-exit.cjs +185 -0
- package/scripts/gen-state-md-docs.cjs +727 -0
- package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
- package/scripts/lib/ci-job-timing.cjs +72 -0
- package/scripts/lib/cli-exit.cjs +546 -44
- package/scripts/lib/drift-scan.cjs +32 -2
- package/scripts/lib/exit-code-registry.cjs +98 -0
- package/scripts/lib/ndjson-reporter.cjs +119 -0
- package/scripts/lib/shellcheck-fetch.cjs +247 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
- package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
- package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
- package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
- package/scripts/lint-phase-enumeration-drift.cjs +45 -14
- package/scripts/lint-phase-id-drift.cjs +133 -8
- package/scripts/lint-planning-prompt-drift.cjs +38 -1
- package/scripts/lint-portable-grep.cjs +176 -0
- package/scripts/lint-removed-but-needed.cjs +184 -16
- package/scripts/lint-response-language-coverage.cjs +524 -0
- package/scripts/lint-seam-enforcement.cjs +182 -0
- package/scripts/lint-slug-derivation-drift.cjs +921 -0
- package/scripts/lint-source-test-name-collision.cjs +241 -0
- package/scripts/lint-state-write-path-drift.cjs +337 -432
- package/scripts/lint-test-file-count.allowlist.json +124 -4
- package/scripts/lint-test-file-count.cjs +25 -3
- package/scripts/lint-unreachable-guard-drift.cjs +51 -64
- package/scripts/lint-vendored-deps.cjs +208 -35
- package/scripts/lint-workflow-shellcheck-baseline.json +1027 -0
- package/scripts/lint-workflow-shellcheck.cjs +614 -0
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/npm-audit-baseline.cjs +376 -0
- package/scripts/prompt-injection-scan.sh +83 -14
- package/scripts/require-issue-link-policy.cjs +16 -1
- package/scripts/secret-scan.sh +75 -13
- package/scripts/select-docs-guards.cjs +56 -0
- package/scripts/sync-runtime-launcher.cjs +22 -3
- package/skills/gsd-discuss-phase/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -1
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-ns-workflow/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +1 -1
- package/skills/gsd-quick/SKILL.md +8 -4
- package/skills/gsd-quick-batch/SKILL.md +105 -0
- package/skills/gsd-surface/SKILL.md +18 -8
- package/vscode/package.json +1 -1
- package/bin/lib/ui-safety-gate.cjs +0 -109
- package/scripts/lint-emitted-drift-ack.cjs +0 -344
- package/scripts/state-write-path-drift-baseline.json +0 -19
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TDD RED-evidence classification (#3770).
|
|
4
|
+
*
|
|
5
|
+
* The `type: tdd` executor gate previously accepted ANY nonzero test command as
|
|
6
|
+
* RED: syntax errors, zero-test discovery, fixture crashes, parser errors, and
|
|
7
|
+
* unrelated assertions all authorized production edits (GREEN). This module
|
|
8
|
+
* defines the compact RED evidence the gate now requires — the TARGET test's
|
|
9
|
+
* identity plus a matching assertion failure — and classifies a persisted test
|
|
10
|
+
* run into exactly one verdict:
|
|
11
|
+
*
|
|
12
|
+
* RED_EVIDENCE_OK — nonzero exit AND the target test failed as a REAL test
|
|
13
|
+
* (distinctly named, TAP-reported failure). The ONLY
|
|
14
|
+
* verdict that may advance to GREEN.
|
|
15
|
+
* INVALID_RED — everything else, with a machine-readable reason:
|
|
16
|
+
* unexpected_green | zero_tests_discovered |
|
|
17
|
+
* nonzero_exit_without_test_failure |
|
|
18
|
+
* fixture_or_load_failure | no_target_test_failure |
|
|
19
|
+
* invalid_record | unreadable_record (router arm).
|
|
20
|
+
*
|
|
21
|
+
* Everything here is PURE — no fs, no spawn, no clock — so the executor can
|
|
22
|
+
* persist the record (command, exit code, failing test, expected, actual) and
|
|
23
|
+
* validate it via `gsd_run check tdd-red-evidence <record.json>`.
|
|
24
|
+
*
|
|
25
|
+
* TAP parsing reuses the proven primitives from prohibition-enforcement
|
|
26
|
+
* (`parseNodeTestSummary`, `tapFailedTestNames`) — the same contract the
|
|
27
|
+
* prohibition probe's fail-first prover already relies on (#1259).
|
|
28
|
+
*/
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.classifyRedEvidence = classifyRedEvidence;
|
|
31
|
+
exports.buildRedEvidenceRecord = buildRedEvidenceRecord;
|
|
32
|
+
const prohibition_enforcement_cjs_1 = require("./prohibition-enforcement.cjs");
|
|
33
|
+
/** Basename of a path-like string ('' for non-strings) — separators `/` and `\`. */
|
|
34
|
+
function baseOf(p) {
|
|
35
|
+
return typeof p === 'string' ? (p.split(/[\\/]/).pop() ?? p) : '';
|
|
36
|
+
}
|
|
37
|
+
/** Coerce and validate the raw record's scalar fields. Returns null exit_code only when absent/non-numeric. */
|
|
38
|
+
function readInput(input) {
|
|
39
|
+
const command = typeof input?.command === 'string' ? input.command : '';
|
|
40
|
+
const output = typeof input?.output === 'string' ? input.output : '';
|
|
41
|
+
const targetTest = typeof input?.targetTest === 'string' ? input.targetTest.trim() : '';
|
|
42
|
+
const exitCode = typeof input?.exitCode === 'number' && Number.isFinite(input.exitCode) ? input.exitCode : null;
|
|
43
|
+
if (!command || !targetTest || exitCode === null)
|
|
44
|
+
return null;
|
|
45
|
+
return { command, exitCode, output, targetTest };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Classify a persisted RED-phase test run. Fail-closed: malformed input, an
|
|
49
|
+
* unparseable/empty TAP summary, a file-named (load/crash) failure, or a
|
|
50
|
+
* failure that is not the target test's are all INVALID_RED — only a nonzero
|
|
51
|
+
* exit WITH the distinctly-named target test failing is RED_EVIDENCE_OK.
|
|
52
|
+
* Never throws.
|
|
53
|
+
*/
|
|
54
|
+
function classifyRedEvidence(input) {
|
|
55
|
+
const parsed = readInput(input);
|
|
56
|
+
if (!parsed) {
|
|
57
|
+
return {
|
|
58
|
+
verdict: 'INVALID_RED',
|
|
59
|
+
reason: 'invalid_record',
|
|
60
|
+
evidence: {
|
|
61
|
+
command: typeof input?.command === 'string' ? input.command : '',
|
|
62
|
+
exit_code: null,
|
|
63
|
+
target_test: '',
|
|
64
|
+
tests: 0,
|
|
65
|
+
pass: 0,
|
|
66
|
+
fail: 0,
|
|
67
|
+
failing_tests: [],
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const { command, exitCode, output, targetTest } = parsed;
|
|
72
|
+
const summary = (0, prohibition_enforcement_cjs_1.parseNodeTestSummary)(output);
|
|
73
|
+
const failing = (0, prohibition_enforcement_cjs_1.tapFailedTestNames)(output);
|
|
74
|
+
const evidence = {
|
|
75
|
+
command,
|
|
76
|
+
exit_code: exitCode,
|
|
77
|
+
target_test: targetTest,
|
|
78
|
+
tests: summary.tests,
|
|
79
|
+
pass: summary.pass,
|
|
80
|
+
fail: summary.fail,
|
|
81
|
+
failing_tests: failing,
|
|
82
|
+
};
|
|
83
|
+
// Existing fail-fast rule, now machine-checked: exit 0 during RED is an
|
|
84
|
+
// unexpected GREEN — the feature may already exist or the test is wrong.
|
|
85
|
+
if (exitCode === 0) {
|
|
86
|
+
return { verdict: 'INVALID_RED', reason: 'unexpected_green', evidence };
|
|
87
|
+
}
|
|
88
|
+
// Zero-test discovery: the discovery pattern / fixture matched no tests.
|
|
89
|
+
// A run that executed nothing cannot prove anything about the behavior.
|
|
90
|
+
if (summary.tests === 0) {
|
|
91
|
+
return { verdict: 'INVALID_RED', reason: 'zero_tests_discovered', evidence };
|
|
92
|
+
}
|
|
93
|
+
// Nonzero exit but TAP reports no failing test: harness/setup/parser crash
|
|
94
|
+
// whose failure never reached a test assertion (or unparseable output).
|
|
95
|
+
if (summary.fail === 0 || failing.length === 0) {
|
|
96
|
+
return { verdict: 'INVALID_RED', reason: 'nonzero_exit_without_test_failure', evidence };
|
|
97
|
+
}
|
|
98
|
+
// Fixture/load failure: every failing entry is named like the target FILE —
|
|
99
|
+
// node reports a load-time crash (throw-on-require, syntax error, ENOENT
|
|
100
|
+
// fixture) as a file-named `not ok 1 - <file>`, never the target test.
|
|
101
|
+
const targetBase = baseOf(input?.targetFile ?? '');
|
|
102
|
+
const distinctlyNamed = failing.filter((n) => (targetBase ? baseOf(n) !== targetBase : true));
|
|
103
|
+
if (distinctlyNamed.length === 0) {
|
|
104
|
+
return { verdict: 'INVALID_RED', reason: 'fixture_or_load_failure', evidence };
|
|
105
|
+
}
|
|
106
|
+
// Unrelated failure: real tests ran and failed, but none is the target test
|
|
107
|
+
// the plan named — an unrelated assertion must not authorize GREEN.
|
|
108
|
+
if (!distinctlyNamed.includes(targetTest)) {
|
|
109
|
+
return { verdict: 'INVALID_RED', reason: 'no_target_test_failure', evidence };
|
|
110
|
+
}
|
|
111
|
+
return { verdict: 'RED_EVIDENCE_OK', reason: 'target_test_failed', evidence };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Project a classification into the persisted record shape — command, exit
|
|
115
|
+
* code, failing test, expected, actual, verdict, reason — so the evidence
|
|
116
|
+
* survives past the terminal and the gate can re-verify it deterministically.
|
|
117
|
+
* Pure: JSON-serializable, no timestamps (the record's mtime/commit carries time).
|
|
118
|
+
*/
|
|
119
|
+
function buildRedEvidenceRecord(input, result) {
|
|
120
|
+
const failingTest = result.evidence.failing_tests.find((n) => n === result.evidence.target_test) ??
|
|
121
|
+
result.evidence.failing_tests[0] ??
|
|
122
|
+
null;
|
|
123
|
+
return {
|
|
124
|
+
command: result.evidence.command,
|
|
125
|
+
exit_code: result.evidence.exit_code,
|
|
126
|
+
failing_test: failingTest,
|
|
127
|
+
target_test: result.evidence.target_test,
|
|
128
|
+
expected: typeof input?.expected === 'string' ? input.expected : null,
|
|
129
|
+
actual: typeof input?.actual === 'string' ? input.actual : null,
|
|
130
|
+
verdict: result.verdict,
|
|
131
|
+
reason: result.reason,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -31,6 +31,9 @@ exports.cmdTeamsStatus = cmdTeamsStatus;
|
|
|
31
31
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
32
|
const ioMod = require("./io.cjs");
|
|
33
33
|
const { output: coreOutput } = ioMod;
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
35
|
+
const cliExitModule = require("./cli-exit.cjs");
|
|
36
|
+
const { ExitError } = cliExitModule;
|
|
34
37
|
// ─── Pure core ────────────────────────────────────────────────────────────────
|
|
35
38
|
/**
|
|
36
39
|
* Resolve the agent-teams status from injected runtime and env.
|
|
@@ -67,7 +70,7 @@ function cmdTeamsStatus(cwd, opts) {
|
|
|
67
70
|
const status = resolveTeamsStatus({ runtime, env: process.env });
|
|
68
71
|
if (opts.active) {
|
|
69
72
|
// --active mode: no output, exit code encodes the boolean
|
|
70
|
-
|
|
73
|
+
throw new ExitError(status.active ? 0 : 1);
|
|
71
74
|
}
|
|
72
75
|
// Default: emit JSON to stdout via io.output, exit 0
|
|
73
76
|
coreOutput(status, false);
|
|
@@ -28,6 +28,9 @@ const { readVerificationStatus } = verification;
|
|
|
28
28
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
29
29
|
const phaseIdMod = require("./phase-id.cjs");
|
|
30
30
|
const { scopeToPhase } = phaseIdMod;
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
|
+
const coreUtils = require("./core-utils.cjs");
|
|
33
|
+
const { normalizeLineEndings } = coreUtils;
|
|
31
34
|
// ─── Blocking state sets (documented for maintainability) ─────────────────────
|
|
32
35
|
// UAT file frontmatter `status` values that indicate the file is not fully done
|
|
33
36
|
const BLOCKING_UAT_FM_STATUSES = new Set([
|
|
@@ -112,32 +115,62 @@ function analyzeMarkdown(raw) {
|
|
|
112
115
|
*/
|
|
113
116
|
function parseUatResultItems(cleanContent) {
|
|
114
117
|
const items = [];
|
|
115
|
-
// Find all ### N. Name headings
|
|
116
|
-
|
|
118
|
+
// Find all ### N. Name headings.
|
|
119
|
+
// #3078-CR MEDIUM (security review follow-up): STRUCTURE and ATTRIBUTION
|
|
120
|
+
// need different split frames. This is a STRUCTURE scan — finding where a
|
|
121
|
+
// heading block begins — and there is no attribution distinction to
|
|
122
|
+
// preserve, so split on any of `\n`, U+2028, U+2029: a heading delimited by
|
|
123
|
+
// an exotic line separator (origin/next's `/m`-anchored scan found these;
|
|
124
|
+
// a naive `split('\n')`-only port silently stopped finding them, making the
|
|
125
|
+
// gate MORE permissive than origin/next) is found exactly like a
|
|
126
|
+
// `\n`-delimited one. Contrast the `result:` scan below, which is an
|
|
127
|
+
// ATTRIBUTION scan and must NOT do this.
|
|
128
|
+
const HEADING_LINE_RE = /^###\s*(\d+)\.\s*(.+)$/;
|
|
117
129
|
const headings = [];
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
{
|
|
131
|
+
// All three separators are exactly one UTF-16 code unit, so the
|
|
132
|
+
// `line.length + 1` offset arithmetic below stays valid regardless of
|
|
133
|
+
// which separator terminated a given line.
|
|
134
|
+
const lines = cleanContent.split(/[\n\u2028\u2029]/);
|
|
135
|
+
let offset = 0;
|
|
136
|
+
for (const line of lines) {
|
|
137
|
+
const hMatch = line.match(HEADING_LINE_RE);
|
|
138
|
+
if (hMatch) {
|
|
139
|
+
headings.push({
|
|
140
|
+
index: offset + hMatch[0].length,
|
|
141
|
+
lineStart: offset,
|
|
142
|
+
test: parseInt(hMatch[1], 10),
|
|
143
|
+
name: hMatch[2].trim(),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
offset += line.length + 1; // +1 for the separator consumed by split
|
|
147
|
+
}
|
|
125
148
|
}
|
|
126
149
|
for (let i = 0; i < headings.length; i++) {
|
|
127
150
|
const h = headings[i];
|
|
128
151
|
const blockStart = h.index;
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const blockContent =
|
|
135
|
-
? cleanContent.slice(blockStart,
|
|
152
|
+
// A block spans until the START of the next heading's line (tracked
|
|
153
|
+
// directly from the same split-frame scan above), not a re-search for a
|
|
154
|
+
// literal '\n###' over unsplit text -- the latter would silently miss a
|
|
155
|
+
// next heading delimited by U+2028/U+2029 instead of '\n' and swallow
|
|
156
|
+
// every subsequent block into this one.
|
|
157
|
+
const blockContent = i + 1 < headings.length
|
|
158
|
+
? cleanContent.slice(blockStart, headings[i + 1].lineStart)
|
|
136
159
|
: cleanContent.slice(blockStart);
|
|
137
|
-
// Column-0
|
|
160
|
+
// Column-0 result line, split-then-match (#3078-CR MEDIUM — same fix as
|
|
161
|
+
// the heading scan above): test each already-split line individually
|
|
162
|
+
// against a single-line (no `/m` anchor) pattern instead of anchoring
|
|
163
|
+
// over unsplit `blockContent`, so a `result:`-shaped line reachable only
|
|
164
|
+
// via a U+2028/U+2029 separator inside an `expected: |` scalar body can
|
|
165
|
+
// never register as a fake column-0 match. FIRST MATCH WINS — no
|
|
166
|
+
// ambiguity counting, matching src/uat.cts's contract.
|
|
138
167
|
// Uses [ \t]* (not \s*) so the captured value must sit on the SAME line as result:.
|
|
139
168
|
// A result: key with the value on a subsequent line yields no match → 'missing' (blocker).
|
|
140
|
-
const
|
|
169
|
+
const RESULT_LINE_RE = /^result:[ \t]*\[?([\w-]+)\]?/i;
|
|
170
|
+
const resultMatch = blockContent
|
|
171
|
+
.split('\n')
|
|
172
|
+
.map((line) => line.match(RESULT_LINE_RE))
|
|
173
|
+
.find((m) => m !== null) ?? null;
|
|
141
174
|
if (resultMatch) {
|
|
142
175
|
items.push({
|
|
143
176
|
test: h.test,
|
|
@@ -205,7 +238,11 @@ function evaluateUatPassed(phaseFullDir, opts) {
|
|
|
205
238
|
const uatFilePath = node_path_1.default.join(phaseFullDir, file);
|
|
206
239
|
let raw = '';
|
|
207
240
|
try {
|
|
208
|
-
|
|
241
|
+
// #3078-CR MEDIUM: normalize line endings at the read boundary — the
|
|
242
|
+
// same seam src/uat.cts and src/verification.cts route through — so a
|
|
243
|
+
// lone-CR *-UAT.md is not read as one unbroken line by the column-0
|
|
244
|
+
// scans below.
|
|
245
|
+
raw = normalizeLineEndings(node_fs_1.default.readFileSync(uatFilePath, 'utf-8'));
|
|
209
246
|
}
|
|
210
247
|
catch {
|
|
211
248
|
blockers.push(`${file}: could not read file`);
|
|
@@ -252,7 +289,8 @@ function evaluateUatPassed(phaseFullDir, opts) {
|
|
|
252
289
|
const verificationFilePath = node_path_1.default.join(phaseFullDir, file);
|
|
253
290
|
let raw = '';
|
|
254
291
|
try {
|
|
255
|
-
|
|
292
|
+
// #3078-CR MEDIUM: same read-boundary normalization as the UAT loop above.
|
|
293
|
+
raw = normalizeLineEndings(node_fs_1.default.readFileSync(verificationFilePath, 'utf-8'));
|
|
256
294
|
}
|
|
257
295
|
catch {
|
|
258
296
|
blockers.push(`${file}: could not read verification file`);
|