@opengsd/gsd-core 1.7.0 → 1.9.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 +45 -1
- package/README.md +2 -0
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-codebase-mapper.md +1 -1
- package/agents/gsd-debug-session-manager.md +78 -4
- package/agents/gsd-debugger.md +87 -29
- package/agents/gsd-executor.md +49 -9
- package/agents/gsd-intel-updater.md +3 -3
- package/agents/gsd-phase-researcher.md +4 -2
- package/agents/gsd-plan-checker.md +20 -0
- package/agents/gsd-planner.md +44 -59
- package/agents/gsd-project-researcher.md +2 -2
- package/agents/gsd-ui-auditor.md +0 -40
- package/agents/gsd-verifier.md +2 -2
- package/bin/install.js +1338 -135
- package/commands/gsd/ai-integration-phase.md +1 -1
- package/commands/gsd/mempalace-capture.md +9 -5
- package/commands/gsd/new-milestone.md +1 -1
- package/commands/gsd/plan-phase.md +5 -3
- package/commands/gsd/plan-review-convergence.md +7 -2
- package/gsd-core/bin/gsd-tools.cjs +2690 -2472
- package/gsd-core/bin/lib/adapter-imperative.cjs +8 -1
- package/gsd-core/bin/lib/agent-command-router.cjs +20 -5
- package/gsd-core/bin/lib/api-coverage.cjs +360 -53
- package/gsd-core/bin/lib/audit.cjs +8 -8
- package/gsd-core/bin/lib/broken-windows.cjs +716 -0
- package/gsd-core/bin/lib/capability-command-router.cjs +733 -0
- package/gsd-core/bin/lib/capability-consent.cjs +40 -1
- package/gsd-core/bin/lib/capability-lifecycle.cjs +58 -0
- package/gsd-core/bin/lib/capability-loader.cjs +23 -1
- package/gsd-core/bin/lib/capability-registry.cjs +1450 -160
- package/gsd-core/bin/lib/capability-trust.cjs +468 -33
- package/gsd-core/bin/lib/capability-validator.cjs +882 -6
- package/gsd-core/bin/lib/capability-writer.cjs +6 -1
- package/gsd-core/bin/lib/check-command-router.cjs +140 -27
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +15 -0
- package/gsd-core/bin/lib/claude-orchestration-command-router.cjs +209 -31
- package/gsd-core/bin/lib/claude-orchestration.cjs +203 -25
- package/gsd-core/bin/lib/command-aliases.cjs +14 -0
- package/gsd-core/bin/lib/commands.cjs +326 -21
- package/gsd-core/bin/lib/config-loader.cjs +214 -30
- package/gsd-core/bin/lib/config.cjs +158 -22
- package/gsd-core/bin/lib/core-utils.cjs +6 -1
- package/gsd-core/bin/lib/decisions.cjs +32 -8
- package/gsd-core/bin/lib/docs.cjs +6 -0
- package/gsd-core/bin/lib/estimate-cli.cjs +336 -0
- package/gsd-core/bin/lib/external-descriptor-trust.cjs +14 -2
- package/gsd-core/bin/lib/frontmatter.cjs +125 -15
- package/gsd-core/bin/lib/gap-checker.cjs +17 -2
- package/gsd-core/bin/lib/host-integration.cjs +215 -8
- package/gsd-core/bin/lib/init.cjs +155 -66
- package/gsd-core/bin/lib/install-engine.cjs +299 -23
- package/gsd-core/bin/lib/install-profiles.cjs +239 -1
- package/gsd-core/bin/lib/installer-migrations/005-opencode-baseline-commands-dir.cjs +146 -0
- package/gsd-core/bin/lib/installer-migrations/006-pi-extension-cjs-to-js.cjs +91 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +44 -5
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +107 -0
- package/gsd-core/bin/lib/milestone.cjs +248 -14
- package/gsd-core/bin/lib/model-catalog.cjs +69 -4
- package/gsd-core/bin/lib/model-resolver.cjs +189 -7
- package/gsd-core/bin/lib/observability/logger.cjs +7 -2
- package/gsd-core/bin/lib/onboard-projection.cjs +11 -8
- package/gsd-core/bin/lib/phase-command-router.cjs +10 -1
- package/gsd-core/bin/lib/phase-estimation.cjs +398 -0
- package/gsd-core/bin/lib/phase-id.cjs +304 -9
- package/gsd-core/bin/lib/phase.cjs +258 -17
- package/gsd-core/bin/lib/plan-drift-guard.cjs +1 -1
- package/gsd-core/bin/lib/plan-scan.cjs +70 -2
- package/gsd-core/bin/lib/planning-workspace.cjs +9 -2
- package/gsd-core/bin/lib/profile-output.cjs +34 -8
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +927 -0
- package/gsd-core/bin/lib/review-lane-invocation.cjs +348 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +594 -0
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +114 -32
- package/gsd-core/bin/lib/roadmap-parser.cjs +61 -10
- package/gsd-core/bin/lib/roadmap.cjs +23 -7
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +38 -5
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +23 -9
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +156 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +15 -2
- package/gsd-core/bin/lib/smart-entry.cjs +70 -5
- package/gsd-core/bin/lib/state-document.cjs +171 -24
- package/gsd-core/bin/lib/state-transition.cjs +50 -11
- package/gsd-core/bin/lib/state.cjs +206 -32
- package/gsd-core/bin/lib/surface.cjs +51 -9
- package/gsd-core/bin/lib/uat-predicate.cjs +6 -4
- package/gsd-core/bin/lib/uat.cjs +428 -11
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +2 -2
- package/gsd-core/bin/lib/unusable-input.cjs +216 -0
- package/gsd-core/bin/lib/validate.cjs +44 -8
- package/gsd-core/bin/lib/verification.cjs +163 -31
- package/gsd-core/bin/lib/verify.cjs +348 -42
- package/gsd-core/bin/lib/worktree-safety.cjs +360 -15
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +4 -15
- package/gsd-core/bin/shared/model-catalog.json +5 -0
- package/gsd-core/bin/shared/runtime-aliases.manifest.json +5 -0
- package/gsd-core/references/api-coverage.md +37 -7
- package/gsd-core/references/checkpoints.md +1 -1
- package/gsd-core/references/common-bug-patterns.md +13 -0
- package/gsd-core/references/context-budget.md +40 -0
- package/gsd-core/references/debugger-bug-taxonomy.md +111 -0
- package/gsd-core/references/debugger-fix-acceptance.md +157 -0
- package/gsd-core/references/debugger-philosophy.md +1 -0
- package/gsd-core/references/debugger-prevention.md +98 -0
- package/gsd-core/references/debugger-rca-branching.md +98 -0
- package/gsd-core/references/debugger-repro-hardening.md +130 -0
- package/gsd-core/references/debugger-sbfl.md +110 -0
- package/gsd-core/references/debugger-semantic-recall.md +81 -0
- package/gsd-core/references/execute-phase-quota-recovery.md +55 -0
- package/gsd-core/references/execute-phase-requirement-revert.md +8 -0
- package/gsd-core/references/execute-phase-response-language.md +7 -0
- package/gsd-core/references/gate-prompts.md +6 -3
- package/gsd-core/references/model-profile-resolution.md +64 -13
- package/gsd-core/references/offer-next.md +88 -0
- package/gsd-core/references/planner-antipatterns.md +6 -0
- package/gsd-core/references/planner-mvp-mode.md +12 -13
- package/gsd-core/references/planner-preconditions.md +156 -0
- package/gsd-core/references/planner-reversibility.md +132 -0
- package/gsd-core/references/planning-config.md +2 -1
- package/gsd-core/references/reviewer-instances.md +28 -19
- package/gsd-core/references/runtime-aware-dispatch.md +42 -0
- package/gsd-core/references/skeleton-template.md +1 -1
- package/gsd-core/references/thinking-models-planning.md +3 -1
- package/gsd-core/references/ui-consideration-probe.md +2 -2
- package/gsd-core/references/worktree-branch-check.md +4 -4
- package/gsd-core/templates/DEBUG.md +5 -3
- package/gsd-core/templates/summary-minimal.md +4 -0
- package/gsd-core/templates/summary-standard.md +4 -0
- package/gsd-core/templates/summary.md +7 -0
- package/gsd-core/workflows/add-phase.md +2 -0
- package/gsd-core/workflows/add-tests.md +3 -1
- package/gsd-core/workflows/add-todo.md +32 -1
- package/gsd-core/workflows/ai-integration-phase.md +8 -6
- package/gsd-core/workflows/audit-fix.md +6 -2
- package/gsd-core/workflows/audit-milestone.md +8 -0
- package/gsd-core/workflows/autonomous.md +19 -15
- package/gsd-core/workflows/check-todos.md +5 -3
- package/gsd-core/workflows/cleanup.md +7 -1
- package/gsd-core/workflows/code-review-fix.md +14 -6
- package/gsd-core/workflows/code-review.md +93 -24
- package/gsd-core/workflows/complete-milestone.md +3 -0
- package/gsd-core/workflows/debug.md +35 -7
- package/gsd-core/workflows/diagnose-issues.md +5 -1
- package/gsd-core/workflows/discovery-phase.md +7 -0
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -4
- package/gsd-core/workflows/discuss-phase/modes/auto.md +0 -6
- package/gsd-core/workflows/discuss-phase/templates/context.md +16 -2
- package/gsd-core/workflows/discuss-phase-assumptions.md +18 -9
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/do.md +7 -1
- package/gsd-core/workflows/docs-update.md +9 -0
- package/gsd-core/workflows/eval-review.md +4 -1
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +4 -0
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +160 -0
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +4 -4
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -2
- package/gsd-core/workflows/execute-phase.md +110 -149
- package/gsd-core/workflows/execute-plan.md +20 -8
- package/gsd-core/workflows/explore.md +4 -0
- package/gsd-core/workflows/extract-learnings.md +21 -0
- package/gsd-core/workflows/graduation.md +3 -0
- package/gsd-core/workflows/health.md +7 -1
- package/gsd-core/workflows/help/modes/full.md +9 -5
- package/gsd-core/workflows/import.md +11 -2
- package/gsd-core/workflows/inbox.md +7 -0
- package/gsd-core/workflows/ingest-docs.md +19 -10
- package/gsd-core/workflows/manager.md +3 -1
- package/gsd-core/workflows/map-codebase.md +17 -10
- package/gsd-core/workflows/mvp-phase.md +3 -0
- package/gsd-core/workflows/new-milestone.md +79 -23
- package/gsd-core/workflows/new-project.md +28 -19
- package/gsd-core/workflows/new-workspace.md +3 -1
- package/gsd-core/workflows/next.md +5 -2
- package/gsd-core/workflows/onboard.md +3 -0
- package/gsd-core/workflows/plan-phase.md +56 -51
- package/gsd-core/workflows/plan-review-convergence.md +61 -12
- package/gsd-core/workflows/plant-seed.md +3 -0
- package/gsd-core/workflows/profile-user.md +7 -1
- package/gsd-core/workflows/progress.md +31 -3
- package/gsd-core/workflows/quick.md +33 -10
- package/gsd-core/workflows/remove-workspace.md +3 -0
- package/gsd-core/workflows/review.md +172 -585
- package/gsd-core/workflows/scan.md +10 -2
- package/gsd-core/workflows/secure-phase.md +13 -2
- package/gsd-core/workflows/settings-integrations.md +3 -0
- package/gsd-core/workflows/settings.md +3 -0
- package/gsd-core/workflows/ship.md +88 -11
- package/gsd-core/workflows/sketch.md +3 -0
- package/gsd-core/workflows/smart-entry.md +4 -1
- package/gsd-core/workflows/spike.md +7 -1
- package/gsd-core/workflows/ui-phase.md +11 -2
- package/gsd-core/workflows/ui-review.md +11 -1
- package/gsd-core/workflows/undo.md +7 -0
- package/gsd-core/workflows/update.md +106 -5
- package/gsd-core/workflows/validate-phase.md +13 -2
- package/gsd-core/workflows/verify-phase.md +2 -2
- package/gsd-core/workflows/verify-work.md +15 -4
- package/hooks/dist/gsd-context-monitor.js +27 -9
- package/hooks/dist/gsd-cursor-session-start.js +6 -2
- package/hooks/dist/gsd-cursor-stop.js +6 -2
- package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
- package/hooks/dist/gsd-graphify-update.sh +9 -0
- package/hooks/dist/gsd-phase-boundary.sh +14 -2
- package/hooks/dist/gsd-prompt-guard.js +101 -2
- package/hooks/dist/gsd-read-guard.js +100 -2
- package/hooks/dist/gsd-read-injection-scanner.js +109 -2
- package/hooks/dist/gsd-statusline.js +97 -9
- package/hooks/dist/gsd-workflow-guard.js +110 -6
- package/hooks/dist/gsd-worktree-path-guard.js +132 -8
- package/hooks/dist/lib/cursor-workspace.js +74 -0
- package/hooks/gsd-context-monitor.js +27 -9
- package/hooks/gsd-cursor-session-start.js +6 -2
- package/hooks/gsd-cursor-stop.js +6 -2
- package/hooks/gsd-cursor-subagent-start.js +6 -2
- package/hooks/gsd-graphify-update.sh +9 -0
- package/hooks/gsd-phase-boundary.sh +14 -2
- package/hooks/gsd-prompt-guard.js +101 -2
- package/hooks/gsd-read-guard.js +100 -2
- package/hooks/gsd-read-injection-scanner.js +109 -2
- package/hooks/gsd-statusline.js +97 -9
- package/hooks/gsd-workflow-guard.js +110 -6
- package/hooks/gsd-worktree-path-guard.js +132 -8
- package/hooks/lib/cursor-workspace.js +74 -0
- package/package.json +10 -8
- package/pi/gsd.cjs +34 -3
- package/scripts/changeset/lint.cjs +1 -0
- package/scripts/changeset/parse.cjs +26 -0
- package/scripts/check-coverage-gate.cjs +51 -0
- package/scripts/check-glossary-refs.cjs +244 -0
- package/scripts/ci-rebase-check.cjs +48 -4
- package/scripts/ci-test-scope.cjs +67 -17
- package/scripts/gen-adr-index.cjs +528 -0
- package/scripts/gen-capability-matrix.cjs +26 -2
- package/scripts/gen-capability-registry.cjs +132 -34
- package/scripts/gen-emitted-baseline.cjs +145 -0
- package/scripts/gen-test-timings.cjs +201 -0
- package/scripts/lint-compiled-artifact-sync.cjs +146 -0
- package/scripts/lint-emitted-drift-ack.cjs +149 -0
- package/scripts/lint-fix-has-regression-test.cjs +131 -0
- package/scripts/lint-portable-timeout.cjs +140 -0
- package/scripts/lint-resolution-provenance.cjs +9 -0
- package/scripts/lint-test-file-count.allowlist.json +1 -0
- package/scripts/mutation-matrix.cjs +4 -0
- package/scripts/prompt-injection-scan.sh +6 -0
- package/scripts/registry-schema.cjs +57 -8
- package/scripts/release-notes/conventional-title.cjs +19 -1
- package/scripts/release-notes/format-github-release-notes.cjs +7 -3
- package/scripts/release-tarball-smoke.cjs +18 -11
- package/scripts/run-tests.cjs +420 -58
- package/scripts/workflow-size.cjs +16 -8
- package/skills/gsd-ai-integration-phase/SKILL.md +1 -1
- package/skills/gsd-mempalace-capture/SKILL.md +9 -5
- package/skills/gsd-new-milestone/SKILL.md +1 -1
- package/skills/gsd-plan-phase/SKILL.md +5 -3
- package/skills/gsd-plan-review-convergence/SKILL.md +7 -2
- package/vscode/package.json +1 -1
- package/scripts/gen-golden-install-parity-zcode.cjs +0 -77
- package/scripts/update-size-baseline.cjs +0 -68
|
@@ -11,12 +11,17 @@
|
|
|
11
11
|
* epic #1267; callers import resolvers from model-resolver.cjs directly.
|
|
12
12
|
*
|
|
13
13
|
* Dependencies (leaf modules only):
|
|
14
|
-
* - node:fs / node:path (
|
|
14
|
+
* - node:fs / node:path (read the per-install .gsd-runtime marker + project config for the #2297 omit gate)
|
|
15
|
+
* - ./runtime-name-policy.cjs (resolveRuntimeNameFromCandidates — canonicalize the active runtime)
|
|
16
|
+
* - ./planning-workspace.cjs (planningDir — workstream/project-aware project-config path)
|
|
15
17
|
* - ./config-loader.cjs (loadConfig)
|
|
16
18
|
* - ./configuration.cjs (CONFIG_DEFAULTS as CANONICAL_CONFIG_DEFAULTS)
|
|
17
19
|
* - ./model-profiles.cjs (MODEL_PROFILES, AGENT_TO_PHASE_TYPE, AGENT_DEFAULT_TIERS, VALID_AGENT_TIERS, nextTier)
|
|
18
|
-
* - ./model-catalog.cjs (MODEL_ALIAS_MAP, RUNTIME_PROFILE_MAP, PROVIDER_PRESETS)
|
|
20
|
+
* - ./model-catalog.cjs (MODEL_ALIAS_MAP, RUNTIME_PROFILE_MAP, PROVIDER_PRESETS, VALID_TIERS)
|
|
19
21
|
*/
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
20
25
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
26
|
const configLoaderModule = require("./config-loader.cjs");
|
|
22
27
|
const { loadConfig } = configLoaderModule;
|
|
@@ -26,6 +31,92 @@ const configuration_cjs_1 = require("./configuration.cjs");
|
|
|
26
31
|
const modelProfiles = require("./model-profiles.cjs");
|
|
27
32
|
const { MODEL_PROFILES, AGENT_TO_PHASE_TYPE, AGENT_DEFAULT_TIERS, VALID_AGENT_TIERS, nextTier } = modelProfiles;
|
|
28
33
|
const model_catalog_cjs_1 = require("./model-catalog.cjs");
|
|
34
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
35
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
36
|
+
const runtime_name_policy_cjs_1 = require("./runtime-name-policy.cjs");
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
|
+
const planningWorkspaceMod = require("./planning-workspace.cjs");
|
|
39
|
+
const { planningDir } = planningWorkspaceMod;
|
|
40
|
+
// ─── #2297: per-install runtime identity for the resolve_model_ids:"omit" gate ─
|
|
41
|
+
//
|
|
42
|
+
// The installer writes `resolve_model_ids:"omit"` into the SHARED
|
|
43
|
+
// ~/.gsd/defaults.json for every runtime that lacks native model aliases (#1156).
|
|
44
|
+
// Because that file is machine-wide, a non-Claude install would otherwise poison
|
|
45
|
+
// a Claude no-project resolution into returning '' — silently defeating Claude's
|
|
46
|
+
// adaptive tier aliases. The "omit" must therefore apply only when a runtime that
|
|
47
|
+
// genuinely lacks native aliases is the one resolving.
|
|
48
|
+
//
|
|
49
|
+
// In a no-project session there is no `.planning/config.json` (so config.runtime
|
|
50
|
+
// is null) and GSD_RUNTIME is not exported by gsd-core, so the only reliable
|
|
51
|
+
// current-runtime signal is the per-install marker the installer co-locates next
|
|
52
|
+
// to VERSION at <install>/gsd-core/.gsd-runtime (this file's dir is
|
|
53
|
+
// <install>/gsd-core/bin/lib). Precedence for the gate: project config.runtime →
|
|
54
|
+
// GSD_RUNTIME env (manual/CI override + test seam) → install marker → 'claude'.
|
|
55
|
+
//
|
|
56
|
+
// `claude` is currently the ONLY runtime with nativeModelAliases:true; a
|
|
57
|
+
// registry-parity test guards this set so a future alias-capable runtime fails
|
|
58
|
+
// loudly here instead of silently omitting.
|
|
59
|
+
const RUNTIMES_WITH_NATIVE_ALIASES = new Set(['claude']);
|
|
60
|
+
let _installMarkerCache;
|
|
61
|
+
function readInstallRuntimeMarker() {
|
|
62
|
+
if (_installMarkerCache !== undefined)
|
|
63
|
+
return _installMarkerCache;
|
|
64
|
+
try {
|
|
65
|
+
const markerPath = node_path_1.default.join(__dirname, '..', '..', '.gsd-runtime');
|
|
66
|
+
const raw = node_fs_1.default.readFileSync(markerPath, 'utf8').trim();
|
|
67
|
+
_installMarkerCache = raw || null;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// No marker: dev/source tree, or an install predating #2297. Fall through to
|
|
71
|
+
// the 'claude' default (keeps tier aliases — never worse than the bug).
|
|
72
|
+
_installMarkerCache = null;
|
|
73
|
+
}
|
|
74
|
+
return _installMarkerCache;
|
|
75
|
+
}
|
|
76
|
+
// Test seams for the install-marker rung (the dev/source tree has no marker, so
|
|
77
|
+
// the file read always bottoms out at 'claude' — these let tests exercise the
|
|
78
|
+
// third precedence rung and reset the module-level cache between cases).
|
|
79
|
+
function _setInstallRuntimeMarkerForTests(value) {
|
|
80
|
+
_installMarkerCache = value;
|
|
81
|
+
}
|
|
82
|
+
function _resetInstallRuntimeMarkerCacheForTests() {
|
|
83
|
+
_installMarkerCache = undefined;
|
|
84
|
+
}
|
|
85
|
+
// The runtime whose install is actually resolving, canonicalized so an alias or
|
|
86
|
+
// case variant (e.g. "claude-code"/"Claude") cannot defeat the native-alias
|
|
87
|
+
// check below (#2297 review). Precedence mirrors resolveRuntime()
|
|
88
|
+
// (runtime-slash.cts): GSD_RUNTIME env → project config.runtime → per-install
|
|
89
|
+
// .gsd-runtime marker → 'claude'.
|
|
90
|
+
function resolveActiveRuntime(config) {
|
|
91
|
+
return (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(process.env['GSD_RUNTIME'], config['runtime'], readInstallRuntimeMarker()) || 'claude';
|
|
92
|
+
}
|
|
93
|
+
// Did the PROJECT's own config (root `.planning/config.json` or the active
|
|
94
|
+
// workstream/project override) explicitly set resolve_model_ids to "omit"?
|
|
95
|
+
// Project config takes precedence over the shared ~/.gsd/defaults.json (#2297
|
|
96
|
+
// out-of-scope guard + #2517 finding #4): an explicit project "omit" is honored
|
|
97
|
+
// regardless of runtime, whereas an "omit" that came only from the global
|
|
98
|
+
// defaults is ignored by native-alias runtimes. Workstream/project-scope aware
|
|
99
|
+
// via planningDir (mirrors loadConfig's precedence: workstream value wins over
|
|
100
|
+
// root); a plain read avoids loadConfig's normalization side effects.
|
|
101
|
+
function projectExplicitlySetsOmit(cwd) {
|
|
102
|
+
const wsDir = planningDir(cwd);
|
|
103
|
+
const rootDir = node_path_1.default.join(cwd, '.planning');
|
|
104
|
+
const layers = wsDir === rootDir ? [rootDir] : [wsDir, rootDir]; // workstream > root
|
|
105
|
+
for (const dir of layers) {
|
|
106
|
+
try {
|
|
107
|
+
const parsed = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(dir, 'config.json'), 'utf8'));
|
|
108
|
+
const value = parsed?.['resolve_model_ids'];
|
|
109
|
+
// First layer that sets the key wins (matches loadConfig's deep-merge
|
|
110
|
+
// precedence). A layer that omits the key falls through to the next.
|
|
111
|
+
if (value !== undefined)
|
|
112
|
+
return value === 'omit';
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Absent/unreadable layer — try the next.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
29
120
|
/**
|
|
30
121
|
* #2517 — Resolve the runtime-aware tier entry for (runtime, tier).
|
|
31
122
|
*/
|
|
@@ -209,8 +300,7 @@ function resolveModelInternal(cwd, agentType) {
|
|
|
209
300
|
const phaseTypeTier = (phaseType && configModels && typeof configModels === 'object')
|
|
210
301
|
? configModels[phaseType]
|
|
211
302
|
: undefined;
|
|
212
|
-
const
|
|
213
|
-
const tier = (phaseTypeTier && VALID_TIERS.has(phaseTypeTier))
|
|
303
|
+
const tier = (phaseTypeTier && model_catalog_cjs_1.VALID_TIERS.has(phaseTypeTier))
|
|
214
304
|
? phaseTypeTier
|
|
215
305
|
: (profile === 'inherit'
|
|
216
306
|
? 'inherit'
|
|
@@ -248,8 +338,18 @@ function resolveModelInternal(cwd, agentType) {
|
|
|
248
338
|
if (entry?.model)
|
|
249
339
|
return entry.model;
|
|
250
340
|
}
|
|
251
|
-
// 4. resolve_model_ids: "omit"
|
|
252
|
-
|
|
341
|
+
// 4. resolve_model_ids: "omit" — runtime-aware (#2297). Honor "omit" when the
|
|
342
|
+
// PROJECT explicitly set it (user intent — project config wins, #2517 finding
|
|
343
|
+
// #4) OR when the active runtime genuinely lacks native model aliases. Only a
|
|
344
|
+
// native-alias runtime (Claude) ignores an "omit" that came solely from the
|
|
345
|
+
// SHARED ~/.gsd/defaults.json — the #2297 poisoning fix — and falls through to
|
|
346
|
+
// its tier aliases below. Active runtime: GSD_RUNTIME → config.runtime → the
|
|
347
|
+
// per-install .gsd-runtime marker → 'claude' (canonicalized).
|
|
348
|
+
// NOTE: a non-Claude runtime that HAS a populated runtime-tier map already
|
|
349
|
+
// returned its own model id at step 3 above, before this gate — for those the
|
|
350
|
+
// explicit-project-omit honoring here is moot (step 3 wins, by #2517 design).
|
|
351
|
+
if (config['resolve_model_ids'] === 'omit'
|
|
352
|
+
&& (projectExplicitlySetsOmit(cwd) || !RUNTIMES_WITH_NATIVE_ALIASES.has(resolveActiveRuntime(config)))) {
|
|
253
353
|
return '';
|
|
254
354
|
}
|
|
255
355
|
// 5. Profile lookup (Claude-native default).
|
|
@@ -262,7 +362,11 @@ function resolveModelInternal(cwd, agentType) {
|
|
|
262
362
|
if (tier === 'inherit')
|
|
263
363
|
return 'inherit';
|
|
264
364
|
const alias = tier;
|
|
265
|
-
|
|
365
|
+
// Only the explicit `true` opt-in materializes full model IDs (#1569). Guard
|
|
366
|
+
// against the loose-truthy check catching a "omit" that a native-alias runtime
|
|
367
|
+
// ignored above (#2297): "omit" must fall through to the tier ALIAS here, not
|
|
368
|
+
// be materialized into a full ID Claude's Agent tool cannot spawn.
|
|
369
|
+
if (config['resolve_model_ids'] === true) {
|
|
266
370
|
return model_catalog_cjs_1.MODEL_ALIAS_MAP[alias] || alias;
|
|
267
371
|
}
|
|
268
372
|
return alias;
|
|
@@ -353,6 +457,80 @@ function resolveModelForTier(cwd, agentType, attempt) {
|
|
|
353
457
|
}
|
|
354
458
|
return alias;
|
|
355
459
|
}
|
|
460
|
+
/**
|
|
461
|
+
* Keep only usable model ids: non-empty strings. A malformed config can put
|
|
462
|
+
* anything in here (nulls, numbers, blank strings), and a blank model id would
|
|
463
|
+
* resolve to an unusable agent invocation rather than failing visibly. Invalid
|
|
464
|
+
* entries are dropped and the surviving order is preserved, so the ladder stays
|
|
465
|
+
* predictable (ADR 227 — validate shape, not just type).
|
|
466
|
+
*/
|
|
467
|
+
function sanitizeProviderEscalation(raw) {
|
|
468
|
+
if (!Array.isArray(raw))
|
|
469
|
+
return [];
|
|
470
|
+
return raw.filter((entry) => typeof entry === 'string' && entry.trim().length > 0);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* #2296 — Resolve the model for one attempt of the PROVIDER escalation ladder.
|
|
474
|
+
*
|
|
475
|
+
* The tier ladder (`resolveModelForTier`) escalates within one provider's
|
|
476
|
+
* `tier_models`, which does not help when that provider is the thing that is
|
|
477
|
+
* throttled. This walks `dynamic_routing.provider_escalation` instead: an
|
|
478
|
+
* ordered list of alternative model ids, capped by
|
|
479
|
+
* `min(max_escalations, list length)`.
|
|
480
|
+
*
|
|
481
|
+
* `applicable` is the caller's policy decision (only a quota-exceeded
|
|
482
|
+
* classification should consult this ladder). It is a parameter rather than a
|
|
483
|
+
* class check here so this module keeps depending only on leaf modules, per
|
|
484
|
+
* CONTEXT.md's Model Resolution module contract.
|
|
485
|
+
*
|
|
486
|
+
* Attempt 0 — and every non-applicable call — stays on the source model.
|
|
487
|
+
* `exhausted` reports that the ladder is spent so the caller can fail loudly
|
|
488
|
+
* naming every model it tried.
|
|
489
|
+
*/
|
|
490
|
+
function resolveProviderEscalation(cwd, agentType, attempt, applicable) {
|
|
491
|
+
// The model that would be used with no provider escalation at all.
|
|
492
|
+
const from = resolveModelForTier(cwd, agentType, 0);
|
|
493
|
+
const stay = (exhausted = false) => ({
|
|
494
|
+
from,
|
|
495
|
+
to: from,
|
|
496
|
+
escalated: false,
|
|
497
|
+
exhausted,
|
|
498
|
+
attempted: [from],
|
|
499
|
+
index: 0,
|
|
500
|
+
});
|
|
501
|
+
if (!applicable)
|
|
502
|
+
return stay();
|
|
503
|
+
const config = loadConfig(cwd);
|
|
504
|
+
const dr = config['dynamic_routing'];
|
|
505
|
+
if (!dr || typeof dr !== 'object' || dr['enabled'] !== true)
|
|
506
|
+
return stay();
|
|
507
|
+
if (dr['escalate_on_failure'] === false)
|
|
508
|
+
return stay();
|
|
509
|
+
const list = sanitizeProviderEscalation(dr['provider_escalation']);
|
|
510
|
+
if (list.length === 0)
|
|
511
|
+
return stay();
|
|
512
|
+
// Same default and same validity rule as the tier ladder above — a negative or
|
|
513
|
+
// non-integer max_escalations is invalid config, not a request for zero.
|
|
514
|
+
const maxEscalations = Number.isInteger(dr['max_escalations']) && dr['max_escalations'] >= 0
|
|
515
|
+
? dr['max_escalations']
|
|
516
|
+
: 1;
|
|
517
|
+
const cap = Math.min(maxEscalations, list.length);
|
|
518
|
+
// An explicit cap of 0 means the ladder exists but is spent before it starts.
|
|
519
|
+
if (cap === 0)
|
|
520
|
+
return stay(true);
|
|
521
|
+
const attemptN = Number.isInteger(attempt) && attempt > 0 ? attempt : 0;
|
|
522
|
+
if (attemptN === 0)
|
|
523
|
+
return stay();
|
|
524
|
+
const index = Math.min(attemptN, cap);
|
|
525
|
+
return {
|
|
526
|
+
from,
|
|
527
|
+
to: list[index - 1],
|
|
528
|
+
escalated: true,
|
|
529
|
+
exhausted: attemptN > cap,
|
|
530
|
+
attempted: [from, ...list.slice(0, index)],
|
|
531
|
+
index,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
356
534
|
// ─── #443 — Unified effort + fast_mode resolvers ─────────────────────────────
|
|
357
535
|
const VALID_EFFORTS = ['minimal', 'low', 'medium', 'high', 'xhigh', 'max'];
|
|
358
536
|
const EFFORT_SET = new Set(VALID_EFFORTS);
|
|
@@ -515,14 +693,18 @@ function resolveEffortForTier(cwd, agentType, attempt) {
|
|
|
515
693
|
}
|
|
516
694
|
module.exports = {
|
|
517
695
|
resolveTierEntry,
|
|
696
|
+
CLAUDE_AGENT_ALIASES,
|
|
518
697
|
resolveModelPolicy,
|
|
519
698
|
resolveModelInternal,
|
|
520
699
|
_resetModelPolicyWarningCacheForTests,
|
|
521
700
|
_resetModelOverrideWarningCacheForTests,
|
|
701
|
+
_setInstallRuntimeMarkerForTests,
|
|
702
|
+
_resetInstallRuntimeMarkerCacheForTests,
|
|
522
703
|
VALID_GRANULARITIES,
|
|
523
704
|
resolveGranularityInternal,
|
|
524
705
|
assertValidGranularityOverride,
|
|
525
706
|
resolveModelForTier,
|
|
707
|
+
resolveProviderEscalation,
|
|
526
708
|
VALID_EFFORTS,
|
|
527
709
|
EFFORT_SET,
|
|
528
710
|
nextEffort,
|
|
@@ -41,7 +41,12 @@ function _safeStringify(value) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Determine whether
|
|
44
|
+
* Determine whether observability is opt-in enabled — via the GSD_AUDIT env var
|
|
45
|
+
* or config.audit.enabled. Exported (#2620) so the live dispatch seam can decide
|
|
46
|
+
* whether to inject the reference logger at all: when observability is off we
|
|
47
|
+
* inject nothing (the Hub stays byte-for-byte silent, preserving the default
|
|
48
|
+
* dispatch output contract, incl. --json-errors); when on, the caller injects
|
|
49
|
+
* createDefaultLogger and gets the stderr-on-error line + opt-in file audit.
|
|
45
50
|
*/
|
|
46
51
|
function _isAuditEnabled(config) {
|
|
47
52
|
if (process.env['GSD_AUDIT'] === '1')
|
|
@@ -143,4 +148,4 @@ function createDefaultLogger({ cwd = process.cwd(), config } = {}) {
|
|
|
143
148
|
},
|
|
144
149
|
};
|
|
145
150
|
}
|
|
146
|
-
module.exports = { createDefaultLogger, createNoOpLogger };
|
|
151
|
+
module.exports = { createDefaultLogger, createNoOpLogger, isAuditEnabled: _isAuditEnabled };
|
|
@@ -269,7 +269,9 @@ function buildOnboardProjection(cwd, options) {
|
|
|
269
269
|
projectExists,
|
|
270
270
|
mapReadiness: mapReadinessValue,
|
|
271
271
|
onboardingSummaryExists,
|
|
272
|
-
|
|
272
|
+
// #2376: absolute (anchored on cwd/project_root), not orchestrator-cwd-relative —
|
|
273
|
+
// a spawned subagent's own cwd may differ from the orchestrator's.
|
|
274
|
+
onboardingSummaryPath: toPosixPath(onboardingSummaryPath),
|
|
273
275
|
hasPlanningArtifacts,
|
|
274
276
|
missingPlanningFiles,
|
|
275
277
|
handoffCommands,
|
|
@@ -289,13 +291,14 @@ function buildOnboardProjection(cwd, options) {
|
|
|
289
291
|
doc_candidate_count: docCandidates.length,
|
|
290
292
|
doc_candidates: docCandidates,
|
|
291
293
|
onboarding_summary_exists: onboardingSummaryExists,
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
294
|
+
// #2376: absolute — see comment on onboardingSummaryPath above.
|
|
295
|
+
onboarding_summary_path: toPosixPath(onboardingSummaryPath),
|
|
296
|
+
project_path: toPosixPath(node_fs_1.default.existsSync(projectRootPath) ? projectRootPath : projectScopedPath),
|
|
297
|
+
requirements_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'REQUIREMENTS.md')),
|
|
298
|
+
roadmap_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
299
|
+
state_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
300
|
+
codebase_dir: toPosixPath(node_path_1.default.join(planningRoot(cwd), 'codebase')),
|
|
301
|
+
onboarding_dir: toPosixPath(node_path_1.default.join(planningRoot(cwd), 'onboarding')),
|
|
299
302
|
};
|
|
300
303
|
}
|
|
301
304
|
module.exports = {
|
|
@@ -20,6 +20,12 @@ const command_aliases_cjs_1 = require("./command-aliases.cjs");
|
|
|
20
20
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
21
|
const commandRoutingHub = require("./command-routing-hub.cjs");
|
|
22
22
|
const { createHub, ERROR_KINDS, makeInvalidArgs } = commandRoutingHub;
|
|
23
|
+
// #2620 (ADR-0174 §6): inject the reference DispatchLogger on the live phase
|
|
24
|
+
// dispatch path, but only when observability is opt-in enabled; otherwise the
|
|
25
|
+
// Hub stays byte-for-byte silent via its no-op fallback.
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
27
|
+
const observabilityLogger = require("./observability/logger.cjs");
|
|
28
|
+
const { createDefaultLogger, isAuditEnabled } = observabilityLogger;
|
|
23
29
|
// ─── Implementation ───────────────────────────────────────────────────────────
|
|
24
30
|
function routePhaseCommand({ phase, args, cwd, raw, error }) {
|
|
25
31
|
// ── Unsupported subcommands ─────────────────────────────────────────────────
|
|
@@ -229,7 +235,10 @@ function routePhaseCommand({ phase, args, cwd, raw, error }) {
|
|
|
229
235
|
const manifest = { phase: manifestSubcommands };
|
|
230
236
|
// ── Construct hub ──────────────────────────────────────────────────────────
|
|
231
237
|
// #175: Hub is CJS-only — no mode param, no sdkLoader.
|
|
232
|
-
|
|
238
|
+
// #2620: wire the reference logger (ADR-0174 §6) only when observability is
|
|
239
|
+
// opt-in enabled; otherwise leave it unset so the Hub stays byte-for-byte
|
|
240
|
+
// silent via its no-op fallback.
|
|
241
|
+
const hub = createHub({ cjsRegistry, manifest, logger: isAuditEnabled() ? createDefaultLogger({ cwd }) : undefined });
|
|
233
242
|
// ── Dispatch ────────────────────────────────────────────────────────────────
|
|
234
243
|
const result = hub.dispatch({
|
|
235
244
|
family: 'phase',
|