@opengsd/gsd-core 1.10.0 → 1.12.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/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-debug-session-manager.md +12 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-doc-synthesizer.md +2 -4
- package/agents/gsd-dom-verifier.md +169 -0
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +22 -14
- package/agents/gsd-framework-selector.md +1 -3
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +5 -3
- package/agents/gsd-pattern-mapper.md +11 -0
- package/agents/gsd-phase-researcher.md +23 -2
- package/agents/gsd-plan-checker.md +50 -53
- package/agents/gsd-planner.md +50 -50
- 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 +63 -4
- package/agents/gsd-ui-researcher.md +41 -3
- package/agents/gsd-user-profiler.md +3 -0
- package/agents/gsd-verifier.md +13 -4
- package/bin/install.js +1448 -1103
- package/commands/gsd/code-review.md +1 -1
- 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/map-codebase.md +1 -1
- package/commands/gsd/mempalace-capture.md +1 -1
- package/commands/gsd/mempalace-recall.md +1 -1
- package/commands/gsd/new-milestone.md +1 -1
- package/commands/gsd/quick.md +9 -5
- package/commands/gsd/review-backlog.md +2 -1
- package/commands/gsd/verify-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +1035 -138
- package/gsd-core/bin/lib/active-workstream-store.cjs +146 -22
- package/gsd-core/bin/lib/adr-parser.cjs +13 -7
- package/gsd-core/bin/lib/agent-install-check.cjs +392 -32
- package/gsd-core/bin/lib/api-coverage.cjs +33 -14
- package/gsd-core/bin/lib/artifacts.cjs +5 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +32 -15
- package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
- package/gsd-core/bin/lib/audit.cjs +1026 -268
- package/gsd-core/bin/lib/broken-windows.cjs +306 -28
- package/gsd-core/bin/lib/capability-consent.cjs +149 -15
- package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +845 -130
- package/gsd-core/bin/lib/capability-source.cjs +92 -0
- package/gsd-core/bin/lib/capability-state.cjs +18 -3
- package/gsd-core/bin/lib/capability-trust.cjs +444 -25
- package/gsd-core/bin/lib/capability-validator.cjs +700 -40
- package/gsd-core/bin/lib/capability-writer.cjs +3 -2
- package/gsd-core/bin/lib/check-command-router.cjs +216 -42
- package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +735 -0
- package/gsd-core/bin/lib/command-aliases.cjs +22 -0
- package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
- package/gsd-core/bin/lib/command-roster.cjs +44 -1
- package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
- package/gsd-core/bin/lib/commands.cjs +1172 -108
- package/gsd-core/bin/lib/commonjs-marker.cjs +12 -6
- package/gsd-core/bin/lib/complexity-trigger.cjs +1192 -0
- package/gsd-core/bin/lib/config-loader.cjs +187 -23
- package/gsd-core/bin/lib/config.cjs +102 -3
- package/gsd-core/bin/lib/configuration.cjs +129 -37
- package/gsd-core/bin/lib/core-utils.cjs +208 -33
- package/gsd-core/bin/lib/decisions.cjs +23 -0
- package/gsd-core/bin/lib/edge-probe.cjs +9 -1
- 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/fallow-runner.cjs +20 -44
- package/gsd-core/bin/lib/frontmatter.cjs +899 -229
- package/gsd-core/bin/lib/gap-checker.cjs +95 -10
- package/gsd-core/bin/lib/git-base-branch.cjs +276 -39
- package/gsd-core/bin/lib/gsd2-import.cjs +10 -1
- package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +149 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +268 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +187 -0
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +451 -0
- package/gsd-core/bin/lib/host-integration.cjs +39 -6
- package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
- package/gsd-core/bin/lib/init-command-router.cjs +118 -21
- package/gsd-core/bin/lib/init.cjs +439 -168
- package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
- package/gsd-core/bin/lib/install-engine.cjs +811 -259
- package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +235 -0
- package/gsd-core/bin/lib/install-profiles.cjs +212 -61
- package/gsd-core/bin/lib/install-scope.cjs +270 -0
- package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
- package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
- package/gsd-core/bin/lib/installer-migration-report.cjs +3 -0
- package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +148 -38
- package/gsd-core/bin/lib/intel.cjs +101 -26
- package/gsd-core/bin/lib/io.cjs +170 -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/markdown-sectionizer.cjs +2 -1
- package/gsd-core/bin/lib/markdown-table.cjs +183 -22
- package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
- package/gsd-core/bin/lib/milestone.cjs +842 -73
- package/gsd-core/bin/lib/model-catalog.cjs +232 -16
- package/gsd-core/bin/lib/model-resolver.cjs +193 -68
- package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
- package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
- package/gsd-core/bin/lib/pattern.cjs +122 -0
- package/gsd-core/bin/lib/phase-estimation.cjs +18 -9
- package/gsd-core/bin/lib/phase-id.cjs +514 -40
- package/gsd-core/bin/lib/phase-lifecycle.cjs +52 -19
- package/gsd-core/bin/lib/phase-locator.cjs +262 -34
- package/gsd-core/bin/lib/phase.cjs +1038 -214
- package/gsd-core/bin/lib/plan-dependency-graph.cjs +72 -1
- package/gsd-core/bin/lib/plan-document.cjs +263 -0
- package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
- package/gsd-core/bin/lib/plan-scan.cjs +98 -3
- 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-scope.cjs +31 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +894 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +112 -6
- package/gsd-core/bin/lib/probe-core.cjs +5 -2
- package/gsd-core/bin/lib/profile-output.cjs +1 -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/real-home-guard.cjs +419 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +766 -0
- package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +11 -6
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +22 -13
- package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +421 -66
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
- package/gsd-core/bin/lib/roadmap-command-router.cjs +59 -11
- package/gsd-core/bin/lib/roadmap-parser.cjs +1006 -184
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
- package/gsd-core/bin/lib/roadmap.cjs +442 -96
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +702 -52
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +459 -55
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
- package/gsd-core/bin/lib/runtime-homes.cjs +69 -3
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +402 -58
- package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
- package/gsd-core/bin/lib/runtime-slash.cjs +96 -8
- package/gsd-core/bin/lib/security.cjs +104 -5
- package/gsd-core/bin/lib/shell-command-projection.cjs +342 -7
- package/gsd-core/bin/lib/smart-entry.cjs +133 -23
- package/gsd-core/bin/lib/spec-section.cjs +12 -7
- package/gsd-core/bin/lib/state-command-router.cjs +52 -19
- package/gsd-core/bin/lib/state-contract.cjs +359 -0
- package/gsd-core/bin/lib/state-document.cjs +338 -8
- package/gsd-core/bin/lib/state-md-schema.cjs +221 -0
- package/gsd-core/bin/lib/state-transition.cjs +846 -176
- package/gsd-core/bin/lib/state.cjs +2589 -369
- package/gsd-core/bin/lib/surface.cjs +33 -11
- 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/teams-status.cjs +4 -1
- package/gsd-core/bin/lib/text-lines.cjs +80 -0
- package/gsd-core/bin/lib/token-scanner.cjs +76 -0
- package/gsd-core/bin/lib/uat-predicate.cjs +67 -23
- package/gsd-core/bin/lib/uat.cjs +1761 -167
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
- package/gsd-core/bin/lib/ui-safety-gate.cjs +51 -12
- package/gsd-core/bin/lib/unusable-input.cjs +37 -0
- package/gsd-core/bin/lib/update-context.cjs +8 -2
- package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +20 -6
- package/gsd-core/bin/lib/vendor/README.md +75 -0
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
- package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
- package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +272 -9
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify.cjs +453 -918
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +53 -32
- package/gsd-core/bin/lib/workstream-inventory.cjs +63 -10
- package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
- package/gsd-core/bin/lib/workstream.cjs +2 -2
- package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
- package/gsd-core/bin/lib/worktree-safety.cjs +341 -18
- package/gsd-core/bin/shared/config-defaults.manifest.json +8 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +12 -1
- 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/references/agent-contracts.md +44 -26
- 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 +39 -21
- package/gsd-core/references/context-budget.md +1 -1
- package/gsd-core/references/decimal-phase-calculation.md +5 -5
- package/gsd-core/references/dispatch-isolation-gate.md +138 -0
- package/gsd-core/references/doc-conflict-engine.md +1 -1
- package/gsd-core/references/edge-probe.md +8 -0
- package/gsd-core/references/execute-mvp-tdd.md +4 -6
- package/gsd-core/references/execute-phase-between-wave-reset.md +15 -14
- package/gsd-core/references/execute-phase-context-guard.md +1 -1
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/execute-phase-wave-guard.md +17 -11
- package/gsd-core/references/failing-direction.md +78 -0
- 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 +5 -4
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +61 -2
- package/gsd-core/references/model-profiles.md +12 -4
- package/gsd-core/references/mvp-concepts.md +9 -9
- 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/planner-failing-direction.md +53 -0
- package/gsd-core/references/planner-guidance.md +3 -9
- package/gsd-core/references/planner-human-verify-mode.md +15 -1
- package/gsd-core/references/planner-preconditions.md +1 -1
- package/gsd-core/references/planner-reviews.md +1 -1
- package/gsd-core/references/planner-revision.md +1 -1
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +44 -13
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/revision-loop.md +1 -1
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/specless-probe-fallback.md +1 -1
- package/gsd-core/references/tdd.md +1 -3
- 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 +5 -5
- package/gsd-core/references/verifier-phase-gates.md +192 -0
- package/gsd-core/references/verify-command-path-resolvability.md +42 -0
- package/gsd-core/references/verify-mvp-mode.md +2 -2
- package/gsd-core/references/workstream-flag.md +33 -17
- 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/discussion-log.md +1 -1
- package/gsd-core/templates/phase-prompt.md +5 -4
- package/gsd-core/templates/state.md +11 -4
- package/gsd-core/templates/verification-report.md +9 -1
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +3 -3
- package/gsd-core/workflows/add-tests.md +3 -8
- package/gsd-core/workflows/add-todo.md +1 -1
- package/gsd-core/workflows/ai-integration-phase.md +13 -20
- package/gsd-core/workflows/audit-fix.md +12 -3
- package/gsd-core/workflows/audit-milestone.md +9 -9
- package/gsd-core/workflows/audit-uat.md +17 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +11 -27
- package/gsd-core/workflows/check-todos.md +1 -1
- package/gsd-core/workflows/cleanup.md +64 -5
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +14 -4
- package/gsd-core/workflows/code-review-fix.md +38 -11
- package/gsd-core/workflows/code-review.md +159 -52
- package/gsd-core/workflows/complete-milestone.md +151 -23
- package/gsd-core/workflows/debug.md +12 -8
- package/gsd-core/workflows/diagnose-issues.md +47 -15
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -8
- package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/text.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
- package/gsd-core/workflows/discuss-phase.md +1 -1
- package/gsd-core/workflows/do.md +3 -6
- package/gsd-core/workflows/docs-update.md +5 -4
- package/gsd-core/workflows/edit-phase.md +27 -2
- package/gsd-core/workflows/eval-review.md +7 -14
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +142 -15
- 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 +77 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +24 -4
- 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 +2 -2
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase.md +72 -100
- package/gsd-core/workflows/execute-plan.md +52 -15
- package/gsd-core/workflows/explore.md +131 -4
- package/gsd-core/workflows/extract-learnings.md +1 -1
- package/gsd-core/workflows/fast.md +10 -2
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +5 -5
- package/gsd-core/workflows/health.md +76 -10
- package/gsd-core/workflows/import.md +18 -15
- package/gsd-core/workflows/inbox.md +4 -5
- package/gsd-core/workflows/ingest-docs.md +49 -16
- package/gsd-core/workflows/insert-phase.md +5 -5
- package/gsd-core/workflows/list-seeds.md +5 -3
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +12 -23
- package/gsd-core/workflows/map-codebase.md +1 -1
- package/gsd-core/workflows/milestone-summary.md +1 -1
- package/gsd-core/workflows/mvp-phase.md +8 -5
- package/gsd-core/workflows/new-milestone.md +22 -29
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +26 -40
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +14 -2
- package/gsd-core/workflows/pause-work.md +1 -1
- 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 +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +3 -3
- package/gsd-core/workflows/plan-phase.md +162 -59
- package/gsd-core/workflows/plan-review-convergence.md +96 -11
- package/gsd-core/workflows/plant-seed.md +2 -2
- package/gsd-core/workflows/pr-branch.md +187 -51
- package/gsd-core/workflows/profile-user.md +16 -14
- package/gsd-core/workflows/progress.md +61 -18
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +5 -7
- package/gsd-core/workflows/quick/steps/quick-verification.md +28 -9
- package/gsd-core/workflows/quick/steps/research-phase.md +4 -6
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick.md +55 -44
- package/gsd-core/workflows/remove-phase.md +4 -4
- package/gsd-core/workflows/remove-workspace.md +2 -2
- package/gsd-core/workflows/resume-project.md +8 -12
- package/gsd-core/workflows/review.md +219 -20
- package/gsd-core/workflows/scan.md +1 -1
- package/gsd-core/workflows/secure-phase.md +3 -3
- package/gsd-core/workflows/session-report.md +2 -1
- package/gsd-core/workflows/settings-advanced.md +7 -9
- package/gsd-core/workflows/settings-integrations.md +64 -31
- package/gsd-core/workflows/settings.md +69 -7
- package/gsd-core/workflows/ship.md +116 -50
- package/gsd-core/workflows/sketch-wrap-up.md +11 -17
- package/gsd-core/workflows/sketch.md +12 -18
- package/gsd-core/workflows/smart-entry.md +3 -5
- package/gsd-core/workflows/spec-phase.md +53 -13
- package/gsd-core/workflows/spike-wrap-up.md +7 -11
- package/gsd-core/workflows/spike.md +20 -31
- package/gsd-core/workflows/stats.md +2 -2
- package/gsd-core/workflows/sync-skills.md +64 -9
- package/gsd-core/workflows/thread.md +11 -7
- package/gsd-core/workflows/transition.md +49 -14
- package/gsd-core/workflows/ui-phase.md +15 -21
- package/gsd-core/workflows/ui-review.md +8 -12
- package/gsd-core/workflows/ultraplan-phase.md +5 -13
- package/gsd-core/workflows/undo.md +8 -16
- package/gsd-core/workflows/update.md +7 -11
- 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 +66 -25
- package/hooks/dist/gsd-agent-isolation-guard.js +158 -30
- package/hooks/dist/gsd-check-update-worker.js +56 -13
- package/hooks/dist/gsd-check-update.js +19 -1
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +19 -10
- package/hooks/dist/gsd-cursor-post-tool.js +3 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +2 -3
- 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 +83 -3
- package/hooks/dist/gsd-cursor-subagent-stop.js +6 -3
- 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 +76 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +37 -27
- package/hooks/dist/gsd-read-guard.js +16 -7
- package/hooks/dist/gsd-read-injection-scanner.js +55 -32
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +231 -24
- package/hooks/dist/gsd-update-banner.js +22 -1
- package/hooks/dist/gsd-validate-commit.sh +80 -6
- 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 +162 -46
- 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 +92 -59
- 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 +45 -0
- package/hooks/dist/lib/isolation-deny-reason.js +39 -0
- package/hooks/dist/lib/isolation-sentinel.js +9 -0
- package/hooks/dist/managed-hooks-registry.cjs +3 -0
- package/hooks/gsd-agent-isolation-guard.js +158 -30
- package/hooks/gsd-check-update-worker.js +56 -13
- package/hooks/gsd-check-update.js +19 -1
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +19 -10
- package/hooks/gsd-cursor-post-tool.js +3 -1
- package/hooks/gsd-cursor-pre-tool.js +2 -3
- package/hooks/gsd-cursor-session-start.js +2 -1
- package/hooks/gsd-cursor-stop.js +2 -1
- package/hooks/gsd-cursor-subagent-start.js +83 -3
- package/hooks/gsd-cursor-subagent-stop.js +6 -3
- package/hooks/gsd-ensure-canonical-path.js +2 -1
- package/hooks/gsd-graphify-update.sh +22 -18
- package/hooks/gsd-node-runner.sh +76 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +37 -27
- package/hooks/gsd-read-guard.js +16 -7
- package/hooks/gsd-read-injection-scanner.js +55 -32
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +231 -24
- package/hooks/gsd-update-banner.js +22 -1
- package/hooks/gsd-validate-commit.sh +80 -6
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +162 -46
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-cmd.js +92 -59
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/lib/injection-patterns.js +45 -0
- package/hooks/lib/isolation-deny-reason.js +39 -0
- package/hooks/lib/isolation-sentinel.js +9 -0
- package/hooks/managed-hooks-registry.cjs +3 -0
- package/package.json +28 -11
- package/pi/gsd.cjs +19 -5
- package/scripts/base64-scan.sh +74 -12
- package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
- package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
- package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
- package/scripts/build-hooks.js +5 -0
- package/scripts/changeset/lint.cjs +60 -5
- package/scripts/check-alias-drift.cjs +7 -43
- package/scripts/check-contract-drift.cjs +297 -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 +64 -14
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/command-contract-helpers.cjs +903 -1
- package/scripts/docs-guard-registry.cjs +396 -0
- package/scripts/gen-adr-index.cjs +728 -38
- package/scripts/gen-capability-registry.cjs +11 -21
- package/scripts/gen-context-index.cjs +2 -11
- 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-health-docs.cjs +390 -0
- package/scripts/gen-hooks-cli-exit.cjs +239 -0
- package/scripts/gen-install-tree-fixtures.cjs +2 -2
- package/scripts/gen-inventory-manifest.cjs +50 -4
- package/scripts/gen-loop-host-contract.cjs +138 -25
- package/scripts/gen-registry.cjs +3 -14
- 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/alias-drift-families.cjs +46 -0
- package/scripts/lib/ci-job-timing.cjs +72 -0
- package/scripts/lib/cli-exit.cjs +546 -44
- package/scripts/lib/drift-scan.cjs +308 -0
- package/scripts/lib/exit-code-registry.cjs +98 -0
- package/scripts/lib/ndjson-reporter.cjs +119 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +1 -26
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
- package/scripts/lint-canary-version-leak.cjs +73 -0
- package/scripts/lint-command-contract.cjs +96 -13
- package/scripts/lint-completion-predicate-drift.cjs +933 -0
- package/scripts/lint-completion-ratio-drift.cjs +214 -0
- package/scripts/lint-default-flip-documentation.cjs +193 -0
- package/scripts/lint-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +193 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +38 -0
- package/scripts/lint-eslint-glob-coverage.cjs +340 -0
- package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
- package/scripts/lint-health-diagnostic-rule-table.cjs +461 -0
- package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
- package/scripts/lint-milestone-window-drift.cjs +468 -0
- package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
- package/scripts/lint-phase-enumeration-drift.cjs +492 -0
- package/scripts/lint-plan-count-drift.cjs +318 -0
- package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
- package/scripts/lint-planning-prompt-drift.cjs +471 -0
- package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
- package/scripts/lint-regression-test-names.cjs +15 -13
- package/scripts/lint-removed-but-needed.cjs +488 -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-field-drift.cjs +805 -0
- package/scripts/lint-state-write-path-drift.cjs +950 -0
- package/scripts/lint-test-file-count.allowlist.json +137 -8
- package/scripts/lint-test-file-count.cjs +25 -3
- package/scripts/lint-unreachable-guard-drift.cjs +830 -0
- package/scripts/lint-vendored-deps.cjs +297 -0
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/pr-changed-files.cjs +63 -0
- package/scripts/pr-template-policy.cjs +14 -4
- package/scripts/prompt-injection-scan.sh +100 -14
- package/scripts/require-issue-link-policy.cjs +192 -0
- package/scripts/secret-scan.sh +75 -13
- package/scripts/select-docs-guards.cjs +56 -0
- package/scripts/sync-runtime-launcher.cjs +24 -7
- package/skills/gsd-autonomous/SKILL.md +0 -1
- package/skills/gsd-code-review/SKILL.md +1 -1
- package/skills/gsd-discuss-phase/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -2
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-map-codebase/SKILL.md +1 -1
- package/skills/gsd-mempalace-capture/SKILL.md +1 -1
- package/skills/gsd-mempalace-recall/SKILL.md +1 -1
- package/skills/gsd-new-milestone/SKILL.md +1 -1
- package/skills/gsd-next/SKILL.md +0 -1
- package/skills/gsd-plan-phase/SKILL.md +0 -1
- package/skills/gsd-progress/SKILL.md +0 -1
- package/skills/gsd-quick/SKILL.md +9 -5
- package/skills/gsd-review-backlog/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +0 -1
- package/skills/gsd-verify-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
- package/bin/lib/ui-safety-gate.cjs +0 -107
- package/gsd-core/workflows/discovery-phase.md +0 -298
- package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
- package/gsd-core/workflows/verify-phase.md +0 -574
- package/scripts/affected-tests-lib.cjs +0 -554
- package/scripts/lint-allow-test-rule-refs.cjs +0 -162
- package/scripts/lint-emitted-drift-ack.cjs +0 -344
- package/scripts/run-affected-tests.cjs +0 -7
- package/scripts/run-tests.cjs +0 -1051
|
@@ -17,6 +17,16 @@
|
|
|
17
17
|
const fs = require('fs');
|
|
18
18
|
const path = require('path');
|
|
19
19
|
const { spawnSync } = require('child_process');
|
|
20
|
+
const { HOOK_ON_CRASH, allow, deny, crash } = require('./lib/hook-exit.js');
|
|
21
|
+
const { reportIfUndetermined } = require('./lib/git-probe.js');
|
|
22
|
+
|
|
23
|
+
// This guard's outer catch has always exited 0 (fail open): a path guard that
|
|
24
|
+
// cannot resolve the worktree must not block the user's edit — its whole job
|
|
25
|
+
// is a targeted containment check, not a general-purpose file-write blocker,
|
|
26
|
+
// and an unresolved worktree root gives it nothing to check against. Declared
|
|
27
|
+
// ONCE here so the outer catch's crash() call states its policy explicitly
|
|
28
|
+
// rather than inheriting a default (#3911).
|
|
29
|
+
const ON_CRASH = HOOK_ON_CRASH.ALLOW;
|
|
20
30
|
|
|
21
31
|
const SPAWNOPT = { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 2000, windowsHide: true };
|
|
22
32
|
|
|
@@ -132,7 +142,7 @@ function normalizeKimiPayload(data) {
|
|
|
132
142
|
}
|
|
133
143
|
|
|
134
144
|
let input = '';
|
|
135
|
-
const stdinTimeout = setTimeout(() =>
|
|
145
|
+
const stdinTimeout = setTimeout(() => allow(undefined), 3000);
|
|
136
146
|
process.stdin.setEncoding('utf8');
|
|
137
147
|
process.stdin.on('data', chunk => input += chunk);
|
|
138
148
|
process.stdin.on('end', () => {
|
|
@@ -143,7 +153,7 @@ process.stdin.on('end', () => {
|
|
|
143
153
|
|
|
144
154
|
// Only guard Edit, Write, and MultiEdit tool calls
|
|
145
155
|
if (toolName !== 'Edit' && toolName !== 'Write' && toolName !== 'MultiEdit') {
|
|
146
|
-
|
|
156
|
+
allow(undefined);
|
|
147
157
|
}
|
|
148
158
|
|
|
149
159
|
const cwd = data.cwd || process.cwd();
|
|
@@ -154,15 +164,20 @@ process.stdin.on('end', () => {
|
|
|
154
164
|
// In the main repo or a submodule it returns .git (or a path without /worktrees/).
|
|
155
165
|
// This approach works even when cwd is a subdirectory of the worktree.
|
|
156
166
|
const gitDirResult = git(['rev-parse', '--git-dir'], cwd);
|
|
167
|
+
// #3911: a timeout/spawn-failure result is indistinguishable from a clean
|
|
168
|
+
// "not a git repo" answer by status/stdout alone — reportIfUndetermined
|
|
169
|
+
// is a no-op on a genuine negative and only fires the diagnostic when the
|
|
170
|
+
// probe itself could not run. The allow() below is UNCHANGED either way.
|
|
171
|
+
reportIfUndetermined('gsd-worktree-path-guard', 'git rev-parse --git-dir', gitDirResult);
|
|
157
172
|
if (gitDirResult.status !== 0 || !gitDirResult.stdout) {
|
|
158
|
-
|
|
173
|
+
allow(undefined); // not a git repo — pass through
|
|
159
174
|
}
|
|
160
175
|
|
|
161
176
|
const gitDir = gitDirResult.stdout.trim();
|
|
162
177
|
// A linked worktree's --git-dir contains .git/worktrees/ as a path component
|
|
163
178
|
const isLinkedWorktree = /[/\\]\.git[/\\]worktrees[/\\]/.test(gitDir);
|
|
164
179
|
if (!isLinkedWorktree) {
|
|
165
|
-
|
|
180
|
+
allow(undefined); // main repo, submodule, or separate-git-dir — no-op
|
|
166
181
|
}
|
|
167
182
|
|
|
168
183
|
// #1342: Only enforce inside a GSD-managed isolated executor worktree. Those
|
|
@@ -172,18 +187,20 @@ process.stdin.on('end', () => {
|
|
|
172
187
|
// on the user's own branch, so the guard must be a no-op there. Detached HEAD
|
|
173
188
|
// / error → not GSD-managed → no-op.
|
|
174
189
|
const branchResult = git(['symbolic-ref', '--short', 'HEAD'], cwd);
|
|
190
|
+
reportIfUndetermined('gsd-worktree-path-guard', 'git symbolic-ref --short HEAD', branchResult);
|
|
175
191
|
const branch = branchResult.status === 0 && branchResult.stdout ? branchResult.stdout.trim() : '';
|
|
176
192
|
// #3021: accept worktree-wf_<runid>-<n> branches (Workflow backend's naming).
|
|
177
193
|
if (!/^((worktree-)?agent-|worktree-wf_)[A-Za-z0-9._/-]+$/.test(branch)) {
|
|
178
|
-
|
|
194
|
+
allow(undefined); // not a GSD-managed executor worktree — no-op
|
|
179
195
|
}
|
|
180
196
|
|
|
181
197
|
// Get the raw --show-toplevel output for the worktree (cwd).
|
|
182
198
|
// We keep it raw (not path.resolve'd) to compare directly with the
|
|
183
199
|
// file's toplevel — same git binary, same format, no normalization needed.
|
|
184
200
|
const wtTopResult = git(['rev-parse', '--show-toplevel'], cwd);
|
|
201
|
+
reportIfUndetermined('gsd-worktree-path-guard', 'git rev-parse --show-toplevel (worktree cwd)', wtTopResult);
|
|
185
202
|
if (wtTopResult.status !== 0 || !wtTopResult.stdout) {
|
|
186
|
-
|
|
203
|
+
allow(undefined); // can't determine root — fail open
|
|
187
204
|
}
|
|
188
205
|
const wtTopRaw = wtTopResult.stdout.trim();
|
|
189
206
|
|
|
@@ -201,7 +218,7 @@ process.stdin.on('end', () => {
|
|
|
201
218
|
? data.tool_input.file_path
|
|
202
219
|
: '';
|
|
203
220
|
if (!rawFilePath) {
|
|
204
|
-
|
|
221
|
+
allow(undefined);
|
|
205
222
|
}
|
|
206
223
|
|
|
207
224
|
// Relative paths resolve against the tool's CWD, which is inside the worktree
|
|
@@ -219,7 +236,7 @@ process.stdin.on('end', () => {
|
|
|
219
236
|
// `../`-laden path exits 0 at this line and escapes the worktree. Stating a
|
|
220
237
|
// mechanism and an unverified premise — not asserting a live bypass.
|
|
221
238
|
if (!path.isAbsolute(rawFilePath)) {
|
|
222
|
-
|
|
239
|
+
allow(undefined);
|
|
223
240
|
}
|
|
224
241
|
|
|
225
242
|
// Normalise .. traversal so /worktree/src/../../../main/file
|
|
@@ -244,7 +261,7 @@ process.stdin.on('end', () => {
|
|
|
244
261
|
// Walked to root without finding any directory — path is synthetic.
|
|
245
262
|
// A path with no existing ancestor is not the #260 main-repo vector;
|
|
246
263
|
// #260 is caught by the different-git-root branch below. Fail open. (#1342)
|
|
247
|
-
|
|
264
|
+
allow(undefined);
|
|
248
265
|
}
|
|
249
266
|
|
|
250
267
|
// Ask git for the toplevel of the file's location.
|
|
@@ -254,6 +271,7 @@ process.stdin.on('end', () => {
|
|
|
254
271
|
// back-slash inconsistencies) — both values come from the same git binary
|
|
255
272
|
// in the same format by definition.
|
|
256
273
|
const fileTopResult = git(['rev-parse', '--show-toplevel'], checkDir);
|
|
274
|
+
reportIfUndetermined('gsd-worktree-path-guard', 'git rev-parse --show-toplevel (file location)', fileTopResult);
|
|
257
275
|
|
|
258
276
|
if (fileTopResult.status !== 0 || !fileTopResult.stdout) {
|
|
259
277
|
// The target's location is not a git work tree. Two sub-cases:
|
|
@@ -263,6 +281,7 @@ process.stdin.on('end', () => {
|
|
|
263
281
|
// - Truly outside all git repositories (e.g. ~/.claude/plans/) → not the
|
|
264
282
|
// main-repo vector → fail open. (#1342)
|
|
265
283
|
const insideGitDir = git(['rev-parse', '--is-inside-git-dir'], checkDir);
|
|
284
|
+
reportIfUndetermined('gsd-worktree-path-guard', 'git rev-parse --is-inside-git-dir', insideGitDir);
|
|
266
285
|
if (insideGitDir.status === 0 && insideGitDir.stdout && insideGitDir.stdout.trim() === 'true') {
|
|
267
286
|
const output = {
|
|
268
287
|
decision: 'block',
|
|
@@ -271,20 +290,17 @@ process.stdin.on('end', () => {
|
|
|
271
290
|
`not the active worktree at '${wtTopRaw}'. Writing to repository internals via an ` +
|
|
272
291
|
`absolute path is not permitted from an isolated executor worktree. Use a relative path.`,
|
|
273
292
|
};
|
|
274
|
-
|
|
275
|
-
// Kimi feeds stderr (not stdout) back to the model on exit 2.
|
|
276
|
-
process.stderr.write(output.reason);
|
|
277
|
-
process.exit(2);
|
|
293
|
+
deny(output, output.reason);
|
|
278
294
|
}
|
|
279
295
|
// Outside all git repositories — fail open (#1342).
|
|
280
|
-
|
|
296
|
+
allow(undefined);
|
|
281
297
|
}
|
|
282
298
|
|
|
283
299
|
const fileTopRaw = fileTopResult.stdout.trim();
|
|
284
300
|
|
|
285
301
|
// Same git toplevel → file is inside the worktree → allow
|
|
286
302
|
if (fileTopRaw === wtTopRaw) {
|
|
287
|
-
|
|
303
|
+
allow(undefined);
|
|
288
304
|
}
|
|
289
305
|
|
|
290
306
|
// BLOCK: file resolves to a different git root than the active worktree
|
|
@@ -299,12 +315,11 @@ process.stdin.on('end', () => {
|
|
|
299
315
|
`(hook cwd: '${cwd}').`,
|
|
300
316
|
};
|
|
301
317
|
|
|
302
|
-
|
|
303
|
-
// Kimi feeds stderr (not stdout) back to the model on exit 2.
|
|
304
|
-
process.stderr.write(output.reason);
|
|
305
|
-
process.exit(2);
|
|
318
|
+
deny(output, output.reason);
|
|
306
319
|
} catch {
|
|
307
|
-
// Silent fail — never block valid tool calls due to hook errors
|
|
308
|
-
|
|
320
|
+
// Silent fail — never block valid tool calls due to hook errors.
|
|
321
|
+
// ON_CRASH is declared ALLOW at module top: this preserves today's
|
|
322
|
+
// exit(0) fail-open behavior exactly (#3911).
|
|
323
|
+
crash(ON_CRASH, undefined);
|
|
309
324
|
}
|
|
310
325
|
});
|
|
@@ -75,6 +75,21 @@
|
|
|
75
75
|
|
|
76
76
|
const fs = require('fs');
|
|
77
77
|
const path = require('path');
|
|
78
|
+
const { HOOK_ON_CRASH, allow, deny, crash } = require('./lib/hook-exit.js');
|
|
79
|
+
|
|
80
|
+
// This guard's outer catch has always exited 0 (fail open — a hook error
|
|
81
|
+
// must never block a legitimate tool call; see the emitBlock/consumeSentinelFor
|
|
82
|
+
// header comments). Declared ONCE here so the outer catch's crash() call
|
|
83
|
+
// states its policy explicitly rather than inheriting a default (#3911).
|
|
84
|
+
const ON_CRASH = HOOK_ON_CRASH.ALLOW;
|
|
85
|
+
|
|
86
|
+
// #3911 (ADR-3889 Phase 7) NOTE: the exit(2) call site (emitBlock, below) is
|
|
87
|
+
// migrated to hooks/lib/hook-exit.js's deny(), using its `stderrPayload`
|
|
88
|
+
// param (added for exactly this site): fd 1 still gets the full JSON
|
|
89
|
+
// `output`, fd 2 gets ONLY the plain-text `output.reason` string — because
|
|
90
|
+
// Kimi's native hook bus reads stderr verbatim back to the model, and a raw
|
|
91
|
+
// JSON-stringified object on stderr is not the same reason text a model
|
|
92
|
+
// should read. Byte-identical to the pre-migration emitBlock.
|
|
78
93
|
|
|
79
94
|
// Block when the pending payload has fewer than this fraction of the on-disk
|
|
80
95
|
// line count (0.4 → a Write shrinking a file below 40% of its current size).
|
|
@@ -158,20 +173,13 @@ function consumeSentinelFor(filePath, normalized) {
|
|
|
158
173
|
|
|
159
174
|
// m2 (round 5): the block emission must itself be exception-safe. An EPIPE
|
|
160
175
|
// from writeSync inside the outer try would land in the fail-OPEN catch —
|
|
161
|
-
// the one outcome the fail-closed branches exist to prevent.
|
|
162
|
-
//
|
|
176
|
+
// the one outcome the fail-closed branches exist to prevent. terminateNow
|
|
177
|
+
// (via deny()) already guarantees this: a failed write never changes the
|
|
178
|
+
// exit code and never throws out of the call. `output.reason` is passed as
|
|
179
|
+
// the distinct stderrPayload so fd 2 gets the plain reason string — not the
|
|
180
|
+
// full JSON `output` fd 1 gets — matching the pre-migration byte-for-byte.
|
|
163
181
|
function emitBlock(output) {
|
|
164
|
-
|
|
165
|
-
// writeSync: pipe writes via process.stdout/stderr are async on Windows
|
|
166
|
-
// and process.exit() does not flush them — a truncated block payload is
|
|
167
|
-
// a guard that silently half-fired.
|
|
168
|
-
fs.writeSync(1, JSON.stringify(output));
|
|
169
|
-
// Kimi feeds stderr (not stdout) back to the model on exit 2.
|
|
170
|
-
fs.writeSync(2, output.reason);
|
|
171
|
-
} catch {
|
|
172
|
-
// Emission failed; the block still stands.
|
|
173
|
-
}
|
|
174
|
-
process.exit(2);
|
|
182
|
+
deny(output, output.reason);
|
|
175
183
|
}
|
|
176
184
|
|
|
177
185
|
// #2304: Kimi's native hook bus delivers Kimi's tool vocabulary in the payload
|
|
@@ -223,7 +231,7 @@ function normalizeKimiPayload(data) {
|
|
|
223
231
|
}
|
|
224
232
|
|
|
225
233
|
let input = '';
|
|
226
|
-
const stdinTimeout = setTimeout(() =>
|
|
234
|
+
const stdinTimeout = setTimeout(() => allow(undefined), 3000);
|
|
227
235
|
process.stdin.setEncoding('utf8');
|
|
228
236
|
process.stdin.on('data', chunk => input += chunk);
|
|
229
237
|
process.stdin.on('end', () => {
|
|
@@ -234,17 +242,17 @@ process.stdin.on('end', () => {
|
|
|
234
242
|
// A null/primitive payload has nothing to guard — exit deliberately
|
|
235
243
|
// rather than throwing into the fail-open catch below (#2595 class).
|
|
236
244
|
if (data === null || typeof data !== 'object') {
|
|
237
|
-
|
|
245
|
+
allow(undefined);
|
|
238
246
|
}
|
|
239
247
|
|
|
240
248
|
// Only whole-file Write is catastrophic-by-construction; Edit/MultiEdit
|
|
241
249
|
// replace bounded spans and are out of scope by design (#2255).
|
|
242
250
|
if (data.tool_name !== 'Write') {
|
|
243
|
-
|
|
251
|
+
allow(undefined);
|
|
244
252
|
}
|
|
245
253
|
|
|
246
254
|
if (isOverrideSet()) {
|
|
247
|
-
|
|
255
|
+
allow(undefined); // documented escape hatch — legitimate reset in progress
|
|
248
256
|
}
|
|
249
257
|
|
|
250
258
|
// Typed read (#2547 class): `[]`/`{}` are truthy, pass a `!value`
|
|
@@ -254,7 +262,7 @@ process.stdin.on('end', () => {
|
|
|
254
262
|
const rawFilePath = typeof rawInput?.file_path === 'string' ? rawInput.file_path : '';
|
|
255
263
|
const content = rawInput?.content;
|
|
256
264
|
if (!rawFilePath || typeof content !== 'string') {
|
|
257
|
-
|
|
265
|
+
allow(undefined);
|
|
258
266
|
}
|
|
259
267
|
|
|
260
268
|
// Resolve relative paths against the session cwd (the same base the
|
|
@@ -272,7 +280,7 @@ process.stdin.on('end', () => {
|
|
|
272
280
|
const normalized = filePath.replace(/\\/g, '/');
|
|
273
281
|
|
|
274
282
|
if (!CURATED_PATTERNS.some(re => re.test(normalized))) {
|
|
275
|
-
|
|
283
|
+
allow(undefined); // not a curated planning artifact
|
|
276
284
|
}
|
|
277
285
|
|
|
278
286
|
// Only guard overwrites — creating a curated file fresh is fine.
|
|
@@ -285,7 +293,7 @@ process.stdin.on('end', () => {
|
|
|
285
293
|
onDisk = fs.readFileSync(filePath, 'utf8');
|
|
286
294
|
} catch (err) {
|
|
287
295
|
if (err && err.code === 'ENOENT') {
|
|
288
|
-
|
|
296
|
+
allow(undefined); // does not exist — new-file Write, nothing to clobber
|
|
289
297
|
}
|
|
290
298
|
emitBlock({
|
|
291
299
|
decision: 'block',
|
|
@@ -306,17 +314,17 @@ process.stdin.on('end', () => {
|
|
|
306
314
|
const newLines = countLines(content);
|
|
307
315
|
|
|
308
316
|
if (oldLines < FLOOR_LINES) {
|
|
309
|
-
|
|
317
|
+
allow(undefined); // sub-floor stub — ratio checks are meaningless here
|
|
310
318
|
}
|
|
311
319
|
|
|
312
320
|
if (newLines >= oldLines * SHRINK_RATIO) {
|
|
313
|
-
|
|
321
|
+
allow(undefined); // shrink (if any) is within tolerance
|
|
314
322
|
}
|
|
315
323
|
|
|
316
324
|
// The mechanical hatch for workflow steps (see header): consulted only
|
|
317
325
|
// here, at the block point, so a within-tolerance write never burns it.
|
|
318
326
|
if (consumeSentinelFor(filePath, normalized)) {
|
|
319
|
-
|
|
327
|
+
allow(undefined); // armed for exactly this file, fresh, now consumed
|
|
320
328
|
}
|
|
321
329
|
|
|
322
330
|
const pct = Math.round((newLines / oldLines) * 100);
|
|
@@ -353,7 +361,9 @@ process.stdin.on('end', () => {
|
|
|
353
361
|
`to bypass this guard once.`,
|
|
354
362
|
});
|
|
355
363
|
} catch {
|
|
356
|
-
// Silent fail — never block valid tool calls due to hook errors
|
|
357
|
-
|
|
364
|
+
// Silent fail — never block valid tool calls due to hook errors.
|
|
365
|
+
// ON_CRASH is declared ALLOW at module top: this preserves today's
|
|
366
|
+
// exit(0) fail-open behavior exactly (#3911).
|
|
367
|
+
crash(ON_CRASH, undefined);
|
|
358
368
|
}
|
|
359
369
|
});
|