Commit Graph

4722 Commits

Author SHA1 Message Date
Tom Boucher
bcf1376727 feat(#2182): implement community capability registry validation + generation
Implements the three pure functions in registry-schema.cjs (isValidGsdRange,
validateEntries, renderMarkdown) that were stubbed in the previous commit, turning
the red suite green: strict per-type schema validation (capability + eos), a
self-contained engines.gsd range validator (no semver dep), and deterministic
Markdown generation with shields.io release badges + per-entry Discussion links.
Regenerates docs/registries/capability-registry.md and adds the Added changeset.

Also hardens the isValidGsdRange fast-check property (letters-only major) so it
cannot intermittently generate a valid prerelease range and flake.

Closes #2182

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 14:26:23 -04:00
Tom Boucher
60e3c4988a feat(#2182): scaffold community capability + EoS registry (tests + stubbed core)
Adds the discoverability-registry surface for issue #2182: JSON-sourced
capability/eos catalogs, a pure schema/vocab module (registry-schema.cjs)
with the ADR-857 loop points + ADR-1239 axes, thin validate/gen CLIs,
the registry-entry PR template, README spec, and CONTEXT.md glossary terms.

The three pure functions (isValidGsdRange/validateEntries/renderMarkdown)
are stubbed here so the comprehensive test suite fails first (red), per the
feature-implementation red-first directive; the next commit implements them.

Refs #2182

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 14:13:02 -04:00
Tom Boucher
30feeaa8be Merge pull request #2172 from open-gsd/feat/2099-eos-copilot
feat(#2099): drive GitHub Copilot through the EoS descriptor + multi-event hook bus (ADR-1239)
2026-07-11 13:35:05 -04:00
Tom Boucher
35ffc489fd docs(#2179): record the PLAN.md human-rendering rejection in .out-of-scope (#2180)
PLAN.md is a documented machine artifact ("Plans are prompts, not documents"),
consumed by gsd-executor/gsd-plan-checker/gsd-verifier and cross-AI reviewers,
with no documented human-review surface. Changing its <task>/<action> tag
convention to improve human GitHub rendering targets a non-goal and risks
silent extraction drift across ~6 surfaces. Rejected as wontfix.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 13:14:15 -04:00
Tom Boucher
d1e9491fef feat(#2099): drive GitHub Copilot through the EoS descriptor + multi-event hook bus (ADR-1239)
Fold Copilot's residual runtime-literal branches onto descriptor-driven
hostBehaviors. Several issue premises were inaccurate (verified via research)
and deliberately NOT followed: writesSharedSettings/"legacy exclusion list"
(per-runtime descriptor data, copilot's false is correct); RUNTIME_CONTENT_DISPATCH.copilot
+ installSurface==='copilot-instructions' (already descriptor-driven);
extendedHookEvents (closed Claude/Gemini enum — hooks extended in code instead);
reapply ternary (already folded, kimi #2095).

Real folds (all byte-parity — golden byte-identical for every runtime):
- src/install-engine.cts + src/surface.cts: the two `.agent.md` filename cutovers
  (_copyStaged + _syncGsdDir) unified onto hostBehaviors.agentFileExtension via a
  new exported agentFileExtensionFor() accessor (kills the two-mechanism divergence).
- src/runtime-artifact-conversion.cts: applyAgentPathRewrites' copilot skip →
  hostBehaviors.noPathRewrite:true (antigravity #2096 precedent).
- bin/install.js uninstall: the two isCopilot cleanup branches → installSurface===
  'copilot-instructions' gate (symmetric with install-time).
- bin/install.js: `!isCopilot` in the two skipSharedHooksInstall checks →
  hostBehaviors.skipSharedHooksInstall:true (copilot has no shared gsd-*.js hooks).
- bin/install.js: three dead legacy inline-agent-loop isCopilot refs removed
  (copilot ∈ _DESCRIPTOR_AGENTS_RUNTIMES → unreachable; byte-parity proven by clean
  golden + real reachable-runtime install diffs). isCopilot dropped from 4 destructures.
Zero live `runtime==='copilot'`/`isCopilot` branches remain in bin/install.js,
install-engine.cts, surface.cts, or runtime-artifact-conversion.cts (AC2 guard scans all four).

UPGRADE 1 (multi-event hook bus): buildCopilotHookConfig() now emits preToolUse/
postToolUse/userPromptSubmitted/sessionEnd advisory handlers alongside sessionStart
(static inline bash/powershell — deterministic, golden-trackable). Only copilot.json's
gsd-session.json hash changes.

UPGRADE 2 (background dispatch): surfaced via the negotiated contract only —
dispatch.background:true exceeds the declarative-cli baseline and survives negotiation
with no downgrade warning. NO .agent.md frontmatter field (copilot has none). MCP
companion out of scope (AC4 names only 2 upgrades).

Tests: declarative-reference-copilot (adapter/axes/fail-closed + AC2 4-file source-grep
guard) + copilot-upgrades (live 5-event hook wiring; dispatch.background negotiation).
Matrix EoS note + how-to; changeset (Changed). capability-registry regenerated.

Incidental flaky-test RE-ARCHITECTURE (no-defer, maintainer-directed):
tests/opencode-review-reconstruction.property.test.cjs spawned ~600 synchronous
execFileSync('jq') subprocesses (numRuns:200 × 3 fast-check properties, one jq per
generated stream); a single jq freezing on a contended macos-22 CI runner hung the whole
unit-test chunk to its 600s kill (this PR's CI). --test-force-exit can't interrupt a
synchronous execFileSync, so the cure is to stop spawning per case, not just time-bound
it. Re-architected to run the SHIPPED jq program over the whole fast-check corpus in ONE
jq process: each generated stream is one compact-JSON array per line in a temp file,
`jq -c <PROGRAM>` (no -s) applies PROGRAM to each array (`.` == the array, exactly what
production's `jq -rs <file>` sees after slurping) and emits one result per line —
empirically byte-identical to the per-stream form across embedded-newline/empty/quote/
unicode/null-drop cases, and file-input (like production) so there's no stdin pipe to
deadlock on large I/O. ~600 spawns → 6; coverage unchanged (200-case corpus per property,
deterministic seeds) plus explicit boundary/diagnostic example batches. Still property-
tests the real shipped jq (no JS reimplementation). Per-call jq timeout retained as a
belt-and-suspenders bound.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 13:10:31 -04:00
Tom Boucher
474ca08e06 docs(#2171): record the statusline data-source scope boundary (#2178)
Records the statusline scope boundary decided during triage of #2160-2164:
the statusline sources only local, read-only data (refine-existing + new-local),
never credentials or external/network APIs. #2164 (account-usage segment) is
out of scope on this boundary; #2163 (git) is in-scope but on the feature track;
#2160/2161/2162 are approved enhancements.

- docs/adr/2164-statusline-scope-boundary.md (new ADR, Accepted)
- docs/adr/README.md (index row)
- CONTEXT.md (### Statusline glossary/seam entry)
- .out-of-scope/statusline-account-usage.md (#2164 rejection record)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 12:52:21 -04:00
Behruz Nassre Esfahani
5235589f62 Merge branch 'next' into fix/2137-derive-progress-header-driven 2026-07-11 06:59:25 -07:00
Tom Boucher
b4a57fb16d Merge pull request #2169 from open-gsd/feat/2098-eos-codebuddy
feat(#2098): drive CodeBuddy through the EoS descriptor + wire subagent hooks (ADR-1239)
2026-07-11 09:55:39 -04:00
Tom Boucher
9e1fad1503 feat(#2098): drive CodeBuddy through the EoS descriptor + wire subagent hooks (ADR-1239)
Fold CodeBuddy's residual runtime-literal branches onto descriptor-driven
hostBehaviors (the issue's "zero branches remain" premise was inaccurate — 2
lived):
- Folded the `if (isCodebuddy)` commands/ report duplicate (byte-identical to
  the generic reportCommandsDir block above it) onto
  hostBehaviors.reportCommandsDir:true, matching cursor's #2089 precedent.
- Deleted the dead `else if (isCodebuddy)` agent-conversion arm (codebuddy ∈
  _DESCRIPTOR_AGENTS_RUNTIMES → gated out before the legacy chain, same dead-arm
  pattern removed for augment/trae in #2097).
- Removed isCodebuddy from all 4 destructure sites (now comments only, mirroring
  the #2096 isAntigravity fold). Zero live isCodebuddy reads remain.

UPGRADE 1 (extended hook bus): populate extendedHookEvents with the full
extended set SubagentStop/Stop/PreCompact/SubagentStart (qwen #2092 / kimi
precedent — codebuddy previously had extendedHookEvents:[] so it got NONE of
these). The generic applySettingsJsonHooks loop wires them, so CodeBuddy's
settings.json now gains all four subagent-lifecycle + stop/compact hooks it
previously lacked, matching Qwen/Kimi coverage. No source change (the
HOOK_EVENT_SURFACES SDK catalog is a locked dict; all 4 events are already in
the validator enum; hookEvents already 'claude'). settings.json is golden-
excluded → no golden change.

UPGRADE 2 (background dispatch): surfaced via the negotiated capability contract
only. CodeBuddy's dispatch.background:true legitimately exceeds the declarative-
cli baseline (false) and survives negotiation with no warning. NO agent-file
frontmatter field is emitted: the CodeBuddy CLI (GSD's install target,
~/.codebuddy/agents/) has NO background-dispatch frontmatter field — background
is a caller-side run_in_background invocation param (verified against
codebuddy.ai/docs/cli/sub-agents); the issue's agentMode/enabledAutoRun are
IDE-only (codebuddy.cn, a different product). Emitting them would be a non-
functional false-green, so it is deliberately not done.

Golden: byte-identical for all 16 runtimes (folds are console/failures-report
only; UPGRADE 1 → golden-excluded settings.json; UPGRADE 2 → no artifact
change). Tests: declarative-reference-codebuddy (adapter/axes/fail-closed
negotiation + AC2 source-grep guard) + codebuddy-upgrades (live install asserts
all 4 extended hooks wired; dispatch.background survives negotiation above
baseline). Matrix + install-on-your-runtime updated; changeset (Changed).
capability-registry regenerated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 09:39:34 -04:00
Behruz Nassre Esfahani
3582a45f9e chore(#2137): add changeset
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 05:52:19 -07:00
Tom Boucher
2cf00705c3 Merge pull request #2166 from open-gsd/feat/2097-eos-augment
feat(#2097): migrate Augment onto EoS declarative adapter + settings.json MCP companion (ADR-1239)
2026-07-11 05:00:34 -04:00
Tom Boucher
17aa35fba7 feat(#2097): migrate Augment onto EoS declarative adapter + settings.json MCP companion (ADR-1239)
Fold augment's runtime-literal conversion branches onto descriptor-driven
hostBehaviors and delete dead code:
- Site A (_applyRuntimeRewrites case 'augment'): the 4 ~/.augment dot-dir
  regexes now derive from getDirName('augment') via escapeRegExp (byte-
  identical; getDirName('augment')==='.augment') — no runtime literal.
- Site B (applyRuntimeContentRewritesForCommandsInPlace): the
  `if (runtime==='augment')` markdown-converter branch now reads
  runtime.hostBehaviors.commandBodyConverter and dispatches through a local
  COMMAND_BODY_CONVERTERS map (degrade-closed on unknown/absent name).
- Deleted dead `claudeToAugmentTools` map (zero refs; orphaned by ADR-1508
  single-sourcing) and the unreachable `else if (isAugment)` agent-conversion
  branch (augment ∈ _DESCRIPTOR_AGENTS_RUNTIMES → gated out upstream).
- Incidental orphan cleanup (no-defer): removed the equally-unreachable
  `else if (isTrae)` agent-conversion arm left behind by trae's already-merged
  migration #2094 (trae ∈ _DESCRIPTOR_AGENTS_RUNTIMES, same upstream gate).
  copilot/windsurf/codebuddy arms are removed by their own pending migrations.

UPGRADE 3 (transport:mcp): register the GSD companion MCP server in Augment's
settings.json under mcpServers.gsd (Augment hosts MCP in settings.json, not a
standalone file). mergeGsdMcpServerIntoSettings mutates the in-memory settings
object finishInstall already writes (gated on hostBehaviors.mcpCompanion===
'settings-json'); non-destructive + idempotent; symmetric uninstall removal.
settings.json is golden-excluded, so no golden change. UPGRADE 1 (named/
background dispatch) + UPGRADE 2 (settings-json hook bus, Claude dialect)
were already live in production — this adds tests exercising both.

Golden: byte-identical for all 16 runtimes (folds preserve regex behavior;
MCP lives in golden-excluded settings.json) — verified by a real double-install
tree diff. Tests: declarative-reference-augment (adapter/axes/fail-closed/
undocumented-sub-axes + source-grep guard scoped to conversion-logic branches)
+ augment-upgrades (dispatch negotiation, hook-bus live install, MCP add/
idempotent/preserve/uninstall). Matrix + connect-gsd-mcp-server + a stale
install-on-your-runtime hook-ownership claim corrected; changeset (Changed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 04:47:56 -04:00
Tom Boucher
41d544248b Merge pull request #2165 from open-gsd/feat/2096-eos-antigravity
feat(#2096): migrate Antigravity onto EoS declarative adapter + permission-writer + MCP companion (ADR-1239)
2026-07-11 03:21:49 -04:00
Tom Boucher
5695522d5f feat(#2096): migrate Antigravity onto EoS declarative adapter + permission-writer + MCP companion (ADR-1239)
Fold all antigravity literal branches into descriptor-driven reads:
getConfigDirFromHome (→ configHome.kind 'dot-home-nested'), projectLocalHookPrefix
(→ hostBehaviors.hookPathStyle 'raw'), applyAgentPathRewrites (→ noPathRewrite),
getProjectInstructionFile (→ projectInstructionFile 'GEMINI.md'); removed the dead
inline convertClaudeAgentToAntigravityAgent branch + dead isAntigravity
destructures (antigravity is already on the descriptor-agents path). subagentToolkit
flipped undocumented→full (Context7: antigravity.google/docs/cli/features);
namedDispatch/nested/maxDepth/backgroundDispatch stay undocumented. Byte-identical
golden parity for all 16 runtimes.

UPGRADE 1 (permission-writer): permissionWriter 'antigravity' + configureAntigravityPermissions
merges a scoped permissions.allow block (GSD's own tree + hooks) into Antigravity's
settings.json — non-destructive, idempotent, symmetric uninstall. Added to
VALID_PERMISSION_WRITERS + the FinishPermissionWriter union.
UPGRADE 2 (MCP companion): configureAntigravityMcpConfig writes mcp_config.json
registering the gsd-core companion MCP server (Gemini-successor mcpServers schema,
best-effort — raw schema unpublished). Both writers dispatch from finishInstall.
settings.json is golden-excluded (HOOK_CONFIG_FILES); mcp_config.json (portable,
no absolute paths) is golden-tracked → only antigravity.json changes.

Tests: declarative-reference-antigravity extended (source-grep guard across 4
modules, fail-closed for the 4 undocumented sub-axes, validator acceptance) +
antigravity-upgrades (permission-writer + mcp_config live-install, idempotency,
user-preservation). Matrix + ADR-1016 + capability-manifest + CONTEXT.md +
connect-gsd-mcp-server docs updated; changeset (Changed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 03:07:01 -04:00
Behruz Nassre Esfahani
3f6be47db9 fix(#2137): parse the ROADMAP Progress table by header, not fixed column count
deriveProgressFromRoadmap read the `## Progress` table with two
4-column-only regexes, so every project past its v1.0 milestone — which
uses the 5-column milestone-grouped shape the same template ships
(| Phase | Milestone | Plans Complete | Status | Completed |) — parsed to
{completedPhases: null, totalPhases: null, totalPlans: null}. Because the
body is wrapped in a bare try/catch the failure was silent, and
phase.complete flipped the ROADMAP row to Complete but never advanced
STATE's progress percent / completed-phase count.

Parse the table by header instead: locate the `## Progress` section
(line-anchored h2, mirroring the writer's #2012 scoping so an earlier
Phase/Status/Completed-shaped table can't hijack it), read the header row
to find the Status, Completed, and plans columns by name, then index each
data row positionally. One code path now handles both the 4-column
greenfield and 5-column milestone-grouped shapes — the same understanding
the writer (cmdPhaseComplete, with its `cells.length === 5` branch)
already had. Preserves the 999.x backlog exclusion, M/N plan summing, and
the prior contract that a count of 0 is reported as null.

Regression tests fold into tests/state.test.cjs: the template's own
5-column Progress block parses non-null, both shapes derive identically,
999.x stays excluded in the 5-column shape, and decoy tables (an earlier
## Retrospective table and an ### Progress h3 subheading) do not hijack
the scope.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:57:15 -07:00
Tom Boucher
e3a8c063b8 Merge pull request #2159 from open-gsd/feat/2095-eos-kimi
feat(#2095): migrate Kimi CLI onto EoS imperative adapter + native hook-bus + background dispatch (ADR-1239)
2026-07-11 01:06:34 -04:00
Tom Boucher
ab04916682 feat(#2095): migrate Kimi CLI onto EoS imperative adapter + native hook-bus + background dispatch (ADR-1239)
Fold all runtime==='kimi'/isKimi logic branches into descriptor-driven
hostBehaviors (localInstallDeferred, verificationStyle, agentManifestStyle,
reapplyCommand, doneBannerStyle) + add 'kimi' to _DESCRIPTOR_AGENTS_RUNTIMES.
Kimi's skills/kimi-agents dispatch was already descriptor-driven (converter-by-
name + kimi-agents kind). Zero isKimi/runtime==='kimi' branches remain.

UPGRADE 1 (native hook bus): new hooksSurface 'kimi-hooks-toml' + a marker-
delimited config.toml [[hooks]] emitter (buildKimiHooksTomlBlock/writeKimiHooksToml
in runtime-hooks-surface.cts; resolveKimiHooksTomlDir in runtime-homes.cts).
GSD's lifecycle hooks now wire into Kimi's native ~/.kimi/config.toml (Context7-
confirmed path) at SessionStart/PreToolUse/Stop/PreCompact/SubagentStart/
SubagentStop — kimi becomes a hooks/ consumer (the 3 && !isKimi exclusion guards
removed). config.toml holds absolute install paths so it's golden-excluded via
an exact relative-path (.kimi/config.toml), not a basename (which would blind
Codex's config.toml). New hooksSurface value added to the closed enum in
capability-validator + runtime-config-adapter-registry.
UPGRADE 2 (background dispatch): flip dispatch.backgroundDispatch true (Kimi's
Agent tool takes run_in_background; root agent already gets the Agent tool), so
negotiation no longer flattens dispatch. subagentToolkit stays 'undocumented'
per AC (coder/explore/plan have distinct tool policies).
MCP transport explicitly deferred (no installer-driven MCP for any runtime).

Golden: only kimi.json changes (hooks/ scripts now installed); all 15 others +
claude-local byte-identical (kilo/zcode keep their own exclusions). Tests:
kimi-imperative-reference (adapter/axes/fail-closed/hostBehaviors + source-grep
guard) + kimi-upgrades (config.toml [[hooks]] SessionStart + marker idempotency
+ backgroundDispatch negotiation). CONTEXT.md glossary + matrix + how-to updated;
changeset (Added).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 00:53:34 -04:00
Tom Boucher
a022eec117 Merge pull request #2157 from open-gsd/feat/2094-eos-trae
feat(#2094): migrate Trae onto EoS imperative adapter + SOLO stage-metadata upgrade (ADR-1239)
2026-07-10 21:46:55 -04:00
Tom Boucher
f744635b3d feat(#2094): migrate Trae onto EoS imperative adapter + SOLO stage-metadata upgrade (ADR-1239)
Fold trae logic branches into descriptor-driven reads: skipSharedHooksInstall
gates (dropped && !isTrae), and the case 'trae' path-rewrite arm now computes
the self-alias from the descriptor-driven dirName (.trae). Dead isTrae bindings
removed from uninstall/writeManifest/finishInstall. trae's skills dispatch was
already descriptor-driven (converter-by-name). RUNTIME_CONTENT_DISPATCH.trae is
left as a runtime-keyed table registration (its regex/callback rewrites can't be
a byte-identical descriptor map — matches cursor/windsurf/cline). trae stays in
RUNTIME_FLAG_IDS: isTrae still gates the agents-converter selection (agents out
of scope; removal gated on the cross-runtime agents-dispatch migration).
Byte-identical golden parity for all 16 runtimes.

UPGRADE: SOLO stage/trigger metadata — emitted Trae SKILL.md now carries
stage: workflow (descriptor-gated via hostBehaviors.soloStageMetadata) so
Trae's SOLO Agent can auto-invoke GSD skills at the corresponding stage. Field
shape is best-effort/inferred (Trae publishes no formal schema). trae.json
golden regenerated.

Tests: trae-imperative-reference (adapter/axes/fail-closed shouldFlattenDispatch
+ no runtime==='trae' source-grep, isTrae exempted for agents) + trae-upgrades
(stage: workflow on installed SKILL.md, descriptor-gated). Matrix note +
changeset added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 21:31:10 -04:00
Tom Boucher
d010ea13d4 Merge pull request #2156 from open-gsd/feat/2093-eos-kilo
feat(#2093): migrate Kilo onto EoS imperative adapter + hook-bus/model/MCP/dispatch upgrades (ADR-1239)
2026-07-10 20:27:27 -04:00
Tom Boucher
f014ec83bd feat(#2093): migrate Kilo onto EoS imperative adapter + hook-bus/model/MCP/dispatch upgrades (ADR-1239)
Fold remaining isKilo logic branches into descriptor-driven reads:
finishPermissionWriter (uninstall cleanup), skipSharedHooksInstall (hooks
copy), and a skills converter-name registry (the artifactLayout.converter
field is now load-bearing, not decorative). frontmatterDialect stays the
documented dispatch key for frontmatter (no descriptor field for it). Dead
isKilo destructure bindings removed. Byte-identical golden parity for all 16
runtimes (opencode, which shares kilo's combined-family path, verified clean).

UPGRADE 1 (hook bus): install .kilo/plugins/gsd-core.js native plugin +
extensionEvents:"kilo" + EXTENSION_EVENT_SURFACES.kilo (OpenCode-fork bus).
UPGRADE 2 (active model): populate runtimeTierDefaults.kilo + thread
modelOverride through convertClaudeToKiloFrontmatter — model no longer stripped
from agents. UPGRADE 3 (MCP): document the gsd-core MCP companion under kilo's
mcp config key. UPGRADE 4 (named dispatch): agents/*.md mode:subagent roster is
the Task-tool dispatch surface (tested); subagentToolkit stays 'undocumented'
per AC so dispatch degrades to 'degraded' by design.

Model-catalog single-source edit ripples the shared model-catalog.json hash
into all 16 golden fixtures (expected). Inline defect fixes (no-defer): stale-
bake-guard resolveAgentDir 'agent'->'agents' (was a silent no-op for opencode/
codex), hardcoded 'Removed OpenCode plugin' uninstall log -> generic, and the
connect-gsd-mcp-server.md OpenCode mcpServers->mcp doc error.

Tests: kilo-imperative-reference (adapter/axes/fail-closed/degradation/
hostBehaviors + widened isKilo source-grep across 4 modules) + kilo-upgrades
(plugin parity+load, model-override converter, agents dispatch surface, MCP
doc). Matrix + how-to + config docs updated; changeset added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 19:55:15 -04:00
Tom Boucher
61d04daacf Merge pull request #2153 from open-gsd/feat/2092-eos-qwen
feat(#2092): migrate Qwen Code onto EoS imperative adapter + native subagents + SubagentStart (ADR-1239)
2026-07-10 16:14:39 -04:00
Tom Boucher
c6ce110efa feat(#2092): migrate Qwen Code onto EoS imperative adapter + native subagents + SubagentStart (ADR-1239)
Fold all runtime==='qwen'/isQwen logic branches (skill-priority frontmatter,
branding/path rewrites, legacy commands/gsd cleanup, hyphen-namespace
normalization, RUNTIME_CONTENT_DISPATCH, hooks-surface label) into
descriptor-driven runtime.hostBehaviors on capabilities/qwen/capability.json,
read via _hostBehaviors(). Shared claude/qwen/hermes legacy-migration branches
in install-engine.cts folded to descriptor flags (claude+hermes descriptors
updated; FALLBACK_HOST_BEHAVIORS.claude floored). Byte-identical golden parity
for qwen/hermes/claude(global+local).

UPGRADE 1: native .qwen/agents/*.md subagent projection — new agents
artifact-layout kind + convertClaudeAgentToQwenAgent converter (name +
description + tools YAML block list; color/model dropped). qwen routed onto
the descriptor-driven agents path (_DESCRIPTOR_AGENTS_RUNTIMES).
UPGRADE 2: SubagentStart hook wired into extendedHookEvents + the
descriptor-gated hook-writer loop (activates only for qwen).

Tests: qwen-imperative-reference (adapter/axes/fail-closed/hostBehaviors +
no runtime==='qwen' source-grep across 4 files) + qwen-upgrades (agents file
validity + SubagentStart mirrors SubagentStop, descriptor-gated). Docs matrix
+ how-to updated; changeset added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 15:44:19 -04:00
Tom Boucher
91a68ae8e6 Merge pull request #2149 from open-gsd/fix/2104-foreign-prefix-sibling-commands
fix(#2104): guard foreign-prefix collapse in init execute-phase/verify-work/phase-op
2026-07-10 15:04:38 -04:00
Tom Boucher
52c938d7e5 Merge pull request #1979 from davesienkowski/feat/1867-ui-consideration-probe
feat(#1867): ui-consideration probe — 3rd probe-core adapter for UI state coverage
2026-07-10 15:04:11 -04:00
Dave
a8ff8fbb30 docs(#1867): specify propose-then-confirm --auto behavior in ui-phase Step 9.5 (review Minor) 2026-07-10 14:41:12 -04:00
Dave
31a500b970 docs(#1867): replace stale plan-phase.md:921 line-pointer with section-name reference (review #6) 2026-07-10 14:40:03 -04:00
Dave
20608cba90 chore(#1867): regen goldens + size baselines after merge onto next
next advanced to a3b9cbae (incl. #1820 specless-rail merge); regenerate
golden-install-parity fixtures + workflow-size-baseline authoritatively.
Manifest + agent baseline already in sync. plan-phase.md conflict
hand-merged to keep both EDGE_ABSENT/PROHIB_ABSENT and UI Considerations.
2026-07-10 14:40:03 -04:00
Dave
830670f288 docs(#1867): clarify Step 9.5 manual element-extraction is by-design (review Minor 1)
trek-e's re-review asked to either mechanize the Step 9.5 element
extraction or add an inline note justifying why it stays manual, so a
future maintainer doesn't read it as an oversight.

Verified the premise: the requirement-side edge-probe path (spec-phase
Step 5.5) it mirrors is ALSO a hand-populated heredoc + fail-loud
<replace:> placeholder guard — not a mechanical parse. The UI probe
mirrors that idiom verbatim. Mechanizing would be worse: a UI-SPEC has no
single machine-parseable "elements" column (surfaces are spread across the
design-token tables, Copywriting, and researcher-named prose), so a
regex/table parse would fail-OPEN (miss a prose-named surface, or feed a
design-token row as a bogus element).

Expanded the inline comment to state the parity + the fail-open rationale
explicitly. No logic change; regenerated the workflow size baseline and
the 16 golden-install-parity fixtures for the +847 B comment.

Refs #1867

Claude-Session: https://claude.ai/code/session_017vYn26e3nkDNxcpty1ciPJ
2026-07-10 14:40:03 -04:00
Dave
dc0c434141 chore(#1867): point changeset at PR #1979
Claude-Session: https://claude.ai/code/session_01BKt4hgNZwXSeJYJtYAQUSS
2026-07-10 14:40:03 -04:00
Dave
a4d8eb4a78 chore(#1867): eslint-ignore generated ui-consideration-probe.cjs (SHIP-01)
ci-preflight (full test:unit) caught a Phase-1 registration gap: the
tsc-generated gsd-core/bin/lib/ui-consideration-probe.cjs was not in the
eslint.config.mjs global ignore list, failing 551-eslint-bin-lib-coverage
("each bin/lib/*.cjs is linted xor ignored according to migration state",
ADR-457/#537). Generated artifacts are ignored, not linted — added it next to
the sibling probe adapters (edge-probe/probe-core/prohibition-enforcement).

Claude-Session: https://claude.ai/code/session_01BKt4hgNZwXSeJYJtYAQUSS
2026-07-10 14:40:03 -04:00
Dave
c1756d0cd5 chore(#1867): register ui-consideration probe + regen install cascade (SHIP-01)
Ship-safe registration + regenerated snapshots for the #1867 UI-consideration
probe (Phase 3, SHIP-01):

- CONTEXT.md: PROBE.ui.{verification,axis,seam} predicates + ui-consideration
  -probe added to PROBE.family (machine-canon for the 3rd adapter, MIXED axis).
- agents/gsd-ui-{researcher,checker}.md: one @-include of
  references/ui-consideration-probe.md each (both under the 24576 agent cap).
- docs/INVENTORY.md + INVENTORY-MANIFEST.json: register the reference doc and
  the compiled ui-consideration-probe.cjs (inventory-manifest-sync green).
- tests/fixtures/golden-install-parity/*.json (16 runtimes): recaptured against
  a clean full build — folds in the deferred Phase-1 (ref doc, plan-phase lift)
  and Phase-2 (ui-phase step, UI-SPEC section) install-surface changes.
- tests/agent-size-baseline.json: ratcheted the two grown UI agents.
- .changeset/vivid-orcas-chatter.md: type Added (pr updated at PR-open).

Inventory/golden/size gates green; lint:ci + lint:docs + lint:changeset green.
The plan-phase.md PRE_PHASE6 ceiling stays RED pending #1852 (unchanged).

Claude-Session: https://claude.ai/code/session_01BKt4hgNZwXSeJYJtYAQUSS
2026-07-10 14:40:03 -04:00
Dave
4bce86650d feat(#1867): add UI Considerations section to UI-SPEC template (WIRE-02)
Record resolved UI-state considerations in the UI-SPEC, backward-compatibly
(Phase 2, WIRE-02). templates/UI-SPEC.md gains a '## UI Considerations' section
(analog of SPEC '## Edge Coverage') after '## Copywriting Contract' — a
| Category | Element(s) | Status | Resolution / Reason | table with
covered/backstop/unresolved rows in the locked probe-core projectTruths format
the shipped plan-phase lift (plan-phase.md:921) reads. Empty/error COPY stays in
Copywriting; this section covers shape-rooted STATE and references those rows
(de-dup).

Tests: docs-fixtures parsed-heading assertion (UI Considerations present +
distinct from Copywriting Contract; allow-test-rule, parsed structure); typed
backward-compat (projectTruths(undefined/[])===[], old UI-SPEC still plans —
Hyrum), format-match, and idempotency (proposeElements determinism). The
template-structure test was the RED driver.

Install-parity cascade (INVENTORY-MANIFEST + 16 golden fixtures +
agent-size-baseline) deferred to Phase 3 SHIP-01, as planned.

Claude-Session: https://claude.ai/code/session_01BKt4hgNZwXSeJYJtYAQUSS
2026-07-10 14:40:03 -04:00
Dave
bea7196c4c feat(#1867): wire ui-consideration probe into ui-phase (WIRE-01)
Add the live ui-phase producer path for the UI-consideration probe (Phase 2,
WIRE-01). Two small exports on the Phase-1 adapter — proposeElements (the
propose-then-confirm view of detected kinds + applicable categories) and
autoResolve (the deterministic --auto floor that never dismisses and never
auto-backstops an unclassified item, #1110) — plus a post-verification
'## 9.5 UI-Consideration Probe' step in ui-phase.md mirroring spec-phase 5.5's
RUNTIME_DIR shim + fatal-invoke/malformed-report/zero-applicable fail-closed
guards, propose-then-confirm (the partial-cue recall mitigation), and the
'## UI Considerations' write-back in the shipped plan-phase.md:921 lift format.

autoResolve is the CODE floor; the covered-upgrade stays workflow prose (the
two-layer --auto). Un-upgraded backstops route to insufficient_spec ->
human_needed at verify, never a silent pass (#1154).

Tests: +8 typed (proposeElements shape/determinism, autoResolve never-dismiss,
partial-cue strict-subset) — structured-value only. ui-phase.md size baseline
ratcheted 15477->24447 (under DEFAULT cap). The plan-phase.md PRE_PHASE6 ceiling
stays RED pending #1852 (unchanged from Phase 1).

Claude-Session: https://claude.ai/code/session_01BKt4hgNZwXSeJYJtYAQUSS
2026-07-10 14:40:03 -04:00
Dave
6d7450c465 feat(#1867): lift UI Considerations into plan-phase must_haves (LIFT-01)
Separate *-UI-SPEC.md glob (edge-coverage glob exclusion at :746 left intact
- Hyrum/D-08); a terse lift bullet reusing the ## Edge Coverage rule verbatim
(covered -> truths string, backstop -> flat scalar {statement, verification:
backstop}, unresolved -> assumption; no new verb - ADR-550 #1278/#1154); and a
no-silent-drop checklist line. Lift logic lives ONLY in the plan-phase
workflow, never gsd-planner.md (D-10, agent-size cap).

NOTE: this grows plan-phase.md +862B, over the #1168 PRE_PHASE6 ceiling (94519)
by ~802B, so the workflow-size gates are RED until #1852's lazy-split lands the
-21KB headroom. Deliberately does NOT raise the ceiling constant (would collide
with #1820/#1835's in-flight raise). #1867 sequences after #1852; rebase +
regenerate the size baseline then.
2026-07-10 14:40:03 -04:00
Dave
29120ea0aa docs(#1867): ui-consideration-probe reference + docs-parity test (ADPT-02)
Reference doc mirrors edge-probe.md structure but links rather than re-argues;
states the MIXED-axis boundary (closed compiled shape-rooted subset here; open
UX subset - real-time/offline, a11y depth, i18n/RTL - prose-owned in
domain-probes.md). Docs-parity test pins doc taxonomy ids == code UI_TAXONOMY
ids and asserts disjointness from domain-probes.md topics (ADR-456
runtime-contract exemption, see #1867).
2026-07-10 14:40:03 -04:00
Dave
cf92eb2cf3 feat(#1867): ui-consideration-probe adapter over probe-core (ADPT-01/02/03, FILT-01)
Third probe-core adapter on the UI element/state axis, mirroring edge-probe.
Closed 8-id shape-rooted UI_TAXONOMY + element-cue relevance filter
(UI_CUES -> classifyElement -> applicableCategories); unclassified fail-loud
soft-signal (#1110); fail-closed on invalid authored element kinds. All
lifecycle/merge/validation delegated to probe-core verbatim (no fork). Item
question carried in the shared Item.probe field. LIFT-01 proven at the
probe-core primitive level (projectTruths/dispositionForUnverifiableTruth):
backstop considerations route to insufficient_spec, never a silent pass.

Tests assert typed returns off the built .cjs (no source-grep).
2026-07-10 14:40:03 -04:00
Tom Boucher
d45ea9e39d docs(changeset): backfill PR number (#2149) 2026-07-10 14:25:00 -04:00
Tom Boucher
f910352ea6 fix(2104): guard foreign-prefix collapse in init execute-phase/verify-work/phase-op
#2056 fixed the foreign-prefix collapse for init plan-phase only.
The identical defect remained in three sibling commands that called
findPhaseInternal/getRoadmapPhaseInternal without the guard:
- cmdInitExecutePhase
- cmdInitVerifyWork
- cmdInitPhaseOp

Extracted the #2056 guard into shared helpers (guardedFindPhase /
guardedGetRoadmapPhase) and routed all four init commands through them.
Deleted the local parsePhasePrefix/isForeignPrefixedPhaseQuery copies in
init.cts — the canonical export from phase-id.cts is now used directly,
eliminating the drift risk flagged by both reviewers.

Added 5 regression tests (3 reject + 2 accept-branch) mirroring the
#2056 plan-phase tests.
2026-07-10 14:24:14 -04:00
Tom Boucher
741d86f819 Merge pull request #2147 from open-gsd/chore/sync-next-version-1.7.0-rc.5
chore: sync next package version to 1.7.0-rc.5
2026-07-10 13:09:46 -04:00
github-actions[bot]
451e58e6d5 chore: sync next package version to 1.7.0-rc.5 2026-07-10 17:09:38 +00:00
Tom Boucher
142b190bd8 Merge pull request #2105 from open-gsd/fix/2056-plan-phase-foreign-prefix
fix(#2056): guard init plan-phase against foreign-prefix numeric collapse
2026-07-10 12:35:13 -04:00
Tom Boucher
a79cdf0f32 Merge pull request #2145 from open-gsd/docs/2143-markdown-table-mutation-adr
docs(#2144): add ADR-2143 markdown table + mutation + fail-loud consolidation (Phase 0)
2026-07-10 12:34:56 -04:00
Tom Boucher
246bcffa43 Merge pull request #2146 from open-gsd/feat/2122-codex-gpt56-model-defaults
feat(#2122): advance Codex/OpenAI model defaults to GPT-5.6 (Sol/Terra/Luna)
2026-07-10 12:34:34 -04:00
Tom Boucher
fed10e331d docs(changeset): backfill PR number (#2146) 2026-07-10 12:23:49 -04:00
Tom Boucher
7bbc243cf5 docs(#2144): index ADR-2143 in docs/adr/README.md
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:12:07 -04:00
Tom Boucher
a146812c5e docs(#2144): add ADR-2143 markdown table + mutation + fail-loud consolidation (Phase 0)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:12:06 -04:00
Tom Boucher
185abe2d66 feat(codex): advance Codex/OpenAI model defaults to GPT-5.6 (Sol/Terra/Luna)
Update runtimeTierDefaults.codex and providerPresets.openai in
model-catalog.json to the GPT-5.6 family (gpt-5.6-sol/terra/luna),
advancing from the superseded GPT-5.4/5.5 generation.

Model IDs verified against OpenAI developer API docs:
- gpt-5.6-sol: flagship, /, reasoning xhigh
- gpt-5.6-terra: balanced, .50/, reasoning medium
- gpt-5.6-luna: fast/cheap, /, reasoning medium

Tier mapping is 1:1 (Sol↔flagship, Terra↔balanced, Luna↔fast),
so profile semantics are unchanged — only the underlying IDs advance.

Updates: catalog JSON, test assertions (catalog defaults), docs
(CONFIGURATION.md + zh-CN/pt-BR translations, workflow settings),
and changeset.

Closes #2122
2026-07-10 12:11:55 -04:00
Tom Boucher
7866e22457 Merge remote-tracking branch 'origin/next' into fix/2056-plan-phase-foreign-prefix
# Conflicts:
#	src/init.cts
2026-07-10 12:01:32 -04:00
Tom Boucher
a890dee7b0 Merge pull request #2141 from open-gsd/chore/2128-phase-id-drift-guard
chore(#2121): phase-id anti-divergence guard + markdown ReDoS hardening — Phase 4
2026-07-10 11:56:22 -04:00