Skip to content
Open
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
18 changes: 12 additions & 6 deletions .agents/skills/ln-build/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,23 @@ Never silently continue past a stale-downstream signal. Never silently delete a

When a scope file is `Mode: coverage` (see [`ln-scope`](../ln-scope/SKILL.md) §Coverage scope files), it holds a closed enumerated ledger of one capability layer rather than a sequence of full cards. The build loop is row-driven:

Before taking a row, reload [`../ln-plan/references/coverage.md`](../ln-plan/references/coverage.md) if you have not read it in this thread.

1. take the next open required (`●`) row — one whose Status is `spec`, `new`, or `partial`
2. build it under the **fill mode declared in that row** (`proving` → tracer that retires the row's unknown; `earned` → land and lock the settled capability). A `new` row needs its micro-decision resolved (`ln-disambiguate` / `ln-spec`) before it can be built
3. run red → green → refactor and the verification harness for that row
4. flip the row's Status to `built` in the ledger and reconcile canonical state
5. commit the row-sized change
6. continue until **no `●` row remains in `spec` / `new` / `partial`** — that aggregate DoD, not any single row, completes the coverage frontier
2. **coverage re-orient checkpoint** — verify the row still fits the declared layer boundary, that its named owner is still the right owner, and that its promised behavior is derivable from the row's source-of-truth inputs. If any of those fail, stop and route back through `ln-scope` / `ln-plan`
3. build it under the **fill mode declared in that row** (`proving` → tracer that retires the row's unknown; `earned` → land and lock the settled capability). A `new` row needs its micro-decision resolved (`ln-disambiguate` / `ln-spec`) before it can be built
4. run red → green → refactor and the verification harness for that row
5. flip the row's Status to `built` in the ledger and reconcile canonical state
6. commit the row-sized change
7. continue until **no `●` row remains in `spec` / `new` / `partial`** — that aggregate DoD, not any single row, completes the coverage frontier

The chain stop conditions and Stale-downstream re-orient apply per row. Two coverage-specific rules:
The chain stop conditions and Stale-downstream re-orient apply per row. Coverage-specific rules:

- **Do not add rows as you go** except to record a genuinely-missing capability (Status `new`, one-line justification). The ledger is a closed list; filling it never means "do everything that rhymes" (global `AGENTS.md` §completionist sprawl).
- **One new row maximum.** If implementation discovers a second new row or a new sub-seam, the inventory was not actually closed; stop and route back through `ln-plan`.
- **A row that grows past ledger-row size** spawns its own `single` scope file; replace the row's Owner / next cell with a pointer rather than fattening the ledger.
- **Do not silently change frontier class.** If the row turns out to be evidence-gated or wait-gated rather than buildable-now, stop and reconcile the classification instead of forcing a ceremonial build.
- **Do not launder ownership.** If the build wants to move single-owner logic into a shared layer (or pull shared logic back into a single owner), stop and re-scope the row explicitly rather than smuggling a topology decision through coverage execution.

## Red

Expand Down
3 changes: 2 additions & 1 deletion .agents/skills/ln-consult/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,14 @@ Spikes are the escape hatch, not the default.
| Plausible interpretations diverge; examples would clarify faster than open-ended questioning | structural | `ln-disambiguate` |
| Understanding exists, needs a written spec | structural | `ln-spec` |
| Spec exists, needs work sequencing | structural | `ln-plan` |
| A capability layer is load-bearing as a whole but vertical slices keep leaving it shallow | structural | `ln-plan` — author a coverage frontier (see `ln-plan` §Horizontal coverage frontiers) |
| A capability layer is load-bearing as a whole but vertical slices keep leaving it shallow | structural | `ln-plan` — author a coverage frontier only if the admission gate in `ln-plan/references/coverage.md` passes |
| Verification strategy is the main uncertainty | structural | `ln-oracles` |
| Next work item needs precise boundaries | structural or bounded | `ln-scope` |
| One settled frontier item needs several small verified commits in sequence | bounded, hardening | `ln-scope` then serial `ln-build` loop, optionally via a `Mode: chain` scope file under `memory/cards/` |
| Module interface needs exploration | structural | `ln-design` |
| Full or light scope card exists, ready to code | bounded, hardening, bugfix | `ln-build` |
| Technical uncertainty blocks progress, or a cheap investigation could invalidate planned work | any | `ln-spike` |
| Review-bot comments or point findings may be symptomatic of a systemic fault | any | `ln-induct` |
| Code works but needs restructuring | refactor | `ln-refactor` |
| Code works but quality / architecture needs audit | any | `ln-review` |
| Docs are stale, overweight, or milestone context needs cleanup | structural / maintenance | `ln-sync` |
Expand Down
122 changes: 122 additions & 0 deletions .agents/skills/ln-induct/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
name: ln-induct
description: "Treat PR review-bot comments (or similar point observations) as samples from a latent defect distribution: induce the operative fault-type, then audit the codebase for unsampled instances. Use when small review findings may be symptomatic of a systemic-ish fault or fallacy, and you want a generative diagnostic lens rather than a one-off fix."
argument-hint: "[pasted comments/observations, or empty to fetch the current branch's PR review comments]"
---

# Ln Induct

A bot comment is a *sample*, not a fix. Defects cluster: one finding is a single draw from a latent fault-type the author can't see.

- **Engine:** infer the type from the sample, then fish for the instances nobody sampled.
- **Governor:** a generative audit wants to manufacture work, so a triage gate (step 3) decides what's worth fishing for. Without it the skill drifts into completionist sprawl and topical caricature (user-global `AGENTS.md` §Local necessity over category default).

This skill **generates** lenses; `ln-review`'s `contract` category is the **library** of stabilized ones. Induce a fresh lens from this batch; when one recurs across PRs, propose graduating it (step 6).

**Find and fix stay separate — including the bot's own fix.** Report and route; never auto-implement. A bot finding can be a true diagnosis carrying a wrong prescription, so validate its suggested repair against project posture, not just its claim. Routing to `ln-build`/`ln-refactor` is a separate, human-gated step.

Read `memory/SPEC.md` first when it exists (lexicon, live architecture register, §Acknowledged Blind Spots); read `memory/PLAN.md` for active frontier context.

## Input

Evidence to work from: $ARGUMENTS

## 1. Ingest the evidence

Two sources:

- **Supplied directly** — if `$ARGUMENTS` carries comments or observations, use those verbatim. Any source counts: PR bot, human reviewer, a thing you noticed.
- **Fetched from the remote** — if `$ARGUMENTS` is empty, **confirm with the user** that you'll look up review comments for the current branch's PR, then fetch them. Use whatever remote-review access is available — GitHub is the usual case (`gh` / `cli-gh-axi`), but do not lock to one provider; GitLab, Graphite (`gt`), or another host are equally valid. Pick the access path that fits the repo.

Normalize each item to `(location, claim, suggested fix)`. Drop nothing yet.

## 2. Abstract each item to a fault type (the lens)

For each item, climb the ladder of abstraction (Hayakawa; Bret Victor) from the concrete comment toward the fault *type* behind it. The stopping rule is the whole craft:

> **Stop at the lowest rung that is both mechanically searchable AND names a repair.**

- Too low → you've restated the comment. No lift.
- Too high → "code should be correct." Useless.
- Just right → "a `Map` built from a list keyed by an assumed-unique field" — you can grep it, and you know the fix.

The lens must be a *fishing instrument*, not a category label. Record the climb (`comment → rung → rung → lens`) so the abstraction is auditable and the user can challenge it.

Seed your climb with the stabilized lenses in `ln-review` §Contract integrity as **priors**, not a checklist — they bias what to look for, but the operative lens is induced from *this* evidence and may be new. A batch may yield several distinct lenses, or none worth promoting.

## 3. Triage: is it symptomatic? (the gate)

For each induced lens, decide **fix-in-place** vs **generalize-and-audit**. Promote to audit only when **all three** hold:

1. **Plausible recurrence** — a pattern a developer or agent reaches for repeatedly, not a freak.
2. **Cheap search exists** — there is a real family-grep or ownership seam you can actually sweep.
3. **High-value failure mode** — the fault is *silent / latent* (data silently dropped, a contract silently unhonored, a wrong default silently chosen). Loud faults self-report and don't need this skill.

Fail any one → fix in place (or route the single finding), record nothing further, move on. Most items will not promote, and that is the correct outcome.

## 4. Audit for unsampled instances

For each promoted lens, fish along **both** axes — not just the easy one:

- **Family axis** (syntactic / structural): every site sharing the pattern's shape. Grep-shaped, fast.
- **Ownership axis** (blast radius): everything a seam *owns* — same-responsibility faults that share no syntax (Parnas: a module's secret, not its shape). Higher-value, harder. **Force at least one ownership-seam question per promoted lens**, or the skill degenerates into "grep for the pattern."

Mind the data plane: it is often gitignored, so `rg` silently reports it clean — enumerate committed artifacts with `git ls-files`, not an ignore-respecting glob. Verify each hit is a real instance, not a shape-only false positive.

## 5. Report

Emit triaged findings. For each: the **assumed contract** in one sentence, the **failure mode** when it breaks, the **repair class**, and a **confidence**. Repair classes (from `ln-review` §Contract integrity, extend if the induced lens needs a new one):

- **enforce it loudly** — fail on violation (throw on collision, assert the invariant)
- **thread the real value** — carry provenance instead of hardcoding it
- **name the contract** — a predicate / type / comment that makes the assumption explicit
- **normalize at the boundary** — for ambient-environment leaks (paths, `cwd`, ordering)

Name adjacent work; do not implement it.

## 6. Propose graduation

Last step, proposal only. If an induced lens recurred here, or matches one this skill has surfaced before, **propose** adding it to `ln-review` §Contract integrity (or as a new review category) — the same promote-stabilized-truth move `ln-sync` uses. State the lens, its cue, and its repair. Leave the edit to the user; do not modify `ln-review` unprompted.

## Canonical reconciliation

Reconcile only durable truth:

- A recurring lens worth a permanent review pass → propose the `ln-review` edit (step 6).
- A confirmed systemic blind spot → propose an entry in `memory/SPEC.md` §Acknowledged Blind Spots.
- Findings tied to active frontier work → note against `memory/PLAN.md` status.
- One-off findings with no durable implication → no canonical update.

Do not create alternate ledgers or audit docs. Canonical docs are `memory/SPEC.md` and `memory/PLAN.md`; the lens library lives in `ln-review`.

## Output

```md
## Induction: [evidence source]

**Samples:** [n comments/observations ingested]

### Lenses induced
1. [lens] — climb: `comment → … → lens` · gate: [promoted | fix-in-place: which test failed]

### Findings (promoted lenses only)
| # | Lens | Location | Assumed contract | Failure mode | Repair | Confidence |
| - | ---- | -------- | ---------------- | ------------ | ------ | ---------- |

### Graduation proposals
- [lens] → `ln-review` §Contract integrity (recurred: [evidence]) | none
```

## Routing

After the report, present the relevant options to the user (use `tool-ask-question`):

| # | Label | Target | Why |
| --- | -------------------- | ------------- | --- |
| 1 | Scope the fixes | `ln-scope` | Findings need buildable cards or durable seam updates |
| 2 | Build a fix | `ln-build` | A finding is settled and ready for red-green-refactor |
| 3 | Plan a cluster | `ln-refactor` | Findings cluster across a seam into a structural change |
| 4 | Graduate the lens | manual edit | A recurring lens should join `ln-review`'s catalog |
| 5 | Reconcile blind spot | `ln-sync` | A confirmed systemic gap belongs in SPEC §Blind Spots |

Recommended depends on the findings: clusters → **3**, isolated silent faults → **1**, nothing promoted → stop and say so.
2 changes: 1 addition & 1 deletion .agents/skills/ln-judo-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Make the change easy, then make the easy change (Beck): if the diff feels tangle

Boring code over magic (Hunt & Thomas): generic mechanisms that hide simple data-shape assumptions are a defect, not a feature.

Ambient-contract reliance: an invariant the code assumes but never enforces, threads, or names — uniqueness keys that silently last-win, dedups that drop kept data, hardcoded literals standing in for upstream provenance, persisted absolute paths/`cwd` leaking into committed fixtures, magic shape-checks instead of named predicates. The judo move is to make the contract intentional: enforce it loudly, thread the real value, or name it — not to tidy the assumption in place. (Full cue list in `ln-review` §Contract integrity.)
Ambient-contract reliance: an invariant the code assumes but never enforces, threads, or names — uniqueness keys that silently last-win, dedups that drop kept data, hardcoded literals standing in for upstream provenance, persisted absolute paths/`cwd` leaking into committed fixtures, renames propagated to code/docs but not to committed fixtures or serialized artifacts, magic shape-checks instead of named predicates. The judo move is to make the contract intentional: enforce it loudly, thread the real value, or name it — not to tidy the assumption in place. (Full cue list in `ln-review` §Contract integrity.)

Functional core / imperative shell (Gary Bernhardt): when independent work is needlessly serialized, or related updates can leave state half-applied, ask whether orchestration should be separated from business logic — and whether the cleaner structure is parallel or atomic.

Expand Down
8 changes: 6 additions & 2 deletions .agents/skills/ln-plan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ A plan may contain a mix of postures across its `Active` / `Next` frontiers. Loa

### Horizontal coverage frontiers (frontier *shape*, not a posture)

Load [`references/coverage.md`](references/coverage.md) whenever a candidate frontier might be coverage, or when reclassifying a live coverage frontier.

Posture answers *how to rank the next vertical slice*; it carries **no completeness test**. Vertical tracers touch a horizontal capability layer (for example "the agent's READ tools as a whole") only as far as each claim needs, so a load-bearing layer can stay permanently shallow while every individual slice is still "done."

A **coverage frontier** fills that gap. It is a different frontier *shape*, not a third posture: it adds no row-level execution mechanics — each row is still built under `proving` or `earned`. What it adds is a layer-level **aggregate definition of done**: *no required row in a closed enumerated inventory is left open.*
Expand All @@ -146,11 +148,13 @@ If you cannot close the enumeration, it is not a coverage frontier — stay trac

Each ledger row declares its own **fill mode** — `proving` if the row still carries an unknown, `earned` if it is settled-but-unbuilt. `ln-build` closes rows; the frontier completes when no `●` row remains in a `spec` / `new` / `partial` state — the ledger DoD, not a single tracer claim.

**Maturity gate.** The coverage shape is young. Treat it as a recognized scope-file mode, **not** a canonical posture or doc type. Promote it to first-class (a `references/coverage.md` posture, a canonical coverage store) only on rule-of-three — at least three real coverage cases *and* a recurring need for row-level mechanics beyond "closed ledger + per-row proving/earned." Until then, do not add a third posture reference or an alternate planning store.
**Maturity gate.** The rule-of-three is now met in this repo: the elicitor cross-cut, graph observed-shapes, and the current runtime/exchange follow-ons exposed recurring row-level failure modes. Coverage therefore now has a dedicated planning reference, but it remains a **frontier shape**, not a third certainty posture or an alternate planning store.

**Sequencing precedence.** If a temporary coverage ledger remains open only because a required row has been promoted into `PLAN`, that promoted frontier outranks new unrelated coverage frontiers by default. Do not let "new breadth we could also do" preempt "the last required row that closes the still-live ledger" unless the user explicitly chooses that deprioritization.

## Procedure

0. Read `.pi/POSTURE.md` if present for the project's default certainty posture. For each `Active` / `Next` frontier, check for an explicit `Certainty:` override and load the matching reference (`references/proving.md` or `references/earned.md`). Load both when the plan is mixed.
0. Read `.pi/POSTURE.md` if present for the project's default certainty posture. For each `Active` / `Next` frontier, check for an explicit `Certainty:` override and load the matching reference (`references/proving.md` or `references/earned.md`). Load both when the plan is mixed. If any frontier candidate is or may be coverage-shaped, also load `references/coverage.md`.
1. Read `memory/PLAN.md` if it exists. Identify existing frontier ids and retire/archive stale completed material into `docs/archive/PLAN_HISTORY.md`.
2. Read `memory/SPEC.md` if it exists. Pull only the live requirements, assumptions, decisions, and invariants that still constrain forward work.
3. Explore the codebase enough to understand real boundaries.
Expand Down
Loading
Loading