Epic: A lightweight lane for small fixes to reach the concept store
⚠️ Utilization risk: assessed L (1–2 weeks). Fills the sprint with no slack for overruns. Watch for scope creep.
Description
The knowledge machinery is gated on epics. The distiller is the only writer of the concept store, it drains only entries, and an entry is drainable only when it holds both an epic.md and a close-record.md. Each of those two files has exactly one producer today, and both producers require an epic issue and at least one story sub-issue. So recording the reason behind a two-line fix costs four durable artifacts and two review cycles: an epic issue, a story issue, an implementation pull request, and a distillation pull request.
The practical result is that the reasons behind small fixes are not recorded at all. A developer facing that price either skips the rationale or dresses the fix as an epic. The first loses knowledge the store exists to hold. The second inflates the store with ceremony and buries the decisions that matter.
This epic adds a fifth entry point. A new /nxs.fix command creates the two files directly for a change that has already landed, taking one GitHub reference as its input and asking the developer why the change mattered. A structural rule, called the razor, keeps the lane honest. A fix entry may only append decision log entries, exactly one per changed page, and only to pages that already exist. It may not create a page, retire one, or change what a page asserts. The rule is enforced mechanically in the validator, on the computed page diff, before the distillation pull request opens. A change that needs to alter a page's stated behavior is a design change, and it keeps taking the epic lane.
Success Metrics
- A developer records the reason for a small fix with one GitHub number as the only durable artifact required, against the four the epic lane forces today.
- Every fix entry that reaches a distillation pull request appends exactly one decision log entry per changed page and leaves the rest of that page byte-identical, apart from the
last_updated_by: frontmatter line and trailing whitespace.
- A fix whose page changes would alter what a page asserts is refused with a named reason before the distillation pull request opens, rather than merged.
- Draining an epic entry behaves exactly as it did before this change.
- Running
/nxs.fix creates nothing on GitHub and commits nothing to the repository.
Personas
Per docs/product/context.md. The actor throughout this epic is the primary persona, the engineer on a small team adopting Nexus, in two moments of their work: landing a small fix and later running the drain. This epic adds no new persona.
Assumptions
/nxs.fix is a command definition under .claude/commands/, driven the way the other nxs.* commands are. The only new code is the validator mode in Story 2 and the helper subcommand in Story 1.
- The
range --pr <N> subcommand is added to the existing pull-request worktree helper script rather than published as a new skill.
- The entry files keep the names
epic.md and close-record.md for a fix entry, as the specification decides, so the drain changes one line of discovery instead of gaining a parallel code path. The entry_kind: fix field carries the truth about what the entry is.
- New TypeScript reaches the repository's 95% coverage bar through spec files beside each changed module.
- The trunk branch is resolved the way the drain already resolves it, and no new configuration key is added.
- Refusing a member repository is a hard block with no migration path, matching how
/nxs.close --pr already behaves.
Out of Scope
- A migration path that lets a member repository drain its own fix entries. The hub path covers the case, by running
/nxs.fix from the hub with a qualified reference.
- A
--pr worktree flow for /nxs.fix. The lane commits nothing, so there is nothing to commit on a branch.
- Batching.
/nxs.fix creates one entry per run, and /nxs.distill batches as it already does.
- Back-filling fixes that landed before this lane existed. The lane starts empty.
- Any change to
/nxs.close, /nxs.epic, or /nxs.decision-record.
- Fixing the
--require-epic guard in the epic resolver. The specification names it as the lane's first customer, to be done through the lane once the lane exists.
- Letting a fix strike through an existing invariant in place. The specification defers this loosening until there is evidence the razor binds too tightly.
- A drift advisory that watches for the lane becoming the default entry point.
Open Questions
None.
Epic: A lightweight lane for small fixes to reach the concept store
Description
The knowledge machinery is gated on epics. The distiller is the only writer of the concept store, it drains only entries, and an entry is drainable only when it holds both an
epic.mdand aclose-record.md. Each of those two files has exactly one producer today, and both producers require an epic issue and at least one story sub-issue. So recording the reason behind a two-line fix costs four durable artifacts and two review cycles: an epic issue, a story issue, an implementation pull request, and a distillation pull request.The practical result is that the reasons behind small fixes are not recorded at all. A developer facing that price either skips the rationale or dresses the fix as an epic. The first loses knowledge the store exists to hold. The second inflates the store with ceremony and buries the decisions that matter.
This epic adds a fifth entry point. A new
/nxs.fixcommand creates the two files directly for a change that has already landed, taking one GitHub reference as its input and asking the developer why the change mattered. A structural rule, called the razor, keeps the lane honest. A fix entry may only append decision log entries, exactly one per changed page, and only to pages that already exist. It may not create a page, retire one, or change what a page asserts. The rule is enforced mechanically in the validator, on the computed page diff, before the distillation pull request opens. A change that needs to alter a page's stated behavior is a design change, and it keeps taking the epic lane.Success Metrics
last_updated_by:frontmatter line and trailing whitespace./nxs.fixcreates nothing on GitHub and commits nothing to the repository.Personas
Per
docs/product/context.md. The actor throughout this epic is the primary persona, the engineer on a small team adopting Nexus, in two moments of their work: landing a small fix and later running the drain. This epic adds no new persona.Assumptions
/nxs.fixis a command definition under.claude/commands/, driven the way the othernxs.*commands are. The only new code is the validator mode in Story 2 and the helper subcommand in Story 1.range --pr <N>subcommand is added to the existing pull-request worktree helper script rather than published as a new skill.epic.mdandclose-record.mdfor a fix entry, as the specification decides, so the drain changes one line of discovery instead of gaining a parallel code path. Theentry_kind: fixfield carries the truth about what the entry is./nxs.close --pralready behaves.Out of Scope
/nxs.fixfrom the hub with a qualified reference.--prworktree flow for/nxs.fix. The lane commits nothing, so there is nothing to commit on a branch./nxs.fixcreates one entry per run, and/nxs.distillbatches as it already does./nxs.close,/nxs.epic, or/nxs.decision-record.--require-epicguard in the epic resolver. The specification names it as the lane's first customer, to be done through the lane once the lane exists.Open Questions
None.