Skip to content

fix: create the first persistent artifact on the incremental path - #1163

Closed
mvanhorn wants to merge 1 commit into
DeusData:mainfrom
mvanhorn:fix/434-persistence-incremental-first-artifact
Closed

fix: create the first persistent artifact on the incremental path#1163
mvanhorn wants to merge 1 commit into
DeusData:mainfrom
mvanhorn:fix/434-persistence-incremental-first-artifact

Conversation

@mvanhorn

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes #434: enabling persistence=true did not create the first persistent artifact on the incremental indexing path. dump_and_persist in pipeline_incremental.c only refreshed an artifact that already existed and never created one on first run, so a persistence=true request was silently a no-op until an artifact happened to exist. git ai stats-style consumers saw the index reported as successful with no persistent artifact written.

This threads a new cbm_pipeline_persistence() accessor into the incremental path (mirroring the existing cbm_pipeline_repo_path / cbm_pipeline_project_name accessors) so it exports the first artifact with CBM_ARTIFACT_BEST when persistence is requested and none exists, matching the full pipeline. Existing artifacts keep refreshing with CBM_ARTIFACT_FAST. It covers changed-file, deleted-file, and no-op incremental runs, and it now propagates a failed cbm_artifact_export as a run error instead of reporting a successful index when the artifact could not be written.

Checklist

  • Every commit is signed off (git commit -s) — required, CI rejects unsigned commits (DCO, see CONTRIBUTING.md)
  • Tests pass locally (make -f Makefile.cbm test)
  • Lint passes (make -f Makefile.cbm lint-ci)
  • New behavior is covered by a test (reproduce-first for bug fixes)

@mvanhorn
mvanhorn requested a review from DeusData as a code owner July 18, 2026 08:47
@DeusData DeusData added the bug Something isn't working label Jul 18, 2026
@DeusData DeusData added this to the 0.9.1-rc milestone Jul 18, 2026
@DeusData DeusData added ux/behavior Display bugs, docs, adoption UX priority/normal Standard review queue; useful PR with ordinary maintainer urgency. labels Jul 18, 2026
@DeusData

Copy link
Copy Markdown
Owner

Thanks for covering both changed-file and no-op incremental paths and for propagating export failure rather than reporting a false success. This is classified with #434 as a 0.9.1-rc bug fix. Review will verify explicit persistence versus automatic refresh semantics, first-export quality selection, artifact failure behavior, and compatibility with the existing incremental artifact stack.

@DeusData

Copy link
Copy Markdown
Owner

Thanks for this, and apologies for the slow acknowledgement. Queued for review.

Currently CONFLICTING against main with CI green (20 checks) — a rebase is the only mechanical blocker. The incremental-indexing area has moved recently, so rebasing will also tell you quickly whether the change still lands the way you intended.

@mvanhorn
mvanhorn force-pushed the fix/434-persistence-incremental-first-artifact branch from e8472f9 to a5e040a Compare July 25, 2026 21:39
@mvanhorn

Copy link
Copy Markdown
Contributor Author

The Windows job failure looks like a timing flake in an unrelated test rather than anything from this PR.

The run is 3669 passed / 1 failed, and the one failure is:

daemon_ipc_windows_rendezvous_bridges_concurrent_lifetime_owner
  FAIL tests/test_daemon_ipc.c:1163: ASSERT(startup_observed)

startup_observed is set by a bounded poll -- 200 iterations of cbm_usleep(1000), so a fixed ~200ms budget -- waiting for a background thread to take cbm-startup-v2.lock. If the runner is loaded enough that the thread doesn't acquire it inside that window, the flag stays false and the assert trips. That Windows job took 17 minutes on this run, so a 200ms race losing is plausible. ci-ok then fails only because it aggregates test.

This PR touches src/pipeline/pipeline.c, pipeline.h, pipeline_incremental.c and tests/test_pipeline.c -- nothing in the daemon or IPC paths, and test_pipeline passes. A re-run should clear it; I can't trigger one.

If it's worth hardening, raising that poll budget or waiting on the lock rather than sampling it would make the test deterministic -- happy to send that separately.

@DeusData

Copy link
Copy Markdown
Owner

A quick note so this does not sit here looking like your problem: your red CI is not caused by your change.

The failure is daemon_ipc_windows_rendezvous_bridges_concurrent_lifetime_owner at tests/test_daemon_ipc.c:1163 — a Windows daemon-startup interleaving flake. It was fixed on main by #1320, which landed after your run.

One thing worth knowing, because it will save you a wasted click: "Re-run failed jobs" will not clear it. A re-run re-tests the same recorded merge commit, so it will fail identically. Only a fresh push refreshes the merge ref — so a rebase on current main (or a git merge origin/main) and a push is what picks up the fix.

Apologies for the delay in getting to this. We are working through a large review backlog oldest-first, and the queue is real rather than an indication your PR was skipped.

cbm_pipeline_refresh_artifact already encodes the policy this PR was written
to add: it exports when persistence is on even with no artifact present, picks
BEST over FAST for that first export, and propagates an export failure. The
full path and the semantic_manifest_equal no-op already call it; the other two
incremental exits did not.

The no_changes no-op returned 0 without refreshing, so a run that changed
nothing never created the first artifact. The dump path hand-rolled an
exists-only FAST export and discarded its result. Both now route through the
helper, which is also why this diff is much smaller than the original branch.

Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
@mvanhorn
mvanhorn force-pushed the fix/434-persistence-incremental-first-artifact branch from 8e972fc to 5ed19a2 Compare August 12, 2026 16:00
@mvanhorn

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and the diff got much smaller, so here is why rather than leaving it looking like work went missing.

Most of what this PR added now exists upstream as cbm_pipeline_refresh_artifact: it exports when persistence is on even with no artifact present, picks BEST over FAST for that first export, and returns the export failure instead of swallowing it. The full path and the semantic_manifest_equal no-op already call it.

What was still missing is the other two incremental exits. The no_changes no-op returned 0 without refreshing, so a run that changed nothing never created the first artifact, and the dump path hand-rolled an exists-only FAST export and discarded its result. Both now go through the helper.

5ed19a2, one file, +10/-6. Builds clean under -Werror and the focused artifact and pipeline suites pass, 265 tests, including the existing pipeline_persistence_export_failure_returns_error.

@DeusData

Copy link
Copy Markdown
Owner

Thank you @mvanhorn for rebasing and explaining exactly what remained after upstream consolidation. The current diff is now one file, +10/-6, routing the two missed incremental exits through the existing refresh helper.

The only red is the macOS PR smoke at its repeated---semantic-query output assertion; the emitted semantic table is present in the log, and the failure is outside the pipeline files changed here. I have recorded the narrowed head and returned it to the review queue without attributing that smoke failure to your patch. The queue is full, so final review may still take some time.

@DeusData

Copy link
Copy Markdown
Owner

Closing in favor of #1263 (merged as 415a64a) — with genuine thanks and credit: you identified the #434 incremental-persistence gap first, and your per-route analysis (the mode-skipped noop at :2493 and the real-run tail at :2864, beyond the one site 87a0e3f covered) is what made the architecture comparison possible at all. We ultimately chose the centralized publish-boundary export because its export-exactly-once property is enforced at one place instead of three, but that decision was informed by your mapping of the routes. If you're up for it, the #1263 design could still use eyes on the artifact-refresh edge you knew best.

@DeusData DeusData closed this Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority/normal Standard review queue; useful PR with ordinary maintainer urgency. ux/behavior Display bugs, docs, adoption UX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cursor | vscode : persistence= true is silently ignored on first artifact creation

2 participants