|
| 1 | +# Unarmed public Unicode pilot: revision v4 of the unreleased evidence protocol |
| 2 | + |
| 3 | +This is a review candidate. No publication or run is authorized by these files. |
| 4 | +The source remains `62a3294181556f17db863c9016524fa3068a374b`; original C tests, |
| 5 | +config values, provider selectors, flags and guest settings retain their reviewed |
| 6 | +profile. The setup-base gate is deliberately stale and must be refreshed to the |
| 7 | +then-verified feature-branch tip after review. Do not change the experiment pin. |
| 8 | + |
| 9 | +Both matrix jobs reject `github.run_attempt != 1` before checkout, and reject |
| 10 | +reruns again in the host, container, installer and stage shell boundaries. A |
| 11 | +rerun requires a new separately reviewed request. The initial launch record is |
| 12 | +still unapproved and the request manifest is still unarmed. |
| 13 | + |
| 14 | +The installer uses strict `apt-get --error-on=any update` and requires exactly |
| 15 | +one matching InRelease for each of the three reviewed suites. All three exact |
| 16 | +hashes are checked after apt's signature and default validity/time checks. No |
| 17 | +insecure/trusted/freshness/TLS bypass is added. The earliest expiry is updates |
| 18 | +metadata on 2026-10-09 at 14:11:18 UTC. Expiry must fail and return for review. |
| 19 | + |
| 20 | +Docker CID bytes are preserved as Docker writes them: exactly 64 lowercase hex |
| 21 | +characters with no newline. The incorrect older newline fixture is retained as |
| 22 | +a negative control. No whitespace normalization changes the recorded file. |
| 23 | + |
| 24 | +Image pull and the full container lifetime are supervised. Installation, |
| 25 | +configuration, build, no-op, ownership audit, guest and parser have individual |
| 26 | +admission/live/terminal samples and explicit native/supervisor/cleanup/interruption |
| 27 | +statuses. Cleanup targets the owned process group even when its leader exits |
| 28 | +first. Docker cleanup is bounded, records errors and fails on uncertainty. The |
| 29 | +host separately checks complete output/evidence caps at termination. The output |
| 30 | +cap stays 1.25 GiB, evidence cap 128 MiB, minimum free disk 1 GiB and minimum |
| 31 | +available memory 512 MiB. Admission retains 4 GiB disk and 6 GiB available memory; |
| 32 | +the initial host admission requires 10 GiB disk. A small evidence reserve covers |
| 33 | +final status writes. Cap measurements use allocated filesystem bytes. Every |
| 34 | +measurement, parse, clock read and record write checks its own return status; |
| 35 | +partial numeric output from a failed command is rejected even when Bash errexit |
| 36 | +is disabled. No evidence is truncated to produce a pass. |
| 37 | + |
| 38 | +## Proposed run and time commitment |
| 39 | + |
| 40 | +The setup commit adds both this workflow and the unarmed manifest. It can trigger |
| 41 | +one request-only run, which is expected to reject the setup push and start no |
| 42 | +member. After that expected outcome is verified, a separate manifest-only |
| 43 | +activation commit can trigger one request job and the sequential C/R pair. |
| 44 | +There is no skip directive or hidden trigger bypass. Approval must cover both |
| 45 | +commits, both possible workflow runs and the specified public logs. |
| 46 | + |
| 47 | +The request job has a 10-minute ceiling in each run. Each member has a proposed |
| 48 | +120-minute GitHub job ceiling. Thus the complete planned setup-plus-activation |
| 49 | +maximum is 260 standard-runner minutes: 10 + 10 + 120 + 120. It is not a measured |
| 50 | +duration. The verified prospective base had no pre-existing workflow files; the |
| 51 | +head and workflow inventory must be rechecked before publication. |
| 52 | + |
| 53 | +The internal soft job deadline is 115 minutes from the first workflow step, |
| 54 | +leaving a five-minute tail relative to that step's 120-minute window. Platform |
| 55 | +setup or cancellation is outside this internal timer; a hard runner cancellation |
| 56 | +remains a failed attempt. Pull is allowed at most 10 minutes. The container |
| 57 | +aggregate is at most 100 minutes and must end at least three minutes before the |
| 58 | +soft job deadline. Native stage allowances are installation 20, configuration 10, |
| 59 | +build 30, no-op 10, ownership 5, guest supervision 17 and parser 5 minutes. |
| 60 | + |
| 61 | +The build allowance is over four times the recorded 6m54s native Rust build, |
| 62 | +while package/network/CI performance remains unmeasured. Stage ceilings share |
| 63 | +the aggregate budget; they are not promises that every stage can consume its |
| 64 | +maximum. A stage overrun fails the pilot instead of changing its work. |
| 65 | + |
| 66 | +The original KUnit timeout remains 300 seconds. The original QEMU outer timeout |
| 67 | +remains exactly 900 seconds with a 10-second kill grace. Its separate supervisor |
| 68 | +allowance is 1,020 seconds, so a 900-second stage wrapper cannot preempt the grace |
| 69 | +or postchecks. Before starting the guest, a recorded admission requires at least |
| 70 | +1,560 seconds remaining in both the container and soft job budgets: 1,020 guest |
| 71 | +supervision + 300 parser + 60 cleanup + 180 evidence seconds. Insufficient budget |
| 72 | +stops before guest launch. No guest clock, workload or original timeout is tuned. |
| 73 | + |
| 74 | +The unchanged original Python KUnit parser and the new strict observer both run. |
| 75 | +Their outputs are written directly, with both statuses and nonempty required |
| 76 | +results checked. There is no tee pipeline whose failure can be lost. |
| 77 | + |
| 78 | +## Complete text evidence |
| 79 | + |
| 80 | +`Evidence.pm` is the exact ordered role catalog. `emit-evidence.pl` emits only |
| 81 | +those text files using `UEV3` framing. It records file identity, UTF-8 byte count, |
| 82 | +SHA256, ordered text chunks and an ordered manifest digest. No binary image, |
| 83 | +object, archive or encoded binary payload is emitted. |
| 84 | + |
| 85 | +The envelope includes full raw stage logs, exact command arrays, resource samples, |
| 86 | +status/cleanup records, source/config/tool/apt evidence, complete before/after |
| 87 | +output-tree hash and symlink inventories, original C command files and object |
| 88 | +identities, the complete selected normalizer command sidecar, final ELF-owner |
| 89 | +observations, raw serial, strict observer output and |
| 90 | +unchanged upstream parser JSON. The selected normalizer command's source/required |
| 91 | +flags are checked and its exact bytes are bound to the output-tree hash inventory; |
| 92 | +C and Rust normalizer command files are not required to be identical. |
| 93 | +Empty diagnostic files are allowed only for |
| 94 | +explicitly designated stderr/cleanup roles. Any missing file, cap overrun or |
| 95 | +encoding/emission failure prevents success. Failures remain visible in the logs. |
| 96 | + |
| 97 | +## Read-only download and comparison |
| 98 | + |
| 99 | +After an authorized run, first verify its repository, event, feature branch, |
| 100 | +approved activation commit, attempt 1, workflow identity and the two unique jobs |
| 101 | +`unicode-c` and `unicode-rust` through authenticated read-only GitHub metadata. |
| 102 | +Both jobs must be terminal successes. Preserve the fetched job text exactly as |
| 103 | +UTF-8 and hash those saved files before comparison. Populate the example receipt |
| 104 | +from that verified metadata and those local file hashes; never populate it from |
| 105 | +success text in the logs themselves. |
| 106 | + |
| 107 | +When a connector returns decoded text, the preserved bytes are the UTF-8 encoding |
| 108 | +of that decoded text. They are not claimed to be original HTTP response bytes. |
| 109 | +If the connector omits or truncates text, obtain a complete supported read or |
| 110 | +stop; do not reconstruct or assume missing evidence. Retain the download receipt |
| 111 | +and original saved text with the existing approved backup process. |
| 112 | + |
| 113 | +Run: |
| 114 | + |
| 115 | + perl compare-logs.pl trusted-download-receipt.json C-job.log Rust-job.log |
| 116 | + |
| 117 | +The comparator checks the download hashes before recognizing optional GitHub |
| 118 | +timestamp prefixes. It then requires one uniquely ordered complete envelope and |
| 119 | +one successful terminal record, verifies every payload/manifest digest and exact |
| 120 | +named role, and checks the substantive stage, config, source, tool, command, |
| 121 | +ownership, original-case and upstream-JSON evidence. C/R original C objects, |
| 122 | +complete commands, package/tool closures and config values must match, except |
| 123 | +the one normalizer selector. Full output and symlink inventories must remain |
| 124 | +identical through each member's no-op, audit and guest. |
| 125 | + |
| 126 | +This validates the evidence contract for logs obtained from the verified run. |
| 127 | +An offline parser cannot authenticate an invented download receipt or distinguish |
| 128 | +a fully fabricated, internally consistent report from its purported origin. |
| 129 | +The GitHub metadata/download verification is therefore a required trust boundary. |
| 130 | +The positive synthetic fixtures intentionally exercise the protocol; they are |
| 131 | +never evidence of a kernel build or runtime pass. |
| 132 | + |
| 133 | +Even a complete passing envelope retains observations and hashes, not final ELF |
| 134 | +bytes. It remains a provisional logs-only C/R result. Independent later binary |
| 135 | +reinspection requires separately approved bounded artifacts; no artifact upload |
| 136 | +or binary-through-logs substitute is included here. |
0 commit comments