branch-currency.md
22 lines · skills/ce-babysit-pr/references/branch-currency.md at 3449230
Most marks come from matching words in the file, so treat them as pointers.
Branch currency (third stream)
Branch currency is consumption-only: a base-into-head update happens only for the exact branch_currency item the snapshot emitted, and this step never creates an item of its own. No item means no base-into-head mutation, whatever else moved.
- Branch currency & conflicts (the third stream — after comments and CI). Act on the exact current
branch_currencyitem; never infer a new item from merge-state prose.UNKNOWNmergeability or any non-nullbase_ref_blockeryields no item and is only re-polled. Managed stacks andprobe-errorare excluded from this step. Anormal-baseitem may be target-local for an independent PR or an eligible manual dependency; do not redirect a manual dependency to its parent. An open child dependent does not disqualify a root PR, but this step never rewrites, rebases, or mutates dependent heads. - Inspection and claim lifecycle. When the snapshot invalidates a grouped decision, the currency source still carries its ordinary mutation-safety facts; apply them as usual. If
attention == "decide", return the exact currency source as a typedneeds-humanresidual through the shared--residual-filemark (the same record review and CI use) and do not claim it; only an exact matching recorded answer can authorize another mutation. Ifattention == "inspect", first preview the current conflict and compute its semantic conflict fingerprint. Compare it withparked_semantic_fingerprints, then mark the exact item with--currency-inspected-fingerprint <fingerprint>. Unchanged evidence stays parked; changed evidence retires the old park and reopens the item. Do not claim before that inspection clears. Forattention == "claim", and only while fixed budget remains, atomically mark the exact item before any external mutation or local merge starts:
bash SKILL_DIR="<absolute path of this skill's directory>"; STATE_DIR="<the $STATE_DIR resolved above: $SCRATCH_ROOT/ce-babysit-pr/<host>-<owner>-<repo>-<N>>"; RUN_INVOCATION_ID="<invocation_id>"; RUN_STARTED_AT="<invocation_started_at>"; RUN_BUDGET_SECONDS="<invocation_budget_seconds>"; PY="$(for c in python3 python py; do command -v "$c" >/dev/null 2>&1 && "$c" -c '' >/dev/null 2>&1 && { echo "$c"; break; }; done)"; [ -n "$PY" ] || { echo "no working Python 3 interpreter on PATH" >&2; exit 1; }; "$PY" "$SKILL_DIR/scripts/pr-snapshot" mark --state-dir "$STATE_DIR" --invocation-id "$RUN_INVOCATION_ID" --session-started-at "$RUN_STARTED_AT" --invocation-budget-seconds "$RUN_BUDGET_SECONDS" --currency-key <currency_key> --currency-disposition claimed
A re-entry into claimed is reconciliation-only: inspect remote and local evidence, never directly resubmit. Record exactly one of --currency-outcome mutation-observed, --currency-outcome proven-no-mutation, or --currency-outcome ambiguous. Continue autonomously only through the recovery the recorded outcome leaves safe: reconcile an observed mutation toward confirmation. Exactly one retry is possible only after conclusive no-mutation proof and the engine's backoff. An ambiguous result never retries or resubmits. Confirm against the same --currency-key. Every terminal currency result with no safe autonomous continuation records one complete typed residual with source { id: <currency_key>, kind: "currency" } in that same locked command through --residual-file. This creates the same decision record used by review and CI; currency has no separate parked or answered decision state. Take a human answer through the shared --answer-decision <decision_id> --answer-file <path> transition in tick.md, then act on the reactivated exact observation. A stale invocation, exhausted budget/max-runtime, or head/base movement between claim and mutation rejects or invalidates the action before it writes.
- **
BEHIND: host-owned update only.** Proceed only forroute == "normal-base"withhost_branch_update_capability == true;false/denied orunknownis aneeds-humanpath, never inferred from Git or direct-push authority. After claim, immediately revalidate that remote head and base OIDs still equal the observation. Invoke the host update operation once through GitHub'sPUT /repos/{owner}/{repo}/pulls/{number}/update-branchendpoint withexpected_head_shaset to the claimed observation's head SHA; never use an update helper that cannot transmit that precondition. Treat an HTTP 422 head mismatch as a stale claim: re-snapshot and reconcile without resubmitting. Host acceptance ismutation-observed, not completion. Confirm the exact claimed observation only after a fresh snapshot and ancestry evidence prove the resulting head contains its observed base OID and no unrelated head/base movement or different current currency evidence invalidates that proof. The claimed item's ownbranch_currency_blockerremains until confirmation and need not be null beforehand. A moved head alone is not proof. - **
DIRTY: exact-base local repair only.**host_branch_update_capabilityis irrelevant and does not imply push access. Separately prove, without mutating, ordinary direct-push authority to the exact head ref; unknown or denied authority requires the shared typed decision above. Require a verified clean PR-head checkout at the observed head, fetch the exact observed base OID, and run a non-mutating merge preview. The semantic conflict fingerprint is the sorted conflicted paths plus their stage blob identities; it excludes the base OID so unrelated later base movement cannot disguise the same conflict. A resolution is mechanical only with positive intent evidence and no reasonable alternative behavior. Two plausible resolutions, a material behavior or user-intent choice, unbounded scope, stale OIDs, incomplete evidence, or missing authority means abort safely and pass--semantic-conflict-fingerprint <fingerprint>with the shared residual mark, concrete options, tradeoffs, and a lean. - **Apply and confirm a mechanical
DIRTYrepair.** Claim and revalidate the exact head/base OIDs and clean checkout again, merge that exact base OID, and mark--currency-outcome mutation-observedas soon as the local merge starts. Resolve only the previewed mechanical conflict, validate proportionally, and use a normal push to the exact head ref. Never rebase or force-push. An interrupted local merge must be reconciled to its validated commit or aborted safely before parking; never layer a second attempt over it. Confirm only when remote evidence proves the head equals or contains the validated merge commit, a fresh snapshot clears the currency gate, and no unrelated movement invalidated the claim. Remote head movement alone is not proof or confirmation. - Managed stack or probe uncertainty. With
manager_status == "confirmed", manager currency outranks ordinary state: pre-existing target staleness becomesstack-sync-needed, never this route; Step 7 (managed upstack maintenance) alone performs post-push manager maintenance. With a manager or relationshipprobe-error, continue review/CI but perform no branch-currency mutation or ready declaration until classification succeeds.
unrequested_base_merge (defect detector)
The snapshot flags a head that is a two-parent merge of the base tip when no claimed currency item produced it (unrequested_base_merge: {head, base_parent}; wake reason unrequested-base-merge). That is the incident shape — main moved, someone merged it into a CLEAN PR, green CI restarted — not maintenance. Report it in the tick summary as a defect residual, name who pushed it if the commit tells you, and keep watching. Never undo it with a rebase or force-push, and never treat the resulting BLOCKED-while-checks-rerun as a new blocker. It clears itself on the next head.