@lab43/q 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +80 -50
  2. package/package.json +21 -4
  3. package/{.claude-plugin → q-extension/.claude-plugin}/plugin.json +1 -1
  4. package/q-extension/agents/adversarial-reviewer.md +98 -0
  5. package/q-extension/conventions/conventions.md +49 -0
  6. package/q-extension/conventions/documentation.md +79 -0
  7. package/q-extension/conventions/extensions.md +70 -0
  8. package/q-extension/conventions/issue-tracking.md +56 -0
  9. package/{conventions → q-extension/conventions}/plans.md +7 -3
  10. package/{conventions → q-extension/conventions}/principles.md +4 -2
  11. package/{conventions → q-extension/conventions}/pull-requests.md +2 -2
  12. package/q-extension/conventions/specs.md +31 -0
  13. package/{conventions → q-extension/conventions}/writing.md +8 -0
  14. package/q-extension/hooks/locked-version.mjs +169 -0
  15. package/q-extension/hooks/session-start.mjs +155 -0
  16. package/{hooks → q-extension/hooks}/session-start.sh +9 -8
  17. package/q-extension/references/agent-briefing.md +66 -0
  18. package/q-extension/references/enforce-declarations.md +16 -0
  19. package/q-extension/references/q-state.md +31 -0
  20. package/{references → q-extension/references}/run-contract.md +18 -10
  21. package/{skills → q-extension/skills}/address-feedback/SKILL.md +19 -15
  22. package/q-extension/skills/clean-worktrees/SKILL.md +66 -0
  23. package/{skills → q-extension/skills}/create-plan/SKILL.md +5 -5
  24. package/{skills → q-extension/skills}/drive/SKILL.md +1 -1
  25. package/q-extension/skills/groom-docs/SKILL.md +65 -0
  26. package/{skills/tackle → q-extension/skills/implement}/SKILL.md +14 -14
  27. package/{skills → q-extension/skills}/implement-plan/SKILL.md +14 -14
  28. package/q-extension/skills/install/SKILL.md +136 -0
  29. package/{skills → q-extension/skills}/parallelize/SKILL.md +5 -5
  30. package/q-extension/skills/reconcile/SKILL.md +110 -0
  31. package/{skills → q-extension/skills}/review/SKILL.md +5 -4
  32. package/{skills → q-extension/skills}/triage/SKILL.md +11 -11
  33. package/{skills → q-extension/skills}/update-docs/SKILL.md +22 -17
  34. package/{skills → q-extension/skills}/upstream/SKILL.md +10 -8
  35. package/.claude-plugin/marketplace.json +0 -6
  36. package/agents/adversarial-reviewer.md +0 -62
  37. package/conventions/documentation.md +0 -99
  38. package/conventions/extensions.md +0 -48
  39. package/conventions/issue-tracking.md +0 -19
  40. package/hooks/session-start.mjs +0 -125
  41. package/references/agent-briefing.md +0 -54
  42. package/references/enforce-pins.md +0 -16
  43. package/references/q-state.md +0 -31
  44. package/skills/groom-docs/SKILL.md +0 -62
  45. package/skills/install/SKILL.md +0 -150
  46. package/skills/sync/SKILL.md +0 -45
  47. package/skills/uninstall-extension/SKILL.md +0 -52
  48. package/skills/update/SKILL.md +0 -75
  49. /package/{hooks → q-extension/hooks}/hooks.json +0 -0
@@ -5,7 +5,9 @@ description: Turn session friction and the project's recorded deviations into up
5
5
 
6
6
  # Upstream
7
7
 
8
- Never edits q or an installed extension in place changes go through a PR to the repo that owns it.
8
+ Never edit q or an installed extension in place. The next install overwrites the change, and no other project ever sees it. Open a PR against the repo that owns the rule instead.
9
+
10
+ Payload docs don't name q's own repo, its practices or its layout. This skill must: a PR needs a destination, and a change set landing there has to satisfy whatever that repo checks (exception: @lab43/q conventions/extensions.md, Which rules ship).
9
11
 
10
12
  Follow the run contract — `${CLAUDE_PLUGIN_ROOT}/references/run-contract.md`.
11
13
 
@@ -16,13 +18,13 @@ Follow the run contract — `${CLAUDE_PLUGIN_ROOT}/references/run-contract.md`.
16
18
  3. The project's marked overrides — grep `docs/conventions/` for "(overrides:", dropping those that target the project's own docs.
17
19
  4. The project's unmarked elaborations — read the project docs whose filenames match one of q's conventions or an installed extension's, for rulings that build on a rule there rather than contradict it.
18
20
 
19
- Partition the candidates by destination: skill friction and "(overrides: q …)" targets belong to the q repo, `Lab43/q`; a candidate targeting an extension's doc belongs to that extension's repo, read from `repository` in `node_modules/<extension>/package.json`. An extension with no repository recorded can't be PRed — carry its candidates to the report for the user to deliver by hand.
21
+ Partition the candidates by destination: skill friction and "(overrides: @lab43/q …)" targets belong to the q repo, `Lab43/q`; a candidate targeting an extension's doc belongs to that extension's repo, read from `repository` in `node_modules/<extension>/package.json`. An extension with no repository recorded can't be PRed — carry its candidates to the report for the user to deliver by hand.
20
22
 
21
23
  ## Step 2: Converge with the user
22
24
 
23
- Qualify the candidates against q's documentation policy (see: q conventions/documentation.md). An override or elaboration made for project-specific reasons doesn't qualify. Don't disqualify one for adopting an alternative the target doc records as rejected — that is evidence against the rejection, and the candidate becomes revisiting it. Check each destination's PR history too — search open and closed PRs per candidate (`gh pr list --repo <owner>/<repo> --state all --search "<topic>"`), reading a hit's diff when its description doesn't settle the overlap: a candidate an open PR already covers is recommended defer, and one already proposed and closed without merging qualifies only with evidence the earlier PR lacked. Non-qualifiers are dropped without discussion and surface only in the report.
25
+ Qualify the candidates against q's documentation policy (see: @lab43/q conventions/documentation.md). An override or elaboration made for project-specific reasons doesn't qualify. Don't disqualify one for adopting an alternative the target doc records as rejected — that is evidence against the rejection, and the candidate becomes revisiting it. Check each destination's PR history too — search open and closed PRs per candidate (`gh pr list --repo <owner>/<repo> --state all --search "<topic>"`), reading a hit's diff when its description doesn't settle the overlap: a candidate an open PR already covers is recommended defer, and one already proposed and closed without merging qualifies only with evidence the earlier PR lacked. Non-qualifiers are dropped without discussion and surface only in the report.
24
26
 
25
- Present the qualifiers grouped by destination — for each, the proposed change and the evidence behind it — and collect a ruling on each (AskUserQuestion), a conversational stretch (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Collaboration modes). In the same batch, ask which review mode — local or ship — the deliveries run under, every destination PR and the project-side deletions alike (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Review modes). Discuss a candidate only where its ruling calls for it: the user pushes back, asks, or raises an alternative. The rulings:
27
+ Present the qualifiers grouped by destination — for each, the proposed change and the evidence behind it — and collect a ruling on each (AskUserQuestion), in conversational mode (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Collaboration modes). In the same batch, ask which review mode — local or ship — the deliveries run under, every destination PR and the project-side deletions alike (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Review modes). Discuss a candidate only where its ruling calls for it: the user pushes back, asks, or raises an alternative. The rulings:
26
28
 
27
29
  - **Ship** — joins the change set the remaining steps carry to its destination's PR.
28
30
  - **Defer** — stays recorded in the project, a candidate for a later run.
@@ -38,14 +40,14 @@ Then, for each destination with shipped candidates:
38
40
 
39
41
  1. **Clone and branch**: clone fresh into a temporary directory outside the project (`gh repo clone <owner>/<repo>`) and branch.
40
42
  2. **Read the checkout's briefing** — `CLAUDE.md` — first and follow it. It governs how the change is made.
41
- 3. **Apply the change set** for the destination. In the q repo, run `claude plugin validate --strict .`. Leave every `version` untouched, in whichever manifests carry one — releasing is the maintainer's act, not the PR's.
43
+ 3. **Apply the change set** for the destination. In the q repo, run `npm run check`. Leave every `version` untouched, in whichever manifests carry one — releasing is the maintainer's act, not the PR's.
42
44
  4. **Commit**, in ship mode — the review history stays inspectable in git.
43
- 5. **Adversarial review**: validate the change set (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Validation) with the **correctness** and **conventions** lenses, run against the checkout. Name q's own rules as the substitute grounding surface in both lenses' launches — every destination shares them, extensions being authored in projects that use q (source: q conventions/extensions.md). The checkout's own recorded deviations win where they speak. This project's project-tier rulings never apply.
44
- 6. **Local review's gate**: in local mode, run the gate over the checkout's diff, committing onto its branch (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The local gate). The gate's own reviewer pass takes the same substitute grounding as item 5's.
45
+ 5. **Adversarial review**: validate the change set (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Validation) with the **correctness** and **conventions** lenses, run against the checkout. Name q's own rules as the substitute grounding surface in both lenses' launches — every destination shares them, extensions being authored in projects that use q (source: @lab43/q conventions/extensions.md). The checkout's own recorded deviations win where they speak. This project's project-tier rulings never apply.
46
+ 6. **The local gate**: in local mode, run it over the checkout's diff, committing onto its branch (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The local gate). The gate's own reviewer pass takes the same substitute grounding as item 5's.
45
47
 
46
48
  ## Step 4: Open the PRs
47
49
 
48
- Push each destination branch and open its PR with `gh pr create` against the default branch — the Step 2 agreement covers these PRs. Author the body per the PR-authoring rules (see: q conventions/pull-requests.md); the destination's own PR conventions and template win where they speak (source: q conventions/pull-requests.md). Carry the provoking context from this session in the body — the PR is the paper trail, so provenance belongs there, never in the conventions prose (source: q conventions/documentation.md, Conventions docs). If pushing to a repo is denied, fall back to a fork and say so.
50
+ Push each destination branch and open its PR with `gh pr create` against the default branch — the Step 2 agreement covers these PRs. Author the body per the PR-authoring rules (see: @lab43/q conventions/pull-requests.md); the destination's own PR conventions and template win where they speak (source: @lab43/q conventions/pull-requests.md). Carry the provoking context from this session in the body — the PR is the paper trail, so provenance belongs there, never in the conventions prose (source: @lab43/q conventions/conventions.md, Conventions docs). If pushing to a repo is denied, fall back to a fork and say so.
49
51
 
50
52
  ## Step 5: Report
51
53
 
@@ -1,6 +0,0 @@
1
- {
2
- "name": "q",
3
- "description": "Serves q's plugin from the installed package.",
4
- "owner": { "name": "Lab43" },
5
- "plugins": [{ "name": "q", "source": "./" }]
6
- }
@@ -1,62 +0,0 @@
1
- ---
2
- name: adversarial-reviewer
3
- description: Adversarial reviewer grounded in the project's conventions — tries to refute what it is given, reporting blocking findings vs nits with file:line references and convention citations. Invoke it two ways. Work review — a diff command or files to examine, code or prose, optionally with what the work is meant to deliver (an agreed scope, or the plan plus which of its steps are in scope, which came earlier, and which are deferred) — under the correctness and/or conventions lens. Plan review — a pre-implementation plan doc — under the feasibility and/or rigor lens. For an artifact outside the invoking project — another repo's checkout — the prompt names the conventions surface that grounds the review.
4
- tools: Read, Grep, Glob, Bash
5
- model: sonnet
6
- ---
7
-
8
- You are an adversarial reviewer for this repository. Your job is to try to refute the artifact you are given — assume it has problems and hunt for them. You are read-only: never modify files and never commit. An unexpected change in the working tree is covered by that, including one you believe you caused. Report it with your findings rather than reverting it. Never run a command that changes state outside this repository. Installs, plugin or package registrations, and writes to machine-wide config belong to the run, not to the review — a command that mutates them can break a project this review has nothing to do with.
9
-
10
- Baseline checks are not your job: lint, typecheck, and the test suites are verified green before a review is launched. Never run them — a green suite is not a finding, and re-running it adds nothing. Use Bash for git and investigation. If you suspect a specific defect that only executing code can confirm, run the narrowest command that tests that suspicion (a single test file or one name-filtered test), never a package or project suite. The same economy governs facts: where the artifact records how a fact was verified, audit that evidence — is the method sound, the source current? Driving the product (launching apps or simulators, exercising UI) is outside your scope: the run owns the environment. When a suspicion only the running product can settle, report it as a finding that names exactly what to check.
11
-
12
- Your prompt supplies an artifact and a lens; the artifact decides the review:
13
-
14
- - **Work review** (see: Work review) — the artifact is a diff, given as a git command (`git diff <sha>..HEAD`, `git diff main...HEAD`) and/or a list of changed files — or, with no change in play, the files or directories to examine for what's already wrong. The prompt may also supply what the work is meant to deliver: an agreed scope, or the plan plus which of its steps are in scope, which came earlier, and which are deferred. Lenses: **correctness**, **conventions**, or both.
15
- - **Plan review** (see: Plan review) — the artifact is a plan doc from `docs/plans/`, alone. Lenses: **feasibility**, **rigor**, or both.
16
-
17
- For an artifact outside this project — another repo's checkout — the prompt names a substitute grounding surface. Wherever these instructions read this project's docs — the agent briefing's docs index, the project's conventions — read that surface instead, and treat the artifact's own repo as the codebase to search.
18
-
19
- A combined review applies each lens in turn over the same artifact. If the prompt is missing something named here, do not review: return only a line naming what is missing, so the caller can relaunch with a complete prompt.
20
-
21
- What to hunt for is defined here, not by the prompt. Anything the prompt carries beyond the artifact, the lens, and what the work is meant to deliver is background. Background may add a place to look. It never narrows the hunt. An account of what changed and why is a claim to refute, not a fact to confirm.
22
-
23
- ## Work review
24
-
25
- The artifact is a diff, or existing files with no change in play — code and prose alike. Your job is to refute it: show what shouldn't merge, or shouldn't stand. Given a diff, run its command and read every changed file in full; given files or directories, read them.
26
-
27
- Then hunt through the assigned lens or lenses:
28
-
29
- **correctness** — defects by universal engineering judgment, rules or no rules. Read enough surrounding/related code to judge integration points and the local idiom — then hunt: bugs, broken or missed edge cases, error handling, security implications, race conditions, state bugs, dead code, inconsistency with the surrounding code's patterns, missing or hollow test coverage (tests that exist but don't exercise the new behavior). This lens owns **reuse**: for each helper, component, or pattern the code introduces, search the codebase (Grep/Glob) for an existing implementation or established pattern that already covers it, and name the existing code to use instead. In prose, hunt claims the repo contradicts and references that don't resolve. When a plan or an agreed scope accompanies the work, verify the work actually delivers it — implemented, not just started — and treat falling short as a BLOCKING finding. With a plan, judge only the in-scope steps: a step assigned elsewhere and missing from the code is NOT a finding.
30
-
31
- **conventions** — defects against this project's recorded law. Read the conventions governing the artifact's territory first, found from the agent briefing's docs index. For prose, the writing rules always apply (see: q conventions/writing.md). Then hunt: violations of those docs (cite the specific doc and rule for every finding), and documentation updates the change requires per the documentation policy (README, briefing, conventions docs). Check whether a reviewed file is a living exemplar — grep the project's conventions for its path. Drift in an exemplar outranks every other finding: the docs actively send imitators to it. On a code-versus-rule conflict the rule is presumed right; grep sibling sites for evidence — many sites deviating the same way indicts the rule, one site indicts the code. Report a rule the evidence indicts as a FOLLOW-UP, flagged as a candidate to amend the rule and carrying the evidence — that call is the user's, and the code is not the thing to fix.
32
-
33
- ## Plan review
34
-
35
- The artifact is a plan doc in `docs/plans/` with no implementation yet — there is no diff to run. Your job is to refute the plan before any code is written. Read it in full. Its recorded decisions are constraints, not findings — do not relitigate them, but DO flag when verified evidence contradicts one (as a finding that names the evidence).
36
-
37
- Then hunt through the assigned lens or lenses:
38
-
39
- **feasibility** — the plan held against reality. Read every file, function, config value, and helper the plan names, plus the code around them — then hunt: claims about current behavior that the code contradicts (wrong file, wrong signature, behavior that doesn't exist); ripple effects the plan misses — search for tests, helpers, CI steps, scripts, and docs that depend on what the plan changes and aren't accounted for; plan steps already done or obsoleted by the current codebase; phases that can't stand alone as commits that build and pass their tests; insufficiency — executing every phase would still not deliver what the Goal section promises; over-engineering — machinery, phases, or generality the Goal does not require, where the codebase offers a simpler path (name it).
40
-
41
- **rigor** — the plan held against its standards. Read the plan format (see: q conventions/plans.md) and the conventions governing the plan's territory, found from the agent briefing's docs index — then hunt: violations of either, quoting the failing text and citing the rule; and sections that contradict each other. When the plan is right and the cited rule looks stale, report the conflict as a FOLLOW-UP, flagged as a candidate to amend the rule — that call is the user's, and the plan is not the thing to fix.
42
-
43
- ## Output
44
-
45
- Your final message is the review: the three sections below, each a numbered list of one-line findings, a section omitted when it is empty — except BLOCKING, which when empty is replaced by the line `NO BLOCKING FINDINGS`.
46
-
47
- ```
48
- BLOCKING:
49
- 1. <anchor> — the defect, in one line; a finding that rests on a rule names it.
50
-
51
- NITS:
52
- 1. ...
53
-
54
- FOLLOW-UPS:
55
- 1. ...
56
- ```
57
-
58
- - The anchor is the finding's evidence: `file:line` for code; the plan section plus what contradicts it for plans (`plan §Phase 2 vs src/services/email.ts:32`).
59
- - BLOCKING = what must not proceed. For a work review: wrong to merge, or wrong to leave as it stands — bugs, convention violations, reimplementation of existing code, missing tests for new behavior, unimplemented plan steps. For a plan: implementing it as written would fail, break something it doesn't mention, or violate conventions.
60
- - NITS = worth noting, fine to skip.
61
- - FOLLOW-UPS = improvements outside the review's scope, as candidates for future work — the reviewed code's approach beats an existing pattern used elsewhere (name where), duplication or debt discovered nearby. Never BLOCKING, never fixed here.
62
- - Do not invent findings to appear useful, and do not rubber-stamp — verify claims against the actual code, not its surface appearance. Every finding must name a concrete failure or a specific violated rule.
@@ -1,99 +0,0 @@
1
- # Documentation Policy
2
-
3
- Rules for what belongs in a project's documentation, where it lives, and how it stays accurate. Follow them over any instinct. Every doc this policy governs must stay reviewable by a human: hold every edit to the writing rules (see: q conventions/writing.md).
4
-
5
- ## Three tiers of conventions
6
-
7
- - **Framework conventions** — `@lab43/q`'s own `conventions/`, pinned in the project's `package.json`. It carries the rules of the workflow itself, and defines the format an extension follows. Every q project installs it, and none can remove it.
8
- - **Extension conventions** — the installed extensions (see: q conventions/extensions.md), each pinned the same way, so rule improvements reach the project on pin updates. An extension extends q with rules of its own — for a library, a stack, or an organization's shared standards.
9
- - **Project conventions** — `docs/conventions/` in the consuming repo (a fixed contract path). Everything specific to the project's stack and codebase, plus its `documentation.md` mirror of this policy, where documentation rulings and deviations are recorded. These are living docs: skills grow them as decisions are made and groom them as they rot.
10
-
11
- **Precedence: project conventions win over any extension's rule, whichever extension carries it. An extension's rule in turn wins over q's.** A project overrides a rule by recording the deviation in the project conventions doc whose topic owns it (created if needed), so the override sits where a reader applying the rule will look.
12
-
13
- - A deviation is written as an ordinary rule: the decision and the rationale, plus an overrides marker (see: Markers) naming the rule it replaces.
14
- - A deviation is refined in place or deleted as the decision evolves, never appended as a log entry.
15
- - An override outlived by its target — updated to agree, or gone — is spent and comes out.
16
- - No other override mechanism exists or is needed — the readers are agents, so a stated deviation is the mechanism.
17
-
18
- A refinement that reaches beyond this project — one that would improve a q rule, or an extension's — is a candidate to upstream. Record it as an ordinary rule where it belongs and suggest `/q:upstream` to the user in the session. Never annotate the doc with its upstream candidacy.
19
-
20
- Conventions graduate into an extension when their audience grows beyond one project (source: q conventions/extensions.md, Graduation).
21
-
22
- ## Conventions docs
23
-
24
- Rules for whoever is about to write or evaluate code — the unit this workflow reads and grows.
25
-
26
- **One topic per doc, broadly targeted until proven otherwise**: a doc is about "tests", not about "mocking data in Jest". Narrow docs scatter rules a reader needs together and multiply index lines — a doc that proves narrower than its topic merges into the doc owning the broader one. A doc narrows only by splitting, when a second topic has demonstrably grown inside it.
27
-
28
- **Every statement is a rule** — something to follow, a constraint to check, or a decision that binds future code, phrased that way. A sentence that wouldn't change what a reader writes or flags gets cut.
29
-
30
- - Descriptions of how the system currently works are not conventions — the code and exemplars carry those.
31
- - Never facts readable from the code: directory listings, dependency lists, schema enumerations, config values, and model/version names rot the moment code moves, and the code already answers them.
32
- - Record decisions and rejected alternatives only when they're highly likely to come up again: the alternative is the first thing a reader would reach for, or something deliberately ignored reads as an oversight. Each rejection names the alternative and the reason, nothing more.
33
- - The rationale stands inline — never cite the repo's issues or PRs as provenance; git history is the paper trail. Links to other projects' trackers as evidence for external-tool claims, and operational pointers to pending work tracked in an issue, remain fine.
34
-
35
- **A rule lands in the doc whose topic owns it**, integrated into the section it belongs to (see: q conventions/writing.md, Refine rather than append) — grep the surface first; the rule may sharpen a sentence already there. A new doc is created only when no existing topic owns the rule, and it arrives complete in one change: its intro (see: Taxonomy) plus its line in the agent briefing's index.
36
-
37
- ## Taxonomy
38
-
39
- The policy owns what this taxonomy names — the `docs/` directories below, the README, and the briefing — plus an authored extension's `conventions/` in its authoring repo (source: q conventions/extensions.md, Authoring). Anything else under `docs/` — assets, generated output, tooling — is outside the policy: no rule here governs it, and grooming leaves it alone.
40
-
41
- File names are kebab-case. Every doc opens with a topic title and an intro stating what the doc is *for* — its purpose, not an inventory of its contents: "Guidance for writing tests", never "Mocking data in Jest, stubbing API calls, and assertion gotchas". A purpose holds as sections change; a contents list rots on the next edit — and purpose is what a reader deciding whether the doc applies actually needs.
42
-
43
- The intro is the authoritative description of its doc. The briefing index's line for the doc is drawn from it and restates it, and grooming checks each pair for agreement.
44
-
45
- - **`docs/conventions/`** — the project's conventions docs (see: Conventions docs).
46
- - **`docs/plans/`** — feature plans across their whole lifecycle — upcoming, in flight, and shipped; format and lifecycle rules live in their own doc (see: q conventions/plans.md). Grooming checks status only — surfacing stale `pending` plans for the user's ruling — and treats merged plans' frozen bodies as exempt from accuracy, duplication, and pruning checks.
47
- - **`docs/guides/`** — guides: instructions for using and operating the product, not for writing its code (deployment walkthroughs, feature guides, operational procedures). Step-by-step detail is fine, and so are inline code-readable specifics — bucket names, URLs, ports — a reader mid-task shouldn't have to dig out of code or config; only repo-referencing facts (script names, env vars, paths, such specifics) are held to accuracy — external-console steps can't be verified from the repo.
48
- - **`README.md`** — the human overview, answering an arriving reader's questions: what this is, what it does, how to use it.
49
- - **Summarizing facts owned elsewhere is its normal mode**, not a violation — the obligation is checkability: a summary that mirrors one identifiable home carries a source marker; free-form overview prose is held accurate against the things it describes by grooming. Inline code-readable specifics — URLs, ports, commands — are fine under the same obligations; the arriving reader shouldn't have to dig for them.
50
- - **Interface, not internals**: enumerating the product's interface (commands, skills, entry points) serves the reader and belongs; inventorying the repo's internals (directory layout, file lists) restates what browsing already shows — an internal detail earns mention only when it explains something non-obvious.
51
- - **Prose is evergreen**: a sentence describing the current moment ("being migrated to…") rots silently once the moment passes — describe what the product is, and let git history carry the journey.
52
- - **`CLAUDE.md`** — the always-loaded agent briefing. Rejected: `AGENTS.md`, the cross-tool briefing convention — Claude Code doesn't read it, and q runs in Claude Code. Every line costs context in every session, so only what applies session-wide belongs; information needed for particular kinds of work lives in the relevant convention doc or skill, with at most a one-line pointer here. Two things are required:
53
- - **The standing instructions** that make the conventions bind: all three tiers of conventions apply (see: Three tiers of conventions) — check them before writing code, before design decisions and reviews, and before changing docs — and doc changes go through `/q:update-docs`, the README and the briefing itself included.
54
- - **The docs index** — one line per doc, restating its intro: every conventions doc, whether q's, an installed extension's, or the project's own, and every guide. An index line is routing, not content. A guide a session can't act on is still one it should know exists. Skills are never indexed: the session's skill list already carries every skill's name and description.
55
-
56
- ## Single source of truth
57
-
58
- Every fact has exactly one home; every other doc links to it, never restates it. A fact's home is normally implied by the taxonomy and the docs' topics — cross-references carry readers there, and no record of the placement is needed. A placement is recorded in the project's `docs/conventions/documentation.md` only when a reasonable writer or groomer would have put the fact elsewhere — the record exists so grooming doesn't re-litigate it; obvious homes need no entry.
59
-
60
- **Restatements**: a doc may restate a rule or fact it operationally depends on — a skill's procedure executing it, the briefing orienting every session with it, a README table presenting it to humans — provided the restatement carries a source marker (see: Markers). The marker is the sanction; an unmarked restatement is ordinary duplication.
61
-
62
- Rejected: a standing central registry of all shared facts and their homes. It accumulates entries whose home is obvious from the doc's topic, and it rots like any other enumeration.
63
-
64
- ## Package doc paths
65
-
66
- Reference q's docs and an extension's by package name plus path from the package root — `@acme/q-ext-x conventions/retries.md`. `q` is the alias for `@lab43/q`: `q conventions/documentation.md`. The name resolves to the installed copy in `node_modules/`, or to the package's working tree in the repo that authors it. Use the form for every such reference across the documentation surface — markers, the briefing's index lines, doc prose. Use it even for a sibling in the doc's own package: a reference must stay unambiguous when its text is quoted away from its file.
67
-
68
- ## Markers
69
-
70
- Inline cross-references tying a statement to the doc it depends on. They are the doc surface's own routing, and must suffice for a reader arriving with no skill running — the skills reinforce the routing but can't be assumed. Agents follow them to the related detail; `/q:groom-docs` reads them as recorded intent — a marked restatement or deviation is checked against its target rather than re-flagged as duplication or drift on every run.
71
-
72
- All share one grammar — `(verb: target)` or `(verb: target, section)`, the section naming a heading within the target. The target is one of:
73
-
74
- - a heading in the current doc (`see: Markers`)
75
- - a repo file or directory, by path from the repo root — a project doc (`docs/conventions/testing.md`), any other file a fact is read from (`source: config.yml`), or a directory when the text summarizes its files (`source: migrations/`)
76
- - one of q's docs or an extension's, by its path form (see: Package doc paths)
77
-
78
- In docs rendered for humans (README, guides), the marker may sit in an HTML comment — agents and grep read the raw file either way. A doc's comments are otherwise ordinary comments (see: q conventions/principles.md, Comments carry constraints, not justification).
79
-
80
- Three markers, all ordinary language:
81
-
82
- - **`(see: X)`** — cross-reference. Nothing is copied; detail lives at X. No obligations attach.
83
- - **`(source: X)`** — provenance. This text restates a fact whose authoritative home is X (see: Single source of truth).
84
- - **`(overrides: X)`** — precedence. This rule deliberately replaces the named rule — a q rule (`overrides: q conventions/documentation.md, Code examples in conventions docs`), an extension's rule (`overrides: @acme/q-ext-x conventions/retries.md, Backoff`), or a broader project convention (`overrides: docs/conventions/style.md, Magic numbers`).
85
-
86
- ## Code examples in conventions docs
87
-
88
- Prose rules carry the conventions; code carries itself:
89
-
90
- - Each pattern names a **living exemplar** — a real file in the repo — and says which of its lines are load-bearing for the pattern, so an imitator doesn't copy the incidental along with the essential. Exemplar references and these notes are a sanctioned exception to the no-code-readable-facts rule; they exist to point *into* the code.
91
- - Short shape-only snippets are allowed where a rule is illegible without one. Snippets must not be copy-paste-complete: no import paths, no env-var literals, no full bodies. Anything an agent would paste verbatim must come from the exemplar.
92
- - Symbols, files, and helpers named in prose must exist — `/q:groom-docs` greps for them.
93
-
94
- Rejected: full copy-paste code templates, even compile-checked ones — doc inaccuracies cluster inside template code and code-readable fact restatements, not prose rules, and a stale template actively produces failing code.
95
-
96
- ## Documentation is the last rung
97
-
98
- Documentation is the weakest enforcement rung (source: q conventions/principles.md, Prefer the strongest enforcement rung): conventions prose carries only what components and lint can't express — decisions, rationale, rejected alternatives, cross-component gotchas. When a rule graduates into a component or a lint rule, delete its doc prose and move the rationale into the component or lint rule itself, where the reader who would remove it will see it. A doc entry survives graduation only if it meets the rejected-alternatives bar; git history keeps everything else.
99
-
@@ -1,48 +0,0 @@
1
- # Extensions
2
-
3
- The format behind the extension conventions tier — rules for authoring and publishing a q extension.
4
-
5
- ## Identity
6
-
7
- A q extension is an npm package whose `package.json` carries the `q-extension` keyword. The keyword is the identity: how tooling tells extensions from a project's other dependencies, and how they are found on the registry. Carrying it means q's machinery:
8
-
9
- - discovers the package
10
- - indexes what it documents
11
- - reconciles the project against its releases
12
-
13
- Nothing without it is an extension — a project's own `docs/conventions/` included.
14
-
15
- q is not an extension but what extensions extend: the framework whose rules they add to and whose format they follow (source: q conventions/documentation.md, Three tiers of conventions). `@lab43/q` carries no keyword, and is named outright wherever a rule reaches it.
16
-
17
- Installing an extension runs no code. The install passes `--ignore-scripts`, and an extension declares no lifecycle scripts. An extension may ship executable files — a plugin's hooks run inside a session — but nothing in it runs as a consequence of being installed.
18
-
19
- ## Layout
20
-
21
- The layout is conditional on what the extension carries:
22
-
23
- - `conventions/` at the package root when it ships conventions docs, each written to the documentation policy (see: q conventions/documentation.md).
24
- - `.claude-plugin/` when it ships a plugin.
25
-
26
- Every extension ships at least one of the two.
27
-
28
- An extension with no `conventions/` is watermarked but never indexed, having nothing for a briefing's docs index to carry. Watermarking and indexing are separate for that reason.
29
-
30
- Rejected: a `q` metadata key in `package.json` (configurable paths, a per-doc manifest) — every job it would do is already covered by the two directories above, the keyword, and the doc intros, and an enumeration of docs rots against its own contents.
31
-
32
- ## Pinning
33
-
34
- An extension is authored in a project that itself uses q, with `@lab43/q` pinned in the extension's own `package.json` — an exact devDependency that is also the authoring project's live install (in a monorepo, the extension as a workspace), so pin and declaration are one field, never two to drift apart. Shipped in the tarball, the pin declares the q version the extension is written against; the skills hold it against a consuming project's own pin and flag drift. q carries no such pin: its version is the thing declared against.
35
-
36
- ## Authoring
37
-
38
- In its authoring project, an extension's `conventions/` joins the documentation surface — groomed and reconciled against q's updates like the project's own docs. Moving the q pin asserts that reconciliation happened: the moved pin declares the docs written against the new version (see: Pinning). Don't record a deviation from a convention you ship — edit it. Deviations, overrides, and upstreaming are for rules you consume, not rules you author. In the authoring repo, references to the extension's docs resolve to its working tree (source: q conventions/documentation.md, Package doc paths).
39
-
40
- An extension's doc may deviate from a q rule the same way a project doc does, stating the deviation with an overrides marker (see: q conventions/documentation.md, Markers); the project's own rulings still win over any extension's (source: q conventions/documentation.md, Three tiers of conventions).
41
-
42
- ## Graduation
43
-
44
- Conventions graduate into an extension when their audience grows beyond one project — org-wide rules, or rules for code that uses a product. Graduating docs move out of the authoring project's `docs/conventions/` into the extension, never copied into both homes; the authoring project keeps only its project-specific rulings local.
45
-
46
- ## Publishing
47
-
48
- The format says nothing about repositories: publishing an extension from a subdirectory of the authoring repo works as well as a dedicated repo. An extension published from a subdirectory sets `repository.directory` so registry links resolve to it. Use a `files` whitelist limiting the tarball to what the extension ships — npm adds `package.json`, the README, and the license itself.
@@ -1,19 +0,0 @@
1
- # Issue Tracking
2
-
3
- Rules for working a project's issue tracker — the shared source of work items — from any session. Sign every item you file and every comment you post: "— Claude 🤖" (source: q conventions/writing.md, Sign what you post).
4
-
5
- ## Respect existing claims
6
-
7
- An item assigned to someone else, marked in progress or blocked, or with a fix already in review is not available to pick up. A claim that looks stale — long untouched, its PR closed unmerged — may be wrong: surface it to the user rather than working the item or silently passing it by.
8
-
9
- ## Claim what you work
10
-
11
- Picking up a tracker item means assigning it to the user and moving it to the tracker's working status — on the user's agreement, asked once per session and carried forward.
12
-
13
- ## Ask before filing
14
-
15
- Filing a new tracker item — the follow-up work a session surfaces — happens on the user's agreement, given per item rather than once per session. Ask the session's candidates together, in one batch.
16
-
17
- ## Work links back
18
-
19
- The PR addressing an item links to it from the PR body; when the tracker doesn't pick that link up automatically, comment the PR's link on the item — on the user's agreement, asked once per session and carried forward.
@@ -1,125 +0,0 @@
1
- // Validate the project's q setup and, when it doesn't validate, tell the
2
- // session to run /q:sync. Claude Code loads whatever plugin version is on
3
- // disk, so drift surfaces only if something checks at session start — no
4
- // other channel runs every session. The checks: the q copy this session
5
- // loaded vs the project's pin, each watermarked package's pin vs its
6
- // watermark vs its installed version, and the reverse direction — a
7
- // q-extension devDependency with no watermark entry (installed by hand,
8
- // never indexed).
9
- //
10
- // The remedy is uniform — /q:sync re-derives the specifics and routes each
11
- // finding to its remedy — so every failure emits the same message and
12
- // the script stops at the first one. The only designed silence is a project
13
- // that declares no @lab43/q devDependency; anything else missing or
14
- // unreadable fails like any other invalid state.
15
-
16
- import fs from "node:fs";
17
- import path from "node:path";
18
- import { fileURLToPath } from "node:url";
19
-
20
- const proj = process.env.CLAUDE_PROJECT_DIR || ".";
21
- const root =
22
- process.env.CLAUDE_PLUGIN_ROOT ||
23
- path.join(path.dirname(fileURLToPath(import.meta.url)), "..");
24
-
25
- // Keep in sync with the message in session-start.sh (bash can't import it).
26
- const MESSAGE =
27
- "The q plugin could not validate this project's q setup, so its conventions and tooling may be stale or broken. Run /q:sync to repair it.";
28
-
29
- const fail = () => {
30
- console.log(
31
- JSON.stringify({
32
- hookSpecificOutput: {
33
- hookEventName: "SessionStart",
34
- additionalContext: MESSAGE,
35
- },
36
- }),
37
- );
38
- process.exit(0);
39
- };
40
- const read = (file) => {
41
- try {
42
- return fs.readFileSync(file, "utf8");
43
- } catch {
44
- return null;
45
- }
46
- };
47
- const parse = (text) => {
48
- try {
49
- return JSON.parse(text);
50
- } catch {
51
- return undefined;
52
- }
53
- };
54
- const installedVersion = (dir) => parse(read(path.join(dir, "package.json")) ?? "")?.version;
55
-
56
- // Pins: one exact devDependency for q and one per extension, in the project's
57
- // package.json. A missing manifest means not a q project. One that exists but
58
- // can't be read or parsed fails like any other invalid state.
59
- let pkgText;
60
- try {
61
- pkgText = fs.readFileSync(path.join(proj, "package.json"), "utf8");
62
- } catch (e) {
63
- if (e.code === "ENOENT" || e.code === "ENOTDIR") process.exit(0);
64
- fail();
65
- }
66
- const pkg = parse(pkgText);
67
- if (pkg === undefined) fail();
68
-
69
- const devDeps =
70
- pkg && typeof pkg.devDependencies === "object" && pkg.devDependencies !== null
71
- ? pkg.devDependencies
72
- : {};
73
-
74
- // Declaring no @lab43/q devDependency is the one designed silence. A pin that
75
- // is declared but is not a version string is an invalid state like any other,
76
- // and fails the way a malformed pin fails for every extension below.
77
- if (!Object.hasOwn(devDeps, "@lab43/q")) process.exit(0);
78
- const pinned = devDeps["@lab43/q"];
79
- if (typeof pinned !== "string") fail();
80
-
81
- // The q this session actually loaded. CLAUDE_PLUGIN_ROOT is the directory it
82
- // was resolved from, and npm wrote that copy's version, so comparing it
83
- // against the pin also catches a session running some other checkout's q.
84
- const loaded = installedVersion(root);
85
- if (typeof loaded !== "string") fail();
86
- if (loaded !== pinned) fail();
87
-
88
- // Watermarks. A pinned project with no state file is unrecorded drift.
89
- const stateText = read(path.join(proj, ".claude/q-state.json"));
90
- if (stateText === null) fail();
91
-
92
- const state = parse(stateText);
93
- if (state === undefined || typeof state !== "object" || state === null) fail();
94
-
95
- const recon = state.reconciledAgainst ?? {};
96
- if (typeof recon !== "object" || recon === null || Array.isArray(recon)) fail();
97
- // q is the framework rather than an extension, so it is checked by name: a
98
- // pinned project with no entry for it is caught here. The reverse-direction
99
- // loop below cannot stand in. It identifies extensions by a keyword read from
100
- // node_modules, which q does not carry and which an uninstalled or stale copy
101
- // doesn't supply either.
102
- if (!Object.hasOwn(recon, "@lab43/q")) fail();
103
-
104
- for (const [ext, mark] of Object.entries(recon)) {
105
- if (typeof mark !== "string") fail();
106
- const pin = Object.hasOwn(devDeps, ext) ? devDeps[ext] : undefined;
107
- if (typeof pin !== "string") fail(); // removed out of band, never reconciled
108
- if (pin !== mark) fail();
109
-
110
- const inst = installedVersion(path.join(proj, "node_modules", ext));
111
- if (typeof inst !== "string") fail();
112
- if (inst !== pin) fail();
113
- }
114
-
115
- // Reverse direction: a devDependency whose installed manifest carries the
116
- // q-extension keyword but that has no watermark entry was installed by hand
117
- // and never indexed. A dependency that isn't installed can't be identified as
118
- // an extension — skip it.
119
- for (const dep of Object.keys(devDeps)) {
120
- if (Object.hasOwn(recon, dep)) continue;
121
- const keywords = parse(
122
- read(path.join(proj, "node_modules", dep, "package.json")) ?? "",
123
- )?.keywords;
124
- if (Array.isArray(keywords) && keywords.includes("q-extension")) fail();
125
- }
@@ -1,54 +0,0 @@
1
- # Agent Briefing
2
-
3
- The shape of a project's agent briefing — `CLAUDE.md`. `/q:install` scaffolds it, `/q:update-docs` extends it, and `/q:groom-docs` checks it.
4
-
5
- The documentation policy decides what the briefing must carry (see: q conventions/documentation.md, Taxonomy). This file gives that a shape.
6
-
7
- ## The template
8
-
9
- ```markdown
10
- ## Documentation
11
-
12
- This project follows q, an agentic coding workflow. Its rules live in the project's own documentation. Those rules are conventions: binding decisions about how this project's code and docs get written, recorded as they are made. Guides sit alongside them — how to operate the project, rather than rules for writing it.
13
-
14
- If the session's skill list has no `/q:` skills, this machine is missing the q plugin — ask the user to install the project's dependencies (`npm install`, or the project's package manager's equivalent), then run `/q:sync`.
15
-
16
- When another session is already working this repo, take a worktree rather than sharing the checkout.
17
-
18
- Conventions come in three tiers: q's own, the conventions of any installed extensions, and this project's own `docs/conventions/` (source: q conventions/documentation.md, Three tiers of conventions). q and the extensions are pinned in `package.json`. Project rules win over an extension's rule, and an extension's rule wins over q's. Check all three tiers before writing code, before design decisions and reviews, and before changing docs. Doc changes — the README and this briefing itself included — go through `/q:update-docs`.
19
-
20
- Package doc paths are package name plus path from the package root, resolved under `node_modules/`. `q` abbreviates `@lab43/q`: `q conventions/principles.md` is `node_modules/@lab43/q/conventions/principles.md` (source: q conventions/documentation.md, Package doc paths).
21
-
22
- q:
23
-
24
- - `q conventions/principles.md` — cross-cutting rules for any design decision, plan, or review
25
- - `q conventions/documentation.md` — what belongs in a project's documentation, where it lives, and how it stays accurate
26
- - `q conventions/extensions.md` — the extension format: rules for authoring and publishing a q extension
27
- - `q conventions/plans.md` — format, sequencing, and lifecycle rules for `docs/plans/` documents
28
- - `q conventions/issue-tracking.md` — rules for working a project's issue tracker from any session
29
- - `q conventions/pull-requests.md` — rules for authoring a pull request
30
- - `q conventions/writing.md` — rules for writing prose: docs, plans, PR bodies, anything a human or agent will read
31
-
32
- Installed extensions:
33
-
34
- - `<package> conventions/<name>.md` — one line per doc, restating its intro
35
-
36
- This project's own:
37
-
38
- - `docs/conventions/principles.md` — cross-cutting rules, including deviations from q's
39
- - `docs/conventions/documentation.md` — documentation rulings and deviations
40
-
41
- Guides:
42
-
43
- - `docs/guides/<name>.md` — one line per guide, restating its intro
44
- ```
45
-
46
- ## Maintaining it
47
-
48
- - **Write into `CLAUDE.md`**, creating it when it doesn't exist. Leave any `AGENTS.md` the project keeps for other tools alone. Linking the two is the project's call, not q's.
49
- - **Conform to the structure**: the section heading, the groups in the order they run here, one line per doc. Name each group for what it actually holds.
50
- - **Treat the prose as a floor, not a script.** Carry at least what the template's prose carries. Leave the project's own wording where it says the same thing. Where a statement isn't true of the project — it authors an extension rather than installing one, or loads the plugin some other way — say what is true instead.
51
- - **Keep what the project put there** — its own standing instructions, notes, and index entries beyond the required ones. Work missing information into what is already written rather than bolting a sentence alongside it. Rewrite freely to do that, but drop nothing the project said.
52
- - **Drop a group with no entries.** A fresh project has no extensions and no guides, so those groups arrive with the first one of each. The q group is always there.
53
- - **Index every doc the policy requires, and nothing stale** — every conventions doc, from q, from an installed extension, or the project's own, and every guide (source: q conventions/documentation.md, Taxonomy). Drop the line for a doc that is gone, including every line of an extension the project no longer installs. The installed extensions are the direct dependencies whose own `package.json` carries the `q-extension` keyword (source: q conventions/extensions.md). An extension shipping no `conventions/` contributes no lines.
54
- - **Write each line as a path plus a blurb restating the doc's intro** — q's docs and an extension's by package name plus path from the package root (see: q conventions/documentation.md, Package doc paths), the project's own by repo-relative path.
@@ -1,16 +0,0 @@
1
- # Enforce Pins
2
-
3
- The machine-local enforcement procedure: make this machine match the project's declared pins. Enforce without asking — pins are the project's recorded decisions, and this merely applies them.
4
-
5
- 1. Check that `node` and `npm` resolve. When either is missing, Node.js is not installed — report that fix. Nothing below runs without it.
6
- 2. When `node_modules/` is missing a pinned package, or holds a version other than its pin, run the project's package-manager install — `npm install`, or the pnpm or yarn equivalent its lockfile indicates. That install is the whole update mechanism: a session reads q from `node_modules/@lab43/q` as it stands, so nothing else has to reach it.
7
- 3. Register the project's marketplace: `claude plugin marketplace add --scope local ./`. The manifest at the project root supplies the name, so nothing has to read or pass one. Skip this step when the project has no `.claude-plugin/marketplace.json`. The add fails outright against a directory holding no manifest. A project without one has not been scaffolded yet. Otherwise run it unconditionally, since the add changes nothing when the registry already points here. Local scope records the registration in the project's own `.claude/settings.local.json`, which does not keep it private.
8
-
9
- Three situations need it:
10
-
11
- - A fresh clone has never registered the marketplace.
12
- - A declined trust prompt left it unregistered.
13
- - Another checkout of this repo has repointed the project's name at itself. The machine-global registry holds one entry per marketplace name. The add repoints it back, because an entry whose name matches but whose path differs is updated to the new path.
14
- 4. After any change above, run `/reload-plugins`.
15
-
16
- Name any tracked file the enforcement rewrote (a lockfile). That change stays in the tree as the user's.
@@ -1,31 +0,0 @@
1
- # The q State File
2
-
3
- Format and writer rules for `.claude/q-state.json`, the consumer-side record of the versions a project was last reconciled against. The skills that read or write the file follow this doc; nothing else edits it.
4
-
5
- ## What the file is
6
-
7
- The file holds machine-written version watermarks — never rules, never doc enumerations. Pins stay authoritative where they are: the project's `package.json`, one exact devDependency for q and one per installed extension. Reconciliation is the work of folding a version change into the project — holding its docs against an extension release's changed rules, or its scaffolded surfaces against a new q version; `/q:update` performs it. A watermark records the version its pin was last reconciled against, so an out-of-band pin move — a hand-run npm install, a teammate's merge, a Dependabot bump — is detectable as pin ≠ watermark. The skills and the session-start hook compare its versions against the pins; nothing consults it for how to behave.
8
-
9
- ## Format
10
-
11
- The file lives at `.claude/q-state.json`, committed. JSON, one key per line, so a watermark move reads as a one-line diff:
12
-
13
- ```json
14
- {
15
- "note": "Machine state written by q's skills. Never edit by hand; /q:sync reports drift.",
16
- "reconciledAgainst": {
17
- "@lab43/q": "0.3.0"
18
- }
19
- }
20
- ```
21
-
22
- `reconciledAgainst` holds one entry for `@lab43/q` and one per installed extension: the version the project was last reconciled against. q's entry has the same shape as the rest, carrying no privilege and no separate field.
23
-
24
- ## Writer rules
25
-
26
- - `/q:install` fills in missing watermarks and never touches present ones — a stale entry is reconciliation's to move. Bootstrapping q, it writes the `@lab43/q` entry; installing an extension, it writes that extension's. Each value is the version just installed, which has no reconciliation debt.
27
- - `/q:update` writes the affected watermark after each reconciliation, whether the run moved a pin or caught up an out-of-band move.
28
- - `/q:uninstall-extension` drops the extension's entry as part of reconciling its removal.
29
- - `/q:sync` reads and compares; it never writes. Watermarks certify reconciliation, and sync never reconciles.
30
-
31
- An absent file means no record — create it on the first watermark write. The file never ships in an extension: it lives in `.claude/`, outside the `files` whitelist a tarball is built from (source: q conventions/extensions.md).
@@ -1,62 +0,0 @@
1
- ---
2
- name: groom-docs
3
- description: Audit the project's whole documentation surface against the documentation policy and consolidate what has drifted. Approved edits ship as a PR. Use when docs feel inflated or stale, after a stretch of merged changes, or on a docs-cleanup request.
4
- ---
5
-
6
- # Groom Docs
7
-
8
- **Read the rubric first, and follow it over any instinct:**
9
-
10
- 1. q's documentation policy (see: q conventions/documentation.md) and its writing rules (see: q conventions/writing.md), plus any installed extension's doc whose topic governs documentation. An extension's rule beats q's where the two disagree (source: q conventions/documentation.md, Three tiers of conventions).
11
- 2. The project's recorded rulings and deviations: `docs/conventions/documentation.md` plus any "(overrides: …)" markers across `docs/conventions/` — grep for them. These win over both.
12
-
13
- If the project has no `docs/conventions/` directory, or `node_modules/@lab43/q/` is absent (a fresh clone may just need `npm install`), stop and suggest the fix — without both there is no surface or rubric to groom against.
14
-
15
- Follow the run contract — `${CLAUDE_PLUGIN_ROOT}/references/run-contract.md`.
16
-
17
- ## Step 1: Inventory
18
-
19
- Build the grooming surface, taking each item only if it exists in this project:
20
-
21
- - `docs/conventions/*.md`, `README.md`, `CLAUDE.md` (the agent briefing) — full checks.
22
- - The `conventions/` of any extension this repo authors — a working-tree `package.json` carrying the `q-extension` keyword — full checks, like the project's own conventions (source: q conventions/extensions.md). Anything else the project's own `documentation.md` puts on the surface joins it, under rubric item 2.
23
- - `docs/guides/*.md` — **guide mode**, per the policy's Taxonomy rules.
24
- - `docs/plans/*.md` — **status check only**, per the policy's `docs/plans/` taxonomy rule.
25
-
26
- Project-local `.claude/` skills and agents are outside the surface — q doesn't govern them. Everything installed under `node_modules/` is read-only, q's conventions and every extension's alike — never groomed.
27
-
28
- ## Step 2: Fan out verification (read-only subagents)
29
-
30
- Launch read-only subagents in parallel — one per check below, except accuracy, which fans out per doc cluster; the duplication and consistency sweeps each hold the whole surface, since cross-file checks can't be sharded. Each reads the rubric first and returns findings with `file:line` citations:
31
-
32
- 1. **Accuracy, per doc cluster** (conventions docs grouped by area; guides clustered separately, in guide mode): every checkable claim — file paths, symbol names, behavior descriptions, commands — verified against current source. Exemplar references get a deeper check: the file exists and still exhibits the rules its doc attaches to it.
33
- 2. **Duplication sweep**, cross-surface: facts stated in more than one place. For each, name the home — implied by the taxonomy, or assigned by a recorded ruling; where the call is genuinely contestable, flag it for the user, whose decision becomes a new ruling. The sweep also runs **cross-tier**, comparing project docs against q's conventions and every installed extension's: a project statement matching one of their rules in substance is duplication to prune; one differing from such a rule without an overrides marker naming it is drift or an unrecorded deviation — escalate to the user; a marked override whose target updated to agree or disappeared is spent — propose deleting it (source: q conventions/documentation.md, Three tiers of conventions). Those docs are read-only: an extension's stale override of a q rule, or two extensions in conflict, can't be edited here — escalate; the remedy is a project ruling or the extension author's.
34
- 3. **Dead references**: every file, symbol, helper, script, and skill named anywhere on the surface exists. Greps must exclude build artifacts (`dist/`, `node_modules/`, and the like) — stale generated files resurrect deleted symbols.
35
- 4. **Consistency**: the agent briefing matches the briefing template (see: `${CLAUDE_PLUGIN_ROOT}/references/agent-briefing.md`); any README skills/conventions table matches its home (skill tables drift-check against `SKILL.md` frontmatter descriptions); cross-references between docs resolve.
36
- 5. **Organization**: each doc's structure — topic scope, intro, section placement, and splits or merges across docs — conforms to the policy. Findings here become reorganization proposals.
37
- 6. **Plan statuses** (if `docs/plans/` exists): every plan has valid `status` frontmatter (source: q conventions/plans.md, Frontmatter); list every `pending` plan with its age (last git commit date).
38
-
39
- ## Step 3: Consolidate with the user
40
-
41
- Merge the findings into proposed edits, each stating its remedy and citing its finding — a conversational stretch (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Collaboration modes).
42
-
43
- - Apply autonomously: wording-level fixes, replacing a single restated sentence or bullet with a cross-reference to its home, and dead-reference corrections.
44
- - **Everything else goes to the user** (AskUserQuestion) — including larger deletions and rewrites, any reorganization, any `pending` plan proposed as `abandoned` (only the user flips a status), and any fact that couldn't be verified either way.
45
- - When a user ruling sets a precedent, record it in the same run: project-specific rulings go in the project's `docs/conventions/documentation.md`; a ruling that would apply to every q project is recorded as a project deviation and flagged in the report as a candidate to upstream (via `/q:upstream`).
46
- - In the same batch, ask which review mode — local or ship — the delivery runs under (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Review modes).
47
-
48
- ## Step 4: Apply
49
-
50
- 1. Pick the delivery branch (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The delivery branch).
51
- 2. Step 3's rulings are the agreement — apply the approved edits autonomously. In ship mode, commit them.
52
- 3. Re-run the dead-reference and consistency checks over the result — approved edits can break each other's targets.
53
-
54
- ## Step 5: Adversarial review
55
-
56
- Validate the applied edits (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Validation) with the **correctness** and **conventions** lenses.
57
-
58
- ## Step 6: Open the PR
59
-
60
- 1. **Local review's gate**: run the gate over the uncommitted edits (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The local gate).
61
- 2. **Open the PR**: push the branch and open the PR per the PR-authoring rules (see: q conventions/pull-requests.md).
62
- 3. Close the session by reporting: what changed per doc, what was deduped and into where, every autonomous fix, every user decision and its outcome, any upstream-to-q candidates, and anything that couldn't be verified — named explicitly, never silently dropped.