Repository navigation
scripts, docs: CS-RG qualification harness and protocol (CSRG-U6) - #97
Merged
Merged
Conversation
scripts/qualify-devguard.py runs the CSRG-U6 qualification on the macOS host: candidate records the exact combination, matrix runs the claimed modes against the installed DevGuard service, faults and authority inject failures against DevGuard's fixture authority, control measures the control path under DG-1's load, and verify recomputes a sealed run's verdicts from its raw files. It drives codespace-mcp over MCP stdio with its own small client, reads DevGuard's journal read-only, gives every child a minimal environment, and never reads, prints or passes a credential: the gateway is given the credential file's path. qualify_analysis.py holds the verdict rules as pure functions; Python 3.9 with no third-party packages. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…CSRG-U6) docs/cs-rg-qualification.md, in English and Korean, is the protocol the harness implements: the candidate, the supported-mode claims, the functional matrix and fault cases with their pass rules, how the order's fault list is covered and where it is not, the control-path targets, schedules and verdicts, accounting, regressions and evidence. It also records the decision the work order requires for the existing backends (CSRG-C09): keep participation off as the compatibility path and default, with its scope, duplicated parts, what it does not provide, and when to revisit or remove it. The integration roadmap links the page from its status and from the C09 paragraph. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The comment on Participation::Required still said CodeSpace could not launch them yet, which stopped being true with CSRG-U4. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The qualification Mac ran the suites at 7a0a748 on 2026-10-13. Three of its failures were the harness's: - matrix expected a governed PTY's death by SIGTERM as exit code 1. A governed PTY child inherits its launch descriptors, so the pinned Codex PTY spawns it on its descriptor-keeping path, which reports 128 plus the signal (143), as docs/devguard-integration.md already says. The harness, the protocol and docs/agent-integration.md, which named only 1, now say so. - matrix's settled check read DevGuard's instances once, right after the last gateway exited, and failed on an instance DevGuard retired moments later with nothing charged. It now awaits the charge and the instances for up to 60 seconds, and its stop message names both. - authority's restarted phase started its termination targets while DevGuard still kept new work closed after the stalled phase's stale host sample. A target refused RESOURCE_UNAVAILABLE is now tried again every second for up to 90 seconds, and the phase records the wait. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 3 of the CSRG-U6 plan: the qualification harness and its protocol, frozen together before any qualification run. Nothing here runs or claims a qualification.
No pin change. No change to the installed service.
Issue
Scope: CSRG-U6 (parity, fault qualification and completion). Tracked in #76 and novelKR/DevGuard#14. This PR does not close an issue.
mainat7024f74(#96's merge)8ed8b086b9826e3with the recorded patch (tree19999371), DevGuard6e7e065; both unchangedSummary
Harness.
scripts/qualify-devguard.py, withqualify_host.pyandqualify_analysis.py. It needs Python 3.9 and no third-party packages, and runs on the qualification Mac in a minimal environment.candidaterecords the exact combination incandidate.json: the commit and its code-tree hash, the DevGuard client pin, the Codex patch check, the binaries, the installed release and whether it matches its manifest, the policy (host.tomlhash,doctor, thecodespaceconsumer without its credential digest), the DG-1 qualification record, the toolchain and the host.matrixruns the claimed modes against the installed service, in-process anduds, pipe and PTY. It covers registration, exits, I/O, termination, timeout, exec failure, shortage, an unsupported minimum, mixed governed and ungoverned executions, a missing or unusable helper, status mode, an unavailable authority and a runner socket. Each governed launch is checked against DevGuard's journal.faultsandauthorityinject failures against DevGuard's fixture authority, never the installed service. The faults are surviving and escaping descendants, a stalled observer, the authority lost, restarted or stalled, a helper ending before READY, refused and missing credentials, a terminate race, shutdown, and a worker killed while preparing.authoritymeasures process control while the authority is paused, stalled, restarted or stopped.controlmeasures the control path under DG-1's load: status p99, termination acknowledgement p99 and the scope's actual end, I/O round trips, refusal latency, and the footprint against the reservation. It runs three repetitions per runner mode, each 10 minutes idle and at least 30 minutes of load.verifychecks a sealed directory's manifest and recomputes every verdict from the raw files.Protocol.
docs/cs-rg-qualification.md, in English and Korean, covers the candidate, the supported-mode claims and every scenario's pass rule. It maps the work order's fault list to the cases and names the known gaps: a replay on the runner wire is not tested, and a journal refusal is not injected. It also gives the control-path targets (DevGuard's SLO protocol, not redefined), the verdict rules, accounting, regressions and evidence. The integration roadmap links it.Legacy
offpath (CSRG-C09). The decision record keeps participationoffas the compatibility path and default, unchanged. It gives the scope, the reason, what is duplicated, whatoffdoes not provide, and when to revisit or remove it. This is the U6 plan's recommendation (its open question 3), so merging this PR records it. Likewise, the control measurement qualifies under the cold load condition; a warm run is an additional condition when it is made (open question 4).Comment fix. The doc comment on
Participation::Requiredno longer says that CodeSpace cannot launch governed executions.Found while building. On the qualification host the Codex submodule holds the recorded patch, so a plain
git statusreports the checkout as dirty. The harness leaves the submodule's files to the Codex check, and a submodule at another commit still counts as a change.Fixed after the macOS check. The Mac's check of
7a0a748found three faults in the harness, fixed in8ed8b08:tty: trueprocess killed by SIGTERM reportsexitedwith exit code 143 (128 + 15), not 1. The pinned Codex PTY spawns a child that inherits descriptors, as a governed one does, on its descriptor-keeping path, which reports a signal death as 128 plus the signal. The matrix now expects 143, anddocs/agent-integration.mdsays so; it said 1, which holds only for an ungoverned PTY.restartedphase's termination targets 5 ms afterstalled, while DevGuard still kept new work closed: a host sample that goes stale while the authority is held closes admission until its samples have been clear for 30 seconds. A target refusedRESOURCE_UNAVAILABLEis now tried again every second for up to 90 seconds, and each phase records the refusals and how long admission took.A product defect found on the Mac. In
udsmode, gateway shutdown kills the worker outright, so the worker cannot end its executions, and on macOS nothing gives them a parent-death signal: a pipe execution outlived the gateway until it ended by itself. Thefaultssuite'sudsshutdown case caught it. The fix changes Rust code, so it comes in its own PR after this one, and the candidate is frozen after that.Commits:
9571cd1scripts: CS-RG qualification harness (CSRG-U6)ca3670bdocs: CS-RG qualification protocol and the legacy off path decision (CSRG-U6)7a0a748policy: say that required executions are launched through the authority8ed8b08scripts: fix the three harness findings of the macOS check (CSRG-U6)Contract changes
None. No tool schema, error code, status value or runtime behavior changes. The harness only uses the existing MCP tools. The integration guide now gives the exit code a governed
tty: trueprocess already reports for a signal death.Tests
scripts/tests/test_qualify_devguard.pyhas 37 tests, which CI runs in thepythonstage of the policy scan. They cover:verify, including a falsified run;host.tomlparser, which never returns a digest;Verified in the cloud (Linux).
8ed8b08, the 37 tests pass on Python 3.13 and 3.9,python3 scripts/validate-upstream.py policy pythonpassed (102 tests), andscripts/check_docs.pypasses (19 paired documents).7a0a748, the docs site'spreparepassed and clippy was clean forcodespace-policy.7a0a748, a smoke run against a real gateway built with--features devguard, in-process anduds: the client and wrapper parse every payload the suites read. That covers exec, status, read, write, resize, terminate, refusals with their attempt IDs, and the gateway log's launch lines.CI on
8ed8b08: CI run 38384742098 passed all 17 jobs. Documentation site run 38384743435 passed. On7a0a748, CI run 38282198652 and documentation site run 38282200167 passed.Run on the qualification Mac (macOS 27.0, Apple M1), in a minimal environment with Rust 1.95.0: release builds of
codespace-mcpandcodespace-codex-runtimewith--features devguard, the installed release0.1.0-6e7e065-94d85365, and DevGuard's fixture authority and launch helper at6e7e065. Before each suite nothing was charged, nocodespaceinstance was active and memory pressure was normal. Afterwards nothing stayed charged, everycodespaceinstance was retired, and the service kept its process.8ed8b08changes no Rust source, so its runs reused the same binaries.candidate7a0a748matrix7a0a748udswas not reached.matrix8ed8b08faults7a0a748udsshutdown case failed on the product defect above: the pipe execution's process group had not ended 15 seconds after the gateway exited.authority7a0a748restartedwas inconclusive in both modes on the third harness finding; the other four phases passed.authority8ed8b08restartedtargets were admitted after 34.6 s (in-process) and 33.7 s (uds), those of every other phase within 0.11 s.control --rehearsal7a0a748verifyfaultsruns again on the fix's PR. The evidence is sealed on the Mac; MANIFEST.json SHA-256 by suite:7a0a748:candidate6b1cc6a10df9f3ca2b80472b5c0d9090a7e1a3a3517a99c1124d10b08a4d9400,matrixbf20056a7351b155f2e73388dbb22cd34d3a54721db0ed0b420842b3a2681f4a,faultse1568fcb5ccb298e2eb581e6687c0947ccf40c8dee1960bcedddb57473792c1a,authority42f8ef5f6b20665120e059add4fd1d7fa3f4ad6f98c8a5b8588fe35f5def1290,control2a8507da10ac571259e4a7f3437102dd24a63cf7d129d9a30492c80f309406818ed8b08:matrix64198825c697e333aaab14469224f297b59852067192afd4614c8e0c77302aa2,authorityffe9332ace437ff926ea2b787daf94ed58a8a691f00e23374fbefaa7797372e4Security scenarios
host.tomlparser returns the consumer's settings without its digest, which is tested. Evidence holds no credential, digest or child environment.CODESPACE_*settings it names.verifywrites nothing.Out of scope
udsshutdown defect, which follows in its own PR.