* chore(#604): rename get-shit-done/ runtime directory to gsd-core/ Renames the installed runtime directory `get-shit-done/` to `gsd-core/` so the on-disk name matches the package (`@opengsd/gsd-core`), repo, and binary (`gsd-tools`). The npm package name and binary are unchanged; npx/npm consumers are unaffected. Mechanical (bulk, ~90% of the diff): - `git mv get-shit-done gsd-core` - Swept path/identifier references across the repo via `perl -pe 's/get-shit-done(?!-\w)/gsd-core/g'`. The negative lookahead preserves the five legitimate slug variants that are NOT the directory: get-shit-done-{OLD,cc,classic,cli,redux} (old package/repo names). - Build/manifest wiring: package.json (bin, files, coverage globs), tsconfig.build.json (outDir), ~86 .gitignore build-output entries, stryker.config.mjs, scan-ignore files, install.js path strings. - Frozen (not rewritten): CHANGELOG.md history; translated docs (README.<locale>.md and docs/{ja-JP,ko-KR,pt-BR,zh-CN}/). New logic (review here): - src/installer-migrations/003-rename-get-shit-done-to-gsd-core.cts: a proper ADR-0008 installer migration. On upgrade it walks the legacy `~/.claude/get-shit-done/` tree, classifies each file via the prior install manifest, and emits remove-managed / backup-and-remove for managed files while PRESERVING unknown user-added files. Symlink-safe (skips a symlinked root and symlinked entries; bounds-checks every path under configDir). The framework rolls back on install failure. Emptied dirs may remain (framework has no recursive dir-removal primitive) — documented. - scripts/lint-legacy-dir-name.cjs: CI regression guard forbidding the bare `get-shit-done` directory token (split token to avoid self-match; case- insensitive; `(?!-\w)` lookahead allows the slug variants; allowlists CHANGELOG, translated docs, and `gsd-allow-legacy-name` marker lines). Wired into the lint-tests CI job. - Restored scripts/lint-package-identity-drift.cjs detection regexes (the mechanical sweep had wrongly rewritten the old-name patterns it exists to detect) and marked them as intentional legacy references. - TDD tests for the migration and the guard; do.md slash-command guard regex tightened so a `/gsd-core/bin` path segment is not mistaken for a command; changeset + docs/installer-migrations.md row added. Breaking: the installed runtime path moves `~/.claude/get-shit-done/` -> `~/.claude/gsd-core/`. Migration 003 removes the stale legacy dir's managed files (preserving user files) on upgrade. Users with custom hooks/configs hardcoding the old path must update them. Closes #604 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): unsweep pending changesets + allowlist injection-example docs CI fixes for the rename PR: - Do not sweep pending .changeset/*.md (ephemeral release-note fragments, like CHANGELOG); reverted those body edits so 5 pre-existing malformed fragments (missing type/pr) no longer enter the PR diff and trip docs-lint. Allowlisted .changeset/ in the legacy-name guard accordingly. - Allowlisted TEST-EXAMPLES.md and docs/explanation/security-model.md in prompt-injection-scan.sh: they contain intentional injection examples / security-model prose; the path-reference rewrites are kept. CodeQL alerts on this PR are pre-existing (alert lines unchanged by this PR; none in the new migration/guard) and are out of scope for the rename. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): resolve CodeQL alerts surfaced on this PR The rename diff touched files carrying pre-existing CodeQL findings; per the no-pre-existing-dismissal rule, fixing every surfaced alert rather than waving them off. All behavior-preserving: - scripts/ci-test-scope.cjs: build the config-path match from string .includes() instead of a RegExp over an arg-derived value (js/regex-injection). - src/profile-output.cts: escape backslashes before pipe-escaping desc/safeName so the table-cell escape is complete (js/incomplete-sanitization). - tests/{bug-2643,bug-2808,docs-parity-live-registry}: two-pass HTML-comment strip so a bare/unclosed `<!--` cannot survive (js/incomplete-multi-character-sanitization). - tests/inline-plan-threshold: drop the no-op `\s`->`\s` identity replace, keep the meaningful POSIX-class conversion (js/identity-replacement). Verified: build:lib green; the touched test files + ci-test-scope + profile-output suites pass; lint:legacy-name clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): correctly resolve remaining CodeQL alerts (regex-injection + sanitization) The prior commit's fixes for two alerts were ineffective: - ci-test-scope.cjs js/regex-injection: the alert is the CLI-arg-derived `file` reaching static regex `.test(file)` calls (not the config rule). Removed ALL regex over file/t — startsWith/includes/=== string checks + an isWindowsHint helper — so there is no regex sink for the tainted value. - js/incomplete-multi-character-sanitization (3 test files): a single `.replace(/<!--...-->/g,'')` can let `<!--` re-form. Replaced with a fixpoint loop (replace until stable) plus a final bare-opener strip. Verified: no regex over file/t remains; ci-test-scope + the 3 test suites pass; lint:legacy-name clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): make ci-test-scope + comment-strippers regex-free to clear CodeQL CodeQL flags the regex PATTERNS syntactically (regex-injection on the --files arg split; incomplete-multi-character-sanitization on the <!--...--> replace), so loop fixes do not satisfy it. Made these paths regex-free: - ci-test-scope.cjs splitFiles: char-by-char separator tokenizer (no /[,\\s]+/). - 3 test files: indexOf/slice HTML-comment stripper (no .replace(/<!--/)). Behavior preserved; ci-test-scope + the 3 suites pass; guard clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): unblock security base64 scan on the large rename diff The security job hit its 10m timeout: base64-scan.sh choked on the binary test fixture tests/feat-3594-parser-property-style.test.cjs (embedded NUL/ non-UTF8 bytes -> thousands of bogus blobs + "ignored null byte" warnings), and the ~800-file rename diff is slow to scan regardless. - scripts/base64-scan.sh: skip binary-by-content files (grep -Iq .) — they can't carry base64-obfuscated *text* and feeding NUL bytes through the per-line scanner is pathologically slow. collect_files already filtered binary *extensions*; this catches binary *content* in text extensions. - .github/workflows/security-scan.yml: raise the security job timeout 10m->30m to accommodate very large diffs (the scan itself is unchanged). Verified locally: scan skips the fixture, 0 "ignored null byte" warnings, 0 findings, exit 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): sweep get-shit-done refs introduced by merging next The branch was updated with next (#614/#384/#618 etc.), which reference the get-shit-done/ dir (still named that on next). Swept the stale references in the merged files to gsd-core so the rename stays consistent and lint:legacy-name passes: - commands/gsd/discuss-phase.md (runtime-launcher shim paths) - src/core.cts (getAgentsDir layout comments) - tests/bug-384-agents-runtime-aware.test.cjs (require path to runtime lib) Verified: guard 0 violations; build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): exclude gsd-core/ path segments from bug-3683 command cross-ref invariant The #614 runtime-launcher shim added to discuss-phase.md references `${_GSD_RUNTIME_ROOT}/gsd-core/bin/...`. bug-3683's REF_PATTERN excluded path-y refs only via lookbehind, but `}` precedes `/gsd-core/` in the shim, so it mis-read the directory path as a dangling `/gsd-core` command ref (same class as the #604 bug-2954 fix). Added a trailing `(?![\w-]*\/)` so `/gsd-<x>/...` path segments are not treated as slash-command references. Verified locally on BOTH platforms before pushing: - mac (node 26) full suite: 0 failures - gsd-test-runner (linux, node22 image) full suite: 0 failures - bug-3683 + bug-2954 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): lazily resolve findProjectRoot in gsd-tools (harden flaky CI) CI intermittently failed state.test's gsd-tools subprocess with "findProjectRoot is not a function" (flip-flopping across legs; not reproducible on mac full suite, gsd-test linux full suite, test:unit, or state.test x8). findProjectRoot is a re-export from core.cjs (sourced from project-root.cjs); binding it via destructure at module-load can be undefined under a load-ordering edge. Resolve it lazily at call time via a small wrapper so the lookup happens after core.cjs is fully initialized. Verified green on BOTH platforms before pushing: - mac (node 26) full suite: 0 failures - gsd-test-runner (linux, node22) full suite: 0 failures - state.test.cjs: 106/106; gsd-tools loads cleanly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): allowlist verification-patterns.md placeholder examples in secret scan The rename git-mv'd references/verification-patterns.md into gsd-core/, pulling it into the secret-scan diff. It documents stub/placeholder RED-FLAG env-var examples (illustrative Stripe test-key / database-URL / API-key placeholders) — not real credentials. Added it to .secretscanignore with the strict annotation, mirroring the existing gsd-core/workflows/plan-phase.md exception. Verified locally: secret-scan-lint --strict OK; secret-scan --diff origin/next exits 0 with 0 findings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -613,7 +613,7 @@ Twelve additional agents ship under `agents/gsd-*.md` and are used by specialty
|
||||
| **Color** | `#F59E0B` (amber) |
|
||||
| **Produces** | Sections 5–7 of `AI-SPEC.md` (Evaluation Strategy, Guardrails, Production Monitoring) |
|
||||
|
||||
**Required reading:** `get-shit-done/references/ai-evals.md` (evaluation framework).
|
||||
**Required reading:** `gsd-core/references/ai-evals.md` (evaluation framework).
|
||||
|
||||
**Key behaviors:**
|
||||
- Turns domain-researcher rubric ingredients into measurable, tooled evaluation criteria
|
||||
@@ -634,7 +634,7 @@ Twelve additional agents ship under `agents/gsd-*.md` and are used by specialty
|
||||
| **Color** | `#EF4444` (red) |
|
||||
| **Produces** | `EVAL-REVIEW.md` with dimension scores, findings, and remediation guidance |
|
||||
|
||||
**Required reading:** `get-shit-done/references/ai-evals.md`.
|
||||
**Required reading:** `gsd-core/references/ai-evals.md`.
|
||||
|
||||
**Key behaviors:**
|
||||
- Compares the implemented codebase against the planned eval strategy — never re-plans
|
||||
@@ -655,7 +655,7 @@ Twelve additional agents ship under `agents/gsd-*.md` and are used by specialty
|
||||
| **Color** | `#38BDF8` (sky blue) |
|
||||
| **Produces** | Scored ranked recommendation (structured return to orchestrator) |
|
||||
|
||||
**Required reading:** `get-shit-done/references/ai-frameworks.md` (decision matrix).
|
||||
**Required reading:** `gsd-core/references/ai-frameworks.md` (decision matrix).
|
||||
|
||||
**Key behaviors:**
|
||||
- Scans `package.json`, `pyproject.toml`, `requirements*.txt` for existing AI libraries before the interview to avoid recommending a rejected framework
|
||||
|
||||
@@ -42,7 +42,7 @@ GSD Core is a **meta-prompting framework** that sits between the user and AI cod
|
||||
│
|
||||
┌─────────────────────▼────────────────────────────────┐
|
||||
│ WORKFLOW LAYER │
|
||||
│ get-shit-done/workflows/*.md — Orchestration logic │
|
||||
│ gsd-core/workflows/*.md — Orchestration logic │
|
||||
│ (Reads references, spawns agents, manages state) │
|
||||
└──────┬──────────────┬─────────────────┬──────────────┘
|
||||
│ │ │
|
||||
@@ -75,7 +75,7 @@ Every agent spawned by an orchestrator gets a clean context window (up to 200K t
|
||||
|
||||
### 2. Thin Orchestrators
|
||||
|
||||
Workflow files (`get-shit-done/workflows/*.md`) never do heavy lifting. They:
|
||||
Workflow files (`gsd-core/workflows/*.md`) never do heavy lifting. They:
|
||||
|
||||
- Load context via `gsd-tools.cjs init <workflow>`
|
||||
- Spawn specialized agents with focused prompts
|
||||
@@ -130,7 +130,7 @@ The router descriptions use pipe-separated keyword tags (≤ 60 chars) per the T
|
||||
|
||||
The eager skill listing is one of two recurring per-turn token costs. The other is the MCP tool schema injected by every enabled MCP server in `.claude/settings.json`. Heavyweight MCP servers (browser/playwright, Mac-tools, Windows-tools) can each cost 20 k+ tokens per turn — often dwarfing what `model_profile` tuning saves. The toggle lives in the Claude Code harness (`enabledMcpjsonServers` / `disabledMcpjsonServers` in `.claude/settings.json`) and is **not** a GSD concern. Together, the two-stage routing layer (#2792) and disciplined MCP enablement are the largest cost levers per turn. See [`docs/USER-GUIDE.md`](USER-GUIDE.md) and `references/context-budget.md` for the audit checklist.
|
||||
|
||||
### Workflows (`get-shit-done/workflows/*.md`)
|
||||
### Workflows (`gsd-core/workflows/*.md`)
|
||||
|
||||
Orchestration logic that commands reference. Contains the step-by-step process including:
|
||||
|
||||
@@ -159,7 +159,7 @@ mirrors the agent budget from #2361:
|
||||
issue #2551. When a workflow grows beyond its tier, extract per-mode bodies
|
||||
into `workflows/<workflow>/modes/<mode>.md`, templates into
|
||||
`workflows/<workflow>/templates/`, and shared knowledge into
|
||||
`get-shit-done/references/`. The parent file becomes a thin dispatcher that
|
||||
`gsd-core/references/`. The parent file becomes a thin dispatcher that
|
||||
Reads only the mode and template files needed for the current invocation.
|
||||
|
||||
`workflows/discuss-phase/` is the canonical example of this pattern —
|
||||
@@ -180,7 +180,7 @@ Specialized agent definitions with frontmatter specifying:
|
||||
|
||||
**Total agents:** 33
|
||||
|
||||
### References (`get-shit-done/references/*.md`)
|
||||
### References (`gsd-core/references/*.md`)
|
||||
|
||||
Shared knowledge documents that workflows and agents `@-reference` (see [`docs/INVENTORY.md`](INVENTORY.md#references-41-shipped) for the authoritative count and full roster):
|
||||
|
||||
@@ -234,7 +234,7 @@ The planner agent (`agents/gsd-planner.md`) was decomposed from a single monolit
|
||||
- `planner-reviews.md` — Cross-AI review integration (reads REVIEWS.md from `/gsd-review`)
|
||||
- `planner-revision.md` — Plan revision patterns for iterative refinement
|
||||
|
||||
### Templates (`get-shit-done/templates/`)
|
||||
### Templates (`gsd-core/templates/`)
|
||||
|
||||
Markdown templates for all planning artifacts. Used by `gsd-tools.cjs template fill` / `phase.scaffold` (and top-level `scaffold`) to create pre-structured files:
|
||||
- `project.md`, `requirements.md`, `roadmap.md`, `state.md` — Core project files
|
||||
@@ -266,13 +266,13 @@ Runtime hooks that integrate with the host AI agent:
|
||||
|
||||
See [`docs/INVENTORY.md`](INVENTORY.md#hooks-11-shipped) for the authoritative 11-hook roster.
|
||||
|
||||
### Command Routing Hub (`get-shit-done/bin/lib/command-routing-hub.cjs`)
|
||||
### Command Routing Hub (`gsd-core/bin/lib/command-routing-hub.cjs`)
|
||||
|
||||
CJS command family routers dispatch through `CommandRoutingHub`. The hub owns the no-throw pure-result contract (`hub.dispatch()` catches internal exceptions and returns `{ ok: false, kind, ...typedPayload }`) and the closed runtime error taxonomy (`UnknownCommand`, `InvalidArgs`, `HandlerRefusal`, `HandlerFailure`). Router adapters remain thin CLI translators — they build the hub, call `dispatch`, then map the Result to `output()`/`error()` calls. The runtime is single-path (no dual-runtime mode selection). See `docs/adr/0174-retire-gsd-sdk-package-boundary.md`.
|
||||
|
||||
### CLI Tools (`get-shit-done/bin/`)
|
||||
### CLI Tools (`gsd-core/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):
|
||||
Node.js CLI utility (`gsd-tools.cjs`) with domain modules split across `gsd-core/bin/lib/` (see [`docs/INVENTORY.md`](INVENTORY.md#cli-modules-33-shipped) for the authoritative roster):
|
||||
|
||||
|
||||
| Module | Responsibility |
|
||||
@@ -479,7 +479,7 @@ UI-SPEC.md (per phase) ───────────────────
|
||||
~/.claude/ # Claude Code (global install)
|
||||
├── skills/gsd-*/SKILL.md # Global skills (authoritative roster: docs/INVENTORY.md)
|
||||
├── commands/gsd/*.md # Local Claude installs use slash commands instead of global skills
|
||||
├── get-shit-done/
|
||||
├── gsd-core/
|
||||
│ ├── bin/gsd-tools.cjs # CLI utility
|
||||
│ ├── bin/lib/*.cjs # Domain modules (authoritative roster: docs/INVENTORY.md)
|
||||
│ ├── workflows/*.md # Workflow definitions (authoritative roster: docs/INVENTORY.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# GSD CLI Tools Reference
|
||||
|
||||
> Reference for the `gsd-tools` CLI (`get-shit-done/bin/gsd-tools.cjs`). For slash commands and user flows, see [Command Reference](COMMANDS.md). Return to [docs index](README.md).
|
||||
> Reference for the `gsd-tools` CLI (`gsd-core/bin/gsd-tools.cjs`). For slash commands and user flows, see [Command Reference](COMMANDS.md). Return to [docs index](README.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
| | |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Shipped path** | `get-shit-done/bin/gsd-tools.cjs` |
|
||||
| **Implementation** | 20 domain modules under `get-shit-done/bin/lib/` (the directory is authoritative) |
|
||||
| **Shipped path** | `gsd-core/bin/gsd-tools.cjs` |
|
||||
| **Implementation** | 20 domain modules under `gsd-core/bin/lib/` (the directory is authoritative) |
|
||||
| **Status** | Primary runtime command surface for orchestration, workflows, and automation. |
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@ Slugs are validated against `[a-zA-Z0-9_-]+`; empty or path-containing slugs are
|
||||
|
||||
## Secret Handling
|
||||
|
||||
API keys configured via `/gsd-settings` (`brave_search`, `firecrawl`, `exa_search`) are written plaintext to `.planning/config.json` but are masked (`****<last-4>`) in every `config-set` / `config-get` output, confirmation table, and interactive prompt. See `get-shit-done/bin/lib/secrets.cjs` for the masking implementation. The `config.json` file itself is the security boundary — protect it with filesystem permissions and keep it out of git (`.planning/` is gitignored by default).
|
||||
API keys configured via `/gsd-settings` (`brave_search`, `firecrawl`, `exa_search`) are written plaintext to `.planning/config.json` but are masked (`****<last-4>`) in every `config-set` / `config-get` output, confirmation table, and interactive prompt. See `gsd-core/bin/lib/secrets.cjs` for the masking implementation. The `config.json` file itself is the security boundary — protect it with filesystem permissions and keep it out of git (`.planning/` is gitignored by default).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -594,7 +594,7 @@ Show GSD commands at the tier you ask for. Default fits one screen; `--full` is
|
||||
/gsd-help --brief <topic> # Compact scoped lookup — signature + one-line summary
|
||||
```
|
||||
|
||||
See `get-shit-done/workflows/help/modes/topic.md` for the full alias table. Unknown topics print the recognized list.
|
||||
See `gsd-core/workflows/help/modes/topic.md` for the full alias table. Unknown topics print the recognized list.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ API key fields accept a string value (the key itself). They can also be set to t
|
||||
| `firecrawl` | string \| boolean \| null | `null` | Firecrawl API key for deep-crawl scraping. Masked in display |
|
||||
| `exa_search` | string \| boolean \| null | `null` | Exa Search API key for semantic search. Masked in display |
|
||||
|
||||
**Masking convention (`get-shit-done/bin/lib/secrets.cjs`):** keys 8+ characters render as `****<last-4>`; shorter keys render as `****`; `null`/empty renders as `(unset)`. Plaintext is written as-is to `.planning/config.json` — that file is the security boundary — but the CLI, confirmation tables, logs, and `AskUserQuestion` descriptions never display the plaintext. This applies to the `config-set` command output itself: `config-set brave_search <key>` returns a JSON payload with the value masked.
|
||||
**Masking convention (`gsd-core/bin/lib/secrets.cjs`):** keys 8+ characters render as `****<last-4>`; shorter keys render as `****`; `null`/empty renders as `(unset)`. Plaintext is written as-is to `.planning/config.json` — that file is the security boundary — but the CLI, confirmation tables, logs, and `AskUserQuestion` descriptions never display the plaintext. This applies to the `config-set` command output itself: `config-set brave_search <key>` returns a JSON payload with the value masked.
|
||||
|
||||
### Code-review CLI routing
|
||||
|
||||
@@ -257,7 +257,7 @@ All workflow toggles follow the **absent = enabled** pattern. If a key is missin
|
||||
| `workflow.plan_chunked` | boolean | `false` | Enable chunked planning mode. When `true` (or when `--chunked` flag is passed to `/gsd-plan-phase`), the orchestrator splits the single long-lived planner Task into a short outline Task followed by N short per-plan Tasks (~3-5 min each). Each plan is committed individually for crash resilience. If a Task hangs and the terminal is force-killed, rerunning with `--chunked` resumes from the last completed plan. Particularly useful on Windows where long-lived Tasks may hang on stdio. Added in v1.38 |
|
||||
| `workflow.code_review_command` | string | (none) | Shell command for external code review integration in `/gsd-ship`. Receives changed file paths via stdin. Non-zero exit blocks the ship workflow. Added in v1.36 |
|
||||
| `workflow.tdd_mode` | boolean | `false` | Enable TDD pipeline as a first-class execution mode. When `true`, the planner aggressively applies `type: tdd` to eligible tasks (business logic, APIs, validations, algorithms) and the executor enforces RED/GREEN/REFACTOR gate sequence. An end-of-phase collaborative review checkpoint verifies gate compliance. Added in v1.36 |
|
||||
| `workflow.human_verify_mode` | string | `'end-of-phase'` | Controls human verification checkpoints. `'end-of-phase'` (default since #3309) suppresses `checkpoint:human-verify` tasks and embeds checks into `<verify><human-check>` blocks for end-of-phase review. `'mid-flight'` restores blocking checkpoint tasks. `checkpoint:decision` and `checkpoint:human-action` are unaffected. See [Checkpoints Reference](../get-shit-done/references/checkpoints.md#checkpoint_types). |
|
||||
| `workflow.human_verify_mode` | string | `'end-of-phase'` | Controls human verification checkpoints. `'end-of-phase'` (default since #3309) suppresses `checkpoint:human-verify` tasks and embeds checks into `<verify><human-check>` blocks for end-of-phase review. `'mid-flight'` restores blocking checkpoint tasks. `checkpoint:decision` and `checkpoint:human-action` are unaffected. See [Checkpoints Reference](../gsd-core/references/checkpoints.md#checkpoint_types). |
|
||||
| `workflow.cross_ai_execution` | boolean | `false` | Delegate phase execution to an external AI CLI instead of spawning local executor agents. Useful for leveraging a different model's strengths for specific phases. Added in v1.36 |
|
||||
| `workflow.cross_ai_command` | string | (none) | Shell command template for cross-AI execution. Receives the phase prompt via stdin. Must produce SUMMARY.md-compatible output. Required when `cross_ai_execution` is `true`. Added in v1.36 |
|
||||
| `workflow.cross_ai_timeout` | number | `300` | Timeout in seconds for cross-AI execution commands. Prevents runaway external processes. Added in v1.36 |
|
||||
@@ -286,7 +286,7 @@ The `code_quality.*` namespace gates optional structural-analysis tooling that a
|
||||
|
||||
## Ship Settings
|
||||
|
||||
`ship.pr_body_sections` adds additional PR body sections for project-specific PRD/PR body content in `/gsd-ship` without editing `get-shit-done/workflows/ship.md`.
|
||||
`ship.pr_body_sections` adds additional PR body sections for project-specific PRD/PR body content in `/gsd-ship` without editing `gsd-core/workflows/ship.md`.
|
||||
|
||||
For a user guide with onboarding examples and troubleshooting, see [Custom PR Body Sections](ship-pr-body-sections.md).
|
||||
|
||||
@@ -786,7 +786,7 @@ Invalid flag tokens are sanitized and logged as warnings. Only recognized GSD fl
|
||||
| gsd-doc-writer | Opus | Sonnet | Haiku | Sonnet | Inherit |
|
||||
| gsd-doc-verifier | Sonnet | Sonnet | Haiku | Haiku | Inherit |
|
||||
|
||||
> **All 33 shipped agents have explicit per-profile tier assignments** in the catalog (`sdk/shared/model-catalog.json`). The table above shows a representative subset of the most-used agents. For agents not listed here, `model_overrides` accepts any shipped agent name. The authoritative profile data is derived from `sdk/shared/model-catalog.json` via `get-shit-done/bin/lib/model-catalog.cjs` and `sdk/src/model-catalog.ts`.
|
||||
> **All 33 shipped agents have explicit per-profile tier assignments** in the catalog (`sdk/shared/model-catalog.json`). The table above shows a representative subset of the most-used agents. For agents not listed here, `model_overrides` accepts any shipped agent name. The authoritative profile data is derived from `sdk/shared/model-catalog.json` via `gsd-core/bin/lib/model-catalog.cjs` and `sdk/src/model-catalog.ts`.
|
||||
|
||||
### Per-Agent Overrides
|
||||
|
||||
|
||||
@@ -2087,7 +2087,7 @@ Test suite that scans all agent, workflow, and command files for embedded inject
|
||||
|
||||
### 92. Gates Taxonomy
|
||||
|
||||
**References:** `get-shit-done/references/gates.md`
|
||||
**References:** `gsd-core/references/gates.md`
|
||||
**Agents:** plan-checker, verifier
|
||||
|
||||
**Purpose:** Define 4 canonical gate types that structure all workflow decision points, enabling plan-checker and verifier agents to apply consistent gate logic.
|
||||
@@ -2936,7 +2936,7 @@ explicit reviewer flags -> --all -> review.default_reviewers -> all detected rev
|
||||
- REQ-HUMAN-VERIFY-02: Human-needed verification MUST remain pending until the end-of-phase review resolves it.
|
||||
- REQ-HUMAN-VERIFY-03: Configs without the key MUST use `"end-of-phase"`.
|
||||
|
||||
**Reference:** [Checkpoints Reference](../get-shit-done/references/checkpoints.md)
|
||||
**Reference:** [Checkpoints Reference](../gsd-core/references/checkpoints.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ These six routers are descriptor-only entries that the model picks first; the bo
|
||||
|
||||
## Workflows (88 shipped)
|
||||
|
||||
Full roster at `get-shit-done/workflows/*.md`. Workflows are thin orchestrators that commands reference internally; most are not read directly by end users. Rows below map each workflow file to its role (derived from the `<purpose>` block) and, where applicable, to the command that invokes it.
|
||||
Full roster at `gsd-core/workflows/*.md`. Workflows are thin orchestrators that commands reference internally; most are not read directly by end users. Rows below map each workflow file to its role (derived from the `<purpose>` block) and, where applicable, to the command that invokes it.
|
||||
|
||||
| Workflow | Role | Invoked by |
|
||||
|----------|------|------------|
|
||||
@@ -266,7 +266,7 @@ Full roster at `get-shit-done/workflows/*.md`. Workflows are thin orchestrators
|
||||
|
||||
## References (63 shipped)
|
||||
|
||||
Full roster at `get-shit-done/references/*.md`. References are shared knowledge documents that workflows and agents `@-reference`. The groupings below match [`docs/ARCHITECTURE.md`](ARCHITECTURE.md#references-get-shit-donereferencesmd) — core, workflow, thinking-model clusters, and the modular planner decomposition.
|
||||
Full roster at `gsd-core/references/*.md`. References are shared knowledge documents that workflows and agents `@-reference`. The groupings below match [`docs/ARCHITECTURE.md`](ARCHITECTURE.md#references-gsd-corereferencesmd) — core, workflow, thinking-model clusters, and the modular planner decomposition.
|
||||
|
||||
### Core References
|
||||
|
||||
@@ -362,13 +362,13 @@ The `gsd-planner` agent is decomposed into a core agent plus reference modules t
|
||||
| `user-story-template.md` | User story format for MVP planning — "As a / I want to / So that" structured fields. |
|
||||
| `spidr-splitting.md` | SPIDR splitting decomposition rules for handling large user stories in MVP mode. |
|
||||
|
||||
> **Subdirectory:** `get-shit-done/references/few-shot-examples/` contains additional few-shot examples (`plan-checker.md`, `verifier.md`) that are referenced from specific agents. These are not counted in the 63 top-level references.
|
||||
> **Subdirectory:** `gsd-core/references/few-shot-examples/` contains additional few-shot examples (`plan-checker.md`, `verifier.md`) that are referenced from specific agents. These are not counted in the 63 top-level references.
|
||||
|
||||
---
|
||||
|
||||
## CLI Modules (82 shipped)
|
||||
|
||||
Full listing: `get-shit-done/bin/lib/*.cjs`.
|
||||
Full listing: `gsd-core/bin/lib/*.cjs`.
|
||||
|
||||
| Module | Responsibility |
|
||||
|--------|----------------|
|
||||
@@ -443,7 +443,7 @@ Full listing: `get-shit-done/bin/lib/*.cjs`.
|
||||
| `task-command-router.cjs` | Thin CJS subcommand router adapter for `gsd-tools task` |
|
||||
| `template.cjs` | Template selection and filling with variable substitution |
|
||||
| `uat.cjs` | UAT file parsing, verification debt tracking, audit-uat support |
|
||||
| `ui-safety-gate.cjs` | Shell-free word-boundary UI token detector (#3706, #3718); reads phase-section text from stdin, exits 0 (UI found) or 1 (no UI); also deployed to `get-shit-done/bin/lib/` so the GSD installer ships it to `$RUNTIME_DIR` (#448) |
|
||||
| `ui-safety-gate.cjs` | Shell-free word-boundary UI token detector (#3706, #3718); reads phase-section text from stdin, exits 0 (UI found) or 1 (no UI); also deployed to `gsd-core/bin/lib/` so the GSD installer ships it to `$RUNTIME_DIR` (#448) |
|
||||
| `update-context.cjs` | Pure install-context resolver for `/gsd:update` — runtime/scope/config-dir/version detection (LOCAL/GLOBAL/UNKNOWN) ported from update.md bash; backs `gsd-tools update-context` (#498) |
|
||||
| `validate-command-router.cjs` | Thin CJS subcommand router adapter for `gsd-tools validate` |
|
||||
| `validate.cjs` | Pure phase variant normalization helpers (`phaseVariants`, `buildRoadmapPhaseVariants`, `buildNotStartedPhaseVariants`) used by `verify.cjs` for W006/W007 checks; no I/O, no async |
|
||||
|
||||
@@ -111,7 +111,7 @@ canonical Codex hooks, and the SDK bridge load path.
|
||||
|
||||
- **Configuration manifests load from the installed payload** —
|
||||
`configuration.generated.cjs` looks in the installed
|
||||
`get-shit-done/bin/shared/` path first, then falls back to
|
||||
`gsd-core/bin/shared/` path first, then falls back to
|
||||
source-checkout `sdk/shared/`. Fixes the install where the manifest
|
||||
loader failed on the runtime layout because the source-tree path
|
||||
doesn't exist after install.
|
||||
|
||||
@@ -35,17 +35,17 @@ A new top-level command that walks the user through framing a phase as a vertica
|
||||
- Mutates the ROADMAP entry to set `**Mode:** mvp` and replaces `**Goal:**` with the assembled user story
|
||||
- Delegates to `/gsd plan-phase --mvp <N>` to produce the plan
|
||||
|
||||
Two new references: [`spidr-splitting.md`](../get-shit-done/references/spidr-splitting.md), [`user-story-template.md`](../get-shit-done/references/user-story-template.md).
|
||||
Two new references: [`spidr-splitting.md`](../gsd-core/references/spidr-splitting.md), [`user-story-template.md`](../gsd-core/references/user-story-template.md).
|
||||
|
||||
#### Execute-phase MVP+TDD runtime gate ([#2878](https://github.com/GSD-redux/get-shit-done-redux/pull/2878))
|
||||
|
||||
When `MVP_MODE` and `TDD_MODE` are both true at execution time, `execute-phase` adds a per-task gate that requires a `test(<phase>-<plan>):` commit to exist before the corresponding `feat(...)` commit. The reference [`execute-mvp-tdd.md`](../get-shit-done/references/execute-mvp-tdd.md) documents the contract; the executor agent (`agents/gsd-executor.md`) gains an MVP+TDD Gate section that explains when the gate trips, what evidence it expects, and how to escalate via the documented escape hatch.
|
||||
When `MVP_MODE` and `TDD_MODE` are both true at execution time, `execute-phase` adds a per-task gate that requires a `test(<phase>-<plan>):` commit to exist before the corresponding `feat(...)` commit. The reference [`execute-mvp-tdd.md`](../gsd-core/references/execute-mvp-tdd.md) documents the contract; the executor agent (`agents/gsd-executor.md`) gains an MVP+TDD Gate section that explains when the gate trips, what evidence it expects, and how to escalate via the documented escape hatch.
|
||||
|
||||
> **Known canary-bake item.** The current bash gate snippet uses some workflow variables that aren't fully wired (`${PLAN_ID}`, `${TASK_TDD}`) and the documented `--force-mvp-gate` escape hatch is referenced in the user-facing error message but not yet implemented in the argument parser. These are tracked as canary-bake follow-ups; the gate itself is functional for the dominant code path.
|
||||
|
||||
#### Verify-work MVP-mode UAT framing ([#2880](https://github.com/GSD-redux/get-shit-done-redux/pull/2880))
|
||||
|
||||
Under MVP mode, `verify-work` flips the UAT script's framing so user-flow steps come **before** technical correctness checks — the inverse of the default order. The verifier agent gains a `mvp_mode_verification` section. New reference: [`verify-mvp-mode.md`](../get-shit-done/references/verify-mvp-mode.md).
|
||||
Under MVP mode, `verify-work` flips the UAT script's framing so user-flow steps come **before** technical correctness checks — the inverse of the default order. The verifier agent gains a `mvp_mode_verification` section. New reference: [`verify-mvp-mode.md`](../gsd-core/references/verify-mvp-mode.md).
|
||||
|
||||
A user-story format guard at the top of `extract_tests` will halt verification if a phase claims `**Mode:** mvp` but its `**Goal:**` doesn't parse as `As a … I want to … so that …` — pointing the user at `/gsd mvp-phase <N>` to repair.
|
||||
|
||||
|
||||
@@ -562,14 +562,14 @@ For a comprehensive troubleshooting guide, see [Recover and troubleshoot](how-to
|
||||
|
||||
### Programmatic CLI (`gsd-tools query` vs `gsd-tools.cjs`)
|
||||
|
||||
For automation, prefer **`gsd-tools query`** with a registered subcommand (see [CLI-TOOLS.md — SDK and programmatic access](CLI-TOOLS.md#sdk-and-programmatic-access) and QUERY-HANDLERS.md). The legacy `node $HOME/.claude/get-shit-done/bin/gsd-tools.cjs` CLI remains supported.
|
||||
For automation, prefer **`gsd-tools query`** with a registered subcommand (see [CLI-TOOLS.md — SDK and programmatic access](CLI-TOOLS.md#sdk-and-programmatic-access) and QUERY-HANDLERS.md). The legacy `node $HOME/.claude/gsd-core/bin/gsd-tools.cjs` CLI remains supported.
|
||||
|
||||
### STATE.md Out of Sync
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state validate # Detect drift
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state sync --verify # Preview changes
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state sync # Reconstruct STATE.md
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state validate # Detect drift
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state sync --verify # Preview changes
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state sync # Reconstruct STATE.md
|
||||
```
|
||||
|
||||
### A Command Looks Frozen After "Spawning..."
|
||||
@@ -667,7 +667,7 @@ Quick audit before a long phase:
|
||||
|
||||
Each disabled server removes its schema from every subsequent turn. Trimming MCPs **compounds** with `model_profile` tuning — both levers are additive, and MCP savings show up immediately across every subagent the orchestrator spawns.
|
||||
|
||||
For the full audit, harness reference, and the composition note with `model_profile`, see [MCP Tool Schema Cost](../get-shit-done/references/context-budget.md#mcp-tool-schema-cost-harness-concern) in the bundled `context-budget.md` reference.
|
||||
For the full audit, harness reference, and the composition note with `model_profile`, see [MCP Tool Schema Cost](../gsd-core/references/context-budget.md#mcp-tool-schema-cost-harness-concern) in the bundled `context-budget.md` reference.
|
||||
|
||||
### Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI, Kilo)
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ We decided to centralize model-selection data in one Model Catalog Module so the
|
||||
|
||||
Before this ADR there were four drifting sources:
|
||||
|
||||
1. `get-shit-done/bin/lib/model-profiles.cjs` — agent → profile alias map, phase-type map, dynamic-routing default tiers
|
||||
1. `gsd-core/bin/lib/model-profiles.cjs` — agent → profile alias map, phase-type map, dynamic-routing default tiers
|
||||
2. `sdk/src/query/config-query.ts` — stale 18-agent copy of `MODEL_PROFILES`
|
||||
3. `get-shit-done/workflows/settings-advanced.md` — runtime → built-in model-id table
|
||||
3. `gsd-core/workflows/settings-advanced.md` — runtime → built-in model-id table
|
||||
4. `sdk/src/session-runner.ts` — hardcoded Claude-only profile → model-id map
|
||||
|
||||
This caused issue #3229: the SDK knew only 18 agents while 33 agent files existed on disk, so ~15 agents silently fell back to Sonnet with `unknown_agent: true`.
|
||||
|
||||
@@ -7,7 +7,7 @@ We propose introducing a Shell Command Projection Module that owns projection fr
|
||||
|
||||
## Decision
|
||||
|
||||
- Add a **Shell Command Projection Module** under `get-shit-done/bin/lib/` as the single owner for runtime-aware command-text rendering.
|
||||
- Add a **Shell Command Projection Module** under `gsd-core/bin/lib/` as the single owner for runtime-aware command-text rendering.
|
||||
- Feed the module typed inputs (`platform`, `shell`, `runtime`, executable token, args, path policy) instead of prebuilt shell strings.
|
||||
- Keep callers as thin Adapters that request projected text for:
|
||||
- managed hook commands in `settings.json`
|
||||
@@ -125,7 +125,7 @@ The seam grew beyond the original "rendering only" scope. The "does not become a
|
||||
|
||||
**Open question resolutions:**
|
||||
|
||||
- Q4 (installer-only vs shared seam): **resolved — shared.** The seam lives in `get-shit-done/bin/lib/`, consumed by installer, planning workflow, and every fs/subprocess call site across the tool.
|
||||
- Q4 (installer-only vs shared seam): **resolved — shared.** The seam lives in `gsd-core/bin/lib/`, consumed by installer, planning workflow, and every fs/subprocess call site across the tool.
|
||||
- Q1, Q2, Q3 (`hooks.shell_preference`, Windows Git Bash modeling, shim/script builder migration timing): unresolved, carried forward as projection-design concerns independent of the I/O expansion.
|
||||
|
||||
See CONTEXT.md "Shell Command Projection Module" entry for the canonical current-state description.
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
---
|
||||
|
||||
We propose introducing a File Operation Engine Module that owns policy for managed file reads, writes, deletes, locks, backups, and rollbacks across installer, migration, and planning surfaces. Today, file mutation behavior is duplicated across `bin/install.js`, `get-shit-done/bin/lib/installer-migrations.cjs`, and multiple planning modules, with drift in atomic-write guarantees, path safety checks, and ownership classification.
|
||||
We propose introducing a File Operation Engine Module that owns policy for managed file reads, writes, deletes, locks, backups, and rollbacks across installer, migration, and planning surfaces. Today, file mutation behavior is duplicated across `bin/install.js`, `gsd-core/bin/lib/installer-migrations.cjs`, and multiple planning modules, with drift in atomic-write guarantees, path safety checks, and ownership classification.
|
||||
|
||||
This ADR also captures where Shell Command Projection Module policy should be consumed or expanded for hook-command-specific file mutations, so shell command drift and file mutation drift do not evolve as separate bug classes.
|
||||
|
||||
## Decision
|
||||
|
||||
- Add a **File Operation Engine Module** under `get-shit-done/bin/lib/` as the single seam for file mutation safety policy.
|
||||
- Add a **File Operation Engine Module** under `gsd-core/bin/lib/` as the single seam for file mutation safety policy.
|
||||
- Keep command-text projection in the Shell Command Projection Module (ADR-0009), but route projection-adjacent hook file mutations through shared managed-hook ownership policy.
|
||||
- Move file operation adapters to the new seam in two tracks:
|
||||
- **Track A (projection-adjacent):** runtime config hook-command detection/rewrite/delete paths consume shared managed-hook policy from the projection seam.
|
||||
@@ -36,9 +36,9 @@ This ADR also captures where Shell Command Projection Module policy should be co
|
||||
- hook cleanup command detection (`isGsdHookCommand`)
|
||||
- stale Codex hook strip basenames (`STALE_HOOK_BASENAMES`)
|
||||
- settings/config hook entry prune/rewrite paths
|
||||
- `get-shit-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs`
|
||||
- `gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs`
|
||||
- `isManagedCodexHookCommand` regex/path detection duplicated from installer-owned hook policy
|
||||
- `get-shit-done/bin/lib/shell-command-projection.cjs`
|
||||
- `gsd-core/bin/lib/shell-command-projection.cjs`
|
||||
- `isManagedHookBasename` already owns part of this policy and should become the canonical owner
|
||||
|
||||
### Solution-wide file operation drift (Track B)
|
||||
@@ -46,13 +46,13 @@ This ADR also captures where Shell Command Projection Module policy should be co
|
||||
- `bin/install.js`
|
||||
- local `atomicWriteFileSync` and temp cleanup registry
|
||||
- large inlined read/modify/write + backup/rollback logic for runtime config and hooks
|
||||
- `get-shit-done/bin/lib/core.cjs`
|
||||
- `gsd-core/bin/lib/core.cjs`
|
||||
- `atomicWriteFileSync` helper diverges in fallback behavior from installer/migration variants
|
||||
- `get-shit-done/bin/lib/installer-migrations.cjs`
|
||||
- `gsd-core/bin/lib/installer-migrations.cjs`
|
||||
- separate `writeFileAtomicSync`, rollback journaling, lock handling, and containment checks
|
||||
- `get-shit-done/bin/lib/planning-workspace.cjs` and `get-shit-done/bin/lib/state.cjs`
|
||||
- `gsd-core/bin/lib/planning-workspace.cjs` and `gsd-core/bin/lib/state.cjs`
|
||||
- duplicated lock-file create/release/remove patterns and best-effort cleanup semantics
|
||||
- `get-shit-done/bin/lib/roadmap.cjs`, `phase.cjs`, `milestone.cjs`, `frontmatter.cjs`, `drift.cjs`
|
||||
- `gsd-core/bin/lib/roadmap.cjs`, `phase.cjs`, `milestone.cjs`, `frontmatter.cjs`, `drift.cjs`
|
||||
- direct read/modify/write flows with inconsistent atomicity and normalization policy application
|
||||
|
||||
## Interface sketch
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
- **Status:** Proposed
|
||||
- **Date:** 2026-05-12
|
||||
|
||||
We propose extending the existing install profile seam (`get-shit-done/bin/lib/install-profiles.cjs`) into a **Skill Surface Budget Module** that owns which subset of GSD's 66 skills is written to the runtime config dirs, and that owns the per-skill `requires:` dependency manifest used to keep that subset closed under cross-skill references. GSD currently ships a binary `--minimal` / full toggle; runtimes that enumerate skills (Claude Code, OpenCode, etc.) cap the `<available_skills>` system-prompt block at `skillListingBudgetFraction` of the context window (default 1% = ~2k tokens at 200k), and GSD alone consumes ~60% of that cap (#3408). Further description shrinkage is unavailable — `scripts/lint-descriptions.cjs` already enforces a hard 100-char ceiling and the mean is 72.5 chars. The remaining lever is surfacing fewer skills, which requires a typed profile model plus a dependency manifest, not more ad-hoc allowlists.
|
||||
We propose extending the existing install profile seam (`gsd-core/bin/lib/install-profiles.cjs`) into a **Skill Surface Budget Module** that owns which subset of GSD's 66 skills is written to the runtime config dirs, and that owns the per-skill `requires:` dependency manifest used to keep that subset closed under cross-skill references. GSD currently ships a binary `--minimal` / full toggle; runtimes that enumerate skills (Claude Code, OpenCode, etc.) cap the `<available_skills>` system-prompt block at `skillListingBudgetFraction` of the context window (default 1% = ~2k tokens at 200k), and GSD alone consumes ~60% of that cap (#3408). Further description shrinkage is unavailable — `scripts/lint-descriptions.cjs` already enforces a hard 100-char ceiling and the mean is 72.5 chars. The remaining lever is surfacing fewer skills, which requires a typed profile model plus a dependency manifest, not more ad-hoc allowlists.
|
||||
|
||||
## Decision
|
||||
|
||||
- Add a **Skill Surface Budget Module** by extending `get-shit-done/bin/lib/install-profiles.cjs` as the single owner for which `commands/gsd/*.md` and `agents/gsd-*.md` files are staged into the per-runtime copy pipeline.
|
||||
- Add a **Skill Surface Budget Module** by extending `gsd-core/bin/lib/install-profiles.cjs` as the single owner for which `commands/gsd/*.md` and `agents/gsd-*.md` files are staged into the per-runtime copy pipeline.
|
||||
- Replace the single `MINIMAL_SKILL_ALLOWLIST` constant with a typed `PROFILES` map keyed by profile name. Each profile is a *base set* of skills; the module computes the **transitive closure** over each skill's declared `requires:` set before staging.
|
||||
- Add a `requires:` frontmatter field to every skill whose body references another GSD skill. The dependency graph in the research memo (`docs/research/2026-05-12-skill-surface-budget.md` §3.1) is the migration spec for this pass.
|
||||
- Extend `bin/install.js` argument parsing to accept `--profile=<name>` and `--profile=<name1>,<name2>` (composable). Preserve `--minimal` / `--core-only` as aliases for `--profile=core`. Default install (no flag) remains `full` for back-compat.
|
||||
@@ -35,7 +35,7 @@ It should **not** in the first pass:
|
||||
|
||||
## Migration Inventory
|
||||
|
||||
### `get-shit-done/bin/lib/install-profiles.cjs`
|
||||
### `gsd-core/bin/lib/install-profiles.cjs`
|
||||
|
||||
- Replace `MINIMAL_SKILL_ALLOWLIST` Object.freeze constant with `PROFILES` Object.freeze map of profile-name → base skill set.
|
||||
- Replace `isMinimalMode(mode)` with `resolveProfile(mode)` returning a typed `{name, skills: Set, agents: Set}` after transitive-closure computation.
|
||||
@@ -141,7 +141,7 @@ requires: [phase, discuss-phase] # GSD skills only; not Claude Code primitives
|
||||
|
||||
- Feature issue: `#3408`
|
||||
- Research input: `docs/research/2026-05-12-skill-surface-budget.md`
|
||||
- Existing seam being extended: `get-shit-done/bin/lib/install-profiles.cjs`
|
||||
- Existing seam being extended: `gsd-core/bin/lib/install-profiles.cjs`
|
||||
- Description budget enforcement: `scripts/lint-descriptions.cjs`
|
||||
- Installer dispatch site: `bin/install.js:123-124`, `:8167-8207`
|
||||
- See `0008-installer-migration-module.md` (the migration that records the profile marker lives here)
|
||||
|
||||
@@ -11,7 +11,7 @@ The root problem is an absence of a profile/surface seam: the installer wrote ev
|
||||
|
||||
## Decision
|
||||
|
||||
- Add a **Skill Surface Budget Module** under `get-shit-done/bin/lib/install-profiles.cjs` as the single owner for which skills and agents are written to runtime config directories.
|
||||
- Add a **Skill Surface Budget Module** under `gsd-core/bin/lib/install-profiles.cjs` as the single owner for which skills and agents are written to runtime config directories.
|
||||
- Define three named profiles: `core` (six skills covering the main loop), `standard` (core + phase management and workspace skills), and `full` (all skills — the previous default).
|
||||
- Compute each profile's effective skill set as the transitive closure over the `requires:` dependency graph extracted from skill frontmatter, so partial installs never break cross-skill dependencies.
|
||||
- Persist the chosen profile in a `.gsd-profile` marker file in each runtime config directory; `gsd update` reads the marker to honor the profile on re-install.
|
||||
@@ -33,9 +33,9 @@ The Phase 2 decision, previously listed as an open question, is recorded here as
|
||||
- `disable <cluster>` — mark a cluster disabled; re-stage to remove its skills from the runtime config dir
|
||||
- `enable <cluster>` — mark a cluster enabled; re-stage to add its skills back
|
||||
- `reset` — clear surface state and re-apply the active profile from `.gsd-profile`
|
||||
- Implement the runtime surface engine in `get-shit-done/bin/lib/surface.cjs`, consuming `stageSkillsForProfile` and `stageAgentsForProfile` from the Phase 1 module without duplicating staging logic.
|
||||
- Implement the runtime surface engine in `gsd-core/bin/lib/surface.cjs`, consuming `stageSkillsForProfile` and `stageAgentsForProfile` from the Phase 1 module without duplicating staging logic.
|
||||
- Persist per-runtime surface state in `<runtimeConfigDir>/.gsd-surface.json`, independent from `.gsd-profile`. The profile marker owns install-time identity; the surface JSON owns session-scope cluster toggles.
|
||||
- Source cluster taxonomy from the research memo §3.2 (2026-05-12-skill-surface-budget.md). Define clusters in `get-shit-done/bin/lib/clusters.cjs` — a separate module so the surface engine and future SDK callers can import cluster definitions without loading the full profile module.
|
||||
- Source cluster taxonomy from the research memo §3.2 (2026-05-12-skill-surface-budget.md). Define clusters in `gsd-core/bin/lib/clusters.cjs` — a separate module so the surface engine and future SDK callers can import cluster definitions without loading the full profile module.
|
||||
- Cluster taxonomy: `core_loop`, `audit_review`, `milestone`, `research_ideate`, `workspace_state`, `docs`, `ui`, `ai_eval`, `ns_meta`, `utility`. Membership may overlap; every installed skill stem must appear in at least one cluster (enforced by `tests/surface-clusters.test.cjs`).
|
||||
- Relationship to Anthropic platform asks: Asks D (native per-skill toggle API) and E (budget-fraction negotiation) remain filed separately. The `/gsd:surface` command is a unilateral GSD-side workaround that does not depend on those platform changes.
|
||||
|
||||
@@ -43,7 +43,7 @@ The Phase 2 decision, previously listed as an open question, is recorded here as
|
||||
|
||||
Phase 1 artifacts landed on `feat/3408-skills-description-dropped-due-to-size`:
|
||||
|
||||
- `get-shit-done/bin/lib/install-profiles.cjs` — `PROFILES` map, `resolveProfile`, `loadSkillsManifest`, `stageSkillsForProfile`, `stageAgentsForProfile`, `readActiveProfile`, `writeActiveProfile`, `mostRestrictiveProfile`, `resolveEffectiveProfile`
|
||||
- `gsd-core/bin/lib/install-profiles.cjs` — `PROFILES` map, `resolveProfile`, `loadSkillsManifest`, `stageSkillsForProfile`, `stageAgentsForProfile`, `readActiveProfile`, `writeActiveProfile`, `mostRestrictiveProfile`, `resolveEffectiveProfile`
|
||||
- `requires:` frontmatter added to 64 skills in `commands/gsd/*.md`
|
||||
- `scripts/lint-skill-deps.cjs` — CI gate for `requires:` integrity, wired into `pretest`
|
||||
- `bin/install.js` — `--profile=<name>` flag (composable); `--minimal`/`--core-only` as aliases; `.gsd-profile` marker write on install; `gsd update` re-reads marker
|
||||
@@ -52,8 +52,8 @@ Phase 1 artifacts landed on `feat/3408-skills-description-dropped-due-to-size`:
|
||||
Phase 2 shipped on the same branch:
|
||||
|
||||
- `commands/gsd/surface.md` — `/gsd:surface` slash command runbook (sub-commands: `list`, `status`, `profile <name>`, `disable <cluster>`, `enable <cluster>`, `reset`)
|
||||
- `get-shit-done/bin/lib/surface.cjs` — runtime engine (`readSurface`, `writeSurface`, `resolveSurface`, `applySurface`, `listSurface`); reuses `stageSkillsForProfile` / `stageAgentsForProfile` from Phase 1
|
||||
- `get-shit-done/bin/lib/clusters.cjs` — 10-cluster taxonomy covering all installed skill stems
|
||||
- `gsd-core/bin/lib/surface.cjs` — runtime engine (`readSurface`, `writeSurface`, `resolveSurface`, `applySurface`, `listSurface`); reuses `stageSkillsForProfile` / `stageAgentsForProfile` from Phase 1
|
||||
- `gsd-core/bin/lib/clusters.cjs` — 10-cluster taxonomy covering all installed skill stems
|
||||
- Tests: `tests/surface-state.test.cjs`, `tests/surface-clusters.test.cjs`, `tests/surface-resolve.test.cjs`, `tests/surface-apply.test.cjs`, `tests/surface-list.test.cjs`
|
||||
- Persistent surface state: `<runtimeConfigDir>/.gsd-surface.json` (independent from `.gsd-profile`)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Seven `*-command-router.cjs` files (`phase`, `phases`, `roadmap`, `state`, `veri
|
||||
|
||||
## Decision
|
||||
|
||||
Introduce `CommandRoutingHub` (`get-shit-done/bin/lib/command-routing-hub.cjs`) as the single dispatch seam for all CJS command family routers. The hub contract:
|
||||
Introduce `CommandRoutingHub` (`gsd-core/bin/lib/command-routing-hub.cjs`) as the single dispatch seam for all CJS command family routers. The hub contract:
|
||||
|
||||
```
|
||||
createHub({ mode: 'sdk' | 'cjs', sdkLoader, cjsRegistry, manifest }) -> hub
|
||||
|
||||
@@ -164,12 +164,12 @@ Root architectural gap: orchestration flows lack a plan strategy seam (`local` v
|
||||
|
||||
- Issue: #15
|
||||
- `commands/gsd/progress.md`
|
||||
- `get-shit-done/workflows/progress.md`
|
||||
- `get-shit-done/workflows/next.md`
|
||||
- `gsd-core/workflows/progress.md`
|
||||
- `gsd-core/workflows/next.md`
|
||||
- `commands/gsd/autonomous.md`
|
||||
- `get-shit-done/workflows/autonomous.md`
|
||||
- `gsd-core/workflows/autonomous.md`
|
||||
- `commands/gsd/plan-review-convergence.md`
|
||||
- `get-shit-done/workflows/plan-review-convergence.md`
|
||||
- `gsd-core/workflows/plan-review-convergence.md`
|
||||
- `commands/gsd/review.md`
|
||||
- `docs/COMMANDS.md` (`/gsd-plan-review-convergence`, `/gsd-review`)
|
||||
- `docs/CONFIGURATION.md` (`workflow.plan_review_convergence`, `review.default_reviewers`, `review.models.*`)
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
- **Extends:** ADR-0005 (seam map) — adds the **Shared-Module Source Policy** to the seam family
|
||||
- **Defers to:** ADR-0001 (Dispatch Policy Module), ADR-0003 (Model Catalog Module), ADR-0004 (Planning Workspace Module), ADR-0006 (Planning Path Projection Module), ADR-0009 (Shell Command Projection Module — post-Phase 3–4, also subsuming superseded ADR-0010)
|
||||
|
||||
We decided to harden the boundary between the CJS tooling layer (`get-shit-done/bin/lib/*.cjs`) and the SDK (`sdk/src/**/*.ts`) by making every Module that is conceptually shared between the two runtimes have exactly one hand-authored source of truth and at most one generated artifact per runtime. The trigger is the recurring drift bug class — #1535, #1542, #2047/#2052, #2638/#2655, #2653/#2670, #2687/#2706, #2798/#2816, #3055/#3116, #3523 — each of which was a fix landing on one side without the other.
|
||||
We decided to harden the boundary between the CJS tooling layer (`gsd-core/bin/lib/*.cjs`) and the SDK (`sdk/src/**/*.ts`) by making every Module that is conceptually shared between the two runtimes have exactly one hand-authored source of truth and at most one generated artifact per runtime. The trigger is the recurring drift bug class — #1535, #1542, #2047/#2052, #2638/#2655, #2653/#2670, #2687/#2706, #2798/#2816, #3055/#3116, #3523 — each of which was a fix landing on one side without the other.
|
||||
|
||||
The precedent shape is already in the repo. `sdk/scripts/gen-command-aliases.ts` emits `sdk/src/query/command-aliases.generated.ts` **and** `get-shit-done/bin/lib/command-aliases.generated.cjs` from one TypeScript source. `sdk/scripts/check-command-aliases-fresh.mjs` is the CI freshness gate. The two consuming sides are pure Adapters over the generated artifact. This ADR generalizes that pattern to the other Shared Modules and forbids the hand-synced-pair anti-pattern that produced #3523.
|
||||
The precedent shape is already in the repo. `sdk/scripts/gen-command-aliases.ts` emits `sdk/src/query/command-aliases.generated.ts` **and** `gsd-core/bin/lib/command-aliases.generated.cjs` from one TypeScript source. `sdk/scripts/check-command-aliases-fresh.mjs` is the CI freshness gate. The two consuming sides are pure Adapters over the generated artifact. This ADR generalizes that pattern to the other Shared Modules and forbids the hand-synced-pair anti-pattern that produced #3523.
|
||||
|
||||
## Decision
|
||||
|
||||
@@ -20,10 +20,10 @@ A **Shared Module** is any Module whose Interface is consumed identically by bot
|
||||
For every Shared Module:
|
||||
|
||||
1. **Exactly one hand-authored source of truth.** Lives at `sdk/src/<module-name>/` as TypeScript when the Module has behavior, or `sdk/shared/<module-name>.manifest.json` when the Module is pure data.
|
||||
2. **Generated artifacts only.** The CJS-side file is `get-shit-done/bin/lib/<module-name>.generated.cjs` and is emitted mechanically. It is never hand-edited.
|
||||
2. **Generated artifacts only.** The CJS-side file is `gsd-core/bin/lib/<module-name>.generated.cjs` and is emitted mechanically. It is never hand-edited.
|
||||
3. **Per-Module freshness check.** A CI script `sdk/scripts/check-<module>-fresh.mjs` re-runs the generator and fails if the emitted artifact differs from the committed one. Precedent: `check-command-aliases-fresh.mjs`.
|
||||
4. **Per-Module drift lint** (when the source is data, not a generator output). Precedent: `scripts/lint-shell-command-projection-drift.cjs`. The lint asserts the canonical-owner invariants that aren't captured by file-equality.
|
||||
5. **Hand-synced pairs are forbidden.** A pre-merge `lint-shared-module-handsync.cjs` greps `get-shit-done/bin/lib/` for non-`.generated.*` files whose basename matches a `sdk/src/query/<same-name>.ts` source and fails the build unless the pair is explicitly allow-listed.
|
||||
5. **Hand-synced pairs are forbidden.** A pre-merge `lint-shared-module-handsync.cjs` greps `gsd-core/bin/lib/` for non-`.generated.*` files whose basename matches a `sdk/src/query/<same-name>.ts` source and fails the build unless the pair is explicitly allow-listed.
|
||||
|
||||
### 2. Module-indexed canonical-owner table
|
||||
|
||||
@@ -31,13 +31,13 @@ The table below indexes by Module, not by physical layer. Each row names the sou
|
||||
|
||||
| Module | Status | Source of truth | Generated artifacts | Adapters |
|
||||
|---|---|---|---|---|
|
||||
| **STATE.md Document Module** | New under this ADR (Phase 1) — see CONTEXT.md "STATE.md Document Module" | `sdk/src/state/index.ts` (promoted from `sdk/src/query/state-document.ts`) | `sdk/src/query/state-document.generated.ts`, `get-shit-done/bin/lib/state-document.generated.cjs` | `bin/lib/state.cjs` and `sdk/src/query/state*.ts` import the generated form |
|
||||
| **Configuration Module** | New under this ADR (Phase 2) — definition added to CONTEXT.md as part of Phase 2 | `sdk/src/config/index.ts` plus data manifests `sdk/shared/config-schema.manifest.json` and `sdk/shared/config-defaults.manifest.json` | `sdk/src/query/config-schema.generated.ts`, `get-shit-done/bin/lib/config-schema.generated.cjs`, `get-shit-done/bin/lib/configuration.generated.cjs` | `bin/lib/config.cjs`, `bin/lib/core.cjs:loadConfig`, `sdk/src/config.ts` |
|
||||
| **Workstream Inventory Module** (Builder) | Amended under this ADR (Phase 3) — Builder split documented in CONTEXT.md update | `sdk/src/workstream/builder.ts` (pure projection from directory entries + STATE.md text + plan scan results → typed inventory) | `sdk/src/query/workstream-inventory-builder.generated.ts`, `get-shit-done/bin/lib/workstream-inventory-builder.generated.cjs` | Per-side fs Readers (`workstream-inventory.cjs` sync, `workstream-inventory.ts` async) call the Builder. Readers stay hand-authored because the fs idiom legitimately differs. |
|
||||
| **Project-Root Resolution Module** | New under this ADR (Phase 4) — short CONTEXT.md entry, behavior already de-facto shared | `sdk/src/project-root/index.ts` | `get-shit-done/bin/lib/project-root.generated.cjs` | `bin/lib/core.cjs` (`findProjectRoot`, `findEffectiveRoot`), `sdk/src/helpers.ts` |
|
||||
| **Frontmatter Module** | Conditional (Phase 3, only if drift catalogue confirms pair duplication) | `sdk/src/frontmatter/index.ts` | `get-shit-done/bin/lib/frontmatter.generated.cjs` | Existing handler call sites |
|
||||
| **Plan Scan Module** | Conditional (Phase 3 or later) | `sdk/src/plan-scan/index.ts` | `get-shit-done/bin/lib/plan-scan.generated.cjs` | Phase/roadmap routers |
|
||||
| **CJS Command Router Adapter Module** | Amended under this ADR (Phase 5). Existing Module (per CONTEXT.md) is extended so the per-family `handlers` map delegates to the SDK runtime bridge in-process instead of to parallel CJS handler implementations. | `sdk/src/query-runtime-bridge.ts` (already exists) + per-family delegate emitter | `get-shit-done/bin/lib/cjs-command-router-adapter.cjs` (existing, ~40 lines) plus per-family `handlers` maps that `require('../../sdk/dist/query-runtime-bridge.cjs')` and call `QueryRuntimeBridge.execute()` | `bin/gsd-tools.cjs` and the seven `bin/lib/*-command-router.cjs` files are the consumers. Per-family CJS handler files (`state.cjs`, `verify.cjs`, `init.cjs`, etc.) shrink to delegates or are deleted once the SDK handler is the only implementation. |
|
||||
| **STATE.md Document Module** | New under this ADR (Phase 1) — see CONTEXT.md "STATE.md Document Module" | `sdk/src/state/index.ts` (promoted from `sdk/src/query/state-document.ts`) | `sdk/src/query/state-document.generated.ts`, `gsd-core/bin/lib/state-document.generated.cjs` | `bin/lib/state.cjs` and `sdk/src/query/state*.ts` import the generated form |
|
||||
| **Configuration Module** | New under this ADR (Phase 2) — definition added to CONTEXT.md as part of Phase 2 | `sdk/src/config/index.ts` plus data manifests `sdk/shared/config-schema.manifest.json` and `sdk/shared/config-defaults.manifest.json` | `sdk/src/query/config-schema.generated.ts`, `gsd-core/bin/lib/config-schema.generated.cjs`, `gsd-core/bin/lib/configuration.generated.cjs` | `bin/lib/config.cjs`, `bin/lib/core.cjs:loadConfig`, `sdk/src/config.ts` |
|
||||
| **Workstream Inventory Module** (Builder) | Amended under this ADR (Phase 3) — Builder split documented in CONTEXT.md update | `sdk/src/workstream/builder.ts` (pure projection from directory entries + STATE.md text + plan scan results → typed inventory) | `sdk/src/query/workstream-inventory-builder.generated.ts`, `gsd-core/bin/lib/workstream-inventory-builder.generated.cjs` | Per-side fs Readers (`workstream-inventory.cjs` sync, `workstream-inventory.ts` async) call the Builder. Readers stay hand-authored because the fs idiom legitimately differs. |
|
||||
| **Project-Root Resolution Module** | New under this ADR (Phase 4) — short CONTEXT.md entry, behavior already de-facto shared | `sdk/src/project-root/index.ts` | `gsd-core/bin/lib/project-root.generated.cjs` | `bin/lib/core.cjs` (`findProjectRoot`, `findEffectiveRoot`), `sdk/src/helpers.ts` |
|
||||
| **Frontmatter Module** | Conditional (Phase 3, only if drift catalogue confirms pair duplication) | `sdk/src/frontmatter/index.ts` | `gsd-core/bin/lib/frontmatter.generated.cjs` | Existing handler call sites |
|
||||
| **Plan Scan Module** | Conditional (Phase 3 or later) | `sdk/src/plan-scan/index.ts` | `gsd-core/bin/lib/plan-scan.generated.cjs` | Phase/roadmap routers |
|
||||
| **CJS Command Router Adapter Module** | Amended under this ADR (Phase 5). Existing Module (per CONTEXT.md) is extended so the per-family `handlers` map delegates to the SDK runtime bridge in-process instead of to parallel CJS handler implementations. | `sdk/src/query-runtime-bridge.ts` (already exists) + per-family delegate emitter | `gsd-core/bin/lib/cjs-command-router-adapter.cjs` (existing, ~40 lines) plus per-family `handlers` maps that `require('../../sdk/dist/query-runtime-bridge.cjs')` and call `QueryRuntimeBridge.execute()` | `bin/gsd-tools.cjs` and the seven `bin/lib/*-command-router.cjs` files are the consumers. Per-family CJS handler files (`state.cjs`, `verify.cjs`, `init.cjs`, etc.) shrink to delegates or are deleted once the SDK handler is the only implementation. |
|
||||
| Command-Alias Module | **Already sealed** by this pattern's precedent — `sdk/scripts/gen-command-aliases.ts` + `check-command-aliases-fresh.mjs` | No change | No change | No change |
|
||||
| Dispatch Policy Module | **Defer — see ADR-0001** (and its 2026-05-05 SDK Runtime Bridge amendment) | n/a | n/a | n/a |
|
||||
| Model Catalog Module | **Defer — see ADR-0003**; the `sdk/shared/model-catalog.json` manifest already follows the source-of-truth policy | n/a | n/a | n/a |
|
||||
@@ -68,7 +68,7 @@ Drift is blocked at three layers, each modeled on an existing in-repo script:
|
||||
|
||||
1. **Per-Module freshness check** — `sdk/scripts/check-<module>-fresh.mjs`, one per Shared Module in the table. Precedent: `check-command-aliases-fresh.mjs`.
|
||||
2. **Per-Module drift lint** (when invariants are not pure file-equality) — `scripts/lint-<module>-drift.cjs`, one per data-manifest-backed Module. Precedent: `lint-shell-command-projection-drift.cjs`.
|
||||
3. **Hand-sync pair lint** — `scripts/lint-shared-module-handsync.cjs` rejects any pair of files at `get-shit-done/bin/lib/<name>.cjs` and `sdk/src/query/<name>.ts` (or `sdk/src/<name>.ts`) that are neither generated artifacts nor on an explicit allow-list. This blocks the #3523 anti-pattern at PR time.
|
||||
3. **Hand-sync pair lint** — `scripts/lint-shared-module-handsync.cjs` rejects any pair of files at `gsd-core/bin/lib/<name>.cjs` and `sdk/src/query/<name>.ts` (or `sdk/src/<name>.ts`) that are neither generated artifacts nor on an explicit allow-list. This blocks the #3523 anti-pattern at PR time.
|
||||
|
||||
CODEOWNERS extends to `sdk/src/<module>/` for each Shared Module. Architecture-team review is required for changes to a source of truth.
|
||||
|
||||
@@ -105,11 +105,11 @@ _(Append-only. Use a dated header when the decision evolves.)_
|
||||
### 2026-05-23 — validate.ts → verify.cjs generator pattern (issue #6)
|
||||
|
||||
Three pure helpers from `sdk/src/query/validate.ts` Check 8 are now generated into
|
||||
`get-shit-done/bin/lib/validate.generated.cjs` via `sdk/scripts/gen-validate.mjs`,
|
||||
`gsd-core/bin/lib/validate.generated.cjs` via `sdk/scripts/gen-validate.mjs`,
|
||||
following the same I/O adapter pattern established by PR #154 (issue #4):
|
||||
|
||||
**Generator:** `sdk/scripts/gen-validate.mjs`
|
||||
**Artifact:** `get-shit-done/bin/lib/validate.generated.cjs`
|
||||
**Artifact:** `gsd-core/bin/lib/validate.generated.cjs`
|
||||
**Freshness check:** `sdk/scripts/check-validate-fresh.mjs`
|
||||
**CI:** `.github/workflows/test.yml` — "SDK generated validate artifact drift check"
|
||||
|
||||
@@ -150,7 +150,7 @@ is still a full implementation; only Check 8 helpers are generated).
|
||||
#### Extension — issue #26: W005/W006-archived/I001 generator migration
|
||||
|
||||
PR #3479 fixed three false-positive classes in `sdk/src/query/validate.ts`. PR #3806 hand-ported
|
||||
the three fixes to `get-shit-done/bin/lib/verify.cjs` but did not route them through the generator
|
||||
the three fixes to `gsd-core/bin/lib/verify.cjs` but did not route them through the generator
|
||||
— meaning they could drift again. Issue #26 closes this gap by extending `gen-validate.mjs`
|
||||
(introduced in this amendment above) to also extract and export the W005/W006-archived/I001 items.
|
||||
|
||||
@@ -211,11 +211,11 @@ verify.cjs migration scope for generator-pattern coverage.
|
||||
**Decision:** Apply the I/O adapter pattern (Section 4) to the pure-computation kernel inside `phase-lifecycle.ts`:
|
||||
|
||||
1. **Three new generator scripts** extract pure helpers from the phase family:
|
||||
- `sdk/scripts/gen-phase.mjs` → `get-shit-done/bin/lib/phase.generated.cjs`
|
||||
- `sdk/scripts/gen-phase.mjs` → `gsd-core/bin/lib/phase.generated.cjs`
|
||||
(pure helpers: `isCanonicalPlanFile`, `describeNonCanonicalPlans`)
|
||||
- `sdk/scripts/gen-phase-lifecycle.mjs` → `get-shit-done/bin/lib/phase-lifecycle.generated.cjs`
|
||||
- `sdk/scripts/gen-phase-lifecycle.mjs` → `gsd-core/bin/lib/phase-lifecycle.generated.cjs`
|
||||
(pure helpers: `deriveProgressFromRoadmap`, `clampPercent`)
|
||||
- `sdk/scripts/gen-phase-lifecycle-policy.mjs` → `get-shit-done/bin/lib/phase-lifecycle-policy.generated.cjs`
|
||||
- `sdk/scripts/gen-phase-lifecycle-policy.mjs` → `gsd-core/bin/lib/phase-lifecycle-policy.generated.cjs`
|
||||
(14 pure policy helpers: `generatePhaseSlug`, `computePhaseDirectory`, `buildPhaseRoadmapEntry`, etc.)
|
||||
|
||||
2. **`phase.cjs:cmdPhaseComplete`** is migrated to use `deriveProgressFromRoadmap` + `clampPercent` from the generated artifact. It reads the freshly-updated ROADMAP synchronously, derives the completed-phase count from Complete-row matching (idempotent), and passes it through `clampPercent` to prevent >100% Progress.
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
- **Issue:** #3660
|
||||
- **Implementation:** #3663 (Phase 1), feat/3663-runtime-artifact-layout-module-phase-1-m
|
||||
|
||||
The **Runtime Surface Module** (`get-shit-done/bin/lib/surface.cjs`, introduced by ADR-0011 Phase 2) re-materializes a resolved Skill Surface profile to disk via `applySurface`. It currently hardcodes two artifact kinds (`commands`, `agents`) and re-derives their source directories via `_findInstallSource` / `_findAgentsSource` walk-up heuristics. The install and uninstall pipelines in `bin/install.js` each encode the same per-runtime artifact layout independently across ~14 install sites and ~6 uninstall sites. Bug #3659 surfaced the resulting drift: `applySurface` omits the `skills` kind for runtimes whose canonical layout is `skills/gsd-<stem>/SKILL.md`, so `gsd-surface profile <name>` leaves ~67 skill directories on disk under the install-time profile's footprint when the resolved profile should have pruned them — roughly 2.7k tokens per session on a measured workstation.
|
||||
The **Runtime Surface Module** (`gsd-core/bin/lib/surface.cjs`, introduced by ADR-0011 Phase 2) re-materializes a resolved Skill Surface profile to disk via `applySurface`. It currently hardcodes two artifact kinds (`commands`, `agents`) and re-derives their source directories via `_findInstallSource` / `_findAgentsSource` walk-up heuristics. The install and uninstall pipelines in `bin/install.js` each encode the same per-runtime artifact layout independently across ~14 install sites and ~6 uninstall sites. Bug #3659 surfaced the resulting drift: `applySurface` omits the `skills` kind for runtimes whose canonical layout is `skills/gsd-<stem>/SKILL.md`, so `gsd-surface profile <name>` leaves ~67 skill directories on disk under the install-time profile's footprint when the resolved profile should have pruned them — roughly 2.7k tokens per session on a measured workstation.
|
||||
|
||||
The root problem is the absence of a typed seam for "where does runtime R put artifact kind K." Three lifecycle sites (install, uninstall, surface) each independently encode this knowledge and drift independently.
|
||||
|
||||
## Decision
|
||||
|
||||
- Add a **Runtime Artifact Layout Module** at `get-shit-done/bin/lib/runtime-artifact-layout.cjs` as the single owner of the per-runtime artifact-placement table.
|
||||
- Add a **Runtime Artifact Layout Module** at `gsd-core/bin/lib/runtime-artifact-layout.cjs` as the single owner of the per-runtime artifact-placement table.
|
||||
- The module requires `runtime-homes.cjs` for the canonical runtime enum and global config-dir resolution. It adds the artifact-kind axis on top.
|
||||
- Expose `resolveRuntimeArtifactLayout(runtime, configDir) → Layout`. The returned `Layout` is a plain typed object — `{ runtime, configDir, kinds: ArtifactKind[] }` — with no I/O on resolution.
|
||||
- Each `ArtifactKind` is `{ kind: 'commands'|'agents'|'skills', destSubpath, prefix, stage }`. `stage` is a function `(resolvedProfile) → stagedDir` that closes over the per-runtime converter where one is needed (e.g. `convertClaudeCommandToClaudeSkill` for the `skills` kind on Claude global).
|
||||
@@ -29,7 +29,7 @@ The root problem is the absence of a typed seam for "where does runtime R put ar
|
||||
|
||||
Phase 1 should land the module and one consumer (the bug-#3659 fix):
|
||||
|
||||
1. New `get-shit-done/bin/lib/runtime-artifact-layout.cjs` — `resolveRuntimeArtifactLayout`, the typed `Layout`/`ArtifactKind` shapes, and the runtime table covering every runtime currently enumerated in `runtime-homes.cjs`.
|
||||
1. New `gsd-core/bin/lib/runtime-artifact-layout.cjs` — `resolveRuntimeArtifactLayout`, the typed `Layout`/`ArtifactKind` shapes, and the runtime table covering every runtime currently enumerated in `runtime-homes.cjs`.
|
||||
2. `surface.cjs:applySurface` migrates to layout-driven iteration. `_findInstallSource` and `_findAgentsSource` deleted. The `skills` kind is now iterated alongside `commands` and `agents` — bug #3659 closed.
|
||||
3. `commands/gsd/surface.md` and `tests/surface-apply.test.cjs` updated to construct + pass `Layout` values.
|
||||
4. New `tests/runtime-artifact-layout-*.test.cjs` covering:
|
||||
@@ -47,10 +47,10 @@ Phase 1 should **not**:
|
||||
## Migration Inventory
|
||||
|
||||
### New file
|
||||
- `get-shit-done/bin/lib/runtime-artifact-layout.cjs` — module body + runtime layout table.
|
||||
- `gsd-core/bin/lib/runtime-artifact-layout.cjs` — module body + runtime layout table.
|
||||
|
||||
### Files modified (Phase 1)
|
||||
- `get-shit-done/bin/lib/surface.cjs` — `applySurface` signature change; `_findInstallSource` + `_findAgentsSource` removal.
|
||||
- `gsd-core/bin/lib/surface.cjs` — `applySurface` signature change; `_findInstallSource` + `_findAgentsSource` removal.
|
||||
- `commands/gsd/surface.md` — runbook updates the 3 sites that call `applySurface` to first call `resolveRuntimeArtifactLayout`.
|
||||
- `tests/surface-apply.test.cjs` — 5 call sites pass `layout` instead of `commandsDir, agentsDir`.
|
||||
|
||||
@@ -132,17 +132,17 @@ function applySurface(runtimeConfigDir, layout, manifest, clusterMap) {
|
||||
- See `0011-skill-surface-budget-module.md` — the Runtime Surface Module this seam serves
|
||||
- See `0008-installer-migration-module.md` — legacy-layout migrations stay there
|
||||
- See `0005-sdk-architecture-seam-map.md` — the seam map this module joins
|
||||
- Existing canonical sibling: `get-shit-done/bin/lib/runtime-homes.cjs`
|
||||
- Existing canonical sibling: `gsd-core/bin/lib/runtime-homes.cjs`
|
||||
- Per-runtime skill converters this module references: `bin/install.js:1622` (Copilot), `:1681` (Claude), `:1792` (Antigravity), `:2534` (Codex)
|
||||
- Hermes nested-skills layout rationale: `#2841`
|
||||
|
||||
## Implementation status
|
||||
|
||||
Phase 1 implementation landed on `feat/3663-runtime-artifact-layout-module-phase-1-m`:
|
||||
- `get-shit-done/bin/lib/runtime-artifact-layout.cjs` — 15-runtime layout table (grok intentionally excluded), `resolveRuntimeArtifactLayout(runtime, configDir, scope) → Layout`, walk-up `findInstallSourceRoot` helper.
|
||||
- `gsd-core/bin/lib/runtime-artifact-layout.cjs` — 15-runtime layout table (grok intentionally excluded), `resolveRuntimeArtifactLayout(runtime, configDir, scope) → Layout`, walk-up `findInstallSourceRoot` helper.
|
||||
- Clarification: in this Phase 1 implementation, **Cline resolves to zero kinds** (`kinds: []`), so it carries no `commands` kind in the layout table.
|
||||
- `get-shit-done/bin/lib/install-profiles.cjs` — new `stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converter, prefix) → stagedDir` helper.
|
||||
- `get-shit-done/bin/lib/surface.cjs` — `applySurface(runtimeConfigDir, layout, manifest, clusterMap)` signature migration; `_findInstallSource` + `_findAgentsSource` deleted; `_syncGsdDir` extended to handle the `skills` kind via directory iteration.
|
||||
- `gsd-core/bin/lib/install-profiles.cjs` — new `stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converter, prefix) → stagedDir` helper.
|
||||
- `gsd-core/bin/lib/surface.cjs` — `applySurface(runtimeConfigDir, layout, manifest, clusterMap)` signature migration; `_findInstallSource` + `_findAgentsSource` deleted; `_syncGsdDir` extended to handle the `skills` kind via directory iteration.
|
||||
- Tests: `runtime-artifact-layout-resolve.test.cjs` (16), `runtime-artifact-layout-edge-cases.test.cjs` (10), `runtime-artifact-layout-stage.test.cjs` (5), `install-profiles-stage.test.cjs` (+7 new), `surface-apply.test.cjs` (updated 5 call sites + new skills-kind test).
|
||||
|
||||
Phase 2 (separate issue #3664 — `bin/install.js` install/uninstall pipeline migration) is blocked on Phase 1 merge.
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
### The `$GSD_SDK` → `gsd_run` rename (#373/#379)
|
||||
|
||||
PRs #373 and #379 renamed the runtime resolver from the unquoted `$GSD_SDK` shell variable to a single-line, space-safe `gsd_run` launcher. The launcher is defined in `get-shit-done/workflows/_runtime-launcher.snippet.sh`, propagated to all workflow `.md` files by `scripts/sync-runtime-launcher.cjs`, and enforced by `tests/runtime-launcher-parity.test.cjs` (which forbids any `$GSD_SDK` token in workflow markdown).
|
||||
PRs #373 and #379 renamed the runtime resolver from the unquoted `$GSD_SDK` shell variable to a single-line, space-safe `gsd_run` launcher. The launcher is defined in `gsd-core/workflows/_runtime-launcher.snippet.sh`, propagated to all workflow `.md` files by `scripts/sync-runtime-launcher.cjs`, and enforced by `tests/runtime-launcher-parity.test.cjs` (which forbids any `$GSD_SDK` token in workflow markdown).
|
||||
|
||||
### The silent regression (#406)
|
||||
|
||||
During a multi-PR merge sweep, PR #406 (`fix(#160)`) — branched **before** #379 — re-introduced 5 `$GSD_SDK` occurrences into `get-shit-done/workflows/next.md`. Because it edited a **different** region of the file than #379, the merge produced no textual conflict and Git accepted it silently.
|
||||
During a multi-PR merge sweep, PR #406 (`fix(#160)`) — branched **before** #379 — re-introduced 5 `$GSD_SDK` occurrences into `gsd-core/workflows/next.md`. Because it edited a **different** region of the file than #379, the merge produced no textual conflict and Git accepted it silently.
|
||||
|
||||
#406's own CI was green because its base predated the parity test, and nothing re-checked the merge result against current `next`. #406 also carried a stale companion assertion (`tests/policy-160-route0-resume.test.cjs`) that **required** `$GSD_SDK` to be present.
|
||||
|
||||
@@ -64,5 +64,5 @@ A green PR on a stale base can still regress the integration branch via a **sema
|
||||
- Rename PRs: #373, #379 (`gsd_run`)
|
||||
- Propagator: `scripts/sync-runtime-launcher.cjs`
|
||||
- Parity test: `tests/runtime-launcher-parity.test.cjs`
|
||||
- Launcher snippet: `get-shit-done/workflows/_runtime-launcher.snippet.sh`
|
||||
- Launcher snippet: `gsd-core/workflows/_runtime-launcher.snippet.sh`
|
||||
- Tracking issue: #415
|
||||
|
||||
@@ -23,7 +23,7 @@ This codebase adopts ESLint flat config (eslint ≥ 9) with `typescript-eslint`,
|
||||
|
||||
### Generated vs hand-written split
|
||||
|
||||
Approximately 59 hand-written and 13 generated `.cjs` files currently coexist in `get-shit-done/bin/lib/`. The hand-written files are not checked by `typescript-eslint` type-aware rules because `tsconfig.lint.json` is not wired into an ESLint project. ADR 457 (`457-generated-cjs-single-source.md`) proposes collapsing this split; the present ADR is a prerequisite: the ESLint harness must exist before the collapse can surface type errors.
|
||||
Approximately 59 hand-written and 13 generated `.cjs` files currently coexist in `gsd-core/bin/lib/`. The hand-written files are not checked by `typescript-eslint` type-aware rules because `tsconfig.lint.json` is not wired into an ESLint project. ADR 457 (`457-generated-cjs-single-source.md`) proposes collapsing this split; the present ADR is a prerequisite: the ESLint harness must exist before the collapse can surface type errors.
|
||||
|
||||
## Decision
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
>
|
||||
> **Provenance note.** An earlier draft of this ADR (and issue #457) was authored
|
||||
> by an agent and asserted a codebase state that did not exist — "~13 files
|
||||
> generated from `.ts` via `tsc`", `get-shit-done/src/` / `sdk/src/` source trees,
|
||||
> generated from `.ts` via `tsc`", `gsd-core/src/` / `sdk/src/` source trees,
|
||||
> and a `tests/cjs-ts-parity.test.cjs`. None of those existed. This rewrite
|
||||
> grounds the decision in verified ground truth. Do not restore the earlier
|
||||
> "natural completion of the 13 generated files" framing; it was fiction.
|
||||
@@ -18,12 +18,12 @@
|
||||
|
||||
### What actually exists today (verified 2026-05-31)
|
||||
|
||||
- `get-shit-done/bin/lib/` holds **84** `.cjs` files. **Exactly one** carries a
|
||||
- `gsd-core/bin/lib/` holds **84** `.cjs` files. **Exactly one** carries a
|
||||
`// @generated` header: `package-identity.cjs`.
|
||||
- That one generated file is **not** `tsc` output. It is produced by
|
||||
`scripts/generate-package-identity.cjs` — a plain Node script that reads
|
||||
`package.json` and **bakes literal coordinate values** into a CJS module.
|
||||
- There is **no** `get-shit-done/src/` or `sdk/src/` TypeScript tree. There is
|
||||
- There is **no** `gsd-core/src/` or `sdk/src/` TypeScript tree. There is
|
||||
**no** TS→CJS transpilation pipeline. There is **no**
|
||||
`tests/cjs-ts-parity.test.cjs`. The only parity test is
|
||||
`tests/issue-498-package-identity.test.cjs`, scoped to the one baked file: it
|
||||
@@ -88,7 +88,7 @@ build artifact?** Three models:
|
||||
|
||||
2. **Build at publish (recommended).** `bin/lib/*.cjs` becomes a gitignored
|
||||
build artifact emitted from a TS `src/` tree by `tsc`; npm publishes the
|
||||
built output. **Feasible today:** `package.json` already ships `get-shit-done`
|
||||
built output. **Feasible today:** `package.json` already ships `gsd-core`
|
||||
and `scripts` via its `files` array, and already runs a pre-publish build
|
||||
step (`"prepublishOnly": "npm run build:hooks"`) — the `.cjs` emit hooks into
|
||||
the same step, and `npm pack` includes on-disk artifacts regardless of
|
||||
|
||||
@@ -93,7 +93,7 @@ The `changes` job treats these paths as code-touching:
|
||||
|
||||
```
|
||||
bin/**
|
||||
get-shit-done/**
|
||||
gsd-core/**
|
||||
agents/**
|
||||
commands/**
|
||||
hooks/**
|
||||
|
||||
@@ -60,15 +60,15 @@ The installer:
|
||||
If the installer cannot resolve `get-shit-done-cc` in your environment, or you
|
||||
prefer to clean up by hand:
|
||||
|
||||
1. **Check each runtime config directory** for a `get-shit-done/` subtree left
|
||||
1. **Check each runtime config directory** for a `gsd-core/` subtree left
|
||||
by the old package:
|
||||
|
||||
```bash
|
||||
ls ~/.claude/get-shit-done/
|
||||
ls ~/.gemini/get-shit-done/
|
||||
ls ~/.codex/get-shit-done/
|
||||
ls ~/.config/opencode/get-shit-done/
|
||||
ls ~/.kilo/get-shit-done/
|
||||
ls ~/.claude/gsd-core/
|
||||
ls ~/.gemini/gsd-core/
|
||||
ls ~/.codex/gsd-core/
|
||||
ls ~/.config/opencode/gsd-core/
|
||||
ls ~/.kilo/gsd-core/
|
||||
```
|
||||
|
||||
Remove any directories found there that were written by `get-shit-done-cc`
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Date:** 2026-05-16
|
||||
**Status:** Discussion active on closed issue. Awaiting maintainer response.
|
||||
**Purpose of this document:** Serve as the primary context file for future Grok (or other) agent sessions started inside this repository (`/home/cristian/bum/get-shit-done`) so they can work on local Grok Build support and improved synchronization across multiple AI coding harnesses.
|
||||
**Purpose of this document:** Serve as the primary context file for future Grok (or other) agent sessions started inside this repository (`/home/cristian/bum/gsd-core`) so they can work on local Grok Build support and improved synchronization across multiple AI coding harnesses.
|
||||
|
||||
---
|
||||
|
||||
@@ -28,13 +28,13 @@ Currently, Grok Build is only supported via its Claude compatibility layer. This
|
||||
## 2. Current Multi-Runtime Setup (as of May 2026)
|
||||
|
||||
### Development Source (Single Source of Truth)
|
||||
- **Path:** `/home/cristian/bum/get-shit-done` (this repo — your working fork of `open-gsd/gsd-core`)
|
||||
- **Path:** `/home/cristian/bum/gsd-core` (this repo — your working fork of `open-gsd/gsd-core`)
|
||||
|
||||
### Installed Locations
|
||||
- `~/.agents/get-shit-done/` — Core workflows, references, templates, `gsd-tools.cjs`, `bin/`
|
||||
- `~/.agents/gsd-core/` — Core workflows, references, templates, `gsd-tools.cjs`, `bin/`
|
||||
- `~/.agents/skills/gsd-*` — ~125 skills (heavily GSD + many large reference skills like `userinterface-wiki`, `react-best-practices`, etc.)
|
||||
- `~/.agents/agents/` — 22 GSD sub-agents (with `.md` + `.toml`)
|
||||
- `~/.claude/skills/gsd-*` + `~/.claude/get-shit-done/` + `~/.claude/agents/` — Parallel Claude Code install (~208 skills total)
|
||||
- `~/.claude/skills/gsd-*` + `~/.claude/gsd-core/` + `~/.claude/agents/` — Parallel Claude Code install (~208 skills total)
|
||||
- `~/.grok/skills/` — Mostly empty (only the 7 official bundled Grok skills)
|
||||
- `~/.grok/` — Not yet properly used by GSD
|
||||
|
||||
@@ -92,7 +92,7 @@ From `trek-e`’s detailed closing comment on #3603:
|
||||
|
||||
## 4. Recommended Work Plan for Future Grok Sessions in This Repo
|
||||
|
||||
When a new Grok session is started inside `/home/cristian/bum/get-shit-done`, it should follow something like this phased approach:
|
||||
When a new Grok session is started inside `/home/cristian/bum/gsd-core`, it should follow something like this phased approach:
|
||||
|
||||
### Phase 0 — Orientation (Current Session Context)
|
||||
- Read this document fully.
|
||||
@@ -148,8 +148,8 @@ Possible components:
|
||||
**In this repo:**
|
||||
- `docs/grok-build-support/` (all 7 documents — highest priority)
|
||||
- `bin/install.js` (installer logic, especially runtime handling and conversion functions)
|
||||
- `get-shit-done/bin/lib/runtime-homes.cjs`
|
||||
- `get-shit-done/bin/lib/shell-command-projection.cjs` (hook projection)
|
||||
- `gsd-core/bin/lib/runtime-homes.cjs`
|
||||
- `gsd-core/bin/lib/shell-command-projection.cjs` (hook projection)
|
||||
- `sdk/shared/model-catalog.json`
|
||||
- Existing `gsd-sync-skills` skill (in `~/.agents/skills/gsd-sync-skills/`)
|
||||
- Any skills that already contain `<codex_skill_adapter>` sections (study the pattern)
|
||||
@@ -176,7 +176,7 @@ Useful commands and checks when working on this:
|
||||
|
||||
When designing improvements to sync:
|
||||
|
||||
- Single source of truth = this repository (`/home/cristian/bum/get-shit-done`).
|
||||
- Single source of truth = this repository (`/home/cristian/bum/gsd-core`).
|
||||
- Runtime-specific transformations should be as declarative and maintainable as possible.
|
||||
- The `<codex_skill_adapter>` pattern is already proven for Grok/Codex — extend it rather than reinvent.
|
||||
- Prefer generating the runtime-specific artifacts during sync rather than maintaining four separate copies.
|
||||
@@ -213,18 +213,18 @@ Then follow the phased plan in Section 4.
|
||||
## 10. Progress — May 2026 Session (Current)
|
||||
|
||||
### Audit Findings (Phase 1)
|
||||
- **Version drift confirmed**: `~/.agents/get-shit-done/` (Grok Build primary) was on 1.38.4; `~/.claude/` on 1.42.2; `~/.codex/` and `~/.gemini/` on 1.41.2.
|
||||
- **Version drift confirmed**: `~/.agents/gsd-core/` (Grok Build primary) was on 1.38.4; `~/.claude/` on 1.42.2; `~/.codex/` and `~/.gemini/` on 1.41.2.
|
||||
- `~/.agents/hooks/` was empty (no hooks active for Grok Build sessions).
|
||||
- `grok inspect` successfully discovers 80+ `gsd-*` skills via the `~/.agents/skills/` layout + the existing `<codex_skill_adapter>` blocks.
|
||||
- No `grok` or `agents` runtime existed in installer or sync logic.
|
||||
- `~/.grok/` itself contains only the 7 official bundled skills; GSD lives entirely in the shared `~/.agents/` layout.
|
||||
|
||||
### Immediate Actions Taken
|
||||
- **Engine drift fixed ASAP**: Backed up old `~/.agents/get-shit-done/` to `.backup-1.38.4/`, then rsynced the current source `get-shit-done/` tree into `~/.agents/get-shit-done/`. Now running the latest from this repo (v1.50.0-canary.0). New modules (active-workstream-store, adr-parser, etc.) and updated workflows are live for Grok Build sessions.
|
||||
- **Engine drift fixed ASAP**: Backed up old `~/.agents/gsd-core/` to `.backup-1.38.4/`, then rsynced the current source `gsd-core/` tree into `~/.agents/gsd-core/`. Now running the latest from this repo (v1.50.0-canary.0). New modules (active-workstream-store, adr-parser, etc.) and updated workflows are live for Grok Build sessions.
|
||||
- **First-class 'grok' runtime added** (pragmatic choice: maps to `~/.agents/`):
|
||||
- [get-shit-done/bin/lib/runtime-homes.cjs](/home/cristian/bum/get-shit-done/get-shit-done/bin/lib/runtime-homes.cjs): Added `grok` case (honors `GROK_AGENTS_HOME` env, defaults to `~/.agents`).
|
||||
- [bin/install.js](/home/cristian/bum/get-shit-done/bin/install.js): Added `--grok` flag, `hasGrok`, `getDirName('grok') → '.agents'`, `getGlobalDir('grok')`, `getConfigDirFromHome`, inclusion in `--all` and help text. Reuses existing Codex conversion logic (skill adapters + agent .toml generation) because Grok Build uses the same invocation model.
|
||||
- [get-shit-done/workflows/sync-skills.md](/home/cristian/bum/get-shit-done/get-shit-done/workflows/sync-skills.md): Added `grok` to supported runtimes and the `--to all` list.
|
||||
- [gsd-core/bin/lib/runtime-homes.cjs](/home/cristian/bum/gsd-core/gsd-core/bin/lib/runtime-homes.cjs): Added `grok` case (honors `GROK_AGENTS_HOME` env, defaults to `~/.agents`).
|
||||
- [bin/install.js](/home/cristian/bum/gsd-core/bin/install.js): Added `--grok` flag, `hasGrok`, `getDirName('grok') → '.agents'`, `getGlobalDir('grok')`, `getConfigDirFromHome`, inclusion in `--all` and help text. Reuses existing Codex conversion logic (skill adapters + agent .toml generation) because Grok Build uses the same invocation model.
|
||||
- [gsd-core/workflows/sync-skills.md](/home/cristian/bum/gsd-core/gsd-core/workflows/sync-skills.md): Added `grok` to supported runtimes and the `--to all` list.
|
||||
- Verified: `node bin/install.js --skills-root grok` correctly returns `~/.agents/skills`.
|
||||
|
||||
### Next Steps (for follow-up sessions)
|
||||
|
||||
@@ -48,7 +48,7 @@ Context engineering alone is not enough. If an agent starts fresh but receives v
|
||||
|
||||
**Spec-driven development** means that every phase produces structured artefacts before execution begins. A `CONTEXT.md` captures implementation decisions from the Discuss step. A `RESEARCH.md` records what the researcher found. A `PLAN.md` breaks work into discrete, dependency-ordered tasks with explicit acceptance criteria. By the time an executor agent touches a file, it has a precise specification to work from — not a re-interpretation of a long conversation.
|
||||
|
||||
**Meta-prompting** means the agent definitions themselves are carefully engineered prompts, not ad-hoc instructions. The files in `get-shit-done/workflows/` and `agents/` encode hard-won knowledge about how to scope tasks, what to verify, and when to escalate to a human checkpoint. The user does not need to re-explain this knowledge in every session; it is baked into the system's own prompts.
|
||||
**Meta-prompting** means the agent definitions themselves are carefully engineered prompts, not ad-hoc instructions. The files in `gsd-core/workflows/` and `agents/` encode hard-won knowledge about how to scope tasks, what to verify, and when to escalate to a human checkpoint. The user does not need to re-explain this knowledge in every session; it is baked into the system's own prompts.
|
||||
|
||||
The combination is deliberate. Fresh context ensures each agent reasons clearly. Spec-driven artefacts ensure each agent reasons about the *right* thing. Meta-prompting ensures each agent knows *how* to reason about it well.
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ collects the result, and updates shared state in `.planning/`.
|
||||
|
||||
## The orchestrator → agent pattern
|
||||
|
||||
Every workflow in `get-shit-done/workflows/` follows the same shape:
|
||||
Every workflow in `gsd-core/workflows/` follows the same shape:
|
||||
|
||||
```text
|
||||
Orchestrator (workflow .md file)
|
||||
|
||||
@@ -129,7 +129,7 @@ exfiltrate information.
|
||||
|
||||
GSD Core addresses prompt injection at three levels.
|
||||
|
||||
**Input validation (`security.cjs`).** The `get-shit-done/bin/lib/security.cjs`
|
||||
**Input validation (`security.cjs`).** The `gsd-core/bin/lib/security.cjs`
|
||||
module is the central security utility. It provides:
|
||||
|
||||
- Path traversal prevention: user-supplied file paths (`--text-file`, `--prd`)
|
||||
|
||||
@@ -89,19 +89,19 @@ This recreates missing `STATE.md`, resets a corrupt `config.json` to defaults, a
|
||||
This produces warning `W002`. Use the state CLI to diagnose and repair:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state validate
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state validate
|
||||
```
|
||||
|
||||
Preview what a sync would change without writing:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state sync --verify
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state sync --verify
|
||||
```
|
||||
|
||||
Apply the sync:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state sync
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state sync
|
||||
```
|
||||
|
||||
These commands reconstruct `STATE.md` from actual project state on disk. They replace manual `STATE.md` editing.
|
||||
|
||||
@@ -481,6 +481,17 @@ This sequence keeps the first implementation small: the existing installer
|
||||
continues to materialize files, while the migration runner takes ownership of
|
||||
cleanup, classification, and reviewable destructive changes.
|
||||
|
||||
## Shipped Migrations
|
||||
|
||||
Each row corresponds to one migration record in `src/installer-migrations/`.
|
||||
|
||||
| ID | File | Introduced In | Scopes | Destructive | Summary |
|
||||
|----|------|---------------|--------|-------------|---------|
|
||||
| `2026-05-11-first-time-baseline-scan` | `000-first-time-baseline.cts` | 1.50.0 | global, local | No | Records classification baseline for existing installs before destructive migrations run. |
|
||||
| `2026-05-11-legacy-orphan-files` | `001-legacy-orphan-files.cts` | 1.50.0 | global, local | Yes | Removes manifest-managed legacy orphan hook files (`hooks/gsd-notify.sh`, `hooks/statusline.js`) retired by the installer. |
|
||||
| `2026-05-11-codex-legacy-hooks-json` | `002-codex-legacy-hooks-json.cts` | 1.50.0 | global, local | Yes | Removes legacy GSD hook registrations from Codex `hooks.json` after the `config.toml` migration. |
|
||||
| `2026-06-02-rename-get-shit-done-to-gsd-core` | `003-rename-get-shit-done-to-gsd-core.cts` | 1.2.0 | global, local | Yes | Removes managed files from the stale `get-shit-done/` runtime directory after the rename to `gsd-core/` (#604). User-added files are preserved; emptied directories may remain (framework limitation). <!-- gsd-allow-legacy-name --> |
|
||||
|
||||
## Prior Art
|
||||
|
||||
The design borrows from established upgrade systems:
|
||||
|
||||
@@ -39,7 +39,7 @@ Fields:
|
||||
|
||||
## Error code taxonomy
|
||||
|
||||
Codes are frozen constants in `get-shit-done/bin/lib/core.cjs` under
|
||||
Codes are frozen constants in `gsd-core/bin/lib/core.cjs` under
|
||||
`ERROR_REASON`. Tests must assert on `reason` values (stable), not `message`
|
||||
text (unstable).
|
||||
|
||||
@@ -117,7 +117,7 @@ assert.strictEqual(err.reason, 'sdk_unknown_command');
|
||||
## Adding a new error code
|
||||
|
||||
1. Add the constant to `ERROR_REASON` in
|
||||
`get-shit-done/bin/lib/core.cjs` (snake\_case, prefixed by subsystem).
|
||||
`gsd-core/bin/lib/core.cjs` (snake\_case, prefixed by subsystem).
|
||||
2. Pass it as the second argument to `error()` at the call site.
|
||||
3. Add a row to this document.
|
||||
4. Add a test asserting the new `reason` code via `JSON.parse`.
|
||||
|
||||
@@ -48,7 +48,7 @@ Use `--local` instead of `--global` for a project-scoped install.
|
||||
|
||||
The installer performs a clean wipe-and-replace of GSD-managed directories only:
|
||||
|
||||
- `~/.claude/get-shit-done/` — workflows, references, templates
|
||||
- `~/.claude/gsd-core/` — workflows, references, templates
|
||||
- `~/.claude/commands/gsd/` — slash commands
|
||||
- `~/.claude/agents/gsd-*.md` — GSD agents
|
||||
- `~/.claude/hooks/dist/` — compiled hooks
|
||||
|
||||
@@ -41,7 +41,7 @@ The fix is mechanical: for every hand-synced pair, replace one side with a gener
|
||||
|
||||
## Approach
|
||||
|
||||
The repo already has a working precedent for shared CJS/SDK Modules: `sdk/scripts/gen-command-aliases.ts` emits both `sdk/src/query/command-aliases.generated.ts` and `get-shit-done/bin/lib/command-aliases.generated.cjs` from a single TypeScript source. `sdk/scripts/check-command-aliases-fresh.mjs` is the CI freshness gate that fails when either generated file drifts from the source. This PRD generalizes that pattern to every Shared Module.
|
||||
The repo already has a working precedent for shared CJS/SDK Modules: `sdk/scripts/gen-command-aliases.ts` emits both `sdk/src/query/command-aliases.generated.ts` and `gsd-core/bin/lib/command-aliases.generated.cjs` from a single TypeScript source. `sdk/scripts/check-command-aliases-fresh.mjs` is the CI freshness gate that fails when either generated file drifts from the source. This PRD generalizes that pattern to every Shared Module.
|
||||
|
||||
For each Shared Module being migrated:
|
||||
|
||||
@@ -66,7 +66,7 @@ Phases are sized to ship in one to two PRs each. Each phase has its own GitHub i
|
||||
|
||||
**Scope:**
|
||||
- Promote `sdk/src/query/state-document.ts` to `sdk/src/state/index.ts` (implemented).
|
||||
- Write `sdk/scripts/gen-state-document.ts` that emits `get-shit-done/bin/lib/state-document.generated.cjs` (and optionally re-exports the TS form at its existing location).
|
||||
- Write `sdk/scripts/gen-state-document.ts` that emits `gsd-core/bin/lib/state-document.generated.cjs` (and optionally re-exports the TS form at its existing location).
|
||||
- Write `sdk/scripts/check-state-document-fresh.mjs` modeled on `check-command-aliases-fresh.mjs`.
|
||||
- Replace `bin/lib/state-document.cjs` content with a thin re-export from `state-document.generated.cjs`. Keep the existing filename so callers (e.g. `workstream-inventory.cjs:16`) don't need to update imports.
|
||||
- Wire `check-state-document-fresh.mjs` into CI alongside `check-command-aliases-fresh.mjs`.
|
||||
@@ -90,7 +90,7 @@ Phases are sized to ship in one to two PRs each. Each phase has its own GitHub i
|
||||
- Add a **Configuration Module** entry to `CONTEXT.md` first. Definition: "Module owning config load, legacy-key normalization, defaults merge, and explicit on-disk migration for `.planning/config.json`." Interface and invariants per ADR §6.
|
||||
- Extract `CONFIG_DEFAULTS`, `VALID_CONFIG_KEYS`, `DYNAMIC_KEY_PATTERNS`, `RUNTIME_STATE_KEYS` to two data manifests: `sdk/shared/config-schema.manifest.json` and `sdk/shared/config-defaults.manifest.json`. Precedent: `sdk/shared/model-catalog.json`.
|
||||
- Write the Configuration Module source at `sdk/src/config/index.ts`. Implementation imports the two manifests and exports `loadConfig`, `normalizeLegacyKeys`, `mergeDefaults`, `migrateOnDisk`.
|
||||
- Write `sdk/scripts/gen-configuration.ts` to emit `get-shit-done/bin/lib/configuration.generated.cjs` and (if needed) `sdk/src/query/config-schema.generated.ts`.
|
||||
- Write `sdk/scripts/gen-configuration.ts` to emit `gsd-core/bin/lib/configuration.generated.cjs` and (if needed) `sdk/src/query/config-schema.generated.ts`.
|
||||
- Write `sdk/scripts/check-configuration-fresh.mjs`.
|
||||
- Replace the inline implementations in `bin/lib/core.cjs:loadConfig` (lines 220–243, 434–449, 485) and `bin/lib/config.cjs` (the validation surface) with thin Adapters over the generated Module. Delete the inline `CONFIG_DEFAULTS`, the false-positive warning at `core.cjs:444-449`, and the duplicated `_deepMergeConfig`.
|
||||
- Replace `sdk/src/config.ts:mergeDefaults` (lines 192–218) with a re-export from the new Module.
|
||||
@@ -113,7 +113,7 @@ Phases are sized to ship in one to two PRs each. Each phase has its own GitHub i
|
||||
|
||||
**Scope:**
|
||||
- Write the Workstream Inventory Builder source at `sdk/src/workstream/builder.ts`. Pure function: takes a list of directory entries plus per-workstream STATE.md text plus plan-scan results and returns the typed `WorkstreamPhaseInventory`/`WorkstreamInventory` projection. No fs reads.
|
||||
- Write `sdk/scripts/gen-workstream-inventory-builder.ts` to emit `get-shit-done/bin/lib/workstream-inventory-builder.generated.cjs` and `sdk/src/query/workstream-inventory-builder.generated.ts`.
|
||||
- Write `sdk/scripts/gen-workstream-inventory-builder.ts` to emit `gsd-core/bin/lib/workstream-inventory-builder.generated.cjs` and `sdk/src/query/workstream-inventory-builder.generated.ts`.
|
||||
- Write `sdk/scripts/check-workstream-inventory-builder-fresh.mjs`.
|
||||
- Refactor `bin/lib/workstream-inventory.cjs` to a sync Reader Adapter: does `fs.readdirSync` + `readFileSync` of STATE.md, calls the Builder. The projection logic is removed.
|
||||
- Refactor `sdk/src/query/workstream-inventory.ts` to an async Reader Adapter: same shape, async I/O, calls the Builder.
|
||||
@@ -177,7 +177,7 @@ Phases are sized to ship in one to two PRs each. Each phase has its own GitHub i
|
||||
### Phase 6 — Enforcement hardening + retrospective
|
||||
|
||||
**Scope:**
|
||||
- Write `scripts/lint-shared-module-handsync.cjs`. Greps for any pair of files at `get-shit-done/bin/lib/<name>.cjs` and `sdk/src/query/<name>.ts` (or `sdk/src/<name>.ts`) where neither file matches `*.generated.*` and the pair is not on an explicit allow-list. Allow-list documents the cooperating-sibling exceptions (e.g. routing files where the implementations are structurally different).
|
||||
- Write `scripts/lint-shared-module-handsync.cjs`. Greps for any pair of files at `gsd-core/bin/lib/<name>.cjs` and `sdk/src/query/<name>.ts` (or `sdk/src/<name>.ts`) where neither file matches `*.generated.*` and the pair is not on an explicit allow-list. Allow-list documents the cooperating-sibling exceptions (e.g. routing files where the implementations are structurally different).
|
||||
- Verify each Shared Module from Phases 1–4 has its own freshness check wired to CI.
|
||||
- Verify Phase 5's golden parity matrix covers every canonical command family.
|
||||
- Add CODEOWNERS rules for `sdk/src/<module>/**` for each Shared Module source-of-truth directory, for `sdk/shared/*.manifest.json`, and for `sdk/src/query-runtime-bridge.ts` (the Phase 5 boundary). Architecture-team review required.
|
||||
@@ -209,7 +209,7 @@ Phase 5 specifically preserves the in-process model: `QueryRuntimeBridge.execute
|
||||
### Build/install pipeline impact
|
||||
|
||||
- Each generator runs at build time on the developer machine (and in CI for the freshness check). No runtime generator execution.
|
||||
- The published `@opengsd/gsd-core` package already includes both `get-shit-done/bin/` and `sdk/dist/`. The generated `.cjs` files are committed to the repo (like `command-aliases.generated.cjs` today), so the install flow is unchanged — no on-install code generation.
|
||||
- The published `@opengsd/gsd-core` package already includes both `gsd-core/bin/` and `sdk/dist/`. The generated `.cjs` files are committed to the repo (like `command-aliases.generated.cjs` today), so the install flow is unchanged — no on-install code generation.
|
||||
- `npm run build:sdk` continues to do what it does. Generators are invoked via `npm run gen:<module>` per the existing precedent.
|
||||
|
||||
### Risks
|
||||
|
||||
@@ -14,7 +14,7 @@ Every phase that has been through the discuss workflow produces one `CONTEXT.md`
|
||||
|
||||
For example: `.planning/phases/03-post-feed/03-CONTEXT.md`.
|
||||
|
||||
The file is produced by `write_context` in `get-shit-done/workflows/discuss-phase.md` (or its PRD / ADR ingest express paths). It is never edited by hand during normal operation — the discuss-phase workflow writes it and downstream agents read it as a sealed source of truth.
|
||||
The file is produced by `write_context` in `gsd-core/workflows/discuss-phase.md` (or its PRD / ADR ingest express paths). It is never edited by hand during normal operation — the discuss-phase workflow writes it and downstream agents read it as a sealed source of truth.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -122,8 +122,8 @@ Lists workflow files the executor reads before starting. Always includes the exe
|
||||
|
||||
```xml
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
@~/.claude/gsd-core/workflows/execute-plan.md
|
||||
@~/.claude/gsd-core/templates/summary.md
|
||||
</execution_context>
|
||||
```
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ paused_at: null
|
||||
|
||||
### Status values
|
||||
|
||||
`normalizeStateStatus()` in `get-shit-done/bin/lib/state-document.cjs` maps raw body text to these canonical values:
|
||||
`normalizeStateStatus()` in `gsd-core/bin/lib/state-document.cjs` maps raw body text to these canonical values:
|
||||
|
||||
| Canonical value | Matched text (case-insensitive) |
|
||||
|---|---|
|
||||
@@ -133,7 +133,7 @@ If a future change replaces the regex parser with a full YAML library, these con
|
||||
|
||||
## Markdown body sections
|
||||
|
||||
The body (everything after the closing `---`) follows the template in `get-shit-done/templates/state.md`. The standard sections are:
|
||||
The body (everything after the closing `---`) follows the template in `gsd-core/templates/state.md`. The standard sections are:
|
||||
|
||||
### Project Reference
|
||||
|
||||
@@ -153,7 +153,7 @@ Where the project stands right now:
|
||||
| `Last activity:` | ISO date (`YYYY-MM-DD`) when handler-written; narrative prose when executor-authored |
|
||||
| `Progress:` | Visual bar, e.g. `[████░░░░░░] 40%` |
|
||||
|
||||
The `Status:` and `Last activity:` fields in this section are updated by GSD handlers when the existing value is a known template default (Knuth invariant: executor-authored values are preserved). The full list of known handler defaults is in `KNOWN_TEMPLATE_DEFAULTS` inside `get-shit-done/bin/lib/state-document.cjs`.
|
||||
The `Status:` and `Last activity:` fields in this section are updated by GSD handlers when the existing value is a known template default (Knuth invariant: executor-authored values are preserved). The full list of known handler defaults is in `KNOWN_TEMPLATE_DEFAULTS` inside `gsd-core/bin/lib/state-document.cjs`.
|
||||
|
||||
### Performance Metrics
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ GSD on its own consumes roughly 60% of the default skill-listing budget. When th
|
||||
|
||||
GSD has done one consolidation pass and shipped one install-time lever:
|
||||
|
||||
- **`--minimal` / `--core-only` install flag** (`bin/install.js:123`, `get-shit-done/bin/lib/install-profiles.cjs`). Stages a filtered copy of `commands/gsd/` into a temp dir before each runtime-specific copy step. Reduces ~12k tokens of cold-start overhead to ~700.
|
||||
- **`--minimal` / `--core-only` install flag** (`bin/install.js:123`, `gsd-core/bin/lib/install-profiles.cjs`). Stages a filtered copy of `commands/gsd/` into a temp dir before each runtime-specific copy step. Reduces ~12k tokens of cold-start overhead to ~700.
|
||||
- **`MINIMAL_SKILL_ALLOWLIST`** — 6 skills: `new-project`, `discuss-phase`, `plan-phase`, `execute-phase`, `help`, `update`. Zero sub-agents in minimal.
|
||||
- **Hard 100-char description budget**, enforced in CI by `scripts/lint-descriptions.cjs` and `npm run lint:descriptions`.
|
||||
- **`gsd update` (without `--minimal`)** as the documented upgrade path from minimal → full.
|
||||
@@ -235,7 +235,7 @@ Drafted for filing at <https://docs.claude.com/feedback> or similar channel; cop
|
||||
|
||||
Phase 1 — profiles (ships with ADR-0010):
|
||||
|
||||
1. In `get-shit-done/bin/lib/install-profiles.cjs`, replace the single `MINIMAL_SKILL_ALLOWLIST` constant with a `PROFILES` map. Each profile is the *transitive closure* over a base set, so `standard` includes `core` automatically.
|
||||
1. In `gsd-core/bin/lib/install-profiles.cjs`, replace the single `MINIMAL_SKILL_ALLOWLIST` constant with a `PROFILES` map. Each profile is the *transitive closure* over a base set, so `standard` includes `core` automatically.
|
||||
2. Add a `requires:` frontmatter field to every skill that calls another skill in its body. Add a lint check in `scripts/lint-descriptions.cjs` (or a sibling `lint-skill-deps.cjs`) that fails CI if a skill body references another skill that isn't in its `requires` list, and that fails if any profile would ship a skill whose `requires` aren't satisfied.
|
||||
3. Extend the `bin/install.js` argument parser: `--profile=<name>` (mutually exclusive with `--minimal`), `--profile=core,audit` for composition. Keep `--minimal` as an alias for `--profile=core`.
|
||||
4. Interactive install: if no `--profile` is given and no runtime/location is forced, present an `AskUserQuestion`-style picker. (Cowork analog already in the install flow.)
|
||||
@@ -261,7 +261,7 @@ Phase 2 — runtime surface command (follow-up ADR or amendment):
|
||||
## 10. References
|
||||
|
||||
- Issue: [#3408](https://github.com/open-gsd/get-shit-done-redux/issues/3408)
|
||||
- Existing seam: `get-shit-done/bin/lib/install-profiles.cjs`
|
||||
- Existing seam: `gsd-core/bin/lib/install-profiles.cjs`
|
||||
- Description lint: `scripts/lint-descriptions.cjs`
|
||||
- Install dispatcher: `bin/install.js:123` (mode parsing), `bin/install.js:8167-8207` (minimal staging)
|
||||
- Audit data: [`docs/research/data/2026-05-12-skill-audit.json`](data/2026-05-12-skill-audit.json) (per-skill dep graph, description sizes, and cluster mapping — reproducible from `commands/gsd/` and `agents/`)
|
||||
|
||||
@@ -27,7 +27,7 @@ These roots are used for managed runtime installs and inventory reporting.
|
||||
|
||||
### Deprecated Import-Only Root
|
||||
|
||||
- `~/.claude/get-shit-done/skills/`
|
||||
- `~/.claude/gsd-core/skills/`
|
||||
|
||||
This root is kept for legacy migration only. Inventory code may report it, but new installs should not write here.
|
||||
|
||||
@@ -44,7 +44,7 @@ This is not a skills root. Discovery code only checks whether it exists so inven
|
||||
- Use the directory name when `name` is missing.
|
||||
- Extract trigger hints from body lines that match `TRIGGER when: ...`.
|
||||
- Treat `gsd-*` directories as installed framework skills.
|
||||
- Treat `~/.claude/get-shit-done/skills/` entries as deprecated/import-only.
|
||||
- Treat `~/.claude/gsd-core/skills/` entries as deprecated/import-only.
|
||||
- Treat `~/.claude/commands/gsd/` as legacy command installation metadata, not skills.
|
||||
|
||||
## Scanner Behavior
|
||||
@@ -55,14 +55,14 @@ This is not a skills root. Discovery code only checks whether it exists so inven
|
||||
- Scans project roots plus managed global roots.
|
||||
- Does not scan the deprecated import-only root.
|
||||
|
||||
### `get-shit-done/bin/lib/profile-output.cjs`
|
||||
### `gsd-core/bin/lib/profile-output.cjs`
|
||||
|
||||
- Builds the project `CLAUDE.md` skills section.
|
||||
- Scans project roots only.
|
||||
- Skips `gsd-*` directories so the project section stays focused on user/project skills.
|
||||
- Adds `.codex/skills/` to the project discovery set.
|
||||
|
||||
### `get-shit-done/bin/lib/init.cjs`
|
||||
### `gsd-core/bin/lib/init.cjs`
|
||||
|
||||
- Generates the skill inventory object for `skill-manifest`.
|
||||
- Reports `skills`, `roots`, `installation`, and `counts`.
|
||||
|
||||
@@ -18,7 +18,7 @@ This is a **beta of a beta**: ultraplan itself is in research preview, so this c
|
||||
|
||||
**In scope:**
|
||||
- New `commands/gsd/ultraplan-phase.md` command
|
||||
- New `get-shit-done/workflows/ultraplan-phase.md` workflow
|
||||
- New `gsd-core/workflows/ultraplan-phase.md` workflow
|
||||
- Runtime gate: Claude Code only (checks `$CLAUDE_CODE_VERSION`)
|
||||
- Builds structured ultraplan prompt from GSD phase context
|
||||
- Return path via existing `/gsd-import --from <file>` (no new import logic)
|
||||
@@ -65,7 +65,7 @@ Frontmatter:
|
||||
- `description:` includes `[BETA]` marker
|
||||
- `argument-hint: [phase-number]`
|
||||
- `allowed-tools:` Read, Bash, Glob, Grep
|
||||
- References: `@~/.claude/get-shit-done/workflows/ultraplan-phase.md`, ui-brand
|
||||
- References: `@~/.claude/gsd-core/workflows/ultraplan-phase.md`, ui-brand
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user