Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a9171f2
FE-737: Start web shell frontier
lunelson May 21, 2026
6ecc356
FE-737 reject non-linear transcript JSONL
lunelson May 21, 2026
3acf9df
FE-737 fail fast on non-linear session RPC
lunelson May 21, 2026
514c01e
FE-737 block TUI branch flows
lunelson May 21, 2026
dbf2bb3
FE-737 clarify web-shell slice status
lunelson May 21, 2026
c0ae135
FE-737 enforce strict transcript reader shape
lunelson May 21, 2026
fec7073
FE-737 centralize linear exchange projection
lunelson May 21, 2026
0a849d3
FE-737 add minimal web HTTP shell
lunelson May 21, 2026
5ef039b
FE-737 add web websocket RPC bridge
lunelson May 21, 2026
0781833
FE-737 render workspace snapshot in React shell
lunelson May 21, 2026
6bdfc28
FE-737: Share JSON-RPC protocol helpers
lunelson May 22, 2026
4a47c3c
FE-737: Add WebSocket RPC transport adapter
lunelson May 22, 2026
18d82e6
FE-737: Persist browser RPC client connection
lunelson May 22, 2026
bffad46
FE-737: Serve canonical built web shell
lunelson May 22, 2026
0d8ccda
FE-737: Stabilize React web runtime
lunelson May 22, 2026
22afcdb
FE-737: Target session projections explicitly
lunelson May 22, 2026
b7bfe88
Harden explicit session projection reads
lunelson May 22, 2026
9b2f65b
Share JSON-RPC dispatch failures
lunelson May 22, 2026
11ab8ca
Harden browser RPC protocol failures
lunelson May 22, 2026
c30c6cb
Constrain web asset paths
lunelson May 22, 2026
ecd668a
Reuse shared JSON-RPC response type
lunelson May 22, 2026
ec2f985
Render read-only web transcript projection
lunelson May 22, 2026
1123508
Share session binding codec
lunelson May 22, 2026
a0fd9dd
Require cwd for RPC handlers
lunelson May 22, 2026
93253d2
Treat browser RPC socket errors as terminal
lunelson May 22, 2026
4d90bbb
Render transcript display projection
lunelson May 22, 2026
c8d986d
Record M3 smoke postconditions
lunelson May 22, 2026
65523f2
Validate explicit session self-description
lunelson May 22, 2026
fc264ca
Render elicitation prompt display rows
lunelson May 22, 2026
1cfb88b
Tie off web shell M3
lunelson May 22, 2026
72a9734
add ln-judo-review skill
lunelson May 22, 2026
f5a26ea
Share Brunch session envelope reader
lunelson May 22, 2026
ab28054
Use explicit transcript custom entry classifiers
lunelson May 22, 2026
1cbd57b
Use typed web session projection target
lunelson May 22, 2026
64406a9
Sync web shell closeout
lunelson May 22, 2026
eab91df
Restore ln-judo-review skill
lunelson May 22, 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
107 changes: 107 additions & 0 deletions .agents/skills/ln-judo-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
name: ln-judo-review
description: "Run a strict maintainability review that demands code-judo restructuring — deletions over rearrangements, not local cleanup. Use as an opinionated sibling of ln-review when a PR feels like it preserves incidental complexity, when a file is about to cross a healthy size boundary, or when spaghetti branching is creeping into existing flows."
argument-hint: "[area of codebase to review, or 'recent' for recently changed files]"
---

# Ln Judo Review

Look for **code judo**: restructurings that preserve behavior while making the implementation dramatically simpler, smaller, and more direct. Prefer paths that *delete* complexity over paths that *rearrange* it. The right reframing makes the change feel inevitable in hindsight.

This is a strict maintainability audit, not a cleanup pass. Do not stop at "this could be a bit cleaner." Do not rubber-stamp working code that leaves the codebase messier. Use the repo's pre-release posture: retire stale concepts, obsolete code paths, and compatibility scaffolding rather than protecting them.

## Input

What to review: $ARGUMENTS

If "recent" or unspecified, focus on recently modified files. Read `memory/SPEC.md` for current lexicon and architecture; read `memory/PLAN.md` if the area touches active frontier work.

## What to look for

Apply Ousterhout's depth test: small interfaces hiding significant complexity. Flag thin wrappers, identity abstractions, and pass-through helpers that add indirection without buying clarity — if deleting the module makes complexity vanish, it was pass-through structure.

Information hiding (Parnas): feature logic stays behind its own boundary. Flag feature-specific branches leaking into shared paths, and feature checks scattered across general-purpose modules.

Make invalid states unrepresentable (Yaron Minsky): explicit typed models over loose objects, casts, `any`/`unknown`, and silent fallbacks that paper over unclear invariants. If a branch relies on silent fallback, ask whether the boundary should be made explicit instead.

Ubiquitous language and canonical layer (Evans): logic lives where the concept already lives. Flag bespoke helpers that duplicate canonical utilities, and logic landing in the wrong package or module.

Make the change easy, then make the easy change (Beck): if the diff feels tangled, the surrounding code probably needs a small preparatory refactor first.

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

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

- **1000-line threshold**: a PR that pushes a file from under 1k to over 1k lines is a presumptive blocker. Ask whether the file should be decomposed first. Waive only with a clear structural reason and visible internal organization. Modules that move together should live together — but a single sprawling file is rarely a deep module.
- **No ad-hoc branching in unrelated flows**: new conditionals, special cases, or one-off booleans bolted onto existing paths are a design problem, not a stylistic nit. Push the logic behind its own abstraction, helper, state machine, or policy object.
- **No unnecessary orchestration**: if independent work is needlessly serialized, ask for parallel execution when it also simplifies the flow. If related updates can leave state half-applied, push for an atomic structure.

### Primary question for every change

> Is there a code-judo move here that would delete whole categories of complexity — entire branches, helpers, modes, layers — rather than rearrange them?

If yes, name it. Do not settle for a cleaner version of the same messy idea when a much simpler idea is plausible.

## Tone

Direct, serious, demanding. Not rude. Do not soften major maintainability issues into mild suggestions. Worked examples of the register:

- `this pushes the file past 1k lines. can we decompose this first?`
- `this adds another special-case branch into an already busy flow. can we move this behind its own abstraction?`
- `this works, but it makes the surrounding code more spaghetti. let's keep the behavior and restructure the implementation.`
- `this feels like feature logic leaking into a shared path. can we isolate it?`
- `this abstraction seems unnecessary. can we just keep the direct flow?`
- `why does this need a cast / optional here? can we make the boundary more explicit instead?`
- `this looks like a bespoke helper for something we already have elsewhere. can we reuse the canonical one?`
- `i think there's a code-judo move here that makes this much simpler. can we reframe this so these branches disappear?`
- `this refactor moves complexity around, but doesn't really delete it. is there a way to make the model itself simpler?`

## Output

Present findings as numbered candidates, prioritized in this order:

1. Structural regressions and missed code-judo opportunities
2. Spaghetti / branching complexity growth
3. Boundary, abstraction, and type-contract problems
4. File-size and decomposition concerns
5. Modularity and legibility

Prefer a small number of high-conviction comments over a long list of cosmetic nits. Use ln-review's compact form:

```md
## Judo Review: [area]

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

### Approval bar

Do not approve on "behavior is correct" alone. These are presumptive blockers unless the author justifies them clearly:

- a visible code-judo move was left on the table
- a file crossed the 1000-line threshold
- ad-hoc branching tangled an existing flow
- feature checks got scattered across shared code
- an unnecessary abstraction, wrapper, or cast-heavy contract added indirection
- a canonical helper got duplicated, or logic landed in the wrong layer

If any of those hold, leave explicit, actionable feedback and push for a cleaner decomposition.

## Routing

After presenting findings, present these options to the user (use `tool-ask-question`):

| # | Label | Target | Why |
| --- | -------------------------- | ------------- | ------------------------------------------------ |
| 1 | Scope a fix | `ln-scope` | A finding warrants a planned slice |
| 2 | Explore a deepening design | `ln-design` | A code-judo candidate needs seam/interface design first |
| 3 | Plan a refactor | `ln-refactor` | Multiple findings need coordinated restructuring |
| 4 | Back to triage | `ln-consult` | Review complete, no immediate action needed |

Recommended: **3** if multiple structural regressions stack up, **2** if the dominant finding is a code-judo deepening candidate, **1** for a single concrete fix, **4** otherwise.

---
*Sibling of `ln-review` with a harsher posture for strict maintainability audits. Distilled from an external thermo-nuclear-code-quality-review prompt; activators aligned with the `ln-*` family vocabulary.*
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
build
dist
dist-web
dist-ssr
*.local

Expand Down
10 changes: 10 additions & 0 deletions archive/docs/archive/PLAN_HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,13 @@ Archived out of `memory/PLAN.md` during `ln-sync` so the live plan keeps only th
- [2026-05-08] FE-698 prompt scenario execution probe — Web-research prompt scenarios can now execute through an injected fakeable model adapter and serialize `succeeded` / `failed` execution results with raw output or deterministic error text, while no-provider artifacts remain deterministic `not-run` snapshots. Structured parsing is explicitly `not-applicable` for this prose-only web-research path. Verified: `npm run verify`. Watch: real provider adapters, Pi, web tools, CLI/UI, persistence, and mutating Brunch handlers remain out of scope for this foundation slice.
- [2026-05-06] Multi-chat substrate + reconciliation needs (FE-697) — `chat` table with one interview chat per spec, nullable `turn.chat_id`, `specification.primary_chat_id`, mirrored `chat.active_turn_id`, plus the `reconciliation_need` queue with directed source/target items, narrow `kind`/`status`, partial unique index on open rows, cascade FK. Spec creation inserts spec + interview chat in one transaction; `advanceHead` is transactional. No user-visible change. Verified: `npm run verify` (673 tests) plus manual fixture playback (39 specs / 81 turns / dual-pointer equivalence). A82 / A83 validated for Phase 1.
- 2026-05-20 — **Pre-POC archive and reseed** — razed pre-POC implementation, archived legacy docs and planning memory under `archive/`, tagged `next-baseline`, and reseeded `memory/SPEC.md` and `memory/PLAN.md` from the three canonical POC architecture docs. Phase 3 infra bootstrap was folded into `walking-skeleton` rather than remaining an independent frontier.

## 2026-05-22 Sync archive

Archived out of `memory/PLAN.md` when `web-shell` closed and the live frontier advanced to `graph-data-plane`.

- 2026-05-22 — **web-shell judo review fixes** — Session projection reads share a canonical Brunch session envelope, prompt-side custom-entry classification uses an explicit allowlist, and the React shell builds transcript query params from a typed session projection target without non-null assertions. Verified: `npm run verify` after each slice.
- 2026-05-22 — **web-shell tie-off queue** — Explicit session projection rejects ambiguous self-description (`brunch.session_binding` duplicates, missing/duplicate Pi headers, binding/header session-id mismatch); `session.transcriptDisplay` includes displayable transcript-native `brunch.elicitation_prompt` rows; M3 browser-open smoke debt was adjudicated as environment-blocked after direct HTTP/WebSocket postconditions passed.
- 2026-05-22 — **web-shell hardening slices** — Shared JSON-RPC protocol helpers, `ws`-backed `/rpc` transport, persistent browser RPC multiplexing, traversal-safe static asset serving, stable React runtime ownership, and explicit read-only session projection by durable session id landed without REST product reads or connection-as-session semantics.
- 2026-05-21 — **web-shell initial slices** — Linear transcript policy hardening landed before browser consumption, transcript readers fail fast on non-linear Pi JSONL, the minimal native web HTTP shell and WebSocket RPC bridge came online, and the React shell rendered `workspace.snapshot` chrome via one WebSocket RPC client.
- 2026-05-20 — **walking-skeleton** — Brunch launches through a pi-backed TUI boot path with coordinator-first spec gating, project-local `.brunch/` state, self-describing Pi JSONL sessions, same-spec `/new`, persistent chrome through pi's extension widget seam, a bin shim, and the store-only runbook checker. Verified: `npm run verify`, manual TUI smoke, automated TUI/coordinator tests, and runbook oracle.
6 changes: 6 additions & 0 deletions docs/praxis/graphite-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ Use **gt** (via `/cli-graphite`) for stack-aware operations:

**Why the split matters:** `gt` commands maintain Graphite's internal metadata about branch parentage. Using raw `git checkout -b` or `git rebase` bypasses this metadata and can corrupt the stack. Commits and reads don't touch stack metadata, so plain git is fine for those.

## Frontier setup

Every new plan-level frontier item starts with a Linear issue in the **Frontend (FE)** team and the **brunch** project, unless the user or current plan explicitly says otherwise. Do not parent new post-release issues under FE-531; only set a parent when the user or `memory/PLAN.md` names an active parent.

Then create or track the corresponding Graphite branch. If another tool creates a raw git branch first, immediately `gt track --parent <parent-frontier-branch>` and rename to the standard branch format if needed.

## Branch granularity

- Branch / Linear-issue granularity follows the containing `memory/PLAN.md` frontier item.
Expand Down
12 changes: 12 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Brunch</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/web-client/main.tsx"></script>
</body>
</html>
Loading
Loading