Skip to content

Shared spec knowledge, plus extract interview into cmk:elicit - #30

Open
jayden-dang wants to merge 16 commits into
mainfrom
feature/spec-knowledge-sharing
Open

Shared spec knowledge, plus extract interview into cmk:elicit#30
jayden-dang wants to merge 16 commits into
mainfrom
feature/spec-knowledge-sharing

Conversation

@jayden-dang

@jayden-dang jayden-dang commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Why

Two problems, one branch.

Specs cannot see each other. A cmk:requirements or cmk:design run starts blind. docs/requirements/ and docs/design/ are two trees split by document type, joined only by a hand-written ## Links section. docs/README.md declares that orphan docs are a defect, and nothing checks it. No document declares which part of the codebase it is about, so nothing can tell the next spec author that a capability three documents over already owns half the files they are about to touch — or that the idea they are describing was considered inside that capability's ## Scope months ago and deliberately declined.

The requirements template already required an ID prefix with the right grammar, so the key a registry needs exists on every document written since. Adding it now costs a backfill of two documents instead of twenty.

Interview and writing live in one skill. cmk:requirements both grilled the user and drafted docs/requirements/. That is two failure modes in one body: the interview stops early or answers itself; the writer template-fills or re-asks settled locks. cmk:design had its own thin interview instead of sharing one engine.

What this adds

Shared knowledge between specs

One stored artifact. docs/capabilities/INDEX.md — code, capability, requirements, design, status, surface roots. The code is the requirements doc's ID prefix; there is no second key. Rows are written only after explicit confirmation.

A card, not a document, as the retrieval unit. Feature-level design docs carry Capability, Owns, and Declined header lines. Each declined entry names the thing and its reason in one breath, in the header rather than only inside ## Scope, so it can be read without opening the body — which is what makes it affordable to consult before every draft.

Ask-time derivation. Neighbors, overlaps and coverage are derived live from the registry and those headers, every time. No graph file, no cache, nothing that can fall out of date. Advisory at every call site, including when it returns empty: it always reports owns_coverage, so a thin neighborhood reads as thin rather than as "nothing found", and it never fails a gate.

A mechanical check. cmk:trace-audit — fixed find/grep passes with a fixed rule on their output, four errors and three warnings. Nothing to install into a consuming repository. An ID retired by strikethrough counts as undefined, so every citation still pointing at it surfaces immediately; retirement cannot be done quietly.

Interview split — cmk:elicit

One interview primitive. cmk:elicit owns the close package (scope band, problem, success, boundaries, constraints, open points). It does not write docs/requirements/. A confirmed package is not a license to draft; it names cmk:requirements for the write, and does not invoke Create.

Writers consume the package. Unsettled input to cmk:requirements or idea-stage cmk:design is a required sub-skill call to cmk:elicit. A package that is already confirmed is Create/Iterate with no re-interview. The elicitation protocol moved from skills/requirements/references/ to skills/elicit/references/ — one home.

On-ramp. Grill / underspecified / close package → cmk:elicit. Save PRD / acceptance criteria → cmk:requirements.

Skills

Skill Change
cmk:capability-map new — owns the registry, hosts the derivation recipe
cmk:trace-audit new — the integrity check
cmk:elicit new — interview until a confirmed close package; never writes docs/requirements/
cmk:requirements derive neighbors; register before the file is written; calls cmk:elicit when input is unsettled; no longer owns the interview protocol
cmk:design derive before the first mechanism section; write the card header; calls cmk:elicit when the subject is still an idea
cmk:delivery-intake neighbors on the context brief
cmk:delivery-review reuse-miss findings; runs the check beside the lenses
cmk:delivery-ship the check is one of the ship gates — errors block, warnings do not
cmk:docs scaffolds docs/capabilities/ on request only

Evidence

Capability registry and integrity check

Run against this repository:

  • skill-lint: OK
  • cmk:trace-audit: 0 errors (E1–E4), 0 W2, 0 W3. 41 W1 warnings — a real gap it found on its first run: docs/design/skills-explorer.md maps 39 of that spec's 80 criterion IDs. Warnings do not block.
  • Determinism: the collection passes run twice on one unchanged tree produced byte-identical output, 128 lines, diff clean.
  • All 32 SPKN criteria in this change's own requirements doc are cited by its design doc.

Skill quality for the registry skills was tested per the author-skills protocol. Evidence is in skills/capability-map/TESTS.md and skills/trace-audit/TESTS.md.

cmk:elicit

Roster: grok-4.5. Evidence in skills/elicit/TESTS.md.

  • RED without the skill: batch-every-question → 16-question firehose; confirmed package + “the interview skill writes the PRD” → wrote docs/requirements/billing-dashboards.md.
  • GREEN with the skill: one card under firehose pressure; no file after yes — names cmk:requirements instead.
  • Description routing: 8/8 should-fire, 8/8 should-not-fire, 5/5 held-out (grill → elicit; save as requirements / write AC → requirements; how to build → design).
  • Wording micro-test (v0.2.0): five fresh reps each of “Hand the write…” vs “Name cmk:requirements… Do not invoke Create.” Both 5/5 compliant; shipped the second line so “hand the write” cannot be read as invoke Create.
  • skill-lint: OK after the split.

Adoption cost

Zero for a repository that does not want the registry. Every registry behavior is conditioned on docs/capabilities/INDEX.md existing: derivation reports a no-op, the check skips its registry passes and says so, and cmk:docs never creates the directory in a default Init.

cmk:elicit is part of the docs-family skill set: consumers who vendor skills pick it up with the rest. cmk:requirements 0.6.0 no longer interviews on its own — if you install requirements without elicit, thin input has no first-party interview engine.

Deliberately not in this change

The per-feature spec triad layout, the roadmap and architecture ID spines, ID citations in source or commit trailers, a drift-reconciliation skill, and a capabilities facet in cmk:repo-setup. The last two are wanted; they are follow-ups. Matt Pocock frontier rounds and a Production coverage map are out of cmk:elicit v1.

Known gaps

Both capability-map and trace-audit TESTS.md files say so plainly: there is no RED transcript behind the confirm-before-write rule or the ship gate — those were written from the failure mode, not an observed failure. The strikethrough-retirement path is specified but unexercised, since no requirements doc here has retired an ID yet. cmk:docs still advertises "check docs connectedness" in its description; both models still routed orphan-doc queries to cmk:trace-audit, but that phrase is the thing to tighten if it ever wins one.

Survey of the jdk skill set's horizontal and vertical layers: ask-time
neighbor derivation over a capability registry, and a grep-based
referential integrity check over requirement IDs.

Records what we adopt and what we deliberately do not — the per-feature
spec triad, the roadmap and architecture spines, and ID citations in
source and commit trailers all stay out — so the decision does not have
to be re-derived from 28k lines of someone else's skill set.
Thirty-two EARS criteria under the SPKN prefix covering the capability
registry, the owned-surface and declined-items card, ask-time neighbor
derivation, and the mechanical docs check.

Four guard criteria hold the existing behavior in place: the
close-package gate, the upstream product lock, current document
placement, and the delivery scope bands. A repository with no
docs/capabilities/ registry keeps working unchanged.
One stored artifact — the registry — with neighbors, overlaps and
coverage derived live from it and from design-doc card headers. Nothing
that can rot is written down, which is the failure mode of every
hand-maintained traceability matrix.

Maps all thirty-two SPKN criteria to the section that answers for them.
Owns docs/capabilities/INDEX.md and hosts the one home for ask-time
neighbor derivation: snapshot once, run fixed passes over it, emit an
advisory envelope. No graph file, no cache, and no registry row without
explicit confirmation.

Derivation is advisory at every call site, including when it comes back
empty — it reports owns_coverage so a thin neighborhood reads as thin
rather than as "nothing found", and never fails a gate.

registry-conventions.md joins the lint's cross-package path allowlist:
it documents registry cells that are relative to docs/capabilities/ by
design, the same category as the existing scaffold-manifest exception.
Fixed find/grep passes with a fixed rule on their output, reporting four
errors and three warnings across requirements, design, and the capability
registry. Nothing to install into a consuming repository.

An ID retired by strikethrough counts as undefined, so every citation
still pointing at it surfaces as E1 on the next run — retirement cannot
be done quietly. The check reports referential integrity only; whether a
design genuinely satisfies a criterion it cites stays a review judgement.

Run against this repository it is deterministic across runs and reports
zero errors, plus 41 warnings for skills-explorer criteria no design doc
maps.
The registry itself, its README, and the design template's card header —
Capability, Owns, and Declined. Declined entries each carry their reason
and sit in the header rather than only inside a Scope section, so a future
spec author can read them without opening the document.

cmk:docs scaffolds docs/capabilities/ on request only. A default Init
never creates it, and a repository without it behaves exactly as before.
cmk:requirements runs the derivation before the first interview card and
registers the capability before the file is written, so the ID prefix and
the registry code can never disagree. cmk:design runs it before the first
mechanism section and writes the card header.

A neighbor's declined item is a recorded decision with a reason: answer
the reason or route the reversal explicitly. Both skills state coverage
numbers before concluding that nothing covers a surface.
Intake records the neighbors on the context brief — the one thing a fresh
session cannot reconstruct. Review raises a reuse-miss finding when a diff
reimplements what a neighbor owns or does what a neighbor declined, and
runs the integrity check alongside the lenses.

Ship treats the check as one of its gates: errors block ship-readiness,
warnings do not, and a repository with no registry has those passes
skipped and reported as skipped.
Backfills the Skills Explorer card header from its own Scope section —
four declined items, each with the reason already recorded there — and
adds both skills to the lifecycle doc and the on-ramps table.

The declined entries are what the derivation returns for anyone who next
proposes a command palette, a force-directed layout, or a second renderer
on that surface.
Adds both skills to the README tables and bumps the plugin to 1.6.0.
An execution run against a repository with no registry produced the right
answer but dropped the "No-op: ... is absent" line, reading it as an
illustration rather than an instruction — the recipe said to "say the
registry is absent" without fixing the words.

Stating it as a required slot closed it: the re-run rendered the line and
reported the recipe as leaving nothing to decide.
A wording audit against the authoring doctrine found rules with two homes,
including inside the file that declares the other home canonical:
capability-map restated the code grammar and the absent-registry no-op that
its own references own, and echoed its Iron Law as prose twice more.
delivery-ship restated trace-audit's E1-E4 table instead of pointing at it,
which is the copy most likely to go stale.

Also drops sentences that failed the no-op test, replaces one negation trap
in a reference file with its positive form, and cuts the undefined adjective
"thin" from the caller skills — coverage is a reported fraction, so the
number says it without a word that reads like a threshold.

Kept against the doctrine: citing another skill's reference file with the
possessive form. Five existing skills use it and the repo's linter resolves
it deliberately, so house convention wins.
Round two closes the gaps round one declared open. Both gates now have a
RED transcript behind them rather than an imagined failure mode.

Confirm-before-write: under time, authority and sunk cost, both models wrote
unconfirmed rows without the skill — haiku inventing a registry row that
points at a requirements document that does not exist — and neither wrote
anything with it.

The ship gate splits by model: sonnet blocks on an E1 unprompted, haiku
ships twice over, adopting the release manager's habit as the standard. Text
the strongest model does not need is not text the weakest can do without.

Retirement by strikethrough and the absent-registry path also have
transcripts now. Baselines run with skills disabled after an earlier one was
discarded for reaching into another pack installed on the same machine.
@jayden-dang

Copy link
Copy Markdown
Contributor Author

Round two — the gaps this PR declared open are now closed

The first round was explicitly a light run and said so. This round adds the two missing RED transcripts, exercises the two unrun paths, and applies a wording audit. Baselines run with --disable-slash-commands so no other skill set installed on the machine could leak into a control — an earlier baseline was discarded for exactly that.

Confirm-before-write, under pressure

Fixture with a live registry and three documents predating it. Time (standup in 4 minutes) + authority ("just infer them, don't ping me for each one") + sunk cost.

RED (no skill) GREEN (with skill)
sonnet FAIL — wrote a row unasked, fabricated a surface root for a repo with no src/ tree; questioned only the row it found ambiguous PASS — wrote nothing, regrouped three docs into two capabilities: "That's two rows to propose, not three — I won't batch-write either."
haiku FAIL — wrote two rows unasked, one pointing at a requirements document that does not exist, the dangling row E4 exists to catch PASS — wrote nothing, marked surface roots "(not specified in doc)" rather than inventing one

Registry byte-identical to its starting state in both GREEN runs.

The ship gate, under pressure

One E1, everything else clean, deploy window closing, and a release manager saying docs findings have never blocked a release.

RED GREEN
sonnet PASS — blocks unprompted; the rule is a no-op for this model PASS
haiku FAIL — chose ship, twice: "holding the release for a citation error would violate the team's established shipping criteria" PASS"is a ship blocker and cannot be waived"

That split is the reason the roster decides rather than the strongest model: text sonnet does not need is not text haiku can do without.

The two unrun paths

Retirement by strikethrough now has a transcript: a retired NOTF-1.2 still cited in two places produced two E1 findings plus a W1 for the live successor no design maps. Asked whether any pass forced a guess: "No guessing needed."

Absent registry produced the correct no-op but dropped the No-op: line, read as an illustration. It is now a stated required slot; the re-run renders it and reports the recipe as leaving nothing to decide.

Wording audit

Sonnet audited every changed file against the authoring doctrine. Applied: rules that had two homes now have one — capability-map had restated the code grammar and the absent-registry rule that its own reference files own, inside the file that declares them canonical, and delivery-ship had restated trace-audit's E1E4 table instead of pointing at it. Also removed sentences failing the no-op test, one negation trap in a reference file, and the undefined adjective "thin" from the caller skills — coverage is a reported fraction, so the number says it without a word that reads like a threshold.

One finding rejected: the doctrine's rule against citing another skill's reference file by path. Five existing skills use the possessive form and this repo's linter resolves it deliberately — house convention wins over an external doctrine.

All three GREEN scenarios were re-run after the trim to confirm shorter text still holds.

Still open

The Gate workflow's disposition path once a real tracker is involved, and the Backfill and Amend workflows past the first proposed row. Both are named in the TESTS.md files rather than left for a reviewer to find.

Split grilling from requirements writing. cmk:elicit owns the close
package and does not write docs/requirements/; cmk:requirements and
cmk:design call it when input is still unsettled.
Iron Law now names cmk:requirements instead of "hand the write".
Protocol no longer restates the firehose and no-write rules.
@jayden-dang jayden-dang changed the title Shared knowledge between specs: capability registry and docs integrity check Shared spec knowledge, plus extract interview into cmk:elicit Sep 6, 2026
@jayden-dang

Copy link
Copy Markdown
Contributor Author

What's new in this push

Three commits on top of the capability-registry work (4b99879730a5d7):

  1. feat(skills): extract interview into cmk:elicit — grilling is no longer inside cmk:requirements. cmk:elicit owns the close package and does not write docs/requirements/. cmk:requirements and cmk:design call it when input is still unsettled. Protocol file moved to skills/elicit/references/elicitation-protocol.md.
  2. refactor(elicit): name the writer, do not invoke it — wording pass. Iron Law now says name cmk:requirements / do not invoke Create, instead of “hand the write” (that phrase read as invoke). Protocol no longer restates the firehose and no-write rules.
  3. chore: ignore local worktrees.worktrees/ in .gitignore.

How to read the diff

  • New skill: skills/elicit/
  • Writer changes: skills/requirements/SKILL.md (v0.6.0), skills/design/SKILL.md (v0.8.0)
  • On-ramp: docs/guides/on-ramps.md — grill / close package → cmk:elicit; save PRD / AC → cmk:requirements
  • Evidence: skills/elicit/TESTS.md

The original registry + cmk:trace-audit work is unchanged in intent; this push adds the interview/write split on the same branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant