Vibe stores transcript content in messages.jsonl while canonical session identity, title, timestamps, model, and usage can live in a sibling meta.json. Moving it behind a concrete provider keeps that companion relationship explicit at the provider boundary.\n\nThe provider preserves recursive session discovery, symlinked session directories, raw and full ID lookup through meta.json, meta-sidecar changed-path classification, effective size and mtime freshness, transcript hashing, fallback-ID exclusion, and parser output normalization through the existing Vibe parser wrapper.
fix(parser): classify removed vibe transcripts
Vibe source events need to keep working after the primary messages.jsonl has already disappeared. Routing deletion and rename-style events through the existing file check meant the watcher could ignore the exact event that should refresh or remove the stored session.
Synthesize source refs only for missing-path removal semantics, keep ordinary lookups existence-checked, and pin the intentionally shallow session directory layout in provider tests. This lets the Vibe provider enter shadow comparison as a real migration step.
Validation: go test -tags "fts5" ./internal/parser -run 'Test(VibeProvider|ProviderMigrationModes)' -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check
test(sync): compare vibe shadow parity
Vibe is shadow-compared on this branch, so add source-level migration coverage that compares provider observation with ParseVibeSessionWrapper.
The test includes meta.json canonical ID promotion, provider-adjusted fingerprint metadata, usage events, and excluded fallback IDs so reviewers can see the migration preserves the composite source behavior.
Validation: go test -tags "fts5" ./internal/parser ./internal/sync -run 'TestObserveProviderSourceMatchesVibeLegacyParser|TestVibeProvider|TestParseVibe|TestClassifyOnePath_Vibe|TestSyncVibe|TestSourceMtimeVibe|TestProcessVibe' -count=1; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go fmt ./...; go vet ./...; git diff --check; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...
test(sync): cover vibe provider usage parity
Roborev job 2711 caught that the Vibe shadow parity fixture compared empty usage slices, so it could not detect regressions in aggregate usage emission.
Seed the fixture with real Vibe metadata fields for active model and nonzero stats, then assert both legacy and provider paths emit usage before comparing them.
Validation: go test -tags "fts5" ./internal/sync -run TestObserveProviderSourceMatchesVibeLegacyParser -count=1; go fmt ./...; go vet ./...; git diff --check
refactor(parser): fold vibe into provider
Move Vibe source discovery, lookup, and parse ownership onto the concrete
vibeProvider and delete the package-level DiscoverVibeSessions,
FindVibeSourceFile, and ParseVibeSessionWrapper free functions. Discovery
and find-source bodies now live as provider-owned helpers
(discoverSessionPaths, findSourceFile) on the vibe source set, the
isVibeMessagesFile guard moves to the provider file, and the messages.jsonl
parser becomes the provider parseVibeResult/parseSession methods.
Make Vibe provider-authoritative and drop its legacy sync dispatch: the
classifyContainerPath classifyVibePath call and method, the processFile case
arm, the processVibe method, and its now-orphaned isSessionBlocked and
isSessionTrashed helpers. vibeEffectiveInfo stays as a shared composite-mtime
helper used by the skip-cache and fingerprint paths.
Because a provider has no database handle, the engine reproduces Vibe's
DB-aware, file-path-scoped bookkeeping in applyProviderFilePathPolicies for
single-session-per-file providers: stale stored IDs at the same source path
are excluded, and a freshly parsed row is suppressed when the user already
removed (trashed or deleted) the session occupying that path, so a canonical
ID flipping between the meta.json session_id and the directory-name fallback
no longer resurrects a hidden session. This is a no-op for stable-ID
providers and skipped for multi-session sources.
Drop the Vibe AgentDef DiscoverFunc/FindSourceFunc hooks, remove it from the
pending shim scan list, replace the shadow-baseline test with provider API
coverage plus a guard that the legacy entrypoints stay gone, and route the
package and engine tests through the provider methods. The obsolete
classifyOnePath Vibe test is removed; the provider's SourcesForChangedPath
coverage replaces it.
Vibe now uses a concrete provider for its session directory layout. The provider keeps messages.jsonl as the stable source while modeling meta.json as a companion for changed-path classification and freshness.
The provider preserves recursive discovery, symlinked session directories, canonical ID lookup through meta.json, effective size and mtime from transcript plus metadata, transcript hashing, fallback-ID exclusion, aggregate usage events, and parse output through the existing Vibe parser wrapper.