Skip to content

Return typed retryable API refusal on real ticket-store lock contention #299

Closed

Description

@tom-sapletta-com

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

  1. added
    priority-highAuto-created label for priority-high
    planfileAuto-created label for planfile
    managedAuto-created label for managed
    subactor:autonomyExplicit issue intake for the governed Subactor coding-agent / Willman workflow
    audit-20261025Auto-created label for audit-20261025
    on Oct 25, 2026
  2. tom-sapletta-com commented on Oct 28, 2026

    @tom-sapletta-com
    ContributorAuthor

    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 registered StoreLockTimeoutError API handler. Its append_ticket_evidence still calls get_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 a10second StoreLockTimeoutError. 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=False evidence-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.

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

    audit-20261025Auto-created label for audit-20261025managedAuto-created label for managedplanfileAuto-created label for planfilepriority-highAuto-created label for priority-highsubactor:autonomyExplicit issue intake for the governed Subactor coding-agent / Willman workflow

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions