Skip to content

feat(parser): migrate kiro providers#781

Draft
mariusvniekerk wants to merge 1 commit into
provider-zed-shelleyfrom
provider-kiro-family
Draft

feat(parser): migrate kiro providers#781
mariusvniekerk wants to merge 1 commit into
provider-zed-shelleyfrom
provider-kiro-family

Conversation

@mariusvniekerk

Copy link
Copy Markdown
Collaborator

Kiro and Kiro IDE now use concrete providers instead of the legacy adapter. The Kiro provider models both direct JSONL session files and the shared data.sqlite3 current store, including physical DB fan-out, per-session virtual lookup, legacy JSONL shadowing when current-store rows exist, source fingerprints, changed-path classification, and force-replace SQLite parse behavior. The Kiro IDE provider models old .chat files and workspace-session JSON files with source discovery, lookup, fingerprinting, and parse normalization through the existing parser.

@roborev-ci

roborev-ci Bot commented Jun 19, 2026

Copy link
Copy Markdown

roborev: Combined Review (7f9d9d1)

Medium findings need attention before merge.

Medium

  • internal/parser/kiro_provider.go:340 - FindSource resolves StoredFilePath/FingerprintKey before checking the current SQLite store. If a legacy JSONL-backed Kiro session has since moved into data.sqlite3, callers that pass the stored legacy path plus the full session ID can get the shadowed legacy source, causing Parse to return SkipNoSession instead of reparsing the current SQLite session. Prefer the SQLite lookup for RawSessionID before accepting stored legacy paths, matching the existing Kiro special-case in Engine.FindSourceFile.

  • internal/parser/kiro_provider.go:428 - Legacy Kiro parsing consumes the companion .json metadata file for session ID, cwd, title, and timestamps, but the provider fingerprint only hashes the .jsonl file and the watch plan only includes *.jsonl. Metadata-only changes can leave archived sessions permanently stale. Include the companion metadata file in the legacy source fingerprint and classify/watch *.json companion changes back to the owning .jsonl source.

  • internal/parser/kiro_ide_provider.go:138 - Kiro IDE new-format parsing depends on sessions.json and execution logs to resolve assistant output and tool calls, but the provider source set fingerprints only the session JSON and ignores execution-log changes in SourcesForChangedPath. If logs are written after the session file, the provider can skip the unchanged session source and keep incomplete messages/tool calls. Use a custom Kiro IDE source set that maps sessions.json/execution-log changes to affected sessions and folds those dependencies into the source fingerprint.


Panel: ci_default_security | Synthesis: codex, 10s | Members: codex_default (codex/default, done, 4m52s), codex_security (codex/security, done, 2m14s) | Total: 7m16s

@roborev-ci

roborev-ci Bot commented Jun 19, 2026

Copy link
Copy Markdown

roborev: Combined Review (dfd4abf)

Medium severity issues were found in provider change detection; no security issues were reported.

Medium

  • internal/parser/kiro_provider.go:307 - The legacy Kiro provider watches and fingerprints only *.jsonl, but ParseKiroSession also reads the companion *.json metadata for session ID, cwd, title, and timestamps. A metadata-only create/update can be skipped, leaving stale or incorrect session metadata.
    Fix: Map companion .json changes back to the .jsonl source and compute a composite fingerprint/mtime/hash over both files.

  • internal/parser/kiro_ide_provider.go:137 - The Kiro IDE provider fingerprints/classifies only .chat and workspace session JSON files, but parsing also reads sessions.json and execution-log files for assistant text and tool calls. Changes or late creation of those sidecars will not trigger a reparse.
    Fix: Include those dependent files in changed-path mapping and the composite fingerprint, or conservatively reparse affected workspace sessions when they change.


Panel: ci_default_security | Synthesis: codex, 8s | Members: codex_default (codex/default, done, 5m40s), codex_security (codex/security, done, 2m36s) | Total: 8m24s

@roborev-ci

roborev-ci Bot commented Jun 20, 2026

Copy link
Copy Markdown

roborev: Review Unavailable (cc410d0)

The review agent repeatedly failed to run (likely an agent or configuration error). roborev will try again on the next commit.

Last error: agent: claude-code failed stream: stream errors: You've hit your session limit · resets 5:50am (UTC): exit status 1

@roborev-ci

roborev-ci Bot commented Jun 21, 2026

Copy link
Copy Markdown

roborev: Combined Review (0b35bf4)

No issues found.


Panel: ci_default_security | Synthesis: codex | Members: codex_default (codex/default, done, 7m15s), codex_security (codex/security, done, 2m26s) | Total: 9m41s

@mariusvniekerk

mariusvniekerk commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

This change is part of the following stack:

Change managed by git-spice.

@roborev-ci

roborev-ci Bot commented Jun 21, 2026

Copy link
Copy Markdown

roborev: Combined Review (bec96d7)

Medium-risk issue found; security review reported no additional findings.

Medium

  • internal/parser/provider_migration.go:44 - Moving AgentKiro to ProviderMigrationShadowCompare does not actually shadow-compare the normal Kiro SQLite sync path. Full and periodic syncs process current-store sessions through syncOneKiroSQLite, which returns pendingWrites directly and never calls observeProviderShadow, so the primary Kiro backend can diverge without any shadow signal.
    • Fix: Add provider observation/comparison around the Kiro SQLite sync path, or synthesize the data.sqlite3 provider source through the file-processing path before enabling Kiro shadow compare.

Panel: ci_default_security | Synthesis: codex, 7s | Members: codex_default (codex/default, done, 5m49s), codex_security (codex/security, done, 1m5s) | Total: 7m1s

@roborev-ci

roborev-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

roborev: Combined Review (5dd509f)

No Medium, High, or Critical findings.

The only reported issue was Low severity, so it is omitted per review rules.


Panel: ci_default_security | Synthesis: codex, 5s | Members: codex_default (codex/default, done, 9m49s), codex_security (codex/security, done, 2m31s) | Total: 12m25s

Kiro has two source families that were still coupled to the legacy sync adapter: CLI JSONL plus current-store SQLite for Kiro, and old .chat plus workspace-session JSON for Kiro IDE. Moving them behind concrete providers keeps those source shapes explicit at the facade boundary.

The Kiro provider preserves current-store fan-out, per-session SQLite virtual lookup, legacy JSONL shadowing, source hashing, changed-path classification, force-replace SQLite parses, per-session source errors, and Kiro IDE old/new session parsing through the existing parsers.

fix(parser): prefer kiro sqlite lookup

Kiro sessions can migrate from legacy JSONL files into the current-store SQLite database while the persisted row still points at the old source path. Source lookup needs to treat the session ID as authoritative in that case, otherwise explicit resyncs can resolve the shadowed JSONL file and skip the current SQLite session.

fix(parser): align kiro provider shadowing

The legacy Kiro sync path treated current-store SQLite sessions as globally shadowing legacy JSONL files across all configured roots. The provider needs the same behavior so multi-root setups do not parse the same logical session from both source families.

Deleted SQLite DBs and per-session rows also need to fingerprint as tombstones so the provider caller can still reach parse and produce the force-replace SkipNoSession outcome used for archive cleanup.

fix(parser): shadow kiro providers

The Kiro provider branch had concrete Kiro and Kiro IDE providers, but the migration manifest still held both agents on legacy-only mode. That prevented the provider bridge from exercising their changed-path behavior during the dual-run phase.

Move both Kiro agents into shadow compare on their migration branch so the stack remains a runtime migration instead of an additive provider implementation.

Validation: go test -tags "fts5" ./internal/parser -run 'Test(KiroProvider|KiroIDEProvider|ProviderMigrationModes)' -count=1; go test -tags "fts5" ./internal/sync -run 'Test.*Kiro' -count=1; go test -tags "fts5" ./internal/parser -count=1; go test -tags "fts5" ./internal/sync -count=1; go vet ./...; git diff --check

test(sync): compare kiro family shadow parity

Kiro and Kiro IDE are shadow-compared on this branch, so the migration should prove provider observation still matches the legacy parsers that currently feed sync writes.

Cover Kiro SQLite database sources and Kiro IDE workspace-session JSON sources through ObserveProviderSource, including force-replace intent and data-version planning.

Validation: go test -tags "fts5" ./internal/parser ./internal/sync -run 'TestObserveProviderSourceMatches(KiroSQLite|KiroIDE)LegacyParser|TestKiroProvider|TestKiroIDEProvider' -count=1; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go fmt ./...; go vet ./...; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...; git diff --check

test(parser): cover kiro stored source hints

Kiro's SQLite provider already supports tombstone parsing for missing database rows and deleted databases, but fresh stored-source lookup still accepted those stale hints. During the dual-run migration, callers use RequireFreshSource to distinguish explicit fresh lookup from changed-path cleanup, so the provider needs to honor that contract before legacy dispatch can be removed.

Fresh stored SQLite paths now require the physical DB or virtual row to exist, while non-fresh lookup still preserves source identity for SkipNoSession tombstones. The tests also reject malformed and stale SQLite virtual paths under the Kiro root.

Validation: go test -tags "fts5" ./internal/parser -run 'TestKiro' -count=1; go test -tags "fts5" ./internal/sync -run 'TestObserveProviderSourceMatchesKiro(SQLite|IDE)LegacyParser|TestProcessFileProviderAuthoritativeSourceErrorsOnlyForceParse' -count=1 -v; go fmt ./...; go vet ./...; GOMAXPROCS=1 GOGC=5 GOMEMLIMIT=128MiB ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser; git diff --check

Generated with Codex
Co-authored-by: Codex <codex@openai.com>

refactor(parser): fold kiro providers

Kiro and Kiro IDE were still dual-running: concrete providers existed but the migration manifest held both on shadow-compare, so the legacy package-level entrypoints and a large legacy sync dispatch still owned writes. Promote both agents to provider-authoritative and delete that legacy surface so the providers are the single source of truth.

The eight legacy free functions are removed: DiscoverKiroSessions, FindKiroSourceFile, ParseKiroSession, FindKiroSQLiteDBPath, ParseKiroSQLiteVirtualPath, ParseKiroSQLiteSession (Kiro) and FindKiroIDESourceFile, ParseKiroIDESession (Kiro IDE). Discovery, legacy-JSONL source lookup, and both parse paths move onto the concrete providers; the orphaned DiscoverKiroIDESessions helper goes with them.

SQLite virtual-path handling is preserved through the provider-neutral resolver. The Kiro provider continues to give each conversation row a stable identity via KiroSQLiteVirtualPath/VirtualSourcePath and resolves a "<db>#<sessionID>" path back through ParseVirtualSourcePathForBase (now via the unexported kiroSQLiteVirtualPathParts in the parser and a sync-package equivalent). Current-store fan-out, per-session virtual lookup, cross-root legacy shadowing, source hashing, force-replace SQLite parses, and per-session source errors all keep their existing behavior.

The engine loses its kiro legacy dispatch: the bulk syncKiroSQLite phase, classifyKiroSQLitePath plus the legacy-JSONL classifyOnePath block, the processKiro/processKiroIDE arms and methods, syncSingleKiroSQLite, and the now-redundant per-session count/shadow helpers. Provider discovery now emits the data.sqlite3 source and processProviderFile fans it out, so the DB is counted once via normal file sync instead of the separate DB-backed accounting. The cross-root legacy shadow filter stays in the engine because a scoped sync configures the provider with only the in-scope roots and cannot otherwise see a current-store DB in an out-of-scope root.

providerChangedPathEventKind now resolves a virtual source path to its physical container before the existence check so a per-session SQLite resync via SyncPaths is treated as a write rather than a phantom remove. Parse-diff discovers kiro through the provider facade (parseDiffProviderDiscover) now that it carries no DiscoverFunc hook.

The two shadow-baseline assertions that encoded the old bulk-sync idempotency (a no-op resync counting zero) are updated for the authoritative model, where the database is rediscovered and re-parsed every full sync; archive preservation on a malformed update is unchanged. The shadow parity test is replaced with provider-API coverage, a parser guard asserts the legacy entrypoints stay gone, and both provider files leave the pending-shim scan list.

fix(parser): thread ctx through kiro_ide source lookups
@roborev-ci

roborev-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown

roborev: Combined Review (77c5229)

High severity issue found; no additional medium-or-higher security findings.

High

  • internal/parser/kiro_provider.go:152
    When the Kiro SQLite DB exists but has no parseable sessions, the provider returns SkipNoSession with ForceReplace. The generic provider path turns that into parser exclusions for all stored data.sqlite3#... sessions, so an empty or currently unparseable Kiro DB can hard-delete previously archived sessions. The old Kiro sync path preserved those rows.

    Fix: For the aggregate Kiro SQLite DB source, return an empty non-skip outcome when no rows parse, or otherwise avoid ForceReplace + SkipNoSession from producing exclusions for Kiro. Add an integration test that syncs a Kiro SQLite session, empties or removes the source rows, resyncs, and verifies the archived session remains.


Panel: ci_default_security | Synthesis: codex, 7s | Members: codex_default (codex/default, done, 7m40s), codex_security (codex/security, done, 2m38s) | Total: 10m25s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant