@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
@@ -1,150 +0,0 @@
1
- ---
2
- name: install
3
- description: Install q into a project, or add an extension to one. Invoke bare to set q up; name an extension to install it. Idempotent, safe to re-run on a partially set-up project. The changes ship as a PR.
4
- ---
5
-
6
- # Install
7
-
8
- The scaffold is deliberately near-empty — this skill creates the structure the other skills expect, not content.
9
-
10
- Follow the run contract — `${CLAUDE_PLUGIN_ROOT}/references/run-contract.md`. The invocation picks the path: a bare run bootstraps q (Steps 3–4); an extension run adds the extension install (Step 5) after them. A run naming `q` or `@lab43/q` is a bare run, because q is the framework rather than an extension (source: q conventions/extensions.md, Identity). Scaffolding brings q's surfaces to the forms in Step 3: create what is absent, correct what has drifted. Any run therefore completes a partially set-up project. Never rewrite what the user owns — each item below marks its own boundary.
11
-
12
- ## Step 1: Survey current state
13
-
14
- Hold the project against each of Step 3's scaffold items, noting what is absent and what has drifted from its form. Alongside, check:
15
-
16
- - Convention-like docs living elsewhere (a `docs/` scan for rule-carrying files, a briefing bloated with per-task rules) — candidates for migration
17
- - Whether an earlier run's scaffold sits uncommitted in the working tree
18
- - On an extension run: whether the named extension is already pinned, installed, indexed, and watermarked
19
- - The GitHub CLI: `gh auth status`, and that the repo's `origin` is GitHub-hosted (`gh repo view` succeeds). q's workflow skills require both. If either fails, tell the user the fix (install via https://cli.github.com and authenticate with `gh auth login`; `gh repo view` failing with an authenticated CLI means `origin` is not GitHub-hosted) and continue — the scaffold still lands.
20
-
21
- ## Step 2: Settle delivery
22
-
23
- Skip this step in any of these cases:
24
-
25
- - A bare run where Step 1 found nothing missing or drifted beyond an unpopulated `node_modules/`, no migration candidates, and no scaffold sitting uncommitted from an earlier run — there is nothing to change or deliver. Enforce the pins per `${CLAUDE_PLUGIN_ROOT}/references/enforce-pins.md` (machine state, not a repo change), then stop with the closing report (Step 8).
26
- - An extension run where the named extension is already pinned, installed, indexed, and watermarked, Step 1 found nothing missing from the q scaffold, and no install sits uncommitted from an earlier run — report that and stop.
27
- - Step 1's GitHub CLI check failed — there is no delivery to settle.
28
- - Another skill's run invoked this one — the changes join that run's change.
29
-
30
- Otherwise, ask which review mode — local or ship — the run delivers under (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Review modes). Then pick the delivery branch (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The delivery branch); on an extension run the connected-work case is the extension arriving with the dependency that ships it.
31
-
32
- ## Step 3: Scaffold
33
-
34
- The invocation is the agreement — scaffold autonomously; on a fully set-up, undrifted project the whole step is a no-op:
35
-
36
- 1. **The two mirror docs** — create each if missing, with exactly this content; if present, leave it untouched. A seeded doc is the user's from creation, intro and entries alike — never corrected on a re-run. `docs/conventions/principles.md`:
37
-
38
- ```markdown
39
- # Principles
40
-
41
- This project's cross-cutting rules, including any deviations from q's (see: q conventions/principles.md).
42
- ```
43
-
44
- `docs/conventions/documentation.md`:
45
-
46
- ```markdown
47
- # Documentation
48
-
49
- This project's documentation rulings and deviations (see: q conventions/documentation.md, Three tiers of conventions).
50
- ```
51
-
52
- No other conventions doc is scaffolded — `/q:update-docs` creates each topical doc when its first entry is recorded.
53
- 2. **The q dependency** — q installs as one pinned npm package, carrying its conventions and its plugin together:
54
- - Ensure a root `package.json` — create `{"private": true}` if the project has none.
55
- - If `@lab43/q` is not yet in `devDependencies`: `npm install --save-dev --save-exact --ignore-scripts @lab43/q` (via the project's package manager when it isn't npm). If it is, leave the recorded pin alone.
56
-
57
- That pin is the only place a q version appears. Moving it and installing is the whole of an update.
58
- 3. **Agent briefing** — ensure the project's briefing carries the section the briefing template defines, adding what is missing and correcting drift, per that file's rules (see: `${CLAUDE_PLUGIN_ROOT}/references/agent-briefing.md`).
59
- 4. **Plugin declaration** — the project publishes its own marketplace, sourcing the q it already has in `node_modules`. Two files hold it, created if missing.
60
-
61
- `.claude-plugin/marketplace.json` at the project root is the conventional path for a project publishing a marketplace, so the file is shared territory rather than q's. Merge the `q` entry into an existing manifest: leave every other `plugins` entry and the recorded name untouched. Write the whole file only when creating it.
62
-
63
- The marketplace needs a name no other project on the machine will use. The registry the CLI resolves against holds one entry per marketplace name, machine-wide (source: ${CLAUDE_PLUGIN_ROOT}/references/enforce-pins.md). Two projects sharing a name means the second one loads a q version it never pinned.
64
-
65
- Name it `q-pin-<owner>-<repo>-<suffix>` — for example, `q-pin-acme-storefront-4f2ab9`. Owner and repo keep the name legible in that registry. The suffix is six random hex characters. It is what keeps the name unique. Read owner and repo from the repo's GitHub origin with `gh repo view --json nameWithOwner`. Use the project directory's name in their place when that command yields nothing. Lowercase the whole name and replace every character outside `a-z0-9-` with a hyphen.
66
-
67
- Generate that name only when creating the file. A project that already records one keeps it, whatever it is. Other clones have already registered that name locally. Regenerating it strands them. Keeping a name the project chose gives up guaranteed uniqueness, which is the better trade against renaming a marketplace the project owns.
68
-
69
- ```json
70
- {
71
- "name": "<marketplace>",
72
- "owner": { "name": "this project" },
73
- "metadata": { "description": "Pins this project's q version. The name must stay unique to this project. Sharing another project's name makes this one resolve to that project's pinned q." },
74
- "plugins": [
75
- {
76
- "name": "q",
77
- "source": "./node_modules/@lab43/q",
78
- "description": "The q workflow plugin, pinned for this project."
79
- }
80
- ]
81
- }
82
- ```
83
-
84
- Then merge into `.claude/settings.json`, leaving other keys untouched. Key both entries to whatever name the manifest records, and correct either if it has drifted from it:
85
-
86
- ```json
87
- {
88
- "extraKnownMarketplaces": {
89
- "<marketplace>": { "source": { "source": "directory", "path": "./" } }
90
- },
91
- "enabledPlugins": { "q@<marketplace>": true, "q@q": false }
92
- }
93
- ```
94
-
95
- Write the path by hand, relative to the project root — `claude plugin marketplace add` records an absolute path, which breaks every other checkout of the repo.
96
-
97
- `"q@q": false` retires the bootstrap marketplace the package ships. Its name is the same in every copy of q, so leaving it enabled means loading whichever copy registered that name last. Disabling it is what makes the project's own pin authoritative.
98
- 5. **Enforce the declarations** — make this machine match the pins just declared, per `${CLAUDE_PLUGIN_ROOT}/references/enforce-pins.md`.
99
- 6. **State file** — write `.claude/q-state.json` per `${CLAUDE_PLUGIN_ROOT}/references/q-state.md`: a `reconciledAgainst` entry for `@lab43/q`, from the version in `node_modules/@lab43/q/package.json`. Write only absent watermarks — a present entry, stale or not, is reconciliation's to move (source: ${CLAUDE_PLUGIN_ROOT}/references/q-state.md).
100
- 7. **Ignore rules** — ensure `.gitignore` covers `node_modules/`, `.claude/settings.local.json`, and `.claude/worktrees/`, and that the committed scaffold files are not ignored: run `git check-ignore` on `.claude/settings.json`, `.claude-plugin/`, and `.claude/q-state.json`, fixing the rules until it reports nothing. A bare negation under an ignored `.claude/` does nothing — the directory rule itself must become `.claude/*` plus the negations. Leave every unrelated ignore rule alone.
101
- 8. **README setup instructions** — ensure the README tells a collaborator using Claude Code how to bring up a fresh clone: install the project's dependencies, which is what delivers q. Fold that into the project's existing setup instructions or setup script — a dependency install the project already documents (`npm install`, a pnpm or yarn equivalent, a bootstrap script) covers it, and a README already carrying the information needs nothing. Present the q steps as applying to collaborators who use Claude Code, never as requirements for working in the repo. Create a minimal README with just these instructions when the project has none.
102
- 9. Scaffold nothing else. An empty taxonomy directory arrives when its first document does.
103
-
104
- ## Step 4: Migration proposals (existing projects only)
105
-
106
- On an extension run, skip this step unless Step 3 just bootstrapped a previously q-less project. If Step 1 found convention-like content outside `docs/conventions/` — rules in the briefing that apply only to particular kinds of work, rule-carrying docs elsewhere in `docs/` — read `node_modules/@lab43/q/conventions/documentation.md` and propose moving the content per its taxonomy, via AskUserQuestion — a conversational stretch. Apply approved moves, leaving a one-line pointer behind where the policy calls for one.
107
-
108
- ## Step 5: Install the extension (extension runs only)
109
-
110
- The named extension is the agreement — install it autonomously. If it is not yet in `devDependencies` (via the project's package manager when it isn't npm):
111
-
112
- ```
113
- npm install --save-dev --save-exact --ignore-scripts <extension>
114
- ```
115
-
116
- If it is, leave the recorded pin alone and make this machine match through `${CLAUDE_PLUGIN_ROOT}/references/enforce-pins.md`.
117
-
118
- Verify what arrived is an extension: `node_modules/<extension>/package.json` carries the `q-extension` keyword, and the package root holds a `conventions/` directory, a `.claude-plugin/` directory, or both (source: q conventions/extensions.md). If not, `npm uninstall` it and report — never index it. When the run changed nothing else, switch back to the prior branch and delete any branch this run created; when Step 3 bootstrapped the project, keep that scaffold, carry on to Step 6, and report the extension failure in the close.
119
-
120
- An extension shipping `conventions/` gets one briefing index line per doc the index doesn't already carry, under its extensions group and contiguous with any lines it already has: package name plus path from the package root (see: q conventions/documentation.md, Package doc paths), blurb restating the doc's intro (source: q conventions/documentation.md, Taxonomy). One shipping no `conventions/` is watermarked without being indexed, having no docs to index (source: q conventions/extensions.md, Layout).
121
-
122
- When the extension has no `reconciledAgainst` entry, write one from the version in `node_modules/<extension>/package.json` (see: ${CLAUDE_PLUGIN_ROOT}/references/q-state.md) — an extension Step 1 found pinned and installed by hand included. Never overwrite a present entry, stale or not — it is reconciliation's to move (source: ${CLAUDE_PLUGIN_ROOT}/references/q-state.md).
123
-
124
- Installing an extension's plugin is not yet part of this step: q scaffolds only its own marketplace entry.
125
-
126
- ## Step 6: Adversarial review
127
-
128
- Invoked from another skill's run, stop here — the changes are that run's to validate and deliver. When the run changed nothing tracked — every proposal declined on an otherwise complete project — and no earlier run's scaffold awaits delivery: switch back to the prior branch, delete any branch this run created, and report that and stop. When Step 1's GitHub CLI check failed, stop here with the closing report (Step 8), adding:
129
-
130
- - That the changes stay uncommitted — restate the `gh` fix.
131
- - That a re-run delivers them once `gh` is in place.
132
-
133
- Otherwise: in ship mode, commit first. In both modes, validate the changes (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Validation) with the **correctness** and **conventions** lenses.
134
-
135
- ## Step 7: Open the PR
136
-
137
- 1. **Local review's gate**: run the gate over the uncommitted changes (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The local gate).
138
- 2. **Open the PR**: push the branch and open the PR per the PR-authoring rules (see: q conventions/pull-requests.md).
139
-
140
- ## Step 8: Report
141
-
142
- Close the session by reporting:
143
-
144
- - What was created.
145
- - What already existed and was left untouched.
146
- - What was proposed, and the user's decisions.
147
- - On an extension run:
148
- - The extension and version installed, and the index lines added.
149
- - Any overrides markers its docs carry against q's rules. These are deviations the project now lives under. The project's own rulings still win on conflict.
150
- - Its q declaration — its `@lab43/q` devDependency (source: q conventions/extensions.md) — held against the project's own pin. An extension written against a newer q than the project runs is the signal to suggest `/q:update`. One written against an older q, or carrying no declaration, is noted as-is — no update closes it.
@@ -1,45 +0,0 @@
1
- ---
2
- name: sync
3
- description: Set up or repair this machine for a q-using project, handing off to /q:install, /q:update, or /q:uninstall-extension when the project's records don't match its pins. Use on a fresh clone or a new machine, or whenever the session-start check says the project's q setup did not validate. Never moves pins and never reconciles docs; the only tracked file it may touch is a lockfile a dependency install rewrites.
4
- ---
5
-
6
- # Sync
7
-
8
- Follow the run contract — `${CLAUDE_PLUGIN_ROOT}/references/run-contract.md`. The invocation is the agreement — proceed autonomously throughout. Sync delivers no repo change, so there is no branch, review mode, or PR.
9
-
10
- ## Step 1: Enforce the pins
11
-
12
- Two states have nothing to sync yet. Propose `/q:install` and stop for either:
13
-
14
- - The project declares no `@lab43/q` devDependency. It has no pins to enforce.
15
- - It declares one but has no `.claude/q-state.json`. q's bytes arrived. The scaffold that records them has not run. This is the window between the bootstrap install and the first `/q:install`. It is the state the session-start check reports.
16
-
17
- Otherwise enforce the pins per `${CLAUDE_PLUGIN_ROOT}/references/enforce-pins.md`.
18
-
19
- ## Step 2: Check the GitHub CLI
20
-
21
- Run `gh auth status`, and `gh repo view` to confirm the repo's `origin` is GitHub-hosted — q's workflow skills require both. When either fails, report the fix: install via https://cli.github.com and authenticate with `gh auth login` for a missing or unauthenticated CLI; a failing `gh repo view` with an authenticated CLI means `origin` is not GitHub-hosted.
22
-
23
- ## Step 3: Compare pins against watermarks
24
-
25
- Read `.claude/q-state.json` (see: ${CLAUDE_PLUGIN_ROOT}/references/q-state.md) and compare:
26
-
27
- - the pin of `@lab43/q` and of each extension in `package.json` against its `reconciledAgainst` entry, in both directions — the extensions are the direct `devDependencies` whose own `package.json` carries the `q-extension` keyword (source: q conventions/extensions.md)
28
-
29
- Each finding routes to its remedy:
30
-
31
- - A pin differing from its watermark (moved out of band, unreconciled) → `/q:update`, invoked bare once — a bare run covers every such finding.
32
- - An entry for an extension no longer in `package.json` (removed out of band, the removal never reconciled) → `/q:uninstall-extension`, with the extension name, one run per extension.
33
- - No record where one belongs → `/q:install` — bare for a missing state file or a missing `@lab43/q` entry; with the extension name for any other pinned extension that has no entry, one run per extension. These were installed or scaffolded by hand, never recorded.
34
-
35
- Never write the state file — watermarks certify reconciliation, and sync never reconciles (source: ${CLAUDE_PLUGIN_ROOT}/references/q-state.md).
36
-
37
- ## Step 4: Report, then hand off
38
-
39
- Report:
40
-
41
- - What Step 1 enforced, and any tracked file it rewrote (a lockfile) left in the tree as the user's.
42
- - The GitHub CLI result, with the fix when it failed.
43
- - Each finding from Step 3 and the remedy it routes to.
44
-
45
- Then make Step 3's hand-offs — each invocation a full run of its own that asks and delivers for itself. Make the `/q:install` and `/q:uninstall-extension` runs before any `/q:update` run, so update starts from repaired records.
@@ -1,52 +0,0 @@
1
- ---
2
- name: uninstall-extension
3
- description: Remove a q extension from a project, or reconcile a removal already made out of band — a hand-run npm uninstall, a teammate's merge. Invoke with the extension name. Uninstalls the package, removes its briefing index lines, drops its watermark, and surfaces the project docs that reference it for the user's ruling. Refuses @lab43/q. The changes ship as a PR.
4
- ---
5
-
6
- # Uninstall Extension
7
-
8
- Follow the run contract — `${CLAUDE_PLUGIN_ROOT}/references/run-contract.md`. Given no extension, ask which one.
9
-
10
- ## Step 1: Take stock
11
-
12
- Refuse `q` and `@lab43/q`. q is the framework rather than an extension (source: q conventions/extensions.md, Identity), and no q project can remove it (source: q conventions/documentation.md, Three tiers of conventions).
13
-
14
- Confirm the named target is an extension — any of the following identifies it:
15
-
16
- - the `q-extension` keyword in `node_modules/<extension>/package.json` (source: q conventions/extensions.md)
17
- - the same keyword read from the registry (`npm view <extension> keywords`), for one pinned but not installed
18
- - a `reconciledAgainst` entry (see: ${CLAUDE_PLUGIN_ROOT}/references/q-state.md)
19
-
20
- A target none of these identify has nothing here to remove — report that and stop.
21
-
22
- ## Step 2: Settle delivery
23
-
24
- Ask which review mode — local or ship — the run delivers under (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Review modes). Then pick the delivery branch (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The delivery branch).
25
-
26
- ## Step 3: Remove the extension's records
27
-
28
- Remove without asking — each item a no-op when already absent:
29
-
30
- 1. When the extension is pinned: `npm uninstall --ignore-scripts <extension>` (via the project's package manager when it isn't npm).
31
- 2. When the pin is already gone: run the package manager's dependency install, catching up any lockfile and `node_modules` remnants the removal left.
32
- 3. Remove the extension's lines from the agent briefing's docs index. An extension that shipped no `conventions/` has none to remove.
33
- 4. Drop the extension's `reconciledAgainst` entry, per `${CLAUDE_PLUGIN_ROOT}/references/q-state.md`.
34
-
35
- ## Step 4: Rule on references
36
-
37
- Grep the docs the documentation policy owns (see: q conventions/documentation.md, Taxonomy) for the extension's name. Every hit lost its backing with the extension: an overrides marker's target, a restatement's home, a cross-reference's destination. On a clean grep, skip the step.
38
-
39
- Recommend a resolution for each hit, grounded in the documentation policy, in one AskUserQuestion batch — a conversational stretch. The user rules. Apply the rulings.
40
-
41
- ## Step 5: Adversarial review
42
-
43
- In ship mode, commit first. In both modes, validate the changes (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Validation) with the **correctness** and **conventions** lenses.
44
-
45
- ## Step 6: Open the PR
46
-
47
- 1. **Local review's gate**: run the gate over the uncommitted changes (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The local gate).
48
- 2. **Open the PR**: push the branch and open the PR per the PR-authoring rules (see: q conventions/pull-requests.md).
49
- 3. Close the session by reporting:
50
- - The extension removed, or the out-of-band removal reconciled.
51
- - The index lines and watermark entry dropped, and any lockfile catch-up applied.
52
- - Each reference surfaced and the user's ruling on it.
@@ -1,75 +0,0 @@
1
- ---
2
- name: update
3
- description: Update q and the project's installed extensions — move pins to the latest releases with the user's go-ahead, reconcile the project's docs with what each release changed, and catch up any pin that moved out of band. Invoked bare it covers q and every installed extension; a named target — q, or an extension — scopes the run. Use after a release ships, or whenever pins may be behind. To audit docs without updating, use groom-docs; to repair this machine without touching docs, use sync. A pin move or catch-up ships as a PR.
4
- ---
5
-
6
- # Update
7
-
8
- Follow the run contract — `${CLAUDE_PLUGIN_ROOT}/references/run-contract.md`.
9
-
10
- ## Step 1: Take stock
11
-
12
- Bare invocation covers `@lab43/q` and every installed extension — the direct `devDependencies` whose own `package.json` carries the `q-extension` keyword (source: q conventions/extensions.md). A named target scopes the run: `q` means `@lab43/q`; any other name means that extension. Confirm any target you can't identify as an extension before treating it as one. Below, *package* covers both q and an extension.
13
-
14
- Read four versions for each package in scope — the watermarks per `${CLAUDE_PLUGIN_ROOT}/references/q-state.md`:
15
-
16
- | Pinned | Installed | Latest | Watermark |
17
- | --- | --- | --- | --- |
18
- | its pin in the project's `package.json`; in a repo authoring an extension, the q pin lives in that extension's own manifest (source: q conventions/extensions.md) | `version` in `node_modules/<package>/package.json` | `npm view <package> version` | its `reconciledAgainst` entry |
19
-
20
- Alongside the versions, hold each third-party extension's q declaration — its `@lab43/q` devDependency (source: q conventions/extensions.md) — against the project's own q pin, and flag a mismatch either way. A declaration ahead of the pin closes by updating q here; one behind closes only by that extension's release.
21
-
22
- A package with no pin and no watermark entry has nothing to update — propose `/q:install` for it and stop.
23
-
24
- Validate the records before sorting. Check that every pinned package in scope carries its watermark. Check that no watermark outlives its pin: every watermark on a bare run, the target's on a named run. On any failure, propose `/q:sync` and stop.
25
-
26
- Report the versions, then sort each package by its state:
27
-
28
- - **Pinned behind latest** → a pin move to offer. Diff the two published versions: `npm pack <package>@<version>` for each into a scratch directory, extract both, and diff the trees. Diff the whole tarball rather than `conventions/` alone, because a release can change skills, hooks, agents and references too. Step 4's reconciliation and the closing report both read from this diff. Summarize what changed and what reconciliation it demands. Pins are recorded decisions — only the user moves them.
29
- - **Pinned ≠ watermark** → a catch-up: the pin moved out of band. Reconciled in Step 4, without moving any pin.
30
- - **Installed ≠ pinned** → machine drift: enforce without asking, per `${CLAUDE_PLUGIN_ROOT}/references/enforce-pins.md`. When a pin move is on offer, enforce only after the ask below, so enforcement lands on the pins the run keeps; otherwise enforce now.
31
- - **Everything agreeing, nothing newer** → in force and reconciled; report and stop.
32
-
33
- Then ask once, one batch: each offered pin move (take it or stay), and the review mode — local or ship — the delivery runs under (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Review modes). A run with only catch-ups asks the review mode alone. A run finding only machine drift asks nothing — enforce, report, stop. The go-ahead makes the rest of the run autonomous: declined moves drop out, catch-ups stay in. When the answers leave nothing due, report and stop.
34
-
35
- ## Step 2: Branch
36
-
37
- Pick the delivery branch (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The delivery branch).
38
-
39
- ## Step 3: Move the pins
40
-
41
- For each pin the user agreed to move:
42
-
43
- Run `npm install --save-dev --save-exact --ignore-scripts <package>@<latest>`, via the project's package manager when it isn't npm. Moving any pin is the same act, q's included.
44
-
45
- ## Step 4: Reconcile what the diff touched
46
-
47
- Work only from the diffs. Each package's diff runs from its watermark to its pin as Step 3 left it. What the diff touched decides which of these applies. A diff may touch both:
48
-
49
- - **Changed `conventions/`** — hold the project's docs against each changed rule:
50
- - remove an override whose target updated to agree or disappeared — it is spent (source: q conventions/documentation.md, Three tiers of conventions)
51
- - re-check each "(source: …)" restatement against its changed home
52
- - prune a project rule the new text now owns — it is duplication now
53
- - ask about a project rule the new text contradicts, the one call the go-ahead didn't settle: keep it as a recorded deviation (add the overrides marker) or adopt the incoming rule. Adopting can leave code non-conforming — suggest `/q:review` on the affected area; code fixes are out of scope here
54
-
55
- An extension authored in this repo is part of that surface: re-check its docs the same way. The q pin this run moved is also that extension's shipped written-against declaration, and the re-check is what makes the moved declaration true (source: q conventions/extensions.md).
56
-
57
- Then sync the briefing's index lines for the package — a doc added or removed changes the list, a changed intro re-draws its blurb (see: q conventions/documentation.md, Taxonomy).
58
- - **A changed plugin** — re-run `/q:install`, scoped to join this run's change: it is idempotent, creating what the new version's scaffold expects and correcting what has drifted from it.
59
-
60
- After each package's reconciliation, write its watermark per `${CLAUDE_PLUGIN_ROOT}/references/q-state.md`: its `reconciledAgainst` entry to its pinned version.
61
-
62
- The go-ahead in Step 1 covered this reconciliation — apply it without re-asking.
63
-
64
- ## Step 5: Adversarial review
65
-
66
- In ship mode, commit first. In both modes, validate the changes (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, Validation) with the **correctness** and **conventions** lenses.
67
-
68
- ## Step 6: Open the PR
69
-
70
- 1. **Local review's gate**: run the gate over the uncommitted changes (see: ${CLAUDE_PLUGIN_ROOT}/references/run-contract.md, The local gate).
71
- 2. **Open the PR**: push the branch and open the PR per the PR-authoring rules (see: q conventions/pull-requests.md).
72
- 3. Close the session by reporting:
73
- - Old and new pins, and each catch-up applied without a pin move.
74
- - What each release changed.
75
- - Each reconciliation applied and any follow-up suggested — a third-party extension the moved q pin leaves behind included; a newer release of that extension is what closes the gap.
File without changes