From 54b06e653e1aa08ea94aa9eaee1015d9e8f5cbe6 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Tue, 5 May 2026 19:29:59 -0400 Subject: [PATCH] docs(sdk): document runtime bridge seam, strict mode, and fallback policy --- docs/ARCHITECTURE.md | 13 ++++++++++++- docs/CLI-TOOLS.md | 5 ++++- docs/adr/0001-dispatch-policy-module.md | 15 +++++++++++++++ sdk/src/query/QUERY-HANDLERS.md | 9 +++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 6268a4a9c..4bb55b400 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -55,7 +55,7 @@ GSD is a **meta-prompting framework** that sits between the user and AI coding a ┌──────▼──────────────▼─────────────────▼──────────────┐ │ CLI TOOLS LAYER │ │ gsd-sdk query (sdk/src/query) + gsd-tools.cjs │ -│ (State, config, phase, roadmap, verify, templates) │ +│ SDK Runtime Bridge Module routes native vs fallback │ └──────────────────────┬───────────────────────────────┘ │ ┌──────────────────────▼───────────────────────────────┐ @@ -266,6 +266,17 @@ Runtime hooks that integrate with the host AI agent: See [`docs/INVENTORY.md`](INVENTORY.md#hooks-11-shipped) for the authoritative 11-hook roster. +### SDK Runtime Bridge Module (`sdk/src/query-runtime-bridge.ts`) + +Programmatic SDK callers (`GSDTools`) route through one seam that owns query dispatch policy: + +- Native registry dispatch preference +- Explicit subprocess fallback policy (`allowFallbackToSubprocess`) +- Strict SDK mode (`strictSdk`) for fail-fast native-only enforcement +- Structured dispatch observability (`onDispatchEvent`) with mode, reason, duration, and outcome + +This keeps callers thin adapters and centralizes transport decisions for SDK publishability. + ### CLI Tools (`get-shit-done/bin/`) Node.js CLI utility (`gsd-tools.cjs`) with domain modules split across `get-shit-done/bin/lib/` (see [`docs/INVENTORY.md`](INVENTORY.md#cli-modules-33-shipped) for the authoritative roster): diff --git a/docs/CLI-TOOLS.md b/docs/CLI-TOOLS.md index b5d09cdd0..c21a84a76 100644 --- a/docs/CLI-TOOLS.md +++ b/docs/CLI-TOOLS.md @@ -45,7 +45,10 @@ Use this when authoring workflows, not when you only need the command list below **2. TypeScript — `@gsd-build/sdk` (`GSDTools`, `createRegistry`)** -- `GSDTools` (used by `PhaseRunner`, `InitRunner`, and `GSD.createTools()`) always shells out to `gsd-tools.cjs` via `execFile` — there is no in-process registry path on this class. For typed, in-process dispatch use `createRegistry()` from `sdk/src/query/index.ts`, or invoke `gsd-sdk query` (see [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md)). +- `GSDTools` now routes through the **SDK Runtime Bridge Module** (`sdk/src/query-runtime-bridge.ts`). Native registry dispatch is preferred; subprocess fallback is explicit policy (`allowFallbackToSubprocess`) and can be disabled for strict SDK-only execution. +- `strictSdk` mode fails fast when a command has no native adapter, making SDK publish/readiness checks deterministic. +- Structured bridge observability is available via `onDispatchEvent` (dispatch mode, fallback reason, duration, outcome, error kind). +- For direct typed dispatch without `GSDTools`, use `createRegistry()` from `sdk/src/query/index.ts`, or invoke `gsd-sdk query` (see [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md)). - Conventions: mutation event wiring, `GSDError` vs `{ data: { error } }`, locks, and stubs — [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md). **CJS → SDK examples (same project directory):** diff --git a/docs/adr/0001-dispatch-policy-module.md b/docs/adr/0001-dispatch-policy-module.md index a85d16105..17ec2d013 100644 --- a/docs/adr/0001-dispatch-policy-module.md +++ b/docs/adr/0001-dispatch-policy-module.md @@ -1,5 +1,8 @@ # Dispatch policy module as single seam for query execution outcomes +- **Status:** Accepted +- **Date:** 2026-05-03 + We decided to centralize query dispatch outcomes in one Dispatch Policy Module that returns a structured union result (`ok` success or failure with typed `kind`, `details`, and final `exit_code`) instead of mixing throws and ad-hoc error mapping across CLI and SDK paths. This keeps fallback policy, timeout classification, and exit mapping in one place for better locality, prevents drift between native and fallback behavior, and makes callers thin adapters over a stable interface. ## Amendment (2026-05-03): query seam deepening completion @@ -24,3 +27,15 @@ Removed wrapper Modules after call-site convergence: - `query-registry-capability.ts` This amendment preserves the original ADR direction: keep policy depth high, adapters thin, and locality concentrated in explicit modules. + +## Amendment (2026-05-05): SDK Runtime Bridge seam deepening + +To make SDK dispatch a cleaner publishable seam, we deepened `GSDTools` dispatch behind one **SDK Runtime Bridge Module** (`sdk/src/query-runtime-bridge.ts`) and converged policy wiring into that seam: + +- `GSDTools` callers now route through one runtime bridge Interface for command resolution, execution, and hotpath dispatch. +- Added explicit fallback policy at the seam (`allowFallbackToSubprocess`) instead of implicit transport behavior. +- Added strict native-only enforcement mode (`strictSdk`) so SDK consumers can fail fast when a command lacks a native adapter. +- Added structured bridge observability (`onDispatchEvent`) for dispatch mode, fallback reason, latency, outcome, and error kind. +- Kept transport and command callers as thin adapters over the bridge seam. + +This continues the dispatch-policy design goal: deep policy Modules, thin Adapters, and high locality for behavior changes. diff --git a/sdk/src/query/QUERY-HANDLERS.md b/sdk/src/query/QUERY-HANDLERS.md index 474844579..afe6f283e 100644 --- a/sdk/src/query/QUERY-HANDLERS.md +++ b/sdk/src/query/QUERY-HANDLERS.md @@ -24,6 +24,15 @@ These families are sourced from `command-manifest.*.ts` files and expanded into CJS routing seams mirror these families with thin adapters (`state/verify/init/phase/phases/validate/roadmap-command-router.cjs`) so `gsd-tools.cjs` stays orchestration-only. +## SDK Runtime Bridge Module (`GSDTools` path) + +`GSDTools` dispatch routes through `sdk/src/query-runtime-bridge.ts`. + +- Native registry dispatch is preferred at the bridge seam. +- Subprocess fallback is explicit (`allowFallbackToSubprocess`), not implicit. +- `strictSdk` can fail fast when a command has no native adapter. +- `onDispatchEvent` emits structured dispatch observability (`query_dispatch` / `query_hotpath_dispatch`) with dispatch mode, fallback reason, latency, outcome, and error kind. + ## `gsd-sdk query` routing 1. **`normalizeQueryCommand()`** (`query-command-resolution-strategy.ts`) — maps the first argv tokens to the same **command + subcommand** patterns as `gsd-tools` `runCommand()` where needed (e.g. `state json` → `state.json`, `init execute-phase 9` → `init.execute-phase` with args `['9']`, `scaffold …` → `phase.scaffold`). Re-exported from **`@gsd-build/sdk`** and **`createRegistry`’s module** (`sdk/src/query/index.ts`) so programmatic callers can mirror CLI tokenization without importing a deep path.