9 Commits

Author SHA1 Message Date
f1fa65ebc2 docs: record how a plugin's .mcp.json reaches apm, and document the gitea prerequisites
A review of this PR concluded that MCP was not an apm primitive, that the
.mcp.json edit therefore did nothing, and that the declaration belonged in
plugins/gitea/apm.yml under dependencies.mcp. The first half was right about
the primitive and wrong about everything that followed.

MCP is a first-class apm primitive. But the .mcp.json route already reaches
it: apm resolves a plugin manifest in the order plugin.json,
.github/plugin/plugin.json, .claude-plugin/plugin.json, so the generated
Copilot manifest wins, its mcpServers string pointer is followed, and
.mcp.json is injected into the package's dependencies.mcp with ${VAR} env
references intact. Verified against the real remote: a git-sourced install of
plugins/gitea at this branch deploys the gitea server with both references
unexpanded. No code change is needed and none is made here.

Moving the declaration into plugins/gitea/apm.yml would have broken the
build. apm-audit-ci runs apm audit --ci inside every plugins/*/, so a declared
dependency arms lockfile-exists there, which then demands an apm.lock.yaml in
the package plus that package's whole deployed tree inside the package
directory: 93 missing deployed files and 79 drifted paths, measured.

So this commit documents rather than changes:

- AGENTS.md and docs/spec/architecture.md said .mcp.json was plugin-root
  material with no .apm/ source, true of .apm/ and read as 'apm has no MCP
  concept'. Both now state what .mcp.json is, how it reaches dependencies.mcp,
  and that a plugin's own apm.yml is the one place not to declare it.
- architecture.md also records the env-strip: apm pack inlines .mcp.json into
  .claude-plugin/plugin.json and its sanitiser drops env and headers blocks
  unconditionally, ${VAR} included. Inert under apm, which never reads that
  file, but a native Claude Code plugin install reads exactly it and would
  start the server with no credentials.
- README.md gains the go toolchain prerequisite and the two environment
  variables the server needs, with placeholder values only.
- LESSONS.md records both process failures, including that three scratch
  installs inverted the result by using local ./path dependencies, where apm
  skips the plugin normalisation that injects .mcp.json.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EmiHiknxqtZPEBnW7ujgNz
2026-09-12 09:50:48 +00:00
dda7f8d3dd chore: merge main into feat/66-wire-gitea-mcp-config
Picks up the AGENTS.md session-rule trim (c613927) and the skill
references/ moves, so the MCP primitive fix lands on current main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EmiHiknxqtZPEBnW7ujgNz
2026-09-12 09:32:29 +00:00
a712f2c186 Merge pull request 'docs: trim four duplicated session rules from AGENTS.md' (#134) from docs/trim-agents-md-session-rules into main
Reviewed-on: https://git.dev.rkdr.net/Defame1297/holocron/pulls/134
2026-09-10 19:37:00 +00:00
2fb1036329 Merge branch 'main' into docs/trim-agents-md-session-rules 2026-09-10 19:36:34 +00:00
5d7c76d797 Merge pull request 'refactor(bin): move non-spec root files into references/ across four skills' (#133) from refactor/122-move-skill-root-files into main
Reviewed-on: https://git.dev.rkdr.net/Defame1297/holocron/pulls/133
Reviewed-by: Defame1297 <gitea@rkdr.net>
2026-09-10 19:36:16 +00:00
c613927fb4 docs: trim four duplicated session rules from AGENTS.md
Removes the ADR-0020 gate summary, the strict test-suite rule, the
pre-push rehearsal rule, and the commit-authoring rule. Each is already
documented at its owning source: docs/spec/gates.md carries the gate
behaviour and both command invocations, README.md carries the pre-push
rehearsal, and the git plugin's own skills carry commit authoring.

AGENTS.md is meant to hold only what applies to every session, so
content with a canonical home elsewhere does not belong here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PDj6F7SPXzh3FtPN78dZ88
2026-09-10 19:35:01 +00:00
c75e4ef4f3 fix(bin): repoint improve-codebase-architecture README's LANGUAGE.md mention
PR #133 renamed the skill's root-level LANGUAGE.md to references/language.md
but missed a prose mention (not a markdown link) in the overview paragraph.
Fix both the .apm/ source and its generated flat mirror.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PDj6F7SPXzh3FtPN78dZ88
2026-09-10 19:12:16 +00:00
4f49b2a249 refactor(bin): move non-spec root files into references/ across four skills
grill-with-docs, improve-codebase-architecture, tdd, and triage kept
non-spec markdown files at their skill root, in violation of
skill-audit's file-structure.md rule (only SKILL.md/README.md belong
at the root; everything else lives in scripts/, references/, assets/
or tests/). A root-level file is invisible to the ADR-0020
dangling-reference gate, which only resolves unqualified
`references/...` pointers.

- Moved and renamed to lowercase-kebab-case under references/:
  grill-with-docs (ADR-FORMAT.md, CONTEXT-FORMAT.md),
  improve-codebase-architecture (DEEPENING.md, INTERFACE-DESIGN.md,
  LANGUAGE.md), tdd (five files, casing was already fine), triage
  (AGENT-BRIEF.md, OUT-OF-SCOPE.md).
- Updated every in-skill link to the new references/ paths, including
  link text that still showed the old uppercase filenames.
- Fixed improve-codebase-architecture/SKILL.md's cross-skill citation
  of grill-with-docs's two files to the sanctioned possessive form
  with the references/ segment included.
- Updated all four skills' README.md file tables to match.
- Regenerated the flat content mirror via
  scripts/sync-plugin-content.sh --all.

Fixes #122.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PDj6F7SPXzh3FtPN78dZ88
2026-09-09 19:59:02 +00:00
058fb5b748 Merge pull request 'fix(tests): pin test-check-rtk-prefix.sh's pre-#113 corpus to a fixed SHA' (#131) from fix/rtk-prefix-test-pinned-ref into main
Reviewed-on: https://git.dev.rkdr.net/Defame1297/holocron/pulls/131
Reviewed-by: Defame1297 <gitea@rkdr.net>
2026-09-09 19:43:05 +00:00
44 changed files with 93 additions and 70 deletions

View File

@@ -15,6 +15,8 @@ This file carries only what applies to **every** session. Setup, prerequisites,
Not everything in a plugin root is generated. `README.md`, `docs/`, `bin/`, `sources.md`, `.mcp.json` and per-plugin extras are hand-authored there with no `.apm/` source — edit those in place. The rule is per-path, not per-directory. But a file placed *inside* a mirrored directory is deleted on the next sync (`sync_dir` runs `rm -rf` before every copy), so plugin-root documentation goes in `docs/`, never in `hooks/` or `skills/`. Not everything in a plugin root is generated. `README.md`, `docs/`, `bin/`, `sources.md`, `.mcp.json` and per-plugin extras are hand-authored there with no `.apm/` source — edit those in place. The rule is per-path, not per-directory. But a file placed *inside* a mirrored directory is deleted on the next sync (`sync_dir` runs `rm -rf` before every copy), so plugin-root documentation goes in `docs/`, never in `hooks/` or `skills/`.
`.mcp.json` is hand-authored but it is **not** outside apm. MCP is a first-class apm primitive, and a plugin's `.mcp.json` is how this repo declares one: apm reads the `mcpServers` pointer in the generated `.github/plugin/plugin.json`, resolves it to `.mcp.json`, and injects the result into that package's `dependencies.mcp` when a consumer installs it. Declare MCP servers there and **never** in the plugin's own `apm.yml` — that arms a per-package gate this repo cannot satisfy (`LESSONS.md`, 2026-09-12).
Full model: `docs/spec/architecture.md`. Full model: `docs/spec/architecture.md`.
## Prefer plugin skills over raw shell ## Prefer plugin skills over raw shell
@@ -36,11 +38,7 @@ Fall back to raw shell only when no skill covers it.
- **Do not add repo-owned keys to `.claude/settings.json`.** apm treats it as its own deployed artifact and `apm audit --ci` replays the install and diffs, so anything apm would not have written is permanent drift that fails the `apm-audit-ci` pre-push hook. A hook you want here is authored in `plugins/<name>/.apm/hooks/` and deployed by apm, never hand-written into that file. The `SessionStart` entry already in it is exactly that: kyberforge authors it in `plugins/kyberforge/.apm/hooks/hooks.json` and apm merges it in, so it is apm's own output, it is what the replay expects, and it belongs in the commit — do not strip it (ADR-0019). Machine-specific settings go in the gitignored `.claude/settings.local.json`; shared enforcement goes in `.pre-commit-config.yaml`. - **Do not add repo-owned keys to `.claude/settings.json`.** apm treats it as its own deployed artifact and `apm audit --ci` replays the install and diffs, so anything apm would not have written is permanent drift that fails the `apm-audit-ci` pre-push hook. A hook you want here is authored in `plugins/<name>/.apm/hooks/` and deployed by apm, never hand-written into that file. The `SessionStart` entry already in it is exactly that: kyberforge authors it in `plugins/kyberforge/.apm/hooks/hooks.json` and apm merges it in, so it is apm's own output, it is what the replay expects, and it belongs in the commit — do not strip it (ADR-0019). Machine-specific settings go in the gitignored `.claude/settings.local.json`; shared enforcement goes in `.pre-commit-config.yaml`.
- **`apm.lock.yaml` turning up modified is expected, not a bug.** kyberforge's `SessionStart` hook runs `apm outdated` at startup and `apm update --yes` when something is behind, which rewrites the lock. Commit or discard it deliberately. - **`apm.lock.yaml` turning up modified is expected, not a bug.** kyberforge's `SessionStart` hook runs `apm outdated` at startup and `apm update --yes` when something is behind, which rewrites the lock. Commit or discard it deliberately.
- **A `.apm/` edit is not live in this session until it is pushed.** The six dependencies resolve from the holocron remote, unpinned against the default branch. `apm install` deploys from the lock; `apm update` is what re-resolves refs. - **A `.apm/` edit is not live in this session until it is pushed.** The six dependencies resolve from the holocron remote, unpinned against the default branch. `apm install` deploys from the lock; `apm update` is what re-resolves refs.
- **The ADR-0020 skill gates ship hot, with no baseline — and the corpus is now clean.** All 39 skills clear both FAIL tiers: no description over 400 characters, no body over 900 words (counted body-only). Retrofitted plugin by plugin under #99 (see `docs/spec/gates.md`). Because nothing is grandfathered, the gates now bite on first commit — a new skill, or an edit that pushes a description past 400, is blocked until it complies. **No routing target dangles**, and `tests/test-adr0020-targets.sh` pins that set as empty, so a new boundary clause naming a non-existent skill fails the suite rather than joining a backlog. Two blind spots survive: `skill-size-check` does not cover the Vale half, so `Kyberforge.CompositionNote` fires nowhere today but any new description can reintroduce it; and no `references/` file is linted by anything, so prose relocated out of a body to satisfy the word gate lands outside the prose gate. It has two independent causes and closing either alone changes nothing — `docs/spec/gates.md` has both, issue #117 tracks it. Check both gates: `pre-commit run --all-files`.
- **Run `bash tests/run-tests.sh --strict` before considering any change done.** Keep the flag: without it a suite whose dependency is missing exits 77 and is counted SKIPPED rather than failed, so the run goes green having verified less than it claims.
- **Before pushing, rehearse the gate locally:** `pre-commit run --hook-stage pre-push --all-files`. It runs the 14 pre-push hooks this repo authors itself plus pre-commit's 2 `meta` hooks, so it prints 16; `check-release-needed` passes without checking anything, because it needs a real push to `main`. `docs/spec/gates.md` reconciles both.
- **Pushing without a network** needs `SKIP=apm-marketplace-check,apm-pack-check-clean git push` — those two resolve a remote marketplace entry via `git ls-remote`. Skip only those two; the rest are real local checks, and adding one to `SKIP` disarms it silently. - **Pushing without a network** needs `SKIP=apm-marketplace-check,apm-pack-check-clean git push` — those two resolve a remote marketplace entry via `git ls-remote`. Skip only those two; the rest are real local checks, and adding one to `SKIP` disarms it silently.
- **Author commits with `git-commits`** — it validates Conventional Commits, which `commit-msg` enforces.
- **This repo and Gitea are the only source of truth.** All project state, decisions, and working conventions live here. Do not use an external memory system for this project — cached state diverges from the repo and you get a split brain. Before answering any design or architecture question, check `docs/adr/` for an existing decision. - **This repo and Gitea are the only source of truth.** All project state, decisions, and working conventions live here. Do not use an external memory system for this project — cached state diverges from the repo and you get a split brain. Before answering any design or architecture question, check `docs/adr/` for an existing decision.
## Key documents ## Key documents

View File

@@ -10,6 +10,14 @@ Patterns observed during development of this repo. Three or more entries on the
--- ---
## 2026-09-12 — "Not an `.apm/` primitive" was read as "not an apm primitive", and the review that followed was wrong
`AGENTS.md` and `docs/spec/architecture.md` both listed `.mcp.json` alongside `README.md`, `docs/` and `bin/` as plugin-root material "hand-authored with no `.apm/` source". That is literally true — nothing under `.apm/` produces MCP config — but it reads as "apm has no MCP concept", and a review of PR #132 drew exactly that conclusion and recommended moving the declaration into the plugin's `apm.yml` under `dependencies.mcp`. The recommendation was wrong twice over. It arms `lockfile-exists` in the per-package `apm audit --ci` that the `apm-audit-ci` hook runs in every `plugins/*/`, which then demands the package's whole deployed tree inside the package directory: 93 missing files and 79 drifted paths on `plugins/gitea`. And it was unnecessary, because the `.mcp.json` route already reaches `dependencies.mcp` through the `mcpServers` pointer in the generated Copilot manifest, env references intact.
Two process lessons, not one. First, when a doc says a file is not a primitive **of a specific subsystem**, say which subsystem and what the file actually is instead — the negative claim alone invites the wrong generalisation. Second, the three scratch installs that produced the wrong conclusion all used local `./path` dependencies, where apm skips the plugin-normalisation step that injects `.mcp.json`. The repo consumes its plugins as `git:` + `path:` objects. A scratch test that does not reproduce the real dependency form can invert the result, so reproduce the form, not just the shape.
---
## 2026-05-17 — Workflow documents should prescribe sub-agent usage, not just allow it ## 2026-05-17 — Workflow documents should prescribe sub-agent usage, not just allow it
When writing workflow documents (like `docs/notes/skill-implementation-workflow.md`), the natural tendency is to describe steps at a high level and leave sub-agent usage as an implementation detail. But if the workflow doesn't explicitly prescribe "spawn a sub-agent here," practitioners default to doing everything in the main context — accumulating token cost and losing the isolation benefit. Fix: make sub-agent usage a named step in the workflow, specifying what the agent receives, what it returns, and why it's isolated. This makes the workflow reproducible rather than dependent on the practitioner remembering to use agents. When writing workflow documents (like `docs/notes/skill-implementation-workflow.md`), the natural tendency is to describe steps at a high level and leave sub-agent usage as an implementation detail. But if the workflow doesn't explicitly prescribe "spawn a sub-agent here," practitioners default to doing everything in the main context — accumulating token cost and losing the isolation benefit. Fix: make sub-agent usage a named step in the workflow, specifying what the agent receives, what it returns, and why it's isolated. This makes the workflow reproducible rather than dependent on the practitioner remembering to use agents.

View File

@@ -35,6 +35,16 @@ Install all of these before setting up. Each one is a hard dependency of a git h
| `python3` + PyYAML | Required by `scripts/skill-size-check.sh` (the `skill-size-check` pre-commit hook), which reads folded YAML frontmatter | `python3` is usually present — pre-commit is itself a Python application. `pip install pyyaml` if the hook reports PyYAML missing | | `python3` + PyYAML | Required by `scripts/skill-size-check.sh` (the `skill-size-check` pre-commit hook), which reads folded YAML frontmatter | `python3` is usually present — pre-commit is itself a Python application. `pip install pyyaml` if the hook reports PyYAML missing |
| `vale` | Required by the `vale-audit-prefilter-skill` / `-agent` pre-commit hooks and the `check-vale-style-sync` pre-push hook | `brew install vale` (macOS), `snap install vale` (Linux), `choco install vale` (Windows), or https://vale.sh/docs/vale-cli/installation/ | | `vale` | Required by the `vale-audit-prefilter-skill` / `-agent` pre-commit hooks and the `check-vale-style-sync` pre-push hook | `brew install vale` (macOS), `snap install vale` (Linux), `choco install vale` (Windows), or https://vale.sh/docs/vale-cli/installation/ |
| `claude` CLI | Required by the `validate-plugins` and `validate-marketplace` pre-push hooks | Claude Code | | `claude` CLI | Required by the `validate-plugins` and `validate-marketplace` pre-push hooks | Claude Code |
| `go` toolchain | The gitea MCP server runs as `go run gitea.com/gitea/gitea-mcp@v1.7.0`, resolved from `PATH`. Without it the server fails to start and every `gitea-*` skill loses its tools | https://go.dev/dl/ — verify with `go version` |
The gitea MCP server additionally needs two environment variables exported in the shell that launches your agent. They are referenced as `${GITEA_ACCESS_TOKEN}` and `${GITEA_HOST}` in `plugins/gitea/.mcp.json`, and apm passes those references through to the deployed config unexpanded, so the values are resolved at server startup and never committed:
```bash
export GITEA_ACCESS_TOKEN='<your-gitea-token>'
export GITEA_HOST='https://<your-gitea-host>'
```
Generate the token in Gitea under Settings, Applications. Scope it to the repositories you want the agent to reach. If the server starts but every call returns an authorization error, that token is the first thing to check.
Two notes worth reading before you skip one: Two notes worth reading before you skip one:

View File

@@ -49,6 +49,13 @@ Two compilers produce the plugin roots you see in the tree:
`.apm/` is the sole hand-edited authoring source for plugin content. An edit made in the flat mirror is discarded by the next sync and is reported as drift by the `check-plugin-content-sync` pre-push hook. Hand-authored material that is not an `.apm/` primitive — `README.md`, `docs/`, `bin/`, `sources.md`, `.mcp.json`, and per-plugin extras such as `plugins/git/config.example.json`, `plugins/gitea/references/` and `plugins/bin/evals/` — lives at the plugin **root** and is untouched by either compiler. `.apm/` is the sole hand-edited authoring source for plugin content. An edit made in the flat mirror is discarded by the next sync and is reported as drift by the `check-plugin-content-sync` pre-push hook. Hand-authored material that is not an `.apm/` primitive — `README.md`, `docs/`, `bin/`, `sources.md`, `.mcp.json`, and per-plugin extras such as `plugins/git/config.example.json`, `plugins/gitea/references/` and `plugins/bin/evals/` — lives at the plugin **root** and is untouched by either compiler.
`.mcp.json` is the one entry in that list that is still load-bearing for apm rather than merely ignored by it. MCP is a first-class apm primitive — `dependencies.mcp` sits beside `dependencies.apm` in the manifest schema, and apm tracks deployed servers in `apm.lock.yaml` under `mcp_servers`, `mcp_configs` and `mcp_config_provenance`. A plugin reaches that primitive indirectly. `apm pack` writes the string `".mcp.json"` into the generated `.github/plugin/plugin.json` as its `mcpServers` value, and on install apm resolves the plugin manifest in the order `plugin.json`, `.github/plugin/plugin.json`, `.claude-plugin/plugin.json` — so the Copilot manifest wins, the pointer is followed, and `.mcp.json` is injected into the package's `dependencies.mcp` with any `${VAR}` env references intact. Verified against the real remote: a git-sourced install of `plugins/gitea` deploys the gitea server with both env references unexpanded.
Two consequences follow, and both have bitten already:
- **Do not declare `dependencies.mcp` in a plugin's own `apm.yml`.** It is the schema-correct place and it breaks the build. The `apm-audit-ci` pre-push hook runs `apm audit --ci` inside every `plugins/*/`, so a declared dependency arms `lockfile-exists` there, which then demands an `apm.lock.yaml` in the package plus every file of that package's own deployed tree present inside the package directory. Measured on `plugins/gitea`: 93 missing deployed files and 79 drifted paths.
- **`.claude-plugin/plugin.json` carries an env-stripped copy.** `apm pack` inlines `.mcp.json` there, and its sanitiser drops `env` and `headers` blocks unconditionally at any depth, `${VAR}` indirection included. That copy is inert under apm, which never reaches it, but a native Claude Code plugin install reads exactly that file and would launch the server with no credentials. Anything installed natively rather than through apm needs its MCP env supplied by the host.
That immunity is positional, not by filename. Anything placed *inside* a mirrored directory is destroyed regardless of what it is: `sync_dir` runs `rm -rf "$dst"` before every copy, and `sync_hooks_json` does the same to `hooks/`. A hand-written `README.md` under `plugins/<name>/hooks/` or `plugins/<name>/skills/` is deleted by the next sync with no drift report, because a file with no `.apm/` counterpart is simply absent from the regenerated tree. This has already cost the repo one document — `plugins/kyberforge/hooks/README.md`, since restored to `plugins/kyberforge/docs/hooks.md`. Plugin-root documentation belongs in `docs/`. That immunity is positional, not by filename. Anything placed *inside* a mirrored directory is destroyed regardless of what it is: `sync_dir` runs `rm -rf "$dst"` before every copy, and `sync_hooks_json` does the same to `hooks/`. A hand-written `README.md` under `plugins/<name>/hooks/` or `plugins/<name>/skills/` is deleted by the next sync with no drift report, because a file with no `.apm/` counterpart is simply absent from the regenerated tree. This has already cost the repo one document — `plugins/kyberforge/hooks/README.md`, since restored to `plugins/kyberforge/docs/hooks.md`. Plugin-root documentation belongs in `docs/`.
## Governance layer ## Governance layer

View File

@@ -33,5 +33,5 @@ Describe the plan or design. Expect questions one at a time, each with a recomme
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `SKILL.md` | The interview instruction plus the domain-awareness rules: file layout discovery, the five during-session behaviours, and the three-part ADR test | | `SKILL.md` | The interview instruction plus the domain-awareness rules: file layout discovery, the five during-session behaviours, and the three-part ADR test |
| `CONTEXT-FORMAT.md` | Skill-root document, cited when a term is resolved: the structure of a `CONTEXT.md` and how to write a Language entry | | `references/context-format.md` | Cited when a term is resolved: the structure of a `CONTEXT.md` and how to write a Language entry |
| `ADR-FORMAT.md` | Skill-root document, cited when an ADR is offered: `docs/adr/` naming, sequential numbering, and the ADR template | | `references/adr-format.md` | Cited when an ADR is offered: `docs/adr/` naming, sequential numbering, and the ADR template |

View File

@@ -76,7 +76,7 @@ When the user states how something works, check whether the code agrees. If you
### Update CONTEXT.md inline ### Update CONTEXT.md inline
When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md). When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [context-format.md](references/context-format.md).
Don't couple `CONTEXT.md` to implementation details. Only include terms that are meaningful to domain experts. Don't couple `CONTEXT.md` to implementation details. Only include terms that are meaningful to domain experts.
@@ -88,6 +88,6 @@ Only offer to create an ADR when all three are true:
2. **Surprising without context** — a future reader will wonder "why did they do it this way?" 2. **Surprising without context** — a future reader will wonder "why did they do it this way?"
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons 3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons
If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md). If any of the three is missing, skip the ADR. Use the format in [adr-format.md](references/adr-format.md).
</supporting-info> </supporting-info>

View File

@@ -10,7 +10,7 @@ Looks for places where a codebase is hard to understand, hard to test, or hard f
2. **Present candidates.** A numbered list, each with files, problem, solution and benefits — benefits stated in terms of *locality* and *leverage* and of how tests would improve. No interfaces are proposed yet; the user picks one. 2. **Present candidates.** A numbered list, each with files, problem, solution and benefits — benefits stated in terms of *locality* and *leverage* and of how tests would improve. No interfaces are proposed yet; the user picks one.
3. **Grilling loop.** Walks the design tree for the chosen candidate, with documentation side effects landing inline as decisions crystallise. 3. **Grilling loop.** Walks the design tree for the chosen candidate, with documentation side effects landing inline as decisions crystallise.
The skill is opinionated about vocabulary, and that is the point: **module, interface, implementation, depth, seam, adapter, leverage, locality**, used exactly, with no drift into "component", "service", "API" or "boundary". Domain nouns come from `CONTEXT.md`, architecture nouns from `LANGUAGE.md` — so a proposal reads as "the Order intake module", never "the FooBarHandler". The skill is opinionated about vocabulary, and that is the point: **module, interface, implementation, depth, seam, adapter, leverage, locality**, used exactly, with no drift into "component", "service", "API" or "boundary". Domain nouns come from `CONTEXT.md`, architecture nouns from `references/language.md` — so a proposal reads as "the Order intake module", never "the FooBarHandler".
ADRs are treated as decisions not to be re-litigated. A candidate that contradicts one is surfaced only when the friction is real enough to warrant reopening it, and is marked as such. ADRs are treated as decisions not to be re-litigated. A candidate that contradicts one is surfaced only when the friction is real enough to warrant reopening it, and is marked as such.
@@ -31,6 +31,6 @@ Point at a codebase or an area of one. Expect a numbered candidate list and a "w
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `SKILL.md` | Condensed glossary, key principles, and the three-stage process | | `SKILL.md` | Condensed glossary, key principles, and the three-stage process |
| `LANGUAGE.md` | Skill-root document, cited throughout `SKILL.md`: full definitions of every term, the words each one replaces, and the full principle list | | `references/language.md` | Cited throughout `SKILL.md`: full definitions of every term, the words each one replaces, and the full principle list |
| `INTERFACE-DESIGN.md` | Skill-root document, read at stage 3 when the user wants alternative interfaces explored: the parallel sub-agent "Design It Twice" pattern, framing the problem space, and the per-agent design constraints | | `references/interface-design.md` | Read at stage 3 when the user wants alternative interfaces explored: the parallel sub-agent "Design It Twice" pattern, framing the problem space, and the per-agent design constraints |
| `DEEPENING.md` | Skill-root document, cited from `INTERFACE-DESIGN.md`: how to deepen a cluster of shallow modules safely, the four dependency categories (in-process, local-substitutable, remote-but-owned, true external), seam discipline, and the replace-don't-layer testing strategy | | `references/deepening.md` | Cited from `references/interface-design.md`: how to deepen a cluster of shallow modules safely, the four dependency categories (in-process, local-substitutable, remote-but-owned, true external), seam discipline, and the replace-don't-layer testing strategy |

View File

@@ -33,7 +33,7 @@ Key principles:
- **The interface is the test surface.** - **The interface is the test surface.**
- **One adapter = hypothetical seam. Two adapters = real seam.** - **One adapter = hypothetical seam. Two adapters = real seam.**
If a term or principle above is ambiguous in the case in front of you, or you need the definitions and the principles the two lists leave out, read `LANGUAGE.md`. If a term or principle above is ambiguous in the case in front of you, or you need the definitions and the principles the two lists leave out, read `references/language.md`.
This skill is _informed_ by the project's domain model. The domain language gives names to good seams; ADRs record decisions the skill should not re-litigate. This skill is _informed_ by the project's domain model. The domain language gives names to good seams; ADRs record decisions the skill should not re-litigate.
@@ -74,7 +74,7 @@ Once the user picks a candidate, drop into a grilling conversation. Walk the des
Side effects happen inline as decisions crystallize: Side effects happen inline as decisions crystallize:
- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md` — same discipline as `grill-with-docs`, in the format `grill-with-docs`'s `CONTEXT-FORMAT.md` defines. Create the file lazily if it doesn't exist. - **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md` — same discipline as `grill-with-docs`, in the format `grill-with-docs`'s `references/context-format.md` defines. Create the file lazily if it doesn't exist.
- **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there. - **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there.
- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones. See `grill-with-docs`'s `ADR-FORMAT.md`. - **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones. See `grill-with-docs`'s `references/adr-format.md`.
- **Want to explore alternative interfaces for the deepened module?** Read `INTERFACE-DESIGN.md`. - **Want to explore alternative interfaces for the deepened module?** Read `references/interface-design.md`.

View File

@@ -1,6 +1,6 @@
# Deepening # Deepening
How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [LANGUAGE.md](LANGUAGE.md) — **module**, **interface**, **seam**, **adapter**. How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [language.md](language.md) — **module**, **interface**, **seam**, **adapter**.
## Dependency categories ## Dependency categories

View File

@@ -2,7 +2,7 @@
When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best. When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best.
Uses the vocabulary in [LANGUAGE.md](LANGUAGE.md) — **module**, **interface**, **seam**, **adapter**, **leverage**. Uses the vocabulary in [language.md](language.md) — **module**, **interface**, **seam**, **adapter**, **leverage**.
## Process ## Process
@@ -11,7 +11,7 @@ Uses the vocabulary in [LANGUAGE.md](LANGUAGE.md) — **module**, **interface**,
Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate: Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate:
- The constraints any new interface would need to satisfy - The constraints any new interface would need to satisfy
- The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md)) - The dependencies it would rely on, and which category they fall into (see [deepening.md](deepening.md))
- A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete - A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete
Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel. Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel.
@@ -20,21 +20,21 @@ Show this to the user, then immediately proceed to Step 2. The user reads and th
Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module. Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module.
Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [DEEPENING.md](DEEPENING.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint: Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [deepening.md](deepening.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint:
- Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point." - Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point."
- Agent 2: "Maximise flexibility — support many use cases and extension." - Agent 2: "Maximise flexibility — support many use cases and extension."
- Agent 3: "Optimise for the most common caller — make the default case trivial." - Agent 3: "Optimise for the most common caller — make the default case trivial."
- Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies." - Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies."
Include both [LANGUAGE.md](LANGUAGE.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language. Include both [language.md](language.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language.
Each sub-agent outputs: Each sub-agent outputs:
1. Interface (types, methods, params — plus invariants, ordering, error modes) 1. Interface (types, methods, params — plus invariants, ordering, error modes)
2. Usage example showing how callers use it 2. Usage example showing how callers use it
3. What the implementation hides behind the seam 3. What the implementation hides behind the seam
4. Dependency strategy and adapters (see [DEEPENING.md](DEEPENING.md)) 4. Dependency strategy and adapters (see [deepening.md](deepening.md))
5. Trade-offs — where leverage is high, where it's thin 5. Trade-offs — where leverage is high, where it's thin
### 3. Present and compare ### 3. Present and compare

View File

@@ -25,8 +25,8 @@ Describe the feature or bug. Expect the skill to ask what the public interface s
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `SKILL.md` | Philosophy, the horizontal-slicing anti-pattern, the four-stage workflow, and the per-cycle checklist | | `SKILL.md` | Philosophy, the horizontal-slicing anti-pattern, the four-stage workflow, and the per-cycle checklist |
| `tests.md` | Skill-root document, cited from Philosophy: worked good and bad test examples | | `references/tests.md` | Cited from Philosophy: worked good and bad test examples |
| `mocking.md` | Skill-root document, cited from Philosophy: mock at system boundaries only, and what not to mock | | `references/mocking.md` | Cited from Philosophy: mock at system boundaries only, and what not to mock |
| `deep-modules.md` | Skill-root document, cited from stage 1: what a deep module is (small interface, large implementation) and why it is the design to aim for | | `references/deep-modules.md` | Cited from stage 1: what a deep module is (small interface, large implementation) and why it is the design to aim for |
| `interface-design.md` | Skill-root document, cited from stage 1: designing interfaces for testability, starting with accepting dependencies rather than creating them | | `references/interface-design.md` | Cited from stage 1: designing interfaces for testability, starting with accepting dependencies rather than creating them |
| `refactoring.md` | Skill-root document, cited from stage 4: the refactor-candidate checklist — duplication, long methods, shallow modules, feature envy, primitive obsession | | `references/refactoring.md` | Cited from stage 4: the refactor-candidate checklist — duplication, long methods, shallow modules, feature envy, primitive obsession |

View File

@@ -18,7 +18,7 @@ metadata:
**Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior. **Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior.
If you need worked examples of the difference — a behaviour-level test beside the implementation-coupled version of the same check — read `tests.md`. If a test needs a collaborator faked, read `mocking.md` before reaching for a mock. If you need worked examples of the difference — a behaviour-level test beside the implementation-coupled version of the same check — read `references/tests.md`. If a test needs a collaborator faked, read `references/mocking.md` before reaching for a mock.
## Anti-Pattern: Horizontal Slices ## Anti-Pattern: Horizontal Slices
@@ -55,8 +55,8 @@ Before writing any code:
- [ ] Confirm with user what interface changes are needed - [ ] Confirm with user what interface changes are needed
- [ ] Confirm with user which behaviors to test (prioritize) - [ ] Confirm with user which behaviors to test (prioritize)
- [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation) - [ ] Identify opportunities for [deep modules](references/deep-modules.md) (small interface, deep implementation)
- [ ] Design interfaces for [testability](interface-design.md) - [ ] Design interfaces for [testability](references/interface-design.md)
- [ ] List the behaviors to test (not implementation steps) - [ ] List the behaviors to test (not implementation steps)
- [ ] Get user approval on the plan - [ ] Get user approval on the plan
@@ -93,7 +93,7 @@ Rules:
### 4. Refactor ### 4. Refactor
After all tests pass, look for [refactor candidates](refactoring.md): After all tests pass, look for [refactor candidates](references/refactoring.md):
- [ ] Extract duplication - [ ] Extract duplication
- [ ] Deepen modules (move complexity behind simple interfaces) - [ ] Deepen modules (move complexity behind simple interfaces)

View File

@@ -31,5 +31,5 @@ Then describe what you want in natural language — "show me anything that needs
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `SKILL.md` | The roles and state machine, the three invocation modes, the needs-info template, and how to resume a prior session | | `SKILL.md` | The roles and state machine, the three invocation modes, the needs-info template, and how to resume a prior session |
| `AGENT-BRIEF.md` | Skill-root document, cited when an issue moves to `ready-for-agent` (and reused for `ready-for-human`): how to write a brief that stays durable for weeks while the codebase moves under it — describe interfaces and behavioural contracts, not line numbers | | `references/agent-brief.md` | Cited when an issue moves to `ready-for-agent` (and reused for `ready-for-human`): how to write a brief that stays durable for weeks while the codebase moves under it — describe interfaces and behavioural contracts, not line numbers |
| `OUT-OF-SCOPE.md` | Skill-root document, cited when an enhancement is closed `wontfix` and when checking for prior rejections: how the `.out-of-scope/` knowledge base is laid out and what it is for — institutional memory, and deduplication against re-litigated requests | | `references/out-of-scope.md` | Cited when an enhancement is closed `wontfix` and when checking for prior rejections: how the `.out-of-scope/` knowledge base is laid out and what it is for — institutional memory, and deduplication against re-litigated requests |

View File

@@ -20,8 +20,8 @@ Every comment or issue posted to the issue tracker during triage **must** start
## Reference docs ## Reference docs
- [AGENT-BRIEF.md](AGENT-BRIEF.md) — how to write durable agent briefs - [agent-brief.md](references/agent-brief.md) — how to write durable agent briefs
- [OUT-OF-SCOPE.md](OUT-OF-SCOPE.md) — how the `.out-of-scope/` knowledge base works - [out-of-scope.md](references/out-of-scope.md) — how the `.out-of-scope/` knowledge base works
## Roles ## Roles
@@ -74,11 +74,11 @@ Show counts and a one-line summary per issue. Let the maintainer pick.
4. **Grill (if needed).** If the issue needs fleshing out, run a `/grill-with-docs` session. 4. **Grill (if needed).** If the issue needs fleshing out, run a `/grill-with-docs` session.
5. **Apply the outcome:** 5. **Apply the outcome:**
- `ready-for-agent` — post an agent brief comment ([AGENT-BRIEF.md](AGENT-BRIEF.md)). - `ready-for-agent` — post an agent brief comment ([agent-brief.md](references/agent-brief.md)).
- `ready-for-human` — same structure as an agent brief, but note why it can't be delegated (judgment calls, external access, design decisions, manual testing). - `ready-for-human` — same structure as an agent brief, but note why it can't be delegated (judgment calls, external access, design decisions, manual testing).
- `needs-info` — post triage notes (template below). - `needs-info` — post triage notes (template below).
- `wontfix` (bug) — polite explanation, then close. - `wontfix` (bug) — polite explanation, then close.
- `wontfix` (enhancement) — write to `.out-of-scope/`, link to it from a comment, then close ([OUT-OF-SCOPE.md](OUT-OF-SCOPE.md)). - `wontfix` (enhancement) — write to `.out-of-scope/`, link to it from a comment, then close ([out-of-scope.md](references/out-of-scope.md)).
- `needs-triage` — apply the role. Optional comment if there's partial progress. - `needs-triage` — apply the role. Optional comment if there's partial progress.
## Quick state override ## Quick state override

View File

@@ -33,5 +33,5 @@ Describe the plan or design. Expect questions one at a time, each with a recomme
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `SKILL.md` | The interview instruction plus the domain-awareness rules: file layout discovery, the five during-session behaviours, and the three-part ADR test | | `SKILL.md` | The interview instruction plus the domain-awareness rules: file layout discovery, the five during-session behaviours, and the three-part ADR test |
| `CONTEXT-FORMAT.md` | Skill-root document, cited when a term is resolved: the structure of a `CONTEXT.md` and how to write a Language entry | | `references/context-format.md` | Cited when a term is resolved: the structure of a `CONTEXT.md` and how to write a Language entry |
| `ADR-FORMAT.md` | Skill-root document, cited when an ADR is offered: `docs/adr/` naming, sequential numbering, and the ADR template | | `references/adr-format.md` | Cited when an ADR is offered: `docs/adr/` naming, sequential numbering, and the ADR template |

View File

@@ -76,7 +76,7 @@ When the user states how something works, check whether the code agrees. If you
### Update CONTEXT.md inline ### Update CONTEXT.md inline
When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md). When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [context-format.md](references/context-format.md).
Don't couple `CONTEXT.md` to implementation details. Only include terms that are meaningful to domain experts. Don't couple `CONTEXT.md` to implementation details. Only include terms that are meaningful to domain experts.
@@ -88,6 +88,6 @@ Only offer to create an ADR when all three are true:
2. **Surprising without context** — a future reader will wonder "why did they do it this way?" 2. **Surprising without context** — a future reader will wonder "why did they do it this way?"
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons 3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons
If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md). If any of the three is missing, skip the ADR. Use the format in [adr-format.md](references/adr-format.md).
</supporting-info> </supporting-info>

View File

@@ -10,7 +10,7 @@ Looks for places where a codebase is hard to understand, hard to test, or hard f
2. **Present candidates.** A numbered list, each with files, problem, solution and benefits — benefits stated in terms of *locality* and *leverage* and of how tests would improve. No interfaces are proposed yet; the user picks one. 2. **Present candidates.** A numbered list, each with files, problem, solution and benefits — benefits stated in terms of *locality* and *leverage* and of how tests would improve. No interfaces are proposed yet; the user picks one.
3. **Grilling loop.** Walks the design tree for the chosen candidate, with documentation side effects landing inline as decisions crystallise. 3. **Grilling loop.** Walks the design tree for the chosen candidate, with documentation side effects landing inline as decisions crystallise.
The skill is opinionated about vocabulary, and that is the point: **module, interface, implementation, depth, seam, adapter, leverage, locality**, used exactly, with no drift into "component", "service", "API" or "boundary". Domain nouns come from `CONTEXT.md`, architecture nouns from `LANGUAGE.md` — so a proposal reads as "the Order intake module", never "the FooBarHandler". The skill is opinionated about vocabulary, and that is the point: **module, interface, implementation, depth, seam, adapter, leverage, locality**, used exactly, with no drift into "component", "service", "API" or "boundary". Domain nouns come from `CONTEXT.md`, architecture nouns from `references/language.md` — so a proposal reads as "the Order intake module", never "the FooBarHandler".
ADRs are treated as decisions not to be re-litigated. A candidate that contradicts one is surfaced only when the friction is real enough to warrant reopening it, and is marked as such. ADRs are treated as decisions not to be re-litigated. A candidate that contradicts one is surfaced only when the friction is real enough to warrant reopening it, and is marked as such.
@@ -31,6 +31,6 @@ Point at a codebase or an area of one. Expect a numbered candidate list and a "w
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `SKILL.md` | Condensed glossary, key principles, and the three-stage process | | `SKILL.md` | Condensed glossary, key principles, and the three-stage process |
| `LANGUAGE.md` | Skill-root document, cited throughout `SKILL.md`: full definitions of every term, the words each one replaces, and the full principle list | | `references/language.md` | Cited throughout `SKILL.md`: full definitions of every term, the words each one replaces, and the full principle list |
| `INTERFACE-DESIGN.md` | Skill-root document, read at stage 3 when the user wants alternative interfaces explored: the parallel sub-agent "Design It Twice" pattern, framing the problem space, and the per-agent design constraints | | `references/interface-design.md` | Read at stage 3 when the user wants alternative interfaces explored: the parallel sub-agent "Design It Twice" pattern, framing the problem space, and the per-agent design constraints |
| `DEEPENING.md` | Skill-root document, cited from `INTERFACE-DESIGN.md`: how to deepen a cluster of shallow modules safely, the four dependency categories (in-process, local-substitutable, remote-but-owned, true external), seam discipline, and the replace-don't-layer testing strategy | | `references/deepening.md` | Cited from `references/interface-design.md`: how to deepen a cluster of shallow modules safely, the four dependency categories (in-process, local-substitutable, remote-but-owned, true external), seam discipline, and the replace-don't-layer testing strategy |

View File

@@ -33,7 +33,7 @@ Key principles:
- **The interface is the test surface.** - **The interface is the test surface.**
- **One adapter = hypothetical seam. Two adapters = real seam.** - **One adapter = hypothetical seam. Two adapters = real seam.**
If a term or principle above is ambiguous in the case in front of you, or you need the definitions and the principles the two lists leave out, read `LANGUAGE.md`. If a term or principle above is ambiguous in the case in front of you, or you need the definitions and the principles the two lists leave out, read `references/language.md`.
This skill is _informed_ by the project's domain model. The domain language gives names to good seams; ADRs record decisions the skill should not re-litigate. This skill is _informed_ by the project's domain model. The domain language gives names to good seams; ADRs record decisions the skill should not re-litigate.
@@ -74,7 +74,7 @@ Once the user picks a candidate, drop into a grilling conversation. Walk the des
Side effects happen inline as decisions crystallize: Side effects happen inline as decisions crystallize:
- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md` — same discipline as `grill-with-docs`, in the format `grill-with-docs`'s `CONTEXT-FORMAT.md` defines. Create the file lazily if it doesn't exist. - **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md` — same discipline as `grill-with-docs`, in the format `grill-with-docs`'s `references/context-format.md` defines. Create the file lazily if it doesn't exist.
- **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there. - **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there.
- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones. See `grill-with-docs`'s `ADR-FORMAT.md`. - **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones. See `grill-with-docs`'s `references/adr-format.md`.
- **Want to explore alternative interfaces for the deepened module?** Read `INTERFACE-DESIGN.md`. - **Want to explore alternative interfaces for the deepened module?** Read `references/interface-design.md`.

View File

@@ -1,6 +1,6 @@
# Deepening # Deepening
How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [LANGUAGE.md](LANGUAGE.md) — **module**, **interface**, **seam**, **adapter**. How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [language.md](language.md) — **module**, **interface**, **seam**, **adapter**.
## Dependency categories ## Dependency categories

View File

@@ -2,7 +2,7 @@
When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best. When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best.
Uses the vocabulary in [LANGUAGE.md](LANGUAGE.md) — **module**, **interface**, **seam**, **adapter**, **leverage**. Uses the vocabulary in [language.md](language.md) — **module**, **interface**, **seam**, **adapter**, **leverage**.
## Process ## Process
@@ -11,7 +11,7 @@ Uses the vocabulary in [LANGUAGE.md](LANGUAGE.md) — **module**, **interface**,
Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate: Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate:
- The constraints any new interface would need to satisfy - The constraints any new interface would need to satisfy
- The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md)) - The dependencies it would rely on, and which category they fall into (see [deepening.md](deepening.md))
- A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete - A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete
Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel. Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel.
@@ -20,21 +20,21 @@ Show this to the user, then immediately proceed to Step 2. The user reads and th
Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module. Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module.
Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [DEEPENING.md](DEEPENING.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint: Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [deepening.md](deepening.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint:
- Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point." - Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point."
- Agent 2: "Maximise flexibility — support many use cases and extension." - Agent 2: "Maximise flexibility — support many use cases and extension."
- Agent 3: "Optimise for the most common caller — make the default case trivial." - Agent 3: "Optimise for the most common caller — make the default case trivial."
- Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies." - Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies."
Include both [LANGUAGE.md](LANGUAGE.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language. Include both [language.md](language.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language.
Each sub-agent outputs: Each sub-agent outputs:
1. Interface (types, methods, params — plus invariants, ordering, error modes) 1. Interface (types, methods, params — plus invariants, ordering, error modes)
2. Usage example showing how callers use it 2. Usage example showing how callers use it
3. What the implementation hides behind the seam 3. What the implementation hides behind the seam
4. Dependency strategy and adapters (see [DEEPENING.md](DEEPENING.md)) 4. Dependency strategy and adapters (see [deepening.md](deepening.md))
5. Trade-offs — where leverage is high, where it's thin 5. Trade-offs — where leverage is high, where it's thin
### 3. Present and compare ### 3. Present and compare

View File

@@ -25,8 +25,8 @@ Describe the feature or bug. Expect the skill to ask what the public interface s
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `SKILL.md` | Philosophy, the horizontal-slicing anti-pattern, the four-stage workflow, and the per-cycle checklist | | `SKILL.md` | Philosophy, the horizontal-slicing anti-pattern, the four-stage workflow, and the per-cycle checklist |
| `tests.md` | Skill-root document, cited from Philosophy: worked good and bad test examples | | `references/tests.md` | Cited from Philosophy: worked good and bad test examples |
| `mocking.md` | Skill-root document, cited from Philosophy: mock at system boundaries only, and what not to mock | | `references/mocking.md` | Cited from Philosophy: mock at system boundaries only, and what not to mock |
| `deep-modules.md` | Skill-root document, cited from stage 1: what a deep module is (small interface, large implementation) and why it is the design to aim for | | `references/deep-modules.md` | Cited from stage 1: what a deep module is (small interface, large implementation) and why it is the design to aim for |
| `interface-design.md` | Skill-root document, cited from stage 1: designing interfaces for testability, starting with accepting dependencies rather than creating them | | `references/interface-design.md` | Cited from stage 1: designing interfaces for testability, starting with accepting dependencies rather than creating them |
| `refactoring.md` | Skill-root document, cited from stage 4: the refactor-candidate checklist — duplication, long methods, shallow modules, feature envy, primitive obsession | | `references/refactoring.md` | Cited from stage 4: the refactor-candidate checklist — duplication, long methods, shallow modules, feature envy, primitive obsession |

View File

@@ -18,7 +18,7 @@ metadata:
**Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior. **Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior.
If you need worked examples of the difference — a behaviour-level test beside the implementation-coupled version of the same check — read `tests.md`. If a test needs a collaborator faked, read `mocking.md` before reaching for a mock. If you need worked examples of the difference — a behaviour-level test beside the implementation-coupled version of the same check — read `references/tests.md`. If a test needs a collaborator faked, read `references/mocking.md` before reaching for a mock.
## Anti-Pattern: Horizontal Slices ## Anti-Pattern: Horizontal Slices
@@ -55,8 +55,8 @@ Before writing any code:
- [ ] Confirm with user what interface changes are needed - [ ] Confirm with user what interface changes are needed
- [ ] Confirm with user which behaviors to test (prioritize) - [ ] Confirm with user which behaviors to test (prioritize)
- [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation) - [ ] Identify opportunities for [deep modules](references/deep-modules.md) (small interface, deep implementation)
- [ ] Design interfaces for [testability](interface-design.md) - [ ] Design interfaces for [testability](references/interface-design.md)
- [ ] List the behaviors to test (not implementation steps) - [ ] List the behaviors to test (not implementation steps)
- [ ] Get user approval on the plan - [ ] Get user approval on the plan
@@ -93,7 +93,7 @@ Rules:
### 4. Refactor ### 4. Refactor
After all tests pass, look for [refactor candidates](refactoring.md): After all tests pass, look for [refactor candidates](references/refactoring.md):
- [ ] Extract duplication - [ ] Extract duplication
- [ ] Deepen modules (move complexity behind simple interfaces) - [ ] Deepen modules (move complexity behind simple interfaces)

View File

@@ -31,5 +31,5 @@ Then describe what you want in natural language — "show me anything that needs
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `SKILL.md` | The roles and state machine, the three invocation modes, the needs-info template, and how to resume a prior session | | `SKILL.md` | The roles and state machine, the three invocation modes, the needs-info template, and how to resume a prior session |
| `AGENT-BRIEF.md` | Skill-root document, cited when an issue moves to `ready-for-agent` (and reused for `ready-for-human`): how to write a brief that stays durable for weeks while the codebase moves under it — describe interfaces and behavioural contracts, not line numbers | | `references/agent-brief.md` | Cited when an issue moves to `ready-for-agent` (and reused for `ready-for-human`): how to write a brief that stays durable for weeks while the codebase moves under it — describe interfaces and behavioural contracts, not line numbers |
| `OUT-OF-SCOPE.md` | Skill-root document, cited when an enhancement is closed `wontfix` and when checking for prior rejections: how the `.out-of-scope/` knowledge base is laid out and what it is for — institutional memory, and deduplication against re-litigated requests | | `references/out-of-scope.md` | Cited when an enhancement is closed `wontfix` and when checking for prior rejections: how the `.out-of-scope/` knowledge base is laid out and what it is for — institutional memory, and deduplication against re-litigated requests |

View File

@@ -20,8 +20,8 @@ Every comment or issue posted to the issue tracker during triage **must** start
## Reference docs ## Reference docs
- [AGENT-BRIEF.md](AGENT-BRIEF.md) — how to write durable agent briefs - [agent-brief.md](references/agent-brief.md) — how to write durable agent briefs
- [OUT-OF-SCOPE.md](OUT-OF-SCOPE.md) — how the `.out-of-scope/` knowledge base works - [out-of-scope.md](references/out-of-scope.md) — how the `.out-of-scope/` knowledge base works
## Roles ## Roles
@@ -74,11 +74,11 @@ Show counts and a one-line summary per issue. Let the maintainer pick.
4. **Grill (if needed).** If the issue needs fleshing out, run a `/grill-with-docs` session. 4. **Grill (if needed).** If the issue needs fleshing out, run a `/grill-with-docs` session.
5. **Apply the outcome:** 5. **Apply the outcome:**
- `ready-for-agent` — post an agent brief comment ([AGENT-BRIEF.md](AGENT-BRIEF.md)). - `ready-for-agent` — post an agent brief comment ([agent-brief.md](references/agent-brief.md)).
- `ready-for-human` — same structure as an agent brief, but note why it can't be delegated (judgment calls, external access, design decisions, manual testing). - `ready-for-human` — same structure as an agent brief, but note why it can't be delegated (judgment calls, external access, design decisions, manual testing).
- `needs-info` — post triage notes (template below). - `needs-info` — post triage notes (template below).
- `wontfix` (bug) — polite explanation, then close. - `wontfix` (bug) — polite explanation, then close.
- `wontfix` (enhancement) — write to `.out-of-scope/`, link to it from a comment, then close ([OUT-OF-SCOPE.md](OUT-OF-SCOPE.md)). - `wontfix` (enhancement) — write to `.out-of-scope/`, link to it from a comment, then close ([out-of-scope.md](references/out-of-scope.md)).
- `needs-triage` — apply the role. Optional comment if there's partial progress. - `needs-triage` — apply the role. Optional comment if there's partial progress.
## Quick state override ## Quick state override