Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
cad53c3
Prune stale scope cards
lunelson Jun 6, 2026
ebd3961
Add characterization coverage for implicit refactor contracts
lunelson Jun 6, 2026
12160ed
Point StructuredExchangeToolResultDetails at the full request-details…
lunelson Jun 6, 2026
a232af9
Name the WebSocket send-readiness predicate against ws OPEN constant
lunelson Jun 6, 2026
31fe7a7
Assemble Pi extension registrars declaratively instead of splicing
lunelson Jun 6, 2026
f29593b
Add request_choice next-tool metadata on answered responses
lunelson Jun 6, 2026
c265ad5
Persist portable probe artifact references
lunelson Jun 6, 2026
14dc189
Extract explicit duplicate-edge precedence policy for Bilal seed port
lunelson Jun 6, 2026
4727624
Throw on duplicate RPC method definitions instead of silent last-win
lunelson Jun 7, 2026
986fc9c
Capture every labeled intent line instead of dropping same-kind repeats
lunelson Jun 7, 2026
be1ea6e
Round-trip present tool provenance for single-select exchanges
lunelson Jun 7, 2026
027a7fb
Make probe reports portable: relative artifact refs and scrubbed ephe…
lunelson Jun 7, 2026
21f9c23
Add contract-integrity lens for ambient-contract reliance to review s…
lunelson Jun 7, 2026
1b40171
ln-skills: add coverage frontier shape for horizontal completeness
lunelson Jun 7, 2026
aa96537
Add renderer preview harness
lunelson Jun 7, 2026
a7acef9
Add render coverage seed fixtures
lunelson Jun 7, 2026
7ddcd4e
Add graph slice list reads
lunelson Jun 7, 2026
1bd879c
remove stale pi extensions audit file
lunelson Jun 7, 2026
5c5e8ac
Add related graph slice reads
lunelson Jun 7, 2026
e3ca317
Add session context read tool
lunelson Jun 7, 2026
4e9ac75
Add graph gaps read mode
lunelson Jun 7, 2026
08f6d1f
Add workspace cwd context snapshot
lunelson Jun 7, 2026
acb5a12
Add workspace overview context mode
lunelson Jun 7, 2026
8fdde75
refinements to coverage skill refinements
lunelson Jun 7, 2026
887ceb9
cross-cut-plan and spec updates, before main thread restart
lunelson Jun 7, 2026
b797fb0
clean up exhausted scope cards
lunelson Jun 7, 2026
76e5dca
Add ordinary message capture RPC
lunelson Jun 7, 2026
5f6eda1
Add freestyle strategy pin
lunelson Jun 7, 2026
370393b
Scope next cross-cut Seam 3a/3b slices; reconcile Seam 2 ledger
lunelson Jun 7, 2026
abafc39
Retire snapshot architecture terminology
lunelson Jun 7, 2026
db4feb9
Reorient elicitation-backlog card to read|project|render split
lunelson Jun 7, 2026
dc4e0b1
move structured-exchange renderers to src/renderers/exchanges
lunelson Jun 8, 2026
9101ba0
Align exchange renderer path docs
lunelson Jun 8, 2026
c692b0f
Reconcile planning around elicitation backlog
lunelson Jun 8, 2026
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: 18 additions & 0 deletions .agents/skills/ln-build/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Never scan or pick by mtime, alphabetical order, or directory-listing heuristics

Once a file is selected, work the next card marked `next` (or the first unfinished card in file order if status markers are absent). If that card is already satisfied on the current branch, do **not** manufacture a no-op build commit; verify the acceptance criteria, mark the card `done` or `dropped` as appropriate, reconcile, and either continue to the next ready card in the same file or route back to `ln-scope` if no build remains.

If the selected file is `Mode: coverage`, it holds a row ledger rather than cards — follow the [Coverage execution mode](#coverage-execution-mode) loop below instead of card-based selection.

Re-enter before red.

If this is a fresh thread or an unfamiliar area, reload:
Expand Down Expand Up @@ -85,6 +87,22 @@ Even when `ln-scope` honored the hard anti-speculation gate (no card's scope was

Never silently continue past a stale-downstream signal. Never silently delete a stale chain before a replacement exists.

## Coverage execution mode

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:

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

The chain stop conditions and Stale-downstream re-orient apply per row. Two 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).
- **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.

## Red

Translate acceptance criteria into failing tests when the change benefits from them. For bugfixes or subtle seam changes, prefer one high-leverage regression test. For trivial maintenance or doc-only work, tests may be unnecessary.
Expand Down
1 change: 1 addition & 0 deletions .agents/skills/ln-consult/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ 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) |
| 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/` |
Expand Down
4 changes: 3 additions & 1 deletion .agents/skills/ln-judo-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ 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.)

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.

### Specific rules
Expand Down Expand Up @@ -77,7 +79,7 @@ Prefer a small number of high-conviction comments over a long list of cosmetic n
```md
## Judo Review: [area]

1. **[Description]** — [category: judo|depth|spaghetti|boundary|file-size|naming] — [impact: low|medium|high]
1. **[Description]** — [category: judo|depth|spaghetti|boundary|contract|file-size|naming] — [impact: low|medium|high]
[1-2 sentence explanation and suggested action]
```

Expand Down
26 changes: 25 additions & 1 deletion .agents/skills/ln-plan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The posture is **per frontier**, not per project. A mostly-earned repo can carry

Posture annotations are **required** on every `Active` / `Next` frontier (see the matching reference for the field set). If no posture-specific annotation applies, the frontier is not earning its slot — reshape, reclassify, or demote it.

When implementation later reveals the posture was wrong, treat that as a state transition (downgrade earned → proving, reshape the slice, route back through `ln-plan` if the frontier itself splits). Do not invent a third permanent posture.
When implementation later reveals the posture was wrong, treat that as a state transition (downgrade earned → proving, reshape the slice, route back through `ln-plan` if the frontier itself splits). Do not invent a third permanent posture. (A horizontal **coverage frontier** is a frontier *shape*, not a third posture — see [§Horizontal coverage frontiers](#horizontal-coverage-frontiers-frontier-shape-not-a-posture).)

Defensive parsing: depend primarily on `.pi/POSTURE.md`'s `certainty:` field; tolerate extra or mismatched fields rather than failing on schema drift.

Expand Down Expand Up @@ -124,6 +124,30 @@ Sequencing pressures and required annotation fields depend on the active frontie

A plan may contain a mix of postures across its `Active` / `Next` frontiers. Load both references when planning a mixed plan.

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

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.*

**Recognition trigger.** Reach for a coverage frontier only when all three hold:

1. a **named layer is load-bearing as a whole** — its value *is* its breadth (an agent's capability surface, a public API's method set, a renderer family), not just one claim it proves;
2. you can **author a closed, enumerated inventory** up front of what the layer must contain; and
3. rows can be marked **required vs deferred** (e.g. POC `●` / later `○`).

If you cannot close the enumeration, it is not a coverage frontier — stay tracer-shallow. Most product layers should (correct YAGNI). Coverage mode is safe *only because the surface is a closed list*; without this gate it degenerates into completionist sprawl (global `AGENTS.md` §completionist sprawl).

**Frontier definition fields.** A coverage frontier names:

- the **layer boundary** — what is in the layer and explicitly what is out;
- the **aggregate DoD** — "every `●` row is closed";
- a pointer to the **`Mode: coverage` scope file** under `memory/cards/` that holds the row ledger (authored via `ln-scope`).

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.

## 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.
Expand Down
20 changes: 18 additions & 2 deletions .agents/skills/ln-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: ln-review
description: "Audit code quality focusing on deep modules, naming, model hygiene, topographic legibility, and architectural clarity. Use after a burst of development, when codebase structure needs assessment, or to make code more agent-navigable."
description: "Audit code quality focusing on deep modules, naming, model hygiene, ambient-contract reliance, topographic legibility, and architectural clarity. Use after a burst of development, when codebase structure needs assessment, or to make code more agent-navigable."
argument-hint: "[area of codebase to review, or 'recent' for recently changed files]"
---

Expand Down Expand Up @@ -46,6 +46,22 @@ Check the functional core / imperative shell boundary (Gary Bernhardt, "Boundari

Make invalid states unrepresentable (Yaron Minsky). Split optional fields into distinct types. Use branded types for domain-distinct values.

### Contract integrity (category: `contract`)

Find invariants the code *assumes* but never enforces, threads, or names — "ambient-contract reliance." The seam works today only because the assumption happens to hold; nothing makes the contract intentional, and a reviewer can't tell intended behavior from accident. Each finding routes to one of three repairs: **enforce it loudly** (fail on violation), **thread the real value** (carry provenance instead of hardcoding it), or **name the contract** (a predicate/type/comment that makes the assumption explicit).

Concrete cues to look for:

- A `Map`/object built from a list keyed by a field assumed unique → duplicates silently last-win. Repair: throw on collision.
- A dedup or "first wins / last wins" that silently drops data the caller meant to keep. Repair: thread distinct keys, or fail loudly.
- A hardcoded literal standing in for a value that should be carried from upstream (`respondsToPresentTool: 'present_options'` when the originating tool varies). Repair: thread the real provenance.
- Persisted or serialized data that assumes an ambient environment (absolute paths, `cwd`, tempdirs, machine-local roots leaking into committed fixtures). Repair: name the portable contract and normalize at the boundary.
- A magic check inferring readiness/state from an object's incidental shape instead of a named constant or predicate. Repair: name the predicate against the canonical constant.
- Ordering or position encoded by a numeric index/splice rather than by structure. Repair: make the order declarative.
- A type alias or name that implies a wider contract than it points at. Repair: point it at the real union, or rename.

Collect findings as numbered items (category: `contract`). Frame each as: the assumed contract in one sentence, the failure mode when it breaks, and which of the three repairs applies. Most are concrete fixes (`ln-scope`/`ln-build`); clusters across a seam route to `ln-refactor`.

### Oracle coverage (category: `oracle-coverage`)

If `memory/SPEC.md` §Oracle Strategy by Loop Tier exists, check whether recent work implemented the oracles declared by the relevant `memory/PLAN.md` frontier definition. If a full or light scope card is available in session context, use it as a higher-resolution slice supplement, not the primary source of truth. Look for:
Expand Down Expand Up @@ -109,7 +125,7 @@ Present findings as numbered candidates. Use the compact form for ordinary findi
```md
## Review: [area]

1. **[Description]** — [category: depth|naming|model|coupling|seam|oracle-coverage|topography] — [impact: low|medium|high]
1. **[Description]** — [category: depth|naming|model|contract|coupling|seam|oracle-coverage|topography] — [impact: low|medium|high]
[1-2 sentence explanation and suggested action]

2. ...
Expand Down
30 changes: 28 additions & 2 deletions .agents/skills/ln-scope/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ Every scope file starts with this header:

Frontier: <frontier-id> | n/a
Status: active | superseded | done
Mode: single | chain
Mode: single | chain | coverage
Created: YYYY-MM-DD
```

`Mode: single` means one card in this file. `Mode: chain` means several cards intended as a sequential mini-queue. Independent concerns belong in **separate files**, not separate sections within one file.
`Mode: single` means one card in this file. `Mode: chain` means several cards intended as a sequential mini-queue. `Mode: coverage` means the file holds a **closed enumerated ledger** for a horizontal coverage frontier (see [§Coverage scope files](#coverage-scope-files-mode-coverage)). Independent concerns belong in **separate files**, not separate sections within one file.

### Why one file per concern, not one file for everything

Expand Down Expand Up @@ -100,6 +100,32 @@ Chain discipline:
- if any card trips the promotion checklist, reveals a frontier split, or turns out to depend on unknown results from an earlier card, stop the chain and route back through `ln-spec` or `ln-plan` as appropriate
- delete the scope file when its chain is exhausted or superseded (per-file deletion only)

## Coverage scope files (`Mode: coverage`)

A `Mode: coverage` scope file is the execution artifact for a **horizontal coverage frontier** (see [`ln-plan`](../ln-plan/SKILL.md) §Horizontal coverage frontiers). Where `single` / `chain` files group *vertical* slices, a coverage file holds a **closed enumerated ledger** of one capability layer, and its definition of done is *aggregate*: every required row closed.

Write one only when `ln-plan` has established a coverage frontier whose three-part gate is satisfied — a named layer that is load-bearing as a whole, a closeable enumeration, and required-vs-deferred marking. If you cannot close the enumeration, do not use this mode; write ordinary vertical cards instead.

### Ledger shape

The file body is a coverage ledger — one table per sub-seam if the layer splits:

| Capability | Status | Req | Fill | Owner / next | Notes |
| --- | --- | --- | --- | --- | --- |
| *one capability the layer must contain* | `have` \| `partial` \| `spec` \| `new` \| `built` | `●` \| `○` | `proving` \| `earned` | *card / decision / pointer* | *links* |

- **Status:** `have` (in code) · `partial` (exists, incomplete vs target) · `spec` (designed, not built) · `new` (beyond spec, needs a decision first) · `built` (closed this push).
- **Req:** `●` required for the DoD · `○` deferred. The DoD is "every `●` row is `have` or `built`."
- **Fill:** the posture each row's build inherits — `proving` if the row still carries an unknown, `earned` if it is settled-but-unbuilt. A `new` row usually needs a micro-decision (`ln-disambiguate` / `ln-spec`) before it can be filled.

### Each row is still a vertical fill

The file is horizontal; each **row** is built as an ordinary thin slice under its declared fill posture. `ln-build` implements rows and flips their Status to `built`; the row's target *is* the acceptance criterion. A row whose scope turns out to need its own full card may spawn a sibling `single` file — leave a pointer in that row's Owner / next cell rather than fattening the ledger.

### Anti-sprawl boundary

The ledger is a **closed list**, not a generative one. "Fill the layer" means *close these enumerated rows*, never "do everything that rhymes" (global `AGENTS.md` §completionist sprawl). Add a row mid-flight only when a genuinely-missing capability is discovered — record it with Status `new` and a one-line justification, never as completionist symmetry.

## Overlap-as-independence-test

When considering whether to write *another* scope file for the same frontier alongside an existing one, apply the overlap test: compare declared **Expected touched paths** across the two proposed files.
Expand Down
2 changes: 1 addition & 1 deletion .fixtures/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ for the current architecture.
├── session.jsonl # Source transcript / canonical run evidence
├── transcript.md # Human-readable semantic rendering
├── report.json # Probe report and artifact paths
└── graph-snapshot.json # Optional graph readback when graph truth is the proof target
└── graph-overview.json # Optional graph readback when graph truth is the proof target
```

## Current runs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"seedSet": "bilal-port-variants",
"seedSlug": "macro-view-grounded-intent",
"selectedBaseProfile": "grounded-intent",
"cwd": "/var/folders/2c/ptn6jcrj61lck_yzfz_p3b5m0000gn/T/brunch-fixture-curation-vg9Eo2",
"cwd": "<ephemeral-workspace>",
"specId": 1,
"sessionId": "019e96f4-ae08-762d-9783-ddd94163e7b3",
"prompt": "Brunch fixture-curation tracer: the selected spec is a Bilal-derived explicit base seed named \"macro-view-grounded-intent\".\n\nUse read_graph once in overview mode. Then use commit_graph exactly once to add a small intent-plane expansion that improves launch/usefulness of this existing spec without duplicating base nodes. Create one to three new intent-plane nodes, connect them legally to existing graph truth when possible, use basis implicit through the propose-graph tool path, and stop after a successful commit_graph result.",
Expand Down Expand Up @@ -36,7 +36,7 @@
11,
12
],
"content": "Graph committed successfully (LSN 3).\nNodes created: n1 R1, n2 R2\nEdges created: #7, #8, #9, #10, #11, #12"
"content": "Graph committed successfully (LSN 3).\nNodes created: n1 \u2192 R1, n2 \u2192 R2\nEdges created: #7, #8, #9, #10, #11, #12"
}
],
"createdNodes": [
Expand Down Expand Up @@ -68,10 +68,10 @@
},
"friction": [],
"artifacts": {
"runDir": "/Users/lunelson/Code/hashintel/brunch-next/.fixtures/runs/fixture-curation/fixture-curation-2026-06-05T104440Z",
"sessionJsonl": "/Users/lunelson/Code/hashintel/brunch-next/.fixtures/runs/fixture-curation/fixture-curation-2026-06-05T104440Z/session.jsonl",
"transcriptMarkdown": "/Users/lunelson/Code/hashintel/brunch-next/.fixtures/runs/fixture-curation/fixture-curation-2026-06-05T104440Z/transcript.md",
"reportJson": "/Users/lunelson/Code/hashintel/brunch-next/.fixtures/runs/fixture-curation/fixture-curation-2026-06-05T104440Z/report.json",
"graphSnapshotJson": "/Users/lunelson/Code/hashintel/brunch-next/.fixtures/runs/fixture-curation/fixture-curation-2026-06-05T104440Z/graph-snapshot.json"
"runDir": "runs/fixture-curation/fixture-curation-2026-06-05T104440Z",
"sessionJsonl": "runs/fixture-curation/fixture-curation-2026-06-05T104440Z/session.jsonl",
"transcriptMarkdown": "runs/fixture-curation/fixture-curation-2026-06-05T104440Z/transcript.md",
"reportJson": "runs/fixture-curation/fixture-curation-2026-06-05T104440Z/report.json",
"graphSnapshotJson": "runs/fixture-curation/fixture-curation-2026-06-05T104440Z/graph-snapshot.json"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale graph artifact field name

Medium Severity

Committed probe report.json files still expose artifacts.graphSnapshotJson pointing at graph-snapshot.json, while the same change retires that naming in .fixtures/README.md and probe writers persist graphOverviewJson and graph-overview.json. Portable path edits alone leave reference runs on a different contract than new runs and docs.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f9274fc. Configure here.

}
}
Loading
Loading