From 91481fd5396e76104303037027035c02461eec04 Mon Sep 17 00:00:00 2001 From: Danil Silantyev Date: Tue, 29 Sep 2026 18:54:02 +0500 Subject: [PATCH] feat: a release of this repository Published at 0.0.82. Propose changes through this repository's issues and pull requests. --- README.md | 5 +-- SUPPORT.md | 11 ++++--- crates/codex-setup-system/src/main.rs | 6 ++-- crates/harness-runtime/src/catalog.rs | 2 +- crates/harness-runtime/src/facts.rs | 4 +-- crates/harness-runtime/src/lib.rs | 5 +-- crates/harness-runtime/src/software.rs | 2 +- crates/harness-runtime/src/surfaces.rs | 6 +++- references/codex-baseline.json | 6 ++-- scripts/evidence.py | 2 +- setups/full-auto/home/config.toml | 10 +++--- .../home/agents/nddev-builder.toml | 33 ++++++++++--------- setups/nddev-builder/home/config.toml | 10 +++--- 13 files changed, 58 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 7d497f3..1afedbf 100644 --- a/README.md +++ b/README.md @@ -139,8 +139,9 @@ powershell -ExecutionPolicy Bypass -File install.ps1 ``` Each fetches the release artifact for this platform, checks it against the -release's own `SHA256SUMS`, and places it at a predictable path: `~/.local/bin` -on Linux and macOS, `%LOCALAPPDATA%\Programs` on Windows. Neither needs +release's own `SHA256SUMS`, and places it at a predictable path: +`~/.local/bin/codex-setup-system` on Linux and macOS, +`%LOCALAPPDATA%\Programs\codex-setup-system\codex-setup-system.exe` on Windows. Neither needs privilege and neither registers anything anywhere. Somewhere else instead: diff --git a/SUPPORT.md b/SUPPORT.md index 70dfdd6..087bcda 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -167,8 +167,6 @@ Configuration home as the product documents it: `~/.codex`. | `prompts` | `command` | [source](https://learn.chatgpt.com/docs/custom-prompts) | | `agents` | `agent` | [source](https://github.com/openai/codex/blob/rust-v0.151.0/codex-rs/agent-roles/src/discovery.rs) -- routing measured by running the 0.151.0 binary against a temporary CODEX_HOME | -A path routing no component kind is owned so a setup can carry it; -nothing compiles a component to it. ### A second target: `target_scope: user_root` @@ -188,9 +186,12 @@ by a restore. ### A second target: `target_scope: project` -Rooted at `project root`, which is not the configuration home -above. A consumer reaches it by naming the scope on the request, and -every path below is relative to that root. +This scope's target is the workspace root rather than the +configuration home above; the scope record names its anchor +`project root`. A consumer reaches it by naming the scope on +the request, and every path below is relative to the workspace +root -- where the product owns a directory there, that directory +is part of the path. | Path | Component kinds routed here | Decided by | | --- | --- | --- | diff --git a/crates/codex-setup-system/src/main.rs b/crates/codex-setup-system/src/main.rs index 59828b9..50bf419 100644 --- a/crates/codex-setup-system/src/main.rs +++ b/crates/codex-setup-system/src/main.rs @@ -220,10 +220,10 @@ pub const CODEX: Harness = Harness { // who else reads it is a question about behaviour rather than routing. // The `user_root` skill question has the same shape. ], - // One scope. Codex's project surfaces live under `.codex/` in a workspace, which is a - // different root rather than a second scope of this target. + // Two scopes. Codex's project surfaces live under the workspace root -- + // `AGENTS.md` at it, `.codex/hooks.json` keeping its product-owned parent -- + // and the user-level `.agents` root is a third home entirely. // - // Empty rather than absent: a harness that owns one target says so. // The one root in this estate that belongs to a convention rather than to a // product. `learn.chatgpt.com/docs/build-skills` names `$HOME/.agents/skills` // as the user-level skills directory -- a *sibling* of `~/.codex`, not a diff --git a/crates/harness-runtime/src/catalog.rs b/crates/harness-runtime/src/catalog.rs index 2bb51c0..7ac6f2b 100644 --- a/crates/harness-runtime/src/catalog.rs +++ b/crates/harness-runtime/src/catalog.rs @@ -107,7 +107,7 @@ pub struct CatalogComponentRef { /// per-harness: `minimal` means the same thing to someone moving from codex to /// pi as it did before they moved. /// -/// A harness may carry more -- cursor and antigravity each ship a builder +/// A harness may carry more -- each of the seven also ships an `nddev-builder` /// toolkit -- but never fewer. pub const UNIVERSAL_SETUPS: &[&str] = &["baseline", "full-auto", "minimal"]; diff --git a/crates/harness-runtime/src/facts.rs b/crates/harness-runtime/src/facts.rs index e5a2dff..98eaa87 100644 --- a/crates/harness-runtime/src/facts.rs +++ b/crates/harness-runtime/src/facts.rs @@ -58,8 +58,8 @@ pub struct Harness { /// and one that can execute code the chosen setup never carried. /// /// A fact rather than a conclusion, carrying how it was established, because - /// the five that are complete are not equally well established: three were - /// measured by asking the product what it resolved, one by making it write, + /// the five that are complete are not equally well established: two were + /// measured by asking the product what it resolved, two by making it write, /// and one rests on a vendor page because no credential-free command of that /// product writes its home. pub launch_binding: LaunchBinding, diff --git a/crates/harness-runtime/src/lib.rs b/crates/harness-runtime/src/lib.rs index 4a583d7..94a600f 100644 --- a/crates/harness-runtime/src/lib.rs +++ b/crates/harness-runtime/src/lib.rs @@ -270,8 +270,9 @@ fn print_help(harness: &Harness) { println!("something to return to. The pool rolls, so a long series of changes"); println!("eventually evicts the oldest: `hold` keeps one until `release` lets"); println!("it go, which is how a baseline survives more captures than the pool."); - println!("Over the wire, install and replace arrive as a bundle and refuse --"); - println!("this build reads setups from its own catalog."); + println!("Over the wire a bundle arrives with install or replace, and this"); + println!("build applies it; this human surface refuses bundles and reads"); + println!("setups from its own catalog."); } #[cfg(test)] diff --git a/crates/harness-runtime/src/software.rs b/crates/harness-runtime/src/software.rs index 92c3a4a..fdf0d50 100644 --- a/crates/harness-runtime/src/software.rs +++ b/crates/harness-runtime/src/software.rs @@ -417,7 +417,7 @@ pub(crate) fn launch( // from one field here. Guessing produced a refusal that told cursor // callers *"this build installs no software"* -- false, it installs // and removes it, and the actual reason is that the product follows - // its variable for one of the eight surfaces this provider owns. + // its variable for one of the seven surfaces this provider owns. format!( "{} does not declare launch: {}", harness.provider_id, diff --git a/crates/harness-runtime/src/surfaces.rs b/crates/harness-runtime/src/surfaces.rs index 2e16621..90d0cbe 100644 --- a/crates/harness-runtime/src/surfaces.rs +++ b/crates/harness-runtime/src/surfaces.rs @@ -227,7 +227,11 @@ fn never_touch_is_disclaimed(harness: &Harness, baseline: &Value, found: &mut Ve /// other direction: a namespace declared, owned, routing nothing, and written /// to by nobody. /// -/// Three of them exist: claude's `rules`, opencode's `tui.json`, pi's `themes`. +/// Seventeen of them exist -- claude's `rules`, `workflows`, `output-styles`, +/// `routines` and `themes`; grok's `sandbox.toml`, `workflows`, `rules`, +/// `commands`, `personas` and `roles`; pi's `APPEND_SYSTEM.md`, `SYSTEM.md` and +/// `themes`; antigravity's `antigravity-cli/keybindings.json` and +/// `antigravity-cli/plugins`; opencode's `tui.json`. /// Each is defensible -- claude's row explains that `instruction` already /// routes to `CLAUDE.md` and the namespace is owned so a setup *could* carry a /// rule -- and the point is not to remove them. It is that the answer should be diff --git a/references/codex-baseline.json b/references/codex-baseline.json index 918a0b1..e79b650 100644 --- a/references/codex-baseline.json +++ b/references/codex-baseline.json @@ -223,7 +223,7 @@ "file": "config.toml", "grammar": "toml", "accepts_comments": true, - "note": "TOML, so `#` comments are part of the grammar. No JSON schema is possible for it and none is expected; the setups are checked by parsing instead.", + "note": "TOML, so `#` comments are part of the grammar. A JSON schema cannot be embedded in it, and none was expected when this was measured; the setups are checked by parsing instead.\n\n**Corrected 2026-09-29: the vendor does publish one.** A `config-schema.json` asset ships with each release and is recorded under `configuration_schema`; a TOML file carries no `$schema` line, which is what this sentence meant by 'possible', and the schema still answers whether a written key is a key the product has.", "measured_at": "2026-08-28" }, "projection_basis": {} @@ -281,7 +281,7 @@ "version": "0.158.0", "verified_at": "2026-09-28T14:26:56+00:00" }, - "setup_catalogue_digest": "sha256:38ea677a1b5ebbb65bd1347ac5e3ae22778eee45a2a3f8361f943c08500319a4", + "setup_catalogue_digest": "sha256:a366a07c80e41fd1980129989d0631a0028a95003f201410f73f8ee134d03c82", "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 pinned version), 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; 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", "registry_size": 150, "stable": 47, "stable_and_off_by_default": [ diff --git a/scripts/evidence.py b/scripts/evidence.py index 36eb96e..6df16e2 100644 --- a/scripts/evidence.py +++ b/scripts/evidence.py @@ -416,7 +416,7 @@ def remove_the_program( # Capture what the *same exposed command* says before removal. Not every # vendor puts its release into `--version`: Pi's two Windows standalone # builds both answer `0.0.0`, while their archive digests and provider - # manifests correctly distinguish 0.84.3 from 0.84.4. Requiring the + # manifests correctly distinguish 0.85.1 from 0.87.1. Requiring the # expected version here tests the vendor's string, not whether removing # an inactive tree moved our command. launch_before = run_text( diff --git a/setups/full-auto/home/config.toml b/setups/full-auto/home/config.toml index 167f0b3..d0ef4dc 100644 --- a/setups/full-auto/home/config.toml +++ b/setups/full-auto/home/config.toml @@ -14,8 +14,9 @@ web_search = "live" # Every capability this build ships as `Stage::Stable` and leaves off, minus # one deliberate exception. Measured rather than chosen: the 0.157.1 feature # registry carries 150 specs, 47 of them stable, and exactly four of those are -# `default_enabled: false` (`codex features list` on the pinned build, -# 2026-09-27). Three are enabled below; the fourth, `secret_auth_storage`, is +# `default_enabled: false` (`codex features list` on the 0.157.1 build, +# 2026-09-27; the pin has since moved to 0.158.0). Three are enabled below; the +# fourth, `secret_auth_storage`, is # not: it moves CLI auth into an encrypted local-secrets backend, is # `default_enabled` on Windows only by design (the 2560-byte Credential Manager # blob limit does not exist here), and flipping a credential store is outside @@ -31,8 +32,9 @@ web_search = "live" # which set nothing at all on the 0.151.0 build, where `ToolsToml` had three # members, no `view_image`, and serde carried no `deny_unknown_fields`, so the # key parsed, was ignored, and left the file claiming a capability it never -# turned on. The schema has since changed twice: `ToolsToml` at this pin is -# `{ web_search, view_image }` *with* `deny_unknown_fields`, so the old line +# turned on. The schema has since changed twice: `ToolsToml` at the 0.157.1 +# measurement is `{ web_search, view_image }` *with* `deny_unknown_fields`, so +# the old line # now parses and sets a real key -- and would still change nothing, because # `view_image` is `default_enabled: true`. # diff --git a/setups/nddev-builder/home/agents/nddev-builder.toml b/setups/nddev-builder/home/agents/nddev-builder.toml index 25d68cf..5338236 100644 --- a/setups/nddev-builder/home/agents/nddev-builder.toml +++ b/setups/nddev-builder/home/agents/nddev-builder.toml @@ -436,7 +436,9 @@ Never change the running agent's active configuration in place. | comments | **parse** | | home moved by | `CODEX_HOME` | -TOML, so `#` comments are part of the grammar. No JSON schema is possible for it and none is expected; the setups are checked by parsing instead. +TOML, so `#` comments are part of the grammar. A JSON schema cannot be embedded in it, and none was expected when this was measured; the setups are checked by parsing instead. + +**Corrected 2026-09-29: the vendor does publish one.** A `config-schema.json` asset ships with each release and is recorded under `configuration_schema`; a TOML file carries no `$schema` line, which is what this sentence meant by 'possible', and the schema still answers whether a written key is a key the product has. ## The same question on the other harnesses @@ -452,8 +454,7 @@ TOML, so `#` comments are part of the grammar. No JSON schema is possible for it **A comment is not a stylistic choice.** In a strict-JSON file a `//` is a parse error, and the product does not start rather than starting -without your setting. Two of the seven take comments; the rest do not, -and one of those takes them at two spellings of the same file. +without your setting. Three of the seven take comments; the rest do not, and one of those takes them at two spellings of the same file. ## Before you write one @@ -468,7 +469,7 @@ and one of those takes them at two spellings of the same file. - **A value here may not be the effective one.** Where an administrator layer exists it clamps everything below it, so a setup can install, verify and restore cleanly on a managed machine and change nothing. - the `nddev-surfaces` prompt, and `codex-setup-system provider-info`, records which layers this product has and + The `nddev-surfaces` prompt and `codex-setup-system provider-info` record which layers this product has and what was searched for the ones it does not. @@ -503,10 +504,10 @@ This row stays `page` because **a path built by joining a directory to a name at | `pi` | `AGENTS.md` | file | **They are not interchangeable, and the difference is not only the -name.** One of the seven takes a *directory* of rules rather than a +name.** Two of the seven take a *directory* of rules rather than a single document, so a file moved between the two is not a rename. -**Some products read a neighbour's.** the `nddev-surfaces` prompt, and `codex-setup-system provider-info`, records +**Some products read a neighbour's.** The `nddev-surfaces` prompt and `codex-setup-system provider-info` record every such cross-read this estate has measured, on the declined rows: a file written for one product can change what a second one sees, and removing a setup can change what a third one sees. That is a property @@ -550,15 +551,16 @@ is preserved, and re-applying identical bytes is a no-op. as a mid-apply surprise. -# The second target this harness owns +# The scoped targets this harness owns ## `target_scope: user_root`, rooted at `~/.agents` **`~/.agents` is not this product's configuration home.** It is a different target, reached by a consumer naming the scope on the -request, and every path below is relative to that root rather than -to the home -- writing the root into the path again would nest it -twice, which is a mistake this estate has made and shipped. +request, and every path below is relative to that root rather +than to the home -- writing the root into the path again would +nest it twice, which is a mistake this estate has made and +shipped. | path | routes | decided by | exercised by | |---|---|---|---| @@ -594,11 +596,12 @@ into a slot here and never reverted out of one. ## `target_scope: project`, rooted at `project root` -**`project root` is not this product's configuration home.** It is a -different target, reached by a consumer naming the scope on the -request, and every path below is relative to that root rather than -to the home -- writing the root into the path again would nest it -twice, which is a mistake this estate has made and shipped. +**This scope's target is the workspace root** (the record names +its anchor `project root`), not this product's configuration home. +It is a different target, reached by a consumer naming the +scope on the request, and every path below is relative to the +workspace root -- a product-owned directory stays part of the +path. | path | routes | decided by | exercised by | |---|---|---|---| diff --git a/setups/nddev-builder/home/config.toml b/setups/nddev-builder/home/config.toml index 167f0b3..d0ef4dc 100644 --- a/setups/nddev-builder/home/config.toml +++ b/setups/nddev-builder/home/config.toml @@ -14,8 +14,9 @@ web_search = "live" # Every capability this build ships as `Stage::Stable` and leaves off, minus # one deliberate exception. Measured rather than chosen: the 0.157.1 feature # registry carries 150 specs, 47 of them stable, and exactly four of those are -# `default_enabled: false` (`codex features list` on the pinned build, -# 2026-09-27). Three are enabled below; the fourth, `secret_auth_storage`, is +# `default_enabled: false` (`codex features list` on the 0.157.1 build, +# 2026-09-27; the pin has since moved to 0.158.0). Three are enabled below; the +# fourth, `secret_auth_storage`, is # not: it moves CLI auth into an encrypted local-secrets backend, is # `default_enabled` on Windows only by design (the 2560-byte Credential Manager # blob limit does not exist here), and flipping a credential store is outside @@ -31,8 +32,9 @@ web_search = "live" # which set nothing at all on the 0.151.0 build, where `ToolsToml` had three # members, no `view_image`, and serde carried no `deny_unknown_fields`, so the # key parsed, was ignored, and left the file claiming a capability it never -# turned on. The schema has since changed twice: `ToolsToml` at this pin is -# `{ web_search, view_image }` *with* `deny_unknown_fields`, so the old line +# turned on. The schema has since changed twice: `ToolsToml` at the 0.157.1 +# measurement is `{ web_search, view_image }` *with* `deny_unknown_fields`, so +# the old line # now parses and sets a real key -- and would still change nothing, because # `view_image` is `default_enabled: true`. #