Repository navigation
Return typed retryable API refusal on real ticket-store lock contention #299
Description
Ordinary ticket PATCH currently leaks StoreLockTimeoutError as an untyped HTTP500 under real mutation-lock contention. This is distinct from #297 / draft PR298: that source change decouples atomic evidence reads from the disposable index; real writer-lock refusal must still remain bounded and preserve the owner. On 2026-10-25T16:03–16:05Z the retained production Planfile API logged PATCH /tickets/PLF-20011 HTTP500; traceback update_ticket -> mutation_lock -> _file_lock -> StoreLockTimeoutError after 10 seconds. Evidence append also timed out on the rebuild lock, tracked separately in297. Main planfile/api/server.py has handlers for ImmutableTerminalReopenError and TicketUpdatedAtConflictError, but no StoreLockTimeoutError handler.
Required bounded delivery: translate proven pre-commit store-lock contention into a documented typed retryable response (for example503 with Retry-After), without exposing host paths or credentials; preserve writer ownership, lock lifetime, ticket state, CAS and evidence idempotency. Audit mutation endpoints consistently. Do not silently replay non-idempotent ticket creation, claim, update or external effects; unknown/post-commit outcomes must retain reconciliation requirements. Keep index-contention prevention in297 as a dependency, not duplicated source scope. Tests must hold the real lock in a separate process, assert bounded refusal and no state/attempt mutation, then successful supported operation after lock release; retain conflicting-key and real unexpected-error behavior. No deleting locks, force-ready/resetting queue attempts, threshold changes or unreviewed runtime patch. Serialize behind active ticket243 where shared source scope applies. Independent exact-head original OneDev/Validator publication and separately qualified runtime deployment remain required.
Operator audit semcod/planfile:PLF-19987; primary runtime ticket19983 remains active. Backlog request only, no second implementation writer. Local immutable observation and outbox are retained in the operator checkpoint.
Ticket impact radar (advisory)
- Complexity:
M - Score:
52/100 - Estimated effort:
47 min - Split recommended:
yes
This estimate does not grant execution, review or merge authority.
Strategy Metadata:
- repository: semcod/planfile
- planfile_id: semcod/planfile:d2a989f6ada2f6b2:PLF-19993
Activity
tom-sapletta-com commentedon Oct 28, 2026
Runtime adoption evidence for existing #299 / native249, also related to #297 / native243.
The active central Planfile API still returns HTTP500 on store/index lock contention. Its deployed image is
sha256:d96361f68299e4af1838a2a8d2020a82cc1c5afc5efbc86b1dd59cfdeb0c4a8a(created2026-10-24). Direct runtime inspection shows no registeredStoreLockTimeoutErrorAPI handler. Itsappend_ticket_evidencestill callsget_ticket(ticket_id)with index repair enabled.The timestamp-bound failure of an idempotent evidence append follows
append_ticket_evidence -> get_ticket -> indexed_ticket -> ensure_ticket_index -> ticket_index_rebuild_lock, then a10secondStoreLockTimeoutError. The write does not reach evidence append; readback remains unchanged. One identical bounded retry also failed. The active lock owner and lock files were preserved; the external outbox and GitHub progress evidence remain durable.Current main already contains native243's
repair_index=Falseevidence-read fix and native249's typed503/Retry-After handling (native249 source PR #308). This is an observed runtime adoption gap, rather than a request to implement those fixes again. Runtime/API source hashes are retained privately; a displayed version alone is insufficient to identify the loaded implementation.Owner next action: qualify and promote an approved API artifact containing both fixes through the declared deployment path, retaining data, idempotency/CAS and current writer ownership; then repeat the contention/recovery canary and drain the same pending outbox. The separately frozen selected-inbound source PR #312 remains under required verification and grants no deployment authority.