Lossless Changelog
product

augment-it's response-reviewer remote (localhost:3005) is in a good place — the triage surface for the structured-output pattern stabilizes after many commits

Over the last two days the response-reviewer microfrontend at localhost:3005 went from a basic review UI to the triage surface for every pack augment-it will ever run. The structured-output extension that landed on 5/25 was the seam; what followed was a fast sequence of commits — many attempts, two scraps, real-data smokes — that turned the remote into a per-row, per-pack triage cockpit with inline correction (URL), human-supply (display_name), and entity-name cleanup (the row's identity column) all riding the same response.set_structured subject. Two emergent-requirements rounds also got captured into the Packs-and-Bundles blueprint so future packs across the Lossless family inherit the discipline. The SearXNG-substrate decision is filed as an issue but deliberately not yet executed — the remote is good enough that the next session can start somewhere new.

Michael StatonMusic Editoraugmented with Claude Code on Claude Opus 4.7 (1M context)

Why care?

augment-it's federated shell hosts a small constellation of microfrontends — record-collector, prompt-template-manager, request-reviewer, response-reviewer, pack-runner, chat. Each one runs standalone on its own port for debuggability and gets mounted into the shell at runtime via Module Federation. localhost:3005 is the response-reviewer remote, and over the past two days it became the surface every pack in the system lands on — not just the existing prompt-template-based enrichments but the new socials packs (common-six, now common-seven with Instagram) that exercise the structured-output extension.

The work to get there was not linear. The git log shows two attempts that ended in scraps (attempt(plan, scrap, redesign, social-search): socials column pivot + Run-entity plan + clarification-gate scope + cleanup script), a foundation-dataset smoke that surfaced eleven emergent UX requirements the upfront blueprint hadn't anticipated, and a Svelte 5 effect-cycle trap that needed a sync-read / async-write fix before the by-record view stayed coherent across re-renders. Most of those are now codified — not as a one-off log of debugging, but as patterns the next pack/bundle implementation across the Lossless family will inherit.

The reason this matters at the ai-labs tier (not just inside augment-it) is that response-reviewer is the triage cockpit pattern the rest of the AI-product tree will copy. memopop-ai's analyst-visible run report has a triage shape coming. dididecks-ai's deck-authoring loop will need a per-slide review surface once the LLM-drafting paths stabilize. The response-reviewer commits are where the pattern got worked out against real data, and the Packs-and-Bundles blueprint is where the lessons got promoted out of the project so the next implementer doesn't re-discover them.

What's new at localhost:3005

The remote on its own port at http://localhost:3005 (and mounted in the shell) now does the following things that it didn't do 48 hours ago:

  • By-record (per-row) triage view. Responses group by the row's canonical entity name (Prospect, Organization — whichever column the schema resolves through entityFieldFor()). Inside each row group, responses cluster by pack so the user can see all six (now seven) social searches for one prospect at once. Alphabetical sort by entity name keeps the list stable across re-runs.

  • Inline URL editing for correction + human-supply. Wrong URL? Edit it in place. Pack didn't find anything but you know the answer? Type it in. Both paths fire response.set_structured on the same subject — the store doesn't care whether the source is a connector or a human. A source_metadata.url_human_edited: true marker fires so audit/provenance survives.

  • Inline display_name editing alongside the URL. Same input idiom — borderless-by-default, hover reveals a border, focus turns it into a proper input. Tracked through a separate nameDrafts $state record so URL edits and name edits save independently.

  • Stale-companion-field discipline in the store, not the UI. services/response-store/src/store.ts now detects "URL changed but display_name and snippet weren't also patched" and auto-derives sensible defaults (display_name → new URL hostname stripped of www., snippet → cleared). The original Tavily fields (tavily_raw_url, etc.) are preserved additively. The UI doesn't have to remember to clear; the store enforces the invariant.

  • Inline entity-name editing in the by-record header. When the researcher needs to clean up the row's name to make subsequent pack runs work ("Accelerate the Future (ACH, GW Match)" → "Accelerate the Future"), they edit the row's identity field inline in the header. entityFieldFor() returns both the resolved column name and the value so the header knows which row.fields key to write back to. On blur, row.update fires and rows re-pull so the canonical value re-sorts the group order.

  • Paired authoring + invocation surfaces. Authoring mode and invocation mode are now peers, not modes of the same toggle — same component family, different default postures. Filter constrains scope rather than hiding rows; default is ready-to-fire.

  • Write-back to row.fields.socials. Pack responses that resolve land back on the row, not just in the response store. The row becomes the canonical place to read enrichment downstream; the response store remains the audit trail.

The cumulative effect: the remote is a researcher's per-row cockpit. Open it, fire common-seven against the focused record set, watch responses arrive, correct or supply as needed, move to the next row. No leaving the surface. No round-tripping through CSV. No CLI.

What's new at the pattern tier

Two context-v documents got the lessons promoted out:

  • context-v/blueprints/Packs-and-Bundles-Pattern.md (semver bumped 0.0.0.2 → 0.0.0.3) gained a new section, Triage Surface UX Requirements (emergent). Eleven pattern-level codifications future pack/bundle implementations across the Lossless family must honor: authoring vs invocation as peers, default to ready-to-fire, filter constrains scope, records-not-cells framing, per-record triage discipline, inline correction + human-supply on one surface, stale-companion-field handling on edit, provenance markers (human_entered / url_human_edited / tavily_raw_url preserved), live progress on long fan-outs, cross-pair state sync via localStorage + window event, federation-time debuggability (standalone-remote-port fallback + CORS un-scrubbing as the proper follow-up), and the Svelte 5 effect-cycle pattern (sync-read / async-write traps, fix by reading past the first await).

  • context-v/plans/Run-as-First-Class-Operation.md (semver bumped 0.0.0.1 → 0.0.0.2) gained a Surfaced from smoke (2026-05-25/26) section — same items but in journey form, each tagged ✅ shipped / 🔧 partial / ⏳ pending with the commit hash that landed it. Two different future-readers, two different shapes: blueprint is the durable institutional pattern; the plan section is the audit trail.

  • context-v/issues/Search-Providers-as-First-Class-SearXNG-Default.md is filed but deliberately not executed. It documents the symptom (Tavily missing obvious social profiles that manual googling finds in seconds), the three-issue diagnosis (thin RAG index for social pages, over-constrained query construction, hardcoded coupling to one connector), the decision (SearXNG primary for social, Tavily stays as peer connector for future content-RAG packs like deep-research), and the architectural goal: separate pack concerns from connector concerns. A connectors/ directory with a common interface and a discriminated-union PackConfig that names which connector each pack uses. Acceptance criterion: ≥60% of previously-not_found social rows resolve on re-fire. Out-of-scope: tearing out Tavily, per-pack quality scorecards.

How we got here — the commit arc

In rough chronological order (oldest first), the ten commits that constitute "getting the remote in a good place":

  1. 288ecec — structured-output extension on the response surface. The seam. response-store, response-reviewer, shared-ui, theme, workspace all touched; this is the foundation every later pack lands on.

  2. 38751d3 — first attempt at common-six social packs end-to-end. Real packs hit the new structured-output surface for the first time.

  3. 18dbf94 — socials column pivot + Run-entity plan + clarification-gate scope + cleanup script. Marked "attempt" because the Run-entity plan and clarification-gate ideas got scrapped before they landed; the socials column pivot survived.

  4. 12546ba — row-grouped triage + paired authoring modes + write-back to row.fields.socials. The by-record view becomes the primary triage shape; pack responses land back on the row.

  5. 4a94f77 — inline URL editing in by-record view. Correction + human-supply paths unified on the same response.set_structured subject.

  6. 21a520a — stale-companion-field discipline + display_name inline editing + emergent-requirements capture. The 11-item blueprint section + the plan's surfaced-from-smoke section get written here.

  7. 7cf8f70 — editable entity-name + instagram pack + SearXNG issue doc. Entity-name cleanup closes the by-record loop (the row's identity column is editable too); common-six becomes common-seven; the SearXNG architectural decision is filed as an issue for the next session.

Two intermediate attempts (the Run-entity plan and the clarification-gate scope) were redesigned mid-stream rather than shipped — the attempt(...) prefix on those commits is honest about that.

What this enables across the tree

  • The triage cockpit pattern is now copyable. memopop-ai's analyst-visible run report (the McKinsey-style URL-drift recovery surface is the canonical test case) can copy the by-record / paired-authoring / inline-correction shape directly. The blueprint codification is the contract; the response-reviewer implementation is the worked example.

  • dididecks-ai's per-slide review loop has a precedent. When the LLM-drafting paths for chroma-decks / calmstorm-decks need a human-in-the-loop triage surface, the response-reviewer pattern is the reference. Different domain (slides vs. enrichment responses), same shape (per-record group, inline correction, human-supply on the same subject, provenance markers in the store).

  • The connectors/ refactor has a clear acceptance criterion before it starts. ≥60% of previously-not_found social rows must resolve on re-fire through SearXNG. That number can be measured against the foundation dataset that drove the emergent-requirements round — the test data already exists.

What's still loose at this tier

  • The SearXNG substrate isn't actually wired yet. The issue doc names the eight-step proposed work; none of it has shipped. Today's packs still hardcode a Tavily-shaped query schema. The remote is good enough to defer this to a deliberate session.

  • The by-record view shows responses from every record set, not just the focused one. After a v4 promote, the parent set's old prompt responses still appear with row_ids the user doesn't recognize. The current entity-name fallback to row_id is the visible symptom. Fix belongs in the by-record grouping path — record-set scope filter chip + only show responses whose row_id resolves through rowsByRowId for the focused set.

  • No live progress bar on long pack-fan-out runs. Named in the blueprint as a UX requirement; not yet implemented. The user fires common-seven against 50 prospects and the only feedback is responses arriving.

  • needs_clarification as a first-class row state. Surfaced in the smoke; not yet modeled.

  • The proper page-title fetch for URL edits. Today the auto-derived display_name is just the hostname; ideally an HTTP fetch + <title> parse on URL edit would do better. Defer until either the user explicitly asks or the SearXNG migration makes it free.