Manthan × swarm_evolution — review + progressive integration
Goal (operator): *review each feature of Manthan, run the cross-model swarm to
improve it, apply changes progressively, post every iteration. 2 rounds.*
The "swarm" is the conduir cross-model review panel (infra/scripts/ in conduir-evolution-engine): the same packet is fanned
multi-agent-review.sh
out to independent model families (gemini / deepseek / copilot) each with a
distinct lens; findings are then ground-truthed against the live repo before
anything is acted on. Panel output is ~50%+ false-positive by reputation, so
every finding below was re-verified against Manthan's actual code; verdicts that
the panel got wrong are recorded as such.
The thesis under test: *Manthan is a generative substrate (the "churn") with no
selection; swarm_evolution is a selection/fitness/quality-diversity engine
pointed only at code. Wire the second into the first and Manthan can actually
surface the "amrita" instead of accumulating artefacts forever.*
Round 1 — make the substrate alive + open the selection feedback loop
Swarm findings (ground-truthed)
| # | Finding (panel) | Verdict vs live code | Action |
|---|---|---|---|
| F1 | seen_artefact_ids is an unbounded in-memory set, lost on restart (gemini CRIT, deepseek HIGH) | TRUE. loop.agent_loop held set[str], grew forever, reset on restart | R1: bounded SeenCache (LRU). Durable cross-restart cursor = documented follow-up |
| F2 | No selection/pruning; patina computed but never steers the loop (gemini HIGH) | TRUE — but signal.py already ranks artefacts read-side; it just never feeds back into generation | R1: selection.rank_candidates lets agents bias toward high read-side signal (default-off) |
| F3 | patina volume-dominated (log1p(authored) unbounded vs diversity/tenure capped at 1.0) (deepseek MED) | TRUE | Deferred to R2 fitness work (patina is a read-side score; superseded by the fitness vector) |
| F4 | patina counts every lineage relation equally — contradicts earns the same as refines; gameable (deepseek MED) | TRUE for patina; signal.py does bucket relations | R2: relation-weighted engagement in the fitness vector |
| F5 | fetch_active_agents called once at startup; retired/dormant agents run forever (deepseek MED) | TRUE | Documented follow-up (periodic re-fetch / NATS presence) |
| F6 | llm.generate writes empty-text artefacts when gateway returns no content (deepseek MED) | TRUE | Documented follow-up (validate content + finish_reason) |
| F7 | extra_metadata vs metadata column mismatch drops the field (deepseek MED) | FALSE POSITIVE — mapped_column("metadata", JSONB) aliases it correctly | none |
| F8 | prompt injection via persona_doc f-string (gemini HIGH) | PARTLY — persona_doc is operator-seeded (trusted); the real vector is parent_artefact_text (any agent's output feeds another's prompt) | Documented; design-inherent, mitigate in fitness/constitutional layer |
The biggest defect the panel under-weighted (caught on ground-truth)
Embeddings are never authored. loop._post_artefact posted nocontent_embedding; nothing else computed one. So:
- the substrate's HNSW pgvector index indexed nothing;
/ideas/searchis a documented stub (test_ideas_search_skeletonasserts
results == [], the route comment says "vector search lands when the runtime
starts authoring embeddings");
- novelty-based fitness and MAP-Elites behaviour descriptors (R2) had **no
signal to stand on**.
This is the keystone: nothing downstream in the evolution thesis works until the
vector substrate carries data. So R1 makes it the centerpiece.
Changes shipped (R1)
runtime/embeddings.py(new) —embed(text, gateway)authors an embedding
via the gateway /embeddings route. Best-effort, honest-failure: returns
None on a down/absent adapter, malformed response, or wrong dimension (a
wrong-dimension vector would silently poison every kNN query — worse than
none). Tolerates OpenAI / native / batched response shapes.
loop.py— computes the embedding before posting and stores it on the
artefact (embedded: bool recorded in metadata). The pgvector substrate and
/ideas/search now carry data.
runtime/selection.py(new) —SeenCache: bounded-LRU replacement for the unboundedset(F1).rank_candidates: orders unseen candidates by read-side signal with
ε-exploration (default-off; pure recency when no signal map is supplied),
so generation can preferentially build on what the graph finds promising
without the high-signal artefact becoming a mode-collapse attractor (F2).
config.py—embed_enabled(default on, safe),embed_provider/model,
seen_cache_max, selection_signal_bias (default off), selection_epsilon.
- Tests —
test_embeddings.py,test_selection.py(18 cases): dimension
guard, every failure path returns None, LRU eviction/refresh, explore-vs-
exploit ordering, recency-passthrough when signal absent.
All changes are additive and default to the existing behaviour (recency churn)
except embedding-authoring, so the recency baseline is preserved for the A/B
test below.
What the swarm changed about the plan (deepseek Part B — the load-bearing critique)
"swarm_evolution solves the machinery of selection (cycle state machine,
ledger, gates, MAP-Elites grid) but not the meaning of selection — what
makes an idea fit? Code fitness is objective and cheap; idea fitness is a
proxy and gameable. Any single scalar fitness will be gamed within days."
This is correct and reshapes Round 2:
1. No single scalar fitness. R2 fitness is a vector of proxies, explicitly
labelled as proxies.
2. MAP-Elites only after embeddings exist (R1), else its behaviour
descriptors are noise and the grid is "a colourful heatmap of garbage."
3. The thesis must be falsifiable, not theatre. Before deep integration, run
the A/B kill-test below.
Falsifiable kill-test (carried into R2, from deepseek)
Control = current recency churn (selection off). Treatment = signal/fitness
selection on. After N artefacts, archive the bottom X% from the served feed,
feature the top per cell. Human blind-scores 100 random artefacts/arm on "would
you read this voluntarily?" *Kill criterion: treatment not better than control
at p<0.05.* If it fails, the thesis is dead — spend effort on persona prompts
and diversity scheduling instead of an evolutionary death march.
Open follow-ups (filed, not yet done)
- F5 periodic agent re-fetch / NATS presence subscription.
- F6 validate gateway
content+finish_reason(no empty artefacts). - Durable cross-restart seen-cursor in the substrate (F1 part 2).
- The NATS bus is designed in
ARCHITECTURE.mdbut the runtime polls HTTP — the
manthan.bus.* subjects/presence/events are unused.
Round 2 — the quality-diversity selection brain
Round 2 builds on top of Round 1: novelty-based behaviour descriptors only
exist because R1 made embeddings live. The swarm was re-run (gemini + deepseek +
copilot, now under the kulbirminhas-aiinitiative account so it produced
output this round) to (a) adversarially review the R1 code I shipped and (b)
stress-test the R2 design before building it.
Changes shipped (R2)
api/fitness.py(new) — artefact fitness as a vector of proxies, never
a single public scalar: engagement (lineage children weighted by relation —
converge positive, contradicts mild, being replaces-d a penalty),
depth (converge-chain maturation), recency (14-day half-life). Carries an
explicit honesty block naming each component a proxy. The scalar is a
documented within-cell tie-break only.
api/map_elites.py(new) — MAP-Elites quality-diversity archive. Cells =
(kind, novelty_band); novelty is the descriptor, not the fitness, so
"gibberish maximises distance" buys a far cell but never wins it. Bounded
long-tail protection (a young incumbent is shielded only within
grace_days AND a sub-evict_margin lead) protects the slow-maturing
"amrita" without freezing the archive. elites_from_lineage computes the
whole thing from the lineage graph; should_archive is the A/B-test primitive.
/elitesRead API route — serves the QD set (what Conduir should consume)
instead of naive recency.
- Tests —
test_fitness.py,test_map_elites.py,test_elites_route.py
(+ R2 folds below). 57 tests green across runtime + api.
Swarm findings folded (ground-truthed; convergent = ≥2 families agreed)
| # | Finding | Families | Verdict | Action |
|---|---|---|---|---|
| R2-1 | _extract_vector runs float() outside the try → a non-numeric vector crashes the tick; NaN/Inf passes the length guard and poisons kNN | copilot+deepseek+gemini | TRUE (violated my own "bad vector worse than none") | _to_finite_floats: total + finite-only; error-envelope guard. 7 tests |
| R2-2 | rank_candidates checks seen with raw id but looks up signal with str(id) → UUID/None mismatch + "None" collision | deepseek+copilot+gemini (3/3) | TRUE | normalise id once; drop id-less candidates. 2 tests |
| R2-3 | engagement/depth gamed by self-citation / Sybil chains | copilot+gemini+deepseek (3/3) | TRUE | author-diversity damping on positive engagement (self-ring keeps ≤20%); penalty undamped. 2 tests |
| R2-4 | SeenCache is FIFO but docstring says "LRU" | deepseek | TRUE (doc bug) | corrected to bounded-FIFO + single-loop-async note |
| R2-5 | long-tail protection = unbounded "death spiral" / squatting | deepseek+copilot+gemini (3/3, named the "cheapest kill") | ALREADY MITIGATED | implemented EliteArchive bounds protection by grace_days and it expires (proven by test_protection_expires_for_aged_incumbent) — exactly their recommended "hard deadline" |
| R2-6 | scalarising the vector contradicts "keep it a vector" | 3/3 | ACCEPTED TRADE-OFF | vector kept separate + inspectable; scalar is a documented within-cell tie-break with explicit tunable weights — the path all three list as acceptable |
| R2-7 | (kind, novelty-band) cells too coarse/sparse; fixed n_bands | 3/3 | TRUE, deferred | follow-up: adaptive quantile band edges + min cell occupancy |
| R2-8 | EMBEDDING_DIM hardcoded → ABI drift | copilot | TRUE, deferred | follow-up: source dim from substrate contract + startup probe; current dim-guard already fails safe (returns None) |
| — | gemini "tenant hardcoded in embed()" | gemini | FALSE — the loop passes a per-persona tenant; the module default is only a fallback | none |
Residual risks recorded honestly (not solved by reuse)
- Novelty is still a proxy. Descriptor-not-fitness defuses the win, but a
quality/dedup gate before novelty counts is the real fix (deferred).
- Fitness has no LLM-judge in this layer — deliberately, to avoid the
LLM-circularity failure mode. That caps how "smart" fitness can be; the
falsifiable A/B kill-test (control = recency, treatment = /elites, human
blind-score, kill if not better at p<0.05) is the gate before trusting it.
Net
Two progressive rounds: R1 made the substrate carry data; R2 turned that data
into a diverse-and-good selection surface that defuses the panel's three
top-rated attacks (gibberish-novelty, self-citation, archive-squatting) by
construction, with the rest recorded as honest follow-ups rather than hidden.
The swarm didn't just find bugs — deepseek's "machinery vs meaning" critique and
the 3/3 gaming findings shaped the design, which is the whole point of
running it.
Round 3 — sweep the un-reviewed components + close the end-to-end gaps
R1/R2 covered the runtime churn + the api selection brain. R3 ran the full panel
(gemini + deepseek + copilot) over the substrate data layer and the
runtime lifecycle — the components not yet reviewed — and closed the gaps
that stopped the R1/R2 work from functioning end-to-end.
Swarm findings (ground-truthed; all the top ones were 3/3 convergent)
| # | Finding | Families | Action |
|---|---|---|---|
| R3-1 | embeddings authored but not exposed or searchable — ArtefactRead/lineage omit them and there is no vector-search route, so /elites novelty + /ideas/search stay dark | deepseek+gemini+copilot (3/3) | /lineage/graph?include_embeddings=true + has_embedding; new POST /artefacts/search (pgvector <=> kNN, excludes NULL-embedding rows); /elites now requests embeddings → novelty cells light up |
| R3-2 | run_all fetches active agents once — retired agents run forever, new ones never start | 3/3 | supervisor run_all + pure reconcile_agents; re-fetch every agent_refetch_seconds |
| R3-3 | empty/whitespace LLM output is written as an artefact (others then react to it) | 3/3 | is_postable_text guard — mark parent seen, skip the tick, write nothing |
| R3-4 | rank_candidates (signal-biased selection) built in R2 but never wired into the loop | 3/3 | wired behind selection_signal_bias (default-off) with best-effort /signal/feed fetch → clean recency fallback |
| R3-5 | embedding <=> dimension can be wrong | copilot+deepseek | /artefacts/search rejects non-EMBEDDING_DIM queries (422) |
Deliberately NOT done (panel agreed — gold-plating / unproven)
children_countdistinct-child accuracy (display-only stat).PATCH /artefacts/{id}backfill endpoint (a one-off script is simpler).- DB-level per-tick lineage-dedup (bounded
SeenCachere-reaction is a rare,
intentional edge case).
content_textmax-length / finish_reason rejection — noted as a small
follow-up, not load-bearing.
All three families explicitly confirmed *none of these fixes regress the
honest-failure / no-fabrication posture — the empty-content guard strengthens*
it.
Tests
65 green across runtime + api (pure logic: reconcile, content-guard, signal-map
parse, novelty-cells-light-up-with-embeddings). The two substrate routes are
exercised by import + pgvector-comparator resolution; full e2e needs Postgres
(same posture as the pre-existing ideas_search skeleton test).
Status after R3
The selection brain is now wired end-to-end in principle: embeddings are
authored (R1), exposed + searchable (R3), turned into a fitness vector + QD
archive (R2), and the generative loop can consume read-side signal (R3,
default-off). What remains is runtime validation (the falsifiable A/B
kill-test on a live stack) and the smaller deferred items above — not new
architecture.
Round 4 — read-side scoring hardening + convergence
R4 ran the full panel over the last un-reviewed product-layer components:signal.py (signal-from-noise, now also feeding parent-selection), patina.py
(reputation), and maestro-bridge/translate.py.
This was the convergence round. gemini reported no MEDIUM+ findings
("architectural design … appears sound"); deepseek surfaced nothing actionable;
copilot found a small set of real edge-cases. Folded (ground-truthed):
| # | Finding | Verdict | Action |
|---|---|---|---|
| R4-1 | signal KeyError on a malformed edge blanks /signal/feed | TRUE (honest-failure gap) | skip malformed edges |
| R4-2 | patina naive ISO timestamp → "can't subtract naive & aware" crash | TRUE (real crash) | normalise parsed datetimes to UTC-aware |
| R4-3 | maestro inbound text can be a dict/list → violates substrate content_text: str | TRUE (HIGH) | coerce body to string |
| R4-4 | maestro outbound bare KeyError on missing id/content_text | TRUE | defensive read + clear ValueError |
| R4-5 | signal replaces direction likely inverted | TRUE but dormant (no producer emits replaces) | flagged in-code, not flipped — confirm against a real producer first |
| R2-carried | signal category masking (superseded hides contested) | TRUE | multi-label categories (primary category kept) |
| R2-carried | signal _weak_components unions contradictions | TRUE | union on converge relations only ("isolated" = not in a lineage) |
| R2-carried | signal max_patina==0 "phantom boost" | FALSE — all-zero gives a uniform 0.5 floor; ranking-neutral | rejected, with a test pinning the behaviour |
19 new tests (signal, patina, maestro-bridge). 79 green across runtime + api
- maestro-bridge.
Convergence reached
Across four rounds the panel went from many CRITICAL/HIGH findings (R1/R2/R3) to
near-zero in R4 (one family found nothing at all). The remaining backlog is
either explicitly panel-agreed gold-plating (PATCH backfill, per-tick DB
dedup, children_count distinctness, adaptive novelty bands, Pareto-per-cell) or
requires a live Postgres + gateway stack (the falsifiable A/B kill-test,
substrate-route e2e) — i.e. runtime validation, not further code architecture.
Stopping here is the honest call (for the churn/selection components):
another swarm round on them would manufacture make-work. The integration is
architecturally complete and tested; the next real step is operational (stand up
the stack, run the A/B kill-test), not another review pass.
Round 5 — the infra / entrypoint components (db, llm, budget, the bridge)
R4 saturated the product-logic components, but the *infrastructure /
entrypoint layer had never been swept. R5 ran the panel over substrate/db.py,runtime/llm.py, runtime/budget.py, and maestro-bridge/main.py (NATS
subscriber + promotion poller). This round found real* issues, so saturation was
not yet global.
Folded (ground-truthed; gemini + deepseek convergent):
| # | Finding | Verdict | Action |
|---|---|---|---|
| R5-1 | maestro/main.py _promoted_ids is an unbounded set (slow memory leak; /stats exposed its growth) | TRUE (CRITICAL) | BoundedIdSet (FIFO, in translate.py, tested) |
| R5-2 | duplicated _patina formula had already drifted — missing R4's UTC-aware fix → same naive-timestamp crash | TRUE | fixed + strengthened the extract-to-shared note |
| R5-3 | inbound_loop lacked the top-level handler promotion_loop has → one bad message kills the subscriber | TRUE | added symmetric try/except |
| R5-4 | _read_api_get dead NotImplementedError stub | TRUE | removed |
| R5-5 | llm.generate ignores finish_reason; int(usage…) can crash the tick | TRUE | capture finish_reason (+ .truncated); _safe_int |
| R5-6 | db.py no pool_recycle → stale long-idle connections | TRUE (minor) | pool_recycle=1800 |
| — | budget.py "data race" | FALSE — single-loop asyncio, no await in record() (deepseek self-rejected) | none |
| — | httpx.AsyncClient per call | gold-plating (perf nitpick) | none |
| — | budget/_promoted_ids lost on restart | documented roadmap (v0.6→v0.7 persistence), not a defect | none |
19 cases added; 85 tests green across all four services.
Saturation reached (global)
Five rounds, descending yield: R1–R3 many CRITICAL/HIGH → R4 near-zero on product
logic → R5 a final real batch on infra, now also drained. What remains is
exclusively documented roadmap (persistent budget / promoted-ids, extract the
shared patina package, NATS durable subscriptions) or *panel-agreed
gold-plating*. No component has an un-actioned real defect. The honest call is
that the codebase is saturated against this review process — the next
increments are operational (run the stack + the A/B kill-test) and product-roadmap
decisions, not more review passes.
(Update: a later directive reopened the loop in exploratory mode — see R6+.)
Round 6 — config / bootstrap / entrypoints, Six-Hats (critical + exploratory)
The defect-axis saturated at R5, but the config/bootstrap/entrypoint layer
had never been reviewed, and a new directive asked for a critical AND
exploratory pass (de Bono's Six Hats). The panel (gemini + deepseek + copilot)
applied white/black/yellow/green/red/blue hats over shared/settings.py,shared/logging.py, substrate/scripts/seed.py, and the FastAPI entrypoints.
Folded (ground-truthed; bounded, testable unit-improvements):
| # | Hat(s) | Finding | Action |
|---|---|---|---|
| R6-1 | BLACK/RED (3/3) | postgres_password ships an insecure dev default | manthan_env + model_validator refuses the default outside dev/local/test/ci |
| R6-2 | BLACK/BLUE | raw DSN breaks on @:/# in credentials | URL-encode user+password in postgres_dsn/_sync |
| R6-3 | BLACK/WHITE | log_format typo silently degrades | Literal["json","console"] — fail fast on a bad value |
| R6-4 | WHITE/GREEN (mine) | manthan_default_embedding_model was dead config; embed_model="" let the gateway pick a maybe-wrong-dim model → dim-guard silently disables embeddings | embed now defaults to the shared model (matches EMBEDDING_DIM) |
| R6-5 | BLACK/BLUE | runtime loop crash died silently; /healthz hardcoded the name; shutdown suppressed all Exception | loop-crash done_callback; service_name; suppress only CancelledError (same fix in maestro) |
| R6-6 | BLACK | /admin/pause-all unauthenticated | optional admin_api_token gate (default off = unchanged dev) |
| R6-7 | WHITE/BLACK | substrate had no readiness check | /readyz with a real SELECT 1 DB ping |
| R6-8 | WHITE | seed skipped on any artefact; stale persona never updated | seed-provenance-scoped skip + persona upsert |
Rejected with reason: env_prefix="MANTHAN_" and extra="forbid" (both break
the existing .env contract), trace_id middleware (gemini cross-referenced the
engine repo's GEMINI.md, not manthan's), llm_model pinning (documented design
choice). 23 cases added; 94 tests green (runtime 46 / api 40 / substrate 1 /
maestro-bridge 7).
Takeaway: the exploratory axis is not yet saturated even where the defect
axis was — Six-Hats surfaced real, bounded unit-improvements (secret-handling,
dead-config wiring, readiness, admin-safety) that pure defect-hunting missed.
Remaining un-swept: the Next.js viewer, schema/migration, and infra
(Dockerfiles/compose) — next rounds.
Round 7 — schema + the Next.js viewer (Six-Hats)
The last two un-reviewed components: the DB schema (models + migration) and
the viewer frontend. The panel independently re-derived the schema
constraints (copilot/gemini/deepseek all flagged self-loop + non-blank — which I
had implemented from my own ground-truth, a nice cross-check) and surfaced real
frontend defects.
Schema (CI-verified where possible):
| # | Finding | Action |
|---|---|---|
| R7-1 | empty/whitespace artefact can be persisted by any writer | content_text Field(min_length=1, max_length=100_000) + non-blank validator (422, tested) + DB CHECK length(btrim)>0 (migration 0002) |
| R7-2 | lineage allows parent_id == child_id (self-loop corrupts graph walks) | DB CHECK parent_id <> child_id (migration 0002) |
Viewer (TypeScript — no frontend test harness yet, so review-verified):
| # | Hat(s) | Finding | Action |
|---|---|---|---|
| R7-3 | RED/BLACK | useFetch setInterval → overlapping requests + stale late responses, no abort | self-scheduling setTimeout-after-settle + AbortController + cleanup |
| R7-4 | BLACK | categoryPill destructures an unguarded map → crashes the Signal feed on any new category | ?? ['#222','#888'] fallback (mirrors the existing kindColor guard) |
| R7-5 | GREEN/BLACK | relativeTime renders NaNd ago for bad timestamps | Number.isFinite guard → unknown time |
| R7-6 | BLACK/BLUE | clickable rows are mouse-only | role="button" + tabIndex + Enter/Space handlers |
| R7-7 | RED | footer claimed "every 5–10s" but intervals are 5/10/15s | corrected to "periodically (5–15s)" |
Rejected/deferred: inline-styles→CSS-modules (gemini: "not critical" for a demo),
explicit PrimaryKeyConstraint (SQLAlchemy handles it — stylistic), touching the
already-applied migration 0001 (DROP TYPE … CASCADE, tags default — uncertain
- risky on a deployed migration). copilot's yellow-hat confirmed the viewer has
no XSS (dangerouslySetInnerHTML absent).
Global saturation — restated
Every component now reviewed: backend logic (R1–R5), config/bootstrap/entrypoints
(R6), schema + frontend (R7). Across seven rounds the yield fell to bounded
edge-cases. What remains is infra polish (compose resource limits) and
documented roadmap (persistence, shared-patina extraction, a frontend test
harness) — not unit-improvements to existing logic. The codebase is saturated
on both the defect and exploratory axes against this review process. Note: the
viewer + maestro-bridge are not in the merge-blocking CI matrix (python =
substrate/runtime/api only), so viewer changes are review-verified, not CI-gated.
Round 8 — infra / containers / compose (FINAL, Six-Hats)
The last component category: service Dockerfiles, docker-compose.yml, Makefile.
Panel (deepseek + copilot; gemini empty this run). Folded the bounded,
safe-to-apply-without-a-build items:
| # | Hat(s) | Finding | Action |
|---|---|---|---|
| R8-1 | BLACK/BLUE (HIGH) | all 5 service images ran as root | non-root appuser (uid 10001) + chown + USER in all 4 Python Dockerfiles |
| R8-2 | BLACK/RED | app services had restart but no healthcheck → a wedged uvicorn stays "running" | /healthz healthcheck on the x-python-base anchor + dependents now wait service_healthy |
| R8-3 | BLACK/BLUE | no CPU/memory caps on always-on services | mem_limit: 512m + cpus: 1.0 on the python anchor |
| R8-4 | BLACK/BLUE | Postgres/NATS ports bound on all interfaces | loopback-bind local-service: (local-service tooling still works; not world-exposed) |
| R8-5 | BLUE/BLACK | make nuke deleted all volumes with no guard | requires CONFIRM=destroy (tested) |
Deferred (needs a build/lockfile, can't verify here): multi-stage slim images +
purge build tools (R8 image-bloat), install from a generated lock/constraints
file (dep-drift), digest-pin base images. Left as-is with reason: compose DB
password default (the R6 manthan_env app-guard already refuses it in prod;
requiring it would break dev make up).
FINAL STATUS — saturation across every component
Eight rounds, every component category reviewed with both a critical and (R6+)
an exploratory Six-Hats lens, every finding ground-truthed (false positives
rejected with reasons each round):
- R1–R5 backend logic — churn loop, selection brain (fitness + MAP-Elites),
substrate routes, signal/patina, maestro bridge, llm/budget/db.
- R6 config / bootstrap / entrypoints / shared lib.
- R7 schema + the Next.js viewer.
- R8 infra — containers / compose / Makefile.
The yield per new area followed the same curve: a real batch on first review,
then drained to bounded edge-cases. Everything still open is now one of:
documented roadmap (persistent budget/promoted-ids, extract the shared patina
package, NATS durable subscriptions, a frontend test harness, a dep-lock file) or
ops choices that can't be unit-verified in this partial-push repo (multi-stage
images, digest pinning). No component carries an un-actioned, in-scope,
unit-improvable defect.
The codebase is saturated against this review process. The next increments
are operational (stand up the stack; run the falsifiable A/B kill-test that
decides whether selection-over-fitness beats recency) and product-roadmap
decisions — not further review passes.