sparring snapshot · v1 · 2026-04-15

AVPv1 brain · skills · personas · spine

The canonical read-first handoff for the v3 framework. Three redundant repos (atlas, monitor, v3) feed this. Not a commitment log — a sparring snapshot.

sparring mode: ON "make it so" not said opus 4.6 · 1M context committed 769251f · pushed · brain-ingested (39 chunks)

§0Name decision

Working title is AVPv1 (Anti-Vibing Patterns v1). Three alternatives below. Pierre picks.

AVPv1

Anti-Vibing Patterns v1

For: Catchy, culturally positioned against vibe-coding.

Against: Defines by opposition. "Vibe" is a meme — dates weirdly. No-hype rule cuts against clever framings.

Hive v1

Pierre's own tsoftwa metaphor.

For: Distributed sessions as workers, brain as colony memory. Positive framing. Short.

Against: "Hive mind" is a tech cliché.

Invariant v1

Points at the load-bearing concept.

For: Session invariants hard, pipeline invariants soft — the thing that makes this not vibe-coding. Quietly technical.

Against: Dry. Less memorable.

Tsoftwa v1

The book metaphor, all in.

For: Unique. No collision. Carries the metaphor as the name.

Against: Unpronounceable cold. Inside-joke risk.

§1Core metaphor

Tsoftwa — the soul of the white ant. One mind distributed across workers (sessions). Each session sees the whole colony's knowledge and contributes back.

Situated cognitive guidance — not automation

Not Zapier. Not IFTTT. This is situated cognitive guidance — clarifies what's invariant while the human decides. The system doesn't execute predetermined workflows; it enhances the human's capacity to work through their own process.

Academic grounding: Activity Theory. The invariant chains map to actions (stable across tools). Operations are fluid and technology-adoptable.

Source: mcp-and-skills-framework-and-brain-v3/research/invariant_driven.md

§2Three pillars

Brain · Nervous system · Distribution. Three structural roles, clean separation.

🧠 Brain = PostgreSQL

Single substrate on Hetzner (100.97.123.98), docker container postgres, accessible via Tailscale. pgvector + JSONB + stored procedures + full-text search + HNSW indexes.

Triple-index: pgvector + LanceDB + Tantivy. LanceDB non-negotiable for voice features.

Container
postgres (docker on cax31)
Access
ssh root@100.97.123.98 → docker exec postgres psql
Read-only role
claude_ro (views only, secrets blocked)
Write role
acebuddy (full, audited via audit_log)
🧬 Nervous system = MCP + skills + CLAUDE.md
  • MCP for discovery — what can the system do? Browse via brain:// resources.
  • Skills for procedure — how do you do it? Native Claude Code SKILL.md format.
  • CLAUDE.md for declarative context — what does a new session need to know?
Rule: Do NOT expose skills through MCP. Kills progressive disclosure. Complementary, not stacked.
🌐 Distribution = git + Tailscale

Skills + code + markdown in git (this repo + others). Dynamic state in Postgres on Hetzner, via Tailscale. Git is the distribution mechanism. Postgres is the runtime truth.

Never install Claude Code on Hetzner. Production surface, not dev surface. Admin only via SSH from dolphin or spud2.

§3Personas (cognitive scaffolding)

Named characters, not role tags. ADHD-friendly handles for parallel threads. Check-in-ability is as important as silent work.

Non-negotiable: Personas = named characters. Never strip to "just a subsystem." Bidirectionality required — a persona that only logs but can't be queried is half-built.

Two tiers, one table

TierBindingExamplesCreationDeletable?
SystemHooksSession Boss, Librarian, Auditor, Cop, ArchivistHard-coded, seeded on installNo — type='system'
UserSkillsSteve (APIs), future Dave (DBs), etc./persona create Name 🎯 "job"Yes

System persona roster

🕴️
Session Boss
Session invariants (purpose, mode, budget), prime load
SessionStart hook · writes sessions row
📚
Librarian
Per-turn raw logging, handoff append, budget tick
Stop hook · writes turns row
🧑‍⚖️
Auditor
Session close: classification, ratings, mistake detection, proposals
/done skill · async batch
👮
Cop
Drift detection — AI + user. 3+ events → checkpoint
Background per turn · writes drift_events
💾
Archivist
Commit + rollback. Local per-turn, push at close, /undo
PostToolUse + SessionEnd

Reserved (gated by use case)

💰
Accountant
Resource tracking (mem/disk per-process)
Timekeeper
Wall clock + prediction calibration
🔬
Workbench Boss
Data workbench pipeline owner
🛒
Grocer
Grocery pipeline owner
📧
Postmaster
Email pipeline owner

Provisional (user-creatable example)

🔧
Steve
Specialist in Pierre's API surface — scans repos, flags usage, writes learnings
User-created · skill-bound · on-demand
The four behaviours every active persona has
  1. Turn-footer commentary — writes one line on every turn, even "nothing to report." Silence kills the feature; the log is what makes check-in possible.
  2. Check-in (on-demand query) — natural language: "Steve, status?" → pulls last ~20 rows from persona_comments WHERE persona_name='Steve'.
  3. Specialist work (on-demand) — invoke by name; persona's bound skill fires; scans repos/brain/resources; writes a learnings row as byproduct. Steve only exists when invoked. NOT a background bot.
  4. Broadcast participation/broadcast fires all actives; each gets ~1000 tokens to report; collated into one chat block. Explicit tool, NEVER auto-fires.

Example footer:

---
🔧 Steve (APIs): no external calls this turn
📚 Librarian: turn 17 queued
👮 Cop: no drift
Invariant split — hard vs soft

Session invariants HARD. Session Boss enforces. No drift. Examples: declared purpose, mode (sparring / execution / debug), budget cap.

Pipeline invariants SOFT. Outcome chains, not schedules. Each link checked at runtime; break → ntfy the pipeline's persona.

Groceries  =  need → captured → bought → dispatched → eaten
Research   =  question → queried → answered → extracted → stored
Email      =  arrived → triaged → digest → delivered → decided
Workbench  =  data → cleaned → analysed → reported → acted on
Auditor rating — three categories, no proliferation

At session close, each persona_comments row gets a rating:

useful | noise | wrong

Three categories only. No KPI proliferation. No "persona quarterly reviews." Pierre's stated boundary — locked.

§4Skills framework

Strangler fig at skill granularity. MCP for discovery, skills for procedure, CLAUDE.md for declarative context.

Architecture decisions (agreed across sessions)
  • Strangler fig at skill granularity — production-proven (VS Code, Obsidian, Neovim, Home Assistant).
  • Use-case-first, not infrastructure-first. Reject the research's bootstrap order (read-file → query-db → register-skill). Start with domain skills.
  • Lazy load ceiling: 5–8 active skills per session. Beyond that, measurable degradation.
  • Delivery: MCP-first, not hook-first. One MCP tool semantic-search-skills(query, k) hits capability_view.
🟡 OPEN QUESTION — canonical SKILL.md format

Two candidates. Pick one (or adopt both in layers).

Candidate A — native Claude Code (minimal)

---
name: skill-name
description: one-liner with triggering keywords
---

Full body as markdown — prose, examples, commands.

Candidate B — rich metadata (from research)

skill:
  id: "skill-name"
  version: "1.0.0"
  description: "what it does"
  keywords: ["tag1", "tag2"]
  category: "data-access|meta|domain|..."
  inputs: [{name, type, required}]
  outputs: [{name, type}]
  trust_level: "untested|trusted|verified|critical"
  cost_estimate: {tokens: 500, usd: 0.002}
  dependencies: ["postgres:brain", "mcp:vector-search"]
  last_tested: "2026-04-15"
  health: "healthy|degraded|broken"
Sparring recommendation: Use A for user personas + routine skills (discoverability via Claude Code native). Layer B on top via brain DB skills table when governance is needed (trust levels, health, cost budgets).
Current state on disk (honest inventory)
LocationCountFormatStatus
~/.claude/skills/72native SKILL.mdlive GSD family + utility
projects/pierre-ops/skills/2SKILL.mdlocal only
projects/mentor-workbench/skills/2Python modulesNOT SKILL.md can't auto-discover
projects/acebuddy/scripts/hooks/9 bashNOT skillsdormant 0 registered
brain DB skills table40+DB metadatareferenced in atlas PROPOSAL
Lock-it-in gate (future process)
  1. Dry run — mocked deps, no side effects.
  2. Integration test — real tools, controlled data.
  3. Register — insert into Postgres skills with trust_level='verified'; update CLAUDE.md.
  4. Health monitor — weekly test runs; degrade trust_level on failure.
  5. Breaking-change detection — re-test all dependents when a dependency changes.
Persona ↔ skill binding (the integration)

A user persona like Steve = one row in personas + one SKILL.md with his system prompt, scope, and tools.

  • Persona name = the handle. /ask Steve, "Steve, status?", turn-footer 🔧 Steve (APIs): ...
  • Skill = the capability. System prompt, tools, output shape.
  • Collaboration = skill composition. "Steve + Dave, work on X" → both skills fire in parallel → outputs collate. No new infra.
Skill-builder meta-tool (open gap)

Identified in monitor research (Apr 14, skill-framework-migration/output.md). The draft → extract → test → version → share loop has no tool yet. Not urgent. Future work.

§5Brain DB schema v2

Canonical base doc: atlas/MIGRATION.md (22 KB, 17 decisions, 0% deployed). Amendment below adds the tables personas + sessions need.

The 6 universal columns on every table
-- Template for every v2 table
CREATE TABLE v2.example (
    id           UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
    status       TEXT NOT NULL DEFAULT 'active'
                 CHECK (status IN ('active','inactive','archived','superseded')),
    source       TEXT,
    metadata     JSONB NOT NULL DEFAULT '{}'
);
id
UUID primary key. Portable, merge-safe.
created_at
Immutable after INSERT.
updated_at
Maintained by v2.set_updated_at() trigger.
status
4 values. Replaces 4 inconsistent soft-delete patterns.
source
Provenance — 'manual', 'bot:weather', 'migration:v1', 'workbench:wb-...'
metadata
JSONB. Prevents new columns for edge cases.
Temporal versioning — valid_from, valid_to, _history

Every table gets system-period temporal columns for full history.

ALTER TABLE v2.example ADD COLUMN
    valid_from TIMESTAMPTZ NOT NULL DEFAULT now(),
    valid_to   TIMESTAMPTZ NOT NULL DEFAULT 'infinity';

CREATE TABLE v2.example_history (LIKE v2.example INCLUDING ALL);

-- Trigger on UPDATE copies OLD to history with valid_to = now()

Time-travel query:

SELECT * FROM v2.entities
WHERE valid_from <= '2026-03-15' AND valid_to > '2026-03-15';
Dual scoring — confidence (machine) + importance (human)

Every content-bearing table:

confidence  FLOAT,      -- Machine-generated, 0.0–1.0
importance  INTEGER,    -- Human-assigned, 1–5 (Pierre)
  • confidence set by ingest pipelines. Transparent. Never a hidden filter.
  • importance set by Pierre manually. Overrides machine scoring.
  • Both VISIBLE in all search results. User sees 50 results, not 5.
🟡 AMENDMENT — tables missing from MIGRATION.md (sessions + personas)

These block the v3 framework. Follow universal standards (6 cols + temporal triggers where applicable).

v2.sessions
CREATE TABLE v2.sessions (
    -- 6 universal columns
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    status          TEXT NOT NULL DEFAULT 'active'
                    CHECK (status IN ('active','ended','abandoned','archived')),
    source          TEXT,
    metadata        JSONB NOT NULL DEFAULT '{}',

    -- Session-specific
    project_path    TEXT,
    purpose         TEXT,                 -- declared by Session Boss
    mode            TEXT,                 -- 'sparring'|'execution'|'debug'
    started_at      TIMESTAMPTZ NOT NULL,
    ended_at        TIMESTAMPTZ,
    turn_count      INTEGER DEFAULT 0,
    tokens_total    INTEGER DEFAULT 0,
    budget_cap      INTEGER,

    -- Temporal
    valid_from      TIMESTAMPTZ NOT NULL DEFAULT now(),
    valid_to        TIMESTAMPTZ NOT NULL DEFAULT 'infinity'
);
v2.turns
CREATE TABLE v2.turns (
    -- 6 universal columns
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    status          TEXT NOT NULL DEFAULT 'ok'
                    CHECK (status IN ('ok','errored','archived')),
    source          TEXT,
    metadata        JSONB NOT NULL DEFAULT '{}',

    -- Turn-specific
    session_id      UUID NOT NULL REFERENCES v2.sessions(id),
    turn_num        INTEGER NOT NULL,
    started_at      TIMESTAMPTZ NOT NULL,
    ended_at        TIMESTAMPTZ,
    user_message    TEXT,
    assistant_response TEXT,
    tokens_in       INTEGER,
    tokens_out      INTEGER,
    tool_calls_count INTEGER DEFAULT 0,
    error_note      TEXT,

    -- Auditor fills async
    classified_at   TIMESTAMPTZ,
    classification  JSONB,

    UNIQUE(session_id, turn_num)
);
v2.personas
CREATE TABLE v2.personas (
    -- 6 universal columns
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    status          TEXT NOT NULL DEFAULT 'active'
                    CHECK (status IN ('active','inactive','archived')),
    source          TEXT,
    metadata        JSONB NOT NULL DEFAULT '{}',

    -- Persona-specific
    name            TEXT NOT NULL UNIQUE,
    emoji           TEXT NOT NULL,
    job             TEXT NOT NULL,
    scope           TEXT,
    tier            TEXT NOT NULL CHECK (tier IN ('system','user')),
    skill_binding   TEXT,
    created_by_session UUID REFERENCES v2.sessions(id)
);
v2.persona_comments
CREATE TABLE v2.persona_comments (
    -- 6 universal columns
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    status          TEXT NOT NULL DEFAULT 'active',
    source          TEXT,
    metadata        JSONB NOT NULL DEFAULT '{}',

    -- Comment-specific
    persona_id      UUID NOT NULL REFERENCES v2.personas(id),
    session_id      UUID NOT NULL REFERENCES v2.sessions(id),
    turn_id         UUID REFERENCES v2.turns(id),
    turn_num        INTEGER,
    comment         TEXT NOT NULL,

    -- Auditor fills at session close
    rating          TEXT CHECK (rating IN ('useful','noise','wrong',NULL)),
    rated_at        TIMESTAMPTZ,

    UNIQUE(persona_id, session_id, turn_num)
);
v2.drift_events
CREATE TABLE v2.drift_events (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    status          TEXT NOT NULL DEFAULT 'active',
    source          TEXT,
    metadata        JSONB NOT NULL DEFAULT '{}',

    session_id      UUID REFERENCES v2.sessions(id),
    turn_id         UUID REFERENCES v2.turns(id),
    drift_type      TEXT NOT NULL CHECK (drift_type IN ('ai','user')),
    detail          TEXT,
    triggered_checkpoint BOOLEAN DEFAULT false
);
Other pending migration items (from MIGRATION.md)
  • Event-sourced ingest pattern — decision #14 flagged "RESEARCH NEEDED before committing."
  • status column on v1 learnings — required to triage 973 unreviewed rows. Blocked on migration.
  • github_repos sync — currently 8 rows, actual ≈60. Fix before atlas Phase 1.
  • claude_sessions sync — broke 2026-04-05. Fix.
Target schema overview — 41 tables from 122 (full breakdown)
DomainTablesNotes
Identity & Relationships6entities, entity_links, contacts (+ channel discriminator), user_profiles, concerns (the spine, 9 entries), concern_manifestations
Knowledge & Memory5learnings, memory, scratchpad, documents (consolidates 5 v1 tables), chunks (pgvector)
Communication3messages (consolidates email/whatsapp/matrix via channel), message_actions, sync_state
Bots & Skills6bot_registry, bot_actions, skills, teams, team_members, team_workflows
Finance5accounts, envelopes, transactions, budgets (consolidates 3), payees
Health & Wearables2health_events, wearable_data (consolidates 9 fitbit + oura tables)
House3properties, rooms, house_items (+ house_systems folded)
Grocery3recipes, recipe_ingredients, grocery_regulars (already well-structured)
Reflector & Embeddings2reflector_entities (1.3M rows), reflector_analytics (consolidates 5)
Infrastructure7audit_log, workflow_runs, cost_ledger, resource_snapshots, task_queue, invariant_events (NEW), alembic_version
Projects & Planning3projects (consolidates 6), experiments, datasets
External Integrations3github_repos, claude_sessions, sso_apps
Assets2assets, asset_links
Workbench3workbench_sessions (+ parent_session_id for chaining), workbench_learnings, workbench_discoveries
Ingest2ingest_sources, ingest_log
V3 amendment (this doc)+5sessions, turns, personas, persona_comments, drift_events
Total41 → 46 with amendment

§6Session spine (the smallest nervous system)

Pierre's ruling (2026-04-14, session 2861cad1 line 79): "spine first. let's make that solid. start with a small spine and then enlarge it."

Tier A — the smallest spine (proposed first sprint)

Three files. Nothing else. Schema contract is the hard-to-change surface; bash hooks are trivial.

mcp-and-skills-framework-and-brain-v3/
  migrations/
    001_spine.sql          -- v2.sessions + v2.turns (6 universal cols + triggers)
~/.claude/hooks/
  session-start.sh         -- INSERT session row via SSH + docker exec, exit
  stop.sh                  -- INSERT turn row via SSH + docker exec, exit

Then register both in ~/.claude/settings.json.

Smoke test: new session → 1 session row exists → 3 turns → 3 turn rows exist. Fail loud on DB connectivity / write failure.
Tier B — additive, won't force schema changes
  1. Tailscale pre-flight — hook verifies tunnel before brain ops. Lives inside session-start.sh as bail condition.
  2. Budget tracker — derived: SELECT SUM(tokens_in+tokens_out) FROM v2.turns WHERE session_id=$1. No state needed.
  3. Handoff auto-append — soft contract. session-start.sh opens HANDOFF.md for append; stop.sh writes turn summary.
  4. Write-failure flagging + retry queue — metadata flag on turns row; periodic retry skill.
Tier C — deferred until Tier A proves solid
  1. Persona declarations, /persona create skill, footer enforcement
  2. Statusline control board (budget, turn count, active personas, brain write status, time)
  3. Auditor /done skill (batch classification, ratings, mistake detection)
  4. Cop drift detector (background per turn, checkpoint at 3 events)
  5. Archivist commit + push + /undo
  6. Time hook (wall clock + prediction-vs-actual calibration)

§6bHooks — the dormant spine discovery (2026-04-15)

9 bash hooks already written in acebuddy/scripts/hooks/. None registered in settings.json. Targets acebuddy-specific concerns (fleet health, ARM64 migration, SLO metrics) — NOT the v3 spine.

Don't conflate: these are useful references for the pattern (especially session-cost-log.sh + error-logger.sh). The v3 Tier A hooks should be NEW, targeted at v2.sessions / v2.turns.
The 9 dormant hooks
FileExistsRegisteredWhat it does
session-start.shInjects orientation (git branch, fleet health, ARM64 phase, audit entries, SLO). Caches state.
session-end.shLogs session end to audit_log if >5 tool uses. Cleans temp.
skill-tracker.shPostToolUse. Parses Skill invocations, logs to audit_log with skill name + args.
error-logger.shPostToolUse. Detects Bash failures. Injects guidance nudge after 1st error, then every 3rd.
post-compact.shRe-injects S4-NO_DESTROY, A1-AUDIT_TRAIL, O1-REGISTRY_TRUTH after compaction.
session-cost-log.shSessionEnd. Parses session jsonl, calculates Opus API-equivalent cost token-by-token.
ntfy-notify.shntfy integration.
progress-check.shPurpose unclear from filename.
verification-gate.shPurpose unclear from filename.
Tier A hook stubs (sketch — not written yet)

session-start.sh

#!/bin/bash
# v3 Tier A: SessionStart hook — writes v2.sessions row

SESSION_ID=$(cat /proc/sys/kernel/random/uuid)
PROJECT_PATH="$CLAUDE_PROJECT_DIR"
STARTED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

ssh root@100.97.123.98 "docker exec postgres psql -U acebuddy -d brain -c \"
INSERT INTO v2.sessions (id, project_path, started_at, source, mode)
VALUES ('$SESSION_ID', '$PROJECT_PATH', '$STARTED_AT', 'claude-code', 'sparring');
\"" || {
  echo '{\"hookSpecificOutput\":{\"hookEventName\":\"SessionStart\",\"additionalContext\":\"⚠️ BRAIN WRITE FAILED — session not logged\"}}'
  exit 2
}

echo "$SESSION_ID" > /tmp/claude-session-id
exit 0

stop.sh

#!/bin/bash
# v3 Tier A: Stop hook — writes v2.turns row after every turn

SESSION_ID=$(cat /tmp/claude-session-id 2>/dev/null)
[ -z "$SESSION_ID" ] && exit 0   # no session? no turn.

TURN_NUM=$(ssh root@100.97.123.98 "docker exec postgres psql -U acebuddy -d brain -tAc \"
SELECT COALESCE(MAX(turn_num),0)+1 FROM v2.turns WHERE session_id='$SESSION_ID';
\"")

# (read turn data from $CLAUDE_TRANSCRIPT_PATH, extract tokens/tool calls)
# (INSERT v2.turns row)

exit 0

Actual implementation: escape properly, fail loud on DB error, extract tokens from transcript.

§7Honest inventory — spec vs built vs registered

LayerSpecBuiltRegisteredConfidence
v2 schema base (atlas)❌ 0 tables95%
v2 amendment (this doc)✅ NEW95%
Skills framework arch⚠️ partial⚠️ 72 in ~/.claude/skills/85%
SKILL.md canonical format❌ 2 candidatesOPEN
Personas — two tiers, four behaviours✅ designed95%
/persona create skill✅ shape agreed90%
Session spine (Tier A)✅ scoped99%
Dormant acebuddy hooks✅ 9 files❌ 0 registered99%
Brain MCP server⚠️ stub failingper atlas

§8Open sparring questions

Decreasing blocking-ness. Next Claude picks any of these up — or Pierre says the words.

🟡 1 — Persona proliferation cap
5 systems + N user personas. Is N capped? Cognitive ceiling? Leaning: no hard cap, but a soft "too many at once" warning at ~10.
🟡 2 — Footer writer: Claude or Stop hook?
Claude writes, Stop hook validates presence and scolds if missing? OR Stop hook writes from a template? Leaning: Claude writes (flexible), hook validates (reliable).
🟡 3 — Check-in invocation syntax
Natural ("Steve, status?") vs explicit (/ask Steve) vs both. Leaning: natural only; learn the pattern.
🟡 4 — System + user personas in one table?
Same table with tier discriminator (proposed) vs separate tables. Leaning: same, with active BOOLEAN to protect system personas.
🟡 5 — Canonical SKILL.md format
Native Claude Code minimal vs rich metadata schema. Leaning: native for discoverability + layer rich metadata via brain skills table for governance.
🔒 6 — Auditor rating categories
useful · noise · wrong. Locked at three? Pierre's stance: yes. No HR-for-imaginary-people.
🟡 7 — Broadcast budget
5 personas × 1000 tokens = 5k per /broadcast. Cap or per-persona configurable?
🟡 8 — Turn-classification schema
Fields, trigger, who fills. Librarian queues raw; Auditor classifies async batch at close.
🟡 9 — Stack shorthand
brain/wiki/stack.md (~18 KB estimated — Hetzner + spud2 + dolphin + brain DB + pipelines + connexions + env + vocabulary + norms). Not yet written. Blocks full prime load.
🟡 10 — Connexion intake protocol
7 questions drafted (monitor), not formalised as skill.
🟡 11 — Event-sourced ingest
Flagged "RESEARCH NEEDED" in MIGRATION.md §14.
🟡 12 — Triage policy for 973 existing learnings
Needs status column migration first.
🟡 13 — session_id format
UUID (proposed) vs acebuddy prefix (e.g. ses_20260415_v3_spine). Leaning: UUID for cross-project portability + store a human tag in metadata.
🟡 14 — Where /persona create skill lives
User scope (~/.claude/skills/) so all Claude sessions can create personas, vs repo scope.

§9Proposed first sprint

Tier A only. One focused day of work, IF Pierre says "make it so."

The work (6 items, ~1 day)
#ArtifactEffort
1migrations/001_spine.sql — v2.sessions + v2.turns with 6 cols, triggers, temporal. Run against brain DB.2 hr
2~/.claude/hooks/session-start.sh — INSERT session row, fail loud2 hr
3~/.claude/hooks/stop.sh — INSERT turn row, fail loud2 hr
4Register both in ~/.claude/settings.json15 min
5Smoke test: new session → 1 session row → 3 turns → 3 turn rows30 min
6Commit + push this repo15 min
Exit criteria: every future session has complete turn lineage in brain DB. No lost context. No orphan rows.
NOT in Tier A: personas, Auditor, Cop, Archivist, statusline, budget enforcement, Tailscale pre-flight. All ride on top without touching the sessions/turns contract.
Pre-execution checklist
  • [ ] Pierre confirms Tier A framing (implicit yes on Apr 14; re-confirm)
  • [ ] Confirm migrations at mcp-and-skills-framework-and-brain-v3/migrations/
  • [ ] Confirm hooks at ~/.claude/hooks/ (user scope, cross-project)
  • [ ] Confirm connection: SSH + docker exec postgres psql -U acebuddy -d brain
  • [ ] Decide session_id format (Q13)
  • [ ] Decide whether to include personas + persona_comments in 001_spine.sql (include-as-empty) or separate 002_personas.sql later
  • [ ] Decide whether spine runs in v2 schema or separate spine schema (leaning: v2 — one cutover path)

§12References

Primary sparring logs
  • atlas/MIGRATION.md — schema v2 spec (canonical base)
  • atlas/PROPOSAL.md — skill layer + spine architecture (outdated on delivery mechanism; extension approach still correct)
  • atlas/HANDOFF.md — atlas session 3 (MCP-first correction)
  • atlas/research/validation/VALIDATION.md — proposal critique
  • atlas/research/orchestration/answer.md — multi-session orchestration research
  • mcp-and-skills-framework-and-brain-v3/.planning/HANDOFF.md — Apr 13 architecture sparring
  • monitor/HANDOFF-session-2.md — Apr 14 personas + four-block sparring
  • monitor/sparring-deploy/spoken-script.txt — 7-min MP3 narration source
  • Session 2861cad1-5ab5-4a0d-86c0-8ac9172756c0.jsonl lines 33–83 — Steve/personas deep sparring (Apr 14 evening)
Research outputs (Perplexity sonar-deep-research)
  • monitor/results/skill-framework-migration/output.md — strangler fig validation, skill-builder gap
  • monitor/results/brain-db-skill-integration/output.md — MCP + read-only views, three-tier write pattern
  • mcp-and-skills-framework-and-brain-v3/research/invariant_driven.md — Activity Theory grounding, five-layer arch
  • mcp-and-skills-framework-and-brain-v3/research/hive_mind.md — distributed cognition, LISTEN/NOTIFY, offline-first
  • mcp-and-skills-framework-and-brain-v3/research/skills_first.md — skill metadata, lock-it-in gate
Memory anchors

At ~/.claude/projects/C--Users-acebu-projects/memory/:

  • user_persona_cognitive_style.md — the non-negotiable cognitive rule
  • feedback_satisficing_redundancy.md — why three repos are not to be consolidated
  • project_v3_framework_state.md — sparring state snapshot (points here)
  • reference_v3_canonical_handoff.md — where this doc lives
  • reference_atlas_brain_v2.md — atlas hub pointer
  • reference_ingest_api.md — brain DB ingest endpoint
Deployed artifacts