Appearance
THE DOMAIN MODEL (ATLAS) — MASTER PLAN
STATUS: 🟢 ACTIVE — the durable git-tracked master plan for the ATLAS lane · Last updated: 2026-07-24 (ATLAS-JUL24-01, W1.5 CLOSE) · Boot:
docs/atlas/HANDOFF.md(or/resume-session ATLAS). This is the canonical copy (the~/.claude/plans/original was machine-local — moved here per the "durable plans live in the repo" rule). The current authority = the## ✅ MASTER PLANblock below.⚠ POST-W1.5 RECONCILIATION (2026-07-24): W1.5 SHIPPED. Anywhere below that still says
docs/domain-model/(the folder is nowdocs/atlas/),model.brandtrackers.xyz(nowatlas.brandtrackers.xyz),domain-model-census.py(nowatlas-census.py), or "a NEW / separate Vercel project" (now the EXISTINGbrandtrackers-appproject — DN-213) is pre-rename / pre-override historical provenance in the superseded phase-list (line 7 declares that list superseded). The live state =docs/atlas/HANDOFF.md+ DN-213.
Supersedes the prior console/operating-model plans (all shipped). This answers Joe's ask: "stop making me re-explain the logic — ONE canonical, human-readable, verified definition of every pillar, relationship, and pipeline, that I point every future session at, before big decisions." Grounded in this session's live probes + two Explore recon passes (doc landscape · pipeline/routing code). Every load-bearing claim below is tagged with its source.
✅ MASTER PLAN — 2026-07-24 (session JULY24-01) — the CURRENT source of truth (supersedes the phase list that was below)
Where we are: session recovered intact (943 records, 0 corruption). Scaffold
docs/DOMAIN-MODEL.mdcommitted2e62bd78a(+ artifact157c1cc6). Dev server up on:3000. Phase-1 corpus-mine is DONE (5 agents, reconciled vs live DB — buckets below). Joe's decisions this turn: end-state = dedicated docs-as-code stack · sequencing = foundation-first · DB audit = full generated census + subagent pillar-mapping · process = keep the loop, add a DOMAIN-MODEL lane · ultracode/Workflow orchestration authorized for the verify-heavy steps (Joe 2026-07-24).
🔎 AUDIT (2026-07-24b, ground-truth file:line-verified) — the boot chain does NOT yet know this initiative exists
No ATLAS lane in INDEX §1/§2 · /resume-session lane list omits it · /resume-session PIPE lands on docs/sessions/PIPE-JUL21-05/HANDOFF.md (gated W2-BUILD, zero domain-model awareness) · all 5 governance ledgers top at 2026-07-21 (DN-212/F-167/A4.53③) · bigprompt-arch.md + docs/domain-model/ are ORPHANS. ⇒ W1 was under-scoped (closed before wiring the boot chain). W1.5 fixes this FIRST — this is the "nothing-lost" gap. Also recovered: Joe's early SessionStart context-recovery hook idea (never captured) + moments/FE scope boundaries.
NAMING — locked: ATLAS (Joe 2026-07-24b)
The domain model = "Atlas" (the navigable map of the whole domain). Site = atlas.brandtrackers.xyz · folder docs/atlas/ (rename from docs/domain-model/) · lane ATLAS · deploy = Vercel git auto-deploy on push (separate project; NOT the main app's manual-promote). "Taxonomy" rejected (= only the Concepts pillar).
⚠ SUPERSEDED 2026-07-24b by DN-213 (Joe override — read this before the deploy sections below): Atlas is NOT a separate Vercel project and NOT git-auto-deploy. It ships from the EXISTING
brandtrackers-appproject (prj_My6gFrYuUlO2f58f1caAidd3PDkt): VitePress builds intofrontend/public/_atlas/and a host-gated rewrite infrontend/src/middleware.tsservesatlas.brandtrackers.xyz(auth bypassed for that host only), on the app's MANUAL-promote cadence (broken docs build → broken preview only, never prod). Every "new / separate Vercel project" line below (§W1.5-D, the DEPLOY RUNBOOK, PHASE-2 item 4) is historical provenance, corrected by DN-213.
PHASE W1.5 — GOVERNANCE CATCH-UP + ATLAS RENAME + SITE LIVE (URGENT · next window · BEFORE fold-in) ← NEXT
The nothing-lost fix + make-it-live, in one focused window:
- A0. DURABILITY FIX — do FIRST (the master plan is a machine-local single-point-of-failure). This plan lives ONLY at
~/.claude/plans/pipe-console-v2-reconciliation-sorted-pike.md— NOT git-tracked. Copy it into the repo asdocs/atlas/PLAN.md(git-tracked; per the project rule "durable plans move into the repo before close") and repoint the HANDOFF + memory at the repo copy. (Recommended: do this NOW before closing JULY24-01 — zero downside, removes the SPOF.) - A. Rename
docs/domain-model/→docs/atlas/(git mv; update README/HANDOFF/census/deltas + memory + plan + CLAUDE.md refs). - B. Wire the boot chain (de-orphan): INDEX §2 → add ATLAS lane row (ATLAS-JUL24-01 · NEXT) + mark PIPE ⏸ PAUSED — gated on Atlas landing + update the ▶ACTIVE banner · INDEX §1 → "Domain model/ontology/data-dictionary →
docs/atlas/" ·.claude/commands/resume-session.md→ add ATLAS to the lane list ·.claude/CLAUDE.md→ one-liner (Atlas = conceptual front-door, bootdocs/atlas/HANDOFF.md) · de-orphanbigprompt-arch.md(cite from README + PRD as the founding brief). - C. Update the 5 governance ledgers (ground-truth, per DEVELOPMENT-LOOP close matrix): STATE.md top snapshot (ATLAS-JUL24-01, verified counts) · claude-progress.txt line · DECISIONS.md DN-### (Atlas = docs-as-code domain model · foundation-first · naming) · FAILURES-AND-PATTERNS.md F-### (cold-reload "lost session" = context reset not data loss → recovery = handoff+boot chain; + census-corrected-my-own-claim = ground-truth-first earns its keep) · INVARIANTS.md A-entry (Atlas drift-check stays green; census = the substrate).
- D. BUILD + DEPLOY LIVE: VitePress config+theme+nav rendering
docs/atlas/→ new Vercel project → atlas.brandtrackers.xyz (git auto-deploy). Local =npm run docs:dev→localhost:5173(document in README). +llms.txt. - E.
scripts/atlas-drift.py(cloneschema_doc_drift.py) wired into/nightly-verify+/handoff. - F. Write
docs/atlas/PRD.md— goal · users (human-reviewer · LLM-boot · future product surface) · journeys · success criteria · acceptance — then audit it holds up. - G. SessionStart context-recovery hook (recovered idea): on boot, auto-surface the active lane's HANDOFF §0 so a cold reload self-re-orients (makes this session's "lost" scare impossible) →
docs/DEVELOPMENT-LOOP.md+.claude/settings.json. - H. Close with
/handoff+ the enumerated close matrix +/nightly-verify. VERIFY: site LIVE at atlas.brandtrackers.xyz · local dev works · drift green ·/resume-session ATLASresolves · every ledger carries ATLAS-JUL24-01 · zero orphans.
FRAMEWORK — LOCKED: VitePress (researched 2026-07-24b)
For a SINGLE focused pure-markdown spec read by BOTH human (browsable/searchable) + LLM (raw .md): fastest dev loop (Vite HMR), simplest config, purest markdown source (no MDX/JSX muddying LLM portability), built-in local search, trivial Vercel deploy, mature vitepress-plugin-llms (auto llms.txt + llms-full.txt). Starlight (Astro) = the one equal alternative (swap-in ok; also has starlight-llms-txt). Docusaurus REJECTED as overkill (versioning/i18n/blog we don't need; MDX-default muddies pure markdown). Key finding: the LLM angle does NOT differentiate — the LLM reads the raw markdown WE control; deciders = human-DX + simplicity + deploy → VitePress.
W1.5-D DEPLOY RUNBOOK (recon'd 2026-07-24b — zero guesswork)
- Vercel team = BRANDTRACKERS
team_ZY4gLEF15uPzcdstcK0YXc3d; main app project =brandtrackers-appprj_My6gFrYuUlO2f58f1caAidd3PDkt— Atlas = a SEPARATE NEW project, NEVER touch the main app project. atlas.brandtrackers.xyz= NXDOMAIN today (create it; subdomain alias of the existing brandtrackers.xyz Vercel domain — no purchase).- Steps: (1) VitePress config +
package.jsondocs scripts (docs:dev/docs:build) renderingdocs/atlas/; (2) NEW Vercel project (e.g.brandtrackers-atlas) under BRANDTRACKERS, SAME repoheyjoenash/brandtrackers-app, build = VitePress → outputdocs/atlas/.vitepress/dist, git auto-deploy on push to main; (3) add domainatlas.brandtrackers.xyz. Local =npm run docs:dev→ localhost:5173.
/resume-session MECHANICS (verified from .claude/commands/resume-session.md)
- Bare
/resume-session(no name) → asks/infers the lane (line 6) — LESS deterministic./resume-session ATLAS(after W1.5-B) = deterministic. - ⚠ Until W1.5-B registers ATLAS in INDEX §2, neither resolves → for the FIRST fresh window, point it at
docs/domain-model/HANDOFF.md(or paste its §0). After W1.5 →/resume-session ATLAS. - The §0 boot-prompt IN the handoff is REQUIRED, not clutter —
resume-session.md:13: the handoff §0 paste-prompt IS the boot prompt the command reads. (Convention pairs HANDOFF+KICKOFF; our single HANDOFF carries both — fine.)
OPERATING LOOP — how we run this across many windows (compaction / thread / work-mode discipline)
- Lane continuity:
/resume-session ATLAS→ work →/handoff(enumerated close matrix). HANDOFF §0 + this master plan = durable state; ground-truth-first every window (re-probe, never trust frozen numbers). - Compaction/thread rule: close at a VERIFIED milestone BEFORE compaction (target ≤~55% context/window); ONE phase-chunk per window; start a FRESH thread at each phase boundary + before any big Workflow fan-out (clean budget). The W1.5-G SessionStart hook makes a cold reload self-re-orient.
- WORK-MODE GUIDE — when to reach for each (and TELL Joe before spending big):
- Plan mode → START of every phase/window that touches multiple files or makes a design call (W1.5, W2, W3+ each: open plan mode → design → ExitPlanMode for approval). SKIP for a single mechanical edit.
- Workflow (deterministic multi-agent fan-out) → VERIFY-HEAVY breadth where missing one item is costly: W2 fold-in (census ~136 core tables → map each to a pillar → adversarially verify each mapping → fold) and Phase-5 harden (conflict-verify every claim across the model). Trigger = "map/verify N things, N large, completeness > tokens." NOT for a single edit or a linear task. Flag Joe first — it spawns many agents / spends real tokens (explicit opt-in).
- ultracode → the exhaustive, cost-no-object pass: Phase-5 adversarial audit of the whole model, or any "be truly comprehensive / don't miss a single X" moment. Trigger = Joe says "ultracode" OR the task is an exhaustive audit. Announce it (big spend).
- /loop + /schedule (recurring/automated) → the Phase-6 daily curation loop (scoped daily review) + /nightly-verify (read-only health battery). Trigger = "run this every X / on a schedule." NOT for one-off work; guardrails = master FALSE + ~$100/24h + human-gate-on-architecture.
- Goals / phase tracking → the durable goal tracker IS this PLAN file (phases W1.5→6) + the HANDOFF §2 + INDEX §2 lane row. Update them at each close; that's how "the goal" persists across windows (no separate goal state to lose).
/handoff+/resume-session= continuity · hooks = enforcement (drift-check, boot-freshness) — every window, non-negotiable.
- Full-trace verification for any code the model eventually drives (DB→backend→pipeline→functions→hooks→FE), per VERIFICATION-PROTOCOL — nothing assumed; a green unit ≠ a working chain.
SCOPE BOUNDARIES (don't collide)
Moments = the Moments pillar; platform coverage (Instagram/TikTok/YouTube) = Content/Channels pillars (moments taxonomy already v1.1-LOCKED). Wiring moments to admin + the FE modal/layout is DOWNSTREAM, and the FE-modal is a PARALLEL session — Atlas does NOT touch it (memory: stay out of other lanes' boot docs).
↩ RETURN TO THE MAIN PIPELINE (the endgame — what happens AFTER Atlas; verified vs PIPE-JUL21-05)
Atlas is the GATE that UNBLOCKS PIPE, not a detour. The chain back:
- W1.5 (site live + lane wired) → W2 fold-in → W3+ Joe WALKS the pillars + rules the ~6 forks → marks land in
docs/atlas/decisions.md= the ratified logic (walk uses the mark-able console pattern,ratify-consoleskill). - Those ratified decisions ARE what PIPE's paused W2 BUILD was gated on — verified from
docs/sessions/PIPE-JUL21-05/HANDOFF.md: NEXT = "W2 BUILD — the mint arbiter + vocabulary homes + credit fixes + deterministic backfills, gated on Joe's marks on the 24-card CONSOLE-V2." The Atlas walk PRODUCES those marks. - When the model is ratified:
/resume-session PIPE(un-pause it) → execute the W2 BUILD against the now-corrected Atlas foundation → the 24-card console marks were recorded intodecisions.mdduring the walk (one approval → one place). Atlas gives PIPE the corrected conceptual foundation it was building blind without. The 24-card console walk = the bridge; it happens INSIDE the Atlas walk, and its output flips PIPE from paused → building.
§0 REDLINES — locked by Joe (apply throughout)
- ACTORS →
ENTITIES(Joe's word + the table name). - "ontological family" vs "group-by lens" — family = what a thing IS (Entities · Works · Groupings · Concepts); lens = how the product SLICES (by industry/audience/channel/campaign/discipline). Keep distinct in §0.
- Placement: Audience, positioning (sector/industry/category), channel = Concepts (axes + lenses), NOT containers. Groupings = real-world containers you can point at (campaign · project · event · brand-identity). Test: Grouping = "a thing that happened/exists"; Concept = "an axis you classify against."
WHY THIS TIME STICKS (the anti-rot thesis — answers Joe's "6 months" fear)
Not memory — generated + enforced: source = git markdown (can't be lost) · site auto-builds (always current) · domain-model-drift.py fails CI on DB divergence (can't silently rot) · registered in the hook-enforced boot chain (every /resume-session lands on it). Docs-as-code + contract-testing, per 2026 best practice (agents are ~half of doc-site traffic now).
PHASE 1 — Corpus-mine + reconcile — ✅ DONE
5 pillar-aligned miners read every line of the ref corpus (logic-only, ancient naming ignored) → deltas re-probed against the live DB. Full ledger banked at scratchpad/phase1-deltas.md (MUST be moved into the repo in W1 — currently at loss-risk in /tmp). Reconciliation buckets:
- A) GENUINELY NET-NEW / UNBUILT (real gaps → §5 forks): signal/temporal spine (
observations→signals→insights→implications, ZERO tables — the product THESIS, 3-agent convergent) · occasion/need-state (3rd positioning grain) · standing inter-entity edges (competitor/partner/AOR —relationship_eventsexists, standing-edge table doesn't) ·content_region(non-video moments) · distinctive_brand_assets / proof-ladder · discipline DAG + per-shot crew-role vocab. - B) ALREADY BUILT (empty or rule-gap, NOT schema-gap → tag ✅VERIFIED): content_credit (role+conf+prov+discipline, 32 rows) · campaign_companies (role_type+dates) · event_participations (3-tier + award_name/category, 10 rows) · products (operates_as_brand+brand_entity_id+parent_product_id+lifecycle dates) · trackers + saved_searches.
- C) SUPERSEDED BY A SHIPPED DECISION (log in §6, do NOT re-add): content_groups (RM-5 campaigns-as-container) · projects (DN-130 Workspace) · services (RM-3) · collapse mentions/credits/sponsor (RM-2 "never collapse") · per-asset sponsor.
PHASE 2 — W1 FOUNDATION ✅ DONE (commits 8086988f6 + 7469f52f8) — folder + census + deltas + regenerator + handoff shipped; ⚠ boot-chain wiring deferred to W1.5 (the audit gap above)
Stood up the docs-as-code substrate (rename to docs/atlas/ + the wiring happens in W1.5):
docs/domain-model/skeleton —index.md(§0) + one file per pillar +relationships.md(§2) +pipelines.md(§3) +use-cases.md(§4) +decisions.md(§5) +homes.md(§6). Each = YAML frontmatter (machine facts: tables·edges·vocab·counts·status) + prose (human).scripts/domain-model-census.py— queriesinformation_schema/pg_catalog→docs/domain-model/_generated/schema-census.{json,md}: ALL 184 tables · 2,296 cols (type/null/default) · 200 FKs (the edge graph) · 598 indexes · 9 enums · schema_enums (973/83) · per-table rowcounts · junction-table detection. Run + commit = the complete "what's standing and where" map; regenerable = never stale.scripts/domain-model-drift.py— clone the proven 84-linescripts/schema_doc_drift.py(manifest-diff ·--liveJSON decoupling ·--check/--write); wire into/nightly-verify+/handoff.- VitePress site — new package/config rendering
docs/domain-model/; deploy a new Vercel project →model.brandtrackers.xyz(greenfield; separate from the Next app, NOT a/modelroute). +llms.txtagent entry. - Move
phase1-deltas.md→docs/domain-model/_research/(kill the /tmp loss-risk). - Register the
DOMAIN-MODELlane in INDEX §2; point INDEX §1 +.claude/CLAUDE.mdat the model as conceptual front-door (peer to INDEX). - Close W1 with: deployed skeleton site (preview URL ok) + committed census + drift-check green + handoff. → the confidence anchor.
PHASE 3 — W2 FOLD-IN (Workflow-orchestrated, adversarially verified)
Workflow: census 184 tables → map each table to a pillar (core / junction / legacy) → adversarially verify each mapping (2nd agent tries to refute) → fold bucket-B (✅VERIFIED) + bucket-A (§5 forks) + bucket-C (§6 settled) into the pillar files, every folded claim re-probed against the live DB before it lands. Apply §0 redlines. Output: a complete, tagged, table-backed model.
PHASE 4 — W3+ PILLAR PROSE + THE WALK
One/two pillars per window: full verified prose → Joe walks + rules the ~6 forks in full context (marks → decisions.md) → a TINY manual daily-review dogfood pass (3-5 real OpenAI items) validates each pillar against reality. The paused 24-card W2 console marks land in decisions.md.
PHASE 5 — HARDEN (fresh window)
Workflow adversarial conflict-verification across the whole model → resolve + archive the entity 6-doc chain + execute §6 demotions → re-audit pipelines against the finished model.
PHASE 6 — (PARKED) Daily human-in-the-loop curation loop — Joe's idea 2026-07-24
The EMPIRICAL validator (theory-from-docs ↔ practice-from-real-content). Scoped daily trickle (one brand · few channels · ~5-10 items/day), LOOK in the grid, DECIDE via CLI, STORE in a review_decisions log feeding §4/§5 + classifier prompts + schema_enums examples. GUARDRAILS: no Label Studio rebuild · master FALSE + ~$100/24h · classify in the REVIEW step not the broken pipeline. TIMING: repeatable machine after the model stabilizes; the tiny manual pass folds into Phase 4 now.
THE ~6 FORKS FOR THE WALK (§5 decisions.md)
- Add a Signal/Temporal pillar? (the thesis layer — biggest) · 2. Occasion/Need-State as a 3rd positioning grain? · 3. Company vs Product = separate positioning trees? · 4. Build the standing inter-entity edge table beside
relationship_events? · 5.content_regionfor non-video moments? · 6. Disciplines tree→DAG + a crew-role vocab? (+ the original entity product→brand threshold, grouping model, routing taxonomy, split-brain-vocab from the scaffold's §5.)
PROCESS + CONTINUITY (the 500k-token / sloppy-handoff fix)
KEEP INDEX.md + DEVELOPMENT-LOOP.md + /handoff + /resume-session — that hook-enforced machinery IS the multi-window continuity. DOMAIN-MODEL lane in INDEX §2; this plan file = the master; SPLIT across windows at verified milestones (never EXPAND one window to 500k).
GUARDRAILS (binding)
master_enabled FALSE · $0 AI / zero pipeline runs (census + drift are READ-only SQL; research read-only) · no schema/code/DB/console/FE-app changes — the census/drift scripts + the VitePress site are NEW infra (a separate static project), not edits to the app · per-file git add (never -A) · ground-truth-first (every delta re-probed; subagent claims are leads).
VERIFICATION (how W1 proves itself)
- census output matches the live probe (184 tables · 2,296 cols · 200 FKs · 598 indexes · 9 enums) — paste literal counts.
domain-model-drift.py --checkprints0 driftinside/nightly-verify+/handoff.- VitePress site loads (preview or
model.brandtrackers.xyz) and rendersdocs/domain-model/. phase1-deltas.mdexists underdocs/domain-model/_research/(NOT /tmp).- INDEX §2 shows the
DOMAIN-MODELlane; INDEX §1 points at the model.
Context — what's really being asked, and what already exists
Joe is asking for the conceptual layer that sits ABOVE the schema and the pipelines — the thing comparable platforms (Crunchbase, PitchBook, Bloomberg) call a domain model / ontology spec / data dictionary. His fear is founded; his Coda instinct (a table per noun, linked) IS the entity-relationship model; it just lives in his head and in ~17 partial docs, never reconciled into one spec.
Verified reality of the doc landscape (recon, file:line): there is NO single whole-system domain model. The system deliberately split into one-home-per-layer (the "Authority Map" declared in docs/specs/PRODUCT/TAXONOMY-CANON.md) — a sound pattern — but it covers taxonomy only. The pillars are never tied together, and three near-misses already exist:
docs/specs/PRODUCT/PIPELINE-MASTER-PRD.md(CANONICAL) already states Joe's three pillars — Brand & Identity / Campaigns / Content.docs/specs/PRODUCT/TAXONOMY-CANON.md(CANONICAL v2.2) is "the ONE dictionary of what every taxonomy layer MEANS" — taxonomy-scoped.docs/reference/briefings/2026-07-22-w2-substrate-walk/05-THE-MENTAL-MODEL.mdhas the atoms-and-assertions frame (unmaintained opinion).docs/specs/CANONICAL-SPEC-SET.md(SCAFFOLD, 2026-06-10) already declared the intended 8 canonical specs and was never executed — the exact consolidation now being asked for.- The entity/product/feature model is a 6-doc chain that CONFLICTS on "when does a product become a brand" (
ENTITY-PRODUCT-MODEL.mdparks it ·ENTITY-PRODUCT-FEATURE-ARCHITECTURE-2026-07-21.mdrules "kind=company stays, brand is a role" ·05-MENTAL-MODELreframes ownership as a disputed assertion) — all three live files.
So this is reconciliation, not greenfield, and not "delete 17 files." The deliverable is the missing TOP of the Authority Map: one conceptual constitution that (a) states the pillars + their relationships + the pipelines + the use-cases + the open decisions in one place, and (b) for every concept, points DOWN to its one authoritative home (keeping the good per-layer docs), and (c) resolves the entity conflict and demotes the superseded chain.
The deliverable: docs/DOMAIN-MODEL.md — the constitution (peer to docs/INDEX.md)
INDEX = "where things live." DOMAIN-MODEL = "what things MEAN and how they relate." Human-readable first, LLM-bootable second. Sections:
- §0 Thesis + pillar map (Mermaid) — the ~10 pillars and allowed edges (the Coda spider, made canonical). Reconciles PIPELINE-MASTER-PRD's 3 pillars with the finer pillar set.
- §1 The pillars — each in plain English + verified state + its authoritative home. For each: what it IS (Joe's voice), the table(s), the controlled vocabulary with live counts [VERIFIED this session], the OPEN decisions, and → the one doc that owns its detail. Pillars (all vocab verified 2026-07-24):
- Actors —
entity(company 1,639 · person 552 · song 125 · artist 122);company_typebrand_owner 27 · product_line 394 · agency 3 · creative_studio 5 · sub_brand 1 · 1,209 NULL (the vendor/buy-side is nearly empty — a coverage gap, not a model gap). Home:DATABASE/ENTITIES.md⚠drift-suspect. - Products — 139 (ai_model/ai_product/developer_platform/software); features tree +
product_feature_tagsjunction. "Product→brand" = OPEN (the 6-doc conflict; resolve here). Home:ENTITY-PRODUCT-FEATURE-ARCHITECTURE-2026-07-21.md. - Positioning — macro_sector 11 → sector 30 → industry 66 → category 240 (
company_categories);market_tier/market_segmenthomeless (W2-04). Market (product positioning) ≠ Audience (who content addresses) — stated once. Home:TAXONOMY-CANON.md. - Vendors & disciplines — agencies/studios/production as
entity+company_type;creative_disciplinestree (158: service→discipline→craft); credited viacontent_credit(role+discipline) andcampaign_companies(role_type, multi-role — W2-10). Home:TAXONOMY-CANON.md+CREATIVE-TAXONOMY-MASTER.md. - Groupings —
campaigns(21 active types incl.projectandpartnership_campaign, both defined-but-0-rows);events(observances/instances/participations); brand-identity = attributes an actor HAS, not a grouping (W2-17). One content item may belong to a campaign AND a project AND exhibit identity — simultaneously. Home:CAMPAIGN-DEFINITION.md. - Content —
content_item(96 cols) +content_itemsview. ⚠ Names the ~15 overlapping type/level/stage columns (content_type, primary_content_type, asset_type, media_type, page_type, element_type, content_level, marketing_level, funnel/journey/lifecycle_stage, messaging_type…) as a KNOWN sprawl to rationalize — this is the routing confusion made physical. Home:REVISED-PIPELINE.md+DB-PRIMITIVES-GLOSSARY.md. - Moments —
content_segment(grain) +content_scenes(detection) + segment classifications/categories (v1.1 shelves LOCKED). Home:MOMENTS-TAXONOMY-V1-BETA.md. - Channels — a column (
channel/platform/source_type; 16 active source_types), not a table. - Audiences —
content_audience_segments(21,249) +market_segmentvocab. - Concepts/vocabulary —
schema_enums(973 active, 83 axes). ⚠ See §3: the classifier does NOT read this at emit time.
- Actors —
- §2 The relationship matrix — every allowed edge as a row: source pillar → verb → target → junction/column → carries-provenance? → cardinality → which pipeline writes it. This is the single artifact that makes "fix-X-break-Y" a diff instead of a surprise.
- §3 Pipelines & routing — the honest map [VERIFIED in code], pointing at
CLASSIFICATION-PIPELINES.mdfor the row-level registry, and stating the four flows + their real gaps:- Content (mature): dispatch by
platform_type(dispatcher.py:85) → two-layer prompt route by source_type→content_category (content_routing.py:44) → per-format analyze (text/image/video/cluster) → classify → synthesize → scenes-classify. 21 lifecycle + 9 operational stages (pipeline_events.py:45). - ⚠ THE SPLIT-BRAIN VOCABULARY — emit-time vocab is hardcoded literals per format (
pipeline_analyze_text.py:58·_image.py:67·pipeline_analyze.py:224+ legacytaxonomy_validation.py:4); validate-time reads DBschema_enums(analysis_validator.py:124); kept in sync by hand. This is the mechanical root of "we authored a vocab and it does nothing" — authoring into the registry has zero emit effect until the hardcoded literals are replaced (the named chunk-6 prompt doctrine). - Entity onboarding — NO builder in code.
pipeline_onboard.py:695is a brand-guideline (logo/color/type) scraper needing a pre-existing entity; sector/products/hierarchy are minted only as an analysis side-effect (entity_auto_create.py:101,post_processor.py:1634). 90% of entities have NULL status. Charter only:ENTITY-ONBOARDING-PIPELINE-CHARTER-2026-07-21.md. - Campaign — two modes, both essentially absent as pipelines: onboarding-backfill grouping = hand-run
campaign_synthesis.py(nopipeline_executionsstage — GAP); real-time discovery from newsrooms/press = an explicit no-op stub (pipeline_intelligence.py:270"TODO(M4)"). Zero campaign code underbackend/routers|services. - Routing gap — dispatch is by SOURCE, never by intrinsic FORMAT; the "model-card PDF vs TVC" decision has no home. The content_type sprawl (§1 Content) is the symptom.
- Content (mature): dispatch by
- §4 Use-case walkthroughs — Joe's own examples traced end-to-end through §2 as the model's acceptance test: IBM × US Open (event + sponsor participation + 2 campaigns + 5 vendors with credits + cross-channel content + moments) · McDonald's × Minecraft (partnership_campaign, two brands, product/feature, press-release trigger) · OpenAI launch + the model-card PDF (routing) · vendor case-study scrape (Ogilvy/Buck → credits + disciplines + shots) · the newsroom link (real-time campaign trigger).
- §5 Open-decisions register — the genuine forks as questions, NOT pretend-resolved: product→brand threshold (resolve the 6-doc conflict) · grouping model (campaign/project/identity/loose) · routing taxonomy (creative content vs supporting material vs research artifact) · product/feature entity-vs-attribute · two-tier classification storage · unify the split-brain vocab. This is where W2 console marks get recorded as ratified logic — closing Joe's loop (one approval → one place updates).
- §6 The concept→home routing table + consolidation manifest — for every concept, its ONE authoritative doc; and the demotion list (from recon): keep
TAXONOMY-CANON,CLASSIFICATION-PIPELINES,MOMENTS-V1-BETA,SCHEMA.md,CAMPAIGN-DEFINITION,CREATIVE-TAXONOMY-MASTER; resolve+archive the conflicting entity chain; refresh (don't recreate) the pre-existingTAXONOMY-DOC-INVENTORY-2026-07-13.mdand the never-executedCANONICAL-SPEC-SET.mdscaffold.
Every factual line tagged: [VERIFIED <probe/file:line>] · [PROPOSED — your ruling] · [CONFLICT — doc A vs B]. Nothing asserted without a this-session tool result; decisions surfaced, never guessed.
Keeping it TRUE (the "markdown is a mess / LLM reads the wrong file" fix)
- Markdown stays the source (LLM-readable, diffable, drift-checkable). The fix is ONE conceptual front-door + a routing table down into the maintained per-layer docs + demotion of the conflicting ones — not a new format.
- Rendered as a site for human reading (MkDocs/Docusaurus generated FROM the markdown) — Joe gets his browsable/searchable "doc site"; the LLM gets clean markdown; same source. Fast-follow, not blocking.
- A drift-check —
scripts/domain-model-drift.py, sibling to the existingschema_doc_drift.py, verifies the doc's counts/vocab against the live DB so the constitution can't silently rot.
Sequencing vs the W2 console — DECIDED: the walk is PAUSED (Joe, this session)
The domain model now GATES the console walk. Joe does NOT walk the 24 cards until he has seen and corrected the domain-model scaffold, so every card is decided in full conceptual context instead of card-by-card on an "incorrect viewpoint." The console + its marks stay intact and untouched; when the walk happens (post-scaffold), the marks get recorded into §5 (the open-decisions register) so walking populates the constitution. Nothing about the console changes now — it simply waits.
Process — produced well, not spun
- Fresh-window job. A complete constitution deserves a clean context booted for it, not the tail of this long session. This session produces the SCAFFOLD (§0 pillar map · §1 one-liners with verified counts · §2 matrix headers · §3 pipeline list · §4 use-case titles · §5 open-Qs · §6 routing-table stub) so Joe corrects the STRUCTURE before any prose chapter is written.
- Authoring = one coherent voice (me), grounded in verified probes + the recon reconciliation — a domain model must read as one mind.
- Verification = a workflow AFTER the draft — every factual claim re-probed, every "doc says X" checked for conflict (the "actually looked at everything" guarantee), adversarial. Draft → then harden.
This session vs the next window — DECIDED: scaffold now + full next (Joe)
- Now (this session, on approval): write
docs/DOMAIN-MODEL.mdas the scaffold — §0 pillar map (Mermaid) · §1 each pillar's plain-English one-liner + verified counts + its authoritative-home pointer · §2 relationship-matrix headers (a first pass at the rows, marked PROPOSED where not yet verified) · §3 the pipeline/routing reality with the split-brain-vocab and format-routing gaps [VERIFIED file:line] · §4 the five use-case titles (walkthroughs stubbed) · §5 the open-decisions register (incl. the entity 6-doc conflict, the 24 console cards mapped in) · §6 the concept→home routing table + the consolidation/demotion manifest. Every line tagged VERIFIED/PROPOSED/CONFLICT. This is the doc Joe reviews and corrects. No full prose chapters, no schema, no code, no console/FE changes. Commit + push (docs-only). - Next window (fresh context, after Joe corrects the scaffold): full prose per pillar (verified) → the verification workflow (re-probe every claim, adversarial conflict-check) → resolve+archive the entity chain and execute the §6 demotions → the site render (MkDocs/Docusaurus) +
domain-model-drift.py→ re-audit the pipelines against the finished model → THEN Joe walks the 24-card console into §5.
Verification
- Every count/vocab/relationship in the scaffold traces to a this-session probe or recon file:line — zero inherited-from-memory claims (tagged inline).
- Reconciles, not duplicates: each existing domain doc appears in §6 with a keep/demote/resolve disposition; the entity conflict is named with its three positions.
- The pillar map (§0) round-trips against the matrix (§2): every pillar has ≥1 edge; every edge joins two named pillars.
- Nothing else touched: no schema, code, console, or FE; the 24-card console and its marks stay intact.