v12 update pin race: ucc update holds cccd's start lock from step 6's stop to the installer's start; install.sh retries an unanswered pin and stops before a short lock #74

Closed
caoer115 wants to merge 0 commits from agent/8c00a11c-update-pin-race into main
Owner

Card: 13-16-ucc-rearchitecture tasks/v12-update-pin-race. Branched from agent/bf7fc6b6-v12-cut (4e60b57: main ee28a52 + PR #71 + PR #72), so against main this PR also shows #71 and #72; its own change is the one commit 23d5a56. Found by C r440 U8-to on afe8d99 (a seat hook started cccd mid-install, cccd 1.12.173+ replaced the mrd engine, one pin refused and dropped, step 7 rc 6). Row U8-pin-race.

Card: 13-16-ucc-rearchitecture tasks/v12-update-pin-race. Branched from agent/bf7fc6b6-v12-cut (4e60b57: main ee28a52 + PR #71 + PR #72), so against main this PR also shows #71 and #72; its own change is the one commit 23d5a56. Found by C r440 U8-to on afe8d99 (a seat hook started cccd mid-install, cccd 1.12.173+ replaced the mrd engine, one pin refused and dropped, step 7 rc 6). Row U8-pin-race.
Another live zt2 seat's hook, which runs without CCC_HOOK_AUTOSTART=0, can start the
daemon seconds after the row's seat registers with it down (r433, 18:12:47Z -> 18:12:50Z).
The row now reads the seat's plane-down frame, the next daemon start and that start's
restore of the seat from daemon.log(.1), whichever process made the start; n only when
the log has no plane-down frame naming the seat.
A 1.12.136 ucc-<profile> launcher execs $UCC/bin/skills-bin/ucc-shadow-ensure under a Paseo,
Codex or OpenCode runner; the landing rebuilt skills-bin from the release, which ships no such
name, so every Paseo seat exited 127 after the crossing (11-15's rehearsal on f1840d7).

kl_list/kl_calls read every skills-bin and shared/skills path a launcher the host keeps names.
sb_keep finds, before a skill moves, each skills-bin name such a launcher calls whose link ends
at an executable file outside what the landing replaces (the fleet's own cc-continuity tree);
the build links it again there after the release's names, on every install. C8 reads the
launchers against the same dry build: kept, replaced and rebuilt calls go in the plan, any other
refuses before L0.
legacy-home.sh: ucc-kimi and ucc-jarvis carry 1.12.136's non-TTY branch (exec skills-bin's
ucc-shadow-ensure under PASEO_AGENT_ID/CODEX_THREAD_ID/OPENCODE_SESSION_ID, exit 127 where it is
not executable); a stand-in shim that logs each call sits in the fleet checkout's ccc-herdr,
reached through the shared/skills link the landing replaces; ucc-cli names ccc-telegram's script
by its shared/skills path and skills-bin's ccc-tmux.

X-cross-kept-calls: the plan names the four calls (two kept, one replaced, one rebuilt), the
landed skills-bin links the shim to the fleet file and install.log says so, the Paseo seat's
reload ran through it, and ucc-kimi under a runner's marker answers rc 0 through it.
X-cross-census plants the refusal: the shim's link moved into the real-directory ccc-base.
X-cross-then-update reads the kept link again after ucc update.
F1: sb_keep reads every entry of the host's skills-bin, not the launchers' literal calls: each one whose link ends at an executable outside
XSET, in no file or folder any account can write (anyw), is linked again by its physical path. The launcher scan stays for the plan and
the refusals; the census prints every skills-bin name the rebuild keeps or drops, and why (sb_plan, sb_why).
F2: sb_add_keep passes on only names no skill of the build carries, so a release name (ccc-tmux on the fleet layout) logs no skip.
F3: the keep set is written to bin/.skills-bin.keep before the skills move and read back while skills-bin.prev stands; the census reads
the set-aside skills-bin too (sb_dir); on_exit removes the file once no set-aside skills-bin stands, the build once it completes.
F4: rebased onto main ee28a52; CHANGELOG keeps PR #69's Rows bullet; counts re-measured (install.sh 2643 lines, README § Crossing 1374
words, manifest 323).
Rows: the fixture gains fleet-old-tool (kept, run bare after the crossing) and fleet-gone-tool (dropped); X-cross-kept-calls reads the
plan's skills-bin lines, both links, no skip line and no keep file left; X-cross-census gains kept-call-open, and kept-call's text moves.
N1: on_exit removed bin/.skills-bin.keep as soon as it put skills-bin.prev back, so a run killed after the
skills landed, then a re-run that stopped normally, left a third run reading the old skills-bin through the
release's skills and dropping the kept names. sb_keep now reads the keep file whenever it stands, then the
other names of the skills-bin; the build removes it once the new skills-bin is complete; on_exit removes it
only where this run read skills-bin alone and stopped before a skill moved.

README § Crossing, CHANGELOG § v12 and sb_keep's comment say what anyw reads: the other-write bit of the
file and its folder. Counts re-measured: install.sh 2649 lines, README § Crossing 1387 words.
C r440 on afe8d99: a live seat's hook started cccd 20 s into the install; cccd from 1.12.173 replaces a
mrd engine it did not start, the one lock pin in that gap was refused ("mrd write verbs talk to the
running daemon … Connection refused"), pin_row logged it and carried on, and step 7 found the contract row
dropped and restored the installed release, rc 6.

- ucc: start_lock — a holder subshell of ucc's own takes cache/ccc-status/daemon.start.lock (flock, or
  perl's on a stock Mac) before step 6's `cccd stop` and holds it until the installer removes the file it
  waits on (UCC_START_LOCK), or within 0.2 s of ucc ending; no child of ucc or the installer inherits the
  lock. While held, a hook's auto-start (Daemonize, wait 0) spawns nothing. Only an installer that names
  UCC_START_LOCK gets it (an older one would wait on it at its own start); the restore's installer too.
  A start lock held 20 s stops the update before the daemon stops, nothing applied.
- install.sh: releases the lock right before its own daemon start (xlock 5, xunlock). pin_row tries a pin
  refused with mrd's daemon-down words again, ten times a second apart; one still unanswered refuses rc 1
  before the lock's commit. The contract-row fingerprint check stays outside ucc update: under it the
  contracts checkout is the followed main, not the release's pin, and step 7's root guard holds the rows.
- Row U8-pin-race (--tarball-next --start-candidate): a git shim in zt2's ~/.local/bin plants, on V3's
  `install: V3 at floor` commit, a one-shot mrd whose first pin runs a seat's hook (`cccd hook`), notes
  whether a daemon came up, and answers with mrd's daemon-down words. Pass: no daemon, the pin lands on
  try 2, rc 0, V3 green.
- CHANGELOG § v12: the line; counts install.sh 2664, ucc 1327, manifest 324.
Leader d9c794b6's round-1 ruling on 23d5a56 (findings 1 and 2, residual (a)).

- 1: steps 6-7 run in the installed ucc, so a v11 host's update into v12 ran with no start lock. install.sh
  under ucc update (UCC_FOLLOWED_AT) with no UCC_START_LOCK, at floor 3, takes it before the binaries
  (start_hold): a holder subshell of its own on flockfd 8 (flock(1), else perl's flock on the inherited fd),
  waiting on SLOCKO and kill -0 $$, so no child of the run inherits it. It goes at the daemon start, by the
  same release as a handed lock (SLOCKM), or when the run ends (on_exit removes SLOCKO). Before the binaries:
  converge_resident leaves a resident mrd that is no cccd's child, and the placed cccd >=1.12.173 replaces it.
  A lock held 20 s by another start: logged, the run goes on, the pins to pin_row's tries.
- 2: pin_unanswered: every transport-class failure of mrd at meridian-rs c5f70a43 (DAEMON_DOWN; "did not
  greet", stalled or silent; "was never delivered … NOTHING was committed"; "the answer to the write on … was
  lost") is tried again, ten times a second apart; exhausted, rc 1 before the lock's commit, any row. A pin
  is an upsert by object and selector (crates/lock/src/lib.rs:338), so a lost answer re-pinned is one row.
- (a): an update meets a systemd-unit cccd only on a crossed fleet-style host (install.sh writes no daemon
  unit; devstation-nyc-1 and workstation-nyc-2 run home-manager's ccc-statusd.service and are no ucc
  installs). There the unit restarts the daemon 5 s after the stop, TakeOver waits 10 s on the held lock and
  starts anyway (internal/core/main.go:586 warns, no loop), and the installer's start restarts it through the
  unit: active (receipt on the card).
- Rows: pin_race_git (round-host.sh) generates the race shim for three rows. U8-pin-race fires at the first
  pin and the first try of every pin on V3's own record (the last rows pinned), answering in turn with
  mrd's four unanswered words; the git shim puts the real mrd back at the `install: <n> pins` commit, before
  the walk and step 7 hash it. New U8-pin-refused (zt2): V2's record § pins answered as lost ten times ->
  V3's installer refuses before the pins commit, rc 6, V2 restored, the restore met no refusal. New
  install-update-pin-race (zitao2, --tarball-prev): rides install-update, the previous release's ucc
  updating into the candidate; from before v12 the installer's own start_hold line is required.
- CHANGELOG § v12 and UPDATE.md step 6 say where the guarantee starts: an installer from v12, whatever ucc
  runs it; a --to/--rollback into a release before v12 keeps that release's behaviour.
Leader d9c794b6: nothing had run the darwin holder (perl's flock on the inherited fd) to show the lock is
held on macOS. darwin.sh role a (mac1), after launchd-daemon-darwin: ucc's start_lock (the installed
bin/ucc's) and install.sh's start_hold (the stage's, under an update that handed none), each cut from its
file; each takes the lock, then cccd stop, a seat's cccd hook, the lock read from outside by perl's LOCK_NB,
the release. Pass: no flock(1) on PATH, held by each, no hook brought a daemon up, each release left it
free; the daemon started again after. bash -n on 3.2.57 ok; a dry run of the block on Linux with no
flock(1) on PATH passes (receipt on the card); not run on a Mac.
Leader d9c794b6's round-2 ruling on 5e8225f (finding 3, lows 1, 2, 4, 5).

- 3: has_part/has_mods read through rec_section, in the main shell (a refuse inside $(...) would have
  exited the subshell alone and read as absent). Absent is mrd's ref_not_found or file_not_found, or a
  serve of other than one section; an unanswered read is tried again ten times a second apart; one still
  failing, or any other refusal, refuses rc 1 before the lock's commit. Checked against the host's mrd
  c5f70a43 on a scratch workspace: § present -> its text, § absent -> ref_not_found -> empty.
- 4: mrd_ask runs every pin and decision read with --json (frame in cache/mrd-out.<pid>, stderr in
  mrd-err.<pid>, on_exit removes them). mrd_unanswered goes by mrd's class: exit 2 (Fail::tool: for these
  fixed calls the dial — DAEMON_DOWN, stalled, silent), recovery retry|respawn (lock_timeout, stale_view,
  workspace_busy, corpus_*), and of io_error (recovery env, also the world's: no git blob oid) only
  write_ipc's client halts: never delivered, answer lost, answer would not parse, ok body not a write, error
  frame would not parse, no error body. Any other refusal is final, as before.
- 1: install-update-pin-race's n line no longer names $v_cur before it is set (set -u, v1-v7).
- 2: the race mrd also fires on every pin of the record install.sh pins last in its glob's order (v9 after
  v12), logged `last record <v>`; and answers the first decision read of V's record as the dial, once.
  Its answers now take mrd's shapes: exit 2 for the dial, an io_error frame and exit 1 for the halts.
  pin_race_ok <file> <V> requires both and the read's `read … on try 2`.
- 5: CHANGELOG § v12 and UPDATE.md step 6 name the likeliest pre-v12 installer: v11's restore of v11 after
  a failed update into v12, beside --to/--rollback into a release before v12.
Counted as at 4e60b57 (wc -l, wc -w, manifest rows without comments or blanks); ucc 1327, skills.md 552 and
README § Installing 2237 / § Crossing 1387 words are unchanged.
Round-3 review of 21e83e9 (Fable correctness): three lows, no silent skip. Low 1: rec_section's refusal said "the lock is not committed" at the post-commit guards (has_mods/has_part after `install: $pins pins`) — LOCKED now set at the commit picks the words. Low 2: mrd's read-side client halts ("the daemon served the read but dropped the §4.7 scoped-mint exchange", "the daemon refused the §4.7 scoped mint with a frame that is not the §8 envelope"; meridian-rs c5f70a43 read_cmd.rs:423-447) join the io_error retry list. Low 3 accepted: exit 2 also covers a workspace not resolved or a hello refused; they take the same ten tries and then refuse (bounded, loud); the comment and CHANGELOG now say "mostly the dial". CHANGELOG count: install.sh 2728 lines.
Author
Owner

Merged as e989d95 (merge of 4794a76); main carries it from d9ce45e = release v12, published 05:05Z 2026-10-25.

Merged as e989d95 (merge of 4794a76); main carries it from d9ce45e = release v12, published 05:05Z 2026-10-25.
caoer115 closed this pull request 2026-10-25 05:12:02 +00:00

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
caoer115/ucc!74
No description provided.