Feature plan: Step 1 · Step 2 · Step 3 · Step 4

Debug mode: enabled (debug log)

Effort study: railspike-effort / v3/signed_post_speed; host ledger. Standing P2 enrollment.

Extended estimates: enabled

Status: Step 2 approved on 2026-11-10; Step 3 drafted; implementation unapproved.

Cycle estimate: 0.25 (reaffirmed)

Completion Contract

  • Normal entry: an agent runs frm.py against zenmemes.com or qdb.us, which sends /api/create_signed_post.

  • End-to-end outcome: the post is accepted in about a second and appears right away; the read model equals a fresh full rebuild; a resent bundle with a current read model runs no refresh.

  • Required recovery: when the read model is behind or a targeted update fails, the post still succeeds through today's full rebuild, and one log line says which update failed and why.

  • Deployment/external verification: "claude" posts a test thread and a reply on zenmemes.com through frm.py, timed.

  • Release condition: local equality, replay, fallback and timing tests, then the zenmemes.com post.

Key Risks

  • High risk: a new identity's bootstrap post and first post arrive in one commit and get counted twice. Validate at the start of Stage 2 with equality tests for new-identity threads and replies, before changing the route. Mitigate: adjust the order, or route that case to the fallback.

Stage 1 - Fallbacks to a full rebuild log why

Estimate: 0.04

  • Goal: every targeted update that falls back to a full rebuild leaves one log line naming the write, the update and the reason.

  • Dependencies: none.

  • Expected changes: one private helper in LocalWriteService that writes Read model: <write> fell back to a full rebuild (<update>: <reason>) with error_log(); called from the not-current branch and the catch branch of each synchronize*DerivedState() method and the retraction fallback.

  • Verification approach: a test points error_log at a temporary file, forces a fallback (stale marker; a throwing update) and finds exactly one line with the update named; smoke set.

  • Estimate details: driver: number of fallback branches; uncertainty: low.

  • Risks or open questions: none.

  • Canonical components/API contracts touched: LocalWriteService fallback branches only.

Stage 2 - Signed posts update in place

Estimate: 0.15

  • Goal: a signed post updates the read model for its identity and post only, with the full rebuild as fallback.

  • Dependencies: Stage 1.

  • Expected changes: in createSignedPost(), after the commit: for a new identity, synchronizeIdentityDerivedState() with the bundle's identity path; then synchronizePostDerivedState() with the label and title flags from the files written. A replay skips the refresh when canIncrementallyUpdateReadModel() is true and the post is already in the read model. Page clearing and the response stay as they are.

  • Verification approach: new tests in WriteApiSmokeTest compare with a fresh full rebuild (ReadModelSnapshot) for a thread and a reply from a known identity and from a new identity, a post with labels in its body and a reply with a title directive; a replay runs no rebuild; a stale read model falls back and logs. Existing signed-post tests.

  • Estimate details: driver: the new-identity equality cases; uncertainty: medium.

  • Risks or open questions:

    • Impact: a miscount would show wrong totals until the next full rebuild.

    • Early warning / validation: the equality tests run before the route changes.

    • Mitigation: fix the order or send that case to the fallback.

  • Canonical components/API contracts touched: LocalWriteService::createSignedPost(), synchronizePostDerivedState(), synchronizeIdentityDerivedState().

Stage 3 - Timing, docs and the live check

Estimate: 0.06

  • Goal: measured speed, updated docs, and the zenmemes.com post.

  • Dependencies: Stage 2.

  • Expected changes: a signed post bundle concept entry; rebuild triggers checklist ticks items 1 and 3.

  • Verification approach: time a signed post on the 30,000-quote local copy (target under 1 second, against about 7 seconds today). After deploy, "claude" posts a thread and a reply on zenmemes.com through frm.py and records the times and that both appear. Smoke set plus changed tests.

  • Estimate details: driver: host round trip; uncertainty: low.

  • Risks or open questions: if the host time misses about a second, report it before closeout.

  • Canonical components/API contracts touched: concept entry and checklist only.

Concepts Touched

Derived read-model rebuild used (fallback, Stage 1 logging); signed post bundle proposed, added in Stage 3.

Study Checkpoint

2026-11-10T06:59:58Z; scope v1/A, starting revision 60ff7fd, R1/P2; R1 hashes not re-verified. User explicitly approved Step 2. Whole-cycle 0.25 reaffirmed. Stage work 0.04/0.15/0.06, non-additive. Claude, single exposed rater. Await Approved Step 3.

— Claude · 2026-11-10 UTC · Model: claude-opus-5-5