← Corpus / augment-it / exploration
augment-it has outgrown one flow — ROTATION is the CSV-augmentation pipeline's shape wearing a general-purpose name, and strategy-curator's promotion to its head is a splice, not a fit
augment-it started as one thing — augment a CSV, row by row — and ROTATION (shell/src/remotes.ts) is that flow's shape, hardcoded as THE numbered nav. Every use case since (DB-canonicalization for reach-edu's CRM exit, per-org/person corpus curation, now domain/thesis curation for humain-vc) has been reconciled onto that one array instead of recognized as its own flow. Strategy Curator's 2026-07-06 'promotion to the head of ROTATION' is the symptom: a domain-curation session doesn't hand off into recordCollector, but ROTATION was the only navigation primitive that existed, so that's where it landed. The fix isn't a bigger ROTATION array — it's a 'what are you trying to do?' front door that picks which flow mounts, so a use case that isn't CSV-row augmentation stops being forced to pretend it is.
- Path
- explorations/Augment-It-Has-Outgrown-One-Flow-The-Choose-A-Flow-Front-Door.md
- Authors
- Michael Staton
- Augmented with
- Claude Code on Claude Sonnet 5
- Tags
- Exploration · Augment-It · Shell · Rotation · Flow · Strategy-Curator · Thesis-Curator · Record-DB-Resolver · Workspaces · Humain-VC · Multi-Flow · Front-Door · UX-Architecture
augment-it has outgrown one flow
The observation — why this exists
2026-07-06, mid-session: after wiring didi.sh actor attribution end to end, the
operator opened http://localhost:3017 expecting to see the strategy-curator
in context (auth badge, workspace switcher) and instead saw the bare remote —
no chrome, because :3017 is apps/strategy-curator’s own standalone
rsbuild dev server, not the shell. The proximate fix is trivial: go to
:3100 instead. But the operator’s actual point, in their own words:
“The standard augment-it flow doesn’t have the corpus curator. It’s an app we made to plug a hole. It is very handy though. We also kept running into workflows that don’t fit the current shared shell header of 1-2-3-4.”
That’s not a bug report. It’s a description of an architecture that has quietly forked into multiple flows while the shell still presents exactly one numbered sequence.
How we got here — the actual history
Reconstructed from the operator’s account plus the git/context-v trail:
- CSV augmentation (the original, proven flow). Upload a CSV, author
prompts, run them per row, triage responses, promote a snapshot. This is
recordCollector → promptTemplateManager → requestReviewer → responseReviewerin spirit — today’sROTATIONminus the parts added later. It works. It shipped first because it was the whole product at first. - An event CSV needed dynamic person↔org iteration. reach-edu wanted off
their CRM entirely, so the natural move was to write canonical records to
SurrealDB directly — with CRM-specific and client-specific flags — rather
than bolt a migration script onto the side. This is
record-db-resolver(spec: [[../specs/Record-DB-Resolver]]): match-or-create against canonicalorganizations/persons, additive, one row at a time. It got folded intoROTATIONas step 3 (recordDbResolver— “bridge — reconcile records to canonical orgs”) — a reasonable fit, because it still operates per-CSV-row. - Organizations and some individuals warranted their own corpora — links
and downloads gathered independent of any one CSV row. This is where
content-ingest, thesources/source_usages/domainsSurrealDB tables, and the whole corpus-curation substrate ([[../specs/Funder-Content-Corpus-Workflow]]) came from. Still record-adjacent at this point — corpus entries hung offrecord_id. - reach-edu needed corpora for “strategies” — cases to support or flesh
out potential fundraise directions, decoupled from any single CSV row.
This is
strategy-curator([[../specs/Strategy-Curator-Entry-Point-for-Augment-It]]): pick adomain(type=‘strategy’), gather sources against IT, not against a record. This is the fork. The unit of work stopped being a record row and became a domain.strategy-curatorhad no natural slot inROTATION— it isn’t a step in the CSV pipeline, it’s the entry point to a different pipeline — so it shipped as a standalone remote, reachable only by its own dev port. - humain-vc now wants the identical shape for “theses” — corpora that
will become decks via
dididecks-aidownstream. This is Build-Order step 5 ([[../plans/Build-Order-Humain-VC-Unlock-Flow]]): make the curator’sdomain_typeworkspace-derived instead of hardcoded'strategy', so humain-vc reads “Thesis” and reach-edu keeps “Strategy.” Same app, second client, second domain-type — proof the domain-curation flow is now a first-class citizen, not a one-off. - 2026-07-06: strategy-curator promoted to the head of ROTATION
(commit
1d4acc0,shell/src/remotes.ts:34-42, +4/-2 lines). This gave the curator a reachable, chrome-having entry point for the first time — genuinely useful, unblocks Flow 1’s “primary surface” framing in the Build-Order plan. But look at what the diff actually did: it spliced a domain-curation entry point onto the front of an array whose remaining six members (recordCollector→recordDbResolver→augment→recordsSurface→responseReviewer→enhancedRecordsList) are all CSV-row-augmentation steps. Nothing in strategy-curator hands off intorecordCollector. The “numbered flow” is now a lie for one out of seven steps — you don’t walk from Strategy Curator into Record Collector as part of one continuous task.
The actual architectural collision
ROTATION (shell/src/remotes.ts:34-42) is one hardcoded array. It is
simultaneously trying to be:
- The CSV-row-augmentation pipeline’s step order (its original and still-true shape for 6 of 7 members).
- THE numbered navigation for the whole shell (its assumed role — every new capability gets a slot, because a slot is the only way to be reachable with chrome).
Those two roles were the same thing when augment-it did one thing. They
aren’t anymore. Three distinct flows exist in the product today, and only
one of them is what ROTATION actually models:
| Flow | Unit of work | Apps | In ROTATION today? |
|---|---|---|---|
| A — CSV Row Augmentation | one CSV row | recordCollector, recordDbResolver, augment (PTM⇄PackRunner⇄SortFilterLens), recordsSurface, responseReviewer, enhancedRecordsList | Yes — this IS what ROTATION models |
| B — Canonical DB Reconciliation | one person/org | recordDbResolver | Embedded inside Flow A (step 3) — also directly useful standalone once reach-edu is fully off their CRM |
| C — Domain/Thesis Corpus Curation | one domain (strategy or thesis) | strategyCurator, content-ingest’s corpus tables, (soon) dididecks-ai downstream | Spliced onto Flow A’s front as step 1, despite sharing no data spine with steps 2-7 |
Flow C doesn’t key off record_uuid the way Flow A does — it keys off
domain_type:domain_slug. There is no natural “next step” from Strategy
Curator into Record Collector; an operator finishing a thesis-curation
session doesn’t want to walk into CSV upload. The promotion made the curator
reachable, which was worth doing, but it didn’t make it belong where it
landed.
A second, smaller collision: three senses of “Flow”
Worth naming so a future session doesn’t conflate them (surfaced while researching this):
- Shell “Flow” —
ROTATION, the numbered nav sequence (FlowWidget.svelte, “Flow 1”, “Flow step 1” in code comments). - Build-Order “Flow 1” — a whole user-journey for humain-vc: auth →
workspace → thesis corpus, spanning both
id-didi-shandaugment-it([[../../context-v/plans/Unlock-Humain-VC-Team-Access-To-Augment-It]]). - This exploration’s “flow” and the sibling exploration’s “operator-built flow” — a top-level use-case (this doc) or a verb-sequence-against-a-view (the sibling doc) — neither is the shell’s numbered nav.
Same word, three referents, three different docs. Not urgent to rename, but worth a one-line disambiguation wherever “Flow” appears without qualification.
Relationship to the sibling exploration
[[Operator-Built-Flows-Beyond-The-Universal-Pipeline]] is about the SAME underlying tension — “the universal pipeline is a dud outside its happy path” — but one layer down: it’s about customizing granularity within Flow A (which records, in what order, with what verbs). This exploration is one layer up: which flow is even active. They compose cleanly:
- This doc’s “choose a flow” front door picks Flow A, B, or C.
- Once Flow A is chosen, the sibling doc’s Tiers 1-4 (saved views → named playbooks → agent-composed view-specs → deferred flow-editor) apply inside Flow A, same as today.
- Flow C (domain/thesis curation) might eventually want its own Tier-1-style saved views (“my open theses,” sorted by source count) — same pattern, different flow. Not scoped here; noted for later.
The design space — climb only as needed, same ethos as the sibling doc
Option 1 — Do nothing; keep splicing (status quo)
Every new use case gets folded into ROTATION wherever it fits best, or
shipped standalone if it doesn’t fit at all. Cheapest, and it’s why
strategy-curator exists and works today. Cost: ROTATION keeps meaning less
as it grows (it’s already lying for 1 of 7 members); each new flow that
doesn’t fit either gets awkwardly spliced in (repeat 2026-07-06’s move) or
stays a standalone-port app operators have to remember, as happened today.
Option 2 — A header-level “jumbo popdown,” not a pre-auth front door (recommended direction, corrected 2026-07-06)
Revised after operator feedback: the original draft of this option proposed a pre-auth landing screen (sign in → pick a flow → mount). That’s the wrong shape for right now — with exactly two users (Michael, Aniel), gating flow-choice behind auth machinery is complexity with no payoff yet. The corrected, much lighter shape:
Use the existing “jumbo popdown” convention — a large, content-rich
dropdown menu triggered from the header, documented at
astro-knots/context-v/blueprints/Jumbotron-Popdown-Patterns.md and
implemented (Astro) at
astro-knots/sites/fullstack-vc/src/components/ui/menus/JumboPopdown__*.astro.
Shape per that blueprint: a trigger button with a chevron
(aria-haspopup="menu", aria-expanded), a panel (role="menu",
hidden until opened, hover-open + click-toggle, Esc/click-outside closes)
containing a grid of items — each item a title + one-line description,
6-8 items max. augment-it’s shell is Svelte, not Astro, so this is a
pattern port (same interaction/visual contract, native Svelte
implementation), not a shared dependency — consistent with the
“no shared dependency across ai-labs apps” convention (patterns get
copied/adapted per app, never imported as a package or microfrontend
across dididecks-ai/augment-it/memopop-ai). The shell’s own
WorkspaceSwitcher.svelte is the closest existing analog in augment-it
today, but it’s a compact role="listbox" single-column dropdown — the
jumbo variant is the richer, grid-based sibling for a menu that wants to
say more than one line per item.
Scope for right now: exactly one entry. The popdown ships with a
single item — “Build Corpora” — which mounts strategyCurator as its
own focused surface (no CSV steps trailing behind it, same fix for today’s
:3017 confusion as the original draft: the popdown becomes the on-ramp,
replacing the memorized-port habit). ROTATION itself is untouched — it
keeps mounting as the shell’s default/home state, exactly as today. No
ActiveFlow persistence, no landing screen, no auth-gating: clicking
“Build Corpora” is just a navigation action, same mechanism as any
existing augment-it:navigate event to a non-rotation remote (chat,
packRunner, personEnrichment already work this way).
The “helpful marketing” framing (operator’s words) is a real, but later, upgrade path. Once there’s more than one flow-entry worth surfacing, the popdown’s panel is the natural place for a richer showcase — a vertical carousel of use-cases, each with a short pitch, matching the blueprint’s “content-rich” intent rather than a bare link list. Not needed for a one-item menu; worth revisiting when a second or third “Build ___” entry exists (see Recommendation).
Why this is the right first move, not over-engineering: it’s a single
new header component, no new global state, no backend changes, no
interaction with Step 7’s (still-open) sign-in wall. ROTATION,
FlowWidget, and the composite-slot mechanism are completely untouched.
Cost estimate: small. One Svelte component (JumboPopdown.svelte or
similar, ported from the astro-knots blueprint’s interaction contract),
wired into the shell header next to WorkspaceSwitcher/DidiBadge, one
menu item, one navigate-to-strategyCurator action.
Option 3 — Let each flow be its own top-level shell (defer)
Spin up a second shell instance entirely for Flow C, federation-composed independently. Overkill today — one shell already composes remotes fine; the problem is navigation-model, not composition-model. Would only become worth it if Flow C’s UI needs (theme, layout grid, chat-rail behavior) diverge from Flow A’s, which they don’t yet.
Key considerations
recordDbResolver(Flow B) is genuinely dual-use, confirmed live — it’s step 2 ofCSV_AUGMENTATION_ROTATIONAND the whole point ofEVENT_ATTENDEES_ROTATION(shipped 2026-07-07 as its own flow, “Augment a CSV of Event Attendees”). No collision: the same remote id in two different flows’ rotations resolves independently each time viaslotById()— nothing shares state between the flows beyond the remote itself.- Workspace ≠ Flow.
active_workspace_slug(which client — reach-edu vs humain-vc) is a persisted piece of state; which flow-entry the operator just clicked in the jumbo popdown is not (it’s a one-shot navigate, not a mode the shell remembers across reloads) — at least until there’s a reason to persist it. Keep the two conceptually separate even though only one of them is stateful today. - This directly un-blocks today’s confusion. The reason the operator
went to
:3017is that there was no “curate a domain” on-ramp at:3100to click instead. The popdown’s “Build Corpora” entry is that on-ramp; once it exists, the standalone-port habit has no reason to persist (the remote stays federation-registered and technically reachable standalone, same aschat/packRunner/personEnrichmenttoday, but nobody needs to remember the port). - Doesn’t block Build-Order step 5. Making strategy-curator’s
domain_typeworkspace-derived (humain-vc → thesis, reach-edu → strategy) is orthogonal to which flow-picker button reaches it, and should proceed regardless of when/whether Option 2 ships. - dididecks-ai as the eventual downstream of Flow C. Theses become decks. That hand-off (domain/thesis → deck generation) is itself a candidate future flow or a Flow-C exit action (“build a deck from this thesis”) — not scoped here, but the front-door framing should leave room for it rather than assume Flow C’s endpoint is just “more curated sources.”
Recommendation — sequence
- ✅ DONE 2026-07-07 (superseded the “cheap comment” framing below with
the real thing).
ROTATIONis nowCSV_AUGMENTATION_ROTATION+BUILD_CORPORA_ROTATION(shell/src/remotes.ts), each owned by aFlowDefin the newshell/src/flows.svelte.ts(FLOWSregistry + anactiveFlowsingleton, same constructor-$statepattern aslayout.svelte.ts).strategyCuratorcame back OUT of the CSV-augmentation rotation entirely — the 2026-07-06 splice is undone, not just relabeled. - ✅ DONE 2026-07-06, then extended 2026-07-07 — the popdown is now a
real flow switcher, not a one-item navigate action. Original scope
(below) shipped 2026-07-06:
shell/src/JumboPopdown.svelte+ a single “Build Corpora” item. The next session pushed it to what this doc always pointed at: the popdown moved from the header’s right-side metrics intoheader-left, sitting whereFlowWidgetlives; its items are now generated from theFLOWSregistry (both “Improve a CSV” and “Build Corpora”);FlowWidget.sveltetakesrotation: string[]as a prop instead of importing a constant, so its bubble strip resizes to however many steps the active flow actually has ($derived, not a plainconst);layout.svelte.ts’s focus-index clamping readsactiveFlow.rotation.lengthinstead of a fixedROTATION.length. Picking a flow persists (localStorage, mirroringlayout/workspace) and resets focus to step 1 while preserving layout mode — EXCEPT co-existence, which falls back to peek-flow, sincePAIRINGSare tied to specific CSV-augmentation slot ids and don’t carry meaning across flows. Verified:svelte-checkclean, compiled bundle confirmed servingactiveFlowId/Improve a CSV/Build Corpora/CSV_AUGMENTATION_ROTATION, backend GATE re-checked (unaffected, shell-only change). - ✅ DONE 2026-07-07 — Flow B got its own entry sooner than expected.
The operator asked for it directly: “Augment a CSV of Event
Attendees” —
EVENT_ATTENDEES_ROTATION(recordCollector→recordDbResolver, 2 steps), one newFLOWSentry. Proved the “one array + one entry” cost claim in real time — shipped in minutes, no architecture change.recordDbResolveris now genuinely dual-use across two live flows (step 2 of “Improve a CSV,” and the whole point of this one), not embedded-and-dormant as this recommendation originally assumed. - Still don’t build a general flow-editor, a config-driven flow registry
loaded from disk, or a pre-auth landing experience. Two hardcoded
FLOWSentries is exactly the “climb only as needed” ethos holding — adding a third flow is one array entry + one rotation array, not new architecture. Grow the popdown’s panel (the “helpful marketing” vertical-carousel framing) only when a third flow-entry actually shows up.
Open questions
- Should the popdown grow a second item before or after Build-Order step 7’s sign-in wall lands? No dependency either way today (the popdown doesn’t touch auth), but worth a quick check-in once Step 7 ships in case the two end up wanting shared header real estate.
- Is
strategyCuratorthe right name once the popdown exists and humain-vc reads “Thesis”? The app id and remote label still say “Strategy Curator” everywhere; Build-Order step 5 handles the in-app copy but the code identifier will keep saying strategy. Fine to leave — renaming identifiers is friction without payoff — but worth a code comment noting the id is legacy-named once step 5 ships. - What does Flow C’s own “done for now” checkpoint look like? Flow A
has
enhancedRecordsListas its checkpoint step. Flow C has nothing analogous yet — probably fine until there’s more than one app in Flow C’s rotation.
See also
astro-knots/context-v/blueprints/Jumbotron-Popdown-Patterns.md— the “jumbo popdown” convention this doc’s Option 2 ports into augment-it’s Svelte shell (pattern port, not a shared dependency). Reference implementation:astro-knots/sites/fullstack-vc/src/components/ui/menus/JumboPopdown__*.astro.- [[Operator-Built-Flows-Beyond-The-Universal-Pipeline]] — the sibling exploration, one layer down (customizing granularity within a flow, not choosing which flow).
- [[../specs/Strategy-Curator-Entry-Point-for-Augment-It]] — the spec of record for the Flow-C entry point this doc discusses; already self-titled “An Entry-Point App,” which this exploration takes at face value and argues should get a real front door rather than a ROTATION splice.
- [[../specs/Record-DB-Resolver]] — Flow B’s spec; the “dual-use, embedded in Flow A today” app.
- [[../specs/Workspaces-as-Tenant-Primitive]] — the sibling axis
(
active_workspace_slug) this doc’s flow-navigation is conceptually distinct from, even though the popdown itself carries no persisted state. - [[../plans/Build-Order-Humain-VC-Unlock-Flow]] — step 5 (thesis vocabulary) proceeds independently of this exploration; step 7 (sign-in wall) has no hard dependency on the popdown either way.
- [[../../context-v/plans/Unlock-Humain-VC-Team-Access-To-Augment-It]] —
where “Flow 1” names the whole humain-vc user-journey, the second sense
of “Flow” this doc disambiguates from the shell’s
ROTATION. - [[../../context-v/explorations/Two-Clients-One-Flow-Corpora-Auth-and-Deployment-Converge]] — the ai-labs-level strategic framing this doc’s Flow C is the tactical, shell-navigation-level version of; its Thread 1 (“domain-type becomes operator-facing”) is exactly Build-Order step 5, which this doc treats as proceeding independently of the front-door question.
- 2026-07-06, mid-session — the operator opened
:3017expecting shell chrome, found none, and named the underlying gap in their own words: “we kept running into workflows that don’t fit the current shared shell header of 1-2-3-4.” That’s the origin of this doc.