install.sh never leaves a green walk on a half-replaced host; ucc adopt, ucc stage, install.sh --release #36

Open
caoer115 wants to merge 0 commits from agent/00d1fa4a-install-never-half into main
Owner

Card: 13-16-ucc-rearchitecture/tasks/install-never-half.md (worker 00d1fa4a). Closes delta-review-2 new 4, 16, 17, 3, 13, per-item 24 and the end report's § Open 'Also for v4' (the adoption block) and 'Stock seats'. Proven locally: the :507 lines on the real v2 template (SR_FORMATS=1), the nothing-written and INCOMPLETE stop paths in a throwaway HOME, ucc stage's shape pass and token refusal on releases/v3.md, --release's refusals before a byte. Round r255 (public line, --tarball-prev --token) is the successor's: U8-to-real, F22-install-dies, stock-seat-skill-dir, install-update with --release. tooling.sh rc 0.

Card: 13-16-ucc-rearchitecture/tasks/install-never-half.md (worker 00d1fa4a). Closes delta-review-2 new 4, 16, 17, 3, 13, per-item 24 and the end report's § Open 'Also for v4' (the adoption block) and 'Stock seats'. Proven locally: the :507 lines on the real v2 template (SR_FORMATS=1), the nothing-written and INCOMPLETE stop paths in a throwaway HOME, ucc stage's shape pass and token refusal on releases/v3.md, --release's refusals before a byte. Round r255 (public line, --tarball-prev --token) is the successor's: U8-to-real, F22-install-dies, stock-seat-skill-dir, install-update with --release. tooling.sh rc 0.
install.sh: one rule for every stop — before a byte moves a refusal says nothing written; after one, opt/VERSION.md reads INCOMPLETE naming the step and what was placed, so the lock reads red on it and never claims a release whose binaries are not all in place (an EXIT trap and refuse() replace the bare exits; delta-review-2 new 17). The template-side formats read tests the page before it extracts (new 4: ucc update --to v2 died at :507). The --desktop merges refuse on a jq failure instead of logging success (new 16). --release v<N> [--token] builds the stage from the clone's record through ucc stage and installs from it; --profile, --port and --desktop not given are read from the installed host (new 3). env.sh and the Desktop settings export CCC_SKILL_DIR to the installed skills (per-item 24). A first floor-3/4 install is born with cache/ccc-status/client-window.closed (daemon-v155's marker, inert until the daemon honours it).

ucc: `stage` (the record's shape, PINS, every artifact downloaded and hashed — shared with update step 4); `adopt` (UPDATE.md § sessions root's block as a hashed verb: the pages, every door armed, M6's bounded wait on .meridian/write.lock, a persisting refusal stops it naming the door, a re-run idempotent; new 13's zsh exit); update reads an INCOMPLETE opt/VERSION.md as the installer's own red and goes on, keeps `previous` at the last landed release, and on an installer stop restores the previous release from its stage under releases/ when it is there, else names the step.

UPDATE.md § release states the owner's step with its inputs (--release, --token, --env), § sop 6 the stop rule, § sessions root names ucc adopt; CHANGELOG § v3's owner step reads reinstall with --release v3, then ucc adopt. § tooling rewritten.

rounds: U8-to-real (ucc update --to the real previous record on the public line), F22-install-dies (a planted stop after the binaries moved: INCOMPLETE, red on opt:VERSION.md alone, the restore attempt named, green again once unplanted), stock-seat-skill-dir (the seat's Bash reads CCC_SKILL_DIR and the handoff SOP's first path exists); install-update's reinstall runs the documented step word for word (--release, no --from/--env/--port).
Security review of PR #36 (leader 69ca540f, work/69ca540f/reviews/pr36-security.md):
- F1: install.sh follow() under ucc update (UCC_FOLLOWED_AT = the ucc commit step 1
  walked, set for the target and the restore installer) pulls no followed checkout;
  a branch move lands at that commit. The restore is walked against the root
  (root_moved, step 7's loop as a function); a restore that re-pinned a root row has
  opt put back to step 1's commit, red on what moved.
- F2: install.sh incomplete() writes landed: (the last release that landed, carried
  across stops); ucc's downgrade guard reads it when release: is INCOMPLETE.
- UPDATE.md § sop steps 2 and 6 say both; § tooling rehashed.
- Rounds: F24-incomplete-downgrade (in F22's INCOMPLETE state, the remote names V1:
  refused), F23-restore-forge-moved (a § sop push lands between the target's stop and
  the restore: V2 restored with its lock at step 1's commit; pulled after, red, refused).
Security re-review of PR #36 (N1): the release name a host records (opt/VERSION.md
release:, landed:, ucc update's downgrade floor) was releases/current.md's frontmatter
version:, which the lock does not pin; it pins § version and § pins alone. A push that
moved the frontmatter alone set the floor (v1: any older release passes the guard; v999:
every real update refused).

- ucc step 2: a plain update whose followed checkout's frontmatter version: is not its
  § version is refused, rc 3, nothing downloaded; on --to/--rollback the stage's
  current.md is written from the record when either name differs from the target.
- install.sh: a stage whose current.md frontmatter and § version differ is refused
  before a byte moves (rc 4), so a hand-run install records no name the lock does not pin.
- UPDATE.md § sop step 2 states it; § tooling rewritten.
- rounds: F25-record-two-names (ucc update rc 3 and install.sh by hand rc 4 on such a
  push); F26-restore-root-moved (a pinned contract file edited while V3's install is
  stopped: the restore's root check names the move, opt/ reset to its commit before the
  overwrite, red on the contract rows) — the reset branch F23 never reached.
- round-host.sh: the previous release's install passes --ucc-remote/--ucc-branch only
  when its installer takes --ucc-branch; v2's takes --ucc-remote alone, so every --public
  round with v2 as the previous release stopped at install/zitao2 (r255).
r256's install-update row: `ucc adopt` replaced rules 025 and 027 and added 005, 030,
031, then stopped (rc 1) before arming any of them. `mrd rules --json` exits 1 while an
armed door's page has drifted — every replaced page is one — and still prints the set;
UPDATE.md's shell block ignored that exit in a pipeline without pipefail, the verb's
`rows=$(…)` under set -euo pipefail did not. The JSON is now read with that exit
tolerated; an unreadable or empty set stops naming it; a set still red after arming
stops naming it instead of exiting through the closing `mrd rules | tee`.

Run on r256's kept VM as zitao2 (v2-born root, pages copied, nothing armed): 005, 030,
031 armed, 025 and 027 re-armed at their live revs, `mrd rules` clean, rc 0; run again:
every door "already armed … unchanged", rc 0.
Leader ruling A8 on PR #36: the default MCP config ($UCC_HOME/config/mcp/ccc-statusd.md)
puts every seat's read and put on the host bearer, and a daemon carrying ccc-statusd #845
(v1.12.155, which v4 pins) honours cache/ccc-status/client-window.closed by refusing the
host bearer — a fresh v4 install would refuse every seat's record calls from its first
day. The step that birthed the marker and its log line go; the marker returns once seats
use their own tokens.
Second security review of PR #37, finding 1 (69ca540f): step 7's exit 6 when the root
moved left opt/ as the install re-pinned it, so the `ucc update --rollback` its stop line
names walked green at its step 1 on the re-pinned rows. opt/ is now reset to its commit
before the overwrite (OPT0, as the restore path does) and walked again; the stop names
what reads red. UPDATE.md § sop step 7 says so; § tooling rewritten.

Row F27-install-root-moved (90-u8.sh, manifest stage: --tarball-next): a pinned contract
file edited once ucc update has walked its root (its `target V3` line in update.log) —
V3's installer pins it, step 7 names the move, opt/ back at its pre-overwrite commit, red
on the contract rows, and the rollback refuses at its step 1 (rc 3).
Leader 3635f01e's review of 883d8b2..254ae64 (results/review2-security/pr36-254ae64-security.md),
residuals 1 and 2:
- step 7 computes the root move and puts the lock back before the red-walk stops, so a
  walk red elsewhere never leaves re-pinned root rows behind it;
- a `git reset --hard $OPT0` that fails (restore path and step 7) stops with exit 6
  naming that the lock could not be put back, instead of exiting 128 under set -e with
  no line and the lock re-pinned.
mrd walk prints a target in the lock's own root bare (VERSION.md), so
step 1's skip of the installer's own mark (opt:VERSION.md) never fired and
every ucc update on an INCOMPLETE host refused at step 1 (r257: F24, F22's
unplant, F23, F25, F26). not_green prefixes a bare target with opt:, which
also makes ucc status and the receipts name it as UPDATE.md does.

install.sh removes skills-bin before the skills installer runs: its verify
fails on a link into a script the new tree drops (r257 U8-to-real, v4 -> v2).
skills-bin is rebuilt from the new tree after it.

The prune after a landed update keeps the stage of the release that last
landed ($LANDED), so --rollback from a host that was INCOMPLETE finds it.

Rounds: F22 allows the release record's red beside opt:VERSION.md (the lock
still pins V2 while the remote names V3); F25's by-hand install unsets the
user's UCC_HOME and the other in-HOME variables.
Security review of 34cb469..155fc2d (leader 3635f01e), residual 1: step 1
passes over the red on opt:VERSION.md §VERSION/components alone, matched
exactly, not by prefix. UPDATE.md § sop step 1 says so: after an install
that stopped, that red is the install's own mark; every other red stops.
Residual 2: install.sh names skills-bin in what the run placed once it
empties it for the skills installer.

Row F28-incomplete-foreign (the review's first testing gap): on the host
F22 left INCOMPLETE, install.sh edited and § tooling regenerated — ucc
update refuses rc 3 on § tooling, opt:VERSION.md not named, nothing
downloaded, still INCOMPLETE.

F7: the launcher it writes always turns the mint off (UCC_SEAT_MINT:-0),
swapping in claude-patched-prev only when the install has it. Since
install-update's owner step installs the published set (install.sh
--release), zitao2 carries no claude-patched-prev on a --public round, and
the fallback ucc-glm minted, so F8 had no host-token write to grade (r257).
After f22-unplanted HEAD is F28's revert; u8_revert reverted HEAD, which put
F28's install.sh edit and regenerated § tooling back on the round remote, and
every row from f22-back on read red on § tooling (r258, found by 7ddd0997).
F24 and F28 net to zero above F22's push, so its revert applies cleanly.
This branch is already included in the target branch. There is nothing to merge.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin agent/00d1fa4a-install-never-half:agent/00d1fa4a-install-never-half
git switch agent/00d1fa4a-install-never-half

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff agent/00d1fa4a-install-never-half
git switch agent/00d1fa4a-install-never-half
git rebase main
git switch main
git merge --ff-only agent/00d1fa4a-install-never-half
git switch agent/00d1fa4a-install-never-half
git rebase main
git switch main
git merge --no-ff agent/00d1fa4a-install-never-half
git switch main
git merge --squash agent/00d1fa4a-install-never-half
git switch main
git merge --ff-only agent/00d1fa4a-install-never-half
git switch main
git merge agent/00d1fa4a-install-never-half
git push origin main
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!36
No description provided.