Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 55 additions & 7 deletions .agents/skills/ln-build/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,63 @@ Run the project's verification harness. All checks must pass. Commit: `feat: [ta

## Traceability (mandatory — do before routing)

After the slice lands and verification passes, do all of these before presenting routing options:
After the slice lands and verification passes, update only the traceability items touched by this slice. For each candidate artifact, choose exactly one action: **add**, **update**, **merge**, **archive**, or **no-op**.

1. If working from `memory/PLAN.md`, mark the slice `done`. Check `## Dependencies` — if this slice unblocked multiple downstream slices, note them as newly available (some may be parallelizable). If working from `memory/REFACTOR.md`, mark the commit step complete there instead
2. Update `memory/SPEC.md` §Assumptions — set `Status` to `validated` or `invalidated` as evidence warrants, update `Confidence` if the evidence changed it, and flag implicated slices in PLAN.md
3. Add new invariants to `memory/SPEC.md` §Invariants — each structural property now protected by tests. If working from `memory/PLAN.md`, update the `Invariants established` field on the corresponding slice
4. Add any new decisions to `memory/SPEC.md` §Decisions, new assumptions to §Assumptions
5. Update `memory/SPEC.md` §Verification Design → Current Coverage with new test files and counts
### Local comparison set

These are bookkeeping steps, not optional. Routing comes after.
Compare new facts only against items the current slice already references:

- the current slice block in `memory/PLAN.md` (and its tracer bullets)
- rows in `memory/SPEC.md` named by the slice (§Assumptions, §Decisions, §Invariants to respect/established)
- assumption/decision IDs from the scope card
- test files added or changed in this slice

Do **not** scan the whole spec looking for the perfect merge target. If nothing in this local set clearly matches, **add** and let `ln-sync` consolidate later.

### Same-item tests

Use these to decide whether a candidate fact is already covered by an existing local row:

- **Same assumption** = same boundary/component + same unresolved claim. Differences in wording, confidence, evidence, or validation method → same assumption.
- **Same decision** = same seam/boundary + same chosen alternative. Narrower helpers, file layout, implementation mechanics, or first concrete use of an already-chosen pattern → same decision.
- **Same invariant** = same seam/boundary + same rule template + same proved decision(s). Approve/reject, confirm/force-close, reload/refresh/resume, or kind/phase/state variants of one shared rule → same invariant.

### Steps

1. **Mark completion.** Mark the slice or tracer bullet `done` in `memory/PLAN.md`. Note newly unblocked downstream slices.

2. **Assumptions** — for each assumption the slice touched or relied on:
- Evidence answered it → **update** status to `validated` or `invalidated`; flag implicated slices
- Evidence changed certainty only → **update** confidence
- Same assumption exists locally → **merge** into it
- New unresolved belief the slice depended on, not already guaranteed by code/tests, and if false would change future work → **add**
- Otherwise → **no-op**

3. **Decisions** — a decision records a committed choice at a seam, not an execution diary entry:
- Slice only implemented an existing decision without changing the choice → **no-op**
- Same decision exists locally and choice stayed the same → **update** (clearer rationale/scope) or **merge** (narrower instance of same pattern)
- Slice chose one alternative among ≥2 plausible alternatives, non-trivial to reverse, future work could revisit → **add**
- Slice changed the answer at the same seam → **add** new row with `Supersedes: Dn`
- Otherwise → **no-op**

4. **Invariants** — prefer one seam-level invariant over many branch-level invariants:
- No new/changed test protects the property → **no-op**
- Property is temporary migration state or one example of a broader rule → **merge** or **no-op**
- Same invariant exists locally and only `Protected by` grew → **update**
- Candidate is another branch/state/kind/phase/action variant of the same rule → **merge** (keep surviving ID, union `Protected by`, append to `Established by` only if the statement widened)
- Property can regress independently of all local invariants (different seam, rule, proved decision, or test family) → **add**
- Otherwise → **merge**

5. **Completed-slice note in PLAN.md** — max 4 bullets / 6 lines:
- shipped outcome
- seam changed (optional)
- evidence (tests/manual)
- remaining debt or follow-up (optional)
- If a note already exists, **update** it; do not append another paragraph. If marking `done` plus invariant/decision updates already captures everything → **no-op**

6. **Verification coverage** — update `memory/SPEC.md` §Current Coverage. If the test file already appears, **update** counts; do not add a duplicate entry.

When uncertain between merge and add → add. When uncertain between update and no-op → update.

## Routing

Expand Down
6 changes: 5 additions & 1 deletion .agents/skills/ln-plan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ argument-hint: "[feature or project area to plan]"

Break a feature into tracer-bullet slices and spikes (Hunt & Thomas), grouped into temporal phases. Slices are thin end-to-end paths through all integration layers. Order by uncertainty first, dependency second (Reinertsen: retire risk early, not just finish tasks early).

**Anti-fragmentation heuristic.** Create a new slice only when it introduces at least one of: (1) a new lifecycle seam, (2) a new cross-boundary transport/persistence seam, (3) a new workflow-mode entry/exit behavior, or (4) a new unblocker for reaching the end-to-end working app state. Do **not** create separate slices for additional action/status permutations or rarer branches on the same seam unless they materially unblock progress.

**Refinement sink.** When deferred variants accumulate, collect them into a later cross-cutting refinement slice instead of fragmenting the active major slice. Plan for the dominant path first; explicitly defer edge-case polish and rarer lifecycle variants.

**Epistemic horizon.** Plan depth must match confidence depth. If `memory/SPEC.md` §Assumptions contains low-confidence items that downstream slices depend on, the plan's horizon stops there — plan spikes that retire the uncertainty, not slices that assume it away.

**Spike economics.** For each low-confidence assumption, evaluate: how many slices depend on it, how cheaply it can be falsified, what decisions it unlocks. High fan-out + low falsification cost → spike early. When uncertainty is broad, the first slices should be invariant-establishing (walking skeleton), not feature-delivering.
Expand All @@ -24,7 +28,7 @@ If context is thin, run a brief interview (not a full `ln-grill`) to fill gaps.

1. If `memory/PLAN.md` exists, read it first. Retire completed slices (mark `done`). Assess what remains and what's changed.
2. Explore the codebase. Identify architectural constraints the slices must respect (routes, schema, auth, third-party boundaries).
3. Draft or revise phases and slices. Each slice must be independently demoable and independently grabbable where possible. Group into temporal phases. For each, name dependent requirements and assumptions from `memory/SPEC.md`, plus any candidate invariant goals to establish or existing invariants to respect.
3. Draft or revise phases and slices. Each slice must be independently demoable and independently grabbable where possible. Group into temporal phases. Bias toward the minimum slice set that covers the main user story and keeps the app moving end to end; if a major slice can be sub-sliced many ways, keep only the variations that unblock forward progress and defer the rest explicitly. For each slice, name dependent requirements and assumptions from `memory/SPEC.md`, plus any candidate invariant goals to establish or existing invariants to respect.
4. Observe and respect local project protocols for mapping slices/spikes to issues or tickets, associated codes, and branch naming conventions, if any. Capture project-specific tracking metadata as optional execution detail — not as the core identity of the slice.
5. Confirm with user — adjust granularity, reorder, split or merge.
6. **Post-edit checklist** — after any addition, removal, or reordering:
Expand Down
6 changes: 5 additions & 1 deletion .agents/skills/ln-scope/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ argument-hint: "[behavior to deliver in this slice]"

Define **one** tracer-bullet slice (Hunt & Thomas) — a thin end-to-end path, not a horizontal layer. If the target behavior needs "and", split it.

**Sub-slicing restraint.** Create a new sub-slice only when it introduces at least one of: (1) a new lifecycle seam, (2) a new cross-boundary transport/persistence seam, (3) a new workflow-mode entry/exit behavior, or (4) a new unblocker for reaching the end-to-end working app state. Do **not** split off a separate slice just for another action/status permutation or a rarer branch on the same seam. If refinements accumulate, prefer one later cross-cutting refinement slice over fragmenting the current major slice.

**Main-path bias.** Scope the smallest slice set that covers the dominant user story and unblocks forward progress. Rare variants, polish, and refinement work should be named explicitly as deferred rather than silently folded into the current slice.

## Input

The behavior to deliver: $ARGUMENTS
Expand Down Expand Up @@ -65,7 +69,7 @@ A slice without a verification approach is not fully scoped. At minimum, inner-l

After the scope card is complete, do these before presenting routing options:

1. New assumptions surfaced during scoping → add to `memory/SPEC.md` §Assumptions with links to this slice
1. New assumptions surfaced during scoping → apply `ln-build` §Same-item tests first. If the same assumption already exists in `memory/SPEC.md`, **update** or **merge** into it. Only **add** if no existing row covers the same boundary + claim.

## Routing

Expand Down
22 changes: 21 additions & 1 deletion .agents/skills/ln-spec/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,27 @@ If `memory/PLAN.md` exists, verify that changed assumptions and decisions still

### Weight management

Spec documents accumulate. Each ln-sync pass may prune items that are embedded, moot, or superseded (see ln-sync §Pruning check). When *adding* items, consider whether an existing item should be retired to make room. A spec with 30 assumptions is not more rigorous than one with 10 — it's harder to read and more likely to mislead a new session.
Use the same unit-of-record rules as `ln-build` §Same-item tests. Before adding a row, compare against nearby items in the same feature area. Prefer **update** or **merge** over **add** when the seam is the same.

**Units of record:**

- **Assumption** = one unresolved question at one seam
- **Decision** = one committed choice between alternatives at one seam
- **Invariant** = one seam-level structural property protected by tests

**These are not new rows** — they are updates or merges to existing rows:
- confidence changes, validation narratives, added evidence
- helper names, file layout, or implementation mechanics
- one more branch/state/kind/phase/action example of an existing rule
- one implementation step under an already-recorded decision

**Smell checks before adding:**
- The sentence starts with "for this slice" or names a temporary cutover step → probably an update, not a new item
- The difference is only approve/reject, confirm/force-close, or kind/phase/state variants of one shared rule → merge into the seam-level row
- The item would stop making sense once the code ships and no alternative remains live → probably a decision that should not be tracked
- The item is an implementation mechanic inside an already-chosen boundary → no-op

Large cleanup is `ln-sync` work. When writing or patching, keep the touched area coherent; do not attempt a risky whole-document consolidation.

### Cross-reference integrity

Expand Down
66 changes: 57 additions & 9 deletions .agents/skills/ln-sync/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,69 @@ For each assumption whose `Status` is `invalidated`:
- Preserve `Status: invalidated` in §Assumptions
- Flag all implicated slices in `memory/PLAN.md`

### 2b. Pruning check
### 2b. Consolidation pass

Tracked items accumulate. Large assumption and decision tables become a confusion surface — new sessions inherit stale context and make wrong inferences. After graduation, assess each remaining item for removal:
`ln-build` is local and conservative — it only compares against items the current slice references. `ln-sync` owns whole-document consolidation: merging equivalent rows, generalizing micro-variants, and absorbing implementation-detail decisions.

Read the full affected sections and merge overly-granular items before pruning.

#### Same-item tests (from ln-build — apply globally here)

- **Same assumption** = same boundary/component + same unresolved claim
- **Same decision** = same seam/boundary + same chosen alternative
- **Same invariant** = same seam/boundary + same rule template + same proved decision(s)

#### Global consolidation rules

- Keep the **oldest surviving ID** among equivalent rows
- Rewrite that survivor to the **generalized statement**
- Union metadata (`Protected by`, `Established by`, dependencies, implicated slices, validation evidence)
- Remove absorbed rows and leave an HTML comment naming absorbed IDs and why
- Do **not** renumber surviving items
- Rewrite references in both `SPEC.md` and `PLAN.md` from absorbed IDs to the surviving ID

Comment format: `<!-- Consolidated 2026-04-XX: absorbed I54, I55 into I52 — same seam/rule, generalized wording -->`

#### Assumptions — merge when:

- same boundary/component + same unresolved claim + differences are only wording, confidence, evidence, or validation method
- After merge: keep one row, preserve strongest status/evidence, union dependent decisions and implicated slices

#### Decisions — merge when:

- same seam/boundary + same chosen alternative + newer rows only add implementation detail, narrower examples, or first use cases of the same pattern
- Keep separate when different alternatives at the same seam, or either choice could still be revisited independently

#### Invariants — merge when:

- same seam/boundary + same rule template + same proved decision(s), or one row is a strict example/branch of the other
- Prefer the generalized seam-level wording; union protecting test files and establishing slices
- Keep separate only when they can regress independently because seam, rule, proof, or test family differs

#### Completed-slice notes in PLAN.md

For every `done` slice:
- keep at most one compact completion block (max 4 bullets / 6 lines): shipped outcome, seam changed, evidence, remaining debt
- replace verbose `Observed current state` / `Observed code seam` narratives with the compact form
- if the parent slice is `done`, fold tracer-bullet prose into the parent note
- delete completion notes that only repeat acceptance text, invariant IDs, or commit history

Git is the history. PLAN.md keeps only routing-relevant summaries.

### 2c. Pruning check

After consolidation, assess each remaining item for removal:

| State | Criterion | Action |
| --- | --- | --- |
| **Embedded** | Status `validated`, and now a structural property of the code — restating it as a tracked question adds noise, not clarity | Remove — the code is the proof |
| **Moot** | Status `invalidated`, and the concern no longer applies (e.g. the technology it worried about was replaced entirely) | Remove |
| **Superseded** | Replaced by a newer decision or assumption | Remove, note in the replacement |

When pruning, leave a comment noting which IDs were removed and why (e.g. `<!-- Pruned 2026-04-03: removed A1, A2 ... — embedded in architecture -->`). Do not renumber surviving items — IDs are stable. Dereference removed items from PLAN.md slice cross-references.
| **Embedded** | Now a structural property of code/tests/decisions/invariants; restating it as a live tracked item adds noise | Remove |
| **Moot** | The concern no longer applies in the current architecture | Remove |
| **Superseded** | Replaced by a newer decision/assumption/invariant and all references can point to the replacement | Remove, note replacement |
| **Redundant** | Equivalent to another surviving row after consolidation | Remove |

After pruning, repair or replace any dangling cross-references in `memory/SPEC.md` and `memory/PLAN.md` that pointed at removed assumptions, decisions, invariants, or verification notes.
When pruning, leave a comment noting which IDs were removed and why (e.g. `<!-- Pruned 2026-04-03: removed A1, A2 — embedded in architecture -->`). Do not renumber surviving items.

The same logic applies to §Decisions: a decision that is now simply how the code works, with no live alternative being weighed, can be removed. Keep decisions that record a *choice between alternatives* that future work might revisit.
After pruning, repair or replace any dangling cross-references in `memory/SPEC.md` and `memory/PLAN.md` that pointed at removed or absorbed items.

### 3. Staleness check

Expand Down
Loading