mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-05 08:23:59 +01:00
fix(ship): name the evidence ladder by skill instead of by a runtime-root path that does not exist yet
test/runtime-root-assets.test.ts checks every $GSTACK_ROOT/<path> literal in a host render against the staged root; investigate/sections/blast-radius.md lands with its own lane, so the Blast radius item and the Capy body step now say "the /investigate skill's Blast radius section, when present". Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
23220e10a9
commit
b3d3e73c73
6 files changed
+9
-7
No files matched your search
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
### Added
|
||||
- **`bin/gstack-prose-lint`, `lib/prose-lint.ts`**: the AI tells a regular expression can decide, as a free check over the files it is given. Eight rules: `vocabulary` (the autopilot word list), `not-just-but`, `metaphor-noun` (each with the plain word to use), `mid-sentence-colon` (a colon doing a conjunction's job; a label, a list introducer or a time is not one), `inline-header-list` (a bold label that restates its line), `arrow` (a measurement such as `1.6740 → 1.7010` and the `before → after` heading pass), `dropped-article` (a bare noun opening a sentence, with compound nouns such as test runs and merge commits left alone) and `unclosed-block` (a fence or HTML comment left open, since nothing after it was read). Fenced code, inline code, URLs, HTML comments and quoted words are never read, so the problem a `## Why` quotes stays in the person's words. `--unreleased` reads only a CHANGELOG's `## [Unreleased]` block, `--base <ref>` only the lines the working tree added since the merge base, and `--sections <a,b>` only the text under those `## ` headings, so an older entry or a verbatim tool section is never judged; `--gate` turns a finding into exit 1 with `PROSE_LINT_FOUND` ([docs/troubleshooting.md#prose-lint-found](docs/troubleshooting.md#prose-lint-found)); without it the run is a report and exits 0. gstack's own templates and docs keep their em dashes, because the lint gates only the CHANGELOG entry and the PR body sections the author writes. The word lists come from pstack's unslop skill (Lauren Tan, MIT; NOTICE.md), the rules are written in gstack's words.
|
||||
- **`## Blast radius` in the /ship PR body** (`ship/sections/pr-body.md`, and `capy-pr.md` after `## Why` on the Capy path): one or two sentences on what else the change touches and the one fact that makes that safe, with the rung of the evidence ladder the fact reached (a file:line read, a walked failure path, a script that ran, a repro). The ladder itself lives in `~/.claude/skills/gstack/investigate/sections/blast-radius.md` once its own lane lands; until then the item's inline rung list is the ladder.
|
||||
- **`## Blast radius` in the /ship PR body** (`ship/sections/pr-body.md`, and `capy-pr.md` after `## Why` on the Capy path): one or two sentences on what else the change touches and the one fact that makes that safe, with the rung of the evidence ladder the fact reached (a file:line read, a walked failure path, a script that ran, a repro). The ladder itself is the `/investigate` skill's Blast radius section once its own lane lands; until then the item's inline rung list is the ladder.
|
||||
- **Quality gate workflow step**: `gstack-prose-lint CHANGELOG.md --unreleased --gate` runs on every PR over the `[Unreleased]` block, which is the entry the PR adds until the train stamps it; a stamped or absent block is `none` and passes.
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -37,7 +37,7 @@ commit themes; do not repeat the captions.
|
||||
the failed run, or their request, quoted); the rest say what changes for them. No inventory: BAD "Adds
|
||||
a lint and a CI step." GOOD "'The review loop is too overzealous.' Pass 2 now reads only pass 1's range."
|
||||
6. **`## Blast radius`:** the body template's item, written once, here: what else the change touches and
|
||||
the one fact that makes that safe, with the evidence-ladder rung it reached (`~/.claude/skills/gstack/investigate/sections/blast-radius.md`, when present).
|
||||
the one fact that makes that safe, with the evidence-ladder rung it reached (the `/investigate` skill's Blast radius section, when present).
|
||||
7. **`## Approvals`:** the output of `~/.claude/skills/gstack/bin/gstack-approvals render`, verbatim. It
|
||||
escapes its cells, and the receipt never reads it as an approval citation. On
|
||||
`APPROVAL_RECORD_UNAVAILABLE` keep its text and say so in the READY report. Never type rows by hand.
|
||||
|
||||
@@ -35,7 +35,7 @@ commit themes; do not repeat the captions.
|
||||
the failed run, or their request, quoted); the rest say what changes for them. No inventory: BAD "Adds
|
||||
a lint and a CI step." GOOD "'The review loop is too overzealous.' Pass 2 now reads only pass 1's range."
|
||||
6. **`## Blast radius`:** the body template's item, written once, here: what else the change touches and
|
||||
the one fact that makes that safe, with the evidence-ladder rung it reached (`~/.claude/skills/gstack/investigate/sections/blast-radius.md`, when present).
|
||||
the one fact that makes that safe, with the evidence-ladder rung it reached (the `/investigate` skill's Blast radius section, when present).
|
||||
7. **`## Approvals`:** the output of `~/.claude/skills/gstack/bin/gstack-approvals render`, verbatim. It
|
||||
escapes its cells, and the receipt never reads it as an approval citation. On
|
||||
`APPROVAL_RECORD_UNAVAILABLE` keep its text and say so in the READY report. Never type rows by hand.
|
||||
|
||||
@@ -86,7 +86,7 @@ before the commit and names each line to rewrite.">
|
||||
<One or two sentences: what else the change touches (callers, consumers, generated
|
||||
files, hosts) and the one fact that makes that safe, with the rung of the evidence
|
||||
ladder the fact reached (file:line read, walked failure path, script ran, repro). The
|
||||
ladder is `~/.claude/skills/gstack/investigate/sections/blast-radius.md`, when present.>
|
||||
ladder is the `/investigate` skill's Blast radius section, when present.>
|
||||
|
||||
## Test Coverage
|
||||
<coverage diagram from Step 7, or "All new code paths have test coverage.">
|
||||
|
||||
@@ -77,7 +77,7 @@ before the commit and names each line to rewrite.">
|
||||
<One or two sentences: what else the change touches (callers, consumers, generated
|
||||
files, hosts) and the one fact that makes that safe, with the rung of the evidence
|
||||
ladder the fact reached (file:line read, walked failure path, script ran, repro). The
|
||||
ladder is `~/.claude/skills/gstack/investigate/sections/blast-radius.md`, when present.>
|
||||
ladder is the `/investigate` skill's Blast radius section, when present.>
|
||||
|
||||
## Test Coverage
|
||||
<coverage diagram from Step 7, or "All new code paths have test coverage.">
|
||||
|
||||
@@ -324,14 +324,16 @@ describe('wiring', () => {
|
||||
expect(summary).toContain('## Blast radius');
|
||||
expect(summary).toContain('the one fact that makes that safe');
|
||||
expect(summary).toContain('file:line read, walked failure path, script ran, repro');
|
||||
expect(summary).toContain('`~/.claude/skills/gstack/investigate/sections/blast-radius.md`, when present');
|
||||
expect(summary).toContain("the `/investigate` skill's Blast radius section, when present");
|
||||
expect(summary).not.toMatch(/skills\/gstack\/investigate\/sections\/blast-radius\.md/);
|
||||
expect(prBody).toContain('names what the user gets, not the mechanism');
|
||||
const capy = read('ship/sections/capy-pr.md.tmpl');
|
||||
expect(capy).toContain('`## Why`, `## Blast radius` and `## Approvals`');
|
||||
expect(capy).toMatch(/\*\*`## Why`:\*\* two or three sentences\. The first states the problem in the person's words/);
|
||||
expect(capy).toMatch(/BAD "[\s\S]+" GOOD "/);
|
||||
expect(capy).toContain("**`## Blast radius`:** the body template's item, written once");
|
||||
expect(capy).toContain('`~/.claude/skills/gstack/investigate/sections/blast-radius.md`, when present');
|
||||
expect(capy).toContain("the `/investigate` skill's Blast radius section, when present");
|
||||
expect(capy).not.toMatch(/skills\/gstack\/investigate\/sections\/blast-radius\.md/);
|
||||
});
|
||||
|
||||
test('the quality gate runs the lint over the [Unreleased] block, and NOTICE.md credits unslop', () => {
|
||||
|
||||
Reference in new issue
Block a user