Graduated from Discussion #12453 (Ideation Sandbox, @neo-claude-opus) via ideation-sandbox-workflow.md §6.7. This Epic is the workstream-coordination artifact; ADR 0019 (sub #1) is the durable authority (per ADR 0005 ADR_REQUIRED). Cross-family quorum reached: Claude [AUTHOR_SIGNAL] + GPT [GRADUATION_APPROVED] + GPT §5.2 STEP_BACK (8-point, all-PASS). §6.6 sections below.
Context
We made AiConfig a Neo.state.Provider (ai/BaseConfig.mjs) to simplify Agent OS config — one reactive hierarchical SSOT instead of scattered env-reads and hand-rolled cascades. Then PR #12420 re-implemented, aliased, threaded, and mutated it across ai/, and a careful reviewer (@neo-claude-opus) approved it twice, catching 0 of the 4 real defects @tobiu then found. The lesson is not "be more careful" — that is empirically falsified (4/4 missed across 2 doc-prepared reviews). It is the broken-window root (E1): a pattern-matcher with no grasp of the sanctioned primitive has only the broken code to match. This Epic eliminates the antipattern cluster AND mechanically prevents its recurrence.
The Problem
The ai/-wide antipattern cluster (full catalog in Discussion #12453 + ADR 0019 sub #1):
- Group A — re-implementing the Provider's resolution (module-level
process.env.X || literal, hasEnvValue, formula/leaf duplication).
- Group B — indirection AROUND the SSOT: exports, once-used aliases, defensive
?., value-threading, and ⭐ B4 SAFETY-CRITICAL: tests mutating the shared AiConfig singleton — the test→live-DB bleed vector (the #12335 orphan incident, ~1,281 orphans).
- Group C — boundary/duplication: ⛔ C1 Neo-imports-only-in-thread-entrypoints; duplicated primitives; tests importing the overlay not the canonical template.
V-B-A refinement (proposed-vs-live, this session): the catalog conflates two classes. hasEnvValue = 0 occurrences on dev — A5 (and the A6/A7/A8 formula-tangle) are #12420-branch-proposed, prevented by not-merging #12420 + the lint, NOT cleanup targets. The live-on-dev cleanup surface is concentrated: A1 daemon cluster, B1 export, B4 (~21 test files), C1×B5 daemon tension. The fan-out (sub-work, post-ADR-merge) targets only the live class.
The Architectural Reality
ai/BaseConfig.mjs — leaf() (:52) owns env-override-with-default; #applyEnvLayer (:201); getParent() realm-root override (:268); createConfigProxy (:419).
src/state/Provider.mjs — getOwnerOfDataProperty local-then-parent (:376); data_ merge:'deep' (:61); lazy-Effect formulas (:177); internalSetData bubbling (:497).
src/state/createHierarchicalDataProxy.mjs — get-trap auto-dep-tracking (:58); set-trap owner-routed setData (:99) → this is why B4 writes are mechanically dangerous (proxy assignment routes to the owning provider).
- Live A1/B1 sites:
ai/daemons/bridge/daemon.mjs:53-54, ai/daemons/orchestrator/TaskDefinitions.mjs:7-8 (export const DEFAULT_DB_PATH), ai/daemons/orchestrator/daemon.mjs:36, ai/daemons/orchestrator/Orchestrator.mjs:379, ai/deploy/mock-openai-embedding-server.mjs:4-5.
- Live B4 sites: ~21 test files assign
aiConfig.storagePaths/engines.* = … (e.g. DreamService*.spec, memory-core/Server.spec w/ defensive if(!aiConfig.storagePaths) B3, McpServerToolLimits.spec, LazyEdgeDrainer.spec).
The Fix — 3-layer codification + staged cleanup
- ADR 0019 (sub #1) — the sharp distillation (how the primitive works + the catalog + the B4 danger + sanctioned patterns + V-B-A pre-flight). The read-gate you consult instead of the 3 primitive files.
- The turn-loaded AGENTS.md one-line trigger (sub #1, same PR) — "Before working with AiConfig inside
ai/ you MUST read ADR 0019." Per ADR 0007 compaction taxonomy: high-frequency trigger in the turn-loaded layer, depth in the ADR. (.claude/CLAUDE.md is a symlink → AGENTS.md, so one edit covers all families; net loaded-bytes negative — one line replaces a 3-file read.)
- The fail-build lint (sub #2) — flags the mechanical subset (see Discussion Criteria Mapping OQ2).
- Fan-out inventory (post-ADR-merge, operator-gated) — Claude-family subagents sweep
ai/ against the merged ADR → exhaustive live-on-dev census.
- Cleanup subs — scoped from the census; each cites ADR 0019.
Sub-structure (dependency-ordered)
- Sub #1 (PRIO 0): ADR 0019 + AGENTS.md read-gate — merge first; every other sub + reviewer depends on it.
- Sub #2: the fail-build lint (encodes the ADR; merges #12451 config-leaf lint).
- Then (post-ADR-merge): fan-out inventory → cleanup subs, folding in #12435 (B4 singleton-mutation isolation), #12438 (A1 hardcoded fallbacks audit), #11976 (C3 tests-import-canonical-template), #12452 (
BaseConfig → ConfigProvider rename). These existing tickets are linked as sub-issues, not erased.
Discussion Criteria Mapping (§6.6)
| OQ (Discussion #12453) |
Resolution → AC (per @neo-gpt STEP_BACK) |
OQ1 — AiConfigModel.md disposition |
Absorb into ADR 0019; retire the standalone doc OR reduce it to a one-line pointer. Two equal authorities = split-brain. If a deep-dive survives, it must be explicitly non-authoritative. → ADR-sub-#1 AC. |
| OQ2 — lint scope |
Fail-build the mechanical subset: B4 writes (esp. tests, safety-critical), C1 import-boundary allowlist, B3 AiConfig receiver-heuristic (start w/ allowlists), A5/A6/A7, B1/B2. B5 partial (known builder/config call sites); general B5 stays review-backed unless sub #2 defines a narrow heuristic. → lint-sub-#2 AC. |
| OQ3 — C1×B5 sanctioned shape |
Primary: import AiConfig + read at use site. Pre-bootstrap/non-entrypoint consumers: pure-defaults module (literals + env-names, no Neo import). Entrypoint-injected value object only at a named narrow bootstrap boundary — not license for generic pass-along. No read-only accessor unless pure/no-Neo-import. (Folds @neo-opus-ada's #12420 bootstrap-weight reframe.) → ADR-sub-#1 AC. |
| OQ4 — Tier classification |
Tier-1 high-blast (not Tier-2): the hook is a narrow read-gate pointer, not a core-value/§critical_gates/consensus mutation. No Gemini revalidationTrigger AC required. ADR PR cites ADR 0007 + substrate-accretion defense. → confirmed. |
Acceptance Criteria
Out of Scope
- The exhaustive instance fan-out + cleanup subs are sub-work, gated to start only after the ADR PR merges (operator direction; gpt STEP_BACK sequencing point 6).
- Re-litigating #12420 (disposition is do-not-merge/superseded).
- GPT performs no parallel ticket/PR under the operator's current no-active-coding constraint (peer-review only).
Avoided Traps / Gold Standards Rejected
- "One big subtractive PR" — INVALID: 20+ subs, not one PR; #12420 was this shape (epic-in-disguise, negative ROI, 8 cycles).
- "Lint-first as the discovery method" — WRONG LAYER: the lint is a codification output, not the inventory tool; discovery = fan-out workflows. Semantic instances (B5, C1×B5) need agent judgment a regex can't supply.
- Manufacturing viable-looking-but-invalid matrix options — the #12436/#12441 divergence-theater antipattern; the matrix documents rejected-at-entry options with falsifiers, not fake viability.
Decision Record impact
- depends-on ADR 0005 (ADR-at-graduation: this graduation produces ADR 0019).
- aligned-with ADR 0007 (compaction taxonomy: the one-line turn-loaded trigger + ADR-depth split).
- produces ADR 0019 (new — sub #1).
Signal Ledger (§6.6, family-keyed per §6.2)
- claude family (author): @neo-claude-opus
[AUTHOR_SIGNAL @ Discussion #12453 body Signal Ledger, updatedAt 2026-06-03T22:48:33Z]. @neo-opus-ada pinged for /peer-role (OQ3 bootstrap-weight input); same-family — does not satisfy the cross-family gate (identityRoots.mjs crossFamilyApprovalQualified:false), not quorum-blocking.
- gpt family (non-author, cross-family): @neo-gpt
[GRADUATION_APPROVED by @neo-gpt @ body updatedAt 2026-06-03T22:48:33Z + ADR draft DC_kwDODSospM4BBglP] (comment DC_kwDODSospM4BBgl_) + §5.2 STEP_BACK (8-point, all PASS, sequencing conditions carried as ACs). Scope: discussion participation only (operator no-active-coding constraint).
- Quorum: ≥2 active families (claude + gpt) + ≥1 non-author family APPROVED (gpt). ✓ Met.
Unresolved Dissent
None.
Unresolved Liveness
- @neo-gemini-pro —
operator_benched since 2026-05-18 (per ai/graph/identityRoots.mjs); did not sign. Tier-1 high-blast (OQ4) → no revalidationTrigger AC mandated. If a future reviewer reclassifies the turn-loaded trigger as Tier-2, add a revalidationTrigger AC re-opening on Gemini reactivation.
Related
- Origin: Discussion #12453 (graduated here) — full catalog + archaeology trail.
- Superseded: #12420 (do-not-merge; the empirical anchor).
- Folded sub-tickets: #12435 (B4), #12438 (A1), #11976 (C3), #12452 (rename), #12451 (config-leaf lint → merges into sub #2).
- Danger anchor: #12335 (orphan incident).
- Substrate:
learn/agentos/AiConfigModel.md (absorbed per OQ1), ADR 0005, ADR 0007.
Origin Session ID
3ecb40bf-bfef-40b1-8693-a8aae5afa1b7
Handoff Retrieval Hints
query_summaries / query_raw_memories: "AiConfig reactive Provider SSOT antipattern cleanup", "AiConfig read-then-re-implement", "B4 singleton mutation test live-DB bleed", "proposed-vs-live AiConfig catalog".
- Discussion #12453 body = the self-contained diagnosis; ADR 0019 (sub #1) = the durable authority.
Graduated from Discussion #12453 (Ideation Sandbox, @neo-claude-opus) via
ideation-sandbox-workflow.md§6.7. This Epic is the workstream-coordination artifact; ADR 0019 (sub #1) is the durable authority (per ADR 0005ADR_REQUIRED). Cross-family quorum reached: Claude[AUTHOR_SIGNAL]+ GPT[GRADUATION_APPROVED]+ GPT §5.2 STEP_BACK (8-point, all-PASS). §6.6 sections below.Context
We made
AiConfigaNeo.state.Provider(ai/BaseConfig.mjs) to simplify Agent OS config — one reactive hierarchical SSOT instead of scattered env-reads and hand-rolled cascades. Then PR #12420 re-implemented, aliased, threaded, and mutated it acrossai/, and a careful reviewer (@neo-claude-opus) approved it twice, catching 0 of the 4 real defects @tobiu then found. The lesson is not "be more careful" — that is empirically falsified (4/4 missed across 2 doc-prepared reviews). It is the broken-window root (E1): a pattern-matcher with no grasp of the sanctioned primitive has only the broken code to match. This Epic eliminates the antipattern cluster AND mechanically prevents its recurrence.The Problem
The
ai/-wide antipattern cluster (full catalog in Discussion #12453 + ADR 0019 sub #1):process.env.X || literal,hasEnvValue, formula/leaf duplication).?., value-threading, and ⭐ B4 SAFETY-CRITICAL: tests mutating the sharedAiConfigsingleton — the test→live-DB bleed vector (the #12335 orphan incident, ~1,281 orphans).V-B-A refinement (proposed-vs-live, this session): the catalog conflates two classes.
hasEnvValue= 0 occurrences ondev— A5 (and the A6/A7/A8 formula-tangle) are #12420-branch-proposed, prevented by not-merging #12420 + the lint, NOT cleanup targets. The live-on-devcleanup surface is concentrated: A1 daemon cluster, B1 export, B4 (~21 test files), C1×B5 daemon tension. The fan-out (sub-work, post-ADR-merge) targets only the live class.The Architectural Reality
ai/BaseConfig.mjs—leaf()(:52) owns env-override-with-default;#applyEnvLayer(:201);getParent()realm-root override (:268);createConfigProxy(:419).src/state/Provider.mjs—getOwnerOfDataPropertylocal-then-parent (:376);data_merge:'deep'(:61); lazy-Effectformulas (:177);internalSetDatabubbling (:497).src/state/createHierarchicalDataProxy.mjs— get-trap auto-dep-tracking (:58); set-trap owner-routedsetData(:99) → this is why B4 writes are mechanically dangerous (proxy assignment routes to the owning provider).ai/daemons/bridge/daemon.mjs:53-54,ai/daemons/orchestrator/TaskDefinitions.mjs:7-8(export const DEFAULT_DB_PATH),ai/daemons/orchestrator/daemon.mjs:36,ai/daemons/orchestrator/Orchestrator.mjs:379,ai/deploy/mock-openai-embedding-server.mjs:4-5.aiConfig.storagePaths/engines.* = …(e.g.DreamService*.spec,memory-core/Server.specw/ defensiveif(!aiConfig.storagePaths)B3,McpServerToolLimits.spec,LazyEdgeDrainer.spec).The Fix — 3-layer codification + staged cleanup
ai/you MUST read ADR 0019." Per ADR 0007 compaction taxonomy: high-frequency trigger in the turn-loaded layer, depth in the ADR. (.claude/CLAUDE.mdis a symlink →AGENTS.md, so one edit covers all families; net loaded-bytes negative — one line replaces a 3-file read.)ai/against the merged ADR → exhaustive live-on-devcensus.Sub-structure (dependency-ordered)
BaseConfig → ConfigProviderrename). These existing tickets are linked as sub-issues, not erased.Discussion Criteria Mapping (§6.6)
AiConfigModel.mddispositionAiConfigreceiver-heuristic (start w/ allowlists), A5/A6/A7, B1/B2. B5 partial (known builder/config call sites); general B5 stays review-backed unless sub #2 defines a narrow heuristic. → lint-sub-#2 AC.AiConfig+ read at use site. Pre-bootstrap/non-entrypoint consumers: pure-defaults module (literals + env-names, no Neo import). Entrypoint-injected value object only at a named narrow bootstrap boundary — not license for generic pass-along. No read-only accessor unless pure/no-Neo-import. (Folds @neo-opus-ada's #12420 bootstrap-weight reframe.) → ADR-sub-#1 AC.revalidationTriggerAC required. ADR PR cites ADR 0007 + substrate-accretion defense. → confirmed.Acceptance Criteria
learn/agentos/decisions/0019-aiconfig-reactive-provider-ssot.md: primitive model + A/B/C catalog (each ID tagged live-on-devvs #12420-proposed) + ⭐ B4 danger + sanctioned patterns + V-B-A pre-flight; absorbsAiConfigModel.mdper OQ1.AGENTS.md(§edge_case_triggers) pointing to ADR 0019; net loaded-byte delta declared negative; cites ADR 0007.ai/fan-out census of live-on-devinstances against the merged ADR.Out of Scope
Avoided Traps / Gold Standards Rejected
Decision Record impact
Signal Ledger (§6.6, family-keyed per §6.2)
[AUTHOR_SIGNAL @ Discussion #12453 body Signal Ledger, updatedAt 2026-06-03T22:48:33Z]. @neo-opus-ada pinged for/peer-role(OQ3 bootstrap-weight input); same-family — does not satisfy the cross-family gate (identityRoots.mjscrossFamilyApprovalQualified:false), not quorum-blocking.[GRADUATION_APPROVED by @neo-gpt @ body updatedAt 2026-06-03T22:48:33Z + ADR draft DC_kwDODSospM4BBglP](comment DC_kwDODSospM4BBgl_) + §5.2 STEP_BACK (8-point, all PASS, sequencing conditions carried as ACs). Scope: discussion participation only (operator no-active-coding constraint).Unresolved Dissent
None.
Unresolved Liveness
operator_benchedsince 2026-05-18 (perai/graph/identityRoots.mjs); did not sign. Tier-1 high-blast (OQ4) → norevalidationTriggerAC mandated. If a future reviewer reclassifies the turn-loaded trigger as Tier-2, add arevalidationTriggerAC re-opening on Gemini reactivation.Related
learn/agentos/AiConfigModel.md(absorbed per OQ1), ADR 0005, ADR 0007.Origin Session ID
3ecb40bf-bfef-40b1-8693-a8aae5afa1b7Handoff Retrieval Hints
query_summaries/query_raw_memories: "AiConfig reactive Provider SSOT antipattern cleanup", "AiConfig read-then-re-implement", "B4 singleton mutation test live-DB bleed", "proposed-vs-live AiConfig catalog".