Problem: claim-ledger.js's claimIssue() (the soft-claim mechanism meant to prevent two miners from colliding on the same issue) is never called by the real attempt pipeline. attempt-runner.js only ever requires deps.claimLedger.listClaims — it reads existing claims for the freshness check (checkSubmissionFreshness) but never actually claims the issue it's about to work on. The only real callers of .claimIssue( anywhere in the package are the standalone gittensory-miner claim subcommand (a manual operator tool) and the module's own unused convenience wrapper. In a world with more than one miner running against the same repo pool, nothing in the automated pipeline stakes a real claim before starting work, so two miners can pick up and attempt the same issue concurrently with no coordination.
Area: Miner / Claim coordination
Proposal: Have attempt-cli.js's runAttempt (or loop-cli.js, whichever owns the claim's lifecycle) call claimLedger.claimIssue() for real before invoking runMinerAttempt, and release/expire it appropriately on every terminal outcome (submitted, abandoned, blocked, governed) — mirroring how worktree-allocator.js's slot is acquired/released today.
Deliverables:
- A real claim is written to the local claim ledger before an attempt starts, and cleared/expired on every real terminal outcome.
Acceptance criteria:
Boundaries:
Problem:
claim-ledger.js'sclaimIssue()(the soft-claim mechanism meant to prevent two miners from colliding on the same issue) is never called by the real attempt pipeline.attempt-runner.jsonly ever requiresdeps.claimLedger.listClaims— it reads existing claims for the freshness check (checkSubmissionFreshness) but never actually claims the issue it's about to work on. The only real callers of.claimIssue(anywhere in the package are the standalonegittensory-miner claimsubcommand (a manual operator tool) and the module's own unused convenience wrapper. In a world with more than one miner running against the same repo pool, nothing in the automated pipeline stakes a real claim before starting work, so two miners can pick up and attempt the same issue concurrently with no coordination.Area: Miner / Claim coordination
Proposal: Have
attempt-cli.js'srunAttempt(orloop-cli.js, whichever owns the claim's lifecycle) callclaimLedger.claimIssue()for real before invokingrunMinerAttempt, and release/expire it appropriately on every terminal outcome (submitted, abandoned, blocked, governed) — mirroring howworktree-allocator.js's slot is acquired/released today.Deliverables:
Acceptance criteria:
gittensory-miner claim listshows a real active claim while an attempt is in flight, and it clears (or expires) once the attempt finishes.attempt/loopinvocation against the same repo+issue observes the existing claim (via the freshness check or a new explicit conflict check) rather than duplicating work silently.Boundaries:
isDuplicateClusterWinnerByClaimfrom@jsonbored/gittensory-engine) is out of scope for this foundation-phase issue. #3355's own original foundation-phase scoping.claim-ledger.js's own storage/expiry logic — this issue only wires the already-builtclaimIssue()into a new real call site.