From 13fe68665f63985ff06a9641ad18b5dc38dd8cc8 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 14 Oct 2026 06:06:58 +0000 Subject: [PATCH 1/2] docs: draft the CS-RG qualification report (CSRG-U6) Adds the qualification report in English and Korean: the claims by level, the qualified combination, every run on the frozen candidate ca306ee with its result and sealed evidence, the accounting items, the regression stages and Linux CI, the amendments, and what stays outside CS-RG. The integration guide gains the qualification and adoption section, with the supported modes, the adoption steps and the rollback, and the protocol's status names the result. The protocol's regression command is corrected to the two invocations that run every stage. The control-path section and its accounting cells still wait for the measurement's per-interval values; the run itself qualified. Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/cs-rg-qualification-report.md | 224 ++++++++++++++++++++++++++ docs/cs-rg-qualification.md | 4 +- docs/devguard-integration.md | 29 +++- docs/ko/cs-rg-qualification-report.md | 224 ++++++++++++++++++++++++++ docs/ko/cs-rg-qualification.md | 4 +- docs/ko/devguard-integration.md | 29 +++- docs/translations.json | 61 ++++++- 7 files changed, 561 insertions(+), 14 deletions(-) create mode 100644 docs/cs-rg-qualification-report.md create mode 100644 docs/ko/cs-rg-qualification-report.md diff --git a/docs/cs-rg-qualification-report.md b/docs/cs-rg-qualification-report.md new file mode 100644 index 0000000..d7086ef --- /dev/null +++ b/docs/cs-rg-qualification-report.md @@ -0,0 +1,224 @@ + + +# CS-RG qualification report + +[English](cs-rg-qualification-report.md) | [한국어](ko/cs-rg-qualification-report.md) + +This page reports the qualification of CodeSpace's use of DevGuard (CS-RG) by unit CSRG-U6, under the [CS-RG qualification protocol](cs-rg-qualification.md). The protocol says what a run must show; this page records what the runs on the frozen candidate showed and where their evidence is. Counts, durations and percentiles are what these runs observed on one host. They are not failure probabilities. + +**Result:** CS-RG is qualified on macOS for the [combination](#report-combination) below: participation `required` in the runner modes `in-process` and `uds` with `--runtime-bin`, each with pipe and PTY executions, and `off` and `required` workspaces in one gateway. Every other mode is unsupported or keeps its existing behavior, as [claimed](#report-claims) below. Linux `required` stays unsupported until DG-LINUX. How an operator adopts the qualified combination, and how to roll it back, is in [qualification and adoption](devguard-integration.md#devguard-qualification). + + + +## What is claimed + +The work order separates four levels of result. Here **implemented** means merged in CodeSpace's main branch; **feature-verified**, shown by tests with fakes, scripted workers or DevGuard's fixture authority, in the regression stages or CI; **platform-verified**, shown on macOS against DevGuard's own components by a suite of the protocol; **qualified**, the exact combination passed every suite that the protocol requires for the claim, and its sealed evidence was verified and reviewed. + +| Mode or behavior | Level | Shown by | +| --- | --- | --- | +| macOS, `in-process`, pipe and PTY, `required` | qualified | [matrix](#report-matrix), [faults](#report-faults), [authority failure](#report-authority), [control path](#report-control), [regressions](#report-regressions) | +| macOS, `uds` with `--runtime-bin`, pipe and PTY, `required` | qualified | the same | +| macOS, `off` and `required` workspaces in one gateway, pipe and PTY | qualified | matrix `mixed` in both runner modes | +| macOS, `uds` with `--runner-socket`, `required` | unsupported; the refusal is platform-verified | matrix `runner-socket` | +| macOS, `required` under `--devguard status` | unsupported; the refusal is platform-verified | matrix `status-mode` | +| macOS, `required` without a usable launch helper | unsupported; the refusal is platform-verified | matrix `no-helper` and `unusable-helper` | +| macOS and Linux, `off` | existing behavior, feature-verified | the regression stages on the candidate, and CI | +| Linux, `required` | unsupported until DG-LINUX; the refusal is feature-verified | Linux CI on the candidate | +| A lost answer to a request past registration; a worker lost during the launch itself | feature-verified | DevGuard's client tests; CodeSpace's runner and gateway tests with a scripted worker | +| A replayed preparation or launch message on the runner wire | not tested, a known gap | | +| A journal or storage refusal | not injected; feature-verified | DevGuard's own suites; CodeSpace's tests of how its codes map | +| Control under DG-1's warm load | not measured | the qualification uses the cold load | +| Foreground browser responsiveness | DG-1's, not measured here | DevGuard's DG-1 qualification of the release | + + + +## The qualified combination + +The `candidate` suite recorded it on 2026-10-13 at 16:23 UTC, and it was checked independently against the commit, with the code-tree hash recomputed. + +| Part | Value | +| --- | --- | +| CodeSpace | commit `ca306eeaec42818c5fdb2a6ca3b6765507e8af8c`, the merge of [#98](https://github.com/novelKR/CodeSpace/pull/98), with no uncommitted change; code-tree SHA-256 `32235f28b930ec1487f6ca508ff6b0c7f77772275462080972c3cfe1d2b4245f`. The commit that adds this report changes documentation only and keeps that code tree | +| DevGuard client | `devguard-client` 0.1.0 and `devguard-contract` 0.1.0 from `novelKR/DevGuard` at `6e7e065a0dd5b3876dc7f4546ab76069489937d1` ([client pin](upstream-lock.md#devguard-client-pin)) | +| Codex | gitlink `6b9826e3aa83b1a5947db50f4332cb9c65f1b340` (`rust-v0.154.0`) with the [recorded patch](upstream-lock.md#codex-downstream-patch), patched tree `1999937194e3a68d982be85679557f0e50fe5408`; `codex_patch.py check` passed | +| Wire and protocol | CodeSpace's runner wire 7; DevGuard protocol 1; MCP `2025-11-25`, as the harness speaks it | +| Binaries | `codespace-mcp` 0.6.0 (`-p codespace-server --features devguard`, release) `1e091e02b648c24bb933d90b1347ecc22119ba0745d401c1f6482364c6500480`, 38,849,664 bytes; `codespace-codex-runtime` (`--features devguard`, release) `a1aebb98919a4a8c67783b0590f1016d6472095a0f72bda01645e3ca03efddaa`, 26,867,360 bytes. For the fixture suites, `fixture_authority` `ea234acf2a3ddf645d4e5a3ad8ab163cfa81df003d323070ac754c035b3ff124` and `devguard-launch` `85c2165e95e19ca52e8a6c213b3efa4f48184de335a828b5409b737dce0e5bf0`, both built from the client pin; for the load, `devguard-qualify` `694c838621b14762dc2ad4af5139a48041764fe44fd62bed005a501d6eb68cc1` | +| DevGuard release | `0.1.0-6e7e065-94d85365`, built from `6e7e065`; `MANIFEST.json` SHA-256 `4535b52cc6466e892ebee2a2ad52f396e6b7520d7560e7e25c20ffa3647ed0df`; the installed `devguardd`, `devguard` and `devguard-launch` match it, and the service is healthy and runs it | +| Policy | configuration fingerprint `8cbb019bbb58e92e2a0d65f797cd5eb5f1696ce9e254bfdb1af97395382efc6f`; `devguard doctor --require admission,registration,macos-cooperative` satisfied; capabilities `durable_admission`, `fenced_launch`, `per_resource_evidence`, `static_control_reservations` and `macos_cooperative`. The `codespace` consumer has the role `control_service`, generation `codespace-g1`, one instance and a control reservation of 150 mCPU, 536,870,912 bytes and 40 tasks. The SHA-256 of `host.toml` is in the sealed record | +| DG-1 qualification | DevGuard's record of the release, SHA-256 `fd4fed318e0fbc640d9e6174a8dd731db80f9607d2235bdfa773c4101f6b17a4`: cold and warm loads qualified on 2026-10-13 under the same `host.toml`, fingerprint and capabilities, and promoted ([DevGuard #34](https://github.com/novelKR/DevGuard/pull/34)) | +| Toolchain | `rustc 1.95.0 (59807616e 2026-04-14)`, `cargo 1.95.0 (f2d3ce0bd 2026-03-21)`, Python 3.9.6, Xcode 27.0 (27A266a) | +| Host | a Mac mini (Macmini9,1, Apple M1) with 8 logical CPUs and 16 GiB, on AC power, macOS 27.0 (26A428); work capacity after the consumer's reservation 5,350 mCPU, 12,079,595,520 bytes and 104 tasks | + + + +## Runs + +Every run used the candidate's binaries in the minimal environment, with Rust 1.95.0 first in `PATH`, and started after checking that nothing was charged, no `codespace` instance was active and memory pressure was normal. Each run was sealed, and `verify` recomputed its verdicts from the raw files and found them unchanged. + +| Run | When (UTC) | Result | +| --- | --- | --- | +| `candidate` | 2026-10-13 16:23 | passed | +| `matrix` | 2026-10-13 16:40–16:42 | passed: 45 of 45 scenarios | +| `faults` | 2026-10-13 16:42–16:45 | passed: 27 of 27 cases | +| `authority` | 2026-10-13 16:45–16:49 | passed: 10 of 10 phases | +| `control --rehearsal` | 2026-10-13 16:50–16:53 | inconclusive only because a rehearsal is shorter than the protocol, as designed | +| regression stages, `all` | 2026-10-13 17:00–17:53 | every stage passed except `linux-isolation`, which needs Linux | +| regression stages, `macos-core` and `macos-fork-race` | 2026-10-13 17:57–18:01 | passed | +| `control --rehearsal` | ⟨CTRL-REH-WHEN⟩ | ⟨CTRL-REH-RESULT⟩ | +| `control` | ⟨CTRL-WHEN⟩ | ⟨CTRL-RESULT⟩ | +| Linux CI | 2026-10-13 23:25–23:42 | passed: every job of the full profile ([run 38484155990](https://github.com/novelKR/CodeSpace/actions/runs/38484155990)) | + + + +## Functional matrix + +`matrix` ran against the installed service in both runner modes: 22 scenarios in `in-process` and 23 in `uds`, all passed. + +| Scenario | `in-process` | `uds` | +| --- | --- | --- | +| registration | passed | passed | +| exits, io, termination, timeout, exec-failed, shortage, unsupported-minimum, mixed | passed on a pipe and on a PTY | passed on a pipe and on a PTY | +| no-helper, unusable-helper, status-mode, authority-unavailable | passed | passed | +| runner-socket | | passed | +| settled | passed | passed | + +Every governed launch matched DevGuard's journal: the reserved and applied quantities equal the workspace's request, CPU, memory and tasks were each `applied`, the scope root was the launched process, and the attempt was released `scope_terminated` holding nothing, with its tracking complete. Every refused call's attempt was in the expected phase holding nothing, or did not exist where the refusal comes first. + + + +## Fault cases + +`faults` ran against DevGuard's fixture authority, a fresh one for each case, in both runner modes: 13 cases in `in-process` and 14 in `uds`, all passed. + +| Case | `in-process` | `uds` | +| --- | --- | --- | +| descendant, escape, stalled-observer | passed on a pipe and on a PTY | passed on a pipe and on a PTY | +| authority-lost, authority-restart, authority-stalled, helper-ends, credential, terminate-race, shutdown | passed | passed | +| worker-killed | | passed | + +The protocol's [fault cases](cs-rg-qualification.md#fault-cases) say what each one shows. Together they show no replay and no premature release: a descendant keeps its attempt charged until it ends, an escaped or unobserved descendant leaves it charged as Suspect, an uncertain or restarted attempt is never launched again, and a call that provably started nothing leaves nothing charged. + + + +## Authority failure + +`authority` ran its five phases in both runner modes against the fixture authority, and all ten passed. Process status, the I/O echo and the termination of governed targets that were already running worked in every phase. New governed executions were admitted while the authority could answer and refused while it could not. + +| Phase | New governed executions | Termination targets admitted after (`in-process` / `uds`) | +| --- | --- | --- | +| baseline | admitted | 0.09 s / 0.09 s | +| paused | admitted | 0.09 s / 0.09 s | +| stalled | refused | 0.09 s / 0.10 s, before the hold | +| restarted | admitted | 36.61 s after 36 refusals / 34.61 s after 34 | +| stopped | refused | 0.12 s / 0.16 s, before the kill | + +The host sample that went stale while `stalled` held the lock kept new work closed until DevGuard's samples had been clear for 30 seconds, so the targets of `restarted` were refused `RESOURCE_UNAVAILABLE` and tried again every second, within the protocol's 90 seconds. + + + +## Control-path availability + +⟨CTRL-SECTION⟩ + + + +## Resource accounting + +The work order's accounting items, each checked against DevGuard's record rather than CodeSpace's view: + +| Item | Where it is shown | Result | +| --- | --- | --- | +| Requested, reserved, supported and applied values | [matrix](#report-matrix): DevGuard's journal record of every governed launch | matched in both runner modes, pipe and PTY | +| Headroom and control reservations | the consumer's reservation is subtracted from the work capacity: 5,500 to 5,350 mCPU, 12,616,466,432 to 12,079,595,520 bytes and 144 to 104 tasks when it was provisioned; matrix `shortage` refuses a request that cannot fit; the [control path](#report-control) compares the execution owner's footprint with the reservation | ⟨ACCT-FOOTPRINT⟩ | +| Pressure | [authority failure](#report-authority): after a stale host sample, new work stays closed until samples have been clear for 30 seconds, while running targets stay controllable; the [control path](#report-control): host pressure under DG-1's load; the service's own pressure behavior is DG-1's | ⟨ACCT-PRESSURE⟩ | +| No release on root exit alone while a descendant remains | faults `descendant`, pipe and PTY | passed | +| Conservative accounting for an unknown state | faults `escape`, `stalled-observer` and `authority-restart`: the attempt stays charged as Suspect | passed | +| No replay after an uncertain launch | faults `authority-stalled`, `authority-restart` (one launch) and `worker-killed`; the control path's duplicate-launch count | passed; ⟨ACCT-DUPLICATES⟩ | +| Cleanup after a definite no-start | matrix `no-helper` and `unusable-helper` (cancelled), `shortage` (denied), `exec-failed` (released when the scope ended); faults `helper-ends` (released as `no_helper_created`), `authority-stalled` and `worker-killed` (nothing held) | passed | + + + +## Regression and parity + +The regression stages ran on the candidate on the qualification host, in the minimal environment, with the DevGuard test binaries required: + +| Stage | Seconds | Result | +| --- | ---: | --- | +| `pin` | 0.67 | passed | +| `policy` | 0.13 | passed | +| `python` | 8.91 | passed | +| `format` | 0.93 | passed | +| `clippy-root` | 192.45 | passed | +| `clippy-adapters` | 235.36 | passed | +| `clippy-codex` | 149.78 | passed | +| `integration` | 2,196.63 | passed | +| `dependencies` | 5.19 | passed | +| `unit-patch` | 21.76 | passed | +| `unit-codex-runtime` | 31.37 | passed | +| `unit-pty` | 7.94 | passed | +| `unit-file-system` | 307.08 | passed | +| `unit-linux-sandbox` | 14.34 | passed | +| `unit-devguard` | 11.32 | passed | +| `unit-linux-sandbox-protocol` | 4.72 | passed | +| `linux-isolation` | | not run on macOS; Linux CI | +| `macos-core` | 75.28 | passed | +| `macos-fork-race` | 129.40 | passed: 400 trials, none failed, 72,946 children each with an exit code, no new crash report | + +`all` passed 782 tests, failed none and ignored 9; the macOS-only stages passed 189, failed none and ignored 9. The adapter's known intermittent failure ("another authority owns this state directory") did not occur. These stages hold the existing tests of every area the work order names: workspace authorization, approvals, pipe and PTY execution, stdin and output, resize, timeout, termination, shutdown, patch helpers, sandbox helpers, the UDS worker and feature-off behavior, which the `dependencies` stage and the builds without the `devguard` feature cover. `macos-core` also runs the gateway's tests against DevGuard's fixture authority and launch helper, which run only on macOS. + +Linux CI ran the full profile on the candidate in the scheduled [run 38484155990](https://github.com/novelKR/CodeSpace/actions/runs/38484155990), from 23:25 to 23:42 UTC on 2026-10-13, and every job passed: the format and pin check, the policy scan, the three Clippy builds and the seven unit stages, `integration` and `linux-isolation` on Ubuntu, and `macos-core`, `macos-fork-race` and `dependencies` on a hosted macOS runner. On Linux, DevGuard has no native host evidence, so the owner cannot register: the adapter's unit tests check that its registration is `incompatible`, and the gateway's tests in `integration` check that a governed execution is refused `RESOURCE_AUTHORITY_UNAVAILABLE` and that nothing is started. That is the feature-verified refusal of Linux `required` [claimed](#report-claims) above. + + + +## Amendments and corrections + +- **The regression command (amendment).** The protocol named one command, `validate-upstream.py all macos-core macos-fork-race`. `all` replaces every other stage name and leaves out the macOS-only stages ([`scripts/validate-upstream.py`](../scripts/validate-upstream.py)), so that command runs neither `macos-core` nor `macos-fork-race`. Both ran in a second invocation on the same candidate, and the protocol now names the two invocations. This changes documentation only; no run was repeated or changed. +- **Corrections before the freeze.** The check of the harness ([#97](https://github.com/novelKR/CodeSpace/pull/97)) on the qualification host at `7a0a748` found three harness defects, fixed before it merged (`8ed8b08`): the expected status of a governed PTY child killed by SIGTERM, which is exit code 143 because the pinned Codex PTY reports a child that inherits its launch descriptors that way; the settled check, which read the active instances once instead of awaiting them; and the `authority` suite, which started the targets of `restarted` before DevGuard admitted work again after `stalled`. It also found a product defect: at gateway shutdown in `uds` mode the worker was killed outright, so a governed pipe execution outlived it, and its scope ended only when its command did, about 30 seconds later. [#98](https://github.com/novelKR/CodeSpace/pull/98) fixed it: the gateway now closes the worker's connection and waits for the worker, which ends its processes as it exits, and kills it only if it still runs 5 seconds later. The same case then ended both scopes at once. The candidate was frozen after #98, every qualification run is on it, and the failed and incomplete checks are kept with the checks that passed afterwards. + + + +## Evidence + +The evidence directories are on the qualification host, under the DevGuard checkout's `evidence/` directory. Each is sealed with a `MANIFEST.json` of every file's SHA-256, and its files are read-only. None holds a credential, a credential digest or a child's environment, and each was scanned for them. A harness run's directory checks out when its `MANIFEST.json` has the SHA-256 below and `qualify-devguard.py verify` accepts it. The regression directories hold `validate-upstream.py`'s report and logs, copied unchanged. The control runs' console and `verify` output are kept beside their directories. + +| Directory | Run | `MANIFEST.json` SHA-256 | +| --- | --- | --- | +| `csrg-u6-candidate-2026-10-13-ca306ee` | candidate | `3e3587d1694e4108912c742b6825684ff95b00e658c6f78fbe63143e37aadc95` | +| `csrg-u6-qual-matrix-2026-10-13-ca306ee` | matrix | `faf673aa028f4d4c4646eb271e617395f2b753740eecb3501241936e2b2ad688` | +| `csrg-u6-qual-faults-2026-10-13-ca306ee` | faults | `b000a94a70c68ea74658e37e2da275fe48a1c7f8b74cd6c7e4bdbb2525ae5025` | +| `csrg-u6-qual-authority-2026-10-13-ca306ee` | authority | `c4a7fb26703939eb56627848affba8d4790e72c6337663533356ca5662b78256` | +| `csrg-u6-qual-control-rehearsal-2026-10-13-ca306ee` | control rehearsal | `2c9c7fc08f4204e8f9c1a921459b50adc0c2ee439219ec8232124d785f0c66b1` | +| `csrg-u6-qual-regressions-2026-10-13-ca306ee` | regression stages, `all` | `2825fb3ca091a5d0280376a3f4134e3d0050e0718cbc95409633fe259840e52e` | +| `csrg-u6-qual-regressions-macos-2026-10-13-ca306ee` | `macos-core` and `macos-fork-race` | `5d160894fbf4b63fd822da63bf137bd8ab6a1d7a1aba005c256f5ba3ff59c2bd` | +| `csrg-u6-control-rehearsal-2026-10-14-ca306ee` | control rehearsal | `ac79024e237ee496b64f524696228e171a7161ccfde7652e02b023c67c25039f` | +| `csrg-u6-control-2026-10-14-ca306ee` | control | `7706aac71c2f793dbc273b5c78f888dcc2af50269c0039d132b21c236b47e9be` | + +The checks before the freeze are kept too: + +| Directory | Commit | Result | `MANIFEST.json` SHA-256 | +| --- | --- | --- | --- | +| `csrg-u6-harness-check-candidate-2026-10-13` | `7a0a748` | passed | `6b1cc6a10df9f3ca2b80472b5c0d9090a7e1a3a3517a99c1124d10b08a4d9400` | +| `csrg-u6-harness-check-matrix-2026-10-13` | `7a0a748` | failed: the two harness defects | `bf20056a7351b155f2e73388dbb22cd34d3a54721db0ed0b420842b3a2681f4a` | +| `csrg-u6-harness-check-faults-2026-10-13` | `7a0a748` | failed: 26 of 27, `uds` shutdown | `e1568fcb5ccb298e2eb581e6687c0947ccf40c8dee1960bcedddb57473792c1a` | +| `csrg-u6-harness-check-authority-2026-10-13` | `7a0a748` | incomplete: `restarted` | `42f8ef5f6b20665120e059add4fd1d7fa3f4ad6f98c8a5b8588fe35f5def1290` | +| `csrg-u6-harness-check-control-2026-10-13` | `7a0a748` | rehearsal, inconclusive as designed | `2a8507da10ac571259e4a7f3437102dd24a63cf7d129d9a30492c80f30940681` | +| `csrg-u6-harness-check-matrix-2026-10-13-8ed8b08` | `8ed8b08` | passed | `64198825c697e333aaab14469224f297b59852067192afd4614c8e0c77302aa2` | +| `csrg-u6-harness-check-authority-2026-10-13-8ed8b08` | `8ed8b08` | passed | `ffe9332ace437ff926ea2b787daf94ed58a8a691f00e23374fbefaa7797372e4` | +| `csrg-u6-harness-check-faults-2026-10-13-b74e5c2` | `b74e5c2` | passed | `6057f26fb81a59f4f8ef6f8c12ff95235ae25c10b7503c7a6f2aaa5264ddae8b` | +| `csrg-u6-harness-check-matrix-2026-10-13-b74e5c2` | `b74e5c2` | passed | `577962c15c89e70b4debfe93c2f7513876fa592c6d15ff86bf7535a585121a76` | +| `csrg-u6-harness-check-authority-2026-10-13-b74e5c2` | `b74e5c2` | passed | `dad385b738361ef883928329f3ed6879f9a874ebdc32f3bdd5aed464ba6dc679` | + +DG-1's measurement of the release, which the policy row relies on, is sealed beside them and recorded in DevGuard. + + + +## Outside CS-RG + +CS-RG ends here. These stay outside it, and nothing here claims them: + +- **P1-RECOVERY**, the next milestone on the critical path: gateway restart and reconnection while an independent runner keeps its processes. It starts only with the owner's separate authorization. +- **DG-LINUX**, enforcement on Linux. Until it qualifies, `required` is refused on Linux, and `off` is the only Linux path. +- **DG-CACHE** and **DG-ADAPTERS**, DevGuard's cache and further adapters. +- **Codex convergence.** Governed PTY executions are observed before the reap through CodeSpace's [recorded Codex patch](upstream-lock.md#codex-downstream-patch) until upstream offers the hook ([openai/codex#53298](https://github.com/openai/codex/issues/53298)). The next Codex pin move is its own change and a new candidate. +- **Another combination.** A different DevGuard client pin, release, policy or host, a code change, or another toolchain is a new candidate that needs its own runs. +- **What the runs did not show:** DG-1's warm load for the control path, foreground browser responsiveness, a replayed message on the runner wire, an injected journal refusal, and protection for arbitrary request or file sizes. diff --git a/docs/cs-rg-qualification.md b/docs/cs-rg-qualification.md index 6638092..6468a2d 100644 --- a/docs/cs-rg-qualification.md +++ b/docs/cs-rg-qualification.md @@ -6,7 +6,7 @@ This page is the protocol for qualifying CodeSpace's use of DevGuard (CS-RG): which combination is qualified, which modes are claimed, how each claim is tested and measured, what makes a run pass, and what evidence a run leaves. It is frozen together with its harness, [`scripts/qualify-devguard.py`](../scripts/qualify-devguard.py), before any qualification run. A change to it, or to the harness, after the first qualification run is a new protocol: it is reviewed like any other change, and the runs it affects are repeated. The [integration roadmap](devguard-integration.md) describes what each unit built; this page decides whether the result qualifies. -**Status:** the protocol and the harness exist; no qualification run has been made, and nothing here is a qualification result. CS-RG stays in progress and not qualified until a run under this protocol passes and its evidence is reviewed. +**Status:** frozen with its harness ([#97](https://github.com/novelKR/CodeSpace/pull/97)) before the first qualification run. The runs on the candidate `ca306ee` passed, and CS-RG is qualified for that combination; the [qualification report](cs-rg-qualification-report.md) has the results and the evidence. The [regression command](#regressions) was corrected after the runs, as the report's [amendments](cs-rg-qualification-report.md#report-amendments) record; nothing else changed. @@ -200,7 +200,7 @@ The harness checks DevGuard's record, never CodeSpace's own view. For each gover ## Regression and parity -On the candidate, on the qualification host in the minimal environment, `python3 scripts/validate-upstream.py all macos-core macos-fork-race` runs every stage, with the DevGuard test binaries required in the stages that use them; Linux is shown by CI on the candidate head, whose `dependencies` stage checks the dependency graph with the `devguard` feature on and off. A regression in any stage fails the qualification. +On the candidate, on the qualification host in the minimal environment, two invocations run every stage, with the DevGuard test binaries required in the stages that use them: `python3 scripts/validate-upstream.py all`, then `python3 scripts/validate-upstream.py macos-core macos-fork-race`. `all` runs every stage but the macOS-only ones and replaces any other stage named with it, so those need their own invocation. Linux is shown by CI on the candidate head, whose `dependencies` stage checks the dependency graph with the `devguard` feature on and off. A regression in any stage fails the qualification. diff --git a/docs/devguard-integration.md b/docs/devguard-integration.md index 7b54b68..79cabca 100644 --- a/docs/devguard-integration.md +++ b/docs/devguard-integration.md @@ -2,13 +2,13 @@ # DevGuard integration roadmap -> **Status: suspended as an implementation directive.** The CS-RG work order, the planned consumer boundary and the design revision 1 references on this page must not be implemented as described; current status and prerequisites are unaffected. This is pending the CS-RG integration-boundary revalidation, an owner-directed review of the CodeSpace integration plan; it is not a work unit. No replacement architecture has been approved; the owner decides after reviewing its results. This notice suspends directives only and relaxes no safety requirement. The text below is retained unchanged for historical traceability, except the current status, the [status-only connection](#devguard-status-connection) of CSRG-U1, which the owner approved on 2026-10-02 outside this suspension, the [execution-owner registration](#devguard-owner-registration) of CSRG-U2, which the owner directed on 2026-10-03, the [admission and pre-spawn preparation](#devguard-admission) of CSRG-U3, which the owner directed on 2026-10-07, the [managed launch](#devguard-launch) of CSRG-U4, which the owner directed on 2026-10-08, and the [lifecycle after launch](#devguard-lifecycle) of CSRG-U5, which the owner directed on 2026-10-09. +> **Status: suspended as an implementation directive.** The CS-RG work order, the planned consumer boundary and the design revision 1 references on this page must not be implemented as described; current status and prerequisites are unaffected. This is pending the CS-RG integration-boundary revalidation, an owner-directed review of the CodeSpace integration plan; it is not a work unit. No replacement architecture has been approved; the owner decides after reviewing its results. This notice suspends directives only and relaxes no safety requirement. The text below is retained unchanged for historical traceability, except the current status, the [status-only connection](#devguard-status-connection) of CSRG-U1, which the owner approved on 2026-10-02 outside this suspension, the [execution-owner registration](#devguard-owner-registration) of CSRG-U2, which the owner directed on 2026-10-03, the [admission and pre-spawn preparation](#devguard-admission) of CSRG-U3, which the owner directed on 2026-10-07, the [managed launch](#devguard-launch) of CSRG-U4, which the owner directed on 2026-10-08, the [lifecycle after launch](#devguard-lifecycle) of CSRG-U5, which the owner directed on 2026-10-09, and the [qualification and adoption](#devguard-qualification) of CSRG-U6, which the owner directed on 2026-10-12. [English](devguard-integration.md) | [한국어](ko/devguard-integration.md) [DevGuard](https://github.com/novelKR/DevGuard) is an independent resource authority for development workloads, licensed under Apache-2.0 like CodeSpace. Its approved integration path adds a shared admission and accounting layer while CodeSpace keeps process ownership, PTY, input/output, permissions, approval holds and workspace coordination. -**Current status:** DevGuard has completed DG-1 in its independent repository ([`395315d`](https://github.com/novelKR/DevGuard/tree/395315d34b5d458ea1774446727f0cb14bd8a120), [milestone ledger](https://github.com/novelKR/DevGuard/blob/395315d34b5d458ea1774446727f0cb14bd8a120/milestones.json)). On top of the DG-0 contracts it provides native macOS host evidence, an authenticated daemon installed as the current user's LaunchAgent, the fenced launch helper and reconciliation, the `devguard` command-line owner with Cargo adapters, parent leases for candidate tests, and upgrade and repair. Its macOS SLO is qualified for release `0.1.0-5daee5d-b3fa569e` (a release ID, not a Git tag) on the measured host and policy; Linux enforcement is not qualified. CodeSpace consumption (CS-RG) is in progress and not qualified. CSRG-U1 added an opt-in, status-only connection: a gateway built with the `devguard` feature and started with `--devguard status` reports DevGuard's status in `workspace_info`, through DevGuard's client pinned at [`6e7e065`](upstream-lock.md#devguard-client-pin). With CSRG-U2, the process that owns CodeSpace's executions registers itself with DevGuard (`--devguard register`), and a workspace's `resources` setting can require resource participation. With CSRG-U3, that owner takes a process slot and has DevGuard admit each such execution before anything is created. With CSRG-U4 and a configured launch helper (`--devguard-launch-helper`), it then launches the execution once through DevGuard's launch helper, which DevGuard authorizes after binding and policing its scope; without a helper it cancels the unstarted attempt and refuses the execution. Nothing runs without DevGuard. With CSRG-U5, each process has one reaper; DevGuard observes a governed execution's scope before its root is reaped, on a pipe through CodeSpace's own reaper and on a PTY through the pinned Codex PTY's waiter with the [recorded patch](upstream-lock.md#codex-downstream-patch); killing a governed process also terminates its scope; and an approval whose governed execution provably never started can be resumed again. Qualification is CSRG-U6: its protocol and harness are in [CS-RG qualification](cs-rg-qualification.md), and nothing is qualified yet. The qualified release remains a candidate for execution, not a selected pin; the client pin is a source pin of the client crates. +**Current status:** DevGuard has completed DG-1 in its independent repository ([`395315d`](https://github.com/novelKR/DevGuard/tree/395315d34b5d458ea1774446727f0cb14bd8a120), [milestone ledger](https://github.com/novelKR/DevGuard/blob/395315d34b5d458ea1774446727f0cb14bd8a120/milestones.json)). On top of the DG-0 contracts it provides native macOS host evidence, an authenticated daemon installed as the current user's LaunchAgent, the fenced launch helper and reconciliation, the `devguard` command-line owner with Cargo adapters, parent leases for candidate tests, and upgrade and repair. Its macOS SLO is qualified for release `0.1.0-6e7e065-94d85365` (a release ID, not a Git tag), built from the client pin's commit and measured on 2026-10-13 on the measured host under the policy that includes CodeSpace's `codespace` consumer ([DevGuard #34](https://github.com/novelKR/DevGuard/pull/34)); Linux enforcement is not qualified. CodeSpace consumption (CS-RG) is qualified on macOS for one exact combination. CSRG-U1 added an opt-in, status-only connection: a gateway built with the `devguard` feature and started with `--devguard status` reports DevGuard's status in `workspace_info`, through DevGuard's client pinned at [`6e7e065`](upstream-lock.md#devguard-client-pin). With CSRG-U2, the process that owns CodeSpace's executions registers itself with DevGuard (`--devguard register`), and a workspace's `resources` setting can require resource participation. With CSRG-U3, that owner takes a process slot and has DevGuard admit each such execution before anything is created. With CSRG-U4 and a configured launch helper (`--devguard-launch-helper`), it then launches the execution once through DevGuard's launch helper, which DevGuard authorizes after binding and policing its scope; without a helper it cancels the unstarted attempt and refuses the execution. Nothing runs without DevGuard. With CSRG-U5, each process has one reaper; DevGuard observes a governed execution's scope before its root is reaped, on a pipe through CodeSpace's own reaper and on a PTY through the pinned Codex PTY's waiter with the [recorded patch](upstream-lock.md#codex-downstream-patch); killing a governed process also terminates its scope; and an approval whose governed execution provably never started can be resumed again. CSRG-U6 qualified one exact combination under the [CS-RG qualification protocol](cs-rg-qualification.md), in the runner modes `in-process` and `uds` with `--runtime-bin`, each with pipe and PTY executions, as the [qualification report](cs-rg-qualification-report.md) records ([qualification and adoption](#devguard-qualification)); Linux `required` stays unsupported until DG-LINUX. The qualified release remains a candidate for execution, not a selected pin; the client pin is a source pin of the client crates. DevGuard [design revision 1](https://github.com/novelKR/DevGuard/blob/d4981b4c241cff42687f5c2c681b583c7847776e/docs/design-revision-1.md), merged in [DevGuard PR #8](https://github.com/novelKR/DevGuard/pull/8) as `d4981b4c241cff42687f5c2c681b583c7847776e`, revised the CS-RG execution layer and work order. It changes plans and design decisions that bind later implementation. It does not change current CodeSpace behavior or any implementation or qualification status. @@ -250,7 +250,30 @@ CSRG-U5 completes a governed execution's lifecycle after its launch: who reaps i **No replay.** Without proof that the first attempt never started, nothing is started again: not after a transcript that does not settle in time, a lost or unknown `BeginLaunch` answer, a worker lost after it took a launch, a cancelled request, a root reaped before any observation, an authority restart or a repeated resume. After an authority restart DevGuard no longer knows a running scope: the process stays CodeSpace's, the owner registers again for new work, and the attempt stays charged as suspect after the process ends. -**Supported** as for CSRG-U4. **Not claimed:** CS-RG qualification (CSRG-U6) and Linux before DG-LINUX. +**Supported** as for CSRG-U4, and qualified for the combination of [CSRG-U6](#devguard-qualification). **Not claimed:** Linux before DG-LINUX. + + + +## Qualification and adoption (CSRG-U6) + +CSRG-U6 qualified CS-RG under the [CS-RG qualification protocol](cs-rg-qualification.md), on the qualification host, for one exact combination: CodeSpace `ca306ee`, or a later commit with the same code tree; DevGuard's client at `6e7e065`; the installed release `0.1.0-6e7e065-94d85365`, with DG-1's qualification under the same policy; Codex `6b9826e` with the recorded patch; and Rust 1.95.0. The [qualification report](cs-rg-qualification-report.md) records the combination, every result and the evidence. + +**Supported.** On macOS with that release: participation `required` in the runner modes `in-process` and `uds` with `--runtime-bin`, each with pipe and PTY executions, and `off` and `required` workspaces in one gateway. Unsupported, and refused before anything runs: `uds` with `--runner-socket`, `required` under `--devguard status` or without the `devguard` feature, and Linux before DG-LINUX. Without a usable launch helper a governed execution is refused `MANAGED_LAUNCH_UNAVAILABLE`. Participation `off` keeps its existing behavior on every platform, as the [legacy `off` path decision](cs-rg-qualification.md#legacy-off-path) records. + +**Adoption.** The claim holds for the qualified combination only: a different release, policy, host, toolchain or code tree is a new candidate that needs its own runs. To use it: + +1. Run the qualified DevGuard release as the current user's service, with a consumer for CodeSpace provisioned as a control service: role `control_service`, a generation, a private credential file, one instance and a static control reservation, qualified at 150 mCPU, 512 MiB and 40 tasks. DevGuard reads its policy only when it starts, and a policy change needs DG-1's measurement again. +2. Build `codespace-mcp` with `-p codespace-server --features devguard`, and for `uds` the worker with `--features devguard`, from a commit with the qualified code tree. +3. Start the gateway with `--devguard register`, the consumer settings of the [status-only connection](#devguard-status-connection) and `--devguard-launch-helper` set to the release's `devguard-launch`, in `in-process` mode or in `uds` mode with `--runtime-bin`. +4. Give each workspace whose executions must be governed `"resources": {"participation": "required"}` and a `request` that fits the work capacity. `workspace_info.resource_authority` reports the owner `registered` and `governs_execution: true` once the owner is registered and has a launch helper. +5. Start or restart DevGuard's service while memory pressure is normal: a service that starts under memory warning admits nothing until memory has been normal for 30 seconds ([DevGuard operations](https://github.com/novelKR/DevGuard/blob/c077c747972cebca828a903968868f5713ce5664/docs/operations.md#available-commands)). + +**Rollback.** None of these steps runs a governed workspace's execution without DevGuard, and none replays or forgets uncertain work. + +- **New admissions.** Restart the gateway without `--devguard register`, or without the launch helper. `required` workspaces then refuse new executions with `RESOURCE_POLICY_UNSUPPORTED` or `MANAGED_LAUNCH_UNAVAILABLE`; they never fall back to `off`. Turning a workspace to `off` is a separate, explicit edit of the registry. +- **Running work.** The gateway's shutdown ends the executions it or its worker owns, governed ones included, and DevGuard releases their attempts once it observes their scopes' end. While DevGuard is stopped, stalled or rolled back, running governed processes stay CodeSpace's: status, output, stdin, resize, termination and timeouts never ask DevGuard, and new governed executions are refused. An attempt that DevGuard can no longer settle stays charged as Suspect, and CodeSpace never launches it again. +- **DevGuard.** Its journal is kept. Its own rollback is `devguard repair --use last-known-good` or an upgrade to an earlier release ([DevGuard operations](https://github.com/novelKR/DevGuard/blob/c077c747972cebca828a903968868f5713ce5664/docs/operations.md#compatibility-checks-and-rollback)), and the `codespace` consumer is removed only after its instances are retired. Each of these leaves the qualified combination. +- **Records.** DevGuard's milestone ledger records what was qualified. A rollback is recorded there, not hidden. ## CS-RG work order diff --git a/docs/ko/cs-rg-qualification-report.md b/docs/ko/cs-rg-qualification-report.md new file mode 100644 index 0000000..4d1df0a --- /dev/null +++ b/docs/ko/cs-rg-qualification-report.md @@ -0,0 +1,224 @@ + + +# CS-RG qualification 보고서 + +[English](../cs-rg-qualification-report.md) | [한국어](cs-rg-qualification-report.md) + +이 문서는 CSRG-U6 단위가 [CS-RG qualification 절차](cs-rg-qualification.md)에 따라 CodeSpace의 DevGuard 사용(CS-RG)을 qualification한 결과를 보고합니다. 실행이 무엇을 보여야 하는지는 절차가 정하고, 이 문서는 고정한 후보에서 한 실행이 실제로 무엇을 보였는지와 그 증거가 어디 있는지를 기록합니다. 횟수, 시간, 백분위수는 한 호스트에서 이 실행들이 관찰한 값이며, 실패 확률이 아닙니다. + +**결과:** CS-RG는 아래 [조합](#report-combination)으로 macOS에서 qualification을 마쳤습니다. 대상은 `in-process`와 `--runtime-bin`을 쓴 `uds` runner 모드의 `required` 참여(각각 pipe와 PTY 실행)와, 한 gateway 안의 `off`와 `required` workspace입니다. 다른 모드는 아래 [주장](#report-claims)대로 지원하지 않거나 기존 동작을 유지합니다. Linux `required`는 DG-LINUX 전까지 지원하지 않습니다. 운영자가 qualification한 조합을 도입하는 방법과 되돌리는 방법은 [qualification과 도입](devguard-integration.md#devguard-qualification)에 있습니다. + + + +## 주장하는 것 + +작업 지시서는 결과를 네 수준으로 나눕니다. 여기서 **구현**은 CodeSpace main 브랜치에 병합되었다는 뜻입니다. **기능 검증**은 fake, 스크립트로 흉내 낸 worker, DevGuard fixture authority를 쓴 시험으로 회귀 단계나 CI에서 보였다는 뜻입니다. **플랫폼 검증**은 절차의 스위트가 macOS에서 DevGuard 자신의 구성 요소를 상대로 보였다는 뜻입니다. **qualification**은 정확한 조합이 그 주장에 절차가 요구하는 모든 스위트를 통과하고, 봉인한 증거를 확인하고 검토했다는 뜻입니다. + +| 모드나 동작 | 수준 | 근거 | +| --- | --- | --- | +| macOS, `in-process`, pipe와 PTY, `required` | qualification | [기능 행렬](#report-matrix), [장애 사례](#report-faults), [authority 장애](#report-authority), [제어 경로](#report-control), [회귀](#report-regressions) | +| macOS, `--runtime-bin`을 쓴 `uds`, pipe와 PTY, `required` | qualification | 위와 같음 | +| macOS, 한 gateway 안의 `off`와 `required` workspace, pipe와 PTY | qualification | 두 runner 모드의 matrix `mixed` | +| macOS, `--runner-socket`을 쓴 `uds`, `required` | 지원하지 않음. 거부는 플랫폼 검증 | matrix `runner-socket` | +| macOS, `--devguard status`에서의 `required` | 지원하지 않음. 거부는 플랫폼 검증 | matrix `status-mode` | +| macOS, 쓸 수 있는 launch helper가 없는 `required` | 지원하지 않음. 거부는 플랫폼 검증 | matrix `no-helper`, `unusable-helper` | +| macOS와 Linux, `off` | 기존 동작, 기능 검증 | 후보의 회귀 단계와 CI | +| Linux, `required` | DG-LINUX 전까지 지원하지 않음. 거부는 기능 검증 | 후보의 Linux CI | +| 등록 뒤 요청에 대한 응답 유실, launch 도중 worker 유실 | 기능 검증 | DevGuard client 시험, 스크립트 worker를 쓴 CodeSpace runner와 gateway 시험 | +| runner wire에서 준비나 launch 메시지 재전송 | 시험하지 않음. 알려진 공백 | | +| journal이나 저장소 거부 | 주입하지 않음. 기능 검증 | DevGuard 자체 스위트, CodeSpace의 코드 대응 시험 | +| DG-1 warm 부하에서의 제어 | 측정하지 않음 | qualification은 cold 부하를 씀 | +| 전경 브라우저 응답성 | DG-1의 것이며 여기서 측정하지 않음 | 그 release에 대한 DevGuard의 DG-1 qualification | + + + +## qualification한 조합 + +`candidate` 스위트가 2026-10-13 16:23 UTC에 기록했고, code tree hash를 다시 계산해 commit과 따로 대조했습니다. + +| 구성 요소 | 값 | +| --- | --- | +| CodeSpace | [#98](https://github.com/novelKR/CodeSpace/pull/98)의 병합 commit `ca306eeaec42818c5fdb2a6ca3b6765507e8af8c`, 커밋하지 않은 변경 없음. code tree SHA-256 `32235f28b930ec1487f6ca508ff6b0c7f77772275462080972c3cfe1d2b4245f`. 이 보고서를 추가하는 commit은 문서만 바꾸므로 같은 code tree를 유지함 | +| DevGuard client | `novelKR/DevGuard`의 `6e7e065a0dd5b3876dc7f4546ab76069489937d1`에서 가져온 `devguard-client` 0.1.0과 `devguard-contract` 0.1.0([client pin](upstream-lock.md#devguard-client-pin)) | +| Codex | gitlink `6b9826e3aa83b1a5947db50f4332cb9c65f1b340`(`rust-v0.154.0`)에 [기록된 패치](upstream-lock.md#codex-downstream-patch)를 적용한 tree `1999937194e3a68d982be85679557f0e50fe5408`. `codex_patch.py check` 통과 | +| wire와 protocol | CodeSpace runner wire 7, DevGuard protocol 1, 하네스가 쓰는 MCP `2025-11-25` | +| 바이너리 | `codespace-mcp` 0.6.0(`-p codespace-server --features devguard`, release) `1e091e02b648c24bb933d90b1347ecc22119ba0745d401c1f6482364c6500480`, 38,849,664바이트. `codespace-codex-runtime`(`--features devguard`, release) `a1aebb98919a4a8c67783b0590f1016d6472095a0f72bda01645e3ca03efddaa`, 26,867,360바이트. fixture 스위트용으로 client pin에서 빌드한 `fixture_authority` `ea234acf2a3ddf645d4e5a3ad8ab163cfa81df003d323070ac754c035b3ff124`와 `devguard-launch` `85c2165e95e19ca52e8a6c213b3efa4f48184de335a828b5409b737dce0e5bf0`, 부하용 `devguard-qualify` `694c838621b14762dc2ad4af5139a48041764fe44fd62bed005a501d6eb68cc1` | +| DevGuard release | `6e7e065`에서 빌드한 `0.1.0-6e7e065-94d85365`. `MANIFEST.json` SHA-256 `4535b52cc6466e892ebee2a2ad52f396e6b7520d7560e7e25c20ffa3647ed0df`. 설치된 `devguardd`, `devguard`, `devguard-launch`가 모두 manifest와 맞고, 서비스는 정상이며 이 release를 실행함 | +| 정책 | 구성 지문 `8cbb019bbb58e92e2a0d65f797cd5eb5f1696ce9e254bfdb1af97395382efc6f`. `devguard doctor --require admission,registration,macos-cooperative` 만족. capability `durable_admission`, `fenced_launch`, `per_resource_evidence`, `static_control_reservations`, `macos_cooperative`. `codespace` 소비자는 role `control_service`, generation `codespace-g1`, 인스턴스 하나, control 예약 150 mCPU, 536,870,912바이트, 40 tasks. `host.toml`의 SHA-256은 봉인한 기록에 있음 | +| DG-1 qualification | 이 release에 대한 DevGuard의 기록, SHA-256 `fd4fed318e0fbc640d9e6174a8dd731db80f9607d2235bdfa773c4101f6b17a4`. 2026-10-13에 같은 `host.toml`, 지문, capability에서 cold와 warm 부하 모두 qualification을 마치고 promote함([DevGuard #34](https://github.com/novelKR/DevGuard/pull/34)) | +| 도구 | `rustc 1.95.0 (59807616e 2026-04-14)`, `cargo 1.95.0 (f2d3ce0bd 2026-03-21)`, Python 3.9.6, Xcode 27.0(27A266a) | +| 호스트 | Mac mini(Macmini9,1, Apple M1), 논리 CPU 8개, 16 GiB, AC 전원, macOS 27.0(26A428). 소비자 예약을 뺀 work capacity 5,350 mCPU, 12,079,595,520바이트, 104 tasks | + + + +## 실행 + +모든 실행은 후보의 바이너리를 `PATH`에서 Rust 1.95.0이 먼저 잡히는 최소 환경에서 썼고, 자원을 차지한 작업과 활성 `codespace` 인스턴스가 없으며 메모리 pressure가 정상인지 확인한 뒤 시작했습니다. 각 실행은 봉인했고, `verify`가 원시 파일에서 판정을 다시 계산해 바뀌지 않았음을 확인했습니다. + +| 실행 | 시각(UTC) | 결과 | +| --- | --- | --- | +| `candidate` | 2026-10-13 16:23 | 통과 | +| `matrix` | 2026-10-13 16:40–16:42 | 통과: 시나리오 45개 중 45개 | +| `faults` | 2026-10-13 16:42–16:45 | 통과: 사례 27개 중 27개 | +| `authority` | 2026-10-13 16:45–16:49 | 통과: 단계 10개 중 10개 | +| `control --rehearsal` | 2026-10-13 16:50–16:53 | 판정 불가. 예행이 절차보다 짧다는 사유뿐이며, 설계대로임 | +| 회귀 단계, `all` | 2026-10-13 17:00–17:53 | Linux가 필요한 `linux-isolation` 말고 모든 단계 통과 | +| 회귀 단계, `macos-core`와 `macos-fork-race` | 2026-10-13 17:57–18:01 | 통과 | +| `control --rehearsal` | ⟨CTRL-REH-WHEN⟩ | ⟨CTRL-REH-RESULT⟩ | +| `control` | ⟨CTRL-WHEN⟩ | ⟨CTRL-RESULT⟩ | +| Linux CI | 2026-10-13 23:25–23:42 | 통과: 전체 프로필의 모든 작업([실행 38484155990](https://github.com/novelKR/CodeSpace/actions/runs/38484155990)) | + + + +## 기능 행렬 + +`matrix`는 설치된 서비스를 상대로 두 runner 모드에서 실행했습니다. `in-process` 시나리오 22개와 `uds` 시나리오 23개가 모두 통과했습니다. + +| 시나리오 | `in-process` | `uds` | +| --- | --- | --- | +| registration | 통과 | 통과 | +| exits, io, termination, timeout, exec-failed, shortage, unsupported-minimum, mixed | pipe와 PTY 모두 통과 | pipe와 PTY 모두 통과 | +| no-helper, unusable-helper, status-mode, authority-unavailable | 통과 | 통과 | +| runner-socket | | 통과 | +| settled | 통과 | 통과 | + +모든 관리 대상 실행이 DevGuard journal과 맞았습니다. 예약하고 적용한 양은 workspace 요청과 같고, CPU·메모리·tasks가 각각 `applied`였고, scope root는 실행한 프로세스였으며, attempt는 아무것도 붙잡지 않은 채 `scope_terminated`로 해제되었고 추적은 끝까지 온전했습니다. 거부된 호출의 attempt는 모두 기대한 단계에서 아무것도 붙잡지 않았고, 거부가 먼저 오는 경우에는 attempt가 없었습니다. + + + +## 장애 사례 + +`faults`는 사례마다 새로 띄운 DevGuard fixture authority를 상대로 두 runner 모드에서 실행했습니다. `in-process` 사례 13개와 `uds` 사례 14개가 모두 통과했습니다. + +| 사례 | `in-process` | `uds` | +| --- | --- | --- | +| descendant, escape, stalled-observer | pipe와 PTY 모두 통과 | pipe와 PTY 모두 통과 | +| authority-lost, authority-restart, authority-stalled, helper-ends, credential, terminate-race, shutdown | 통과 | 통과 | +| worker-killed | | 통과 | + +각 사례가 무엇을 보이는지는 절차의 [장애 사례](cs-rg-qualification.md#fault-cases)에 있습니다. 함께 보면 재실행도, 이른 해제도 없다는 것을 보입니다. 자손이 남으면 끝날 때까지 attempt가 자원을 차지한 채 남고, 빠져나갔거나 관찰하지 못한 자손이 있으면 Suspect로 자원을 차지한 채 남으며, 불확실하거나 재시작 전의 attempt는 다시 실행하지 않고, 아무것도 시작하지 않았음이 증명된 호출은 아무것도 charge하지 않습니다. + + + +## authority 장애 + +`authority`는 fixture authority를 상대로 두 runner 모드에서 다섯 단계를 실행했고, 열 개 모두 통과했습니다. 이미 실행 중인 관리 대상의 프로세스 status, I/O echo, 종료는 모든 단계에서 동작했습니다. 새 관리 대상 실행은 authority가 답할 수 있을 때 허용되고, 답할 수 없을 때 거부되었습니다. + +| 단계 | 새 관리 대상 실행 | 종료 대상이 허용된 시점(`in-process` / `uds`) | +| --- | --- | --- | +| baseline | 허용 | 0.09초 / 0.09초 | +| paused | 허용 | 0.09초 / 0.09초 | +| stalled | 거부 | 0.09초 / 0.10초, hold 전 | +| restarted | 허용 | 36번 거부 뒤 36.61초 / 34번 거부 뒤 34.61초 | +| stopped | 거부 | 0.12초 / 0.16초, kill 전 | + +`stalled`가 잠금을 잡고 있는 동안 오래된 호스트 표본 때문에 DevGuard는 표본이 30초 동안 정상일 때까지 새 작업을 닫아 두었습니다. 그래서 `restarted`의 대상은 `RESOURCE_UNAVAILABLE`로 거부되었고, 절차가 정한 90초 안에서 1초마다 다시 시도했습니다. + + + +## 제어 경로 가용성 + +⟨CTRL-SECTION⟩ + + + +## 자원 회계 + +작업 지시서의 회계 항목을 CodeSpace의 관점이 아니라 DevGuard의 기록으로 확인했습니다. + +| 항목 | 근거 | 결과 | +| --- | --- | --- | +| 요청, 예약, 지원, 적용 값 | [기능 행렬](#report-matrix): 모든 관리 대상 실행에 대한 DevGuard journal 기록 | 두 runner 모드, pipe와 PTY 모두 일치 | +| headroom과 control 예약 | 소비자 예약은 work capacity에서 빠짐. 소비자를 준비할 때 5,500에서 5,350 mCPU로, 12,616,466,432에서 12,079,595,520바이트로, 144에서 104 tasks로 줄었음. matrix `shortage`는 들어가지 않는 요청을 거부함. [제어 경로](#report-control)는 실행 소유자의 사용량을 예약과 비교함 | ⟨ACCT-FOOTPRINT⟩ | +| pressure | [authority 장애](#report-authority): 오래된 호스트 표본 뒤에는 표본이 30초 동안 정상일 때까지 새 작업이 닫히고, 실행 중인 대상은 계속 제어됨. [제어 경로](#report-control): DG-1 부하에서의 호스트 pressure. 서비스 자체의 pressure 동작은 DG-1이 보임 | ⟨ACCT-PRESSURE⟩ | +| 자손이 남아 있으면 root 종료만으로 해제하지 않음 | faults `descendant`, pipe와 PTY | 통과 | +| 알 수 없는 상태는 보수적으로 회계 | faults `escape`, `stalled-observer`, `authority-restart`: attempt가 Suspect로 자원을 차지한 채 남음 | 통과 | +| 불확실한 launch 뒤 재실행 없음 | faults `authority-stalled`, `authority-restart`(launch 한 번), `worker-killed`, 제어 경로의 중복 실행 수 | 통과. ⟨ACCT-DUPLICATES⟩ | +| 시작하지 않았음이 확실한 경우의 정리 | matrix `no-helper`와 `unusable-helper`(cancelled), `shortage`(denied), `exec-failed`(scope가 끝나면 해제). faults `helper-ends`(`no_helper_created`로 해제), `authority-stalled`와 `worker-killed`(붙잡은 것 없음) | 통과 | + + + +## 회귀와 동등성 + +회귀 단계는 후보에서, qualification 호스트의 최소 환경으로, DevGuard 시험 바이너리를 반드시 쓰게 해서 실행했습니다. + +| 단계 | 초 | 결과 | +| --- | ---: | --- | +| `pin` | 0.67 | 통과 | +| `policy` | 0.13 | 통과 | +| `python` | 8.91 | 통과 | +| `format` | 0.93 | 통과 | +| `clippy-root` | 192.45 | 통과 | +| `clippy-adapters` | 235.36 | 통과 | +| `clippy-codex` | 149.78 | 통과 | +| `integration` | 2,196.63 | 통과 | +| `dependencies` | 5.19 | 통과 | +| `unit-patch` | 21.76 | 통과 | +| `unit-codex-runtime` | 31.37 | 통과 | +| `unit-pty` | 7.94 | 통과 | +| `unit-file-system` | 307.08 | 통과 | +| `unit-linux-sandbox` | 14.34 | 통과 | +| `unit-devguard` | 11.32 | 통과 | +| `unit-linux-sandbox-protocol` | 4.72 | 통과 | +| `linux-isolation` | | macOS에서는 실행하지 않음. Linux CI | +| `macos-core` | 75.28 | 통과 | +| `macos-fork-race` | 129.40 | 통과: 시도 400회, 실패 0, 자식 72,946개 모두 exit code 있음, 새 crash report 없음 | + +`all`은 시험 782개 통과, 실패 0, 무시 9였고, macOS 전용 단계는 189개 통과, 실패 0, 무시 9였습니다. adapter의 알려진 간헐 실패("another authority owns this state directory")는 나타나지 않았습니다. 이 단계들은 작업 지시서가 꼽은 모든 영역의 기존 시험을 담고 있습니다. workspace 권한, 승인, pipe와 PTY 실행, stdin과 출력, resize, timeout, 종료, shutdown, patch helper, sandbox helper, UDS worker, feature를 끈 동작이며, 마지막은 `dependencies` 단계와 `devguard` feature 없는 빌드가 다룹니다. `macos-core`는 macOS에서만 도는, DevGuard fixture authority와 launch helper를 상대로 한 gateway 시험도 실행합니다. + +Linux CI는 예약된 [실행 38484155990](https://github.com/novelKR/CodeSpace/actions/runs/38484155990)에서 2026-10-13 23:25부터 23:42 UTC까지 후보에 전체 프로필을 실행했고, 모든 작업이 통과했습니다. 형식과 pin 검사, 정책 검사, Clippy 빌드 세 개와 단위 단계 일곱 개, Ubuntu의 `integration`과 `linux-isolation`, 호스팅된 macOS runner의 `macos-core`, `macos-fork-race`, `dependencies`입니다. Linux에서는 DevGuard에 실제 호스트 증거가 없으므로 소유자가 등록할 수 없습니다. adapter의 단위 시험은 등록이 `incompatible`인지 확인하고, `integration`의 gateway 시험은 관리 대상 실행이 `RESOURCE_AUTHORITY_UNAVAILABLE`로 거부되고 아무것도 시작되지 않는지 확인합니다. 이것이 위 [주장](#report-claims)에서 기능 검증이라고 한 Linux `required`의 거부입니다. + + + +## 수정 기록 + +- **회귀 명령(절차 수정).** 절차는 `validate-upstream.py all macos-core macos-fork-race`라는 명령 하나를 적었습니다. 그런데 `all`은 다른 단계 이름을 모두 대신하고 macOS 전용 단계를 빼므로([`scripts/validate-upstream.py`](../../scripts/validate-upstream.py)), 그 명령은 `macos-core`도 `macos-fork-race`도 실행하지 않습니다. 두 단계는 같은 후보에서 두 번째 실행으로 돌렸고, 이제 절차는 두 번의 실행을 적습니다. 문서만 바뀌었으며 다시 하거나 바꾼 실행은 없습니다. +- **고정 전 수정.** qualification 호스트에서 `7a0a748`의 하네스([#97](https://github.com/novelKR/CodeSpace/pull/97))를 점검해 하네스 결함 세 가지를 찾았고, 병합 전에 고쳤습니다(`8ed8b08`). SIGTERM으로 죽은 관리 대상 PTY 자식의 기대 status(launch descriptor를 물려받은 자식을 고정 Codex PTY가 그렇게 보고하므로 exit code 143), 활성 인스턴스를 기다리지 않고 한 번만 읽던 settled 확인, `stalled` 뒤 DevGuard가 다시 작업을 받기 전에 `restarted`의 대상을 시작하던 `authority` 스위트입니다. 제품 결함도 하나 찾았습니다. `uds` 모드에서 gateway가 종료할 때 worker를 바로 죽였기 때문에 관리 대상 pipe 실행이 worker보다 오래 남았고, 그 scope는 명령이 스스로 끝난 약 30초 뒤에야 끝났습니다. [#98](https://github.com/novelKR/CodeSpace/pull/98)이 이를 고쳤습니다. 이제 gateway는 worker 연결을 닫고, 종료하면서 자기 프로세스를 끝내는 worker를 기다리며, 5초 뒤에도 실행 중일 때만 worker를 죽입니다. 같은 사례에서 두 scope가 바로 끝났습니다. 후보는 #98 뒤에 고정했고 모든 qualification 실행은 그 후보에서 했습니다. 실패했거나 끝나지 않은 점검은 그 뒤 통과한 점검과 함께 보존합니다. + + + +## 증거 + +증거 디렉터리는 qualification 호스트의 DevGuard checkout 아래 `evidence/` 디렉터리에 있습니다. 각 디렉터리는 모든 파일의 SHA-256을 담은 `MANIFEST.json`으로 봉인했고, 파일은 읽기 전용입니다. credential, credential digest, 자식의 환경은 어느 디렉터리에도 없으며, 각각 검사했습니다. 하네스 실행의 디렉터리는 `MANIFEST.json`의 SHA-256이 아래와 같고 `qualify-devguard.py verify`가 받아들이면 확인된 것입니다. 회귀 디렉터리에는 `validate-upstream.py`의 보고서와 로그를 그대로 복사했습니다. 제어 실행의 콘솔 출력과 `verify` 출력은 디렉터리 옆에 남겼습니다. + +| 디렉터리 | 실행 | `MANIFEST.json` SHA-256 | +| --- | --- | --- | +| `csrg-u6-candidate-2026-10-13-ca306ee` | candidate | `3e3587d1694e4108912c742b6825684ff95b00e658c6f78fbe63143e37aadc95` | +| `csrg-u6-qual-matrix-2026-10-13-ca306ee` | matrix | `faf673aa028f4d4c4646eb271e617395f2b753740eecb3501241936e2b2ad688` | +| `csrg-u6-qual-faults-2026-10-13-ca306ee` | faults | `b000a94a70c68ea74658e37e2da275fe48a1c7f8b74cd6c7e4bdbb2525ae5025` | +| `csrg-u6-qual-authority-2026-10-13-ca306ee` | authority | `c4a7fb26703939eb56627848affba8d4790e72c6337663533356ca5662b78256` | +| `csrg-u6-qual-control-rehearsal-2026-10-13-ca306ee` | 제어 예행 | `2c9c7fc08f4204e8f9c1a921459b50adc0c2ee439219ec8232124d785f0c66b1` | +| `csrg-u6-qual-regressions-2026-10-13-ca306ee` | 회귀 단계, `all` | `2825fb3ca091a5d0280376a3f4134e3d0050e0718cbc95409633fe259840e52e` | +| `csrg-u6-qual-regressions-macos-2026-10-13-ca306ee` | `macos-core`와 `macos-fork-race` | `5d160894fbf4b63fd822da63bf137bd8ab6a1d7a1aba005c256f5ba3ff59c2bd` | +| `csrg-u6-control-rehearsal-2026-10-14-ca306ee` | 제어 예행 | `ac79024e237ee496b64f524696228e171a7161ccfde7652e02b023c67c25039f` | +| `csrg-u6-control-2026-10-14-ca306ee` | 제어 | `7706aac71c2f793dbc273b5c78f888dcc2af50269c0039d132b21c236b47e9be` | + +고정 전의 점검도 보존합니다. + +| 디렉터리 | commit | 결과 | `MANIFEST.json` SHA-256 | +| --- | --- | --- | --- | +| `csrg-u6-harness-check-candidate-2026-10-13` | `7a0a748` | 통과 | `6b1cc6a10df9f3ca2b80472b5c0d9090a7e1a3a3517a99c1124d10b08a4d9400` | +| `csrg-u6-harness-check-matrix-2026-10-13` | `7a0a748` | 실패: 하네스 결함 두 가지 | `bf20056a7351b155f2e73388dbb22cd34d3a54721db0ed0b420842b3a2681f4a` | +| `csrg-u6-harness-check-faults-2026-10-13` | `7a0a748` | 실패: 27개 중 26개, `uds` shutdown | `e1568fcb5ccb298e2eb581e6687c0947ccf40c8dee1960bcedddb57473792c1a` | +| `csrg-u6-harness-check-authority-2026-10-13` | `7a0a748` | 끝나지 않음: `restarted` | `42f8ef5f6b20665120e059add4fd1d7fa3f4ad6f98c8a5b8588fe35f5def1290` | +| `csrg-u6-harness-check-control-2026-10-13` | `7a0a748` | 예행, 설계대로 판정 불가 | `2a8507da10ac571259e4a7f3437102dd24a63cf7d129d9a30492c80f30940681` | +| `csrg-u6-harness-check-matrix-2026-10-13-8ed8b08` | `8ed8b08` | 통과 | `64198825c697e333aaab14469224f297b59852067192afd4614c8e0c77302aa2` | +| `csrg-u6-harness-check-authority-2026-10-13-8ed8b08` | `8ed8b08` | 통과 | `ffe9332ace437ff926ea2b787daf94ed58a8a691f00e23374fbefaa7797372e4` | +| `csrg-u6-harness-check-faults-2026-10-13-b74e5c2` | `b74e5c2` | 통과 | `6057f26fb81a59f4f8ef6f8c12ff95235ae25c10b7503c7a6f2aaa5264ddae8b` | +| `csrg-u6-harness-check-matrix-2026-10-13-b74e5c2` | `b74e5c2` | 통과 | `577962c15c89e70b4debfe93c2f7513876fa592c6d15ff86bf7535a585121a76` | +| `csrg-u6-harness-check-authority-2026-10-13-b74e5c2` | `b74e5c2` | 통과 | `dad385b738361ef883928329f3ed6879f9a874ebdc32f3bdd5aed464ba6dc679` | + +정책 행이 근거로 삼는 그 release의 DG-1 측정도 같은 곳에 봉인되어 있고, DevGuard에 기록되어 있습니다. + + + +## CS-RG 밖에 남는 것 + +CS-RG는 여기서 끝납니다. 다음은 CS-RG 밖에 남으며, 이 문서는 그것을 주장하지 않습니다. + +- **P1-RECOVERY.** critical path의 다음 마일스톤으로, 독립 runner가 프로세스를 유지하는 동안 gateway를 재시작하고 다시 연결하는 일입니다. 소유자의 별도 승인이 있어야만 시작합니다. +- **DG-LINUX.** Linux에서의 강제 보호입니다. 이것이 qualification을 마치기 전까지 Linux에서 `required`는 거부되고, Linux 경로는 `off`뿐입니다. +- **DG-CACHE**와 **DG-ADAPTERS.** DevGuard의 cache와 추가 adapter입니다. +- **Codex 수렴.** upstream이 hook을 제공할 때까지([openai/codex#53298](https://github.com/openai/codex/issues/53298)) 관리 대상 PTY 실행은 CodeSpace의 [기록된 Codex 패치](upstream-lock.md#codex-downstream-patch)로 reap 전에 관찰합니다. 다음 Codex pin 이동은 별도 변경이며 새 후보입니다. +- **다른 조합.** DevGuard client pin, release, 정책, 호스트가 다르거나, 코드가 바뀌거나, 도구가 다르면 새 후보이며 따로 실행해야 합니다. +- **실행이 보이지 않은 것:** 제어 경로의 DG-1 warm 부하, 전경 브라우저 응답성, runner wire의 메시지 재전송, 주입한 journal 거부, 임의 크기의 요청이나 파일에 대한 보호. diff --git a/docs/ko/cs-rg-qualification.md b/docs/ko/cs-rg-qualification.md index bc8c227..6811b23 100644 --- a/docs/ko/cs-rg-qualification.md +++ b/docs/ko/cs-rg-qualification.md @@ -6,7 +6,7 @@ 이 문서는 CodeSpace가 DevGuard를 쓰는 방식(CS-RG)을 qualification하는 절차입니다. 어떤 조합을 qualification하는지, 어떤 모드를 지원한다고 주장하는지, 각 주장을 어떻게 시험하고 측정하는지, 무엇이 통과인지, 실행이 어떤 증거를 남기는지를 정합니다. 이 절차는 하네스 [`scripts/qualify-devguard.py`](../../scripts/qualify-devguard.py)와 함께, 첫 qualification 실행 전에 고정합니다. 첫 qualification 실행 뒤에 절차나 하네스를 바꾸면 새 절차가 됩니다. 다른 변경처럼 검토하고, 영향받는 실행은 다시 합니다. 각 단위가 무엇을 만들었는지는 [결합 로드맵](devguard-integration.md)에 있고, 이 문서는 그 결과가 qualification을 통과하는지를 판단합니다. -**현재 상태:** 절차와 하네스만 있습니다. qualification 실행은 아직 하지 않았고, 이 문서의 어떤 내용도 qualification 결과가 아닙니다. 이 절차로 한 실행이 통과하고 그 증거를 검토할 때까지 CS-RG는 진행 중이며 qualification을 마치지 않은 상태입니다. +**현재 상태:** 첫 qualification 실행 전에 하네스와 함께 고정했습니다([#97](https://github.com/novelKR/CodeSpace/pull/97)). 후보 `ca306ee`에서 한 실행이 통과해 CS-RG는 그 조합으로 qualification을 마쳤으며, 결과와 증거는 [qualification 보고서](cs-rg-qualification-report.md)에 있습니다. [회귀 명령](#regressions)은 실행 뒤에 바로잡았고, 보고서의 [수정 기록](cs-rg-qualification-report.md#report-amendments)에 남겼습니다. 그 밖에 바뀐 것은 없습니다. @@ -200,7 +200,7 @@ fixture authority를 쓰는 gateway 시험은 DevGuard 시험 바이너리가 ## 회귀와 동등성 -후보 조합에서, qualification 호스트의 최소 환경으로 `python3 scripts/validate-upstream.py all macos-core macos-fork-race`를 실행해 모든 단계를 돌립니다. DevGuard 시험 바이너리를 쓰는 단계에서는 그 바이너리가 꼭 있어야 합니다. Linux는 후보 head의 CI가 보여 주며, 그 `dependencies` 단계가 `devguard` feature를 켠 의존성 그래프와 끈 그래프를 모두 확인합니다. 어느 단계에서든 회귀가 있으면 qualification은 실패합니다. +후보 조합에서, qualification 호스트의 최소 환경으로 두 번 실행해 모든 단계를 돌립니다. 먼저 `python3 scripts/validate-upstream.py all`, 다음에 `python3 scripts/validate-upstream.py macos-core macos-fork-race`입니다. DevGuard 시험 바이너리를 쓰는 단계에서는 그 바이너리가 꼭 있어야 합니다. `all`은 macOS 전용 단계를 뺀 모든 단계를 돌리고 함께 적은 다른 단계 이름을 대신하므로, macOS 전용 단계는 따로 실행해야 합니다. Linux는 후보 head의 CI가 보여 주며, 그 `dependencies` 단계가 `devguard` feature를 켠 의존성 그래프와 끈 그래프를 모두 확인합니다. 어느 단계에서든 회귀가 있으면 qualification은 실패합니다. diff --git a/docs/ko/devguard-integration.md b/docs/ko/devguard-integration.md index 7bbaec8..24041c1 100644 --- a/docs/ko/devguard-integration.md +++ b/docs/ko/devguard-integration.md @@ -2,13 +2,13 @@ # DevGuard 결합 로드맵 -> **상태: 구현 지시로서 효력 중지.** 이 페이지의 ‘CS-RG 작업 순서’, ‘소비 경계’, ‘설계 개정 1 참조’ 절은 적힌 대로 구현하지 않습니다. 현재 상태와 선행 조건은 영향이 없습니다. CodeSpace 통합 계획에 대해 소유자가 지시한 검토인 CS-RG 통합 경계 재검증(작업 단위가 아닙니다)이 끝날 때까지 적용됩니다. 대체 구조는 승인되지 않았으며, 소유자가 재검증 결과를 검토한 뒤 결정합니다. 이 표기는 지시의 효력만 중지하며 어떤 안전 요구도 완화하지 않습니다. 아래 내용은 이력 추적을 위해 바꾸지 않고 남깁니다. 다만 현재 상태, 소유자가 2026-10-02에 이 효력 중지와 별도로 승인한 CSRG-U1의 [상태 전용 연결](#devguard-status-connection), 소유자가 2026-10-03에 지시한 CSRG-U2의 [실행 소유자 등록](#devguard-owner-registration), 소유자가 2026-10-07에 지시한 CSRG-U3의 [실행 허용과 spawn 전 준비](#devguard-admission), 소유자가 2026-10-08에 지시한 CSRG-U4의 [관리형 실행](#devguard-launch), 소유자가 2026-10-09에 지시한 CSRG-U5의 [실행 뒤 생명주기](#devguard-lifecycle)는 예외입니다. +> **상태: 구현 지시로서 효력 중지.** 이 페이지의 ‘CS-RG 작업 순서’, ‘소비 경계’, ‘설계 개정 1 참조’ 절은 적힌 대로 구현하지 않습니다. 현재 상태와 선행 조건은 영향이 없습니다. CodeSpace 통합 계획에 대해 소유자가 지시한 검토인 CS-RG 통합 경계 재검증(작업 단위가 아닙니다)이 끝날 때까지 적용됩니다. 대체 구조는 승인되지 않았으며, 소유자가 재검증 결과를 검토한 뒤 결정합니다. 이 표기는 지시의 효력만 중지하며 어떤 안전 요구도 완화하지 않습니다. 아래 내용은 이력 추적을 위해 바꾸지 않고 남깁니다. 다만 현재 상태, 소유자가 2026-10-02에 이 효력 중지와 별도로 승인한 CSRG-U1의 [상태 전용 연결](#devguard-status-connection), 소유자가 2026-10-03에 지시한 CSRG-U2의 [실행 소유자 등록](#devguard-owner-registration), 소유자가 2026-10-07에 지시한 CSRG-U3의 [실행 허용과 spawn 전 준비](#devguard-admission), 소유자가 2026-10-08에 지시한 CSRG-U4의 [관리형 실행](#devguard-launch), 소유자가 2026-10-09에 지시한 CSRG-U5의 [실행 뒤 생명주기](#devguard-lifecycle), 소유자가 2026-10-12에 지시한 CSRG-U6의 [qualification과 도입](#devguard-qualification)은 예외입니다. [English](../devguard-integration.md) | [한국어](devguard-integration.md) [DevGuard](https://github.com/novelKR/DevGuard)는 개발 작업의 자원을 중앙에서 관리하는 독립 시스템이며 CodeSpace와 동일한 Apache-2.0 라이선스를 적용한다. 승인된 결합 경로에 따라 실행 허용과 자원 회계를 공통 계층에 맡기고, CodeSpace는 프로세스 소유권, PTY, 입출력, 권한, 승인 hold와 workspace 조정을 계속 담당한다. -**현재 상태:** DevGuard는 독립 저장소에서 DG-1을 완료했다([`395315d`](https://github.com/novelKR/DevGuard/tree/395315d34b5d458ea1774446727f0cb14bd8a120), [마일스톤 원장](https://github.com/novelKR/DevGuard/blob/395315d34b5d458ea1774446727f0cb14bd8a120/milestones.json)). DG-0 계약 위에 macOS 실제 호스트 증거, 현재 사용자의 LaunchAgent로 설치하는 인증 daemon, fenced launch helper와 대조, Cargo adapter를 갖춘 `devguard` 명령행 owner, 후보 시험용 parent lease, upgrade와 repair를 제공한다. 측정한 호스트와 정책에서 release `0.1.0-5daee5d-b3fa569e`(Git tag가 아닌 release ID)의 macOS SLO qualification을 마쳤으며 Linux 강제 보호는 qualification하지 않았다. CodeSpace 소비(CS-RG)는 진행 중이며 qualification을 마치지 않았다. CSRG-U1은 opt-in 상태 전용 연결을 추가했다. `devguard` feature로 빌드하고 `--devguard status`로 시작한 gateway는 [`6e7e065`](upstream-lock.md#devguard-client-pin)에 고정한 DevGuard client로 DevGuard의 상태를 `workspace_info`에 보고한다. CSRG-U2부터는 CodeSpace의 실행을 소유한 프로세스가 스스로를 DevGuard에 등록하며(`--devguard register`), workspace의 `resources` 설정으로 자원 참여를 필수로 지정할 수 있다. CSRG-U3부터 그 소유자는 이런 실행마다 무엇을 만들기 전에 프로세스 slot을 잡고 DevGuard의 실행 허용을 받는다. CSRG-U4부터는 launch helper를 설정했으면(`--devguard-launch-helper`) 그 실행을 DevGuard의 launch helper로 한 번 실행한다. DevGuard는 helper의 scope를 묶고 정책을 적용한 뒤에 실행을 승인한다. helper가 없으면 시작하지 않은 attempt를 취소하고 실행을 거부한다. DevGuard 없이 실행하는 것은 없다. CSRG-U5부터 프로세스마다 reaper는 하나다. DevGuard는 관리 대상 실행의 scope를 root가 reap되기 전에 관찰한다. pipe에서는 CodeSpace 자신의 reaper가, PTY에서는 [기록된 패치](upstream-lock.md#codex-downstream-patch)를 적용한 고정 Codex PTY의 waiter가 그 기회를 준다. 관리 대상 프로세스를 죽이면 그 scope도 종료하며, 시작하지 않았음이 증명된 관리 대상 실행의 승인은 다시 재개할 수 있다. qualification은 CSRG-U6이 맡으며, 그 절차와 하네스는 [CS-RG qualification](cs-rg-qualification.md)에 있다. 아직 qualification을 마친 조합은 없다. qualification을 마친 release는 실행에 쓸 후보로 남으며 선택된 pin이 아니다. client pin은 client crate의 소스 pin이다. +**현재 상태:** DevGuard는 독립 저장소에서 DG-1을 완료했다([`395315d`](https://github.com/novelKR/DevGuard/tree/395315d34b5d458ea1774446727f0cb14bd8a120), [마일스톤 원장](https://github.com/novelKR/DevGuard/blob/395315d34b5d458ea1774446727f0cb14bd8a120/milestones.json)). DG-0 계약 위에 macOS 실제 호스트 증거, 현재 사용자의 LaunchAgent로 설치하는 인증 daemon, fenced launch helper와 대조, Cargo adapter를 갖춘 `devguard` 명령행 owner, 후보 시험용 parent lease, upgrade와 repair를 제공한다. macOS SLO qualification은 release `0.1.0-6e7e065-94d85365`(Git tag가 아닌 release ID)에 대해 마쳤다. 이 release는 client pin의 commit에서 빌드했고, 2026-10-13에 측정한 호스트에서 CodeSpace의 `codespace` 소비자를 포함한 정책으로 측정했다([DevGuard #34](https://github.com/novelKR/DevGuard/pull/34)). Linux 강제 보호는 qualification하지 않았다. CodeSpace 소비(CS-RG)는 정확히 한 조합에 대해 macOS에서 qualification을 마쳤다. CSRG-U1은 opt-in 상태 전용 연결을 추가했다. `devguard` feature로 빌드하고 `--devguard status`로 시작한 gateway는 [`6e7e065`](upstream-lock.md#devguard-client-pin)에 고정한 DevGuard client로 DevGuard의 상태를 `workspace_info`에 보고한다. CSRG-U2부터는 CodeSpace의 실행을 소유한 프로세스가 스스로를 DevGuard에 등록하며(`--devguard register`), workspace의 `resources` 설정으로 자원 참여를 필수로 지정할 수 있다. CSRG-U3부터 그 소유자는 이런 실행마다 무엇을 만들기 전에 프로세스 slot을 잡고 DevGuard의 실행 허용을 받는다. CSRG-U4부터는 launch helper를 설정했으면(`--devguard-launch-helper`) 그 실행을 DevGuard의 launch helper로 한 번 실행한다. DevGuard는 helper의 scope를 묶고 정책을 적용한 뒤에 실행을 승인한다. helper가 없으면 시작하지 않은 attempt를 취소하고 실행을 거부한다. DevGuard 없이 실행하는 것은 없다. CSRG-U5부터 프로세스마다 reaper는 하나다. DevGuard는 관리 대상 실행의 scope를 root가 reap되기 전에 관찰한다. pipe에서는 CodeSpace 자신의 reaper가, PTY에서는 [기록된 패치](upstream-lock.md#codex-downstream-patch)를 적용한 고정 Codex PTY의 waiter가 그 기회를 준다. 관리 대상 프로세스를 죽이면 그 scope도 종료하며, 시작하지 않았음이 증명된 관리 대상 실행의 승인은 다시 재개할 수 있다. CSRG-U6은 [CS-RG qualification 절차](cs-rg-qualification.md)에 따라 정확히 한 조합을 qualification했다. runner 모드는 `in-process`와 `--runtime-bin`을 쓴 `uds`이고, 각각 pipe와 PTY 실행을 포함한다. 그 결과는 [qualification 보고서](cs-rg-qualification-report.md)에 있다([qualification과 도입](#devguard-qualification)). Linux `required`는 DG-LINUX 전까지 지원하지 않는다. qualification을 마친 release는 실행에 쓸 후보로 남으며 선택된 pin이 아니다. client pin은 client crate의 소스 pin이다. DevGuard [설계 개정 1](https://github.com/novelKR/DevGuard/blob/d4981b4c241cff42687f5c2c681b583c7847776e/docs/ko/design-revision-1.md)은 [DevGuard PR #8](https://github.com/novelKR/DevGuard/pull/8)의 병합 `d4981b4c241cff42687f5c2c681b583c7847776e`로 반영되었으며 CS-RG의 실행 계층과 작업 순서를 개정했다. 이 개정은 계획과 이후 구현을 구속하는 설계 결정을 바꾼다. 현재 CodeSpace 동작이나 구현·qualification 상태는 바꾸지 않는다. @@ -250,7 +250,30 @@ CSRG-U5는 관리 대상 실행의 실행 뒤 생명주기를 완성한다. 누 **재실행 없음.** 첫 attempt가 시작하지 않았다는 증거가 없으면 아무것도 다시 시작하지 않는다. 제때 끝나지 않은 transcript, 잃어버렸거나 알 수 없는 `BeginLaunch` 답, 실행 요청을 받은 뒤 잃은 worker, 취소된 요청, 관찰 전에 reap된 root, authority 재시작, 반복된 재개 모두 그렇다. authority가 재시작하면 DevGuard는 실행 중인 scope를 더는 알지 못한다. 프로세스는 계속 CodeSpace의 것이고, 소유자는 새 작업을 위해 다시 등록하며, attempt는 프로세스가 끝난 뒤에도 suspect로 자원을 차지한다. -**지원**은 CSRG-U4와 같다. **주장하지 않는 것:** CS-RG qualification(CSRG-U6), DG-LINUX 전의 Linux. +**지원**은 CSRG-U4와 같고, [CSRG-U6](#devguard-qualification)의 조합으로 qualification을 마쳤다. **주장하지 않는 것:** DG-LINUX 전의 Linux. + + + +## qualification과 도입(CSRG-U6) + +CSRG-U6은 [CS-RG qualification 절차](cs-rg-qualification.md)에 따라 qualification 호스트에서 정확히 한 조합으로 CS-RG를 qualification했다. 그 조합은 CodeSpace `ca306ee`(또는 code tree가 같은 이후 commit), `6e7e065`의 DevGuard client, 같은 정책에서 DG-1 qualification을 마친 설치 release `0.1.0-6e7e065-94d85365`, 기록된 패치를 적용한 Codex `6b9826e`, Rust 1.95.0이다. 조합, 모든 결과, 증거는 [qualification 보고서](cs-rg-qualification-report.md)에 있다. + +**지원.** 그 release를 쓰는 macOS에서 `in-process`와 `--runtime-bin`을 쓴 `uds` runner 모드의 `required` 참여를 각각 pipe와 PTY 실행으로 지원하고, 한 gateway 안의 `off`와 `required` workspace를 지원한다. 지원하지 않으며 아무것도 실행하기 전에 거부하는 것: `--runner-socket`을 쓴 `uds`, `--devguard status`나 `devguard` feature 없이 쓰는 `required`, DG-LINUX 전의 Linux. 쓸 수 있는 launch helper가 없으면 관리 대상 실행은 `MANAGED_LAUNCH_UNAVAILABLE`로 거부된다. `off` 참여는 [기존 `off` 경로 결정](cs-rg-qualification.md#legacy-off-path)에 적은 대로 모든 플랫폼에서 기존 동작을 유지한다. + +**도입.** 이 주장은 qualification한 조합에만 해당한다. release, 정책, 호스트, 도구, code tree 가운데 하나라도 다르면 새 후보이며 따로 실행해야 한다. 쓰는 방법은 다음과 같다. + +1. qualification한 DevGuard release를 현재 사용자의 서비스로 실행하고, CodeSpace용 소비자를 control service로 준비한다. role은 `control_service`이고 generation, 비공개 credential 파일, 인스턴스 하나, 정적 control 예약이 필요하다. 예약은 150 mCPU, 512 MiB, 40 tasks로 qualification했다. DevGuard는 시작할 때만 정책을 읽으며, 정책을 바꾸면 DG-1 측정을 다시 해야 한다. +2. `codespace-mcp`는 `-p codespace-server --features devguard`로, `uds`의 worker는 `--features devguard`로, qualification한 code tree를 가진 commit에서 빌드한다. +3. gateway를 `--devguard register`, [상태 전용 연결](#devguard-status-connection)의 소비자 설정, release의 `devguard-launch`를 가리키는 `--devguard-launch-helper`로 시작한다. 모드는 `in-process`이거나 `--runtime-bin`을 쓴 `uds`다. +4. 실행을 관리해야 하는 workspace마다 `"resources": {"participation": "required"}`와 work capacity에 들어가는 `request`를 준다. 소유자가 등록되고 launch helper가 있으면 `workspace_info.resource_authority`는 소유자를 `registered`로, `governs_execution`을 `true`로 보고한다. +5. DevGuard 서비스는 메모리 pressure가 정상일 때 시작하거나 재시작한다. 메모리 경고 중에 시작한 서비스는 메모리가 30초 동안 정상이 될 때까지 아무것도 받아들이지 않는다([DevGuard 운영 문서](https://github.com/novelKR/DevGuard/blob/c077c747972cebca828a903968868f5713ce5664/docs/operations.md#available-commands)). + +**되돌리기.** 아래 어느 단계도 관리 대상 workspace의 실행을 DevGuard 없이 돌리지 않으며, 불확실한 작업을 다시 실행하거나 잊지 않는다. + +- **새 실행 허용.** gateway를 `--devguard register` 없이, 또는 launch helper 없이 다시 시작한다. 그러면 `required` workspace는 새 실행을 `RESOURCE_POLICY_UNSUPPORTED`나 `MANAGED_LAUNCH_UNAVAILABLE`로 거부하며, `off`로 바뀌지 않는다. workspace를 `off`로 바꾸는 것은 registry를 따로, 명시적으로 고치는 일이다. +- **실행 중인 작업.** gateway가 종료하면 gateway나 그 worker가 소유한 실행은 관리 대상까지 모두 끝나고, DevGuard는 그 scope가 끝난 것을 관찰한 뒤 attempt를 해제한다. DevGuard가 멈추거나 정체되거나 되돌려지는 동안에도 실행 중인 관리 대상 프로세스는 CodeSpace의 것으로 남는다. status, 출력, stdin, resize, 종료, timeout은 DevGuard에 묻지 않으며, 새 관리 대상 실행은 거부된다. DevGuard가 더는 정리할 수 없는 attempt는 Suspect로 자원을 차지한 채 남고, CodeSpace는 그것을 다시 실행하지 않는다. +- **DevGuard.** journal은 보존한다. DevGuard 자체의 되돌리기는 `devguard repair --use last-known-good`나 이전 release로의 upgrade다([DevGuard 운영 문서](https://github.com/novelKR/DevGuard/blob/c077c747972cebca828a903968868f5713ce5664/docs/operations.md#compatibility-checks-and-rollback)). `codespace` 소비자는 그 인스턴스가 모두 retire된 뒤에만 제거한다. 이 가운데 무엇을 해도 qualification한 조합을 벗어난다. +- **기록.** DevGuard의 마일스톤 원장은 무엇을 qualification했는지 기록한다. 되돌리기는 그곳에 기록하며 숨기지 않는다. ## CS-RG 작업 순서 diff --git a/docs/translations.json b/docs/translations.json index 72c33b0..f3ae68e 100644 --- a/docs/translations.json +++ b/docs/translations.json @@ -48,6 +48,7 @@ "devguard-launch", "devguard-lifecycle", "devguard-owner-registration", + "devguard-qualification", "devguard-status-connection", "devguard-결합-로드맵", "execution-owner-registration-csrg-u2", @@ -57,6 +58,8 @@ "minimum-adoption-conditions", "plan-and-evidence-references", "prerequisites-and-priority", + "qualification-and-adoption-csrg-u6", + "qualification과-도입csrg-u6", "resource-adoption-levels", "resource-consumer-boundary", "resource-gateway-recovery", @@ -75,8 +78,8 @@ "최소-도입-조건", "최초-gateway-복구-범위" ], - "source_sha256": "7ca40059fa574da9d60492618d2520c1e4a8d6a97e591d55d3b3c61e1044c76b", - "translation_sha256": "5fba264f1c5e64d56b997a80078876abc5d863580f0c7f49184bc75b70f7f873" + "source_sha256": "3158dd7bc4040281e0666a63aa6675bd34df702c20d9a84a039db6fcd25efb6d", + "translation_sha256": "845f9a126b8e34948fd21d51ac168d9beb0f7d66c0577e6ed7d4919e58bb95f1" }, { "id": "cs-rg-qualification", @@ -130,8 +133,58 @@ "회귀와-동등성", "후보-조합" ], - "source_sha256": "99d92fa6d0a302b40c70b892f5af601e662e866f4ff99cd612220577d6149128", - "translation_sha256": "3fc102df0febc47abe134718152cddd532cdc1245c997a6570f246fc3c0c6510" + "source_sha256": "dc0a5ce31fcd3fc4ac9b27b53ed04e04cb448b14f13c8f0fe26f1bf0edc5d283", + "translation_sha256": "6396e29330c89d2b231cfef742ec7dc7927c2297ecefec52a93a67bf210497fb" + }, + { + "id": "cs-rg-qualification-report", + "section": "project", + "order": 3, + "route": "/guide/cs-rg-qualification-report", + "source": "docs/cs-rg-qualification-report.md", + "translation": "docs/ko/cs-rg-qualification-report.md", + "anchors": [ + "amendments-and-corrections", + "authority-failure", + "authority-장애", + "control-path-availability", + "cs-rg-qualification-report", + "cs-rg-qualification-보고서", + "cs-rg-밖에-남는-것", + "evidence", + "fault-cases", + "functional-matrix", + "outside-cs-rg", + "qualification한-조합", + "regression-and-parity", + "report-accounting", + "report-amendments", + "report-authority", + "report-claims", + "report-combination", + "report-control", + "report-evidence", + "report-faults", + "report-matrix", + "report-outside", + "report-regressions", + "report-runs", + "resource-accounting", + "runs", + "the-qualified-combination", + "what-is-claimed", + "기능-행렬", + "수정-기록", + "실행", + "자원-회계", + "장애-사례", + "제어-경로-가용성", + "주장하는-것", + "증거", + "회귀와-동등성" + ], + "source_sha256": "1c79724e4a76e3dade7ad31b88c5ae36937508be6625f8e2acd7e8b7b83745b2", + "translation_sha256": "850a2a4a01d73c402e922c96c76f0d823f267d39fb9f0d60e95d9dc33dbce636" }, { "id": "overview", From 68e274da8fb3be8f1d2f4c79913939d63d2b494a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 14 Oct 2026 06:26:14 +0000 Subject: [PATCH 2/2] docs: record the CS-RG control-path results (CSRG-U6) The control run on the candidate qualified on 2026-10-14: both runner modes, three repetitions each, and all twelve idle and load intervals passed under DG-1's cold load. The report now has its per-interval values (status p99 at most 4.922 ms against 500 ms, acknowledgement p99 at most 0.804 ms against 1 second), the scope's end, release, I/O and refusal times, the load's 1,199 runs, the host's pressure and the execution owner's footprint against its reservation, the accounting cells that depend on them, and both control runs' evidence hashes. Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/cs-rg-qualification-report.md | 56 ++++++++++++++++++++++++--- docs/ko/cs-rg-qualification-report.md | 56 ++++++++++++++++++++++++--- docs/translations.json | 4 +- 3 files changed, 102 insertions(+), 14 deletions(-) diff --git a/docs/cs-rg-qualification-report.md b/docs/cs-rg-qualification-report.md index d7086ef..d01624e 100644 --- a/docs/cs-rg-qualification-report.md +++ b/docs/cs-rg-qualification-report.md @@ -64,8 +64,8 @@ Every run used the candidate's binaries in the minimal environment, with Rust 1. | `control --rehearsal` | 2026-10-13 16:50–16:53 | inconclusive only because a rehearsal is shorter than the protocol, as designed | | regression stages, `all` | 2026-10-13 17:00–17:53 | every stage passed except `linux-isolation`, which needs Linux | | regression stages, `macos-core` and `macos-fork-race` | 2026-10-13 17:57–18:01 | passed | -| `control --rehearsal` | ⟨CTRL-REH-WHEN⟩ | ⟨CTRL-REH-RESULT⟩ | -| `control` | ⟨CTRL-WHEN⟩ | ⟨CTRL-RESULT⟩ | +| `control --rehearsal` | 2026-10-13 23:20–23:24 | inconclusive only because a rehearsal is shorter than the protocol, as designed; all four intervals passed | +| `control` | 2026-10-13 23:24 to 2026-10-14 03:33 | qualified: both runner modes, three repetitions each, all twelve intervals passed | | Linux CI | 2026-10-13 23:25–23:42 | passed: every job of the full profile ([run 38484155990](https://github.com/novelKR/CodeSpace/actions/runs/38484155990)) | @@ -118,7 +118,49 @@ The host sample that went stale while `stalled` held the lock kept new work clos ## Control-path availability -⟨CTRL-SECTION⟩ +`control` ran the full protocol from 23:24 UTC on 2026-10-13 to 03:33 UTC on 2026-10-14, right after a rehearsal (23:20–23:24) that was inconclusive only because a rehearsal is shorter than the protocol. In each runner mode it ran three repetitions of a 10-minute idle interval and a load interval of at least 30 minutes, under DG-1's cold load against the installed release. The load intervals lasted 1,829 to 1,865 seconds, because the load's runs finish after the planned end. All twelve intervals and all six repetitions passed, so both runner modes qualified, and so did the run. The service ran the release with process ID 23023 before and after every repetition. + +The targets are a `process_status` p99 of at most 500 ms and a termination acknowledgement p99 of at most 1 second. Times are in milliseconds. Because the slot at an interval's end is taken too, a count can be one above its schedule, or two for the status samples of the two targets. + +| Runner mode | Repetition | Interval | Seconds | Status p99 / max | Status samples / schedule | Acknowledgement p99 | Terminations / schedule | Verdict | +| --- | ---: | --- | ---: | ---: | ---: | ---: | ---: | --- | +| `in-process` | 1 | idle | 600 | 2.150 / 45.195 | 1,201 / 1,200 | 0.539 | 30 / 30 | pass | +| `in-process` | 1 | load | 1,857 | 0.463 / 17.616 | 3,714 / 3,712 | 0.633 | 93 / 92 | pass | +| `in-process` | 2 | idle | 600 | 1.130 / 1.371 | 1,202 / 1,200 | 0.614 | 30 / 30 | pass | +| `in-process` | 2 | load | 1,854 | 0.664 / 1.075 | 3,710 / 3,708 | 0.417 | 93 / 92 | pass | +| `in-process` | 3 | idle | 600 | 1.107 / 1.404 | 1,202 / 1,200 | 0.481 | 30 / 30 | pass | +| `in-process` | 3 | load | 1,829 | 1.871 / 3.067 | 3,660 / 3,658 | 0.723 | 91 / 91 | pass | +| `uds` | 1 | idle | 600 | 1.418 / 2.801 | 1,200 / 1,200 | 0.741 | 30 / 30 | pass | +| `uds` | 1 | load | 1,857 | 0.985 / 1.772 | 3,716 / 3,714 | 0.729 | 93 / 92 | pass | +| `uds` | 2 | idle | 600 | 1.572 / 4.298 | 1,202 / 1,200 | 0.694 | 30 / 30 | pass | +| `uds` | 2 | load | 1,865 | 1.076 / 1.765 | 3,732 / 3,730 | 0.804 | 93 / 93 | pass | +| `uds` | 3 | idle | 600 | 4.922 / 12.753 | 1,202 / 1,200 | 0.693 | 30 / 30 | pass | +| `uds` | 3 | load | 1,839 | 0.560 / 1.658 | 3,678 / 3,676 | 0.473 | 92 / 91 | pass | + +The scope's end and DevGuard's release are timed separately from the acknowledgement, and the I/O echo and the refusal latency have no established target, so these are reported. The harness does not summarize the time to the exited status; its p99 here is computed from the raw samples by the same nearest-rank rule. + +| Runner mode | Repetition | Interval | Exited p99 | Process group gone p99 | Released p99 | I/O p99 | Refusal p99 | +| --- | ---: | --- | ---: | ---: | ---: | ---: | ---: | +| `in-process` | 1 | idle | 63.5 | 63.6 | 181.0 | 3.361 | 62.233 | +| `in-process` | 1 | load | 82.2 | 82.3 | 188.8 | 1.509 | 47.722 | +| `in-process` | 2 | idle | 63.1 | 63.1 | 190.8 | 2.903 | 45.778 | +| `in-process` | 2 | load | 88.1 | 88.1 | 195.9 | 2.140 | 45.017 | +| `in-process` | 3 | idle | 63.1 | 63.1 | 169.3 | 2.382 | 49.874 | +| `in-process` | 3 | load | 86.4 | 86.4 | 187.6 | 1.466 | 48.828 | +| `uds` | 1 | idle | 64.1 | 64.1 | 197.4 | 25.798 | 44.069 | +| `uds` | 1 | load | 92.9 | 92.9 | 208.3 | 16.182 | 43.818 | +| `uds` | 2 | idle | 63.5 | 63.5 | 178.4 | 2.947 | 39.582 | +| `uds` | 2 | load | 85.4 | 85.4 | 200.5 | 1.855 | 32.597 | +| `uds` | 3 | idle | 86.1 | 86.2 | 179.7 | 2.779 | 49.090 | +| `uds` | 3 | load | 76.9 | 76.9 | 181.8 | 1.056 | 43.143 | + +In every interval no slot was missed, and no status sample was an error or an answer about a target that no longer ran. Every acknowledged termination ended its target and was released, and each status target's final termination was effective. No I/O line was lost. Every refusal was `RESOURCE_UNAVAILABLE`, and no request that had to be refused ran. No sample lost the MCP connection, no execution was launched twice (the launches in the gateway's log match DevGuard's journal), no uncertain attempt was admitted again, and nothing stayed charged, the load's own attempts included. + +**Load.** DG-1's six consumers made 1,199 runs in the six load intervals, 196 to 202 in each, and every run succeeded: none exited with a nonzero status, failed to start or was uncertain, and admitted load covered 99.99% of the load intervals. Every consumer ran in every interval: `cargo` 22 to 26 times, `cpu` and `memory` 15 times each, `io` 58 or 59, `output` 59 and `slow-input` 27 or 28. + +**Host and footprint.** Every host sample of every interval was at memory pressure level 1 (normal), and swap peaked at 1,987 MiB. The execution owner, which is the gateway in `in-process` mode and the worker in `uds` mode, stayed within the `codespace` consumer's reservation of 150 mCPU, 512 MiB and 40 tasks in every interval: its peaks were 19.3 MiB of RSS and 16 threads, with a mean CPU of at most 2.5 mCPU. In `uds` mode the worker and the gateway together peaked at 30.6 MiB and 25 threads, with a mean CPU of at most 2.1 mCPU. The sampler does not count processes; the measured processes are the gateway in `in-process` mode, and the worker and the gateway in `uds` mode. This comparison is reported, not judged. + +**Rehearsal and afterwards.** The rehearsal's four intervals (30 seconds idle and 99 seconds of load per runner mode) passed with the same zero counts, a status p99 of at most 4.352 ms and an acknowledgement p99 of at most 0.464 ms. After both runs nothing was charged and no lease was held, every `codespace` instance in DevGuard's journal was retired, and the service still ran the release with process ID 23023; it did not restart during either run. @@ -129,11 +171,11 @@ The work order's accounting items, each checked against DevGuard's record rather | Item | Where it is shown | Result | | --- | --- | --- | | Requested, reserved, supported and applied values | [matrix](#report-matrix): DevGuard's journal record of every governed launch | matched in both runner modes, pipe and PTY | -| Headroom and control reservations | the consumer's reservation is subtracted from the work capacity: 5,500 to 5,350 mCPU, 12,616,466,432 to 12,079,595,520 bytes and 144 to 104 tasks when it was provisioned; matrix `shortage` refuses a request that cannot fit; the [control path](#report-control) compares the execution owner's footprint with the reservation | ⟨ACCT-FOOTPRINT⟩ | -| Pressure | [authority failure](#report-authority): after a stale host sample, new work stays closed until samples have been clear for 30 seconds, while running targets stay controllable; the [control path](#report-control): host pressure under DG-1's load; the service's own pressure behavior is DG-1's | ⟨ACCT-PRESSURE⟩ | +| Headroom and control reservations | the consumer's reservation is subtracted from the work capacity: 5,500 to 5,350 mCPU, 12,616,466,432 to 12,079,595,520 bytes and 144 to 104 tasks when it was provisioned; matrix `shortage` refuses a request that cannot fit; the [control path](#report-control) compares the execution owner's footprint with the reservation | reported: the execution owner stayed within the reservation in every control interval, at most 19.3 MiB, 16 threads and a mean of 2.5 mCPU | +| Pressure | [authority failure](#report-authority): after a stale host sample, new work stays closed until samples have been clear for 30 seconds, while running targets stay controllable; the [control path](#report-control): host pressure under DG-1's load; the service's own pressure behavior is DG-1's | passed; under the control load every host sample was normal | | No release on root exit alone while a descendant remains | faults `descendant`, pipe and PTY | passed | | Conservative accounting for an unknown state | faults `escape`, `stalled-observer` and `authority-restart`: the attempt stays charged as Suspect | passed | -| No replay after an uncertain launch | faults `authority-stalled`, `authority-restart` (one launch) and `worker-killed`; the control path's duplicate-launch count | passed; ⟨ACCT-DUPLICATES⟩ | +| No replay after an uncertain launch | faults `authority-stalled`, `authority-restart` (one launch) and `worker-killed`; the control path's duplicate-launch count | passed; none in the control path | | Cleanup after a definite no-start | matrix `no-helper` and `unusable-helper` (cancelled), `shortage` (denied), `exec-failed` (released when the scope ended); faults `helper-ends` (released as `no_helper_created`), `authority-stalled` and `worker-killed` (nothing held) | passed | @@ -193,6 +235,8 @@ The evidence directories are on the qualification host, under the DevGuard check | `csrg-u6-control-rehearsal-2026-10-14-ca306ee` | control rehearsal | `ac79024e237ee496b64f524696228e171a7161ccfde7652e02b023c67c25039f` | | `csrg-u6-control-2026-10-14-ca306ee` | control | `7706aac71c2f793dbc273b5c78f888dcc2af50269c0039d132b21c236b47e9be` | +The two control runs' directories carry the date 2026-10-14, which the command was given before it started at 23:20 UTC on 2026-10-13. + The checks before the freeze are kept too: | Directory | Commit | Result | `MANIFEST.json` SHA-256 | diff --git a/docs/ko/cs-rg-qualification-report.md b/docs/ko/cs-rg-qualification-report.md index 4d1df0a..ebe9c9c 100644 --- a/docs/ko/cs-rg-qualification-report.md +++ b/docs/ko/cs-rg-qualification-report.md @@ -64,8 +64,8 @@ | `control --rehearsal` | 2026-10-13 16:50–16:53 | 판정 불가. 예행이 절차보다 짧다는 사유뿐이며, 설계대로임 | | 회귀 단계, `all` | 2026-10-13 17:00–17:53 | Linux가 필요한 `linux-isolation` 말고 모든 단계 통과 | | 회귀 단계, `macos-core`와 `macos-fork-race` | 2026-10-13 17:57–18:01 | 통과 | -| `control --rehearsal` | ⟨CTRL-REH-WHEN⟩ | ⟨CTRL-REH-RESULT⟩ | -| `control` | ⟨CTRL-WHEN⟩ | ⟨CTRL-RESULT⟩ | +| `control --rehearsal` | 2026-10-13 23:20–23:24 | 판정 불가. 예행이 절차보다 짧다는 사유뿐이며, 설계대로임. 네 구간 모두 통과 | +| `control` | 2026-10-13 23:24부터 2026-10-14 03:33까지 | qualified: 두 runner 모드, 각각 세 번 반복, 열두 구간 모두 통과 | | Linux CI | 2026-10-13 23:25–23:42 | 통과: 전체 프로필의 모든 작업([실행 38484155990](https://github.com/novelKR/CodeSpace/actions/runs/38484155990)) | @@ -118,7 +118,49 @@ ## 제어 경로 가용성 -⟨CTRL-SECTION⟩ +`control`은 2026-10-13 23:24 UTC부터 2026-10-14 03:33 UTC까지 전체 절차를 실행했습니다. 바로 앞의 예행(23:20–23:24)은 예행이 절차보다 짧다는 사유 하나로만 판정 불가였습니다. runner 모드마다 10분 유휴 구간과 30분 이상의 부하 구간을 세 번 반복했고, 설치된 release를 상대로 DG-1의 cold 부하를 걸었습니다. 부하는 예정된 끝 뒤에 진행 중인 실행을 마치므로 부하 구간은 1,829–1,865초였습니다. 열두 구간과 여섯 반복이 모두 통과해 두 runner 모드 모두 qualification을 통과했고, 실행 전체도 통과했습니다. 서비스는 모든 반복 전후에 프로세스 ID 23023으로 그 release를 실행했습니다. + +목표는 `process_status` p99 500 ms 이하와 종료 확인 응답 p99 1초 이하입니다. 시간은 밀리초입니다. 구간 끝의 일정도 재므로 표본 수는 일정보다 하나, 두 대상의 status 표본은 둘까지 많을 수 있습니다. + +| runner 모드 | 반복 | 구간 | 초 | status p99 / 최대 | status 표본 / 일정 | 종료 확인 p99 | 종료 / 일정 | 판정 | +| --- | ---: | --- | ---: | ---: | ---: | ---: | ---: | --- | +| `in-process` | 1 | 유휴 | 600 | 2.150 / 45.195 | 1,201 / 1,200 | 0.539 | 30 / 30 | 통과 | +| `in-process` | 1 | 부하 | 1,857 | 0.463 / 17.616 | 3,714 / 3,712 | 0.633 | 93 / 92 | 통과 | +| `in-process` | 2 | 유휴 | 600 | 1.130 / 1.371 | 1,202 / 1,200 | 0.614 | 30 / 30 | 통과 | +| `in-process` | 2 | 부하 | 1,854 | 0.664 / 1.075 | 3,710 / 3,708 | 0.417 | 93 / 92 | 통과 | +| `in-process` | 3 | 유휴 | 600 | 1.107 / 1.404 | 1,202 / 1,200 | 0.481 | 30 / 30 | 통과 | +| `in-process` | 3 | 부하 | 1,829 | 1.871 / 3.067 | 3,660 / 3,658 | 0.723 | 91 / 91 | 통과 | +| `uds` | 1 | 유휴 | 600 | 1.418 / 2.801 | 1,200 / 1,200 | 0.741 | 30 / 30 | 통과 | +| `uds` | 1 | 부하 | 1,857 | 0.985 / 1.772 | 3,716 / 3,714 | 0.729 | 93 / 92 | 통과 | +| `uds` | 2 | 유휴 | 600 | 1.572 / 4.298 | 1,202 / 1,200 | 0.694 | 30 / 30 | 통과 | +| `uds` | 2 | 부하 | 1,865 | 1.076 / 1.765 | 3,732 / 3,730 | 0.804 | 93 / 93 | 통과 | +| `uds` | 3 | 유휴 | 600 | 4.922 / 12.753 | 1,202 / 1,200 | 0.693 | 30 / 30 | 통과 | +| `uds` | 3 | 부하 | 1,839 | 0.560 / 1.658 | 3,678 / 3,676 | 0.473 | 92 / 91 | 통과 | + +scope의 끝과 DevGuard의 해제는 종료 확인 응답과 따로 재고, I/O echo와 거부 지연은 정해진 목표가 없으므로 보고만 합니다. 하네스는 exited 상태까지의 시간을 요약하지 않으므로, 여기의 p99는 원시 표본에서 같은 nearest-rank 규칙으로 계산했습니다. + +| runner 모드 | 반복 | 구간 | exited p99 | 프로세스 그룹 소멸 p99 | 해제 p99 | I/O p99 | 거부 p99 | +| --- | ---: | --- | ---: | ---: | ---: | ---: | ---: | +| `in-process` | 1 | 유휴 | 63.5 | 63.6 | 181.0 | 3.361 | 62.233 | +| `in-process` | 1 | 부하 | 82.2 | 82.3 | 188.8 | 1.509 | 47.722 | +| `in-process` | 2 | 유휴 | 63.1 | 63.1 | 190.8 | 2.903 | 45.778 | +| `in-process` | 2 | 부하 | 88.1 | 88.1 | 195.9 | 2.140 | 45.017 | +| `in-process` | 3 | 유휴 | 63.1 | 63.1 | 169.3 | 2.382 | 49.874 | +| `in-process` | 3 | 부하 | 86.4 | 86.4 | 187.6 | 1.466 | 48.828 | +| `uds` | 1 | 유휴 | 64.1 | 64.1 | 197.4 | 25.798 | 44.069 | +| `uds` | 1 | 부하 | 92.9 | 92.9 | 208.3 | 16.182 | 43.818 | +| `uds` | 2 | 유휴 | 63.5 | 63.5 | 178.4 | 2.947 | 39.582 | +| `uds` | 2 | 부하 | 85.4 | 85.4 | 200.5 | 1.855 | 32.597 | +| `uds` | 3 | 유휴 | 86.1 | 86.2 | 179.7 | 2.779 | 49.090 | +| `uds` | 3 | 부하 | 76.9 | 76.9 | 181.8 | 1.056 | 43.143 | + +모든 구간에서 놓친 일정이 없었고, 오류이거나 이미 실행 중이 아닌 대상에 대한 status 표본도 없었습니다. 확인된 종료는 모두 대상을 끝냈고 해제되었으며, 각 status 대상의 마지막 종료도 효과가 있었습니다. 돌아오지 않은 I/O 줄은 없었습니다. 거부는 모두 `RESOURCE_UNAVAILABLE`이었고, 거부되어야 할 요청이 실행된 적은 없습니다. MCP 연결이 끊긴 표본, 두 번 실행된 실행(gateway 로그의 실행 수가 DevGuard journal과 같음), 다시 허용된 불확실한 attempt, 자원을 계속 차지한 attempt는 부하 자신의 attempt까지 포함해 하나도 없었습니다. + +**부하.** DG-1의 소비자 여섯은 부하 구간 여섯 개에서 1,199번(구간마다 196–202번) 실행했고 모두 성공했습니다. 0이 아닌 종료, 시작 실패, 불확실한 실행은 없었고, 허용된 부하가 부하 구간의 99.99%를 덮었습니다. 모든 소비자가 모든 구간에서 실행했습니다. `cargo`는 22–26번, `cpu`와 `memory`는 각각 15번, `io`는 58–59번, `output`은 59번, `slow-input`은 27–28번입니다. + +**호스트와 사용량.** 모든 구간의 호스트 표본이 메모리 pressure 수준 1(정상)이었고, swap은 최대 1,987 MiB였습니다. 실행 소유자(`in-process` 모드에서는 gateway, `uds` 모드에서는 worker)는 모든 구간에서 `codespace` 소비자의 예약 150 mCPU, 512 MiB, 40 tasks 안에 있었습니다. 최대값은 RSS 19.3 MiB와 thread 16개였고, CPU 평균은 최대 2.5 mCPU였습니다. `uds` 모드에서 worker와 gateway를 합쳐도 최대 30.6 MiB와 thread 25개, CPU 평균 최대 2.1 mCPU였습니다. 표본기는 프로세스 수를 세지 않으며, 측정한 프로세스는 `in-process` 모드의 gateway, `uds` 모드의 worker와 gateway입니다. 이 비교는 보고이며 판정이 아닙니다. + +**예행과 그 뒤.** 예행의 네 구간(runner 모드마다 유휴 30초와 부하 99초)도 같은 0의 기록으로 통과했고, status p99는 최대 4.352 ms, 종료 확인 응답 p99는 최대 0.464 ms였습니다. 두 실행이 끝난 뒤 자원을 차지한 것도 lease도 없었고, DevGuard journal의 `codespace` 인스턴스는 모두 retire되었으며, 서비스는 프로세스 ID 23023으로 그 release를 계속 실행했습니다. 두 실행 동안 서비스는 재시작하지 않았습니다. @@ -129,11 +171,11 @@ | 항목 | 근거 | 결과 | | --- | --- | --- | | 요청, 예약, 지원, 적용 값 | [기능 행렬](#report-matrix): 모든 관리 대상 실행에 대한 DevGuard journal 기록 | 두 runner 모드, pipe와 PTY 모두 일치 | -| headroom과 control 예약 | 소비자 예약은 work capacity에서 빠짐. 소비자를 준비할 때 5,500에서 5,350 mCPU로, 12,616,466,432에서 12,079,595,520바이트로, 144에서 104 tasks로 줄었음. matrix `shortage`는 들어가지 않는 요청을 거부함. [제어 경로](#report-control)는 실행 소유자의 사용량을 예약과 비교함 | ⟨ACCT-FOOTPRINT⟩ | -| pressure | [authority 장애](#report-authority): 오래된 호스트 표본 뒤에는 표본이 30초 동안 정상일 때까지 새 작업이 닫히고, 실행 중인 대상은 계속 제어됨. [제어 경로](#report-control): DG-1 부하에서의 호스트 pressure. 서비스 자체의 pressure 동작은 DG-1이 보임 | ⟨ACCT-PRESSURE⟩ | +| headroom과 control 예약 | 소비자 예약은 work capacity에서 빠짐. 소비자를 준비할 때 5,500에서 5,350 mCPU로, 12,616,466,432에서 12,079,595,520바이트로, 144에서 104 tasks로 줄었음. matrix `shortage`는 들어가지 않는 요청을 거부함. [제어 경로](#report-control)는 실행 소유자의 사용량을 예약과 비교함 | 보고: 실행 소유자는 모든 제어 구간에서 예약 안에 있었음. 최대 19.3 MiB, thread 16개, CPU 평균 2.5 mCPU | +| pressure | [authority 장애](#report-authority): 오래된 호스트 표본 뒤에는 표본이 30초 동안 정상일 때까지 새 작업이 닫히고, 실행 중인 대상은 계속 제어됨. [제어 경로](#report-control): DG-1 부하에서의 호스트 pressure. 서비스 자체의 pressure 동작은 DG-1이 보임 | 통과. 제어 부하에서 호스트 표본은 모두 정상 | | 자손이 남아 있으면 root 종료만으로 해제하지 않음 | faults `descendant`, pipe와 PTY | 통과 | | 알 수 없는 상태는 보수적으로 회계 | faults `escape`, `stalled-observer`, `authority-restart`: attempt가 Suspect로 자원을 차지한 채 남음 | 통과 | -| 불확실한 launch 뒤 재실행 없음 | faults `authority-stalled`, `authority-restart`(launch 한 번), `worker-killed`, 제어 경로의 중복 실행 수 | 통과. ⟨ACCT-DUPLICATES⟩ | +| 불확실한 launch 뒤 재실행 없음 | faults `authority-stalled`, `authority-restart`(launch 한 번), `worker-killed`, 제어 경로의 중복 실행 수 | 통과. 제어 경로에서도 없음 | | 시작하지 않았음이 확실한 경우의 정리 | matrix `no-helper`와 `unusable-helper`(cancelled), `shortage`(denied), `exec-failed`(scope가 끝나면 해제). faults `helper-ends`(`no_helper_created`로 해제), `authority-stalled`와 `worker-killed`(붙잡은 것 없음) | 통과 | @@ -193,6 +235,8 @@ Linux CI는 예약된 [실행 38484155990](https://github.com/novelKR/CodeSpace/ | `csrg-u6-control-rehearsal-2026-10-14-ca306ee` | 제어 예행 | `ac79024e237ee496b64f524696228e171a7161ccfde7652e02b023c67c25039f` | | `csrg-u6-control-2026-10-14-ca306ee` | 제어 | `7706aac71c2f793dbc273b5c78f888dcc2af50269c0039d132b21c236b47e9be` | +두 제어 실행의 디렉터리 날짜 2026-10-14는 명령이 2026-10-13 23:20 UTC에 시작하기 전에 받은 날짜입니다. + 고정 전의 점검도 보존합니다. | 디렉터리 | commit | 결과 | `MANIFEST.json` SHA-256 | diff --git a/docs/translations.json b/docs/translations.json index f3ae68e..1e679f7 100644 --- a/docs/translations.json +++ b/docs/translations.json @@ -183,8 +183,8 @@ "증거", "회귀와-동등성" ], - "source_sha256": "1c79724e4a76e3dade7ad31b88c5ae36937508be6625f8e2acd7e8b7b83745b2", - "translation_sha256": "850a2a4a01d73c402e922c96c76f0d823f267d39fb9f0d60e95d9dc33dbce636" + "source_sha256": "8b05c00a7ecd9d0960e1bfb69bf2c6fcb9d22686392c0b4264e2ca2d41b727a7", + "translation_sha256": "c344d8142f13a2acc3e9c3e3e511423b3da0b8da399418679302696ab3c62a59" }, { "id": "overview",