Route selection moves into one helper, pickRoute(proxyOf), that both checks call: the
primary preflight, and the fallback with its own preflight only when the primary's
fails, with the same messages. The final check passes proxyFor and is otherwise
unchanged. The first check of a proxy launch passes a stand-in session proxy (marker
key PENDING_ADMISSION_KEY and the configured loopback base URL), which reaches only
the preflights, then runs gate() with a null session proxy on the predicted route only.
The round 1 union over both routes is gone.
The managed fixture takes extra (more harnesses switched on), real (harnesses loaded
unfaked) and hostEnv. Seven tests in proxy-launch-order.test.mjs.
F1: with system.proxy set, the first launcher check no longer returns
before the account, sandbox, capacity and limit checks. It skips only the
harness preflight and the session proxy key match, which need the key P2
admits in startLocked. A launch that can never start now refuses before
authorizeLaunch, the workspace and checkouts, and modelPreflight. The first
proxy pass accepts only credential "proxy" for a declared account, tries
the fallback model when the primary refuses, and lets mayLaunch
key-quota-no-model-key through so P2 can issue the first key. The final
check is unchanged and still runs before newRun and spawn.
F4: the proxy test option is renamed testProxy and createLauncher throws
test-proxy-refused when it is given with system.proxy.
launch-account.test.mjs is a second caller, so the option stays.
Tests: proxy-launch-order.test.mjs (6), launcher.test.mjs F4 throw test;
the managed launch fixture gains bwrap, admit and trace.ops.
Ruling 1: the bus runtime passes launchSettings a key lineage lookup read
from its own credential records (ids only). A new daily key quota takes the
earliest stored since among the old document's daily key quotas in its key's
lineage, and now only when there is none. A reset still sets now, a
caller-supplied since still refuses, and a quota removed and added back in a
later write is new. A failed or malformed lookup refuses proxy-key-refused; a
write that adds no new daily key quota never calls it.
Ruling 2: every limits refresh updates the remembered orphan set, an empty
set when no daily key quota is left, so a quota removed and added back logs
again. In memory only: a restart is a fresh observation.
Ruling 3: pollSettledAfterTick yields on the real setImmediate, captured at
load, inside its deadline.
Tests: p5-key-lineage (writer move counts 160, reset restarts, lookup
failure, orphan remove and re-add), p5-runtime (exhausted on A, moved to B
through the real runtime, refuses), p5-background (barrier with every timer
mocked), token-limit-settings (earliest, no match, re-add, caller since,
malformed answers, default refusal). READMEs: business, plugins, daily-quota,
cliproxy-queue.
Appends a BUILD-LOG entry that corrects the R1 entry without editing it: the
R1 walk change also dropped the recursive lstat, which R2 restores; the
tester-cli freePort helper has no callers and binds nothing; the stack-release
and control-board probe-then-bind window stays a known risk for a follow-up.
Appends one SESSIONS line.
R1 passed the parent's stat of a listed directory into the recursive walk,
so a recursive entry no longer took its own lstat. A directory replaced by a
symlink after that stat passed the stale directory check and readdirSync
followed the link; a directory replaced by a regular file leaked a raw
ENOTDIR instead of refusing with project-repository.
The walk now takes a root flag. The .git root keeps its raw lstat and its
own error; every recursive entry takes a fresh lstat through statEntry, so
a vanished entry still maps ENOENT to 'git metadata changed during
inspection' and a replaced one refuses with 'expected local .git directory'.
The mapper is unchanged: ENOENT only.
Two deterministic tests replace a directory under .git/objects inside the
lstat call that stats it as a listed entry, after the real stat is taken:
once with a symlink to a fixture-only directory outside the repo, once with
a regular file. Both refuse with project-repository.
leasePort({closed:true}) ignored its option: it probed an ephemeral port and
closed it, so a parallel test file could bind it and answer a request the
test expected to fail (preview.test.mjs:209 saw 200 instead of 502).
leaseClosedPort holds a bound, non-listening socket in a perl child until the
test's after hook. Connects still get ECONNREFUSED, bind() from another
process gets EADDRINUSE, and the kernel's ephemeral allocation skips the port.
Lane mode keeps its band and per-port lock, and releases the socket before
the lock. leasePort now refuses a closed option, so a stale call cannot get
the unheld port again.
Unanswerable callers (webui preview, serve, service) move to leaseClosedPort(t).
Callers that listen on the port themselves (stack-release rehearse, control-board
serve, tester-cli) keep leasePort and drop the ignored option.
Fixture helpers that commit to a repository the product later inspects now pass
maintenance.auto=false and gc.auto=0, as the product's own git calls already do,
so a detached git maintenance run no longer writes pack temp files mid-walk.
inspectGit now refuses a git metadata entry that vanishes between readdir and
lstat (or between listing a directory and reading it) with project-repository,
'git metadata changed during inspection', instead of leaking a raw ENOENT.
It still refuses rather than skipping or retrying. A missing .git keeps its
existing error.
A deterministic test removes the named entry from inside a replaced readdirSync,
for both a file and a directory.
Ruling 1: model records keep a bounded previous list (64 ids, oldest dropped)
of ids that left by rotation, grace expiry or re-issue; a fire removes the
record. A tokens.keys leaf matches and counts every id in the lineage that
holds it. Lineage ids are unique host-wide. An orphaned leaf limits nothing,
logs one value-free line when it becomes orphaned, and the Console usage
view lists it.
Ruling 2: an agent with no model key under a key quota refuses
key-quota-no-model-key, passed through the broker, launcher and stop reason.
Ruling 3: covered by the lineage; no mayLaunch change.
Ruling 4: the usage module receives a frozen { readUsageQueue } only.
Ruling 5: every telemetry fixture wait races a 5 s real-timer deadline.
GPT review of the 1.19 rebase found the test header still called the PRD a candidate and the rebase record placed lines 793 and 645 in the wrong requirements. Comment and record only; no assertion changes.
Rebased onto refactor as 1.19 because row 335 landed 1.18 first. Requirement text, IDs, order and the 101
records match the approved fd9ae104d apart from version labels. GPT review APPROVE with two P3s, fixed in the
next commit.
Adds agents/gosalyn/work/disk-prd118/REBASE-1.19.md: the cherry-pick
conflicts and their resolutions, every label moved to 1.19 and every 1.18
kept, the byte check against fd9ae104d with version labels normalized, and
the test runs and version mutant.
Row 335 landed PRD version 1.18 first, for the REQ-INST-2 correction. The
disk-space governance text that Jason approved as 1.18 in Q289 therefore
lands as 1.19. Only version labels move: the status line, the disk version
source bullet, the "since version" labels in the disk sections, the disk
milestone, and requirements.json "version". The requirement text, IDs,
order, defaults, settings and the 101 records are unchanged.
The prior approval history bullet now runs through version 1.18 and carries
the row 335 lines. The two test pins follow the renumbering.
Records the replayed join of row 333 R2 (0ef269da9) onto landed row 332 (5df0e9d6f) in merge c0c291cda: the two conflict hunks and their resolution, the comparison with the earlier join resolution, and the nine suite results. Adds the docs/SESSIONS.md line.
R3 (abc66a598) changed its mode from 100755 to 100644. Every other scripts/test-*.sh is 100755.
The landing gate runs it through bash, so no run broke; this restores the R2 mode.
Appends the R3 section to agents/steelbeak/work/queue-227/BUILD.md: the
R2 red on dummy links, the fixes, how the TMPDIR limit is derived, the
namespace containment and control table, runs, signal probes, the tip
check on 5df0e9d6f and follow-ups. One line each in BUILD-LOG.md and
docs/SESSIONS.md. Earlier entries are unchanged.
Joins row 333 R2 head 0ef269da9 (base 09a847eda: R1 503b91e56, overlay
2627321f6, docs c012b2e0a and ddb3e961f, R2 fixtures 12eba4b59 and
0ef269da9) onto refactor with row 332 landed at 5df0e9d6f. Run with the
union attributes for BUILD-LOG.md and docs/SESSIONS.md. Two files
conflicted; no other path did.
packages/business/src/launch.mjs, import block: 332 changed the errors
import to `{ BusinessError, refuse }` for the proxy route refusals; 333
added `isDailyModelQuota` from plugins/src/model-quota.mjs for the daily
model leaves under limits.tokens.keys. Kept both: the model-quota import
and the `{ BusinessError, refuse }` import. The rest of launch.mjs merged
without conflict (332's checkModels route handling and checkAccount
credential "proxy"; 333's checkTokenLimits keys block).
packages/plugins/README.md, end of file: 332 appended "Per-session proxy
context (P3)" and 333 appended "Proxy usage telemetry (row333 / P5)" at
the same spot. Kept both sections, P3 first, one blank line between.
The resolved files match the earlier 332 R1 join resolution
(join-resolution.patch) line for line apart from hunk offsets.
P1: a failed mktemp, mkdir or output redirect now stops the script with
exit 2 before it derives a path, sets a trap or starts anything. The
sandbox root is checked to be absolute, a new empty directory this user
owns and its own physical path, and its device:inode is recorded.
sweep_sandbox and remove_sandbox in scripts/case2/sandbox.sh each refuse
unless the root still matches, so an early, late or empty call gets a
refusal instead of a sweep of the host.
P2: the sweep reads every /proc/<pid>/cwd target with one find and
compares it as a string, root or root plus "/", so *, ? and [ in the
path are literal. A cwd in a deleted directory under the root matches.
P3: a TMPDIR whose tools socket path would pass the 107-byte limit in
packages/seat/src/session.mjs is refused at entry with one line naming
the limit and both lengths. The length comes from the socket path built
on the real sandbox root.
scripts/case2/sandbox-check.sh checks the guard and the match against
dummy symlinks; nothing in it sends a signal.
Row 333 made packages/business/src/launch.mjs and organization.mjs import
packages/plugins/src/model-quota.mjs. The stack-release fixtures copy
packages/business/src and added only plugins/src/kinds.mjs, so their copies
failed with 'Cannot find module .../model-quota.mjs'. Whole cli runs on the
row 333 tip gave stack-release 56 pass 168 fail, stack-release-external
4/21 and stack-upgrade 7/14.
business-imports.mjs reads the imports of packages/business/src and returns
the files outside it that they reach, so both fixture builders copy what
business needs instead of a hard-coded name. No product code, schema or
assertion changes.
Appends the "R2" section to agents/steelbeak/work/queue-227/BUILD.md: findings and fixes,
no step failures past launchFixture, the environment and signal controls, the mutant table
(m6 on requireCitation survived and is a follow-up), run times and the tip check. One line
each in BUILD-LOG.md and docs/SESSIONS.md. Earlier sections are unchanged.
F1 fixed in da1f0ceda, with the federation acceptance red and green runs and
the script suite results. F2: the invalid-proxy-context BundleError is raised
at launcher.mjs:569, outside the try at :655, so :686 never sees it;
fromSession maps it at :1199 and launchPm rethrows it at :1215.
GPT review F1: prepare() built the host env from HOME, PATH, TMPDIR,
MOSAIC_CONFIG and NODE_EXTRA_CA_CERTS only, so the pi credential preflight
refused the assistant launch (no-session-credential) and the RESULT wait
failed. scripts/test-federation-acceptance.sh red on 6e9f3d723, green with
the fake ZAI_API_KEY the cli tests use.
Remove the R1 slot-controller ties from the C2-14 fixture: the ROW227_CONTROL_ROOT
check, the native permit wait in bindLaunch, the fixture-cleanup.json write, the
priority.mjs preload and the owned-bwrap.sh override. The launcher uses its own bwrap.
The shell runs the driver from an explicit env -i environment (PATH, LANG, a sandbox
HOME, XDG dirs and TMPDIR, MOSAIC_CONFIG, no global git config) as its own process
group. On a signal the driver gets 3 s by the clock, then its group and any process
whose cwd is in the sandbox get SIGKILL, inside the landing gate's 5 s grace.
The fixture credentials are defined only in scripts/case2/fixture-credentials.mjs.
The new scripts/case2/leak-check.mjs reads them from there and never prints them.
Append-only R2 section: correction to R1's evidence, the two causes of the
53 cli failures, items 1 to 6 with their tests, RED, hermetic and GREEN
tables, five killed mutants on 39eadf8ba, and the F1, F4 and F2 docs
follow-ups.
The cli tests that launch pi deleted only the session login names, so pi's
preflight passed or refused by whatever provider keys the host exported. A
shared helper now deletes every credential pi's preflight reads and gives pi
launches one made-up key. The refusal itself is unchanged.
pi bundle() takes a default argument again, so a call with none returns the
non-proxy bundle, as before P3. pi.bundle leaves out a launch.models entry
whose provider has no proxy route instead of failing every pi launch (F2);
malformed proxy entries still refuse. The invalid session proxy context
BundleError gets the code invalid-proxy-context. New tests cover F2, the code,
and the three proxy account branches in the launcher (F3).
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.