CB-596 code is live; 1.1 is down to two operator actions
+44
-17
@@ -232,9 +232,9 @@ commits** have landed on `main` with **no tag**. So the stage tables above are t
|
||||
the obvious question unanswered: what is actually left before the single-host story can be called
|
||||
finished?
|
||||
|
||||
**The answer, as of 2026-08-17: one implementation unit, CB-596.** Everything else in 1.1 is merged
|
||||
and deployed. CB-596 looked like a single operator command; running that command is what showed it is
|
||||
not. See *Open* below — the measurement was step 1 of six.
|
||||
**The answer, as of 2026-08-17: no code. Two operator actions.** Every ticket in 1.1, CB-596
|
||||
included, is merged and running on the live daemon. What is left is the half of CB-596 that lives in
|
||||
the operator's own secret store, plus the probe that proves it. See *Open* below.
|
||||
|
||||
Gitea milestone: **`1.1 — single-host close-out`**. The admission rule is one sentence — **if it
|
||||
would still be broken with exactly one host, it belongs in 1.1.** Read strictly, that rule sent four
|
||||
@@ -268,9 +268,10 @@ flowchart LR
|
||||
class op,fed,defer todo
|
||||
```
|
||||
|
||||
*Figure: the 1.1 milestone by theme, as of 2026-08-16 night. Green is merged; amber is open. One
|
||||
amber box is left, and it is the one no session can close: CB-596 needs the operator to run a probe
|
||||
the command classifier refuses. Everything on the left is single-host work; the right is release 2.*
|
||||
*Figure: the 1.1 milestone by theme, as of 2026-08-17. Green is merged and deployed; amber is open.
|
||||
The one amber box on the left is CB-596, and its code is green — what is amber is the half that lives
|
||||
in the operator's secret store, which no session may edit. Everything on the left is single-host
|
||||
work; the right is release 2.*
|
||||
|
||||
### Done — merged and verified
|
||||
|
||||
@@ -288,11 +289,11 @@ the command classifier refuses. Everything on the left is single-host work; the
|
||||
|
||||
### Open
|
||||
|
||||
One — and it grew when it was measured.
|
||||
One — and its code has landed. What is open is a file no session may edit.
|
||||
|
||||
| Theme | Ticket | The point |
|
||||
|---|---|---|
|
||||
| **Credential scope** | CB-596 (#82) | CB-592 blocks one credential name. A member's pane runs a login shell that re-sources the operator's whole secret store, so the other names come straight back. **Measured 2026-08-17 inside a live member: 31 names, all set.** Criterion 1 is done; criteria 2–6 are an implementation unit, now delegated. |
|
||||
| **Credential scope** | CB-596 (#82) | CB-592 blocks one credential name. A member's pane runs a login shell that re-sources the operator's whole secret store, so the other names come straight back. **Measured 2026-08-17 inside a live member: 31 names, all set** — later 34 once the gap detector ran. The fix merged (`ac40de1`) and is deployed (jar `e11160695fbe`): `memberCredentials:` in config, deny-by-default, 34 known / 7 allowed / 29 blocked, with a startup summary and a per-spawn gap warning. **The remaining half is the operator's:** the launcher writes the member's environment, and then the pane's login shell overwrites it, so the same block must be re-applied by a `BRIDGED_MEMBER`-guarded export at the end of the secret store. |
|
||||
|
||||
**What the measurement actually said.** Two results, and they point in opposite directions.
|
||||
|
||||
@@ -318,6 +319,20 @@ safe way to compare two readings on one machine and an unsafe thing to publish:
|
||||
has length 5 and hashes to `8c6976e5b541`, which is SHA-256 of `admin`. A truncated hash of a
|
||||
low-entropy value is not an anonymiser. The finding was written up with names and lengths only.
|
||||
|
||||
**What the fix found that no list contained.** The gap detector warns, on every spawn, about any
|
||||
credential-shaped variable on neither `known:` nor `allow:`. On its very first spawn it named two:
|
||||
`CLAUDE_CODE_MESSAGING_TOKEN` and `SSH_AUTH_SOCK`. Neither is in the secret store, so no list written
|
||||
by reading that file could ever have held them. `SSH_AUTH_SOCK` is the serious one — a member needs
|
||||
it to push, because worktree remotes are `ssh://`, but it lets a member sign with every key the
|
||||
operator's agent holds. That is strictly broader than the repo-scoped forge token CB-302 built to
|
||||
avoid exactly this. Allowed for now, with the reasoning written into the config; filed as **CB-607
|
||||
(#110)** on 2.0, fixed by pushing over HTTPS with `WORKER_GITEA_TOKEN`.
|
||||
|
||||
The general lesson is worth more than the instance: **the enumeration was of a file, and the exposure
|
||||
is of an environment.** Anything granted by a handle rather than by a value is invisible to a list
|
||||
built by reading `secrets.sh` — which is the argument for having the daemon report the gap instead of
|
||||
trusting the list.
|
||||
|
||||
### Deferred to 2.0 — the cut decision
|
||||
|
||||
Made 2026-08-16, by reading the admission rule strictly.
|
||||
@@ -332,15 +347,27 @@ Made 2026-08-16, by reading the admission rule strictly.
|
||||
### Before the tag
|
||||
|
||||
1. ~~Land or defer CB-606 and CB-586.~~ Both merged and deployed.
|
||||
2. **Land CB-596.** Its measurement is done and it is delegated; criteria 2–6 still have to land and
|
||||
be verified. This is the last code in 1.1.
|
||||
3. ~~Redeploy the daemon.~~ Done 2026-08-16: `scripts/redeploy-bridged.sh --yes`, 860 tests, BUILD
|
||||
SUCCESS, jar `64908de1cb56`. **CB-596's fix will need another redeploy after it merges** — a merge
|
||||
is not a deployment, and this one changes what a member's environment contains.
|
||||
4. ~~Confirm `bridge_whoami` still answers `primary`.~~ Done: `primary`, leader `opus`. Note the trap
|
||||
— the redeploy cuts the lead's own bridge MCP mount and it does not reconnect by itself, so this
|
||||
check usually needs the operator to run `/mcp` first.
|
||||
5. Then tag `v1.1.0` and mark this section closed.
|
||||
2. ~~Land CB-596.~~ Merged `ac40de1`, 870 tests, BUILD SUCCESS.
|
||||
3. ~~Redeploy the daemon.~~ Done twice. The second, 2026-08-17, put CB-596 live: jar
|
||||
`e11160695fbe`, and the startup line reads
|
||||
`memberCredentials: 34 known name(s), 5 allowed — blocking 29 on every spawn`. A merge is not a
|
||||
deployment, and this change alters what a member's environment contains.
|
||||
4. ~~Confirm `bridge_whoami` still answers `primary`.~~ Done: `primary`. Note the trap — the redeploy
|
||||
cuts the lead's own bridge MCP mount. It reconnected by itself the second time and did not the
|
||||
first, so do not rely on either; if the tools are gone, ask the operator to run `/mcp`.
|
||||
5. **Two operator actions, in this order.** Neither can be done by any session.
|
||||
1. **Rotate `GITEA_ACCESS_TOKEN`.** A lead leaked about 31 characters of it into a transcript
|
||||
while dumping the structure of the secret store: the redaction covered `export NAME=…` lines,
|
||||
and the token is set on a line that begins with a guard, so it fell through. Reported at once;
|
||||
the operator chose to rotate later.
|
||||
2. **Append the CB-596 block to the secret store.** A `BRIDGED_MEMBER`-guarded loop that exports
|
||||
the same sentinel over the 29 blocked names. It is a drop-in block that moves, copies and
|
||||
retypes no value; the daemon's blocked set and that block were diffed name-by-name and agree.
|
||||
6. **Then run the verification probe:** spawn a member and run `scripts/probe-member-credentials.sh`.
|
||||
The pass condition is that the 29 blocked names come back at the sentinel's length and hash, and
|
||||
the 7 allowed keep their real lengths. That measurement is what lets #82 close honestly — the
|
||||
config half alone does not prove anything, because the login shell runs after it.
|
||||
7. Then tag `v1.1.0` and mark this section closed.
|
||||
|
||||
**On "Stage 5 ✅ production shape".** That row was never wrong — CB-504 did build a launchd agent and
|
||||
a systemd unit. But a unit in `deploy/` that no host has loaded is not supervision. CB-594 and CB-600
|
||||
|
||||
Reference in New Issue
Block a user