Files
dotfiles/claude/memory/bmf-summarizer-contract.md
T
David F GliddenandClaude Opus 4.7 119285cf43 claude: back up custom skills, memory, and settings with symlink pattern
The ~/.claude/ directory was previously local-only — a machine wipe
would have lost the accumulated memory, custom skills, and settings.
This commit moves the durable parts into dotfiles with the same
symlink-to-home pattern used for CLAUDE.md, PENDING.md, REVIEWED.md,
and L2-BOOTSTRAP.md.

Preserved (symlinked from ~/.claude/* into here):
  skills/audit/              — thinking-folder drift scanner
  skills/symmetria/          — practice-of-return discipline
  skills/vault-update-people/ — Obsidian People-file maintainer
  skills/wake-up/            — session restoration
  skills/wrap-up/            — session state capture
  memory/                    — 55+ memory files (MEMORY.md, sessions,
                               ledgers, project state, feedback, etc.)
  settings/settings.json     — user preferences (hooks, flags, no secrets)

Deliberately NOT backed up:
  settings.local.json   — contains operational secrets (HF_TOKEN,
                           SSH password in expect scripts); by naming
                           convention, *.local.* is not synced.
                           Needs separate review and probable rotation.
  sessions/, history.jsonl, caches, telemetry — ephemeral
  plugins/, marketplace skills and agents — reinstallable

The working copies at ~/.claude/skills/* and
~/.claude/projects/-Users-davidglidden/memory are symlinks into this
directory, so every write flows here automatically. install.sh
recreates the symlinks on a fresh machine.

FOLLOW-ON (flagged, not in this commit):
  settings.local.json contains a HuggingFace token and an SSH password
  as plaintext strings inside allowed Bash command patterns. These
  should be rotated and moved to secure storage (keychain / pass /
  env file outside the settings file).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 13:51:04 +02:00

3.3 KiB

name, description, type, originSessionId
name description type originSessionId
BMF summarizer-connector coupling Factory's maybeGenerateSummary is silently coupled to the local_files observation shape; most connectors fall through. Deferred refactor target. project 1c1bf37d-b1c3-4a62-9355-613c50f4c028

BMF summarizer-connector coupling (deferred refactor)

Surfaced: 2026-04-14, during the SQLite+LanceDB recall unblock session.

src/factory/factory.ts::maybeGenerateSummary implicitly requires the local_files observation shape:

  • source.item_type ∈ {'file','image','passage'}
  • payload.metadata.file_path (or source.item_id)
  • payload.metadata.mime_type (unless item_type is 'file' or 'image')
  • payload.metadata.size_bytes
  • source.content_hash

When documentSummarizer.isAvailable() is true, processFactoryBatch previously set skipDispatch: true uniformly for the whole batch. Any observation that didn't match the summarizer's entry guard was written to logchain and then silently dropped — never dispatched, never summarized. This was the actual cause of zero embeddings after 2,457 Obsidian notes ingested.

Audit of mime_type usage across connectors (2026-04-14):

  • Sets it: local_files, google, obsidian (post-fix).
  • Does NOT: claude_transcripts, slack, github, apple_calendar, apple_contacts, imessage, git, file_import.

Every connector in the second group drops content silently when a summarizer is available — until the partition fix landed.

Why: fixes applied in this session

  • Structural safety net (factory.ts::processFactoryBatch): partition the batch by a summary-eligibility predicate mirroring maybeGenerateSummary's entry guard. Summarizable → skipDispatch: true; pass-through → skipDispatch: false. Guarantees every content type reaches modules regardless of summarizer shape.
  • Notes first-class (connectors/obsidian.ts, factory.ts::maybeGenerateSummary): emit mime_type: 'text/markdown' + file_path; extend summarizer 'file' branch to accept 'note'. Notes get the quality path (summary, teacher enrichment eligible).
  • Provenance (factory.ts::generateAndObserveSummary): connector_id and factory:* tag now use job.connector_id instead of hardcoded 'local_files'.

How to apply: the remaining [PROPOSAL]

Not "add mime_type everywhere." Most connectors (git, apple_contacts, apple_calendar, slack/imessage messages, claude_transcripts per-turn, short github comments) are correctly pass-through and should NOT be summarized. The right generalization is an explicit contract:

  • Add summarizable: boolean to ConnectorObservation (or equivalent) — chosen per-connector.
  • Dispatch partition uses the flag directly rather than inferring via item_type/mime_type.
  • Summarizer accepts a generic-text shape (title + content + content_hash), not local_files-shaped metadata.
  • Fail-loud telemetry: a batch with zero summaries AND zero pass-through dispatches should alarm, not silently succeed.

Touches connector contracts — deserves its own focused PR with Seb reviewing, not a tail-end addition to the storage-migration PR.

When to revisit

  • When opening the next L1 PR after the storage-migration one merges.
  • Before onboarding any new text-bearing connector (the wrong default will keep catching people).
  • If any recall quality investigation points at content-not-dispatched as a suspect — this is the mechanism.