Skip to content

Commit 7a7515e

Browse files
committed
Gate updates on enabled feature health
1 parent 8bed43e commit 7a7515e

19 files changed

Lines changed: 204 additions & 142 deletions

.github/workflows/upstream-build-app.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ on:
1010
- scripts/patch-linux-window-ui.js
1111
- scripts/patch-linux-window-ui.test.js
1212
- scripts/patches/**
13-
- linux-features/remote-mobile-control/**
14-
- linux-features/ui-tweaks/**
1513
- scripts/ci/validate-patch-report.js
1614
- scripts/ci/upstream-dmg-*.js
1715
- scripts/validate-upstream-dmg.js
@@ -29,8 +27,6 @@ on:
2927
- scripts/patch-linux-window-ui.js
3028
- scripts/patch-linux-window-ui.test.js
3129
- scripts/patches/**
32-
- linux-features/remote-mobile-control/**
33-
- linux-features/ui-tweaks/**
3430
- scripts/ci/validate-patch-report.js
3531
- scripts/ci/upstream-dmg-*.js
3632
- scripts/validate-upstream-dmg.js

AGENTS.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,10 @@ Primary human docs: [architecture](docs/architecture.md),
121121
and the same format-specific command layer as normal installs.
122122
- Local installs, updater rebuilds, and scheduled CI use the same upstream DMG
123123
acceptance profile. Build into a sibling candidate and promote it only after
124-
an `accepted` or `accepted_with_warnings` verdict; optional drift remains
125-
fail-soft and rejected/inconclusive candidates must not replace the working
126-
app.
124+
an `accepted` or `accepted_with_warnings` verdict. Only user-enabled Linux
125+
features participate in local/updater acceptance, and drift in any enabled
126+
feature rejects the candidate. Disabled features are not probed. Rejected or
127+
inconclusive candidates must not replace the working app.
127128

128129
## Generated Artifacts
129130

@@ -159,7 +160,7 @@ Side-by-side rebuild candidate: `./scripts/rebuild-candidate.sh` or
159160

160161
## Runtime Expectations
161162

162-
- `python3`, `7z`, `curl`, `unzip`, `tar`, `make`, and `g++` are required for
163+
- `python3`, `7z`, `curl`, `unzip`, `tar`, `flock`, `make`, and `g++` are required for
163164
`install.sh`.
164165
- Native package builders require their format-specific tools: `dpkg-deb`,
165166
`rpmbuild`, `makepkg`/pacman tooling, or `appimagetool`.
@@ -197,7 +198,9 @@ for broad cross-format confidence.
197198
when adding or removing shared payload files.
198199
- Keep new core patch descriptors fail-soft and idempotent unless there is a
199200
deliberate `required-upstream` CI policy.
200-
- Keep optional feature patches optional in CI and disabled by default.
201+
- Keep optional features disabled by default. When a user enables one, its
202+
patch drift must block candidate promotion until the user disables it or the
203+
feature is repaired for the current DMG.
201204
- Add tests near the behavior being changed: patcher tests for ASAR needles,
202205
feature tests for Linux features, Rust tests for updater/MCP backends, and
203206
package smoke checks for payload/layout changes.

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
1010
- A shared upstream DMG acceptance profile now produces the same structured
1111
decision for local installs, updater rebuilds, and scheduled CI. Scheduled
1212
rejections create one fingerprinted drift issue and supersede issues for
13-
older DMGs without turning optional patch drift into a blocker.
13+
older DMGs. Acceptance evaluates only the user's enabled Linux features and
14+
preserves the working app if any enabled feature drifts.
1415
- Nix module configurations can select the opt-in `mcp-helper-reaper`
1516
feature. Its Rust helper is supplied by a reproducible Nix derivation and is
1617
not added to the default package closure.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ make build-app DMG=/path/to/Codex.dmg
309309
Local builds are transactional: the candidate must pass the same
310310
[upstream DMG acceptance profile](docs/upstream-dmg-acceptance.md) used by the
311311
scheduled GitHub workflow before it replaces the working `codex-app/`.
312+
Only configured Linux Features are checked; drift in an enabled feature keeps
313+
the current app installed until that feature is disabled or repaired.
312314

313315
Build and install a package:
314316

docs/agents/validation-playbook.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ scripts/ci/validate-patch-report.js codex-app/.codex-linux/patch-report.json
5050
```
5151

5252
Local installs and scheduled CI share `scripts/validate-upstream-dmg.js` and
53-
`scripts/lib/upstream-dmg-release-profile.js`. Exercise decision and issue
54-
behavior with:
53+
`scripts/lib/upstream-dmg-release-profile.js`. Acceptance must inspect only the
54+
features recorded as enabled in the candidate patch report. Add fixtures
55+
proving enabled feature drift rejects promotion and disabled features are not
56+
probed. Exercise decision and issue behavior with:
5557

5658
```bash
5759
node --test scripts/ci/upstream-dmg-acceptance.test.js

docs/build-and-packaging.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ next to `Codex.dmg` and refreshes the cached file when that upstream fingerprint
7878
changes. Every command builds a sibling candidate and runs the shared
7979
[upstream DMG acceptance profile](upstream-dmg-acceptance.md) before replacing
8080
`codex-app/`. A rejected or inconclusive candidate leaves the working app
81-
unchanged. `--fresh` still forces a cache removal before rebuilding, and an
81+
unchanged. Acceptance checks only configured Linux Features and rejects drift
82+
in any enabled feature; disable that feature before retrying if necessary.
83+
`--fresh` still forces a cache removal before rebuilding, and an
8284
explicit `DMG=/path/to/Codex.dmg` uses that file exactly.
8385
Native install shortcuts use `--fresh --reuse-dmg`, so they build a clean
8486
candidate while still reusing the cached DMG when upstream metadata matches.

docs/troubleshooting.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
| Renderer crashes in containers with a tiny `/dev/shm` | The launcher keeps `--disable-dev-shm-usage` automatically when `/dev/shm` is missing or below 1 GiB; force it with `CODEX_ELECTRON_DISABLE_DEV_SHM_USAGE=1` |
2323
| Screen reader does not read the app UI | Renderer accessibility is forced automatically when Orca, brltty, the GNOME screen-reader setting, AT-SPI accessibility state (`org.a11y.Status IsEnabled` or `toolkit-accessibility`, e.g. after `codex-computer-use-linux setup`), or accessibility env markers are detected; force it with `CODEX_FORCE_RENDERER_ACCESSIBILITY=1` |
2424
| Stale install / cached DMG | `make build-app-fresh` refreshes the cached DMG and builds a clean candidate; the working app remains until acceptance succeeds |
25-
| `Candidate was not installed (verdict: rejected)` | Open `dist-next/rebuild/upstream-dmg-decision.json` and its referenced patch reports; fix required current-DMG drift before retrying |
25+
| `Candidate was not installed (verdict: rejected)` | Open `dist-next/rebuild/upstream-dmg-decision.json`. If the blocker is `enabled-feature-drift`, disable the named Linux Feature and retry; otherwise fix required current-DMG drift before retrying |
2626
| `Candidate was not installed (verdict: inconclusive)` | Check the build/inspect logs and missing report paths in `upstream-dmg-decision.json`; infrastructure failures intentionally preserve the working app |
2727
| Computer Use plugin invisible in UI | Enable the Computer Use UI opt-in; upstream server/account rollout can still hide some controls |
2828
| Computer Use `doctor` reports no input backend | Grant `/dev/uinput`, enable XDG RemoteDesktop portal, or start `ydotoold` / `ydotool.service` |

docs/updater.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ fresh upstream `Codex.dmg`, builds the native package, and installs it. The
139139
rebuild uses the shared [upstream DMG acceptance profile](upstream-dmg-acceptance.md);
140140
rejected and inconclusive candidates never replace the working generated app
141141
or advance to package installation.
142+
The rebuild evaluates only the Linux Features selected in the user's saved
143+
configuration. Drift in any selected feature rejects the candidate; disable
144+
that feature and retry if receiving the upstream update is more important than
145+
retaining it.
142146

143147
Updater downloads are streamed to unique temporary files and published as
144148
`Codex-<sha256>.dmg` only after the file and parent directory are synced. The

docs/upstream-dmg-acceptance.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,25 @@ is the only component that decides whether the candidate can be promoted.
1010
| Verdict | Meaning | Local promotion | Scheduled issue |
1111
|---|---|---:|---:|
1212
| `accepted` | Build and every required release check passed | yes | close obsolete drift issues |
13-
| `accepted_with_warnings` | Only optional fail-soft patches drifted | yes | close obsolete drift issues |
14-
| `rejected` | A required core/feature/integrity contract failed | no | create or update the current fingerprint issue |
13+
| `accepted_with_warnings` | Only fail-soft core diagnostics drifted | yes | close obsolete drift issues |
14+
| `rejected` | A required core/integrity check or an enabled Linux Feature drifted | no | create or update the current fingerprint issue |
1515
| `inconclusive` | Reports are missing or an infrastructure failure prevented a decision | no | no change |
1616

17-
The profile derives required core patches from patch descriptors. Its explicit
18-
feature probe enables `remote-mobile-control` and `ui-tweaks`; these requirements
19-
live in the profile rather than in workflow YAML.
17+
The profile derives required core patches from patch descriptors and reads the
18+
enabled feature set from the candidate's patch report. It never enables a
19+
feature for diagnostics. Disabled features are not checked; any patch drift in
20+
a user-enabled feature rejects the candidate so the working installation keeps
21+
that feature intact. The user can disable the feature and retry the update.
2022

2123
## Transactional Local Install
2224

23-
`install.sh` builds into a hidden sibling candidate directory. It then runs the
24-
feature probe and writes `dist-next/rebuild/upstream-dmg-decision.json`. The
25-
existing app is moved only after an accepted verdict, immediately before the
26-
candidate is renamed into place. A failed rename restores the timestamped
27-
backup.
25+
`install.sh` builds into a hidden sibling candidate directory. It evaluates the
26+
candidate patch report and writes
27+
`dist-next/rebuild/upstream-dmg-decision.json`. The existing app is moved only
28+
after an accepted verdict, immediately before the candidate is renamed into
29+
place. A failed rename restores the timestamped backup. Each build evaluates
30+
reports from its own transaction directory, and a per-target promotion lock
31+
serializes the short final replacement window.
2832

2933
`--fresh` refreshes the DMG and candidate without deleting the working app
3034
early. Set `CODEX_KEEP_REJECTED_CANDIDATE=1` to retain a rejected candidate for

flake.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ PY
460460
pkgs.patchelf
461461
pkgs.python3
462462
pkgs.unzip
463+
pkgs.util-linux
463464
];
464465

465466
dontConfigure = true;

0 commit comments

Comments
 (0)