Skip to content

[Agentic Preview delivery slice] Preserve first raster writes across recovery checkpoints #620

Description

@Flow-Fly

Parent

#534 — Public site tools

Sources of truth

Authorization and exact dispatch boundary

After the completed #553 production-build playtest reported #619 and proposed “fix #619, then future deployed-client validation,” the owner replied, “Okay, allons-y” on 2026-09-10. Director interpretation: this authorizes the bounded #619 correction through a fresh finalizer-approved, green integration into develop. It does not authorize deployment, promotion to main, or the later deployed-client validation itself.

  • Repository: Flow-Fly/pixel-forge
  • Branch: dev-619-stable-raster-checkpoint
  • Target: develop
  • Original starting/red-evidence base: d6d4042bddba54a050442534c32e97da9d8a8c07 (historical evidence only)
  • Current immediate integration and quality/Fallow comparison base: ea1352ab7387aed9c052d5a7e8e47ed102ee4068
  • Implementation: one Astra Medium delivery-worker
  • Review: one fresh Astra High finalizer after the complete draft head is green; follow the repository's fresh-pass rule after any finalizer fix

Exact-base reconciliation — 2026-09-10

Merged PR #616 advanced origin/develop to ea1352ab7387aed9c052d5a7e8e47ed102ee4068. Its changed paths are quality scripts/configuration, workflow and agent documentation, lint/Fallow configuration, and focused quality tests; it has no product-source overlap with #620. Existing draft PR #621 at 212b0993a07cfae6024ae7275e3bede73fecf8e4 is mergeable but behind. Prior candidate certification is stale.

The owner authorization already recorded for #620 covers this routine integration recovery. Merge origin/develop@ea1352ab7387aed9c052d5a7e8e47ed102ee4068 into the existing dev-619-stable-raster-checkpoint branch; a merge commit is preferred so the original red baseline and focused implementation commits remain explicit. Resolve only integration conflicts within the already approved slice. Do not reimplement or alter #616. Any further movement of origin/develop, product-source conflict, or scope change requires a new Director reconciliation.

After the merge, all earlier head-specific evidence and review remain historical. Produce one new exact candidate head, run the new quality workflow against ea1352ab7387aed9c052d5a7e8e47ed102ee4068, obtain green PR checks, and only then dispatch a fresh finalizer.

Linked task issues

Task order: #619 is the sole task and should be one focused implementation commit where practical.

Outcome

The first raster transaction on a newly approved blank safe copy crosses the real pre-write recovery checkpoint once and commits once. Checkpoint capture remains a read-only boundary with respect to the live revision/digest contract, while the detached checkpoint remains a coherent, restorable project snapshot. Ordinary default save/reload preserves a legitimately absent live and serialized index buffer; a pre-existing index buffer is still rebuilt when stale.

Diagnosis retained as the implementation constraint

At the delivered baseline, raster observation at revision 0 digests the blank cel as RGBA. checkpointBeforeFirstWrite() then calls the real recovery target's default saveProject(), which rebuilds the live index buffer without advancing the Project Revision. Raster preflight correctly sees a different representation/digest and refuses the formerly current observation as revision_conflict.

The repair must make checkpoint capture stable and coherent. Blindly using rebuildIndexBuffers: false is insufficient because #519 proves that a live canvas can already contain newer RGBA pixels than its index buffer. The serialized checkpoint must derive or otherwise contain index data coherent with its raster bytes without silently changing the live project beneath the observation/write guard.

Director disposition — live versus serialized indices

Existing tests/browser/symbol-grid.test.ts coverage establishes that raster patch, Undo, and Redo preserve an originally absent live index buffer. This slice therefore preserves that live command representation. A detached recovery checkpoint derives coherent matching index data without mutating live project state. Ordinary default save/reload preserves absent indexData when the live index buffer is legitimately absent; when a live index buffer exists but is stale, default save still rebuilds it under the existing palette growth, color-matching, and shared-canvas identity policy. No raster-command behavior changes are authorized.

Compatibility evidence

With the snapshot-only repair, the first raster write commits, but actual Reject still enters recovery-required at revision 2 in the current WIP; the untouched Golden public journey also detects “mid-journey reload changed public project content” at src/editor/golden-automation-journey.ts:499-508: it observes raster before saveRevision / captureDocument, then ordinary default save silently materializes previously absent indices and reload changes the public digest. The earlier checkpoint side effect masked this. The Golden journey and fixture remain unchanged as an acceptance signal; the smallest default serialization correction is part of this same ProjectStore/animation seam and does not create a second capability.

Acceptance criteria

  • A red-before/green-after real Chromium test enters through the normal app, approves a fresh blank safe copy through the shipped local dialogs, performs structure/palette/raster observation at revision 0, starts the run, and submits a one-pixel raster-patch as the first transaction through the public Site Tool facade and actual recovery checkpoint. It commits exactly once at revision 1 with the exact RGBA pixel while preserving the fresh project’s originally absent live index-buffer representation. The detached recovery checkpoint contains a coherent index projection, while ordinary default save/reload keeps legitimately absent serialized indexData absent; the run does not enter recovery-required.
  • The regression invokes the public facade/fallback normal-entry path. Existing transport conformance remains green; native execution is exercised only when the supported browser API is available and is not a develop acceptance dependency.
  • Checkpoint capture does not mutate the live project's raster/index representation, history, change events, or Project Revision. The observed digest remains valid until a real project or concurrent change occurs.
  • The existing digest, expected-revision, target, idempotency, and write-turn/concurrency guards remain intact. A genuinely stale digest or revision is still refused atomically with no partial raster change.
  • The detached checkpoint file itself has coherent PNG/raster bytes and palette indices, including a focused pre-existing stale-index fixture equivalent to Shape gestures leave RGBA and palette indices temporarily inconsistent #519's canvas-newer-than-index state. This criterion constrains checkpoint serialization only; it does not require ordinary save to materialize a legitimately absent index buffer and does not repair Shape gestures.
  • After the successful first raster commit, genuine Reject completes in the terminal rejected phase rather than recovery-required, with the exact blank checkpoint raster bytes restored. Checkpoint rewind/restore is likewise exact, the edited result remains in the required recovery copy, and the original source project stays untouched. Merely creating or opening a Recovery Copy is not sufficient proof.
  • Undo and Redo around the committed raster transaction preserve one history operation, revision semantics, exact RGBA pixels, and the originally absent live index-buffer representation. Detached checkpoint serialization contains coherent matching indices. Ordinary default save/reload preserves absent indices when absent and rebuilds pre-existing stale indices when present; package preparation and reload preserve the same public pixels/digest and continue to satisfy existing artifact checks.
  • The already successful [Agentic Preview delivery slice] Expose the public Site Tool Facade and WebMCP fallback #553 lifecycle path remains green, including fresh observation after authority loss, a later raster write, Pause, package checksums, recovery-copy access, renewed approval, and local Accept.

Non-goals

  • Repairing Rectangle, Ellipse, Line, or any other Shape gesture tracked by Shape gestures leave RGBA and palette indices temporarily inconsistent #519.
  • Changing the public Site Tool facade, JSON Schemas, catalogue, wire format, command IDs, raster digest framing, or Project Revision contract.
  • Weakening or removing digest comparison, optimistic concurrency, idempotency, recovery safety, or safe-copy preservation.
  • Redesigning project serialization, changing the persisted .pf format, adding a migration, changing palette policy, or broadly refactoring animation/project stores.
  • Adding dependencies, backend/provider work, production telemetry, deployment, live-host/model-client acceptance, or promotion to main.

Write boundaries

Production edits are limited to the existing recovery checkpoint capture and project snapshot serialization seams:

  • src/editor/creative-run-recovery-boundaries.ts
  • src/stores/project-store.ts
  • src/stores/animation/store.ts and src/stores/animation/index-buffer.ts only if the smallest coherent non-mutating snapshot projection belongs there

Focused evidence may edit:

  • tests/browser/site-tools.test.ts
  • tests/editor/site-tool-host.test.ts
  • tests/editor/creative-run-recovery.test.ts
  • tests/stores/project-serialization.test.ts
  • tests/editor/timeline-cel-unlink.test.ts
  • tests/browser/creative-run-panel.test.ts
  • the smallest existing raster/serialization browser test only if the public normal-entry test cannot directly prove byte/index coherence

The timeline cel-unlink test may update only its old default-save expectation: it must assert that absent live and serialized indices plus shared-canvas identity survive save, while retaining the existing Undo/Redo proof. The Creative Run panel Rewind test may replace its ordinary-save equality assumption with a digest comparison between the stored checkpoint and the actual createProjectRecoveryTarget(...).captureProject() result; it must retain the terminal outcome and revision assertions and should also assert that ordinary save leaves absent indices absent. These changes strengthen compatibility coverage for the approved serialization distinction and do not expand production scope or permit weakening other assertions.

Do not edit Site Tool contracts/transports, command/digest implementations, UI product behavior, shared/, server/, dependency manifests, telemetry, or unrelated documentation. Stop and return to the Director if the repair cannot fit these seams.

Contract and runtime surfaces

  • Producer: ProjectStore.saveProject() and any existing animation/index serialization projection it uses, distinguishing ordinary default save from the detached coherent recovery-checkpoint projection.
  • Checkpoint caller: createProjectRecoveryTarget().captureProject().
  • Guarded write path: CreativeRunController pre-write checkpoint followed by project.raster.patch digest/revision validation.
  • Durable recovery consumer: CreativeRunRecoveryCoordinator checkpoint digest, copy, reject, rewind, restore, and reload paths.
  • Public proof: normal-entry window.pixelForgeSiteTools.invoke lifecycle and the existing WebMCP/fallback conformance boundary.
  • Persisted contract: current ProjectFile; its schema/version and externally visible digest semantics remain unchanged.

Decision and safety gates

The product decision is complete: recovery capture must preserve both a valid current observation and a coherent restorable snapshot. The same bounded seam may make the smallest default-save adjustment needed to preserve legitimately absent live and serialized indices through ordinary save/reload, while continuing to rebuild a pre-existing stale index buffer under the current palette and identity policy. Implementation may choose the smallest pure checkpoint/index projection and ordinary-save adjustment inside the named seam. Stop for Director review if a safe fix requires a file-format/API/schema/digest change, migration, weaker concurrency checks, changed recovery meaning, Shape repair, new telemetry, dependency, backend work, or scope outside one PR.

The original selected project and the fresh safe copy must remain distinct. No recovery path may overwrite unpreserved user work. Automated browser evidence is the acceptance path for this correction; deployed-client validation remains a later owner-controlled #524 gate.

Observability

Decision: none. The failure is deterministic local client state with a direct regression test and existing factual recovery records. Production telemetry would not answer an unresolved operational question and could expose private project state. Tests may retain content-free local command results and screenshots; no new logging or event is added.

Verification

Before resuming implementation, fetch and confirm origin/develop is exactly ea1352ab7387aed9c052d5a7e8e47ed102ee4068, #619 remains ready and unblocked, and PR #621 is the sole delivery PR. Merge that exact develop commit into the existing branch as authorized above. If origin/develop moves again or the merge exposes product overlap, stop for another exact-base handoff.

Retain the independent red baseline from the production build at the original d6d4042bddba54a050442534c32e97da9d8a8c07 commit: qa/baseline-first-pixel.json, .png, and .log in the delivery artifact root. It is historical bug evidence and is not a new-candidate certification. It records revision_conflict, recovery-required, revision 0, and zero committed transactions.

Run the smallest focused unit/browser tests needed to prove every criterion above, including the normal-entry first-raster regression, real recovery restoration, and ordinary save/reload stability. Keep the existing Golden journey and fixture unchanged and make that public lifecycle green through the serialization repair. Then run:

npx tsc --noEmit
npm run lint
npm run quality:verify -- --base ea1352ab7387aed9c052d5a7e8e47ed102ee4068
npm run quality:check -- --base ea1352ab7387aed9c052d5a7e8e47ed102ee4068 --head <exact-candidate-sha>
npm run build
git diff --check

quality:verify is the required producer for the five separate root, Chromium, shared, server, and Worker profiles plus shared Node smoke, runtime-import checks, boundaries, and the policy-aware Fallow comparison. Do not substitute the old bare test:run, test:browser, or fallow:audit summaries for this certification. Record the bundle path, manifest and certification digests, exact profile scopes, commands, inputs, exclusions, and results. Confirm the checkout stays clean at the exact candidate and the comparison base is ea1352ab7387aed9c052d5a7e8e47ed102ee4068.

After CI is green for that exact head, retain its Actions quality artifact ID, digest, and expiry. In a clean finalizer checkout, accept the downloaded bundle read-only with npm run quality:check -- --base ea1352ab7387aed9c052d5a7e8e47ed102ee4068 --head <exact-candidate-sha> --bundle <downloaded-directory>. CI checkout/head provenance, checks, and server-container must all identify the same candidate.

PR #621 remains the sole draft PR targeting develop; keep its canonical Linked task issues list current. Only a fresh exact head with successful focused checks, local quality certification, build, whitespace check, green CI, and downloaded-bundle acceptance may be handed to a fresh finalizer.

Dependencies and later work

Native blocked by: none. #553/PR #617 are merged prerequisites and stay closed as their historical delivery record. #519 is adjacent evidence, carries its own human gate, and is neither linked nor blocked by this slice. After this correction is reviewed green and integrated, deployed-client/live-host validation remains future owner-controlled work under #524; it is not part of this PR.

Delivery record — #619 / PR #621

Delivered through PR #621. Finalizer pass 1 approved candidate 186b6916201e2cf18910393e98665e3188d0c745 without edits or blockers; integration commit aa679c699875765309942f05a24e01fc4785e844 preserves exact base/head parents. Candidate CI 34469433987 and post-merge CI 34474412151 passed. Post-merge quality artifact 10151076640 has digest sha256:3e8a0f4668cafc03da8d588819e0e66c8f6e9da1c42bb21326e87b3c59bf5a5a; its exact clean-checkout bundle acceptance passed with no blockers or advisories.

Fresh local production-build QA passed all six required scenarios in Chrome 152 fallback and Canary 155 native WebMCP, including exact first raster, genuine Rewind and Reject restoration, and complete lifecycle acceptance. The original d6d4042 failure and superseded d945d27 CI attempts remain historical evidence. Deployed pixel-forge.app, external-agent validation, #519 Shape repair, main, and deployment remain outside this slice.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentic-loopTracked by the reusable agentic loop workflowbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions