Repository navigation
refactor(layers): flip the output seam — view bridge moves into features/feed (#493 PR-3) - #503
Merged
Merged
Conversation
…res/feed (#493 PR-3) rendering/view/ ceases to exist: - ledgerFeedItems.ts (+ test) and useLedgerFeedItems.ts move to features/feed/ledger/. Every one of the bridge's imports is now legal: FeedRenderItem / VisibleDecision / groupSemanticActivity are same-layer siblings; RenderLedger/RenderRow come from rendering/model (feed -> rendering, the sanctioned direction). The react import leaves rendering/ entirely — the decide layer is now framework-free. - groupSemanticActivity STAYS feed-side (plan D3): issue PR-2 wanted it in rendering/view, but with the whole view stage relocating here that would have been round-trip churn; presentation grouping is render-layer. Replay harness un-inverted by injection: - recordedSession.ts no longer imports the bridge. New seam: ReplayOptions.projectItems (ReplayItemsProjection) — the harness runs slices -> adapter -> ledger and stops at RenderLedger, the decide layer's own output; projecting rows into feed items is the render layer's job, injected by callers. ReplayTick.feedItems is unknown[] (empty when no projector given). - recordedSession.test / invariants.test / recordingCorpus.test inject the REAL production bridge from features/feed/ledger, so full-stack coverage (incl. the #239 dropped-candidate accounting) is unchanged — test files are outside the layer contract by design. The #493 acceptance now holds and is grep-verified: grep -rn "@renderer/features|@renderer/workspace|from 'react'" \ src/renderer/src/rendering/ --include='*.ts' | grep -v '\.test\.' # -> empty grep -rn "@renderer/(workspace|features|app-state)|from 'react'" \ src/renderer/src/session-runtime/ # -> empty Three folders, one-way: session-runtime (ingest) <- rendering (decide) <- features/feed (render); the ledger consumes exactly RuntimeRenderInput and emits exactly RenderLedger/RenderRow[]. Gates: tsc node+web clean, vitest 467/467, remote-client build OK. Stack is linear on origin/main (fast-forward merge). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rojection, refresh moved-path comments Two Claude + two Codex reviewers over the full stack; zero blockers. The two actionable findings: - projectItems is now a REQUIRED ReplayOptions field (codex finding): an omitted projection was indistinguishable from "projected with zero drops", silently vacating the #239 dropped-candidate invariant for that run. Required-field = the forgotten-injection mistake is a compile error, not a green-but-hollow test. - Stale comment path pointers to pre-#493 module locations refreshed (claude finding): reconstructSlices mirror-source block, Feed.tsx ghost notes, streamingWriteInput, observations/{ghosts,semantic}, providerConfig, main/{ghostJournal,index}. Navigation pointers are exactly what the CLAUDE.md comment policy exists to keep accurate. Codex's remaining finding — the phone's hard-coded lastJsonlEntryAt: 0 — pre-exists this stack (the old cast hid the same value) and needs real committed-tail plumbing on the wire protocol; deferred to a follow-up rather than smuggled into a behavior-preserving refactor. Gates: tsc node+web clean, vitest 467/467. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Juliusolsson05
changed the base branch from
refactor/render-input-contract
to
main
July 9, 2026 08:24
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 3 of 3 for #493, stacked on #502 (which stacks on #501). Plan:
docs/superpowers/plans/2026-07-09-layer-isolation.md§4.What
rendering/view/dissolves.ledgerFeedItems.ts(theRenderLedger → FeedRenderItem[]bridge) +useLedgerFeedItems.ts(the producer hook) move tofeatures/feed/ledger/. Every formerly-inverted import becomes legal:FeedRenderItem/VisibleDecision/groupSemanticActivityare now same-layer siblings, andRenderLedger/RenderRowflow feed → rendering, the sanctioned direction. Thereactimport leavesrendering/entirely — the decide layer is now framework-free.groupSemanticActivitystays feed-side (plan D3): issue PR-2's "move it into rendering/view" and PR-3's "move the view into feed" contradicted each other; the end state wins — presentation grouping is render-layer.Replay un-inverted by injection. The harness (
recordedSession.ts) now stops atRenderLedger— the decide layer's own output — and takes an injectedprojectItems: ReplayItemsProjectionfor the feed-item stage. The three replay/corpus tests inject the REAL production bridge fromfeatures/feed/ledger, so full-stack coverage (including the #239 dropped-candidate accounting) is byte-for-byte what it was; test files are outside the layer contract by design.Issue #493 acceptance (verified one-off, per the issue's own "grep, not a CI lock")
Three folders, one-directional:
session-runtime/(ingest) ←rendering/(decide) ←features/feed/(render). The ledger consumes exactlyRuntimeRenderInput, emits exactlyRenderLedger/RenderRow[], and the bridge toFeedRenderItemis feed-owned.Gates
tsc node+web clean · vitest 467/467 · remote-client build OK · stack is linear on
origin/main(merge is a fast-forward, so the per-PR gates ARE the merge-simulation).After the stack merges: close #493 quoting the greps; small follow-up refreshes
docs/rendering/rendering-system.md's where-to-look index for the new paths.🤖 Generated with Claude Code