Repository navigation
Conversation
… history A local-only maintenance command for the gap the 7/23-7/25 Signal v2 projection stall left: the legacy store kept ingesting while v2 did not. It imports legacy Signal messages that v2 lacks through the historical-import seam with live ingest's natural keys (idempotent; repeat and interrupted runs converge), requires the existing signal-primary/signal_cli account, corrects conversation kind from the Signal remote prefix, keeps malformed-sender messages under a null sender identity, and defers media (counted in the report). Safety: takes the data directory's instance lock and refuses (exit 4) if it is held or if a backend answers on OPENMESSAGES_HOST:OPENMESSAGES_PORT; opens legacy through a new repair-free read-only path (db.OpenReadOnly) and v2 read-only under --dry-run (sqlite.OpenReadOnly). stdout is exactly one JSON report; guidance goes to stderr. Ported from wip/signal-reconcile (7eac32f, 2026-07-26), which was built on the #155 branch before #155 landed as the squash b02aabb (#156). This commit is the net diff b95775c..7eac32f (b95775c = the #155 tip) without the agent's PROGRESS.md ledger, applied to 2b09b61. main.go conflicted only because main added `repair` in the same spots; both commands are kept. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft. This adds
openmessage v2 reconcile-signal, a local-only maintenance command that copies Signal messages from the legacy store into v2 when v2 is missing them. It targets the gap left by the 7/23–7/25 Signal v2 projection stall: the legacy path kept ingesting while the v2 read projection stood still. It has not been run against a real install. It needs a review, and then a deliberate run by Max after the Signal relink.What it does
openmessage v2 reconcile-signal [--from <dir>] [--since YYYY-MM-DD] [--dry-run] [--json]messages.dband imports any that v2 lacks through the v2 historical-import seam. It uses the same natural keys as live ingest, so a repeat run or an interrupted run converges instead of duplicating. That includes the byte-identical legacy source IDs and outgoinglocal:aliases (internal/reconcile/signal.go).signal-primaryaccount with thesignal_clibridge key. It never creates or enables transport state, and it touches no credentials or network.signal:vssignal-group:). It never links a group or the self account as a direct peer. It keeps messages with missing or malformed sender metadata, using a null sender identity.media_deferred).--sincelimits the scan to legacy messages at or after local midnight on that date.conversations_scanned,conversations_created,messages_scanned,messages_imported,messages_already_present,media_deferred,skipped, andskip_reasons. Human guidance goes to stderr. Exit codes: 3 = source/usage problem, 4 = lock or running backend, 5 = run failure.Safety guards (in
cmd/reconcile.go)OPENMESSAGES_HOST/OPENMESSAGES_PORT, default127.0.0.1:7007) and exits 4 if a backend answers, or if it cannot rule one out.db.OpenReadOnly). v2 is opened read-only under--dry-run(sqlite.OpenReadOnly).--dry-runperforms every read and derivation without mutating either store, and a test pins that immutability.How Max would run it (after the Signal relink, d328)
printf 'max-age=2h\nsignal reconcile\n' > ~/Library/Application\ Support/OpenMessage/watchdog-disabledopenmessage v2 reconcile-signal --dry-run > /tmp/reconcile-dry.json, then readmessages_imported(what a real run would add) andskip_reasons.--dry-run. A second real run should reportmessages_imported: 0.Provenance
The work was done on 2026-07-26 on
wip/signal-reconcile(7eac32f), on top of the #155 branch. #155 later landed as the squash commit b02aabb (#156), so that branch now carries pre-squash duplicates of #155 and conflicts with main. This PR carries only the reconcile work: the net diffb95775c..7eac32f, where b95775c is the #155 tip, minus the agent'sPROGRESS.mdledger. Applied to current main (2b09b61), onlymain.goconflicted: main had added therepaircommand in the same two spots, and both are kept.wip/signal-reconcileis left untouched.Tests
The new tests cover:
--since, and dry-run immutabilityinternal/ingest/reconcile_signal_test.go).Local results at af46a22 on 2026-09-25 (macOS, loopback listeners allowed, unlike the July sandbox):
GOWORK=off go build ./...andgo veton the touched packages: clean.gofmt -l: clean.GOWORK=off go test ./internal/reconcile/ ./internal/db/ ./internal/storage/sqlite/ ./internal/ingest/ ./internal/v2read/ -count=1: all ok.GOWORK=off go test ./cmd/ -run '(?i)signal|reconcile' -count=1: ok.GOWORK=off go test ./... -count=1: all 34 packages with tests pass. The July run could not do this because its sandbox blocked loopback listeners.Open questions for review
openmessage v2 …(it is the firstv2subcommand) or next torepair google-idspaceasrepair signal-history?messages_already_presentand nothing to import, and this can be closed.🤖 Generated with Claude Code