Chain · Explicit push — AI conversations become a curated corpus

Updated · View the entry on sijie.xyz ↗

L0 · Vision

  • thesis — AI conversation is the primary input; the loop: agentically curate the good parts → push via MCP → corpus accumulates. Two load-bearing choices, verbatim: "Explicit push, not automatic capture" and "Curated corpus, not raw transcript dump."
  • ai-conversation-is-the-substrate — the thinking substrate migrated into the chat log, which is private and ephemeral.
  • why-now — (b) MCP makes agentic ingestion ergonomic.
  • introduction — "the act of attaching it is the trust boundary; never scraped."

L1 · Promise

Nothing enters except what the owner deliberately curated and pushed; the private substrate becomes a durable public-facing layer only through deliberate acts.

L2 · Requirements (journeys & features)

The owner curation journeys — the raw→wiki→output promotion chain. Feature surfaces: admin Raw / Wiki / Output / Subjectivity / Writings (app/src/components/admin/sections/); the service-handle tools (StandMeet-as-MCP-server — see confusables): corpus.create / update / delete / promote with the genre as a parameter (the old per-tier promote_to_wiki / promote_wiki_to_output collapsed on 2026-08-01, 27a407e31; backend/internal/corpus/ops), plus writings.save / publish / unpublish and subjectivity.write; the admin Obsidian surface as the second ingestion route.

L3 · Design decisions

  • Curation is a pipeline, not a dump — three-tier-corpus-promotion: entries are promoted raw→wiki→output; the tiers make "curated, not dumped" structural.
  • derived-path-corpus-as-filesystem — parent_id tree, paths derived; backlinks-as-rebuilt-edge-tables — wiki_refs rebuilt declaratively from [[wikilinks]].
  • Push rides the service handle — the owner's AI session pushes through StandMeet-as-MCP-server (as-mcp-facade, the outward plane — NOT the agent's capability plane; see capabilities), authenticated by owner-keypair-auth Sigv1; the keypair is the trust anchor of agentic ingestion.
  • The vault route — writings-import-export / obsidian-sync-mechanism, the actual mechanics (verified at 36789537d): manual, batch, no watcher — streamed zip export / whole-vault multipart import (authoritative form field decides prune vs upsert, routes/admin/obsidian.go:262); every routed .md persists — frontmatter publish is not an import gate, it only feeds the published column that gates the anonymous reader (backend/internal/corpus/obsidian/sync.go:13-16); idempotency key = obsidian_source_path; the web-edit guard skips any row edited on the web after the last import. It is a sync-mode connector since 2026-07-08 (d51805372: connector.NewSyncConnector + SyncIngester, backend/internal/connector/sync.go:41-62; /obsidian/import delegates through it, routes/admin/obsidian.go:221).

L4 · Engineering artifacts

  • Tables: one corpus_notes table with a genre column (raw / wiki / output / subjectivity / writing) + the note_refs edge table (+ writing_refs for the writings genre) — backend/db/schema.sql.
  • Queries/usecases: backend/db/queries/corpus/*.sql, backend/internal/corpus/{usecase,ops,repo} (the domain-module layout, backend-domain-modules).
  • MCP surface: routes/mcphandle (tools registered via OwnerMCPBindings, backend/internal/capabilities/capreg/registry.go, as-mcp-facade).
  • The obsidian subsystem: backend/internal/corpus/obsidian/ (sync.go, sync_classify.go, sync_note.go, export_corpus.go) + routes/admin/obsidian{,_multipart,_state}.go, behind connector/sync.go.

L5 · Verification

Promotion-chain and admin-corpus e2e exist; service-handle (Sigv1) auth covered. The vault route is no longer the weak level: seventeen e2e/test/sync-*.spec.ts files at 36789537d (routing, tree, title, publish, links, alias-links, frontmatter, hidden, reconcile, raw, export, authoritative-prune, large-vault, subjectivity), so the backlink rebuild (writings-import-export) has its own specs (sync-e-links, sync-e-alias-links).

Status & gaps

Writings: push + export/import landed in both directions. Wiki, subjectivity and raw are wired to the vault too — SyncVault routes by top-level folder (obsidian/sync.go:2, sync_classify.go:64); output stays promote-derived on the way in, and the reverse export writes wiki/subjectivity/output back as genre folders (export_corpus.go, 9f1ffcf13, 2026-07-29). No watcher/live sync — batch by current design; the route is already a sync-mode connector, so that is the remaining step, not a re-plumbing. The "curated not dumped" stance is enforced by structure (tiers + the published reader gate), not by review — deliberate.

Related notes