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>
This commit is contained in:
38
.out-of-scope/statusline-account-usage.md
Normal file
38
.out-of-scope/statusline-account-usage.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Statusline Account / Usage Segment (credential-reading, external API)
|
||||
|
||||
GSD's statusline does not read credentials or call external network APIs to
|
||||
display account-level resource state (5-hour / 7-day rate-limit utilization,
|
||||
usage windows, plan quotas).
|
||||
|
||||
## Why this is out of scope
|
||||
|
||||
The statusline draws its data boundary at **local, read-only** sources — see
|
||||
[`docs/adr/2164-statusline-scope-boundary.md`](../docs/adr/2164-statusline-scope-boundary.md).
|
||||
It refines the stdin payload Claude Code already sends (model, context meter,
|
||||
GSD-state) and may add a new *local* source (e.g. `git`), but it does not:
|
||||
|
||||
- read Claude Code's OAuth credentials (`.credentials.json`, or the macOS login
|
||||
Keychain via `security`), or
|
||||
- make authenticated network calls (e.g. `https://api.anthropic.com/api/oauth/usage`)
|
||||
to fetch data.
|
||||
|
||||
Reasons:
|
||||
|
||||
- **Trust surface.** A planning-workflow hook reading an OAuth token is a
|
||||
materially larger trust surface than any rendering concern — even read-only,
|
||||
never-logged, and opt-in. Credential custody belongs to the platform, not to
|
||||
a markdown planning tool.
|
||||
- **Unstable dependency.** The usage endpoint is undocumented; it can change or
|
||||
disappear and silently rot the feature.
|
||||
- **Scope.** Surfacing account/rate-limit state is a platform (Claude Code)
|
||||
concern. This matches the prior in
|
||||
[`temporal-context.md`](./temporal-context.md): *"Statusline / TUI re-entry is
|
||||
platform-level, not GSD-level."*
|
||||
|
||||
**Revisit if** a documented, first-party usage API — or a platform-provided
|
||||
value delivered to the hook without GSD reading credentials — becomes
|
||||
available. That would move usage display out of the excluded tier.
|
||||
|
||||
## Prior requests
|
||||
|
||||
- #2164 — "enhancement(statusline): opt-in 5-hour/7-day account usage segment"
|
||||
@@ -124,6 +124,9 @@ Module owning runtime identity normalization at runtime-selection seams. Canonic
|
||||
### Host-Integration Interface
|
||||
Pure, additive, no-I/O Module owning the versioned, negotiated contract over the six host-integration interface points (command, dispatch, model, hooks, state, artifact) — ADR-1239 Phase A. Extends the ADR-1016 runtime descriptor with eight closed-vocabulary axes carried under `capability.json` `runtime.hostIntegration`: `embeddingMode` (`imperative|declarative`), `commandSurface` (`slash-file|slash-programmatic|slash-toml|palette|prose-only`), `dispatch` (`{namedDispatch,nested,maxDepth,background,backgroundDispatch,subagentToolkit}`), `modelMode` (`active|passive`), `hookBus` (`host|engine|none`), `stateIO` (`filesystem|sandboxed-storage|session-log-append`), `transport` (`mcp|native-extension`), `runtime` (`node|bun|sandboxed-web|python|go|rust|electron|other`). Interface: `negotiateHostCapabilities(host, engine?) → { protocolVersion, effective, points, warnings }` enforcing the trust-boundary invariant `effective ⊆ host-declared ∩ engine-known` (never augment with an undeclared or unknown/future-`protocolVersion` value — fail-closed via the most-restrictive-known `SAFE_DEFAULTS`); `degradationFor(point, axes) → { level, fallback }` (a pure Full/Degraded/Absent ladder table, never throws); `profileOf(axes) → 'programmatic-cli'|'declarative-cli'|'ide'|null`; plus `PROTOCOL_VERSION` (integer, starts at 1 — distinct from the package `version`/`engines.gsd` semver), `HOST_INTEGRATION_AXES` (the frozen closed vocabulary, single source of truth), `PROFILE_BASELINES`, and `shouldFlattenDispatch(dispatch) → boolean` (ADR-1239 Phase B / #1708 — graduates the #853 rule: returns `true` = run the orchestrator inline UNLESS the host is documented to background a nesting-capable orchestrator (`background === true && backgroundDispatch === true`); fail-closed to inline; exposed to the plan/execute workflows via the `gsd_run query dispatch-should-flatten --raw` CLI, which replaced the former scattered `RUNTIME === 'codex'` prose check). The runtime-descriptor validator (`gsd-core/bin/lib/capability-validator.cjs` `validateRuntimeBody`) mirrors the closed vocabulary inline (exported as `_HOST_INTEGRATION_VOCAB`) and is kept in lock-step by the parity guard `tests/host-integration-validator-parity.test.cjs`. Orthogonal axes (resolved explicitly per ADR-1239 Phase A): `commandStyle` (GSD emission style, retained) vs `commandSurface` (host surface type); `hookEvents` dialect vs `hookBus` ownership (a host with `hooksSurface:none` may still be `hookBus:host` — e.g. opencode); `runtimeCompat` (feature→host) vs these negotiated runtime→engine axes. Phase A defined the interface; Phase B (#1679) wires it incrementally — `destSubpath` write-confinement (#1704) and the typed documentation-sourced #853 dispatch-flatten (#1708, the first consumer of a negotiated `dispatch` axis); adapters/MCP/host-bindings remain Phases C–E. Source of truth: `gsd-core/bin/lib/host-integration.cjs` (generated from `src/host-integration.cts`). See ADR-1239 and ADR-1016.
|
||||
|
||||
### Statusline
|
||||
Host-integration hook (`hooks/gsd-statusline.js`) that renders the session status line: model name, context-window meter, workspace directory, and the GSD-state segment (`formatGsdState()` projecting `.planning/` STATE.md). Opt-in segments are gated by `.planning/config.json` keys (`statusline.show_last_command`, `statusline.context_position`, plus the approved `statusline.show_context_tokens` and `statusline.state_format`), each registered across `gsd-core/bin/shared/config-schema.manifest.json` + `src/config.cts` + the `loadConfig` whitelist + `docs/CONFIGURATION.md`. The compact GSD-state format consumes the canonical status vocabulary from `normalizeStateStatus()` (STATE.md Document Module) rather than a parallel keyword list. **Data-source boundary (ADR-2164):** the statusline sources only local, read-only data — it refines the stdin payload Claude Code already sends and may add a new *local* source (e.g. `git`), but does not read credentials or call external/network APIs for data; account/usage/platform-level state is out of scope.
|
||||
|
||||
### Install Engine Module
|
||||
Module owning the layout-driven runtime-artifact install pipeline — `installRuntimeArtifacts`, `uninstallRuntimeArtifacts`, `installOpencodeFamilySkills`, and their cluster helpers (`_copyStaged`, `_snapshotDir`/`_restoreDir`, legacy-migration + GSD-entry pruning, user-artifact preserve/restore). Extracted from the 12k-line `bin/install.js` (ADR-1239 Phase B, #1679) so adapters import the engine instead of reaching into the installer. Commit-attribution resolution stays in `bin/install.js` and is injected via a `resolveAttribution` parameter (the engine takes no config I/O). Source: `src/install-engine.cts` -> `gsd-core/bin/lib/install-engine.cjs`.
|
||||
|
||||
|
||||
44
docs/adr/2164-statusline-scope-boundary.md
Normal file
44
docs/adr/2164-statusline-scope-boundary.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Statusline draws its data boundary at local, read-only sources
|
||||
|
||||
- **Status:** Accepted
|
||||
- **Date:** 2026-07-11
|
||||
- **Issue:** #2164
|
||||
- **Implementation:** Policy ADR — no code change. Governs triage of statusline enhancement/feature requests.
|
||||
|
||||
## Decision
|
||||
|
||||
The GSD statusline (`hooks/gsd-statusline.js`) may source data from three tiers, and is bounded to the first two:
|
||||
|
||||
| Tier | Data source | In scope? |
|
||||
|------|-------------|-----------|
|
||||
| 0 — Refine existing | The stdin payload Claude Code already sends (model name, context-window usage, GSD-state read from `.planning/`) | Yes |
|
||||
| 1 — New local source | Read-only local reads / bounded subprocesses scoped to the workspace (e.g. `git status`) | Yes, if opt-in and bounded |
|
||||
| 2 — External / credentialed | Reading credentials (OAuth tokens, keychains) or calling external/network APIs for data | No |
|
||||
|
||||
The statusline refines what it is already handed and may add a new **local, read-only** source, but it does not read credentials or make authenticated/network calls to fetch data. Surfacing account-level or platform-level resource state (usage limits, rate-limit windows) from a GSD hook is a platform concern, not GSD's.
|
||||
|
||||
## Rationale
|
||||
|
||||
- The statusline is a planning-workflow surface, not a platform dashboard. Its existing segments (model, context meter, directory, GSD-state) are all local, read-only projections of data GSD is already given.
|
||||
- Reading credentials from a planning hook is a materially larger trust surface than any rendering concern; even read-only and opt-in, it is not something a planning tool should own.
|
||||
- External/undocumented endpoints (e.g. an OAuth usage API) are unstable dependencies that rot silently when they change.
|
||||
- Consistent with the existing prior in `.out-of-scope/temporal-context.md`: *"Statusline / TUI re-entry is platform-level, not GSD-level."*
|
||||
|
||||
## Consequences
|
||||
|
||||
- New statusline requests are triaged against the tier table. The **data-source** axis (this ADR) is orthogonal to the **enhancement-vs-feature** axis (CONTRIBUTING.md): refining an existing segment is an enhancement; adding a new segment or data source is a feature (a new concept/integration), regardless of tier.
|
||||
- Applied at decision time:
|
||||
- **#2160 / #2161 / #2162** — refine existing model / context-meter / GSD-state rendering. Tier 0; approved as enhancements.
|
||||
- **#2163** — git segment. Tier 1 (new local source): in scope, but routed to the feature track (`approved-feature` + complete spec) because it adds a new segment.
|
||||
- **#2164** — 5h/7d account-usage segment. Tier 2 (reads OAuth creds + calls `api.anthropic.com/api/oauth/usage`): out of scope; closed `wontfix`, recorded in `.out-of-scope/statusline-account-usage.md`.
|
||||
|
||||
## Revisit if
|
||||
|
||||
A documented, first-party usage API — or a platform-provided value delivered to the hook without GSD reading credentials — becomes available. That would move usage display out of Tier 2.
|
||||
|
||||
## References
|
||||
|
||||
- `.out-of-scope/statusline-account-usage.md` — the #2164 rejection record.
|
||||
- `.out-of-scope/temporal-context.md` — prior "statusline is platform-level" note.
|
||||
- `CONTRIBUTING.md` — enhancement vs feature gates.
|
||||
- Issues: #2160, #2161, #2162 (approved enhancements), #2163 (feature-track), #2164 (this ADR's trigger).
|
||||
@@ -67,6 +67,7 @@ See **[CONTRIBUTING.md — "Proposing an ADR or PRD"](../../CONTRIBUTING.md#prop
|
||||
| [1990-existing-code-onboarding.md](1990-existing-code-onboarding.md) | Existing Code Onboarding Module owns deterministic repo-state detection and onboarding route selection | Proposed |
|
||||
| [2121-phase-identifier-parsing-consolidation.md](2121-phase-identifier-parsing-consolidation.md) | Phase-identifier parsing consolidation — single canonical owner (phase-id.cts) + anti-divergence guard | Accepted |
|
||||
| [2143-markdown-table-and-mutation-consolidation.md](2143-markdown-table-and-mutation-consolidation.md) | Markdown table model, bounded mutation, and fail-loud consolidation (#1372 part 2) | Accepted |
|
||||
| [2164-statusline-scope-boundary.md](2164-statusline-scope-boundary.md) | Statusline draws its data boundary at local, read-only sources (no external/credentialed data) | Accepted |
|
||||
|
||||
## Seam map
|
||||
|
||||
|
||||
Reference in New Issue
Block a user