[#224] refactor: assess-* output-only; record-decision sole adoption writer#310
Conversation
…writer
- assess-* (10 skills) rewritten output-only: emit {content,target} proposal + report, no writes
- assess-debt: no scan-mode, no auto-created items, never blocks PR (R7.2)
- record-decision: sole adoption writer; accepts generic {content,target} persist path
- bootstrap/review rewired to persist assess-* proposals via record-decision
- write-issue: $labels arg for deliberate tech-debt promotion
- ADR-009 records the pattern; skills-catalog updated; conformance test added
- dataset + installed mirror synced byte-consistent under mirror transform
- Tasks: T1-T7
Refs: #224
Code Review — PR #310Review InformationPR Number: #310 Review SummaryOverall Assessment
Key Changes SummaryMakes all 10 Business Value ValidationDelivers the story thesis: assessing becomes side-effect-free, persistence explicit/gated, debt surfaced without backlog pollution (R7.2). Verified independently against AC + code, not just the PR claims. AC Verification
Quality Gates (re-run independently in worktree)Issues to AddressMajor
Minor
Non-actionable (reported for transparency)
Positive Feedback
Risk AssessmentLow — no product/runtime code. Surface is skill markdown + docs + one ADR + one test. Behavior change limited to skill orchestration semantics. Independent review per |
…coped merge, ADR naming, DDR template Remediate 4 review findings on record-decision (dataset + mirror kept byte-consistent): - F1 (Major): reword "single/only writer of adoption files" -> "sole GENERIC writer"; carve /setup-pm as the one delegated exception (writes PM section of way-of-working.md directly). Applied to overview, Step 4, Composition output + invariant, and adr-009 (Decision, Consequences, invariant, new Trade-offs bullet). - F2 (Minor): clarify Generic Persist is a heading-scoped merge into $target's owned section (not a verbatim whole-file overwrite); applied to overview, $content row, Step 4 act, Composition output. - F3 (Minor): copy ddr-template.md to repo-root templates so the mirror link resolves. - F4 (Minor): document ADR naming as sequential adr-NNN (matches repo reality); split ADR/ADL in File naming, add next-sequence step, scope idempotency note to ADL, fix naming-rationale. adr-009 not renamed (already adr-NNN). Gates: knowledge-hub tests 80/80, check:links OK, markdownlint 0, docs:staleness in sync. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remediation — round 1 (commit
|
Code Review — PR #310 (Re-review, round 2)Review InformationPR Number: #310 Review SummaryOverall Assessment
Scope of this roundRemediation commit Verification of round-1 findings
Byte-consistency (dataset ↔ installed mirror, record-decision)
Conformance test integrityRemediation did not touch Previously-accepted items (carried forward)
Risk AssessmentLow — no product/runtime code. Surface is skill markdown + one ADR + one template. Remediation is documentation-precision only. Positive Feedback
Independent re-review per |
…idelines (PR #311 review) KB guideline files ship to every adopting project via pair install/update; they must never cite this repo's own paths or issue numbers as "evidence" (meaningless/stale for external consumers). - design-rules.md: remove the 3 "Evidence (historical — #199)" paragraphs (DR-1/2/3) and the whole "Migration Plan" section (also now factually stale re: scan-mode removed by #224/#310); Recognition + Don't + Do already fully define each rule without a citation. Overview's rule enumeration updated accordingly. - Add DR-4 "Split Files Without a Barrel" (companion rule to this PR's ops/copy/ and test-utils/in-memory-fs/ folder-module refactors), generic illustrative snippets only, no repo citation. - shared-config-packages.md: genericize the apps/pair-cli, apps/website, packages/brand code-comment examples to placeholder project names (apps/api, apps/web, packages/ui-lib) so the guideline doesn't imply the reader's project has those directories. Repo-wide grep confirms these were the only two guideline files with this pattern.
3 ADRs used YYYY-MM-DD-<topic>.md while 8/11 existing ADRs use the dominant adr-NNN-<topic>.md convention (per record-decision's own documented naming rule, reconfirmed in #224/#310). Renamed in creation order to adr-011/012/013 — numbers 009/010 already claimed by open branches #224/#310 (adr-009) and #313 (adr-010), avoiding a collision on merge. Updated the one cross-reference in collaborative-workflow.context.md. No content changes, no self-references found in the 3 files. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Addresses review finding: the prior commit's rationale wasn't traced to a decision record, and overclaimed record-decision already documents adr-NNN on main (it doesn't yet — that ships with #224/#310). Records the convention decision, the 011-013 numbering choice, its dependency on #224/#310 and #313's adr-009/adr-010, and the deferred H1-title fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Pass esplorativo di riduzione testo su 16/35 skill (le altre 14 erano mutex con #310, ora mergiata). Risultato onesto: -1.5% parole, non il grande guadagno sperato — il corpus era già scritto in stile compresso. Ha portato alla scoperta che il guadagno vero è strutturale (description non trigger-oriented, zero progressive disclosure, duplicazione cross-skill), ora formalizzato come standard in #313 (T2 su PR #319), che riscriverà il corpus più a fondo nei task T3-T6 successivi.
Refactoring:
assess-*skills → output-only;record-decision→ sole adoption writerStory: Closes #224 (Epic #209 — Code Quality & Testing foundations)
Type: Refactor · Priority: P1 · Risk: Low (no product code; skill/docs semantics only)
Motivation
The execution-layer dogfood surfaced an ambiguity: each
assess-*skill both assessed a domain and persisted the outcome (wrote its adoption file + composed/record-decision). Assessing had side effects, there were effectively two adoption writers, andassess-debtrisked polluting the backlog via scan-mode/auto-conversion. This PR cleanly separates assessing (read + recommend, zero side effects) from deciding/persisting (write), with a single writer.The contract (per the issue's "Contract: assess output → record-decision input")
assess-*output = a proposal carrying the rendered adoption content + target (ready-to-write section/file body + which adoption file/section) plus a human-facing report. It performs no write.record-decisioninput ={ content, target, decision-metadata }. Generic persister: writescontenttotarget+ records ADR/ADL. No per-domain rendering — that lives in each assess-* output.assess-* → [accept] → record-decision). Inbootstrap/reviewthe caller is the process skill; standalone it's the human/agent.Invariant: only
record-decisiontouches adoption files; onlyassess-*renders its own adoption content; the caller only orchestrates.Changes Made
assess-*output-only (all 10): debt, code-quality, stack, architecture, testing, ai, pm, infrastructure, observability, methodology. Removed every file/adoption write step and everycompose record-decisionstep; kept the resolution cascade (Argument > Adoption > Assessment) and the report. Step 4 → "Render Adoption Proposal", Step 5 → "Emit Proposal" ({content, target, decision-metadata}). code-quality/debt were already read-only — annotated as output-only.record-decisionsole writer + bootstrap rewire: record-decision documents itself as the sole adoption writer and gains a generic{content, target}persist path (Step 4 "Generic Persist").pair-process-bootstrapStep 2.2 rewired to compose/record-decision(content, target)per accepted proposal.assess-debthas no$mode:scan(and never auto-creates items); explicit "no auto-creation / never blocks (R7.2)". (Remaining "Scan"/"full scan" wording refers to reading the codebase and the cascade path — not a mode.)pair-process-reviewStep 4.2 rewritten — new debt is surfaced in the review output, no auto-issue, PR never blocked on debt grounds.assess-stackPhase 3 rewired to persist viarecord-decisionon approval.tech-debtlabel kept:write-issuegained a$labelsarg + a note that promotion to the backlog is a deliberate, selective act (never a 100% auto-conversion)..pair/adoption/tech/adr/adr-009-assess-output-only.md.skills-catalog.mdxassessment section updated to the output-only contract; conformance test added atpackages/knowledge-hub/src/assess-output-only.test.ts.Every touched skill was synced in dataset source (
packages/knowledge-hub/dataset/.skills/...) and installed mirror (.claude/skills/...) in the same commit, byte-consistent under the mirror transform (name-prefix + strip trailing slash on markdown dir-links).Files Changed (31)
assess-*,record-decision,write-issue,process/bootstrap,process/review..pair/adoption/tech/adr/adr-009-assess-output-only.md,packages/knowledge-hub/src/assess-output-only.test.ts.apps/website/content/docs/reference/skills-catalog.mdx.AC coverage
assess-*produces report/proposal, writes nothing → T1 (all 10).record-decision(generic, no per-domain rendering) → T1 + T2.assess-debthas no$mode:scan, no auto-creation → T3.tech-debtpromotion viawrite-issue→ T5.Reviewer notes (disclosures — you cannot see the checkpoint)
record-decisionmirror DDR forward-port. The installedrecord-decisionmirror was already stale before this PR — it lacked the DDR/domain content merged in DDR type in pair-capability-record-decision + ddr-template #245 (the mirror was never regenerated then). Because assess-* skills are output-only; record-decision is the sole adoption writer (no scan-mode) #224 editsrecord-decision, its mirror was regenerated from the dataset source of truth, which also forward-ports that DDR type in pair-capability-record-decision + ddr-template #245 DDR content. That's why therecord-decisionmirror diff (~115 lines) is larger than the dataset diff (~25 lines). This is a legitimate mirror-sync, not a assess-* skills are output-only; record-decision is the sole adoption writer (no scan-mode) #224 behavior change./implementintentionally untouched (scope). The directive scoped the rewire tobootstrap+review./implementstill composes/assess-stackfor new deps; persistence flows through its existing/record-decisionstep, andassess-stack's Composition Interface documents the output-only contract for that caller. A minor wording tidy in implement Step 2.4 is pre-existing and functionally covered — noted as a possible tiny follow-up, out of assess-* skills are output-only; record-decision is the sole adoption writer (no scan-mode) #224 scope.Design decisions
.pair/adoption/tech/adr/adr-009-assess-output-only.md): the full record — options considered, the contract, and consequences.Testing / Quality Gates
Note for local test runs:
@pair/content-opsmust be built first (turbo run build --filter=@pair/content-ops) or 2 knowledge-hub suites fail to resolve the package entry.Risk Assessment
Low — no product/runtime code changed. Surface is skill markdown + docs + one ADR + one conformance test. Behavior change is limited to skill orchestration semantics (persistence moves from assess-* to the caller via record-decision).
🤖 Generated with Claude Code