From 45c0d661021b1a51842b568c50d4c60c4bf67f70 Mon Sep 17 00:00:00 2001 From: Danil Silantyev Date: Wed, 30 Sep 2026 06:21:18 +0500 Subject: [PATCH] feat: a release of this repository Published at 0.0.84. Propose changes through this repository's issues and pull requests. --- .github/workflows/release.yml | 20 +++++++++++++---- SECURITY.md | 2 +- SUPPORT.md | 2 +- clippy.toml | 11 +++++----- crates/harness-runtime/src/catalog.rs | 19 +++++++++------- crates/harness-runtime/src/facts.rs | 4 +++- crates/harness-runtime/src/surfaces.rs | 22 ++++++++++++++++++- references/codex-baseline.json | 15 +++++++++---- scripts/evidence.py | 3 ++- .../home/agents/nddev-builder.toml | 22 +++++++++---------- 10 files changed, 83 insertions(+), 37 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6f08511..b4f44e4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,6 +10,11 @@ on: tags: - "[0-9]+.[0-9]+.[0-9]+" workflow_dispatch: + inputs: + tag: + description: release tag to rebuild, matching the crate version + required: true + type: string permissions: {} @@ -56,6 +61,12 @@ jobs: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + # A dispatched run releases the tag it was asked for, not whatever the + # dispatching branch happened to point at -- `github.ref_name` there + # is the branch, and `gh release create` would mint a tag named after + # it. On a tag push the input is empty and `github.ref_name` is the + # tag, so the expression is the tag either way. + ref: ${{ inputs.tag || github.ref_name }} persist-credentials: false - name: Set up Rust toolchain @@ -77,9 +88,9 @@ jobs: # -- only `python` is -- so running it on all three would fail there for a # reason that has nothing to do with the release. - name: Refuse a tag that does not match the crate version - if: matrix.os == 'ubuntu-latest' && github.event_name == 'push' + if: matrix.os == 'ubuntu-latest' env: - TAG: ${{ github.ref_name }} + TAG: ${{ inputs.tag || github.ref_name }} run: | version=$(cargo metadata --no-deps --format-version 1 \ | python3 -c 'import json,sys; print(next(p["version"] for p in json.load(sys.stdin)["packages"] if p["name"] == "codex-setup-system"))') @@ -170,7 +181,7 @@ jobs: - name: Publish one immutable release env: GH_TOKEN: ${{ github.token }} - TAG: ${{ github.ref_name }} + TAG: ${{ inputs.tag || github.ref_name }} run: | gh release create "$TAG" staging/* \ --repo "$GITHUB_REPOSITORY" \ @@ -196,6 +207,7 @@ jobs: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + ref: ${{ inputs.tag || github.ref_name }} persist-credentials: false - name: Collect the built binaries @@ -224,7 +236,7 @@ jobs: - name: Build and push both architectures id: push env: - TAG: ${{ github.ref_name }} + TAG: ${{ inputs.tag || github.ref_name }} run: | image="ghcr.io/$(echo "$GITHUB_REPOSITORY" | tr '[:upper:]' '[:lower:]')" docker buildx create --use --name release >/dev/null 2>&1 || docker buildx use release diff --git a/SECURITY.md b/SECURITY.md index 0fc37bf..5d4f3ba 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -27,5 +27,5 @@ before, and reports identity digests. It does not read credentials, does not send anything over the network in its configuration lifecycle, and records no secret values in its state. -A finding that breaks any of those four statements is in scope regardless of +A finding that breaks any of those statements is in scope regardless of severity. diff --git a/SUPPORT.md b/SUPPORT.md index 087bcda..d238240 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -64,7 +64,7 @@ newer. `scoped_projection_profiles` (`ADR-0125`) is the field this applies to, and it is omitted entirely when empty -- so a build that declares no scope satisfies an older checker by accident, and a build that declares one does not. -Two versions, two different answers, both measured: +Three versions, three different answers, all measured: | checker | result | | --- | --- | diff --git a/clippy.toml b/clippy.toml index 80610a8..409a3d5 100644 --- a/clippy.toml +++ b/clippy.toml @@ -13,11 +13,12 @@ doc-valid-idents = ["NDDev", "OpenNetwork", "OpenCode", "GitHub", "macOS", "Setu # `std::net` is refused outright: no command here opens a socket, and every v3 # phase declares `network_requirement: none`. # -# `std::process::Command` is refused everywhere except two `#[allow]` sites that -# name their reason: `harness_runtime::software` starts the product for `launch`, -# which is `runtime_external` by declaration, and `harness_runtime::probe` drives -# this binary's own executable from a test. An allowlist of two, both named, is a -# boundary; an allowlist nobody counted is a habit. +# `std::process::Command` is refused everywhere except two spawn sites that +# name their reason: `harness_runtime::software` builds the product command for +# `launch` and hands it to `exec` -- one site in two `#[allow]` attributes -- +# and `harness_runtime::probe` drives this binary's own executable from a test. +# An allowlist of two, both named, is a boundary; an allowlist nobody counted is +# a habit. # # Chosen over asserting a child count at run time: counting children portably # means /proc on Linux and something else on each of the other two, so that diff --git a/crates/harness-runtime/src/catalog.rs b/crates/harness-runtime/src/catalog.rs index 7ac6f2b..7054745 100644 --- a/crates/harness-runtime/src/catalog.rs +++ b/crates/harness-runtime/src/catalog.rs @@ -428,12 +428,14 @@ pub fn undescribed(setups: &[Setup]) -> Examined { /// Matched on the suffix so a fifth vendor works rather than being a silent /// miss. /// -/// **Two of the six that declare `plugin` have no manifest at all, and saying -/// "the rest" was wrong.** An OpenCode plugin is a JavaScript or TypeScript -/// module — `plugins/.js`, one file exporting functions — and a Pi -/// extension is a package. Neither carries `name` or `description` for a -/// product to read, so there is nothing here to check and no arm to add: a -/// module's identity is its filename and its behaviour is its exports. +/// **Two of the six plugin-kind projections have no manifest at all, and +/// saying "the rest" was wrong.** An OpenCode plugin is a JavaScript or +/// TypeScript module — `plugins/.js`, one file exporting functions — and +/// a Pi extension is a package (its `ProjectionKind::Package`, counted here +/// because it answers the same question). Neither carries `name` or +/// `description` for a product to read, so there is nothing here to check and +/// no arm to add: a module's identity is its filename and its behaviour is its +/// exports. /// /// That is a real difference rather than a gap, and it is written down because /// the first version of this comment claimed the manifest shapes covered every @@ -931,8 +933,9 @@ pub struct Setup { /// -- and those three are exactly what a consumer renders on the surface /// that precedes an install. `full-auto`'s description runs to 3312 /// characters on one harness and is safety context, not marketing copy; - /// `sources` is what `check_authored_keys.py` reads to source every key a - /// setup writes. The provenance chain ran through a file no digest held. + /// `sources` is what `check_authored_keys.py` -- not shipped in the + /// rendered trees -- reads to source every key a setup writes. The provenance + /// chain ran through a file no digest held. /// /// Proved rather than reasoned: a description was rewritten and the whole /// gate stayed clean. diff --git a/crates/harness-runtime/src/facts.rs b/crates/harness-runtime/src/facts.rs index 98eaa87..fab6c0b 100644 --- a/crates/harness-runtime/src/facts.rs +++ b/crates/harness-runtime/src/facts.rs @@ -158,7 +158,9 @@ pub struct Harness { /// /// Measured 2026-08-31 across the seven: twelve of them, in five harnesses. /// A person's keybindings under one, a plugin directory under another, and - /// a `select minimal` took both. + /// a `select minimal` took both. Recounted 2026-09-30: seventeen in the + /// same five harnesses -- claude's four further namespaces and pi's three + /// were added as the audits reached them. /// /// They stay **owned**, which is the point: a backup still captures them, /// the identity still hashes them so drift is visible, and `remove` still diff --git a/crates/harness-runtime/src/surfaces.rs b/crates/harness-runtime/src/surfaces.rs index 90d0cbe..91685d5 100644 --- a/crates/harness-runtime/src/surfaces.rs +++ b/crates/harness-runtime/src/surfaces.rs @@ -216,6 +216,22 @@ fn never_touch_is_disclaimed(harness: &Harness, baseline: &Value, found: &mut Ve if harness.native_namespaces.contains(name) { found.push(format!("{name:?} is claimed and disclaimed")); } + // When the block itself is absent, `disagreements` already names that + // one absence; repeating it once per disclaimed name adds noise, not + // information. + let recorded = baseline.get(BLOCK).is_none() + || baseline + .get("never_touch") + .and_then(Value::as_array) + .is_some_and(|list| list.iter().any(|entry| entry.as_str() == Some(name))); + if !recorded { + found.push(format!( + "{name:?} is disclaimed by {} and the baseline's never_touch \ + list does not record it -- a disclaimer without a measured \ + record is one a reader cannot check", + harness.provider_id + )); + } } } @@ -1504,7 +1520,11 @@ mod tests { "source": "this provider's own contract", }, ], - } + }, + // A disclaimer without a measured record is one a reader cannot + // check: every real baseline records the names its declaration + // disclaims at the top level, so the fixture does too. + "never_touch": TEST.never_touch, }) } diff --git a/references/codex-baseline.json b/references/codex-baseline.json index 005bfa8..d693db0 100644 --- a/references/codex-baseline.json +++ b/references/codex-baseline.json @@ -49,7 +49,7 @@ "shape": "file", "source": "https://learn.chatgpt.com/docs/config-file/config-reference; anchored literal measured in the pinned artifact by scripts/evidence.py", "evidence": "bytes", - "note": "MCP servers live here under [mcp_servers.]; a key inside a file is not a projection surface, so mcp is not declared Confirmed 2026-08-29 by `scripts/evidence.py`, which installs the pinned artifact into a temporary prefix and searches the installed bytes for each declared namespace joined to the configuration home the binary itself documents -- 11 occurrence(s) of `.codex/config.toml`. A namespace no product can own is searched alongside the real ones in the same pass and was absent, which is what separates a reading from a search that matches everything." + "note": "MCP servers live here under [mcp_servers.]; a key inside a file is not a projection surface, so mcp is not declared. Confirmed 2026-08-29 by `scripts/evidence.py`, which installs the pinned artifact into a temporary prefix and searches the installed bytes for each declared namespace joined to the configuration home the binary itself documents -- 11 occurrence(s) of `.codex/config.toml`. A namespace no product can own is searched alongside the real ones in the same pass and was absent, which is what separates a reading from a search that matches everything." }, { "path": "hooks.json", @@ -281,7 +281,7 @@ "version": "0.159.1", "verified_at": "2026-09-29T21:23:57+00:00" }, - "setup_catalogue_digest": "sha256:a366a07c80e41fd1980129989d0631a0028a95003f201410f73f8ee134d03c82", + "setup_catalogue_digest": "sha256:bc0430dc5b315ed0b0604d6a2c3c88e4b4112903d05786862cffb5c20477fa73", "previous_software_artifacts": { "command": "codex", "shape": "gzip-tar", @@ -330,7 +330,7 @@ "measured_at": "2026-09-27", "measured_against": "0.157.1", "evidence": "ran", - "source": "codex features list + codex doctor on the installed 0.157.1 build (the pin at that date; 0.158.0 now), 2026-09-27; registry source https://github.com/openai/codex/blob/rust-v0.157.1/codex-rs/features/src/lib.rs", + "source": "codex features list + codex doctor on the installed 0.157.1 build (the pin at that date), 2026-09-27; registry source https://github.com/openai/codex/blob/rust-v0.157.1/codex-rs/features/src/lib.rs", "registry_size": 150, "stable": 47, "stable_and_off_by_default": [ @@ -366,5 +366,12 @@ "control": "zzq-invented-surface-nobody-ships", "control_hits": 0, "method": "Every namespace this harness declares, global and scoped, searched as a fixed string in the artifact the current pin names, digest verified before reading; both the declared path and its last segment counted, because a product that composes a path by joining segments never spells the whole of it. A count here is a lower bound and not a routing proof -- what it answers is whether a surface vanished from the product under a version bump, which five of the seven took on 2026-09-02. The invented control was searched in the same run and found nowhere, so the search discriminates." - } + }, + "never_touch": [ + "auth.json", + "cache", + "history.jsonl", + "sessions", + "shell_snapshots" + ] } diff --git a/scripts/evidence.py b/scripts/evidence.py index 6df16e2..2744f92 100644 --- a/scripts/evidence.py +++ b/scripts/evidence.py @@ -670,7 +670,8 @@ def owned_surfaces_named_by_the_product(binary: str, prefix: Path, info: dict) - **It reports and never promotes.** Writing an `evidence` value still takes somebody recording what they measured, and `tools/derive_evidence.py --check` - refuses a value stronger than a row's own prose supports. Two instruments + -- which is not shipped in this tree -- refuses a + value stronger than a row's own prose supports. Two instruments with one opinion between them would be one instrument. **Both inputs are asked of their owner rather than copied.** The namespaces diff --git a/setups/nddev-builder/home/agents/nddev-builder.toml b/setups/nddev-builder/home/agents/nddev-builder.toml index 5338236..ff7b329 100644 --- a/setups/nddev-builder/home/agents/nddev-builder.toml +++ b/setups/nddev-builder/home/agents/nddev-builder.toml @@ -69,9 +69,9 @@ what it owns, ask the binary: `codex-setup-system provider-info`. ## Before you ship one -- **The surface is declared, so the component is a promise.** Every kind this provider declares is a promise of a rollback. A component written to a path the declaration does not carry is installed by nobody and removed by nobody. -- **Name it once.** Where the product derives identity from the directory or the filename, the frontmatter `name` is either redundant or a second place to be wrong. Keep them equal. -- **Read it back.** After an install, look at the file where the product reads it, not at the step that put it there. +- **The surface is declared, so the component is a promise.** Every kind this provider declares is a promise of a rollback. A component written to a path the declaration does not carry is installed by nobody and removed by nobody. +- **Name it once.** Where the product derives identity from the directory or the filename, the frontmatter `name` is either redundant or a second place to be wrong. Keep them equal. +- **Read it back.** After an install, look at the file where the product reads it, not at the step that put it there. ## Command @@ -96,7 +96,7 @@ what it owns, ask the binary: `codex-setup-system provider-info`. ## The same file on the other harnesses -Generated from the same rows as the section above, for every harness in this estate that routes this kind. `—` means the product's own reference does not name the field, and **dropped** means it names it as one it accepts and does not act on. +Generated from the same rows as the section above, for every harness in this estate that describes this kind the same way. A harness that routes the kind another way is absent rather than approximated. `—` means the product's own reference does not name the field, and **dropped** means it names it as one it accepts and does not act on. | field | `claude` | `codex` | `pi` | `opencode` | `cursor` | `antigravity` | |---|---|---|---|---|---|---| @@ -115,9 +115,9 @@ Generated from the same rows as the section above, for every harness in this est ## Before you ship one -- **The surface is declared, so the component is a promise.** Every kind this provider declares is a promise of a rollback. A component written to a path the declaration does not carry is installed by nobody and removed by nobody. -- **Name it once.** Where the product derives identity from the directory or the filename, the frontmatter `name` is either redundant or a second place to be wrong. Keep them equal. -- **Read it back.** After an install, look at the file where the product reads it, not at the step that put it there. +- **The surface is declared, so the component is a promise.** Every kind this provider declares is a promise of a rollback. A component written to a path the declaration does not carry is installed by nobody and removed by nobody. +- **Name it once.** Where the product derives identity from the directory or the filename, the frontmatter `name` is either redundant or a second place to be wrong. Keep them equal. +- **Read it back.** After an install, look at the file where the product reads it, not at the step that put it there. ## Hook @@ -155,7 +155,7 @@ Generated from the same rows as the section above, for every harness in this est ## The same file on the other harnesses -Generated from the same rows as the section above, for every harness in this estate that routes this kind. `—` means the product's own reference does not name the field, and **dropped** means it names it as one it accepts and does not act on. +Generated from the same rows as the section above, for every harness in this estate that describes this kind the same way. A harness that routes the kind another way is absent rather than approximated. `—` means the product's own reference does not name the field, and **dropped** means it names it as one it accepts and does not act on. | field | `codex` | `grok` | `antigravity` | |---|---|---|---| @@ -178,9 +178,9 @@ Generated from the same rows as the section above, for every harness in this est ## Before you ship one -- **The surface is declared, so the component is a promise.** Every kind this provider declares is a promise of a rollback. A component written to a path the declaration does not carry is installed by nobody and removed by nobody. -- **Name it once.** Where the product derives identity from the directory or the filename, the frontmatter `name` is either redundant or a second place to be wrong. Keep them equal. -- **Read it back.** After an install, look at the file where the product reads it, not at the step that put it there. +- **The surface is declared, so the component is a promise.** Every kind this provider declares is a promise of a rollback. A component written to a path the declaration does not carry is installed by nobody and removed by nobody. +- **Name it once.** Where the product derives identity from the directory or the filename, the frontmatter `name` is either redundant or a second place to be wrong. Keep them equal. +- **Read it back.** After an install, look at the file where the product reads it, not at the step that put it there. # The Commands This Program Answers