Story Statement
As a developer who installed @pair/pair-cli from npm and is following the published docs
I want every documented invocation to name the binary that actually exists (pair-cli)
So that copy-pasting pair-cli kb-validate (or any other example) runs the CLI instead of failing with command not found
Where: apps/pair-cli/src/commands/*/metadata.ts (usage + examples, ten files), apps/website/content/docs/reference/cli/{examples,workflows}.mdx, DEVELOPMENT.md, apps/website/lib/docs-staleness-check.ts (+ its test).
Epic Context
Parent Epic: TBD
Status: Refined
Priority: P2 (Could-Have) — confirmed during refinement
Status Workflow
- Refined: Story is detailed, estimated, and ready for development
- In Progress: Story is actively being developed
- Done: Story delivered and accepted
Classification
risk:yellow · cost: green (not projected — tech/risk-matrix.md Active list is risk only)
Matrix — per dimension
| Dimension |
Tier |
Source |
Note |
| Service/domain criticality |
green |
tech/risk-matrix.md Criticality Table: apps/pair-cli = Low, apps/website = Low |
both touched deployables explicitly Low |
| Change/diff risk |
yellow |
story scope — touches ~15 files across two apps (apps/pair-cli + apps/website) plus a shared gate script |
mechanical rename, but not confined to one module; the default-artifact-downgrade override does not apply because this yellow is a Change/diff-risk yellow, not a Service-criticality/Business-impact one |
| Business impact |
yellow |
subdomain: Adoption & Guidelines (Supporting) — pair-cli's commands (install/update/kb-validate/kb-verify/kb-info/package) are the operational surface of "manages the adoption of practices, tools, and processes" |
no new subdomain needed, existing classification applies |
| Security relevance |
green |
heuristic over touched paths |
pure doc/string rename + a gate regex; no authn/authz, secrets, PII, or untrusted-input parsing |
| Coupling balance |
not assessed |
no cross-context integration introduced — same monorepo, no new external dependency |
excluded from tier max (D21) |
Tier = max(assessed) = yellow, from Change/diff risk (multi-module) and Business impact (Supporting subdomain); the tier-resolution.default-artifact-downgrade override (tech/risk-matrix.md) cannot bring it to green because Change/diff risk — not just Service-criticality/Business-impact — carries the yellow.
Acceptance Criteria
Functional Requirements
-
Given a clean npm install @pair/pair-cli
When the developer runs pair-cli --help or any subcommand's --help
Then every usage and examples line shown names pair-cli, and running it as printed succeeds (no command not found).
-
Given any of the ten apps/pair-cli/src/commands/*/metadata.ts files
When its usage and examples fields are inspected
Then every invocation string starts with pair-cli (per ADL 2026-08-25-cli-invocation-canonical-name-is-pair-cli.md — no pair bin alias is introduced).
-
Given apps/website/content/docs/reference/cli/examples.mdx and workflows.mdx
When every fenced code block and inline-code invocation is inspected
Then each one names pair-cli, including the seven previously-surviving pair kb validate (hyphen-less, non-existent subcommand) occurrences, now corrected to pair-cli kb-validate.
-
Given DEVELOPMENT.md's CLI command reference table and its two prose mentions (lines 132, 135, current numbering) of the pair update mirror-guard mechanism
When the file is inspected
Then every invocation reads pair-cli <command>.
-
Given apps/website/content/docs/customization/organization.mdx
When the file is inspected for actual shell invocations (not prose mentions of "pair" as the product/KB name)
Then none are found — confirmed out of scope for this story (narrowed from the original issue text, which cited a stale organization.mdx:249 occurrence already resolved by an earlier change).
-
Given apps/website/lib/docs-staleness-check.ts's checkDocsCommands
When a docs page contains a bare pair <cmd> invocation (no -cli)
Then checkDocsCommands reports it as an error (new behavior — today it is invisible to the gate because INVOCATION_PREFIX matches only pair-cli ).
-
Given apps/website/lib/docs-staleness-check.ts's existing behavior for pair-cli <cmd> invocations
When the widened INVOCATION_PREFIX change lands
Then the existing checks (unregistered subcommand, npx-prefixed invocation, prose/noun usage ignored, version-string ignored) continue to pass exactly as before — regression-free (see docs-staleness-check.test.ts:209-242 for the existing coverage this must not break).
Business Rules
- The CLI invocation name is
pair-cli everywhere a command is documented or printed — no dual naming, no alias (ADL 2026-08-25).
apps/pair-cli/package.json's bin field is unchanged: {"pair-cli": "dist/cli.js"}.
- Zero occurrences of
pair kb validate (with a space, hyphen-less) anywhere in the repo after this story.
- Zero occurrences of a bare
pair <command> invocation (missing -cli) in any file listed under Story Statement → Where, after this story.
Edge Cases and Error Handling
- Prose mentions of "pair" as the product/KB name (e.g. "the pair KB", "your project's pair assets", CI step names like
- name: Install pair assets): left untouched — only actual shell invocations are renamed. docs-staleness-check.ts already has coverage for "ignores pair-cli used as a noun in prose" (test at line 232-234); the widened prefix must not start flagging prose that merely contains the word "pair".
npx-prefixed invocations (npx --no @pair/pair-cli update, etc.): already handled by the existing INVOCATION_PREFIX npx clause — verify the widened regex still recognizes these as valid pair-cli invocations, not as the new bare-pair error case.
- Version-string /
--version output (pair-cli vX.Y.Z, pair-cli --version): already ignored by existing tests — must stay ignored.
Definition of Done Checklist
Development Completion
Quality Assurance
Deployment and Release
Story Sizing and Sprint Readiness
Refined Story Points
Final Story Points: 2 (S) — confirmed at original rough sizing
Confidence Level: High (raised from Medium — the naming decision that was the story's main uncertainty is now resolved by ADL 2026-08-25, and the full file/occurrence list is enumerated by grep evidence above, not estimated)
Sizing Justification: Purely mechanical string rename across ~15 files (10 metadata.ts, 2 mdx, 1 md) plus one regex widening + matching test additions in docs-staleness-check.ts. No new logic, no new integration, no schema change.
Sprint Capacity Validation
Sprint Fit Assessment: Fits in a single sprint easily; likely a single session.
Development Time Estimate: 0.5 day
Testing Time Estimate: 0.5 day (mostly the new staleness-check test cases + manual verification that pnpm docs:staleness is green)
Total Effort Assessment: Fits within sprint capacity: Yes
Story Splitting Recommendations
Not needed — story is already S-sized and cohesive (one root cause, one decision, one mechanical sweep).
Dependencies and Coordination
Story Dependencies
Prerequisite Stories: None.
Dependent Stories: None known. Independent of #188 / PR #445 (deliberately left untouched by that PR; this story is the follow-up).
Shared Components: apps/website/lib/docs-staleness-check.ts is also touched by any future CLI-docs story — no other in-flight story is known to touch it concurrently.
Team Coordination
Development Roles Involved:
- CLI: rename
usage/examples strings in the ten metadata.ts files.
- Docs: rename invocations in
examples.mdx, workflows.mdx, DEVELOPMENT.md.
- Tooling/CI: widen
INVOCATION_PREFIX in docs-staleness-check.ts and extend its test.
- QA: verify
pnpm docs:staleness is green and manually spot-check a few --help outputs.
External Dependencies
Third-party Integrations: None.
Infrastructure Requirements: None.
Compliance Requirements: None.
Validation and Testing Strategy
Acceptance Testing Approach
Testing Methods: Unit tests in docs-staleness-check.test.ts for the widened regex (new bare-pair failure case + regression of existing npx/prose/version cases); pnpm docs:staleness run as the end-to-end check that the corrected docs pass the gate; manual pair-cli --help / per-command --help spot check.
Test Data Requirements: None beyond the existing fixture-style doc strings already in the test file.
Environment Requirements: Local dev environment; no external service.
User Validation
User Feedback Collection: Not applicable — internal DX/docs-correctness fix, no user-facing feature to validate with end users beyond "the copy-pasted command runs."
Success Metrics: Zero pair kb validate and zero bare pair <cmd> occurrences in the repo; pnpm docs:staleness green.
Rollback Plan: Revert the commit; no data or state to roll back.
Notes and Additional Context
Refinement Session Insights: The story's central open question ("is pair the eventual public name, or is pair-cli canonical and the docs wrong?") is resolved by evidence already in the repo — .pair/adoption/tech/infrastructure.md already commits to bin/pair-cli as the release contract, and the staleness gate's own regex already targets pair-cli. Recorded as ADL 2026-08-25-cli-invocation-canonical-name-is-pair-cli.md.
Team Concerns: None raised.
Future Considerations: If a shorter public alias (pair) is ever wanted, it requires reopening this ADL explicitly — not a silent docs drift back to pair.
Documentation Links: ADL 2026-08-25-cli-invocation-canonical-name-is-pair-cli.md; ADL 2026-08-12-manual-cli-artifact-types-are-optional.md (the release-artifact contract this decision cross-references).
Technical Analysis
Implementation Approach
Technical Strategy: Mechanical, decision-driven rename — no new abstractions. Apply the ADL's chosen branch (pair-cli canonical) uniformly: (1) rename every usage/examples string in the ten metadata.ts files; (2) rename every invocation in examples.mdx, workflows.mdx, DEVELOPMENT.md (leaving prose mentions of "pair" untouched); (3) widen docs-staleness-check.ts's INVOCATION_PREFIX/checkDocsCommands to also flag a bare pair <cmd> as an error, and extend docs-staleness-check.test.ts with a case asserting that; (4) run pnpm docs:staleness to confirm the corrected docs pass and no bare-pair regression remains anywhere in scope.
Key Components:
apps/pair-cli/src/commands/{install,kb-cache,kb-info,kb-validate,kb-verify,package,scaffold-kb,update-link,update,validate-config}/metadata.ts
apps/website/content/docs/reference/cli/examples.mdx, workflows.mdx
DEVELOPMENT.md
apps/website/lib/docs-staleness-check.ts (INVOCATION_PREFIX, SPAN_INVOCATION, LINE_INVOCATION, checkDocsCommands) + docs-staleness-check.test.ts
Risks: Low-complexity mechanical change; the only real risk is an incomplete sweep (missing an occurrence) or an over-broad regex widening that starts flagging legitimate prose ("pair" as a noun) as an error — mitigated by AC6/AC7's explicit regression coverage and by running pnpm docs:staleness as the final check rather than trusting a partial manual grep.
Design: not required
Design flag
Design: not required
Technical Risks and Mitigation
| Risk |
Impact |
Mitigation |
Incomplete rename sweep leaves a stray bare pair <cmd> in scope |
Low — a missed doc example still fails for the npm-install reader |
Run pnpm docs:staleness after the widened regex lands; it now catches this class by construction (AC6) |
Widened INVOCATION_PREFIX over-matches prose containing "pair" |
Low — false-positive gate failures on unrelated docs edits |
Explicit regression test cases for prose/npx/version forms (AC7), reusing the existing test file's own coverage as the baseline |
Coupling: not assessed — no cross-context/service integration is introduced by this story (single monorepo, no new external dependency); excluded from the classification tier max per D21.
Task Breakdown
Dependency Graph
T-1 ──┬── T-2 ──┐
├── T-3 ──┼── T-5
└── T-4 ──┘
AC Coverage
| AC |
Tasks |
AC-1 (--help output names pair-cli) |
T-2, T-5 |
AC-2 (metadata usage/examples say pair-cli) |
T-2 |
AC-3 (docs mdx invocations + kb validate fix) |
T-3 |
AC-4 (DEVELOPMENT.md invocations) |
T-4 |
AC-5 (organization.mdx confirmed out of scope) |
T-3 |
AC-6 (gate flags bare pair <cmd>) |
T-1 |
| AC-7 (gate stays regression-free on existing cases) |
T-1, T-5 |
T-1: Widen the docs-staleness gate to flag a bare pair <cmd> invocation
Priority: P0 | Estimated Hours: 2h | Bounded Context: Adoption & Guidelines (CLI docs tooling)
Summary: Extend docs-staleness-check.ts so a documented invocation missing the -cli suffix (pair install, pair kb-validate, …) is reported as an error, not silently ignored. Written before the rename tasks (test-first, per the repo's bug-resolution workflow) so the new test first proves the defect against the current (unrenamed) docs, then stays green once T-2/T-3/T-4 fix them.
Type: Bug Fix
Description: INVOCATION_PREFIX in apps/website/lib/docs-staleness-check.ts:447 currently matches only (?:npx ...)?pair-cli\s+, so checkDocsCommands never sees a bare pair <cmd> line — this is the structural reason the class of defect in AC-6/AC-7 survived undetected. Add a second, narrower check (or a second regex) that recognizes a code-block/inline invocation starting with pair immediately followed by a known-shaped command token (not preceded by a hyphen, not part of a longer word like pair-cli), and reports it as an error distinct from — and in addition to — the existing "unregistered subcommand" check. Must not start flagging prose ("the pair KB", "pair assets") or pair-cli-prefixed lines.
Acceptance Criteria:
- Primary deliverable:
checkDocsCommands returns a non-empty error array for a fixture containing pair install (bare, no -cli).
- Quality standard: new test cases added to
docs-staleness-check.test.ts, colocated with the existing describe('checkDocsCommands', ...) block.
- Integration requirement: existing test cases (lines ~209-242:
pair-cli init, pair-cli kb validate unregistered-subcommand case, pair-cli install valid case, npx-prefixed, prose noun usage, version string, --version) all still pass unmodified.
- Verification method:
pnpm --filter website test -- docs-staleness-check green; running the check against the current (pre-rename) examples.mdx/workflows.mdx/DEVELOPMENT.md reports the bare-pair occurrences (confirms the new check actually fires before T-2–T-4 remove the fixtures it would fire on).
Technical Requirements:
- Functionality: bare
pair <cmd> detected in both fenced code blocks and inline-code spans (mirroring SPAN_INVOCATION/LINE_INVOCATION's existing dual coverage).
- Performance: negligible — same regex-scan pass, no new file I/O.
- Security: not applicable.
Implementation Approach:
- Technical Design: add a sibling regex/branch next to
SPAN_INVOCATION/LINE_INVOCATION that matches a pair prefix (space, not hyphen) followed by a word-start token, excluding matches already captured by the pair-cli prefix; wire it into checkDocsCommands as a new error kind (e.g. wrong-binary-name).
- Bounded Context & Modules:
apps/website/lib/docs-staleness-check.ts (gate logic), apps/website/lib/docs-staleness-check.test.ts (coverage).
- Files to Modify/Create:
apps/website/lib/docs-staleness-check.ts — widen INVOCATION_PREFIX/add bare-pair detection in checkDocsCommands.
apps/website/lib/docs-staleness-check.test.ts — add the new failing-then-passing test case(s) plus explicit regression assertions for the existing npx/prose/version cases.
- Technical Standards References: repo
AGENTS.md Bug Resolution Workflow (test-first).
Dependencies:
- Technical: none.
- Tasks: none — this is the first task, deliberately ahead of the renames.
Implementation Steps:
- Write the new test case(s) in
docs-staleness-check.test.ts asserting a bare pair install/pair kb-validate line is flagged; run and confirm it fails against the current implementation.
- Widen
INVOCATION_PREFIX/checkDocsCommands in docs-staleness-check.ts to detect and report the bare-pair case.
- Re-run the new test — confirm it now passes.
- Re-run the full existing
docs-staleness-check.test.ts suite — confirm zero regressions (prose, npx, version-string, valid pair-cli cases all still behave as before).
- Run
pnpm docs:staleness against the current (still unrenamed) docs and confirm it now reports the bare-pair occurrences that T-2–T-4 will fix.
Testing Strategy:
- Unit Tests: new cases in
docs-staleness-check.test.ts for bare-pair detection; existing suite re-run for regression.
- Integration Tests:
pnpm docs:staleness run against real repo docs (pre- and post-rename).
- Manual Testing: none beyond the above.
Notes: This task is the "create a failing test that reproduces the bug" step of the repo's mandated bug workflow — the "bug" being the gate's blindness to the wrong binary name, reproduced by asserting it fires on the current (not-yet-renamed) docs.
T-2: Rename pair → pair-cli in the ten CLI command metadata.ts files
Priority: P1 | Estimated Hours: 1h | Bounded Context: Adoption & Guidelines (pair-cli)
Summary: Rename every usage/examples string across all ten command metadata files from pair <cmd> to pair-cli <cmd> — mechanical, no behavior change.
Type: Bug Fix
Description: Per ADL 2026-08-25-cli-invocation-canonical-name-is-pair-cli.md, pair-cli is the sole canonical invocation. apps/pair-cli/package.json's bin field already declares pair-cli — only the strings shown by --help are wrong. Rename in place, one string replace per line, no logic change.
Acceptance Criteria:
- Primary deliverable: all ten
metadata.ts files' usage and every examples array entry start with pair-cli .
- Quality standard: no other content in these files changes (option flags, descriptions, command names untouched).
- Integration requirement:
pair-cli <command> --help output reflects the renamed strings (metadata is read directly by the help renderer).
- Verification method:
grep -rn "'pair " apps/pair-cli/src/commands/*/metadata.ts returns zero matches after the change (only 'pair-cli remains).
Technical Requirements:
- Functionality: pure string content change, no signature/type change.
- Performance: not applicable.
- Security: not applicable.
Implementation Approach:
- Technical Design: find-and-replace
'pair → 'pair-cli (and equivalent double-quote/template-literal forms if present) scoped to usage:/examples: fields only.
- Bounded Context & Modules:
apps/pair-cli/src/commands/*/metadata.ts.
- Files to Modify/Create:
apps/pair-cli/src/commands/install/metadata.ts
apps/pair-cli/src/commands/kb-cache/metadata.ts
apps/pair-cli/src/commands/kb-info/metadata.ts
apps/pair-cli/src/commands/kb-validate/metadata.ts
apps/pair-cli/src/commands/kb-verify/metadata.ts
apps/pair-cli/src/commands/package/metadata.ts
apps/pair-cli/src/commands/scaffold-kb/metadata.ts
apps/pair-cli/src/commands/update-link/metadata.ts
apps/pair-cli/src/commands/update/metadata.ts
apps/pair-cli/src/commands/validate-config/metadata.ts
- Technical Standards References: ADL
2026-08-25-cli-invocation-canonical-name-is-pair-cli.md.
Dependencies:
- Technical: none.
- Tasks: T-1 (gate widened and proven to catch this class first).
Implementation Steps:
- Sweep each of the ten
metadata.ts files, renaming every pair occurrence in usage/examples to pair-cli .
- Re-run any existing metadata/help snapshot tests, if present, and update fixtures.
- Manually spot-check
pair-cli <command> --help for 2-3 commands.
- Run
pnpm --filter @pair/pair-cli test.
Testing Strategy:
- Unit Tests: existing metadata/CLI tests must still pass; update any snapshot expecting the old
pair string.
- Integration Tests: none new.
- Manual Testing:
pair-cli install --help, pair-cli kb-validate --help spot check.
Notes: No new tests required — this is a pure content fix covered by T-5's end-to-end gate check.
T-3: Rename pair → pair-cli in examples.mdx and workflows.mdx (incl. kb validate → kb-validate)
Priority: P1 | Estimated Hours: 1.5h | Bounded Context: Adoption & Guidelines (docs site)
Summary: Rename every documented invocation in the two CLI reference/workflow docs pages, fixing both the missing -cli suffix and the seven surviving hyphen-less kb validate occurrences. Confirm organization.mdx needs no change.
Type: Documentation
Description: apps/website/content/docs/reference/cli/examples.mdx and workflows.mdx contain dozens of pair <cmd> invocations (both fenced code blocks and inline code); examples.mdx additionally has non-existent pair kb validate (hyphen-less) occurrences that must become pair-cli kb-validate. apps/website/content/docs/customization/organization.mdx was checked during refinement and contains no actual invocation lines (only prose mentions of "pair" as the product name) — no change needed there; this task's completion should re-confirm that (docs may have drifted since refinement).
Acceptance Criteria:
- Primary deliverable: every invocation in
examples.mdx and workflows.mdx reads pair-cli <cmd>; zero remaining pair kb validate (space) anywhere.
- Quality standard: prose mentions of "pair" as a noun (e.g. "Keep your project's pair assets up to date") are left untouched.
- Integration requirement: code examples remain copy-paste runnable against a real
pair-cli install.
- Verification method:
grep -rn '\pair ' apps/website/content/docs/reference/cli/examples.mdx apps/website/content/docs/reference/cli/workflows.mdxreturns zero matches for an actual invocation line;grep -rn "pair kb validate" .` returns zero matches repo-wide.
Technical Requirements:
- Functionality: content-only change to
.mdx files.
- Performance: not applicable.
- Security: not applicable.
- Compatibility: not applicable.
Implementation Approach:
- Technical Design: line-by-line rename inside fenced ```bash blocks and inline
`pair ...` spans; hyphen-less `kb validate` → `kb-validate` in the same pass.
- Bounded Context & Modules:
apps/website/content/docs/reference/cli/.
- Files to Modify/Create:
apps/website/content/docs/reference/cli/examples.mdx
apps/website/content/docs/reference/cli/workflows.mdx
- Technical Standards References: ADL
2026-08-25-cli-invocation-canonical-name-is-pair-cli.md.
Dependencies:
- Technical: none.
- Tasks: T-1 (gate widened first).
Implementation Steps:
- Sweep
examples.mdx — rename all invocation lines, fix kb validate → kb-validate.
- Sweep
workflows.mdx — rename all invocation lines (leave prose/CI-step-name mentions of "pair" untouched).
- Re-check
organization.mdx for any invocation lines introduced since refinement; fix if present, otherwise leave as-is.
- Run
pnpm docs:staleness scoped to these files (or full repo) to confirm no remaining bad invocations.
Testing Strategy:
- Unit Tests: not applicable (docs content).
- Integration Tests:
pnpm docs:staleness.
- Manual Testing: skim rendered docs pages for readability after the rename.
Notes: This is the largest occurrence count in the story — do the sweep methodically (grep before/after) rather than trusting memory of the line numbers cited in the original issue text, since they may have shifted.
T-4: Rename pair → pair-cli in DEVELOPMENT.md
Priority: P1 | Estimated Hours: 0.5h | Bounded Context: Adoption & Guidelines (contributor docs)
Summary: Rename the CLI command reference table and the two mirror-guard prose mentions from pair to pair-cli.
Type: Documentation
Description: DEVELOPMENT.md's command table (current lines ~154-160) and two prose references to the pair update mirror-guard mechanism (current lines ~132, ~135) name the CLI as pair; rename all to pair-cli.
Acceptance Criteria:
- Primary deliverable: every
pair <cmd> occurrence in DEVELOPMENT.md becomes pair-cli <cmd>.
- Quality standard: surrounding table formatting and prose grammar preserved.
- Integration requirement: none beyond textual accuracy.
- Verification method:
grep -n "pair " DEVELOPMENT.md shows only pair-cli occurrences (or unrelated prose) afterward.
Technical Requirements:
- Functionality: content-only.
- Performance: not applicable.
- Security: not applicable.
Implementation Approach:
- Technical Design: direct string replace in the command table and the two prose lines.
- Bounded Context & Modules: root
DEVELOPMENT.md.
- Files to Modify/Create:
- Technical Standards References: ADL
2026-08-25-cli-invocation-canonical-name-is-pair-cli.md.
Dependencies:
- Technical: none.
- Tasks: T-1 (gate widened first).
Implementation Steps:
- Rename the command-reference table rows.
- Rename the two mirror-guard prose mentions.
- Re-read the surrounding paragraph for grammatical consistency after the rename.
Testing Strategy:
- Unit Tests: not applicable.
- Integration Tests:
pnpm docs:staleness (if it covers root-level .md files; otherwise manual grep).
- Manual Testing: visual read-through.
Notes: Smallest task in the story; safe to do alongside T-3.
T-5: End-to-end validation — pnpm docs:staleness green, zero bad-invocation occurrences repo-wide
Priority: P0 | Estimated Hours: 1h | Bounded Context: Adoption & Guidelines (CLI docs tooling)
Summary: Final gate: confirm the widened staleness check (T-1) passes clean against the renamed docs/metadata (T-2, T-3, T-4), and that no bare pair <cmd> or pair kb validate occurrence remains anywhere in scope.
Type: Testing
Description: This task is the story's Definition-of-Done proof: pnpm docs:staleness must run green, and a full repo-wide grep for the two forbidden patterns must return zero results. It also re-confirms T-1's regression coverage (npx-prefixed, prose "pair" mentions, version strings) still passes now that the real docs have changed underneath it.
Acceptance Criteria:
- Primary deliverable:
pnpm docs:staleness exits 0.
- Quality standard: zero occurrences of
pair kb validate (space) and zero bare pair <cmd> invocations repo-wide.
- Integration requirement:
pair-cli --help and every subcommand --help name a resolvable invocation on a clean npm install (manual spot check).
- Verification method: CI run of
pnpm docs:staleness + docs-staleness-check.test.ts full suite, both green.
Technical Requirements:
- Functionality: no new functionality — verification only.
- Performance: not applicable.
- Security: not applicable.
Implementation Approach:
- Technical Design: run the gate and the grep checks; fix any straggler found (loop back to the relevant T-2/T-3/T-4 file).
- Bounded Context & Modules: whole-repo verification pass.
- Files to Modify/Create: none expected; only if a straggler occurrence turns up.
- Technical Standards References: story Definition of Done.
Dependencies:
- Technical: none.
- Tasks: T-1, T-2, T-3, T-4 (all renames and the widened gate must land first).
Implementation Steps:
- Run
pnpm docs:staleness — must exit 0.
- Run
docs-staleness-check.test.ts full suite — must be green.
grep -rn "pair kb validate" . and a bare-pair-invocation grep across the Where-listed files — both zero.
- Spot-check
pair-cli --help and 2-3 subcommand --help outputs manually.
Testing Strategy:
- Unit Tests: n/a (verification task).
- Integration Tests:
pnpm docs:staleness (the real end-to-end gate).
- Manual Testing:
--help spot check.
Notes: If this task finds a straggler, fix it in place and re-run rather than filing a follow-up — the story's Definition of Done requires zero occurrences, not "reduced."
Story Statement
As a developer who installed
@pair/pair-clifrom npm and is following the published docsI want every documented invocation to name the binary that actually exists (
pair-cli)So that copy-pasting
pair-cli kb-validate(or any other example) runs the CLI instead of failing withcommand not foundWhere:
apps/pair-cli/src/commands/*/metadata.ts(usage+examples, ten files),apps/website/content/docs/reference/cli/{examples,workflows}.mdx,DEVELOPMENT.md,apps/website/lib/docs-staleness-check.ts(+ its test).Epic Context
Parent Epic: TBD
Status: Refined
Priority: P2 (Could-Have) — confirmed during refinement
Status Workflow
Classification
risk:yellow· cost: green (not projected —tech/risk-matrix.mdActive list isriskonly)Matrix — per dimension
tech/risk-matrix.mdCriticality Table:apps/pair-cli= Low,apps/website= Lowapps/pair-cli+apps/website) plus a shared gate scriptdefault-artifact-downgradeoverride does not apply because this yellow is a Change/diff-risk yellow, not a Service-criticality/Business-impact onepair-cli's commands (install/update/kb-validate/kb-verify/kb-info/package) are the operational surface of "manages the adoption of practices, tools, and processes"Tier = max(assessed) = yellow, from Change/diff risk (multi-module) and Business impact (Supporting subdomain); the
tier-resolution.default-artifact-downgradeoverride (tech/risk-matrix.md) cannot bring it to green because Change/diff risk — not just Service-criticality/Business-impact — carries the yellow.Acceptance Criteria
Functional Requirements
Given a clean
npm install @pair/pair-cliWhen the developer runs
pair-cli --helpor any subcommand's--helpThen every
usageandexamplesline shown namespair-cli, and running it as printed succeeds (nocommand not found).Given any of the ten
apps/pair-cli/src/commands/*/metadata.tsfilesWhen its
usageandexamplesfields are inspectedThen every invocation string starts with
pair-cli(per ADL 2026-08-25-cli-invocation-canonical-name-is-pair-cli.md — nopairbin alias is introduced).Given
apps/website/content/docs/reference/cli/examples.mdxandworkflows.mdxWhen every fenced code block and inline-code invocation is inspected
Then each one names
pair-cli, including the seven previously-survivingpair kb validate(hyphen-less, non-existent subcommand) occurrences, now corrected topair-cli kb-validate.Given
DEVELOPMENT.md's CLI command reference table and its two prose mentions (lines 132, 135, current numbering) of thepair updatemirror-guard mechanismWhen the file is inspected
Then every invocation reads
pair-cli <command>.Given
apps/website/content/docs/customization/organization.mdxWhen the file is inspected for actual shell invocations (not prose mentions of "pair" as the product/KB name)
Then none are found — confirmed out of scope for this story (narrowed from the original issue text, which cited a stale
organization.mdx:249occurrence already resolved by an earlier change).Given
apps/website/lib/docs-staleness-check.ts'scheckDocsCommandsWhen a docs page contains a bare
pair <cmd>invocation (no-cli)Then
checkDocsCommandsreports it as an error (new behavior — today it is invisible to the gate becauseINVOCATION_PREFIXmatches onlypair-cli).Given
apps/website/lib/docs-staleness-check.ts's existing behavior forpair-cli <cmd>invocationsWhen the widened
INVOCATION_PREFIXchange landsThen the existing checks (unregistered subcommand, npx-prefixed invocation, prose/noun usage ignored, version-string ignored) continue to pass exactly as before — regression-free (see
docs-staleness-check.test.ts:209-242for the existing coverage this must not break).Business Rules
pair-clieverywhere a command is documented or printed — no dual naming, no alias (ADL 2026-08-25).apps/pair-cli/package.json'sbinfield is unchanged:{"pair-cli": "dist/cli.js"}.pair kb validate(with a space, hyphen-less) anywhere in the repo after this story.pair <command>invocation (missing-cli) in any file listed under Story Statement → Where, after this story.Edge Cases and Error Handling
- name: Install pair assets): left untouched — only actual shell invocations are renamed.docs-staleness-check.tsalready has coverage for "ignorespair-cliused as a noun in prose" (test at line 232-234); the widened prefix must not start flagging prose that merely contains the word "pair".npx-prefixed invocations (npx --no @pair/pair-cli update, etc.): already handled by the existingINVOCATION_PREFIXnpx clause — verify the widened regex still recognizes these as validpair-cliinvocations, not as the new bare-pairerror case.--versionoutput (pair-cli vX.Y.Z,pair-cli --version): already ignored by existing tests — must stay ignored.Definition of Done Checklist
Development Completion
docs-staleness-check.test.tsfor the new bare-pair <cmd>error case (AC6), and for the npx/prose/version regression checks (AC7) — no coverage percentage target beyond the existing suite's own standard, this is a pure string/regex changeQuality Assurance
pnpm docs:stalenessrun locally and passes clean (zero bare-pairand zeropair kb validatefindings)docs-staleness-check.test.tssuite (lines 209-242 and surrounding) still passes unmodified in intentDeployment and Release
Story Sizing and Sprint Readiness
Refined Story Points
Final Story Points: 2 (S) — confirmed at original rough sizing
Confidence Level: High (raised from Medium — the naming decision that was the story's main uncertainty is now resolved by ADL 2026-08-25, and the full file/occurrence list is enumerated by grep evidence above, not estimated)
Sizing Justification: Purely mechanical string rename across ~15 files (10 metadata.ts, 2 mdx, 1 md) plus one regex widening + matching test additions in
docs-staleness-check.ts. No new logic, no new integration, no schema change.Sprint Capacity Validation
Sprint Fit Assessment: Fits in a single sprint easily; likely a single session.
Development Time Estimate: 0.5 day
Testing Time Estimate: 0.5 day (mostly the new staleness-check test cases + manual verification that
pnpm docs:stalenessis green)Total Effort Assessment: Fits within sprint capacity: Yes
Story Splitting Recommendations
Not needed — story is already S-sized and cohesive (one root cause, one decision, one mechanical sweep).
Dependencies and Coordination
Story Dependencies
Prerequisite Stories: None.
Dependent Stories: None known. Independent of #188 / PR #445 (deliberately left untouched by that PR; this story is the follow-up).
Shared Components:
apps/website/lib/docs-staleness-check.tsis also touched by any future CLI-docs story — no other in-flight story is known to touch it concurrently.Team Coordination
Development Roles Involved:
usage/examplesstrings in the tenmetadata.tsfiles.examples.mdx,workflows.mdx,DEVELOPMENT.md.INVOCATION_PREFIXindocs-staleness-check.tsand extend its test.pnpm docs:stalenessis green and manually spot-check a few--helpoutputs.External Dependencies
Third-party Integrations: None.
Infrastructure Requirements: None.
Compliance Requirements: None.
Validation and Testing Strategy
Acceptance Testing Approach
Testing Methods: Unit tests in
docs-staleness-check.test.tsfor the widened regex (new bare-pairfailure case + regression of existing npx/prose/version cases);pnpm docs:stalenessrun as the end-to-end check that the corrected docs pass the gate; manualpair-cli --help/ per-command--helpspot check.Test Data Requirements: None beyond the existing fixture-style doc strings already in the test file.
Environment Requirements: Local dev environment; no external service.
User Validation
User Feedback Collection: Not applicable — internal DX/docs-correctness fix, no user-facing feature to validate with end users beyond "the copy-pasted command runs."
Success Metrics: Zero
pair kb validateand zero barepair <cmd>occurrences in the repo;pnpm docs:stalenessgreen.Rollback Plan: Revert the commit; no data or state to roll back.
Notes and Additional Context
Refinement Session Insights: The story's central open question ("is
pairthe eventual public name, or ispair-clicanonical and the docs wrong?") is resolved by evidence already in the repo —.pair/adoption/tech/infrastructure.mdalready commits tobin/pair-clias the release contract, and the staleness gate's own regex already targetspair-cli. Recorded as ADL 2026-08-25-cli-invocation-canonical-name-is-pair-cli.md.Team Concerns: None raised.
Future Considerations: If a shorter public alias (
pair) is ever wanted, it requires reopening this ADL explicitly — not a silent docs drift back topair.Documentation Links: ADL 2026-08-25-cli-invocation-canonical-name-is-pair-cli.md; ADL 2026-08-12-manual-cli-artifact-types-are-optional.md (the release-artifact contract this decision cross-references).
Technical Analysis
Implementation Approach
Technical Strategy: Mechanical, decision-driven rename — no new abstractions. Apply the ADL's chosen branch (
pair-clicanonical) uniformly: (1) rename everyusage/examplesstring in the tenmetadata.tsfiles; (2) rename every invocation inexamples.mdx,workflows.mdx,DEVELOPMENT.md(leaving prose mentions of "pair" untouched); (3) widendocs-staleness-check.ts'sINVOCATION_PREFIX/checkDocsCommandsto also flag a barepair <cmd>as an error, and extenddocs-staleness-check.test.tswith a case asserting that; (4) runpnpm docs:stalenessto confirm the corrected docs pass and no bare-pairregression remains anywhere in scope.Key Components:
apps/pair-cli/src/commands/{install,kb-cache,kb-info,kb-validate,kb-verify,package,scaffold-kb,update-link,update,validate-config}/metadata.tsapps/website/content/docs/reference/cli/examples.mdx,workflows.mdxDEVELOPMENT.mdapps/website/lib/docs-staleness-check.ts(INVOCATION_PREFIX,SPAN_INVOCATION,LINE_INVOCATION,checkDocsCommands) +docs-staleness-check.test.tsRisks: Low-complexity mechanical change; the only real risk is an incomplete sweep (missing an occurrence) or an over-broad regex widening that starts flagging legitimate prose ("pair" as a noun) as an error — mitigated by AC6/AC7's explicit regression coverage and by running
pnpm docs:stalenessas the final check rather than trusting a partial manual grep.Design: not required
Design flag
Design: not required
Technical Risks and Mitigation
pair <cmd>in scopepnpm docs:stalenessafter the widened regex lands; it now catches this class by construction (AC6)INVOCATION_PREFIXover-matches prose containing "pair"Coupling: not assessed — no cross-context/service integration is introduced by this story (single monorepo, no new external dependency); excluded from the classification tier max per D21.
Task Breakdown
pair <cmd>invocationpair→pair-cliin the ten CLI commandmetadata.tsfilespair→pair-cliinexamples.mdxandworkflows.mdx(incl.kb validate→kb-validate)pair→pair-cliinDEVELOPMENT.mdpnpm docs:stalenessgreen, zero bad-invocation occurrences repo-wideDependency Graph
AC Coverage
--helpoutput namespair-cli)usage/examplessaypair-cli)kb validatefix)DEVELOPMENT.mdinvocations)organization.mdxconfirmed out of scope)pair <cmd>)T-1: Widen the docs-staleness gate to flag a bare
pair <cmd>invocationPriority: P0 | Estimated Hours: 2h | Bounded Context: Adoption & Guidelines (CLI docs tooling)
Summary: Extend
docs-staleness-check.tsso a documented invocation missing the-clisuffix (pair install,pair kb-validate, …) is reported as an error, not silently ignored. Written before the rename tasks (test-first, per the repo's bug-resolution workflow) so the new test first proves the defect against the current (unrenamed) docs, then stays green once T-2/T-3/T-4 fix them.Type: Bug Fix
Description:
INVOCATION_PREFIXinapps/website/lib/docs-staleness-check.ts:447currently matches only(?:npx ...)?pair-cli\s+, socheckDocsCommandsnever sees a barepair <cmd>line — this is the structural reason the class of defect in AC-6/AC-7 survived undetected. Add a second, narrower check (or a second regex) that recognizes a code-block/inline invocation starting withpairimmediately followed by a known-shaped command token (not preceded by a hyphen, not part of a longer word likepair-cli), and reports it as an error distinct from — and in addition to — the existing "unregistered subcommand" check. Must not start flagging prose ("the pair KB", "pair assets") orpair-cli-prefixed lines.Acceptance Criteria:
checkDocsCommandsreturns a non-empty error array for a fixture containingpair install(bare, no-cli).docs-staleness-check.test.ts, colocated with the existingdescribe('checkDocsCommands', ...)block.pair-cli init,pair-cli kb validateunregistered-subcommand case,pair-cli installvalid case, npx-prefixed, prose noun usage, version string,--version) all still pass unmodified.pnpm --filter website test -- docs-staleness-checkgreen; running the check against the current (pre-rename)examples.mdx/workflows.mdx/DEVELOPMENT.mdreports the bare-pairoccurrences (confirms the new check actually fires before T-2–T-4 remove the fixtures it would fire on).Technical Requirements:
pair <cmd>detected in both fenced code blocks and inline-code spans (mirroringSPAN_INVOCATION/LINE_INVOCATION's existing dual coverage).Implementation Approach:
SPAN_INVOCATION/LINE_INVOCATIONthat matches apairprefix (space, not hyphen) followed by a word-start token, excluding matches already captured by thepair-cliprefix; wire it intocheckDocsCommandsas a new error kind (e.g.wrong-binary-name).apps/website/lib/docs-staleness-check.ts(gate logic),apps/website/lib/docs-staleness-check.test.ts(coverage).apps/website/lib/docs-staleness-check.ts— widenINVOCATION_PREFIX/add bare-pairdetection incheckDocsCommands.apps/website/lib/docs-staleness-check.test.ts— add the new failing-then-passing test case(s) plus explicit regression assertions for the existing npx/prose/version cases.AGENTS.mdBug Resolution Workflow (test-first).Dependencies:
Implementation Steps:
docs-staleness-check.test.tsasserting a barepair install/pair kb-validateline is flagged; run and confirm it fails against the current implementation.INVOCATION_PREFIX/checkDocsCommandsindocs-staleness-check.tsto detect and report the bare-paircase.docs-staleness-check.test.tssuite — confirm zero regressions (prose, npx, version-string, validpair-clicases all still behave as before).pnpm docs:stalenessagainst the current (still unrenamed) docs and confirm it now reports the bare-pairoccurrences that T-2–T-4 will fix.Testing Strategy:
docs-staleness-check.test.tsfor bare-pairdetection; existing suite re-run for regression.pnpm docs:stalenessrun against real repo docs (pre- and post-rename).Notes: This task is the "create a failing test that reproduces the bug" step of the repo's mandated bug workflow — the "bug" being the gate's blindness to the wrong binary name, reproduced by asserting it fires on the current (not-yet-renamed) docs.
T-2: Rename
pair→pair-cliin the ten CLI commandmetadata.tsfilesPriority: P1 | Estimated Hours: 1h | Bounded Context: Adoption & Guidelines (pair-cli)
Summary: Rename every
usage/examplesstring across all ten command metadata files frompair <cmd>topair-cli <cmd>— mechanical, no behavior change.Type: Bug Fix
Description: Per ADL
2026-08-25-cli-invocation-canonical-name-is-pair-cli.md,pair-cliis the sole canonical invocation.apps/pair-cli/package.json'sbinfield already declarespair-cli— only the strings shown by--helpare wrong. Rename in place, one string replace per line, no logic change.Acceptance Criteria:
metadata.tsfiles'usageand everyexamplesarray entry start withpair-cli.pair-cli <command> --helpoutput reflects the renamed strings (metadata is read directly by the help renderer).grep -rn "'pair " apps/pair-cli/src/commands/*/metadata.tsreturns zero matches after the change (only'pair-cliremains).Technical Requirements:
Implementation Approach:
'pair→'pair-cli(and equivalent double-quote/template-literal forms if present) scoped tousage:/examples:fields only.apps/pair-cli/src/commands/*/metadata.ts.apps/pair-cli/src/commands/install/metadata.tsapps/pair-cli/src/commands/kb-cache/metadata.tsapps/pair-cli/src/commands/kb-info/metadata.tsapps/pair-cli/src/commands/kb-validate/metadata.tsapps/pair-cli/src/commands/kb-verify/metadata.tsapps/pair-cli/src/commands/package/metadata.tsapps/pair-cli/src/commands/scaffold-kb/metadata.tsapps/pair-cli/src/commands/update-link/metadata.tsapps/pair-cli/src/commands/update/metadata.tsapps/pair-cli/src/commands/validate-config/metadata.ts2026-08-25-cli-invocation-canonical-name-is-pair-cli.md.Dependencies:
Implementation Steps:
metadata.tsfiles, renaming everypairoccurrence inusage/examplestopair-cli.pair-cli <command> --helpfor 2-3 commands.pnpm --filter @pair/pair-cli test.Testing Strategy:
pairstring.pair-cli install --help,pair-cli kb-validate --helpspot check.Notes: No new tests required — this is a pure content fix covered by T-5's end-to-end gate check.
T-3: Rename
pair→pair-cliinexamples.mdxandworkflows.mdx(incl.kb validate→kb-validate)Priority: P1 | Estimated Hours: 1.5h | Bounded Context: Adoption & Guidelines (docs site)
Summary: Rename every documented invocation in the two CLI reference/workflow docs pages, fixing both the missing
-clisuffix and the seven surviving hyphen-lesskb validateoccurrences. Confirmorganization.mdxneeds no change.Type: Documentation
Description:
apps/website/content/docs/reference/cli/examples.mdxandworkflows.mdxcontain dozens ofpair <cmd>invocations (both fenced code blocks and inline code);examples.mdxadditionally has non-existentpair kb validate(hyphen-less) occurrences that must becomepair-cli kb-validate.apps/website/content/docs/customization/organization.mdxwas checked during refinement and contains no actual invocation lines (only prose mentions of "pair" as the product name) — no change needed there; this task's completion should re-confirm that (docs may have drifted since refinement).Acceptance Criteria:
examples.mdxandworkflows.mdxreadspair-cli <cmd>; zero remainingpair kb validate(space) anywhere.pair-cliinstall.grep -rn '\pair ' apps/website/content/docs/reference/cli/examples.mdx apps/website/content/docs/reference/cli/workflows.mdxreturns zero matches for an actual invocation line;grep -rn "pair kb validate" .` returns zero matches repo-wide.Technical Requirements:
.mdxfiles.Implementation Approach:
`pair ...`spans; hyphen-less `kb validate` → `kb-validate` in the same pass.apps/website/content/docs/reference/cli/.apps/website/content/docs/reference/cli/examples.mdxapps/website/content/docs/reference/cli/workflows.mdx2026-08-25-cli-invocation-canonical-name-is-pair-cli.md.Dependencies:
Implementation Steps:
examples.mdx— rename all invocation lines, fixkb validate→kb-validate.workflows.mdx— rename all invocation lines (leave prose/CI-step-name mentions of "pair" untouched).organization.mdxfor any invocation lines introduced since refinement; fix if present, otherwise leave as-is.pnpm docs:stalenessscoped to these files (or full repo) to confirm no remaining bad invocations.Testing Strategy:
pnpm docs:staleness.Notes: This is the largest occurrence count in the story — do the sweep methodically (grep before/after) rather than trusting memory of the line numbers cited in the original issue text, since they may have shifted.
T-4: Rename
pair→pair-cliinDEVELOPMENT.mdPriority: P1 | Estimated Hours: 0.5h | Bounded Context: Adoption & Guidelines (contributor docs)
Summary: Rename the CLI command reference table and the two mirror-guard prose mentions from
pairtopair-cli.Type: Documentation
Description:
DEVELOPMENT.md's command table (current lines ~154-160) and two prose references to thepair updatemirror-guard mechanism (current lines ~132, ~135) name the CLI aspair; rename all topair-cli.Acceptance Criteria:
pair <cmd>occurrence inDEVELOPMENT.mdbecomespair-cli <cmd>.grep -n "pair " DEVELOPMENT.mdshows onlypair-clioccurrences (or unrelated prose) afterward.Technical Requirements:
Implementation Approach:
DEVELOPMENT.md.DEVELOPMENT.md2026-08-25-cli-invocation-canonical-name-is-pair-cli.md.Dependencies:
Implementation Steps:
Testing Strategy:
pnpm docs:staleness(if it covers root-level.mdfiles; otherwise manual grep).Notes: Smallest task in the story; safe to do alongside T-3.
T-5: End-to-end validation —
pnpm docs:stalenessgreen, zero bad-invocation occurrences repo-widePriority: P0 | Estimated Hours: 1h | Bounded Context: Adoption & Guidelines (CLI docs tooling)
Summary: Final gate: confirm the widened staleness check (T-1) passes clean against the renamed docs/metadata (T-2, T-3, T-4), and that no bare
pair <cmd>orpair kb validateoccurrence remains anywhere in scope.Type: Testing
Description: This task is the story's Definition-of-Done proof:
pnpm docs:stalenessmust run green, and a full repo-wide grep for the two forbidden patterns must return zero results. It also re-confirms T-1's regression coverage (npx-prefixed, prose "pair" mentions, version strings) still passes now that the real docs have changed underneath it.Acceptance Criteria:
pnpm docs:stalenessexits 0.pair kb validate(space) and zero barepair <cmd>invocations repo-wide.pair-cli --helpand every subcommand--helpname a resolvable invocation on a clean npm install (manual spot check).pnpm docs:staleness+docs-staleness-check.test.tsfull suite, both green.Technical Requirements:
Implementation Approach:
Dependencies:
Implementation Steps:
pnpm docs:staleness— must exit 0.docs-staleness-check.test.tsfull suite — must be green.grep -rn "pair kb validate" .and a bare-pair-invocation grep across the Where-listed files — both zero.pair-cli --helpand 2-3 subcommand--helpoutputs manually.Testing Strategy:
pnpm docs:staleness(the real end-to-end gate).--helpspot check.Notes: If this task finds a straggler, fix it in place and re-run rather than filing a follow-up — the story's Definition of Done requires zero occurrences, not "reduced."