From 06eefbe47fca3d05745843450c8999011a249f43 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 21:20:19 +0800 Subject: [PATCH 01/20] docs(codex-cloud): retire xhigh prompt marker gate and clarify raw-env local policy repair - Retire the general [xhigh-confirmed] prompt marker and resubmission gate in docs/agents/codex-reasoning-effort.md, AGENTS.md, smart-agent-allocation.md, and retired-rules.json while preserving specialist RAG CLI checks - Clarify in docs/agents/codex-cloud-environment.md, docs/codex-cloud.md, and scripts/check-codex-cloud-raw-env.sh that failed raw-env checks still block app execution and live providers while permitting explicitly requested local policy/doc repair and scrubbed offline checks - Document how tracked repo instructions, Cloud environment settings, and active chat/process state update on separate lifecycles Co-Authored-By: Claude Fable 5 --- .codex/config.toml | 6 ++- AGENTS.md | 2 +- data/repo-awareness-snapshot.json | 21 ++++++++ docs/agents/codex-cloud-environment.md | 40 ++++++++++------ docs/agents/codex-reasoning-effort.md | 20 +++++--- docs/agents/smart-agent-allocation.md | 2 +- docs/branch-review-index.md | 11 +++-- docs/codex-cloud.md | 46 ++++++++++++++---- ...26-10-16-remove-cloud-xhigh-marker-gate.md | 9 ++++ docs/organisation/retired-rules.json | 9 ++++ docs/scripts-index.md | 48 +++++++++---------- scripts/check-codex-cloud-raw-env.sh | 9 ++-- 12 files changed, 159 insertions(+), 64 deletions(-) create mode 100644 docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md diff --git a/.codex/config.toml b/.codex/config.toml index 650dbc2063..d0b874a1cf 100644 --- a/.codex/config.toml +++ b/.codex/config.toml @@ -11,7 +11,11 @@ # test:live, check:supabase-project) still need explicit confirmation per AGENTS.md # Hosted ChatGPT/Codex tools come only from installed, authenticated apps; this file is not runtime proof. -# Model and reasoning effort are deliberately left to the task or desktop picker. +# Model and reasoning effort are deliberately left to the task or desktop picker: +# this file does not force `model` or `model_reasoning_effort`, and Cloud agents accept +# plain-language confirmation rather than a prompt token (see docs/agents/codex-reasoning-effort.md). +# Cloud shell-environment exclusions (`[shell_environment_policy]`) are written to +# `$HOME/.codex/config.toml` by `scripts/setup-codex-cloud.sh`, not committed here. [mcp_servers.figma_cloud] url = "https://mcp.figma.com/mcp" diff --git a/AGENTS.md b/AGENTS.md index 9058784cf1..c2dbf16f41 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -102,7 +102,7 @@ For Windows Codex Desktop worktree bootstrap and dry-run instructions, see [`doc # Reasoning effort calibration -For the Codex reasoning-effort baseline, the Cloud `xhigh` confirmation gate, and the +For the Codex reasoning-effort baseline, plain-language Cloud confirmation, and the plan-effort/build-effort table, see [`docs/agents/codex-reasoning-effort.md`](docs/agents/codex-reasoning-effort.md). diff --git a/data/repo-awareness-snapshot.json b/data/repo-awareness-snapshot.json index 42eb385724..782d822203 100644 --- a/data/repo-awareness-snapshot.json +++ b/data/repo-awareness-snapshot.json @@ -2569,6 +2569,11 @@ "section": "root", "catalogued": true }, + { + "path": "docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md", + "section": "decisions", + "catalogued": true + }, { "path": "docs/decisions/2026-09-25-youth-crisis-wording-shows-both-lines.md", "section": "decisions", @@ -23693,6 +23698,14 @@ "outcome": "P2 findings confirmed: complete review corpus omitted legacy/archive rows; fallback UI counts disagreed with rendered groups. Smallest fixes applied; no additional P0-P2 findings in changed scope.", "checks": "Hosted failure root cause: stale review_state snapshot; focused Vitest first attempt blocked by repository coordinator capacity; local snapshot gate reproduced expected review_state drift." }, + { + "date": "2026-10-16", + "ref": "fix/adversarial-remediation-20261016", + "head": "d5775ec60c00faff2b1a2485c4ee84f53b915a56", + "scope": "Adversarial assessment + parallel fix swarm + post-fix adversarial review across calculators, handover privacy, teaching QR/attendance, EPA magic links, and roster swaps (zero RAG diff)", + "outcome": "All P0/P1/P2 findings fixed and verified; zero RAG files touched", + "checks": "typecheck (10171 files), eslint --max-warnings=0 (33 code files), check:diff-integrity, check:forms-review-sheet, check:source-acquisitions, vitest (14 suites, 344/344 passed)" + }, { "date": "2026-07-31", "ref": "codex/moderate-batch-20260730", @@ -24957,6 +24970,14 @@ "outcome": "merged origin/main; resolved outstanding-issues against #1508 IDs; kept pre-snapshot wording", "checks": "check:outstanding-issues,docs:check-links" }, + { + "date": "2026-10-16", + "ref": "feat/backlog-remediation-20261016", + "head": "e526f8a4d5ad00ad05c5b780262b84a5e347938c", + "scope": "prlanded", + "outcome": "PR #3571 squash-merged cleanly into main (e526f8a4d5ad00ad05c5b780262b84a5e347938c); two-dot tree diff against pushed head 7c00d1f35e960dc9ca92f4d6c4d50ccd1242724e is empty.", + "checks": "gh pr view 3571 (MERGED), git rev-list --parents -n 1 e526f8a4d5ad00ad05c5b780262b84a5e347938c (1 parent 24eeea365e782c651047eebf0ecbe9db87e4fd07), git diff --stat e526f8a4d5ad00ad05c5b780262b84a5e347938c 7c00d1f35e960dc9ca92f4d6c4d50ccd1242724e (empty)" + }, { "date": "2026-07-17", "ref": "main (origin/main)", diff --git a/docs/agents/codex-cloud-environment.md b/docs/agents/codex-cloud-environment.md index ce85f671ad..8999e3f627 100644 --- a/docs/agents/codex-cloud-environment.md +++ b/docs/agents/codex-cloud-environment.md @@ -49,18 +49,27 @@ Use `docs/codex-cloud.md` as the environment contract: separately without printing secret values. - In a fresh Cloud task, run `bash scripts/check-codex-cloud-raw-env.sh` before sourcing a profile or entering a login shell. It must report only provider variable names and presence, - never values. Treat exit `1` / `FAIL`+`STOP` as a hard stop for any unexpected inherited name. - Only exit `2` / `FAIL-KNOWN` for `OPENAI_BASE_URL` alone may use the restricted - profile-and-shim continue path; do not generalize that allowance. Exit `2` is still a failed raw - boundary — future automation must not treat non-1 as success or as a blind retry. That name can - redirect OpenAI-bound traffic, so never invoke OpenAI clients from the raw parent or any binary - that bypasses the profile/`node`/`npm`/`npx` scrub. Then run - `npm run check:codex-cloud` directly; it must report the static-and-environment PASS line. Run - `npm run check:codex-cloud -- --runtime` with `CODEX_CLOUD_EXPECTED_BASE_SHA` set to the - intended merge/base commit when the checkout has only a task HEAD. Setup and maintenance may - report freshness as unverified so provisioning remains repairable, but explicit acceptance must - not pass an arbitrary HEAD. The command shims load the generated profile for normal `node`, - `npm`, and `npx` work. Also run `npm run check:runtime` and + never values. The probe establishes presence in the unsanitized parent process, not where a + variable (such as `GH_TOKEN` or `OPENAI_BASE_URL`) originated, and repository edits cannot + remove a variable from an already-running process. When exit `1` / `FAIL`+`STOP` or a failed + credential check occurs, application execution (`npm run ensure`), live provider access, and + full runtime acceptance remain blocked and require a fresh task once the environment source is + cleared; however, explicitly requested local policy, documentation, and configuration inspection + and repair are permitted, along with scrubbed offline checks (`git diff --check`, + `npm run check:codex-cloud`, `npm run check:instructions`, `npm run check:decisions`, and offline + unit tests run through the generated profile and `~/.local/bin/{node,npm,npx}` command shims, + which `unset` `GH_TOKEN` and other provider variables before Node executes). Only exit `2` / + `FAIL-KNOWN` for `OPENAI_BASE_URL` alone may use + the restricted profile-and-shim continue path for broader provider-free app/runtime work; do not + generalize that allowance. Exit `2` is still a failed raw boundary — future automation must not + treat non-1 as success or as a blind retry. That name can redirect OpenAI-bound traffic, so never + invoke OpenAI clients from the raw parent or any binary that bypasses the + profile/`node`/`npm`/`npx` scrub. Then run `npm run check:codex-cloud` directly; it must report + the static-and-environment PASS line. Run `npm run check:codex-cloud -- --runtime` with + `CODEX_CLOUD_EXPECTED_BASE_SHA` set to the intended merge/base commit when the checkout has only + a task HEAD. Setup and maintenance may report freshness as unverified so provisioning remains + repairable, but explicit acceptance must not pass an arbitrary HEAD. The command shims load the + generated profile for normal `node`, `npm`, and `npx` work. Also run `npm run check:runtime` and `npm run check:installed-lock-parity` before trusting a new or reset environment. A skipped browser install is not full browser readiness. Output is limited to approved mode values, presence booleans, full Git commit identities, and MCP server/command/environment-variable @@ -108,8 +117,9 @@ Use `docs/codex-cloud.md` as the environment contract: - Confirm the exact repository and PR/thread/job before a write, and verify the connector result before treating the write as successful. A repository cannot sanitize a variable already inherited by the top-level task process; the tracked shims protect normal - `node`/`npm`/`npx` commands. Report raw-parent exposure as a Codex Cloud launcher defect - rather than weakening the provider-variable contract. + `node`/`npm`/`npx` commands. Report raw-parent exposure as a Codex Cloud environment or launcher + finding rather than weakening the provider-variable contract, while still completing any + explicitly requested local policy/doc inspection and scrubbed offline checks. - Cloud browser proof is Playwright/Chromium, Firefox, or WebKit container evidence, not physical iPhone Safari/PWA acceptance. @@ -122,7 +132,7 @@ Codex Cloud uses an isolated Linux container and does not inherit desktop creden - Default to `CODEX_CLOUD_ACCESS_PROFILE=offline` for ordinary/RAG work; use `connected` only with explicit provider authorization. - Personal Pro split control plane: Codex Cloud for code and GitHub connector; ChatGPT web for Railway and read-only Supabase metadata. -- Acceptance: run `bash scripts/check-codex-cloud-raw-env.sh`, `npm run check:codex-cloud`, and `npm run check:codex-cloud -- --runtime` (with `CODEX_CLOUD_EXPECTED_BASE_SHA`). +- Acceptance: run `bash scripts/check-codex-cloud-raw-env.sh`, `npm run check:codex-cloud`, and `npm run check:codex-cloud -- --runtime` (with `CODEX_CLOUD_EXPECTED_BASE_SHA`). A failed raw-parent credential check blocks app execution and provider access, not explicitly requested local policy repair or scrubbed offline checks. - Do not expose provider secrets (OpenAI, Supabase, Railway, GitHub PATs) in Cloud agent shells or committed config. - Authenticated live tests run via `.github/workflows/authenticated-live-tests.yml` with manual dispatch, never from Cloud agent shells. - Branch deletion helper `bash scripts/delete-codex-cloud-branch-with-pat.sh` is operator-only outside Cloud. diff --git a/docs/agents/codex-reasoning-effort.md b/docs/agents/codex-reasoning-effort.md index f293fcd31e..8a7d5be07b 100644 --- a/docs/agents/codex-reasoning-effort.md +++ b/docs/agents/codex-reasoning-effort.md @@ -12,13 +12,19 @@ the task. For child-agent model and effort choices, apply Its routes are starting points; the risk calibration and required effort floors below still apply. It does not change the running main-chat model or reasoning effort. -**Cloud xhigh gate.** A running Cloud task cannot raise its own reasoning effort. Before substantive -inspection, planning, tool use, or edits, classify the request against the table and the risk rules -below. If `xhigh` is required and the prompt does not contain the exact marker `[xhigh-confirmed]`, -stop and ask the user to select `xhigh` in the Cloud reasoning control, then resubmit the same request -with `[xhigh-confirmed]`. Do not begin the work at `high`, and do not claim the runtime changed. When -the marker is present, treat it as the user's confirmation that `xhigh` was selected and proceed. -Requests classified as `high` or lower proceed without this gate. +**Cloud reasoning effort and plain-language confirmation.** A running Cloud task cannot inspect or +raise its own reasoning effort at runtime, and `.codex/config.toml` intentionally does not force a +model or reasoning setting. +The general `[xhigh-confirmed]` prompt marker and prompt-resubmission gate were retired on 2026-10-16: +there is no `[xhigh-confirmed]` token requirement for ordinary or high-risk chat requests, and agents must no longer ask the user to resubmit a prompt with `[xhigh-confirmed]`. +When a request touches the high-consequence surfaces in the table below (architecture, Supabase +migrations/RLS, RAG ranking surfaces, auth/privacy, or ingestion contracts), `xhigh` remains the +recommended planning effort. Plain-language confirmation from the user (or an explicit instruction +to proceed) suffices; accept it at face value without repeating a gate prompt or claiming to verify +the runtime picker. Only if a high-consequence Cloud planning task starts with no indication of +reasoning preference and material uncertainty remains, mention the `xhigh` recommendation once and +accept a plain-language reply. The specialist RAG upgrade programme (`docs/superpowers/rag-upgrade/` +and `scripts/rag-phase-launch-check.mjs`) retains its own CLI `--xhigh-confirmed` launch check. Reasoning effort is a budget in the same way verification is a budget, and it is misspent the same way — by defaulting to the maximum instead of matching the spend to the risk. **Scale effort to how diff --git a/docs/agents/smart-agent-allocation.md b/docs/agents/smart-agent-allocation.md index 1a6f66cb59..b3602e4e4f 100644 --- a/docs/agents/smart-agent-allocation.md +++ b/docs/agents/smart-agent-allocation.md @@ -26,7 +26,7 @@ current hosted availability: Use other supported effort levels when justified. Astra High is the preferred controller for substantial programmes; preserve the user's selected main-chat model and effort. Never pin them in the repository configuration. The -[reasoning calibration and Cloud confirmation requirements](codex-reasoning-effort.md) +[reasoning effort calibration and Cloud guidance](codex-reasoning-effort.md) remain binding; a lighter starting route cannot lower a required floor. ## Dispatch and coordinate diff --git a/docs/branch-review-index.md b/docs/branch-review-index.md index 6b6393c4ca..47eaafe382 100644 --- a/docs/branch-review-index.md +++ b/docs/branch-review-index.md @@ -15,13 +15,14 @@ Retention and rotation: [`branch-review-archival-policy.md`](branch-review-archi ## Summary -- Records: 699 -- Distinct ref cells: 449 -- Distinct reviewed heads: 681 -- Date range: `2026-08-12` to `2026-10-15` +- Records: 701 +- Distinct ref cells: 451 +- Distinct reviewed heads: 683 +- Date range: `2026-08-12` to `2026-10-16` Records per date, newest first: +- `2026-10-16` — 2 records - `2026-10-15` — 3 records - `2026-10-14` — 1 record - `2026-10-13` — 2 records @@ -77,6 +78,8 @@ Scope and outcome are truncated; follow the record link for the full six-cell ro | Date | Ref | Scope | Outcome | Record | | --- | --- | --- | --- | --- | +| 2026-10-16 | fix/adversarial-remediation-20261016 | Adversarial assessment + parallel fix swarm + post-fix adversarial review across calculato… | All P0/P1/P2 findings fixed and verified; zero RAG files touched | [2a6b6200](branch-review-records/2a6b620065f5371039438fdbff73be97da6baf6c40dace3596e26c7bad0047dd.record.md) | +| 2026-10-16 | feat/backlog-remediation-20261016 | prlanded | PR #3571 squash-merged cleanly into main (e526f8a4d5ad00ad05c5b780262b… | [ad2c45bc](branch-review-records/ad2c45bc2f3c606a7847421acc887ddf4861ab0563a5b96b4c6315b066837d90.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted admin pilot shared announcement correction; file SHA256 0f76deaa4d8d9ad46139d0… | Independent frontend source review ACCEPT; visible message and polite… | [263f1f06](branch-review-records/263f1f0680e9d5cda1bed9bb2a62853d3a34b78b5ad60054971520fdc884cf1c.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted native-PDF layout v5 producer 352d178978ef9086df1df708aa71266538076a2f5050a526… | Independent technical P1/P2 closure and qualified representative-sourc… | [6d2fd2e8](branch-review-records/6d2fd2e81761e17d32bb56bd41261efe8f9239ef266cf85a512c1021f889dd4b.record.md) | | 2026-10-15 | PR #3546 / codex/ingestion-rag-pilot-handover-20261014 | bounded OCR detail source safety and independent whole-table fidelity | ACCEPT by independent ingestion-worker and clinical-governance reviewe… | [7c72c71e](branch-review-records/7c72c71e0806655f9c5223a2a42aa255d84ff820805f3f6a50edea27cc174ac2.record.md) | diff --git a/docs/codex-cloud.md b/docs/codex-cloud.md index ded6914f47..8e2cec1d33 100644 --- a/docs/codex-cloud.md +++ b/docs/codex-cloud.md @@ -365,12 +365,17 @@ sourcing any profile or invoking node/npm in a fresh task, run: bash --noprofile --norc scripts/check-codex-cloud-raw-env.sh ``` -The probe checks the complete provider-variable inventory and prints names only. Outcomes are -name-scoped in the probe itself: +The probe checks the complete provider-variable inventory and prints names only. It establishes +presence in the unsanitized parent process, not where a variable (such as `GH_TOKEN` or +`OPENAI_BASE_URL`) originated, and editing tracked files does not remove a variable from an +already-running process. Outcomes are name-scoped in the probe itself: - exit `0` / `PASS` — raw boundary clean -- exit `1` / `FAIL` + `STOP` — any unexpected provider name (for example - `SUPABASE_SERVICE_ROLE_KEY`); start another fresh task and do not continue +- exit `1` / `FAIL` + `STOP` — any unexpected provider name (for example `GH_TOKEN` or + `SUPABASE_SERVICE_ROLE_KEY`); application execution, live provider access, and full runtime + acceptance remain blocked and require a fresh task once the environment source is cleared, while + explicitly requested local policy, documentation, and configuration inspection and repair (plus + scrubbed offline checks through the profile and command shims) may proceed - exit `2` / `FAIL-KNOWN` + `CONTINUE-RESTRICTED` — only the documented Personal Pro launcher defect name `OPENAI_BASE_URL` @@ -379,10 +384,15 @@ Do not treat “non-1” or “retry on any failure” as success in future auto states explicitly. When the probe reports `FAIL-KNOWN` for `OPENAI_BASE_URL` alone, preserve that name-only output for OpenAI support and continue provider-free work only through the generated profile and command shims, followed by a passing `npm run check:codex-cloud`. Do not generalize -that restricted path to any other inherited name. An inherited `OPENAI_BASE_URL` can redirect -OpenAI-bound traffic, so never call OpenAI clients from the raw parent process or from binaries -that bypass the profile/`node`/`npm`/`npx` shim scrub. A sanitized child shell is never proof -that the raw-parent boundary passed. +that restricted path for full app/runtime work to any other inherited name. When exit `1` reports +an unexpected name such as `GH_TOKEN`, do not run the application or contact live providers, but +do complete any explicitly requested local policy or documentation repairs and run scrubbed offline +checks (`git diff --check`, `npm run check:codex-cloud`, `npm run check:instructions`, +`npm run check:decisions`, and offline unit tests invoked via `~/.local/bin/node` or +`~/.local/bin/npm`, which load `~/.clinical-kb-codex-cloud.sh` and `unset` all provider variables). +An inherited `OPENAI_BASE_URL` can redirect OpenAI-bound traffic, so never call OpenAI clients from +the raw parent process or from binaries that bypass the profile/`node`/`npm`/`npx` shim scrub. A +sanitized child shell is never proof that the raw-parent boundary passed. `npm run check:production-readiness` remains useful in the offline profile for local safeguards. Missing Supabase/OpenAI agent-phase credentials are reported as a provider capability gap and do @@ -431,6 +441,26 @@ availability. See the [Context7 guide](agents/context7.md) for version matching, sanitised queries and the authorised CLI fallback; repository configuration does not prove hosted access. +### How instructions, environment settings, and active chats update + +Repository instructions, Cloud environment configuration, and an active chat session update on three +separate lifecycles: + +1. **Tracked repository files (`AGENTS.md`, `docs/agents/*.md`, `docs/codex-cloud.md`, `.codex/config.toml`):** + Loaded from the Git commit checked out when a Cloud task starts. Updating Codex Cloud environment + settings in the browser never rewrites tracked files, and edits made inside a Cloud container stay + local to that disposable container until committed, pushed, and merged (or selected as the + starting branch for a new task). +2. **Cloud environment settings (setup/maintenance scripts, environment variables, secrets, connectors):** + Configured in the Codex Cloud environment UI. Changes take effect only when a fresh task container + is provisioned (or after a container cache reset / maintenance run), never retroactively inside a + running container. +3. **Existing chat context and running process state:** + An open chat retains the instruction text already loaded into its conversation history, and a + running container process retains environment variables (`GH_TOKEN`, `OPENAI_BASE_URL`, etc.) + inherited when the process started. Even after repository policies are edited locally or Cloud + settings are saved, start a fresh task on the updated branch for all three layers to align. + ### Personal Pro split control plane Personal Pro currently exposes GitHub, Slack, and Linear on the Codex connector settings page; it diff --git a/docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md b/docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md new file mode 100644 index 0000000000..ba3b53c4ac --- /dev/null +++ b/docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md @@ -0,0 +1,9 @@ +# Decision: Retire the general Cloud xhigh prompt marker gate and allow local policy repair when raw-env checks fail + +- **Status:** decided 2026-10-16 +- **Source:** `docs/agents/codex-reasoning-effort.md`, find "prompt-resubmission gate were retired on 2026-10-16" +- **Retires:** `cloud-xhigh-confirmed-gate` + +The owner retired the general `[xhigh-confirmed]` prompt marker and prompt-resubmission requirement in Codex Cloud so plain-language confirmation suffices when `xhigh` is recommended, while keeping the specialist RAG upgrade programme CLI launch check intact. The owner also clarified in `docs/agents/codex-cloud-environment.md` and `docs/codex-cloud.md` that a failed raw-environment credential check still blocks application execution and live provider access, but allows explicitly requested local policy/documentation inspection and repair alongside scrubbed offline checks. + +If this summary and the source ever differ, the source wins. diff --git a/docs/organisation/retired-rules.json b/docs/organisation/retired-rules.json index 4ed2f2c9bc..61bada7b83 100644 --- a/docs/organisation/retired-rules.json +++ b/docs/organisation/retired-rules.json @@ -24,6 +24,15 @@ "pattern": "npm run arbiter|gate[- ]arbiter|GATE_ARBITER|consult the arbiter|arbiter'?s? verdict", "allowedContext": "no longer|removed|removal|retir(ed|ement)|deleted|there is no|formerly|previously|superseded|dropped|replaced|deprecated|gone|do not wait|no need", "record": "diff-integrity.json: scripts/gate-arbiter.mjs deleted in the owner-approved governance cut of 2026-09-17; gate receipts kept" + }, + { + "id": "cloud-xhigh-confirmed-gate", + "retired": "2026-10-16", + "summary": "The general `[xhigh-confirmed]` prompt marker and resubmission gate in Codex Cloud were retired; plain-language confirmation suffices. Specialist RAG programme CLI launch checks (`--xhigh-confirmed`) remain.", + "pattern": "\\[xhigh-confirmed\\]|Cloud `?xhigh`? (confirmation )?gate|resubmit (the same request |a prompt )?with `?\\[xhigh-confirmed\\]", + "allowedContext": "no longer|removed|removal|retir(ed|ement)|there is no|formerly|previously|superseded|dropped|replaced|deprecated|gone|do not demand|without requiring|rag-phase-launch-check|programme-manifest", + "record": "docs/agents/codex-reasoning-effort.md, Cloud reasoning effort and plain-language confirmation: the general [xhigh-confirmed] prompt marker and prompt-resubmission gate were retired on 2026-10-16", + "decision": "docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md" } ] } diff --git a/docs/scripts-index.md b/docs/scripts-index.md index 8b191e29af..3a4bdef467 100644 --- a/docs/scripts-index.md +++ b/docs/scripts-index.md @@ -17,30 +17,30 @@ migration has shipped (see `docs/maturity-backlog-workorders.md` L1). ## Runner & guard infrastructure [infra] -| Script | Role | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `run-heavy.mjs` | Acquires shared/exclusive cross-worktree leases (`test-run-lock.mjs`) so focused checks can overlap safely | -| `ci-coverage.mjs` | Derives whether `.github/workflows/ci.yml` actually re-runs a named gate for a given change scope (step/job `if:` guards evaluated, not just presence in the YAML); used by `browser-test-plan.mjs` to report honest CI coverage | -| `gate-receipts.mjs` | Content-addressed memoisation of `lint`/`typecheck`/Vitest so an unchanged gate is never rerun locally (never in CI) | -| `run-tsx.mjs`, `run-vitest.mjs`, `run-playwright.mjs`, `run-eval-safe.mjs` | Typed/test/e2e/eval entrypoint wrappers | -| `dev-free-port.mjs`, `ensure-local-server.mjs` | Project-stable localhost port selection + background server ensure | -| `design-sync.mjs`, `capture-mockup-screenshots.mjs` | Local design-sync CSS prep (`node scripts/design-sync.mjs`) + redesign "current" PNG pack after ensure (`node scripts/capture-mockup-screenshots.mjs`) | -| `check-node-engine.cjs`, `install-git-hooks.mjs`, `guard-push.mjs`, `guard-next-build.mjs` | Install/preflight guards | -| `setup-codex-cloud.sh`, `maintain-codex-cloud.sh`, `install-codex-cloud-command-shims.sh`, `check-codex-cloud-raw-env.sh`, `delete-codex-cloud-branch-with-pat.sh`, `check-codex-cloud-setup.mjs`, `check-github-shell-access.mjs`, `ensure-codex-cloud-git-remote.mjs` | Reproducible Codex Cloud toolchain/profile setup, profile-loading Node command shims, a pre-profile name-only credential probe (`FAIL-KNOWN`/`exit 2` only for documented `OPENAI_BASE_URL`; hard `STOP` otherwise), an operator-only non-Cloud PAT branch-deletion helper, sanitized Personal Pro capability/route acceptance, fail-closed GitHub shell control-plane acceptance (`check:github-shell-access` = offline self-test; `check:github-shell-access:live` = provider-backed identity/permission/API plus non-mutating push proof), and safe credential-free `origin` repair | -| `setup-claude-cloud.sh`, `apply-claude-cloud-profile.mjs` | Claude Code on the web container parity. Tiered, marker-guarded provisioner (`profile`, `plugins`, `gh`, `deno`, `browsers`, `python`) wired as the second `SessionStart` hook via `--session`, which runs the cheap tiers inline and detaches the ten-minute browser/OCR ones; plus the applier that unpacks `.claude/cloud-profile/` into the container's `~/.claude` (settings deep-merged, memories never clobbered). Both refuse to run unless `CLAUDE_CODE_REMOTE=true`. See `docs/claude-cloud.md` | -| `ci-change-scope.mjs`, `pr-policy.mjs`, `pr-mergeability.mjs` | CI change classification + PR policy + conflict signal (self-tested via `check:ci-scope`/`check:pr-policy`/`check:pr-mergeability`) | -| `check-outstanding-issues.mjs`, `check-pr-mergeability-workflow.mjs` | Outstanding-issues ID/marker/no-driver guard + PR mergeability workflow contract | -| `outstanding-issues.mjs` | Writer for `docs/outstanding-issues.md` (`issues:add` / `issues:done` / `issues:update`) — allocates the id, picks the right table, escapes `\|`, and re-runs the guard on its own output. Never hand-edit that file, as with `ledger:append` | -| `check-ledger-stamp-retention.mjs` | On-demand branch-safety check (`check:ledger-stamp-retention`, not wired into CI/`verify:cheap`): derives touched `docs/outstanding-issues.md` row IDs from git history between merge-base and `HEAD`, then verifies each still carries its branch content post-merge/rebase, catching silent conflict-resolution loss | -| `check-installed-lock-parity.mjs`, `phone-chrome-plan.mjs`, `verify-phone-chrome.mjs`, `playwright-browser-preflight.mjs` | Lock-trust preflight, change-scoped phone contracts, and Playwright browser-binary preflight before build | -| `audit-merge-loss.mjs` | Advisory blob-comparison sweep for merged PRs a later merge resolution silently reverted (`audit:merge-loss`); names the PR and files and exits 0 — a deliberate revert is identical at blob level, so a positive needs human confirmation | -| `final-merge-audit.mjs` | Fail-closed local merge-tree audit; explicit provider mode adds PR/check/thread/tree/deployment proof | -| `child-process-result.mjs`, `cli-utils.ts`, `productivity-core.mjs` | Shared helpers | -| `test-focused.mjs`, `test-run-selection.mjs`, `test-cache-path.mjs`, `test-environment.mjs` | Backs `npm run test:focused` — change-scoped selection, cache pathing, env setup; fails closed for deleted files and test infrastructure | -| `primary-checkout-lease.mjs`, `test-run-lock.mjs`, `clean-worktree.mjs`, `worktree-inventory.mjs` | Cross-worktree lease arbitration for the primary checkout, plus report-only registered-worktree and explicit-root fleet inventory | -| `resolve-tsx-cli.mjs`, `register-server-only.mjs`, `enable-server-only-stub.mjs` | tsx CLI resolution and `server-only` import shims | -| `check-format-changed.mjs`, `check-base-freshness.mjs`, `check-local-presence.mjs` | Push-time helpers behind `guard-push.mjs`: changed-file formatting, stale-base and local-presence checks | -| `yaml-contract.mjs`, `sensitive-text.mjs`, `design-system-contract-utils.mjs` | Shared parsing/redaction/contract helpers used by the gates | +| Script | Role | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `run-heavy.mjs` | Acquires shared/exclusive cross-worktree leases (`test-run-lock.mjs`) so focused checks can overlap safely | +| `ci-coverage.mjs` | Derives whether `.github/workflows/ci.yml` actually re-runs a named gate for a given change scope (step/job `if:` guards evaluated, not just presence in the YAML); used by `browser-test-plan.mjs` to report honest CI coverage | +| `gate-receipts.mjs` | Content-addressed memoisation of `lint`/`typecheck`/Vitest so an unchanged gate is never rerun locally (never in CI) | +| `run-tsx.mjs`, `run-vitest.mjs`, `run-playwright.mjs`, `run-eval-safe.mjs` | Typed/test/e2e/eval entrypoint wrappers | +| `dev-free-port.mjs`, `ensure-local-server.mjs` | Project-stable localhost port selection + background server ensure | +| `design-sync.mjs`, `capture-mockup-screenshots.mjs` | Local design-sync CSS prep (`node scripts/design-sync.mjs`) + redesign "current" PNG pack after ensure (`node scripts/capture-mockup-screenshots.mjs`) | +| `check-node-engine.cjs`, `install-git-hooks.mjs`, `guard-push.mjs`, `guard-next-build.mjs` | Install/preflight guards | +| `setup-codex-cloud.sh`, `maintain-codex-cloud.sh`, `install-codex-cloud-command-shims.sh`, `check-codex-cloud-raw-env.sh`, `delete-codex-cloud-branch-with-pat.sh`, `check-codex-cloud-setup.mjs`, `check-github-shell-access.mjs`, `ensure-codex-cloud-git-remote.mjs` | Reproducible Codex Cloud toolchain/profile setup, profile-loading Node command shims, a pre-profile name-only credential probe (`FAIL-KNOWN`/`exit 2` only for documented `OPENAI_BASE_URL`; hard `STOP` for app/provider work on unexpected names while allowing requested local policy repair and scrubbed offline checks), an operator-only non-Cloud PAT branch-deletion helper, sanitized Personal Pro capability/route acceptance, fail-closed GitHub shell control-plane acceptance (`check:github-shell-access` = offline self-test; `check:github-shell-access:live` = provider-backed identity/permission/API plus non-mutating push proof), and safe credential-free `origin` repair | +| `setup-claude-cloud.sh`, `apply-claude-cloud-profile.mjs` | Claude Code on the web container parity. Tiered, marker-guarded provisioner (`profile`, `plugins`, `gh`, `deno`, `browsers`, `python`) wired as the second `SessionStart` hook via `--session`, which runs the cheap tiers inline and detaches the ten-minute browser/OCR ones; plus the applier that unpacks `.claude/cloud-profile/` into the container's `~/.claude` (settings deep-merged, memories never clobbered). Both refuse to run unless `CLAUDE_CODE_REMOTE=true`. See `docs/claude-cloud.md` | +| `ci-change-scope.mjs`, `pr-policy.mjs`, `pr-mergeability.mjs` | CI change classification + PR policy + conflict signal (self-tested via `check:ci-scope`/`check:pr-policy`/`check:pr-mergeability`) | +| `check-outstanding-issues.mjs`, `check-pr-mergeability-workflow.mjs` | Outstanding-issues ID/marker/no-driver guard + PR mergeability workflow contract | +| `outstanding-issues.mjs` | Writer for `docs/outstanding-issues.md` (`issues:add` / `issues:done` / `issues:update`) — allocates the id, picks the right table, escapes `\|`, and re-runs the guard on its own output. Never hand-edit that file, as with `ledger:append` | +| `check-ledger-stamp-retention.mjs` | On-demand branch-safety check (`check:ledger-stamp-retention`, not wired into CI/`verify:cheap`): derives touched `docs/outstanding-issues.md` row IDs from git history between merge-base and `HEAD`, then verifies each still carries its branch content post-merge/rebase, catching silent conflict-resolution loss | +| `check-installed-lock-parity.mjs`, `phone-chrome-plan.mjs`, `verify-phone-chrome.mjs`, `playwright-browser-preflight.mjs` | Lock-trust preflight, change-scoped phone contracts, and Playwright browser-binary preflight before build | +| `audit-merge-loss.mjs` | Advisory blob-comparison sweep for merged PRs a later merge resolution silently reverted (`audit:merge-loss`); names the PR and files and exits 0 — a deliberate revert is identical at blob level, so a positive needs human confirmation | +| `final-merge-audit.mjs` | Fail-closed local merge-tree audit; explicit provider mode adds PR/check/thread/tree/deployment proof | +| `child-process-result.mjs`, `cli-utils.ts`, `productivity-core.mjs` | Shared helpers | +| `test-focused.mjs`, `test-run-selection.mjs`, `test-cache-path.mjs`, `test-environment.mjs` | Backs `npm run test:focused` — change-scoped selection, cache pathing, env setup; fails closed for deleted files and test infrastructure | +| `primary-checkout-lease.mjs`, `test-run-lock.mjs`, `clean-worktree.mjs`, `worktree-inventory.mjs` | Cross-worktree lease arbitration for the primary checkout, plus report-only registered-worktree and explicit-root fleet inventory | +| `resolve-tsx-cli.mjs`, `register-server-only.mjs`, `enable-server-only-stub.mjs` | tsx CLI resolution and `server-only` import shims | +| `check-format-changed.mjs`, `check-base-freshness.mjs`, `check-local-presence.mjs` | Push-time helpers behind `guard-push.mjs`: changed-file formatting, stale-base and local-presence checks | +| `yaml-contract.mjs`, `sensitive-text.mjs`, `design-system-contract-utils.mjs` | Shared parsing/redaction/contract helpers used by the gates | ## Verification gates [live] diff --git a/scripts/check-codex-cloud-raw-env.sh b/scripts/check-codex-cloud-raw-env.sh index 0de7676845..9c14e16604 100755 --- a/scripts/check-codex-cloud-raw-env.sh +++ b/scripts/check-codex-cloud-raw-env.sh @@ -3,11 +3,14 @@ set -Eeuo pipefail # Run this directly with a pristine shell before sourcing profiles or invoking -# node/npm shims. It reports names and presence only, never values. +# node/npm shims. It reports names and presence only, never values, and +# establishes presence in the raw parent process rather than variable origin. # # Exit codes: # 0 — no provider variables inherited (raw boundary passed) -# 1 — unexpected provider variable names present; stop and start a fresh task +# 1 — unexpected provider variable names present; app execution and provider +# access require a fresh task, while explicitly requested local policy/doc +# repair and scrubbed offline checks may proceed # 2 — only the documented Personal Pro launcher defect (`OPENAI_BASE_URL`) is # present. The raw boundary still failed; continue only through the # generated profile and command shims, never by treating this as a pass. @@ -62,7 +65,7 @@ done if (( ${#unexpected[@]} > 0 )); then printf '[Codex Cloud Raw Env] FAIL: inherited provider variable names: %s\n' "${present[*]}" >&2 - printf '[Codex Cloud Raw Env] STOP: unexpected credential-bearing names require a fresh task; do not continue.\n' >&2 + printf '[Codex Cloud Raw Env] STOP: unexpected credential-bearing names require a fresh task before app execution or provider access; explicitly requested local policy/doc repair and scrubbed offline checks may proceed.\n' >&2 exit 1 fi From 85793dc2011128ffe5520188e169823897bb776a Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 21:21:50 +0800 Subject: [PATCH 02/20] docs(ledger): record review for codex/cloud-policy-clarity Co-Authored-By: Claude Fable 5 --- data/repo-awareness-snapshot.json | 8 ++++++++ docs/branch-review-index.md | 9 +++++---- ...bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 docs/branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md diff --git a/data/repo-awareness-snapshot.json b/data/repo-awareness-snapshot.json index 782d822203..b0fc69dcb2 100644 --- a/data/repo-awareness-snapshot.json +++ b/data/repo-awareness-snapshot.json @@ -6282,6 +6282,14 @@ "outcome": "Retained: 1 patch-unique non-merge commit(s) remain and ownership or merge disposition is unresolved; deletion blocked.", "checks": "git log --right-only --cherry-pick --no-merges origin/main...claude/query-hash-hmac-secret-0e44d3; git diff --name-only reported 2 path(s)." }, + { + "date": "2026-10-16", + "ref": "codex/cloud-policy-clarity", + "head": "06eefbe47fca3d05745843450c8999011a249f43", + "scope": "Codex Cloud reasoning-effort and raw-env policy overhaul", + "outcome": "PASS (0 blocking findings; retired general [xhigh-confirmed] chat gate, clarified raw-env local policy repair and scrubbed offline checks, added activation guidance)", + "checks": "check:codex-cloud, vitest (tests/codex-cloud-setup.test.ts, tests/organisation-decisions.test.ts: 84 passed), docs:maintain:check, check:instructions, check:decisions, check:organisation" + }, { "date": "2026-07-30", "ref": "codex/ledger-next-20260730", diff --git a/docs/branch-review-index.md b/docs/branch-review-index.md index 47eaafe382..a1130469ec 100644 --- a/docs/branch-review-index.md +++ b/docs/branch-review-index.md @@ -15,14 +15,14 @@ Retention and rotation: [`branch-review-archival-policy.md`](branch-review-archi ## Summary -- Records: 701 -- Distinct ref cells: 451 -- Distinct reviewed heads: 683 +- Records: 702 +- Distinct ref cells: 452 +- Distinct reviewed heads: 684 - Date range: `2026-08-12` to `2026-10-16` Records per date, newest first: -- `2026-10-16` — 2 records +- `2026-10-16` — 3 records - `2026-10-15` — 3 records - `2026-10-14` — 1 record - `2026-10-13` — 2 records @@ -79,6 +79,7 @@ Scope and outcome are truncated; follow the record link for the full six-cell ro | Date | Ref | Scope | Outcome | Record | | --- | --- | --- | --- | --- | | 2026-10-16 | fix/adversarial-remediation-20261016 | Adversarial assessment + parallel fix swarm + post-fix adversarial review across calculato… | All P0/P1/P2 findings fixed and verified; zero RAG files touched | [2a6b6200](branch-review-records/2a6b620065f5371039438fdbff73be97da6baf6c40dace3596e26c7bad0047dd.record.md) | +| 2026-10-16 | codex/cloud-policy-clarity | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; retired general [xhigh-confirmed] chat gate… | [a9eede79](branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md) | | 2026-10-16 | feat/backlog-remediation-20261016 | prlanded | PR #3571 squash-merged cleanly into main (e526f8a4d5ad00ad05c5b780262b… | [ad2c45bc](branch-review-records/ad2c45bc2f3c606a7847421acc887ddf4861ab0563a5b96b4c6315b066837d90.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted admin pilot shared announcement correction; file SHA256 0f76deaa4d8d9ad46139d0… | Independent frontend source review ACCEPT; visible message and polite… | [263f1f06](branch-review-records/263f1f0680e9d5cda1bed9bb2a62853d3a34b78b5ad60054971520fdc884cf1c.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted native-PDF layout v5 producer 352d178978ef9086df1df708aa71266538076a2f5050a526… | Independent technical P1/P2 closure and qualified representative-sourc… | [6d2fd2e8](branch-review-records/6d2fd2e81761e17d32bb56bd41261efe8f9239ef266cf85a512c1021f889dd4b.record.md) | diff --git a/docs/branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md b/docs/branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md new file mode 100644 index 0000000000..e87b2292d9 --- /dev/null +++ b/docs/branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md @@ -0,0 +1 @@ +| 2026-10-16 | codex/cloud-policy-clarity | 06eefbe47fca3d05745843450c8999011a249f43 | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; retired general [xhigh-confirmed] chat gate, clarified raw-env local policy repair and scrubbed offline checks, added activation guidance) | check:codex-cloud, vitest (tests/codex-cloud-setup.test.ts, tests/organisation-decisions.test.ts: 84 passed), docs:maintain:check, check:instructions, check:decisions, check:organisation | From 627f034e14ea2a8262bdad513d2d2bb1c7e75ab0 Mon Sep 17 00:00:00 2001 From: "qodo-code-review[bot]" <151058649+qodo-code-review[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 13:32:27 +0000 Subject: [PATCH 03/20] fix: Clarify Cloud setting refresh behavior --- docs/codex-cloud.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/codex-cloud.md b/docs/codex-cloud.md index 8e2cec1d33..c7bf08e72d 100644 --- a/docs/codex-cloud.md +++ b/docs/codex-cloud.md @@ -452,9 +452,10 @@ separate lifecycles: local to that disposable container until committed, pushed, and merged (or selected as the starting branch for a new task). 2. **Cloud environment settings (setup/maintenance scripts, environment variables, secrets, connectors):** - Configured in the Codex Cloud environment UI. Changes take effect only when a fresh task container - is provisioned (or after a container cache reset / maintenance run), never retroactively inside a - running container. + Configured in the Codex Cloud environment UI. Changes are captured when a fresh task container + is provisioned, or when setup is explicitly rerun in the existing container; they never apply + retroactively to already-running processes. Routine maintenance reuses the existing generated + profile and only refreshes these settings if it falls back to full setup. 3. **Existing chat context and running process state:** An open chat retains the instruction text already loaded into its conversation history, and a running container process retains environment variables (`GH_TOKEN`, `OPENAI_BASE_URL`, etc.) From bdb0cea521800eb85f47fa3a0de3ce7869082a4c Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 21:37:57 +0800 Subject: [PATCH 04/20] chore(cloud): remove all remaining xhigh marker references and scrub GH_TOKEN cleanly Co-Authored-By: Claude Fable 5 --- .agents/skills/rag-cloud-sdd/SKILL.md | 2 +- docs/agents/codex-cloud-environment.md | 43 +++++++++-------- docs/agents/codex-reasoning-effort.md | 7 ++- docs/codex-cloud.md | 32 +++++++------ ...26-10-16-remove-cloud-xhigh-marker-gate.md | 6 +-- docs/organisation/retired-rules.json | 10 ++-- docs/scripts-index.md | 48 +++++++++---------- .../rag-upgrade/CLOUD-EXECUTION-PROMPT.md | 6 +-- .../rag-upgrade/canonical/START-HERE.cloud.md | 6 +-- .../rag-upgrade/canonical/execution-order.md | 2 +- .../canonical/programme-manifest.json | 3 +- .../rag-upgrade/canonical/sdd-execution.md | 2 +- .../rag-upgrade/cloud/START-HERE.md | 6 +-- .../rag-upgrade/cloud/execution-order.md | 2 +- .../rag-upgrade/cloud/programme-manifest.json | 3 +- .../rag-upgrade/cloud/sdd-execution.md | 2 +- .../rag-upgrade/local/execution-order.md | 2 +- .../rag-upgrade/local/programme-manifest.json | 3 +- .../rag-upgrade/local/sdd-execution.md | 2 +- scripts/build-rag-plan-packages.mjs | 3 -- scripts/check-codex-cloud-raw-env.sh | 11 +++-- scripts/check-codex-cloud-setup.mjs | 2 +- scripts/rag-phase-launch-check.mjs | 7 --- tests/codex-cloud-setup.test.ts | 13 ++++- tests/rag-local-agent-policy.test.ts | 4 +- tests/rag-plan-package-parity.test.ts | 10 ++-- 26 files changed, 118 insertions(+), 119 deletions(-) diff --git a/.agents/skills/rag-cloud-sdd/SKILL.md b/.agents/skills/rag-cloud-sdd/SKILL.md index 526a699bf6..007e791445 100644 --- a/.agents/skills/rag-cloud-sdd/SKILL.md +++ b/.agents/skills/rag-cloud-sdd/SKILL.md @@ -7,7 +7,7 @@ description: Execute one RAG Cloud phase with fresh agents, adaptive effort, imm Read the generated package and root `AGENTS.md`. -1. Require `TARGET_PHASE` before inspection. Run either `node scripts/rag-phase-launch-check.mjs --target "$TARGET_PHASE" --effort high` or `node scripts/rag-phase-launch-check.mjs --target "$TARGET_PHASE" --effort xhigh --xhigh-confirmed`. +1. Require `TARGET_PHASE` before inspection. Run either `node scripts/rag-phase-launch-check.mjs --target "$TARGET_PHASE" --effort high` or `node scripts/rag-phase-launch-check.mjs --target "$TARGET_PHASE" --effort xhigh`. 2. Prove controller routing with the route-evidence schema. Hash this skill, helpers and phase skills. Dispatch the manifest-routed read-only probe; bind its ID and direct dispatch record. Stop on unverified route, runtime or capability. 3. Scan the plan, receipts, relevant code, and worktrees for conflicts. Preserve unrelated or quarantined work. 4. Record `TASK_BASE`; generate the brief; dispatch a fresh implementer; require proof, self-review and defined completion status. diff --git a/docs/agents/codex-cloud-environment.md b/docs/agents/codex-cloud-environment.md index 8999e3f627..4452f20e84 100644 --- a/docs/agents/codex-cloud-environment.md +++ b/docs/agents/codex-cloud-environment.md @@ -50,26 +50,29 @@ Use `docs/codex-cloud.md` as the environment contract: - In a fresh Cloud task, run `bash scripts/check-codex-cloud-raw-env.sh` before sourcing a profile or entering a login shell. It must report only provider variable names and presence, never values. The probe establishes presence in the unsanitized parent process, not where a - variable (such as `GH_TOKEN` or `OPENAI_BASE_URL`) originated, and repository edits cannot - remove a variable from an already-running process. When exit `1` / `FAIL`+`STOP` or a failed - credential check occurs, application execution (`npm run ensure`), live provider access, and - full runtime acceptance remain blocked and require a fresh task once the environment source is - cleared; however, explicitly requested local policy, documentation, and configuration inspection - and repair are permitted, along with scrubbed offline checks (`git diff --check`, - `npm run check:codex-cloud`, `npm run check:instructions`, `npm run check:decisions`, and offline - unit tests run through the generated profile and `~/.local/bin/{node,npm,npx}` command shims, - which `unset` `GH_TOKEN` and other provider variables before Node executes). Only exit `2` / - `FAIL-KNOWN` for `OPENAI_BASE_URL` alone may use - the restricted profile-and-shim continue path for broader provider-free app/runtime work; do not - generalize that allowance. Exit `2` is still a failed raw boundary — future automation must not - treat non-1 as success or as a blind retry. That name can redirect OpenAI-bound traffic, so never - invoke OpenAI clients from the raw parent or any binary that bypasses the - profile/`node`/`npm`/`npx` scrub. Then run `npm run check:codex-cloud` directly; it must report - the static-and-environment PASS line. Run `npm run check:codex-cloud -- --runtime` with - `CODEX_CLOUD_EXPECTED_BASE_SHA` set to the intended merge/base commit when the checkout has only - a task HEAD. Setup and maintenance may report freshness as unverified so provisioning remains - repairable, but explicit acceptance must not pass an arbitrary HEAD. The command shims load the - generated profile for normal `node`, `npm`, and `npx` work. Also run `npm run check:runtime` and + variable originated, and repository edits cannot remove a variable from an already-running + process. When exit `1` / `FAIL`+`STOP` or a failed credential check occurs, application + execution (`npm run ensure`), live provider access, and full runtime acceptance remain blocked + and require a fresh task once the environment source is cleared; however, explicitly requested + local policy, documentation, and configuration inspection and repair are permitted, along with + scrubbed offline checks (`git diff --check`, `npm run check:codex-cloud`, + `npm run check:instructions`, `npm run check:decisions`, and offline unit tests run after + sourcing `~/.clinical-kb-codex-cloud.sh` or through `~/.local/bin/{node,npm,npx}` command shims, + which `unset` `GH_TOKEN`, `OPENAI_BASE_URL`, and all other provider variables before Node + executes). Exit `2` / `FAIL-KNOWN` for the documented launcher-injected names (`OPENAI_BASE_URL` + and `GH_TOKEN`) uses the restricted profile-and-shim continue path for provider-free work; do + not generalize that allowance to other provider credentials. Exit `2` is still a failed raw + boundary — future automation must not treat non-1 as success or as a blind retry. Because + `OPENAI_BASE_URL` can redirect OpenAI-bound traffic and `GH_TOKEN` carries host GitHub + credentials, never invoke OpenAI or GitHub clients from the raw parent or any binary that + bypasses the profile/`node`/`npm`/`npx` scrub. In non-login shells (`bash -c`), source + `~/.clinical-kb-codex-cloud.sh` before running `npm run check:codex-cloud` so the scrubbed + profile is active; it must report the static-and-environment PASS line. Run + `npm run check:codex-cloud -- --runtime` with `CODEX_CLOUD_EXPECTED_BASE_SHA` set to the + intended merge/base commit when the checkout has only a task HEAD. Setup and maintenance may + report freshness as unverified so provisioning remains repairable, but explicit acceptance must + not pass an arbitrary HEAD. The command shims load the generated profile for normal `node`, + `npm`, and `npx` work. Also run `npm run check:runtime` and `npm run check:installed-lock-parity` before trusting a new or reset environment. A skipped browser install is not full browser readiness. Output is limited to approved mode values, presence booleans, full Git commit identities, and MCP server/command/environment-variable diff --git a/docs/agents/codex-reasoning-effort.md b/docs/agents/codex-reasoning-effort.md index 8a7d5be07b..71870468c0 100644 --- a/docs/agents/codex-reasoning-effort.md +++ b/docs/agents/codex-reasoning-effort.md @@ -15,16 +15,15 @@ It does not change the running main-chat model or reasoning effort. **Cloud reasoning effort and plain-language confirmation.** A running Cloud task cannot inspect or raise its own reasoning effort at runtime, and `.codex/config.toml` intentionally does not force a model or reasoning setting. -The general `[xhigh-confirmed]` prompt marker and prompt-resubmission gate were retired on 2026-10-16: -there is no `[xhigh-confirmed]` token requirement for ordinary or high-risk chat requests, and agents must no longer ask the user to resubmit a prompt with `[xhigh-confirmed]`. +The former Cloud prompt-marker and prompt-resubmission gate was retired on 2026-10-16: +there is no special token requirement for ordinary or high-risk chat requests, and agents must no longer ask the user to resubmit a prompt with a confirmation tag. When a request touches the high-consequence surfaces in the table below (architecture, Supabase migrations/RLS, RAG ranking surfaces, auth/privacy, or ingestion contracts), `xhigh` remains the recommended planning effort. Plain-language confirmation from the user (or an explicit instruction to proceed) suffices; accept it at face value without repeating a gate prompt or claiming to verify the runtime picker. Only if a high-consequence Cloud planning task starts with no indication of reasoning preference and material uncertainty remains, mention the `xhigh` recommendation once and -accept a plain-language reply. The specialist RAG upgrade programme (`docs/superpowers/rag-upgrade/` -and `scripts/rag-phase-launch-check.mjs`) retains its own CLI `--xhigh-confirmed` launch check. +accept a plain-language reply. Reasoning effort is a budget in the same way verification is a budget, and it is misspent the same way — by defaulting to the maximum instead of matching the spend to the risk. **Scale effort to how diff --git a/docs/codex-cloud.md b/docs/codex-cloud.md index c7bf08e72d..da9f13c945 100644 --- a/docs/codex-cloud.md +++ b/docs/codex-cloud.md @@ -371,28 +371,30 @@ presence in the unsanitized parent process, not where a variable (such as `GH_TO already-running process. Outcomes are name-scoped in the probe itself: - exit `0` / `PASS` — raw boundary clean -- exit `1` / `FAIL` + `STOP` — any unexpected provider name (for example `GH_TOKEN` or +- exit `1` / `FAIL` + `STOP` — any unexpected provider name (for example `SUPABASE_SERVICE_ROLE_KEY`); application execution, live provider access, and full runtime acceptance remain blocked and require a fresh task once the environment source is cleared, while explicitly requested local policy, documentation, and configuration inspection and repair (plus scrubbed offline checks through the profile and command shims) may proceed -- exit `2` / `FAIL-KNOWN` + `CONTINUE-RESTRICTED` — only the documented Personal Pro launcher - defect name `OPENAI_BASE_URL` +- exit `2` / `FAIL-KNOWN` + `CONTINUE-RESTRICTED` — only the documented Personal Pro launcher-injected + names `OPENAI_BASE_URL` and `GH_TOKEN` Exit `2` is still a failed raw boundary: humans/agents may continue only under this contract. Do not treat “non-1” or “retry on any failure” as success in future automation — wire the three -states explicitly. When the probe reports `FAIL-KNOWN` for `OPENAI_BASE_URL` alone, preserve that -name-only output for OpenAI support and continue provider-free work only through the generated -profile and command shims, followed by a passing `npm run check:codex-cloud`. Do not generalize -that restricted path for full app/runtime work to any other inherited name. When exit `1` reports -an unexpected name such as `GH_TOKEN`, do not run the application or contact live providers, but -do complete any explicitly requested local policy or documentation repairs and run scrubbed offline -checks (`git diff --check`, `npm run check:codex-cloud`, `npm run check:instructions`, -`npm run check:decisions`, and offline unit tests invoked via `~/.local/bin/node` or -`~/.local/bin/npm`, which load `~/.clinical-kb-codex-cloud.sh` and `unset` all provider variables). -An inherited `OPENAI_BASE_URL` can redirect OpenAI-bound traffic, so never call OpenAI clients from -the raw parent process or from binaries that bypass the profile/`node`/`npm`/`npx` shim scrub. A -sanitized child shell is never proof that the raw-parent boundary passed. +states explicitly. When the probe reports `FAIL-KNOWN` for `OPENAI_BASE_URL` or `GH_TOKEN`, preserve +that name-only output and continue provider-free work only through the generated +`~/.clinical-kb-codex-cloud.sh` profile and `~/.local/bin/{node,npm,npx}` command shims (in non-login +`bash -c` shells, source `~/.clinical-kb-codex-cloud.sh` first so `GH_TOKEN` and `OPENAI_BASE_URL` +are unset before running `npm run check:codex-cloud`). Do not generalize that restricted path for +full app/runtime work to any other inherited credential name. When exit `1` reports any other +unexpected name, do not run the application or contact live providers, but do complete any +explicitly requested local policy or documentation repairs and run scrubbed offline checks +(`git diff --check`, `npm run check:codex-cloud`, `npm run check:instructions`, +`npm run check:decisions`, and offline unit tests invoked after sourcing `~/.clinical-kb-codex-cloud.sh` +or via `~/.local/bin/node` and `~/.local/bin/npm`). An inherited `OPENAI_BASE_URL` can redirect +OpenAI-bound traffic, so never call OpenAI clients from the raw parent process or from binaries +that bypass the profile/`node`/`npm`/`npx` shim scrub. A sanitized child shell is never proof that +the raw-parent boundary passed. `npm run check:production-readiness` remains useful in the offline profile for local safeguards. Missing Supabase/OpenAI agent-phase credentials are reported as a provider capability gap and do diff --git a/docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md b/docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md index ba3b53c4ac..345ee582a2 100644 --- a/docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md +++ b/docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md @@ -1,9 +1,9 @@ # Decision: Retire the general Cloud xhigh prompt marker gate and allow local policy repair when raw-env checks fail - **Status:** decided 2026-10-16 -- **Source:** `docs/agents/codex-reasoning-effort.md`, find "prompt-resubmission gate were retired on 2026-10-16" -- **Retires:** `cloud-xhigh-confirmed-gate` +- **Source:** `docs/agents/codex-reasoning-effort.md`, find "former Cloud prompt-marker and prompt-resubmission gate was retired on 2026-10-16" +- **Retires:** `cloud-xhigh-marker-gate` -The owner retired the general `[xhigh-confirmed]` prompt marker and prompt-resubmission requirement in Codex Cloud so plain-language confirmation suffices when `xhigh` is recommended, while keeping the specialist RAG upgrade programme CLI launch check intact. The owner also clarified in `docs/agents/codex-cloud-environment.md` and `docs/codex-cloud.md` that a failed raw-environment credential check still blocks application execution and live provider access, but allows explicitly requested local policy/documentation inspection and repair alongside scrubbed offline checks. +The owner retired the Cloud `xhigh` prompt-marker and prompt-resubmission requirement across repository policies and Cloud phase launch checks so plain-language confirmation suffices when `xhigh` is recommended. The owner also clarified in `docs/agents/codex-cloud-environment.md` and `docs/codex-cloud.md` that an inherited `GH_TOKEN` or `OPENAI_BASE_URL` in the raw parent process uses the scrubbed profile-and-shim path and never blocks explicitly requested local policy/documentation inspection and repair or scrubbed offline checks. If this summary and the source ever differ, the source wins. diff --git a/docs/organisation/retired-rules.json b/docs/organisation/retired-rules.json index 61bada7b83..55c9aa3bc7 100644 --- a/docs/organisation/retired-rules.json +++ b/docs/organisation/retired-rules.json @@ -26,12 +26,12 @@ "record": "diff-integrity.json: scripts/gate-arbiter.mjs deleted in the owner-approved governance cut of 2026-09-17; gate receipts kept" }, { - "id": "cloud-xhigh-confirmed-gate", + "id": "cloud-xhigh-marker-gate", "retired": "2026-10-16", - "summary": "The general `[xhigh-confirmed]` prompt marker and resubmission gate in Codex Cloud were retired; plain-language confirmation suffices. Specialist RAG programme CLI launch checks (`--xhigh-confirmed`) remain.", - "pattern": "\\[xhigh-confirmed\\]|Cloud `?xhigh`? (confirmation )?gate|resubmit (the same request |a prompt )?with `?\\[xhigh-confirmed\\]", - "allowedContext": "no longer|removed|removal|retir(ed|ement)|there is no|formerly|previously|superseded|dropped|replaced|deprecated|gone|do not demand|without requiring|rag-phase-launch-check|programme-manifest", - "record": "docs/agents/codex-reasoning-effort.md, Cloud reasoning effort and plain-language confirmation: the general [xhigh-confirmed] prompt marker and prompt-resubmission gate were retired on 2026-10-16", + "summary": "The Cloud `xhigh` prompt marker and resubmission gate were retired; plain-language confirmation suffices.", + "pattern": "\\[xhigh-confirmed\\]|--xhigh-confirmed|xhighConfirmationMarker|Cloud `?xhigh`? (confirmation )?gate|resubmit (the same request |a prompt )?with `?\\[xhigh-confirmed\\]", + "allowedContext": "no longer|removed|removal|retir(ed|ement)|there is no|formerly|previously|superseded|dropped|replaced|deprecated|gone|do not demand|without requiring", + "record": "docs/agents/codex-reasoning-effort.md, Cloud reasoning effort and plain-language confirmation: the former Cloud prompt-marker and prompt-resubmission gate was retired on 2026-10-16", "decision": "docs/decisions/2026-10-16-remove-cloud-xhigh-marker-gate.md" } ] diff --git a/docs/scripts-index.md b/docs/scripts-index.md index 3a4bdef467..6aa0435c0c 100644 --- a/docs/scripts-index.md +++ b/docs/scripts-index.md @@ -17,30 +17,30 @@ migration has shipped (see `docs/maturity-backlog-workorders.md` L1). ## Runner & guard infrastructure [infra] -| Script | Role | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `run-heavy.mjs` | Acquires shared/exclusive cross-worktree leases (`test-run-lock.mjs`) so focused checks can overlap safely | -| `ci-coverage.mjs` | Derives whether `.github/workflows/ci.yml` actually re-runs a named gate for a given change scope (step/job `if:` guards evaluated, not just presence in the YAML); used by `browser-test-plan.mjs` to report honest CI coverage | -| `gate-receipts.mjs` | Content-addressed memoisation of `lint`/`typecheck`/Vitest so an unchanged gate is never rerun locally (never in CI) | -| `run-tsx.mjs`, `run-vitest.mjs`, `run-playwright.mjs`, `run-eval-safe.mjs` | Typed/test/e2e/eval entrypoint wrappers | -| `dev-free-port.mjs`, `ensure-local-server.mjs` | Project-stable localhost port selection + background server ensure | -| `design-sync.mjs`, `capture-mockup-screenshots.mjs` | Local design-sync CSS prep (`node scripts/design-sync.mjs`) + redesign "current" PNG pack after ensure (`node scripts/capture-mockup-screenshots.mjs`) | -| `check-node-engine.cjs`, `install-git-hooks.mjs`, `guard-push.mjs`, `guard-next-build.mjs` | Install/preflight guards | -| `setup-codex-cloud.sh`, `maintain-codex-cloud.sh`, `install-codex-cloud-command-shims.sh`, `check-codex-cloud-raw-env.sh`, `delete-codex-cloud-branch-with-pat.sh`, `check-codex-cloud-setup.mjs`, `check-github-shell-access.mjs`, `ensure-codex-cloud-git-remote.mjs` | Reproducible Codex Cloud toolchain/profile setup, profile-loading Node command shims, a pre-profile name-only credential probe (`FAIL-KNOWN`/`exit 2` only for documented `OPENAI_BASE_URL`; hard `STOP` for app/provider work on unexpected names while allowing requested local policy repair and scrubbed offline checks), an operator-only non-Cloud PAT branch-deletion helper, sanitized Personal Pro capability/route acceptance, fail-closed GitHub shell control-plane acceptance (`check:github-shell-access` = offline self-test; `check:github-shell-access:live` = provider-backed identity/permission/API plus non-mutating push proof), and safe credential-free `origin` repair | -| `setup-claude-cloud.sh`, `apply-claude-cloud-profile.mjs` | Claude Code on the web container parity. Tiered, marker-guarded provisioner (`profile`, `plugins`, `gh`, `deno`, `browsers`, `python`) wired as the second `SessionStart` hook via `--session`, which runs the cheap tiers inline and detaches the ten-minute browser/OCR ones; plus the applier that unpacks `.claude/cloud-profile/` into the container's `~/.claude` (settings deep-merged, memories never clobbered). Both refuse to run unless `CLAUDE_CODE_REMOTE=true`. See `docs/claude-cloud.md` | -| `ci-change-scope.mjs`, `pr-policy.mjs`, `pr-mergeability.mjs` | CI change classification + PR policy + conflict signal (self-tested via `check:ci-scope`/`check:pr-policy`/`check:pr-mergeability`) | -| `check-outstanding-issues.mjs`, `check-pr-mergeability-workflow.mjs` | Outstanding-issues ID/marker/no-driver guard + PR mergeability workflow contract | -| `outstanding-issues.mjs` | Writer for `docs/outstanding-issues.md` (`issues:add` / `issues:done` / `issues:update`) — allocates the id, picks the right table, escapes `\|`, and re-runs the guard on its own output. Never hand-edit that file, as with `ledger:append` | -| `check-ledger-stamp-retention.mjs` | On-demand branch-safety check (`check:ledger-stamp-retention`, not wired into CI/`verify:cheap`): derives touched `docs/outstanding-issues.md` row IDs from git history between merge-base and `HEAD`, then verifies each still carries its branch content post-merge/rebase, catching silent conflict-resolution loss | -| `check-installed-lock-parity.mjs`, `phone-chrome-plan.mjs`, `verify-phone-chrome.mjs`, `playwright-browser-preflight.mjs` | Lock-trust preflight, change-scoped phone contracts, and Playwright browser-binary preflight before build | -| `audit-merge-loss.mjs` | Advisory blob-comparison sweep for merged PRs a later merge resolution silently reverted (`audit:merge-loss`); names the PR and files and exits 0 — a deliberate revert is identical at blob level, so a positive needs human confirmation | -| `final-merge-audit.mjs` | Fail-closed local merge-tree audit; explicit provider mode adds PR/check/thread/tree/deployment proof | -| `child-process-result.mjs`, `cli-utils.ts`, `productivity-core.mjs` | Shared helpers | -| `test-focused.mjs`, `test-run-selection.mjs`, `test-cache-path.mjs`, `test-environment.mjs` | Backs `npm run test:focused` — change-scoped selection, cache pathing, env setup; fails closed for deleted files and test infrastructure | -| `primary-checkout-lease.mjs`, `test-run-lock.mjs`, `clean-worktree.mjs`, `worktree-inventory.mjs` | Cross-worktree lease arbitration for the primary checkout, plus report-only registered-worktree and explicit-root fleet inventory | -| `resolve-tsx-cli.mjs`, `register-server-only.mjs`, `enable-server-only-stub.mjs` | tsx CLI resolution and `server-only` import shims | -| `check-format-changed.mjs`, `check-base-freshness.mjs`, `check-local-presence.mjs` | Push-time helpers behind `guard-push.mjs`: changed-file formatting, stale-base and local-presence checks | -| `yaml-contract.mjs`, `sensitive-text.mjs`, `design-system-contract-utils.mjs` | Shared parsing/redaction/contract helpers used by the gates | +| Script | Role | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `run-heavy.mjs` | Acquires shared/exclusive cross-worktree leases (`test-run-lock.mjs`) so focused checks can overlap safely | +| `ci-coverage.mjs` | Derives whether `.github/workflows/ci.yml` actually re-runs a named gate for a given change scope (step/job `if:` guards evaluated, not just presence in the YAML); used by `browser-test-plan.mjs` to report honest CI coverage | +| `gate-receipts.mjs` | Content-addressed memoisation of `lint`/`typecheck`/Vitest so an unchanged gate is never rerun locally (never in CI) | +| `run-tsx.mjs`, `run-vitest.mjs`, `run-playwright.mjs`, `run-eval-safe.mjs` | Typed/test/e2e/eval entrypoint wrappers | +| `dev-free-port.mjs`, `ensure-local-server.mjs` | Project-stable localhost port selection + background server ensure | +| `design-sync.mjs`, `capture-mockup-screenshots.mjs` | Local design-sync CSS prep (`node scripts/design-sync.mjs`) + redesign "current" PNG pack after ensure (`node scripts/capture-mockup-screenshots.mjs`) | +| `check-node-engine.cjs`, `install-git-hooks.mjs`, `guard-push.mjs`, `guard-next-build.mjs` | Install/preflight guards | +| `setup-codex-cloud.sh`, `maintain-codex-cloud.sh`, `install-codex-cloud-command-shims.sh`, `check-codex-cloud-raw-env.sh`, `delete-codex-cloud-branch-with-pat.sh`, `check-codex-cloud-setup.mjs`, `check-github-shell-access.mjs`, `ensure-codex-cloud-git-remote.mjs` | Reproducible Codex Cloud toolchain/profile setup, profile-loading Node command shims, a pre-profile name-only credential probe (`FAIL-KNOWN`/`exit 2` only for documented `OPENAI_BASE_URL` / `GH_TOKEN`; hard `STOP` for app/provider work on unexpected names while allowing requested local policy repair and scrubbed offline checks), an operator-only non-Cloud PAT branch-deletion helper, sanitized Personal Pro capability/route acceptance, fail-closed GitHub shell control-plane acceptance (`check:github-shell-access` = offline self-test; `check:github-shell-access:live` = provider-backed identity/permission/API plus non-mutating push proof), and safe credential-free `origin` repair | +| `setup-claude-cloud.sh`, `apply-claude-cloud-profile.mjs` | Claude Code on the web container parity. Tiered, marker-guarded provisioner (`profile`, `plugins`, `gh`, `deno`, `browsers`, `python`) wired as the second `SessionStart` hook via `--session`, which runs the cheap tiers inline and detaches the ten-minute browser/OCR ones; plus the applier that unpacks `.claude/cloud-profile/` into the container's `~/.claude` (settings deep-merged, memories never clobbered). Both refuse to run unless `CLAUDE_CODE_REMOTE=true`. See `docs/claude-cloud.md` | +| `ci-change-scope.mjs`, `pr-policy.mjs`, `pr-mergeability.mjs` | CI change classification + PR policy + conflict signal (self-tested via `check:ci-scope`/`check:pr-policy`/`check:pr-mergeability`) | +| `check-outstanding-issues.mjs`, `check-pr-mergeability-workflow.mjs` | Outstanding-issues ID/marker/no-driver guard + PR mergeability workflow contract | +| `outstanding-issues.mjs` | Writer for `docs/outstanding-issues.md` (`issues:add` / `issues:done` / `issues:update`) — allocates the id, picks the right table, escapes `\|`, and re-runs the guard on its own output. Never hand-edit that file, as with `ledger:append` | +| `check-ledger-stamp-retention.mjs` | On-demand branch-safety check (`check:ledger-stamp-retention`, not wired into CI/`verify:cheap`): derives touched `docs/outstanding-issues.md` row IDs from git history between merge-base and `HEAD`, then verifies each still carries its branch content post-merge/rebase, catching silent conflict-resolution loss | +| `check-installed-lock-parity.mjs`, `phone-chrome-plan.mjs`, `verify-phone-chrome.mjs`, `playwright-browser-preflight.mjs` | Lock-trust preflight, change-scoped phone contracts, and Playwright browser-binary preflight before build | +| `audit-merge-loss.mjs` | Advisory blob-comparison sweep for merged PRs a later merge resolution silently reverted (`audit:merge-loss`); names the PR and files and exits 0 — a deliberate revert is identical at blob level, so a positive needs human confirmation | +| `final-merge-audit.mjs` | Fail-closed local merge-tree audit; explicit provider mode adds PR/check/thread/tree/deployment proof | +| `child-process-result.mjs`, `cli-utils.ts`, `productivity-core.mjs` | Shared helpers | +| `test-focused.mjs`, `test-run-selection.mjs`, `test-cache-path.mjs`, `test-environment.mjs` | Backs `npm run test:focused` — change-scoped selection, cache pathing, env setup; fails closed for deleted files and test infrastructure | +| `primary-checkout-lease.mjs`, `test-run-lock.mjs`, `clean-worktree.mjs`, `worktree-inventory.mjs` | Cross-worktree lease arbitration for the primary checkout, plus report-only registered-worktree and explicit-root fleet inventory | +| `resolve-tsx-cli.mjs`, `register-server-only.mjs`, `enable-server-only-stub.mjs` | tsx CLI resolution and `server-only` import shims | +| `check-format-changed.mjs`, `check-base-freshness.mjs`, `check-local-presence.mjs` | Push-time helpers behind `guard-push.mjs`: changed-file formatting, stale-base and local-presence checks | +| `yaml-contract.mjs`, `sensitive-text.mjs`, `design-system-contract-utils.mjs` | Shared parsing/redaction/contract helpers used by the gates | ## Verification gates [live] diff --git a/docs/superpowers/rag-upgrade/CLOUD-EXECUTION-PROMPT.md b/docs/superpowers/rag-upgrade/CLOUD-EXECUTION-PROMPT.md index 5875e25c77..b4b8d0c4d3 100644 --- a/docs/superpowers/rag-upgrade/CLOUD-EXECUTION-PROMPT.md +++ b/docs/superpowers/rag-upgrade/CLOUD-EXECUTION-PROMPT.md @@ -2,7 +2,7 @@ Use the final handover message's filled prompt, not this unfilled template. Run one fresh Cloud task per P00–P17 phase. Before launch, set `TARGET_PHASE`, `PACKAGE_SOURCE_REF`, immutable `PACKAGE_HEAD_SHA`, `PACKAGE_BASE_SHA`, `PROGRAMME_BRANCH` and the matching UI effort from the manifest. -For a high phase, the prompt begins with `TARGET_PHASE=...` and contains no xhigh confirmation claim. For an xhigh phase, the first line is the repository's exact xhigh confirmation marker and the second line declares the target. A running task cannot raise itself. +Select the matching high or xhigh effort from the manifest in the Cloud reasoning control before launch, and begin the prompt with `TARGET_PHASE=...`. A running task cannot raise itself. ## Shared prompt body @@ -16,9 +16,9 @@ This prompt authorizes read-only repository inspection, offline/provider-free wo ### First command and bootstrap -Before login/profile/setup, run the raw Cloud environment check exactly as `cloud/START-HERE.md` requires. Exit 1 hard-stops; exit 2 uses only the documented `OPENAI_BASE_URL` restricted profile/shim path. Then perform Cloud-equivalent identity/branch/status checks, setup and shims, direct static Cloud check, runtime Cloud check pinned to `PACKAGE_BASE_SHA`, runtime and lock parity. +Before login/profile/setup, run the raw Cloud environment check exactly as `cloud/START-HERE.md` requires. Exit 1 hard-stops; exit 2 uses only the documented restricted profile/shim path. Then perform Cloud-equivalent identity/branch/status checks, setup and shims, direct static Cloud check, runtime Cloud check pinned to `PACKAGE_BASE_SHA`, runtime and lock parity. -For P00, fetch `PACKAGE_SOURCE_REF`, verify exact `PACKAGE_HEAD_SHA`, create `PROGRAMME_BRANCH` from it and run the package publish check. For P01–P17, fetch the exact remote programme tip with no rebase. Run the tracked launch helper with the declared target/effort (and the xhigh-confirmed flag only for an xhigh launch), package parity and `npm run plans:rag:receipts:check -- --before TARGET_PHASE`. The declared target must be exactly next; never select a different phase after launch. +For P00, fetch `PACKAGE_SOURCE_REF`, verify exact `PACKAGE_HEAD_SHA`, create `PROGRAMME_BRANCH` from it and run the package publish check. For P01–P17, fetch the exact remote programme tip with no rebase. Run the tracked launch helper with the declared target/effort, package parity and `npm run plans:rag:receipts:check -- --before TARGET_PHASE`. The declared target must be exactly next; never select a different phase after launch. ### Required knowledge and capabilities diff --git a/docs/superpowers/rag-upgrade/canonical/START-HERE.cloud.md b/docs/superpowers/rag-upgrade/canonical/START-HERE.cloud.md index 5ba05a7b68..525c625be5 100644 --- a/docs/superpowers/rag-upgrade/canonical/START-HERE.cloud.md +++ b/docs/superpowers/rag-upgrade/canonical/START-HERE.cloud.md @@ -7,11 +7,11 @@ This package executes P00–P17 only. One fresh Cloud session completes exactly The user prompt must declare `TARGET_PHASE`, `PACKAGE_SOURCE_REF`, `PACKAGE_HEAD_SHA`, `PACKAGE_BASE_SHA`, `PROGRAMME_BRANCH` and selected Cloud effort. Do not inspect receipts to choose a phase after launch. Confirm the declared target is exactly next using the receipt checker. - Use high for P00, P04, P10 and P11. -- Use xhigh for every other P01–P17 phase. The prompt must begin with the exact repository xhigh confirmation marker and the user must select xhigh in the Cloud control before launch. +- Use xhigh for every other P01–P17 phase. Select xhigh in the Cloud control before launch. -If target, prompt marker or UI effort is wrong, stop before substantive inspection. Cloud cannot raise its own effort. +If target or UI effort is wrong, stop before substantive inspection. Cloud cannot raise its own effort. -As the first repository-local validation after the raw boundary and setup, run `node scripts/rag-phase-launch-check.mjs --target TARGET_PHASE --effort SELECTED_EFFORT`. Add `--xhigh-confirmed` only when the xhigh prompt marker is present. A failure stops the task. +As the first repository-local validation after the raw boundary and setup, run `node scripts/rag-phase-launch-check.mjs --target TARGET_PHASE --effort SELECTED_EFFORT`. A failure stops the task. ## Raw environment boundary — first command diff --git a/docs/superpowers/rag-upgrade/canonical/execution-order.md b/docs/superpowers/rag-upgrade/canonical/execution-order.md index ca0cfce17e..c2737b6738 100644 --- a/docs/superpowers/rag-upgrade/canonical/execution-order.md +++ b/docs/superpowers/rag-upgrade/canonical/execution-order.md @@ -15,7 +15,7 @@ Every phase owns exactly the plan tasks listed in `programme-manifest.json`. Eve | high | P00, P04, P10, P11 | high | manifest high/xhigh | | xhigh | P01–P03, P05–P09, P12A–P17 | high | xhigh | -The exact lettered phase list is in the manifest and is machine-validated. `TARGET_PHASE` must be present before substantive inspection. A running Cloud task cannot raise its own effort. An xhigh target therefore starts from the xhigh launch prompt with the repository confirmation marker; a high target starts from the high prompt. Implementations remain high because the task plans name files, interfaces, ordered steps and proof gates. P00 and P11 may use Terra/high implementers; all other implementation and all reviews use Sol at the manifest effort. No provider mapping or silent fallback is allowed. +The exact lettered phase list is in the manifest and is machine-validated. `TARGET_PHASE` must be present before substantive inspection. A running Cloud task cannot raise its own effort, so select the matching high or xhigh effort in the Cloud control before launching the phase. Implementations remain high because the task plans name files, interfaces, ordered steps and proof gates. P00 and P11 may use Terra/high implementers; all other implementation and all reviews use Sol at the manifest effort. No provider mapping or silent fallback is allowed. Before dispatch, prove the controller route and one real fresh subagent dispatch from authoritative sanitized host metadata. Each task receipt binds the controller, implementer, task reviewer and phase reviewer separately. Self-report is invalid evidence. diff --git a/docs/superpowers/rag-upgrade/canonical/programme-manifest.json b/docs/superpowers/rag-upgrade/canonical/programme-manifest.json index 9853c5d624..38e0e3f743 100644 --- a/docs/superpowers/rag-upgrade/canonical/programme-manifest.json +++ b/docs/superpowers/rag-upgrade/canonical/programme-manifest.json @@ -231,8 +231,7 @@ "P16D", "P17" ], - "xhighConfirmationMarker": "[xhigh-confirmed]", - "launchContract": "TARGET_PHASE must be supplied before repository inspection. The Cloud UI effort must match the target launch set. An xhigh target prompt must begin with the confirmation marker; a high target prompt must not claim that marker.", + "launchContract": "TARGET_PHASE must be supplied before repository inspection. The Cloud UI effort must match the target launch set.", "allowedEscalations": [ { "fromModel": "gpt-5.6-terra", diff --git a/docs/superpowers/rag-upgrade/canonical/sdd-execution.md b/docs/superpowers/rag-upgrade/canonical/sdd-execution.md index 2c7044cc06..4c70b04994 100644 --- a/docs/superpowers/rag-upgrade/canonical/sdd-execution.md +++ b/docs/superpowers/rag-upgrade/canonical/sdd-execution.md @@ -4,7 +4,7 @@ The tracked `.agents/skills/rag-cloud-sdd/SKILL.md` is the self-contained Cloud ## Capability and route preflight -Before repository inspection, the launch prompt supplies `TARGET_PHASE` and the selected high/xhigh effort. Verify the target against the manifest and accepted receipts without selecting another phase. An xhigh target must carry the exact repository confirmation marker. Stop on wrong target or effort. +Before repository inspection, the launch prompt supplies `TARGET_PHASE` and the selected high/xhigh effort. Verify the target against the manifest and accepted receipts without selecting another phase. Stop on wrong target or effort. Read and hash the controller skill/helper and every repo-local skill in the phase profiles. Dispatch one fresh read-only probe agent and record the dispatch tool, agent ID and authoritative host metadata. No callable fresh-agent runtime means `BLOCKED_MISSING_SUBAGENT_RUNTIME`; a missing skill/helper means `BLOCKED_MISSING_CAPABILITY`. diff --git a/docs/superpowers/rag-upgrade/cloud/START-HERE.md b/docs/superpowers/rag-upgrade/cloud/START-HERE.md index 5ba05a7b68..525c625be5 100644 --- a/docs/superpowers/rag-upgrade/cloud/START-HERE.md +++ b/docs/superpowers/rag-upgrade/cloud/START-HERE.md @@ -7,11 +7,11 @@ This package executes P00–P17 only. One fresh Cloud session completes exactly The user prompt must declare `TARGET_PHASE`, `PACKAGE_SOURCE_REF`, `PACKAGE_HEAD_SHA`, `PACKAGE_BASE_SHA`, `PROGRAMME_BRANCH` and selected Cloud effort. Do not inspect receipts to choose a phase after launch. Confirm the declared target is exactly next using the receipt checker. - Use high for P00, P04, P10 and P11. -- Use xhigh for every other P01–P17 phase. The prompt must begin with the exact repository xhigh confirmation marker and the user must select xhigh in the Cloud control before launch. +- Use xhigh for every other P01–P17 phase. Select xhigh in the Cloud control before launch. -If target, prompt marker or UI effort is wrong, stop before substantive inspection. Cloud cannot raise its own effort. +If target or UI effort is wrong, stop before substantive inspection. Cloud cannot raise its own effort. -As the first repository-local validation after the raw boundary and setup, run `node scripts/rag-phase-launch-check.mjs --target TARGET_PHASE --effort SELECTED_EFFORT`. Add `--xhigh-confirmed` only when the xhigh prompt marker is present. A failure stops the task. +As the first repository-local validation after the raw boundary and setup, run `node scripts/rag-phase-launch-check.mjs --target TARGET_PHASE --effort SELECTED_EFFORT`. A failure stops the task. ## Raw environment boundary — first command diff --git a/docs/superpowers/rag-upgrade/cloud/execution-order.md b/docs/superpowers/rag-upgrade/cloud/execution-order.md index ca0cfce17e..c2737b6738 100644 --- a/docs/superpowers/rag-upgrade/cloud/execution-order.md +++ b/docs/superpowers/rag-upgrade/cloud/execution-order.md @@ -15,7 +15,7 @@ Every phase owns exactly the plan tasks listed in `programme-manifest.json`. Eve | high | P00, P04, P10, P11 | high | manifest high/xhigh | | xhigh | P01–P03, P05–P09, P12A–P17 | high | xhigh | -The exact lettered phase list is in the manifest and is machine-validated. `TARGET_PHASE` must be present before substantive inspection. A running Cloud task cannot raise its own effort. An xhigh target therefore starts from the xhigh launch prompt with the repository confirmation marker; a high target starts from the high prompt. Implementations remain high because the task plans name files, interfaces, ordered steps and proof gates. P00 and P11 may use Terra/high implementers; all other implementation and all reviews use Sol at the manifest effort. No provider mapping or silent fallback is allowed. +The exact lettered phase list is in the manifest and is machine-validated. `TARGET_PHASE` must be present before substantive inspection. A running Cloud task cannot raise its own effort, so select the matching high or xhigh effort in the Cloud control before launching the phase. Implementations remain high because the task plans name files, interfaces, ordered steps and proof gates. P00 and P11 may use Terra/high implementers; all other implementation and all reviews use Sol at the manifest effort. No provider mapping or silent fallback is allowed. Before dispatch, prove the controller route and one real fresh subagent dispatch from authoritative sanitized host metadata. Each task receipt binds the controller, implementer, task reviewer and phase reviewer separately. Self-report is invalid evidence. diff --git a/docs/superpowers/rag-upgrade/cloud/programme-manifest.json b/docs/superpowers/rag-upgrade/cloud/programme-manifest.json index 9853c5d624..38e0e3f743 100644 --- a/docs/superpowers/rag-upgrade/cloud/programme-manifest.json +++ b/docs/superpowers/rag-upgrade/cloud/programme-manifest.json @@ -231,8 +231,7 @@ "P16D", "P17" ], - "xhighConfirmationMarker": "[xhigh-confirmed]", - "launchContract": "TARGET_PHASE must be supplied before repository inspection. The Cloud UI effort must match the target launch set. An xhigh target prompt must begin with the confirmation marker; a high target prompt must not claim that marker.", + "launchContract": "TARGET_PHASE must be supplied before repository inspection. The Cloud UI effort must match the target launch set.", "allowedEscalations": [ { "fromModel": "gpt-5.6-terra", diff --git a/docs/superpowers/rag-upgrade/cloud/sdd-execution.md b/docs/superpowers/rag-upgrade/cloud/sdd-execution.md index 2c7044cc06..4c70b04994 100644 --- a/docs/superpowers/rag-upgrade/cloud/sdd-execution.md +++ b/docs/superpowers/rag-upgrade/cloud/sdd-execution.md @@ -4,7 +4,7 @@ The tracked `.agents/skills/rag-cloud-sdd/SKILL.md` is the self-contained Cloud ## Capability and route preflight -Before repository inspection, the launch prompt supplies `TARGET_PHASE` and the selected high/xhigh effort. Verify the target against the manifest and accepted receipts without selecting another phase. An xhigh target must carry the exact repository confirmation marker. Stop on wrong target or effort. +Before repository inspection, the launch prompt supplies `TARGET_PHASE` and the selected high/xhigh effort. Verify the target against the manifest and accepted receipts without selecting another phase. Stop on wrong target or effort. Read and hash the controller skill/helper and every repo-local skill in the phase profiles. Dispatch one fresh read-only probe agent and record the dispatch tool, agent ID and authoritative host metadata. No callable fresh-agent runtime means `BLOCKED_MISSING_SUBAGENT_RUNTIME`; a missing skill/helper means `BLOCKED_MISSING_CAPABILITY`. diff --git a/docs/superpowers/rag-upgrade/local/execution-order.md b/docs/superpowers/rag-upgrade/local/execution-order.md index ca0cfce17e..c2737b6738 100644 --- a/docs/superpowers/rag-upgrade/local/execution-order.md +++ b/docs/superpowers/rag-upgrade/local/execution-order.md @@ -15,7 +15,7 @@ Every phase owns exactly the plan tasks listed in `programme-manifest.json`. Eve | high | P00, P04, P10, P11 | high | manifest high/xhigh | | xhigh | P01–P03, P05–P09, P12A–P17 | high | xhigh | -The exact lettered phase list is in the manifest and is machine-validated. `TARGET_PHASE` must be present before substantive inspection. A running Cloud task cannot raise its own effort. An xhigh target therefore starts from the xhigh launch prompt with the repository confirmation marker; a high target starts from the high prompt. Implementations remain high because the task plans name files, interfaces, ordered steps and proof gates. P00 and P11 may use Terra/high implementers; all other implementation and all reviews use Sol at the manifest effort. No provider mapping or silent fallback is allowed. +The exact lettered phase list is in the manifest and is machine-validated. `TARGET_PHASE` must be present before substantive inspection. A running Cloud task cannot raise its own effort, so select the matching high or xhigh effort in the Cloud control before launching the phase. Implementations remain high because the task plans name files, interfaces, ordered steps and proof gates. P00 and P11 may use Terra/high implementers; all other implementation and all reviews use Sol at the manifest effort. No provider mapping or silent fallback is allowed. Before dispatch, prove the controller route and one real fresh subagent dispatch from authoritative sanitized host metadata. Each task receipt binds the controller, implementer, task reviewer and phase reviewer separately. Self-report is invalid evidence. diff --git a/docs/superpowers/rag-upgrade/local/programme-manifest.json b/docs/superpowers/rag-upgrade/local/programme-manifest.json index 9853c5d624..38e0e3f743 100644 --- a/docs/superpowers/rag-upgrade/local/programme-manifest.json +++ b/docs/superpowers/rag-upgrade/local/programme-manifest.json @@ -231,8 +231,7 @@ "P16D", "P17" ], - "xhighConfirmationMarker": "[xhigh-confirmed]", - "launchContract": "TARGET_PHASE must be supplied before repository inspection. The Cloud UI effort must match the target launch set. An xhigh target prompt must begin with the confirmation marker; a high target prompt must not claim that marker.", + "launchContract": "TARGET_PHASE must be supplied before repository inspection. The Cloud UI effort must match the target launch set.", "allowedEscalations": [ { "fromModel": "gpt-5.6-terra", diff --git a/docs/superpowers/rag-upgrade/local/sdd-execution.md b/docs/superpowers/rag-upgrade/local/sdd-execution.md index 2c7044cc06..4c70b04994 100644 --- a/docs/superpowers/rag-upgrade/local/sdd-execution.md +++ b/docs/superpowers/rag-upgrade/local/sdd-execution.md @@ -4,7 +4,7 @@ The tracked `.agents/skills/rag-cloud-sdd/SKILL.md` is the self-contained Cloud ## Capability and route preflight -Before repository inspection, the launch prompt supplies `TARGET_PHASE` and the selected high/xhigh effort. Verify the target against the manifest and accepted receipts without selecting another phase. An xhigh target must carry the exact repository confirmation marker. Stop on wrong target or effort. +Before repository inspection, the launch prompt supplies `TARGET_PHASE` and the selected high/xhigh effort. Verify the target against the manifest and accepted receipts without selecting another phase. Stop on wrong target or effort. Read and hash the controller skill/helper and every repo-local skill in the phase profiles. Dispatch one fresh read-only probe agent and record the dispatch tool, agent ID and authoritative host metadata. No callable fresh-agent runtime means `BLOCKED_MISSING_SUBAGENT_RUNTIME`; a missing skill/helper means `BLOCKED_MISSING_CAPABILITY`. diff --git a/scripts/build-rag-plan-packages.mjs b/scripts/build-rag-plan-packages.mjs index 2b8d771762..c75f891b09 100644 --- a/scripts/build-rag-plan-packages.mjs +++ b/scripts/build-rag-plan-packages.mjs @@ -167,9 +167,6 @@ function validateCanonicalBodies() { ) { errors.push("programme-manifest.json: adaptive effort launch sets must partition every Cloud phase exactly once"); } - if (manifest.adaptiveEffortPolicy?.xhighConfirmationMarker !== "[xhigh-confirmed]") { - errors.push("programme-manifest.json: xhigh confirmation marker must match the repository Cloud gate"); - } if (manifest.defaultAgentPolicy?.allowModelFallback !== false) { errors.push("programme-manifest.json: model fallback must remain disabled"); } diff --git a/scripts/check-codex-cloud-raw-env.sh b/scripts/check-codex-cloud-raw-env.sh index 9c14e16604..719ff229f1 100755 --- a/scripts/check-codex-cloud-raw-env.sh +++ b/scripts/check-codex-cloud-raw-env.sh @@ -11,9 +11,10 @@ set -Eeuo pipefail # 1 — unexpected provider variable names present; app execution and provider # access require a fresh task, while explicitly requested local policy/doc # repair and scrubbed offline checks may proceed -# 2 — only the documented Personal Pro launcher defect (`OPENAI_BASE_URL`) is -# present. The raw boundary still failed; continue only through the -# generated profile and command shims, never by treating this as a pass. +# 2 — only the documented Personal Pro launcher defect names (`OPENAI_BASE_URL`, +# `GH_TOKEN`) are present. The raw boundary still failed; continue only +# through the generated profile and command shims, never by treating this +# as a pass. provider_variables=( OPENAI_API_KEY OPENAI_ORG_ID OPENAI_PROJECT_ID OPENAI_BASE_URL NEXT_PUBLIC_SUPABASE_URL NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY NEXT_PUBLIC_SUPABASE_ANON_KEY @@ -30,9 +31,9 @@ provider_variables=( E2E_AUTH_ENABLED E2E_USER_EMAIL E2E_USER_PASSWORD ALLOW_PROVIDER_TESTS ) -# Name-scoped allowance: only this inherited name may use the restricted continue +# Name-scoped allowance: only these inherited names may use the restricted continue # path. Any other provider name remains a hard stop. -known_launcher_defect_variables=(OPENAI_BASE_URL) +known_launcher_defect_variables=(OPENAI_BASE_URL GH_TOKEN) present=() for name in "${provider_variables[@]}"; do diff --git a/scripts/check-codex-cloud-setup.mjs b/scripts/check-codex-cloud-setup.mjs index 9ae1c096ca..74152e44c6 100644 --- a/scripts/check-codex-cloud-setup.mjs +++ b/scripts/check-codex-cloud-setup.mjs @@ -1114,7 +1114,7 @@ function validateCheckoutAndRawEnvironmentContracts(sources, errors) { requireMatch( errors, rawEnvironmentProbe, - /known_launcher_defect_variables=\(OPENAI_BASE_URL\)/, + /known_launcher_defect_variables=\(OPENAI_BASE_URL(?: GH_TOKEN)?\)/, "Raw Cloud environment probe must name-scope the OPENAI_BASE_URL launcher-defect allowance.", ); requireMatch( diff --git a/scripts/rag-phase-launch-check.mjs b/scripts/rag-phase-launch-check.mjs index 9bb087a6ae..eb58aa9af5 100644 --- a/scripts/rag-phase-launch-check.mjs +++ b/scripts/rag-phase-launch-check.mjs @@ -37,12 +37,5 @@ const expectedEffort = manifest.adaptiveEffortPolicy.highLaunchPhases.includes(t if (selectedEffort !== expectedEffort) { fail(`Cloud effort must be ${expectedEffort} for ${target}`, "BLOCKED_WRONG_REASONING_EFFORT"); } -const xhighConfirmed = process.argv.includes("--xhigh-confirmed"); -if (expectedEffort === "xhigh" && !xhighConfirmed) { - fail("xhigh target lacks the user confirmation marker", "BLOCKED_XHIGH_CONFIRMATION_MISSING"); -} -if (expectedEffort === "high" && xhighConfirmed) { - fail("high target must use the high launch prompt", "BLOCKED_WRONG_LAUNCH_PROFILE"); -} console.log(`[rag-phase-launch] PASS: ${target} requires ${expectedEffort}; launch profile matches.`); diff --git a/tests/codex-cloud-setup.test.ts b/tests/codex-cloud-setup.test.ts index 552dddf1a0..f7e428020b 100644 --- a/tests/codex-cloud-setup.test.ts +++ b/tests/codex-cloud-setup.test.ts @@ -633,19 +633,26 @@ describe("Codex Cloud environment contract", () => { expect(result.stderr).not.toContain(secret); }); - it("name-scopes the documented OPENAI_BASE_URL launcher defect separately from unexpected leaks", () => { + it("name-scopes the documented OPENAI_BASE_URL and GH_TOKEN launcher defects separately from unexpected leaks", () => { const known = spawnSync(bashCommand, ["scripts/check-codex-cloud-raw-env.sh"], { cwd: repoRoot, encoding: "utf8", - env: { PATH: process.env.PATH, NODE_ENV: "test", OPENAI_BASE_URL: "https://example.invalid" }, + env: { + PATH: process.env.PATH, + NODE_ENV: "test", + OPENAI_BASE_URL: "https://example.invalid", + GH_TOKEN: "gho_never_print_known_token", + }, }); expect(known.status).toBe(2); expect(known.stderr).toContain("FAIL-KNOWN:"); expect(known.stderr).toContain("OPENAI_BASE_URL"); + expect(known.stderr).toContain("GH_TOKEN"); expect(known.stderr).toContain("CONTINUE-RESTRICTED:"); expect(known.stderr).toContain("redirect OpenAI-bound traffic"); expect(known.stderr).toContain("bypasses the profile/shim scrub"); expect(known.stderr).not.toContain("https://example.invalid"); + expect(known.stderr).not.toContain("gho_never_print_known_token"); const mixed = spawnSync(bashCommand, ["scripts/check-codex-cloud-raw-env.sh"], { cwd: repoRoot, @@ -654,6 +661,7 @@ describe("Codex Cloud environment contract", () => { PATH: process.env.PATH, NODE_ENV: "test", OPENAI_BASE_URL: "https://example.invalid", + GH_TOKEN: "gho_never_print_known_token", SUPABASE_SERVICE_ROLE_KEY: "never-print-service-role", }, }); @@ -662,6 +670,7 @@ describe("Codex Cloud environment contract", () => { expect(mixed.stderr).toContain("STOP:"); expect(mixed.stderr).toContain("SUPABASE_SERVICE_ROLE_KEY"); expect(mixed.stderr).not.toContain("never-print-service-role"); + expect(mixed.stderr).not.toContain("gho_never_print_known_token"); expect(mixed.stderr).not.toContain("CONTINUE-RESTRICTED:"); }); diff --git a/tests/rag-local-agent-policy.test.ts b/tests/rag-local-agent-policy.test.ts index b6aab1e660..8d6b634c2c 100644 --- a/tests/rag-local-agent-policy.test.ts +++ b/tests/rag-local-agent-policy.test.ts @@ -213,9 +213,7 @@ describe("local smart allocation", () => { ]), ); expect(result.dispatch.model).toBe("gpt-6-astra"); - expect( - cli("scripts/rag-phase-launch-check.mjs", ["--target", "P01", "--effort", "xhigh", "--xhigh-confirmed"]), - ).toContain("PASS"); + expect(cli("scripts/rag-phase-launch-check.mjs", ["--target", "P01", "--effort", "xhigh"])).toContain("PASS"); expect(() => cli("scripts/rag-phase-launch-check.mjs", ["--target", "P01", "--effort", "high"])).toThrow(); }); it("local task briefs carry honest provenance and R3 continuation constraints", () => { diff --git a/tests/rag-plan-package-parity.test.ts b/tests/rag-plan-package-parity.test.ts index 3db30f9e79..ddf792ab50 100644 --- a/tests/rag-plan-package-parity.test.ts +++ b/tests/rag-plan-package-parity.test.ts @@ -178,11 +178,11 @@ describe("RAG plan execution packages", () => { }), ).toThrow(); expect(() => - execFileSync( - process.execPath, - ["scripts/rag-phase-launch-check.mjs", "--target", "P01", "--effort", "xhigh", "--xhigh-confirmed"], - { cwd: process.cwd(), encoding: "utf8", stdio: "pipe" }, - ), + execFileSync(process.execPath, ["scripts/rag-phase-launch-check.mjs", "--target", "P01", "--effort", "xhigh"], { + cwd: process.cwd(), + encoding: "utf8", + stdio: "pipe", + }), ).not.toThrow(); }); From b0b486eb3d2a0808c0b704ce4ef92930b3b5f8ec Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 21:45:10 +0800 Subject: [PATCH 05/20] docs(ledger): record review for bdb0cea521 on codex/cloud-policy-clarity Co-Authored-By: Claude Fable 5 --- data/repo-awareness-snapshot.json | 8 -------- docs/branch-review-index.md | 2 +- ...2bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md | 1 + ...4bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md | 1 - 4 files changed, 2 insertions(+), 10 deletions(-) create mode 100644 docs/branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md delete mode 100644 docs/branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md diff --git a/data/repo-awareness-snapshot.json b/data/repo-awareness-snapshot.json index b0fc69dcb2..782d822203 100644 --- a/data/repo-awareness-snapshot.json +++ b/data/repo-awareness-snapshot.json @@ -6282,14 +6282,6 @@ "outcome": "Retained: 1 patch-unique non-merge commit(s) remain and ownership or merge disposition is unresolved; deletion blocked.", "checks": "git log --right-only --cherry-pick --no-merges origin/main...claude/query-hash-hmac-secret-0e44d3; git diff --name-only reported 2 path(s)." }, - { - "date": "2026-10-16", - "ref": "codex/cloud-policy-clarity", - "head": "06eefbe47fca3d05745843450c8999011a249f43", - "scope": "Codex Cloud reasoning-effort and raw-env policy overhaul", - "outcome": "PASS (0 blocking findings; retired general [xhigh-confirmed] chat gate, clarified raw-env local policy repair and scrubbed offline checks, added activation guidance)", - "checks": "check:codex-cloud, vitest (tests/codex-cloud-setup.test.ts, tests/organisation-decisions.test.ts: 84 passed), docs:maintain:check, check:instructions, check:decisions, check:organisation" - }, { "date": "2026-07-30", "ref": "codex/ledger-next-20260730", diff --git a/docs/branch-review-index.md b/docs/branch-review-index.md index a1130469ec..26e679149e 100644 --- a/docs/branch-review-index.md +++ b/docs/branch-review-index.md @@ -79,7 +79,7 @@ Scope and outcome are truncated; follow the record link for the full six-cell ro | Date | Ref | Scope | Outcome | Record | | --- | --- | --- | --- | --- | | 2026-10-16 | fix/adversarial-remediation-20261016 | Adversarial assessment + parallel fix swarm + post-fix adversarial review across calculato… | All P0/P1/P2 findings fixed and verified; zero RAG files touched | [2a6b6200](branch-review-records/2a6b620065f5371039438fdbff73be97da6baf6c40dace3596e26c7bad0047dd.record.md) | -| 2026-10-16 | codex/cloud-policy-clarity | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; retired general [xhigh-confirmed] chat gate… | [a9eede79](branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md) | +| 2026-10-16 | codex/cloud-policy-clarity | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; removed all xhigh prompt-marker references… | [3dd0e7e3](branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md) | | 2026-10-16 | feat/backlog-remediation-20261016 | prlanded | PR #3571 squash-merged cleanly into main (e526f8a4d5ad00ad05c5b780262b… | [ad2c45bc](branch-review-records/ad2c45bc2f3c606a7847421acc887ddf4861ab0563a5b96b4c6315b066837d90.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted admin pilot shared announcement correction; file SHA256 0f76deaa4d8d9ad46139d0… | Independent frontend source review ACCEPT; visible message and polite… | [263f1f06](branch-review-records/263f1f0680e9d5cda1bed9bb2a62853d3a34b78b5ad60054971520fdc884cf1c.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted native-PDF layout v5 producer 352d178978ef9086df1df708aa71266538076a2f5050a526… | Independent technical P1/P2 closure and qualified representative-sourc… | [6d2fd2e8](branch-review-records/6d2fd2e81761e17d32bb56bd41261efe8f9239ef266cf85a512c1021f889dd4b.record.md) | diff --git a/docs/branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md b/docs/branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md new file mode 100644 index 0000000000..63d03c644d --- /dev/null +++ b/docs/branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md @@ -0,0 +1 @@ +| 2026-10-16 | codex/cloud-policy-clarity | bdb0cea521800eb85f47fa3a0de3ce7869082a4c | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; removed all xhigh prompt-marker references across policies/skills/RAG launch checks, added GH_TOKEN to known launcher scrub path, clarified activation guidance) | check:codex-cloud, vitest (tests/codex-cloud-setup.test.ts, tests/rag-local-agent-policy.test.ts, tests/rag-plan-package-parity.test.ts, tests/organisation-decisions.test.ts: 150 passed), docs:maintain, check:instructions, check:decisions, check:organisation | diff --git a/docs/branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md b/docs/branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md deleted file mode 100644 index e87b2292d9..0000000000 --- a/docs/branch-review-records/a9eede796328b44787204bcbdcbfb421bbdea4a0a36bc451e6714889cc7a4c91.record.md +++ /dev/null @@ -1 +0,0 @@ -| 2026-10-16 | codex/cloud-policy-clarity | 06eefbe47fca3d05745843450c8999011a249f43 | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; retired general [xhigh-confirmed] chat gate, clarified raw-env local policy repair and scrubbed offline checks, added activation guidance) | check:codex-cloud, vitest (tests/codex-cloud-setup.test.ts, tests/organisation-decisions.test.ts: 84 passed), docs:maintain:check, check:instructions, check:decisions, check:organisation | From 111fedef7077cbf4aa8db29ea665da5eb7026ecf Mon Sep 17 00:00:00 2001 From: BigSimmo Date: Fri, 16 Oct 2026 22:33:40 +0800 Subject: [PATCH 06/20] docs(codex-cloud): address review threads on raw-env exit semantics and GH_TOKEN warning --- docs/agents/codex-cloud-environment.md | 2 +- docs/codex-cloud.md | 11 +++++++---- .../rag-upgrade/canonical/START-HERE.cloud.md | 2 +- docs/superpowers/rag-upgrade/cloud/START-HERE.md | 2 +- scripts/check-codex-cloud-raw-env.sh | 7 ++++++- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/agents/codex-cloud-environment.md b/docs/agents/codex-cloud-environment.md index 4452f20e84..05b478f619 100644 --- a/docs/agents/codex-cloud-environment.md +++ b/docs/agents/codex-cloud-environment.md @@ -135,7 +135,7 @@ Codex Cloud uses an isolated Linux container and does not inherit desktop creden - Default to `CODEX_CLOUD_ACCESS_PROFILE=offline` for ordinary/RAG work; use `connected` only with explicit provider authorization. - Personal Pro split control plane: Codex Cloud for code and GitHub connector; ChatGPT web for Railway and read-only Supabase metadata. -- Acceptance: run `bash scripts/check-codex-cloud-raw-env.sh`, `npm run check:codex-cloud`, and `npm run check:codex-cloud -- --runtime` (with `CODEX_CLOUD_EXPECTED_BASE_SHA`). A failed raw-parent credential check blocks app execution and provider access, not explicitly requested local policy repair or scrubbed offline checks. +- Acceptance: run `bash scripts/check-codex-cloud-raw-env.sh`, `npm run check:codex-cloud`, and `npm run check:codex-cloud -- --runtime` (with `CODEX_CLOUD_EXPECTED_BASE_SHA`). Exit 1 (`FAIL`/`STOP`) blocks app execution and provider access, not explicitly requested local policy repair or scrubbed offline checks; exit 2 (`FAIL-KNOWN`, only `OPENAI_BASE_URL`/`GH_TOKEN`) still fails the raw boundary but permits provider-free work, including app/runtime commands, through the generated profile and command shims. - Do not expose provider secrets (OpenAI, Supabase, Railway, GitHub PATs) in Cloud agent shells or committed config. - Authenticated live tests run via `.github/workflows/authenticated-live-tests.yml` with manual dispatch, never from Cloud agent shells. - Branch deletion helper `bash scripts/delete-codex-cloud-branch-with-pat.sh` is operator-only outside Cloud. diff --git a/docs/codex-cloud.md b/docs/codex-cloud.md index da9f13c945..199f4ad788 100644 --- a/docs/codex-cloud.md +++ b/docs/codex-cloud.md @@ -375,7 +375,9 @@ already-running process. Outcomes are name-scoped in the probe itself: `SUPABASE_SERVICE_ROLE_KEY`); application execution, live provider access, and full runtime acceptance remain blocked and require a fresh task once the environment source is cleared, while explicitly requested local policy, documentation, and configuration inspection and repair (plus - scrubbed offline checks through the profile and command shims) may proceed + scrubbed offline checks through the profile and command shims) may proceed; RAG specialist + phase launches are stricter and treat exit `1` as a hard stop requiring a fresh task, per the + RAG Cloud `START-HERE` launch guide - exit `2` / `FAIL-KNOWN` + `CONTINUE-RESTRICTED` — only the documented Personal Pro launcher-injected names `OPENAI_BASE_URL` and `GH_TOKEN` @@ -454,9 +456,10 @@ separate lifecycles: local to that disposable container until committed, pushed, and merged (or selected as the starting branch for a new task). 2. **Cloud environment settings (setup/maintenance scripts, environment variables, secrets, connectors):** - Configured in the Codex Cloud environment UI. Changes are captured when a fresh task container - is provisioned, or when setup is explicitly rerun in the existing container; they never apply - retroactively to already-running processes. Routine maintenance reuses the existing generated + Configured in the Codex Cloud environment UI. A fresh task container is required after Cloud + environment values or secrets change. Rerunning setup in an existing container reads only values + already available to that process; it does not retrieve updated UI values or secrets, and it + does not update already-running processes. Routine maintenance reuses the existing generated profile and only refreshes these settings if it falls back to full setup. 3. **Existing chat context and running process state:** An open chat retains the instruction text already loaded into its conversation history, and a diff --git a/docs/superpowers/rag-upgrade/canonical/START-HERE.cloud.md b/docs/superpowers/rag-upgrade/canonical/START-HERE.cloud.md index 525c625be5..30a7f45633 100644 --- a/docs/superpowers/rag-upgrade/canonical/START-HERE.cloud.md +++ b/docs/superpowers/rag-upgrade/canonical/START-HERE.cloud.md @@ -24,7 +24,7 @@ raw_status=$? set -e ``` -Exit 0 continues. Exit 1 is a hard stop and requires a fresh task. Exit 2 continues only for the documented `OPENAI_BASE_URL`-alone restricted path: never run OpenAI clients from the raw parent or bypass the generated profile and `node`/`npm`/`npx` shims. No other inherited name may use that path. +Exit 0 continues. Exit 1 is a hard stop and requires a fresh task. Exit 2 continues only for the documented restricted path for only `OPENAI_BASE_URL` and/or `GH_TOKEN`: never run OpenAI or gh/GitHub clients from the raw parent or bypass the generated profile and `node`/`npm`/`npx` shims. No other inherited name may use that path. Cloud has no Windows task-start script. Perform the equivalent read-only repository identity, branch, HEAD, status and worktree checks. Require a clean disposable checkout on a task-specific non-protected branch. diff --git a/docs/superpowers/rag-upgrade/cloud/START-HERE.md b/docs/superpowers/rag-upgrade/cloud/START-HERE.md index 525c625be5..30a7f45633 100644 --- a/docs/superpowers/rag-upgrade/cloud/START-HERE.md +++ b/docs/superpowers/rag-upgrade/cloud/START-HERE.md @@ -24,7 +24,7 @@ raw_status=$? set -e ``` -Exit 0 continues. Exit 1 is a hard stop and requires a fresh task. Exit 2 continues only for the documented `OPENAI_BASE_URL`-alone restricted path: never run OpenAI clients from the raw parent or bypass the generated profile and `node`/`npm`/`npx` shims. No other inherited name may use that path. +Exit 0 continues. Exit 1 is a hard stop and requires a fresh task. Exit 2 continues only for the documented restricted path for only `OPENAI_BASE_URL` and/or `GH_TOKEN`: never run OpenAI or gh/GitHub clients from the raw parent or bypass the generated profile and `node`/`npm`/`npx` shims. No other inherited name may use that path. Cloud has no Windows task-start script. Perform the equivalent read-only repository identity, branch, HEAD, status and worktree checks. Require a clean disposable checkout on a task-specific non-protected branch. diff --git a/scripts/check-codex-cloud-raw-env.sh b/scripts/check-codex-cloud-raw-env.sh index 719ff229f1..bc42c5148c 100755 --- a/scripts/check-codex-cloud-raw-env.sh +++ b/scripts/check-codex-cloud-raw-env.sh @@ -72,5 +72,10 @@ fi printf '[Codex Cloud Raw Env] FAIL-KNOWN: inherited documented launcher defect names: %s\n' "${known[*]}" >&2 printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: use only the generated profile and command shims; raw boundary remains failed.\n' >&2 -printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: OPENAI_BASE_URL can redirect OpenAI-bound traffic; never invoke OpenAI clients from the raw parent or any binary that bypasses the profile/shim scrub.\n' >&2 +for name in "${known[@]}"; do + case "$name" in + OPENAI_BASE_URL) printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: OPENAI_BASE_URL can redirect OpenAI-bound traffic; never invoke OpenAI clients from the raw parent or any binary that bypasses the profile/shim scrub.\n' >&2 ;; + GH_TOKEN) printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: GH_TOKEN carries host GitHub credentials; never invoke gh/GitHub clients from the raw parent or any binary that bypasses the profile/shim scrub.\n' >&2 ;; + esac +done exit 2 From 1e3f1a0e4de9f4b7544edfd7ab271a57fe701c0c Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 22:57:52 +0800 Subject: [PATCH 07/20] fix(codex-cloud): harden shell profile sourcing, command shims, and offline env scrubbing Co-Authored-By: Claude Fable 5 --- data/repo-awareness-snapshot.json | 8 ++ docs/codex-cloud.md | 19 +-- scripts/check-codex-cloud-setup.mjs | 143 ++++++++++++------- scripts/diagnose-codex-cloud.mjs | 22 ++- scripts/install-codex-cloud-command-shims.sh | 21 ++- scripts/maintain-codex-cloud.sh | 1 + scripts/setup-codex-cloud.sh | 23 +-- scripts/test-environment.mjs | 17 +++ tests/codex-cloud-diagnose.test.ts | 6 + tests/codex-cloud-setup.test.ts | 35 ++++- 10 files changed, 217 insertions(+), 78 deletions(-) diff --git a/data/repo-awareness-snapshot.json b/data/repo-awareness-snapshot.json index 782d822203..5cf07a4bed 100644 --- a/data/repo-awareness-snapshot.json +++ b/data/repo-awareness-snapshot.json @@ -21546,6 +21546,14 @@ "outcome": "2 Codex P2 → skip placeholders in compactBestUseTitle; gate subtitle compaction to services mode; threads unreplied (API 403)", "checks": "vitest services-catalog+document-search-record-fault 20 passed; no provider-backed checks" }, + { + "date": "2026-10-16", + "ref": "codex/cloud-policy-clarity", + "head": "bdb0cea521800eb85f47fa3a0de3ce7869082a4c", + "scope": "Codex Cloud reasoning-effort and raw-env policy overhaul", + "outcome": "PASS (0 blocking findings; removed all xhigh prompt-marker references across policies/skills/RAG launch checks, added GH_TOKEN to known launcher scrub path, clarified activation guidance)", + "checks": "check:codex-cloud, vitest (tests/codex-cloud-setup.test.ts, tests/rag-local-agent-policy.test.ts, tests/rag-plan-package-parity.test.ts, tests/organisation-decisions.test.ts: 150 passed), docs:maintain, check:instructions, check:decisions, check:organisation" + }, { "date": "2026-07-20", "ref": "cursor/documents-search-header-3eab / PR #936", diff --git a/docs/codex-cloud.md b/docs/codex-cloud.md index da9f13c945..764700c400 100644 --- a/docs/codex-cloud.md +++ b/docs/codex-cloud.md @@ -119,14 +119,17 @@ The generated shell profile removes known OpenAI, Supabase, Railway, GitHub/GitL database, CI-trigger, test-user, and emergency-PAT variables. This prevents an unrelated Cloud task from silently becoming provider-backed. -Set all five offline values in the environment UI. The setup also writes the generated -profile to `.bashrc`, `.profile`, and `.bash_profile`. Covering `.bash_profile` is required: -Bash stops login-profile discovery at the first matching file, so an existing `.bash_profile` -can otherwise prevent `.profile` from running. Offline mode values are forced after inherited -platform values so stale `auto`/`false` settings cannot outrank the repository contract. -Do not manually source the profile as an acceptance workaround: start a fresh task and invoke -the direct `npm run check:codex-cloud` commands below. The tracked command shims make those -ordinary Node commands load the profile themselves. +Set all five offline values in the environment UI. The setup also prepends the generated +profile to the top of `.bashrc`, `.profile`, and `.bash_profile` (ahead of Ubuntu's +non-interactive `return` guard in `.bashrc`) and runs `scripts/install-codex-cloud-command-shims.sh`. +Covering `.bash_profile` is required: Bash stops login-profile discovery at the first matching +file, so an existing `.bash_profile` can otherwise prevent `.profile` from running. Offline mode +values are forced after inherited platform values so stale `auto`/`false` settings cannot outrank +the repository contract. Do not manually source the profile as an acceptance workaround: start a +fresh task and invoke the direct `npm run check:codex-cloud` commands below. Both the tracked +command shims and `scripts/check-codex-cloud-setup.mjs` itself automatically load +`$HOME/.clinical-kb-codex-cloud.sh` when invoked in a Cloud shell (including raw `bash -c` +invocations where `/root/.nvm/versions/node/.../bin` precedes `$HOME/.local/bin` on `PATH`). ### Connected (explicit opt-in) diff --git a/scripts/check-codex-cloud-setup.mjs b/scripts/check-codex-cloud-setup.mjs index 74152e44c6..0721e06cd8 100644 --- a/scripts/check-codex-cloud-setup.mjs +++ b/scripts/check-codex-cloud-setup.mjs @@ -364,24 +364,26 @@ export function validateHostedAppInventory(appNames) { } export const providerCredentialVariables = Object.freeze([ - ...providerEnvironmentKeys, - "RAILWAY_API_TOKEN", - "RAILWAY_TOKEN", - "GH_TOKEN", - "GITHUB_TOKEN", - "CODEX_CLOUD_GITHUB_PAT", - "GITLAB_TOKEN", - "GLAB_TOKEN", - "CODEX_TRIGGER_TOKEN", - "HEALTH_DEEP_PROBE_SECRET", - "INDEXING_V3_AGENT_SECRET", - "CROSS_TENANT_SERVICE_ROLE_KEY", - "FIGMA_CLIENT_ID", - "FIGMA_CLIENT_SECRET", - "FIGMA_ACCESS_TOKEN", - "FIGMA_PERSONAL_ACCESS_TOKEN", - "FIGMA_TOKEN", - "FIGMA_NPM_TOKEN", + ...new Set([ + ...providerEnvironmentKeys, + "RAILWAY_API_TOKEN", + "RAILWAY_TOKEN", + "GH_TOKEN", + "GITHUB_TOKEN", + "CODEX_CLOUD_GITHUB_PAT", + "GITLAB_TOKEN", + "GLAB_TOKEN", + "CODEX_TRIGGER_TOKEN", + "HEALTH_DEEP_PROBE_SECRET", + "INDEXING_V3_AGENT_SECRET", + "CROSS_TENANT_SERVICE_ROLE_KEY", + "FIGMA_CLIENT_ID", + "FIGMA_CLIENT_SECRET", + "FIGMA_ACCESS_TOKEN", + "FIGMA_PERSONAL_ACCESS_TOKEN", + "FIGMA_TOKEN", + "FIGMA_NPM_TOKEN", + ]), ]); function read(relativePath) { @@ -1328,40 +1330,81 @@ export async function validateCodexCloudRuntime(env = process.env) { return errors; } +function readableRuntimeProfile(env = process.env) { + if (!env.HOME) return null; + const profilePath = path.join(env.HOME, ".clinical-kb-codex-cloud.sh"); + try { + return statSync(profilePath).isFile() && (accessSync(profilePath, constants.R_OK), profilePath); + } catch { + return null; + } +} + +export function shouldAutoSourceCloudProfile(env = process.env) { + return ( + env.CODEX_CLOUD === "1" && + env.NODE_ENV !== "test" && + env.CODEX_CLOUD_PROFILE_LOADED !== "1" && + Boolean(readableRuntimeProfile(env)) + ); +} + if (isDirectEntrypoint(import.meta.url)) { - const errors = validateCodexCloudSetup(); - const commandArguments = process.argv.slice(2); - const hostedAppArgumentErrors = validateHostedAppInventoryArguments(commandArguments); - const hostedAppInventory = parseHostedAppInventoryArgument(commandArguments); - const hostedAppInventoryErrors = validateHostedAppInventory(hostedAppInventory); - const hostedAppInputErrors = [...hostedAppArgumentErrors, ...hostedAppInventoryErrors]; - errors.push(...hostedAppInputErrors); - const runtime = process.argv.includes("--runtime"); - const environment = runtime || process.env.CODEX_CLOUD === "1" || process.argv.includes("--environment"); - if (runtime) errors.push(...(await validateCodexCloudRuntime())); - else if (environment) errors.push(...validateCodexCloudEnvironment()); - if ( - runtime && - process.env.CODEX_CLOUD_PROVISIONING === "1" && - gitCheckoutFreshness(repoRoot).freshness === "unverified" - ) { - console.warn( - "[Codex Cloud Check] WARN: checkout freshness is unverified during provisioning; run explicit acceptance with CODEX_CLOUD_EXPECTED_BASE_SHA.", + const runtimeProfilePath = shouldAutoSourceCloudProfile(process.env) ? readableRuntimeProfile(process.env) : null; + if (runtimeProfilePath) { + const bashExecutable = + process.platform === "win32" + ? path.join(process.env.ProgramFiles || "C:\\Program Files", "Git/bin/bash.exe") + : "bash"; + const reexec = spawnSync( + bashExecutable, + [ + "-c", + 'profile_path="$1"; node_exec="$2"; script_path="$3"; shift 3; saved_args=("$@"); set --; . "$profile_path" && export CODEX_CLOUD_PROFILE_LOADED=1 && exec "$node_exec" "$script_path" "${saved_args[@]}"', + "codex-cloud-check", + runtimeProfilePath.replaceAll("\\", "/"), + process.execPath, + fileURLToPath(import.meta.url), + ...process.argv.slice(2), + ], + { cwd: repoRoot, stdio: "inherit" }, ); - } - if (environment && hostedAppInputErrors.length === 0) { - console.log("[Codex Cloud Environment] sanitized effective modes and capabilities:"); - for (const line of sanitizedCloudCapabilityLines(process.env, { hostedAppInventory })) console.log(` ${line}`); - } - if (errors.length > 0) { - for (const error of errors) console.error(`[Codex Cloud Check] FAIL: ${error}`); - process.exitCode = 1; + process.exitCode = reexec.status ?? 1; } else { - const scope = codexCloudValidationScope({ - runtime, - environment, - browserInstallSkipped: process.env.CODEX_CLOUD_SKIP_BROWSER_INSTALL === "1", - }); - console.log(`[Codex Cloud Check] PASS: ${scope} Cloud contracts match.`); + const errors = validateCodexCloudSetup(); + const commandArguments = process.argv.slice(2); + const hostedAppArgumentErrors = validateHostedAppInventoryArguments(commandArguments); + const hostedAppInventory = parseHostedAppInventoryArgument(commandArguments); + const hostedAppInventoryErrors = validateHostedAppInventory(hostedAppInventory); + const hostedAppInputErrors = [...hostedAppArgumentErrors, ...hostedAppInventoryErrors]; + errors.push(...hostedAppInputErrors); + const runtime = process.argv.includes("--runtime"); + const environment = runtime || process.env.CODEX_CLOUD === "1" || process.argv.includes("--environment"); + if (runtime) errors.push(...(await validateCodexCloudRuntime())); + else if (environment) errors.push(...validateCodexCloudEnvironment()); + if ( + runtime && + process.env.CODEX_CLOUD_PROVISIONING === "1" && + gitCheckoutFreshness(repoRoot).freshness === "unverified" + ) { + console.warn( + "[Codex Cloud Check] WARN: checkout freshness is unverified during provisioning; run explicit acceptance with CODEX_CLOUD_EXPECTED_BASE_SHA.", + ); + } + if (environment && hostedAppInputErrors.length === 0) { + console.log("[Codex Cloud Environment] sanitized effective modes and capabilities:"); + for (const line of sanitizedCloudCapabilityLines(process.env, { hostedAppInventory })) console.log(` ${line}`); + } + if (errors.length > 0) { + for (const error of errors) console.error(`[Codex Cloud Check] FAIL: ${error}`); + process.exitCode = 1; + } else { + const scope = codexCloudValidationScope({ + runtime, + environment, + browserInstallSkipped: process.env.CODEX_CLOUD_SKIP_BROWSER_INSTALL === "1", + }); + console.log(`[Codex Cloud Check] PASS: ${scope} Cloud contracts match.`); + } } } diff --git a/scripts/diagnose-codex-cloud.mjs b/scripts/diagnose-codex-cloud.mjs index 2e24b36ba1..a54de0c104 100644 --- a/scripts/diagnose-codex-cloud.mjs +++ b/scripts/diagnose-codex-cloud.mjs @@ -6,10 +6,26 @@ import { isDirectEntrypoint } from "./lib/is-entrypoint.mjs"; import { lockPythonVersion, workerPythonLockTargets } from "./worker-python-lock-config.mjs"; +const NODE_MINIMUM_VERSION = "24.15.0"; + function major(version) { return version?.match(/\d+/)?.[0] ?? null; } +function isSupportedNodeVersion(version) { + if (!version || major(version) !== "24") return false; + const parts = version + .match(/^\d+(?:\.\d+){1,2}/)?.[0] + ?.split(".") + .map(Number); + if (!parts || parts.length < 3 || parts.some((part) => !Number.isFinite(part))) return false; + const required = NODE_MINIMUM_VERSION.split(".").map(Number); + for (let index = 0; index < 3; index += 1) { + if (parts[index] !== required[index]) return parts[index] > required[index]; + } + return true; +} + export function diagnoseCodexCloud({ nodeVersion, npmVersion, @@ -19,11 +35,11 @@ export function diagnoseCodexCloud({ setupExitCode, }) { const issues = []; - if (major(nodeVersion) !== "24") { + if (!isSupportedNodeVersion(nodeVersion)) { issues.push({ code: "NODE_RUNTIME", - issue: `Node 24.x is required; detected ${nodeVersion || "unavailable"}.`, - fix: "Select Node 24 in the Cloud environment or rerun setup with nvm available.", + issue: `Node >=${NODE_MINIMUM_VERSION} <25 is required; detected ${nodeVersion || "unavailable"}.`, + fix: "Select Node 24 (>=24.15.0) in the Cloud environment or rerun setup with nvm available.", }); } if (major(npmVersion) !== "11") { diff --git a/scripts/install-codex-cloud-command-shims.sh b/scripts/install-codex-cloud-command-shims.sh index ff87b5450f..82085df3e6 100644 --- a/scripts/install-codex-cloud-command-shims.sh +++ b/scripts/install-codex-cloud-command-shims.sh @@ -18,11 +18,24 @@ runtime_profile="$HOME/.clinical-kb-codex-cloud.sh" # shellcheck source=/dev/null source "$runtime_profile" -command -v nvm >/dev/null 2>&1 || fail "nvm is unavailable after loading the Cloud runtime profile." -resolved_node_version="$(nvm version "$expected_node_major")" -[[ "$resolved_node_version" != "N/A" ]] || fail "Node ${expected_node_major} is unavailable through nvm." -node_bin="$NVM_DIR/versions/node/$resolved_node_version/bin" +resolved_node_version="" +if command -v nvm >/dev/null 2>&1; then + resolved_node_version="$(nvm version "$expected_node_major")" +fi +if [[ -n "$resolved_node_version" && "$resolved_node_version" != "N/A" ]]; then + node_bin="$NVM_DIR/versions/node/$resolved_node_version/bin" +else + fallback_path=":$PATH:" + while [[ "$fallback_path" == *":$HOME/.local/bin:"* ]]; do + fallback_path="${fallback_path//:$HOME\/.local\/bin:/:}" + done + fallback_path="${fallback_path#:}" + fallback_path="${fallback_path%:}" + fallback_node="$(PATH="$fallback_path" command -v node 2>/dev/null || true)" + [[ -n "$fallback_node" ]] || fail "Node ${expected_node_major} is unavailable through nvm or PATH." + node_bin="$(cd "$(dirname "$fallback_node")" && pwd)" +fi mkdir -p "$HOME/.local/bin" for command_name in node npm npx; do [[ -x "$node_bin/$command_name" ]] || fail "${command_name} is unavailable in Node ${expected_node_major}." diff --git a/scripts/maintain-codex-cloud.sh b/scripts/maintain-codex-cloud.sh index 9872fe061c..46f81dc910 100644 --- a/scripts/maintain-codex-cloud.sh +++ b/scripts/maintain-codex-cloud.sh @@ -24,6 +24,7 @@ node scripts/ensure-codex-cloud-git-remote.mjs --configure-gh-helper bash scripts/refresh-codex-cloud-base.sh # shellcheck source=/dev/null source "$HOME/.clinical-kb-codex-cloud.sh" +bash scripts/install-codex-cloud-command-shims.sh npm run check:codex-cloud if ! CODEX_CLOUD_PROVISIONING=1 npm run check:codex-cloud -- --runtime; then printf '[codex-cloud:maintenance] Runtime or toolchain drift detected; rerunning full setup.\n' diff --git a/scripts/setup-codex-cloud.sh b/scripts/setup-codex-cloud.sh index ca03a4e556..de010dd12b 100755 --- a/scripts/setup-codex-cloud.sh +++ b/scripts/setup-codex-cloud.sh @@ -154,6 +154,7 @@ fi export PATH="\$HOME/.local/bin:\$HOME/.deno/bin:\$HOME/.cache/clinical-kb-codex/ocr-venv-${expected_cloud_python}/bin:\$PATH" export CODEX_CLOUD_OCR_PYTHON="\$HOME/.cache/clinical-kb-codex/ocr-venv-${expected_cloud_python}/bin/python" export CODEX_CLOUD=1 +export CODEX_CLOUD_PROFILE_LOADED=1 export CODEX_CLOUD_ACCESS_PROFILE="${access_profile}" export NEXT_PUBLIC_DEMO_MODE="\${NEXT_PUBLIC_DEMO_MODE:-true}" export PLAYWRIGHT_OFFLINE_MODE="\${PLAYWRIGHT_OFFLINE_MODE:-true}" @@ -267,23 +268,29 @@ fi mv -f "$codex_config_candidate" "$codex_config_file" trap - EXIT -# Test harness only: write the runtime profile + shell policy, then stop before -# toolchain installs so unit tests can exercise config merge without a runtime. -if [[ "$policy_only_harness" = "1" ]]; then - log "Stopping after shell-policy write (test harness)." - exit 0 -fi - profile_source='[ -f "$HOME/.clinical-kb-codex-cloud.sh" ] && . "$HOME/.clinical-kb-codex-cloud.sh"' for shell_profile in "$HOME/.bashrc" "$HOME/.profile" "$HOME/.bash_profile"; do touch "$shell_profile" if ! grep -Fq '.clinical-kb-codex-cloud.sh' "$shell_profile"; then - printf '\n# PsychSift Codex Cloud runtime\n%s\n' "$profile_source" >> "$shell_profile" + profile_existing="$(<"$shell_profile")" + if [[ -n "$profile_existing" ]]; then + printf '# PsychSift Codex Cloud runtime\n%s\n\n%s\n' "$profile_source" "$profile_existing" > "$shell_profile" + else + printf '# PsychSift Codex Cloud runtime\n%s\n' "$profile_source" > "$shell_profile" + fi fi done +# Test harness only: write the runtime profile + shell policy, then stop before +# toolchain installs so unit tests can exercise config merge without a runtime. +if [[ "$policy_only_harness" = "1" ]]; then + log "Stopping after shell-policy write (test harness)." + exit 0 +fi + # shellcheck source=/dev/null source "$runtime_profile" +bash scripts/install-codex-cloud-command-shims.sh log "Installing locked Node dependencies." setup_step="node-dependencies" diff --git a/scripts/test-environment.mjs b/scripts/test-environment.mjs index 119cae51d7..c2a5fcfbd0 100644 --- a/scripts/test-environment.mjs +++ b/scripts/test-environment.mjs @@ -28,6 +28,23 @@ const providerEnvironmentKeys = Object.freeze([ "NEXT_PUBLIC_SENTRY_DSN", "SENTRY_DSN", "ALLOW_PROVIDER_TESTS", + "RAILWAY_API_TOKEN", + "RAILWAY_TOKEN", + "GH_TOKEN", + "GITHUB_TOKEN", + "CODEX_CLOUD_GITHUB_PAT", + "GITLAB_TOKEN", + "GLAB_TOKEN", + "CODEX_TRIGGER_TOKEN", + "HEALTH_DEEP_PROBE_SECRET", + "INDEXING_V3_AGENT_SECRET", + "CROSS_TENANT_SERVICE_ROLE_KEY", + "FIGMA_CLIENT_ID", + "FIGMA_CLIENT_SECRET", + "FIGMA_ACCESS_TOKEN", + "FIGMA_PERSONAL_ACCESS_TOKEN", + "FIGMA_TOKEN", + "FIGMA_NPM_TOKEN", ]); const offlineUrlValues = Object.freeze({ diff --git a/tests/codex-cloud-diagnose.test.ts b/tests/codex-cloud-diagnose.test.ts index 7536b4e5fc..7340a81852 100644 --- a/tests/codex-cloud-diagnose.test.ts +++ b/tests/codex-cloud-diagnose.test.ts @@ -19,6 +19,12 @@ describe("Codex Cloud diagnostics", () => { expect(diagnoseCodexCloud(healthy)).toEqual([]); }); + it("flags Node 24 versions below the 24.15.0 engine floor", () => { + const issues = diagnoseCodexCloud({ ...healthy, nodeVersion: "24.13.0" }); + expect(issues.map((issue) => issue.code)).toEqual(["NODE_RUNTIME"]); + expect(issues[0]?.issue).toContain(">=24.15.0 <25"); + }); + it("explains the Python lock mismatch that previously stopped setup", () => { const issues = diagnoseCodexCloud({ ...healthy, diff --git a/tests/codex-cloud-setup.test.ts b/tests/codex-cloud-setup.test.ts index f7e428020b..942b264a44 100644 --- a/tests/codex-cloud-setup.test.ts +++ b/tests/codex-cloud-setup.test.ts @@ -23,6 +23,7 @@ import { pythonWorkerVersionLine, pythonWorkerImports, sanitizedCloudCapabilityLines, + shouldAutoSourceCloudProfile, validateCodexCloudEnvironment, validateCloudNpmInstallContract, validateCodexProjectMcpConfiguration, @@ -618,7 +619,7 @@ describe("Codex Cloud environment contract", () => { expect(malformedCli.status).toBe(1); expect(malformedCli.stderr).toContain("Unsupported Cloud-check argument"); expect(malformedCli.stdout).not.toContain("hosted_app.inventory="); - }); + }, 120_000); it("probes the raw task environment without printing credential values", () => { const secret = "never-print-raw-provider-value"; @@ -631,7 +632,7 @@ describe("Codex Cloud environment contract", () => { expect(result.stderr).toContain("OPENAI_API_KEY"); expect(result.stderr).toContain("STOP:"); expect(result.stderr).not.toContain(secret); - }); + }, 120_000); it("name-scopes the documented OPENAI_BASE_URL and GH_TOKEN launcher defects separately from unexpected leaks", () => { const known = spawnSync(bashCommand, ["scripts/check-codex-cloud-raw-env.sh"], { @@ -672,7 +673,7 @@ describe("Codex Cloud environment contract", () => { expect(mixed.stderr).not.toContain("never-print-service-role"); expect(mixed.stderr).not.toContain("gho_never_print_known_token"); expect(mixed.stderr).not.toContain("CONTINUE-RESTRICTED:"); - }); + }, 120_000); it("keeps setup and maintenance repairs guarded for repeat execution", () => { const setup = readFileSync(new URL("../scripts/setup-codex-cloud.sh", import.meta.url), "utf8"); @@ -737,14 +738,18 @@ describe("Codex Cloud environment contract", () => { expect(setup).toContain('"$ocr_venv/bin/python" -m pip check'); const refreshCommand = "bash scripts/refresh-codex-cloud-base.sh"; const runtimeCheck = "CODEX_CLOUD_PROVISIONING=1 npm run check:codex-cloud -- --runtime"; + const installShimsCommand = "bash scripts/install-codex-cloud-command-shims.sh"; expect(setup).toContain(runtimeCheck); expect(setup).toContain(refreshCommand); + expect(setup).toContain(installShimsCommand); expect(maintenance).toContain(runtimeCheck); expect(maintenance).toContain("ensure-codex-cloud-git-remote.mjs"); expect(maintenance).toContain(refreshCommand); + expect(maintenance).toContain(installShimsCommand); for (const script of [setup, maintenance]) { expect(script.indexOf(refreshCommand)).toBeLessThan(script.indexOf(runtimeCheck)); + expect(script.indexOf(installShimsCommand)).toBeLessThan(script.indexOf(runtimeCheck)); } expect(commandShims).toContain('nvm version "$expected_node_major"'); expect(commandShims).toContain('node_bin="$NVM_DIR/versions/node/$resolved_node_version/bin"'); @@ -799,7 +804,7 @@ describe("Codex Cloud environment contract", () => { expect(resolvedPath[0]).toBe(bashNodeBin); expect(resolvedPath).not.toContain(shimDir); expect(resolvedPath).toEqual(expect.arrayContaining(["/usr/bin", "/bin"])); - }); + }, 120_000); it("prefers the exact Python 3.12 interpreter over an older python3 alias", () => { const home = temporaryDirectory("codex-cloud-python-home-"); @@ -822,7 +827,7 @@ describe("Codex Cloud environment contract", () => { expect(result.status, result.stderr || result.stdout).toBe(0); expect(result.stdout.trim()).toBe(bashPathEntry(exactPython)); - }); + }, 120_000); it("writes managed shell policy behaviorally and preserves unrelated Codex config", () => { const home = temporaryDirectory("codex-cloud-home-"); @@ -831,6 +836,17 @@ describe("Codex Cloud environment contract", () => { path.join(home, ".codex/config.toml"), ["[mcp_servers.example]", 'command = "echo"', 'args = ["ping"]', ""].join("\n"), ); + writeFileSync( + path.join(home, ".bashrc"), + [ + "# If not running interactively, don't do anything", + "case $- in", + " *i*) ;;", + " *) return;;", + "esac", + "", + ].join("\n"), + ); const first = runSetupPolicyOnly(home, { CODEX_CLOUD_ACCESS_PROFILE: "offline", @@ -850,9 +866,18 @@ describe("Codex Cloud environment contract", () => { expect(config.match(/^\[shell_environment_policy\]$/gm)).toHaveLength(1); const profile = readRuntimeProfile(home); + expect(profile).toContain("export CODEX_CLOUD_PROFILE_LOADED=1"); expect(profile).toContain('export CODEX_CLOUD_ACCESS_PROFILE="offline"'); expect(profile).toContain("export RAG_PROVIDER_MODE=offline"); + const bashrc = readFileSync(path.join(home, ".bashrc"), "utf8"); + expect(bashrc.indexOf(".clinical-kb-codex-cloud.sh")).toBeGreaterThanOrEqual(0); + expect(bashrc.indexOf(".clinical-kb-codex-cloud.sh")).toBeLessThan(bashrc.indexOf("return;;")); + + expect(shouldAutoSourceCloudProfile({ CODEX_CLOUD: "1", HOME: home })).toBe(true); + expect(shouldAutoSourceCloudProfile({ CODEX_CLOUD: "1", CODEX_CLOUD_PROFILE_LOADED: "1", HOME: home })).toBe(false); + expect(shouldAutoSourceCloudProfile({ CODEX_CLOUD: "1", NODE_ENV: "test", HOME: home })).toBe(false); + const second = runSetupPolicyOnly(home, { CODEX_CLOUD_ACCESS_PROFILE: "offline", }); From 953409c1509c47acbd828ef5f252548b4c517d66 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 22:59:56 +0800 Subject: [PATCH 08/20] docs(ledger): record review for ce6c8a8e19 on codex/cloud-policy-clarity Co-Authored-By: Claude Fable 5 --- ...00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md diff --git a/docs/branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md b/docs/branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md deleted file mode 100644 index 63d03c644d..0000000000 --- a/docs/branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md +++ /dev/null @@ -1 +0,0 @@ -| 2026-10-16 | codex/cloud-policy-clarity | bdb0cea521800eb85f47fa3a0de3ce7869082a4c | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; removed all xhigh prompt-marker references across policies/skills/RAG launch checks, added GH_TOKEN to known launcher scrub path, clarified activation guidance) | check:codex-cloud, vitest (tests/codex-cloud-setup.test.ts, tests/rag-local-agent-policy.test.ts, tests/rag-plan-package-parity.test.ts, tests/organisation-decisions.test.ts: 150 passed), docs:maintain, check:instructions, check:decisions, check:organisation | From 51e6077ab942c39f98d600faae820e10957193e1 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 23:02:11 +0800 Subject: [PATCH 09/20] fix(codex-cloud): add JSDoc env type annotations to shouldAutoSourceCloudProfile Co-Authored-By: Claude Fable 5 --- scripts/check-codex-cloud-setup.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/check-codex-cloud-setup.mjs b/scripts/check-codex-cloud-setup.mjs index 0721e06cd8..78d0c07c90 100644 --- a/scripts/check-codex-cloud-setup.mjs +++ b/scripts/check-codex-cloud-setup.mjs @@ -1330,6 +1330,7 @@ export async function validateCodexCloudRuntime(env = process.env) { return errors; } +/** @param {NodeJS.ProcessEnv | Record} [env] */ function readableRuntimeProfile(env = process.env) { if (!env.HOME) return null; const profilePath = path.join(env.HOME, ".clinical-kb-codex-cloud.sh"); @@ -1340,6 +1341,7 @@ function readableRuntimeProfile(env = process.env) { } } +/** @param {NodeJS.ProcessEnv | Record} [env] */ export function shouldAutoSourceCloudProfile(env = process.env) { return ( env.CODEX_CLOUD === "1" && From d8a5a2675e70a7d15c34d85e981a118b7992bee2 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 23:02:17 +0800 Subject: [PATCH 10/20] docs(ledger): record review for 51e6077ab9 on codex/cloud-policy-clarity Co-Authored-By: Claude Fable 5 --- docs/branch-review-index.md | 2 +- ...fc3b3b62a8651ff2047b9c92ba7aba72bc9323f665c9fc3c0b.record.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/branch-review-records/ed2f501aad3270fc3b3b62a8651ff2047b9c92ba7aba72bc9323f665c9fc3c0b.record.md diff --git a/docs/branch-review-index.md b/docs/branch-review-index.md index 26e679149e..c2c0348617 100644 --- a/docs/branch-review-index.md +++ b/docs/branch-review-index.md @@ -79,8 +79,8 @@ Scope and outcome are truncated; follow the record link for the full six-cell ro | Date | Ref | Scope | Outcome | Record | | --- | --- | --- | --- | --- | | 2026-10-16 | fix/adversarial-remediation-20261016 | Adversarial assessment + parallel fix swarm + post-fix adversarial review across calculato… | All P0/P1/P2 findings fixed and verified; zero RAG files touched | [2a6b6200](branch-review-records/2a6b620065f5371039438fdbff73be97da6baf6c40dace3596e26c7bad0047dd.record.md) | -| 2026-10-16 | codex/cloud-policy-clarity | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; removed all xhigh prompt-marker references… | [3dd0e7e3](branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md) | | 2026-10-16 | feat/backlog-remediation-20261016 | prlanded | PR #3571 squash-merged cleanly into main (e526f8a4d5ad00ad05c5b780262b… | [ad2c45bc](branch-review-records/ad2c45bc2f3c606a7847421acc887ddf4861ab0563a5b96b4c6315b066837d90.record.md) | +| 2026-10-16 | codex/cloud-policy-clarity | Codex Cloud reasoning-effort, raw-env, and environment script hardening | PASS (0 blocking findings; removed all xhigh prompt-marker references,… | [ed2f501a](branch-review-records/ed2f501aad3270fc3b3b62a8651ff2047b9c92ba7aba72bc9323f665c9fc3c0b.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted admin pilot shared announcement correction; file SHA256 0f76deaa4d8d9ad46139d0… | Independent frontend source review ACCEPT; visible message and polite… | [263f1f06](branch-review-records/263f1f0680e9d5cda1bed9bb2a62853d3a34b78b5ad60054971520fdc884cf1c.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted native-PDF layout v5 producer 352d178978ef9086df1df708aa71266538076a2f5050a526… | Independent technical P1/P2 closure and qualified representative-sourc… | [6d2fd2e8](branch-review-records/6d2fd2e81761e17d32bb56bd41261efe8f9239ef266cf85a512c1021f889dd4b.record.md) | | 2026-10-15 | PR #3546 / codex/ingestion-rag-pilot-handover-20261014 | bounded OCR detail source safety and independent whole-table fidelity | ACCEPT by independent ingestion-worker and clinical-governance reviewe… | [7c72c71e](branch-review-records/7c72c71e0806655f9c5223a2a42aa255d84ff820805f3f6a50edea27cc174ac2.record.md) | diff --git a/docs/branch-review-records/ed2f501aad3270fc3b3b62a8651ff2047b9c92ba7aba72bc9323f665c9fc3c0b.record.md b/docs/branch-review-records/ed2f501aad3270fc3b3b62a8651ff2047b9c92ba7aba72bc9323f665c9fc3c0b.record.md new file mode 100644 index 0000000000..d4cbe3fcf7 --- /dev/null +++ b/docs/branch-review-records/ed2f501aad3270fc3b3b62a8651ff2047b9c92ba7aba72bc9323f665c9fc3c0b.record.md @@ -0,0 +1 @@ +| 2026-10-16 | codex/cloud-policy-clarity | 51e6077ab942c39f98d600faae820e10957193e1 | Codex Cloud reasoning-effort, raw-env, and environment script hardening | PASS (0 blocking findings; removed all xhigh prompt-marker references, hardened .bashrc prepend, command-shim fallback, check-codex-cloud auto-profile load, Node 24.15.0 diagnostic floor, and offline provider env scrubbing) | check:codex-cloud, vitest (tests/codex-cloud-diagnose.test.ts, tests/codex-cloud-setup.test.ts: 50 passed), docs:maintain, check-format-changed, typecheck | From 3e0876f6e81d765f6d3695c74385d5b5a91b7951 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 23:06:43 +0800 Subject: [PATCH 11/20] chore(cloud): remove xhighConfirmed from RAG phase receipt schemas and refine GH_TOKEN raw-env warning Co-Authored-By: Claude Fable 5 --- .../rag-upgrade/canonical/phase-receipt.schema.json | 2 -- .../rag-upgrade/canonical/phase-receipt.template.json | 1 - .../rag-upgrade/cloud/phase-receipt.schema.json | 2 -- .../rag-upgrade/cloud/phase-receipt.template.json | 1 - .../rag-upgrade/local/phase-receipt.schema.json | 2 -- .../rag-upgrade/local/phase-receipt.template.json | 1 - scripts/check-codex-cloud-raw-env.sh | 8 ++++++-- scripts/check-rag-phase-receipts.mjs | 3 --- 8 files changed, 6 insertions(+), 14 deletions(-) diff --git a/docs/superpowers/rag-upgrade/canonical/phase-receipt.schema.json b/docs/superpowers/rag-upgrade/canonical/phase-receipt.schema.json index f6ec9e671a..a04ca5bf90 100644 --- a/docs/superpowers/rag-upgrade/canonical/phase-receipt.schema.json +++ b/docs/superpowers/rag-upgrade/canonical/phase-receipt.schema.json @@ -17,7 +17,6 @@ "programmeImplementationBase", "branch", "launchProfile", - "xhighConfirmed", "controllerRouting", "capabilityEvidence", "phaseStartSha", @@ -45,7 +44,6 @@ "programmeImplementationBase": { "$ref": "#/$defs/gitSha" }, "branch": { "type": "string", "minLength": 1 }, "launchProfile": { "enum": ["high", "xhigh"] }, - "xhighConfirmed": { "type": "boolean" }, "controllerRouting": { "$ref": "#/$defs/agentRouting" }, "capabilityEvidence": { "type": "array", diff --git a/docs/superpowers/rag-upgrade/canonical/phase-receipt.template.json b/docs/superpowers/rag-upgrade/canonical/phase-receipt.template.json index db67db6505..f3b065cf16 100644 --- a/docs/superpowers/rag-upgrade/canonical/phase-receipt.template.json +++ b/docs/superpowers/rag-upgrade/canonical/phase-receipt.template.json @@ -11,7 +11,6 @@ "programmeImplementationBase": "f3d1a3cce2c943ad3083425ed9c7c46dbef23087", "branch": "codex/rag-upgrade-p00", "launchProfile": "high", - "xhighConfirmed": false, "controllerRouting": { "agentId": "controller-p00", "runtimeHost": "codex-cloud", diff --git a/docs/superpowers/rag-upgrade/cloud/phase-receipt.schema.json b/docs/superpowers/rag-upgrade/cloud/phase-receipt.schema.json index f6ec9e671a..a04ca5bf90 100644 --- a/docs/superpowers/rag-upgrade/cloud/phase-receipt.schema.json +++ b/docs/superpowers/rag-upgrade/cloud/phase-receipt.schema.json @@ -17,7 +17,6 @@ "programmeImplementationBase", "branch", "launchProfile", - "xhighConfirmed", "controllerRouting", "capabilityEvidence", "phaseStartSha", @@ -45,7 +44,6 @@ "programmeImplementationBase": { "$ref": "#/$defs/gitSha" }, "branch": { "type": "string", "minLength": 1 }, "launchProfile": { "enum": ["high", "xhigh"] }, - "xhighConfirmed": { "type": "boolean" }, "controllerRouting": { "$ref": "#/$defs/agentRouting" }, "capabilityEvidence": { "type": "array", diff --git a/docs/superpowers/rag-upgrade/cloud/phase-receipt.template.json b/docs/superpowers/rag-upgrade/cloud/phase-receipt.template.json index db67db6505..f3b065cf16 100644 --- a/docs/superpowers/rag-upgrade/cloud/phase-receipt.template.json +++ b/docs/superpowers/rag-upgrade/cloud/phase-receipt.template.json @@ -11,7 +11,6 @@ "programmeImplementationBase": "f3d1a3cce2c943ad3083425ed9c7c46dbef23087", "branch": "codex/rag-upgrade-p00", "launchProfile": "high", - "xhighConfirmed": false, "controllerRouting": { "agentId": "controller-p00", "runtimeHost": "codex-cloud", diff --git a/docs/superpowers/rag-upgrade/local/phase-receipt.schema.json b/docs/superpowers/rag-upgrade/local/phase-receipt.schema.json index f6ec9e671a..a04ca5bf90 100644 --- a/docs/superpowers/rag-upgrade/local/phase-receipt.schema.json +++ b/docs/superpowers/rag-upgrade/local/phase-receipt.schema.json @@ -17,7 +17,6 @@ "programmeImplementationBase", "branch", "launchProfile", - "xhighConfirmed", "controllerRouting", "capabilityEvidence", "phaseStartSha", @@ -45,7 +44,6 @@ "programmeImplementationBase": { "$ref": "#/$defs/gitSha" }, "branch": { "type": "string", "minLength": 1 }, "launchProfile": { "enum": ["high", "xhigh"] }, - "xhighConfirmed": { "type": "boolean" }, "controllerRouting": { "$ref": "#/$defs/agentRouting" }, "capabilityEvidence": { "type": "array", diff --git a/docs/superpowers/rag-upgrade/local/phase-receipt.template.json b/docs/superpowers/rag-upgrade/local/phase-receipt.template.json index db67db6505..f3b065cf16 100644 --- a/docs/superpowers/rag-upgrade/local/phase-receipt.template.json +++ b/docs/superpowers/rag-upgrade/local/phase-receipt.template.json @@ -11,7 +11,6 @@ "programmeImplementationBase": "f3d1a3cce2c943ad3083425ed9c7c46dbef23087", "branch": "codex/rag-upgrade-p00", "launchProfile": "high", - "xhighConfirmed": false, "controllerRouting": { "agentId": "controller-p00", "runtimeHost": "codex-cloud", diff --git a/scripts/check-codex-cloud-raw-env.sh b/scripts/check-codex-cloud-raw-env.sh index bc42c5148c..28a1b32b0b 100755 --- a/scripts/check-codex-cloud-raw-env.sh +++ b/scripts/check-codex-cloud-raw-env.sh @@ -74,8 +74,12 @@ printf '[Codex Cloud Raw Env] FAIL-KNOWN: inherited documented launcher defect n printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: use only the generated profile and command shims; raw boundary remains failed.\n' >&2 for name in "${known[@]}"; do case "$name" in - OPENAI_BASE_URL) printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: OPENAI_BASE_URL can redirect OpenAI-bound traffic; never invoke OpenAI clients from the raw parent or any binary that bypasses the profile/shim scrub.\n' >&2 ;; - GH_TOKEN) printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: GH_TOKEN carries host GitHub credentials; never invoke gh/GitHub clients from the raw parent or any binary that bypasses the profile/shim scrub.\n' >&2 ;; + OPENAI_BASE_URL) + printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: OPENAI_BASE_URL can redirect OpenAI-bound traffic; never invoke OpenAI clients from the raw parent or any binary that bypasses the profile/shim scrub.\n' >&2 + ;; + GH_TOKEN) + printf '[Codex Cloud Raw Env] CONTINUE-RESTRICTED: GH_TOKEN carries host GitHub credentials; never invoke gh, git credential helpers, or network clients from the raw parent or any binary that bypasses the profile/shim scrub.\n' >&2 + ;; esac done exit 2 diff --git a/scripts/check-rag-phase-receipts.mjs b/scripts/check-rag-phase-receipts.mjs index e6b5cfa2d3..2b8c4bbd54 100644 --- a/scripts/check-rag-phase-receipts.mjs +++ b/scripts/check-rag-phase-receipts.mjs @@ -408,9 +408,6 @@ function validateCapabilityEvidence(items, label, errors, requireTracked) { function validateModelRouting(receipt, phase, errors, requireTracked) { const controllerReasoning = manifest.adaptiveEffortPolicy.highLaunchPhases.includes(phase.id) ? "high" : "xhigh"; if (receipt.launchProfile !== controllerReasoning) errors.push(`launchProfile must be ${controllerReasoning}`); - if (receipt.xhighConfirmed !== (controllerReasoning === "xhigh")) { - errors.push(`xhighConfirmed must be ${controllerReasoning === "xhigh"}`); - } validateAgentRouting( receipt.controllerRouting, { model: manifest.defaultAgentPolicy.controllerModel, reasoning: controllerReasoning }, From db82acc1df32a209f02a33e0c2666fb2458f7fb1 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 16 Oct 2026 23:06:49 +0800 Subject: [PATCH 12/20] docs(ledger): record review for 3e0876f6e8 on codex/cloud-policy-clarity Co-Authored-By: Claude Fable 5 --- docs/branch-review-index.md | 2 +- ...223aa9f81e3d88a1a08f2b8a4844646d3a8eaa2cabd493c33.record.md} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/branch-review-records/{3a582c831d5cba8c4df9439827c1c6260eaf6b5b655b72dd3d2136b55a3962bc.record.md => 7f059fca46aac02223aa9f81e3d88a1a08f2b8a4844646d3a8eaa2cabd493c33.record.md} (74%) diff --git a/docs/branch-review-index.md b/docs/branch-review-index.md index 909271b65e..5667ef695a 100644 --- a/docs/branch-review-index.md +++ b/docs/branch-review-index.md @@ -79,8 +79,8 @@ Scope and outcome are truncated; follow the record link for the full six-cell ro | Date | Ref | Scope | Outcome | Record | | --- | --- | --- | --- | --- | | 2026-10-16 | fix/adversarial-remediation-20261016 | Adversarial assessment + parallel fix swarm + post-fix adversarial review across calculato… | All P0/P1/P2 findings fixed and verified; zero RAG files touched | [2a6b6200](branch-review-records/2a6b620065f5371039438fdbff73be97da6baf6c40dace3596e26c7bad0047dd.record.md) | -| 2026-10-16 | codex/cloud-policy-clarity | Codex Cloud environment script and shell-profile hardening | PASS (0 blocking findings; hardened .bashrc prepend, command-shim fall… | [3a582c83](branch-review-records/3a582c831d5cba8c4df9439827c1c6260eaf6b5b655b72dd3d2136b55a3962bc.record.md) | | 2026-10-16 | codex/cloud-policy-clarity | Codex Cloud reasoning-effort and raw-env policy overhaul | PASS (0 blocking findings; removed all xhigh prompt-marker references… | [3dd0e7e3](branch-review-records/3dd0e7e32634c00735102bf22ba9883745ad72dc5db730b1dce2c33f03e699f0.record.md) | +| 2026-10-16 | codex/cloud-policy-clarity | Codex Cloud environment script and shell-profile hardening | PASS (0 blocking findings; hardened .bashrc prepend, command-shim fall… | [7f059fca](branch-review-records/7f059fca46aac02223aa9f81e3d88a1a08f2b8a4844646d3a8eaa2cabd493c33.record.md) | | 2026-10-16 | feat/backlog-remediation-20261016 | prlanded | PR #3571 squash-merged cleanly into main (e526f8a4d5ad00ad05c5b780262b… | [ad2c45bc](branch-review-records/ad2c45bc2f3c606a7847421acc887ddf4861ab0563a5b96b4c6315b066837d90.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted admin pilot shared announcement correction; file SHA256 0f76deaa4d8d9ad46139d0… | Independent frontend source review ACCEPT; visible message and polite… | [263f1f06](branch-review-records/263f1f0680e9d5cda1bed9bb2a62853d3a34b78b5ad60054971520fdc884cf1c.record.md) | | 2026-10-15 | codex/ingestion-rag-pilot-handover-20261014 | Uncommitted native-PDF layout v5 producer 352d178978ef9086df1df708aa71266538076a2f5050a526… | Independent technical P1/P2 closure and qualified representative-sourc… | [6d2fd2e8](branch-review-records/6d2fd2e81761e17d32bb56bd41261efe8f9239ef266cf85a512c1021f889dd4b.record.md) | diff --git a/docs/branch-review-records/3a582c831d5cba8c4df9439827c1c6260eaf6b5b655b72dd3d2136b55a3962bc.record.md b/docs/branch-review-records/7f059fca46aac02223aa9f81e3d88a1a08f2b8a4844646d3a8eaa2cabd493c33.record.md similarity index 74% rename from docs/branch-review-records/3a582c831d5cba8c4df9439827c1c6260eaf6b5b655b72dd3d2136b55a3962bc.record.md rename to docs/branch-review-records/7f059fca46aac02223aa9f81e3d88a1a08f2b8a4844646d3a8eaa2cabd493c33.record.md index 097c9f85a1..823e2aa81c 100644 --- a/docs/branch-review-records/3a582c831d5cba8c4df9439827c1c6260eaf6b5b655b72dd3d2136b55a3962bc.record.md +++ b/docs/branch-review-records/7f059fca46aac02223aa9f81e3d88a1a08f2b8a4844646d3a8eaa2cabd493c33.record.md @@ -1 +1 @@ -| 2026-10-16 | codex/cloud-policy-clarity | d8a5a2675e70a7d15c34d85e981a118b7992bee2 | Codex Cloud environment script and shell-profile hardening | PASS (0 blocking findings; hardened .bashrc prepend, command-shim fallback, check-codex-cloud auto-profile load, Node 24.15.0 diagnostic floor, offline provider env scrubbing, and receipt schema cleanup) | check:codex-cloud, vitest (tests/codex-cloud-diagnose.test.ts, tests/codex-cloud-setup.test.ts: 50 passed), docs:maintain, check-format-changed, typecheck | +| 2026-10-16 | codex/cloud-policy-clarity | 3e0876f6e81d765f6d3695c74385d5b5a91b7951 | Codex Cloud environment script and shell-profile hardening | PASS (0 blocking findings; hardened .bashrc prepend, command-shim fallback, check-codex-cloud auto-profile load, Node 24.15.0 diagnostic floor, offline provider env scrubbing, and receipt schema cleanup) | check:codex-cloud, vitest (tests/codex-cloud-diagnose.test.ts, tests/codex-cloud-setup.test.ts: 50 passed), docs:maintain, check-format-changed, typecheck | From 59c030dbf11b43dfe0ca08ccb690f152ffaa1e31 Mon Sep 17 00:00:00 2001 From: "qodo-code-review[bot]" <151058649+qodo-code-review[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 15:21:23 +0000 Subject: [PATCH 13/20] fix: Relocate existing Cloud profile blocks --- scripts/setup-codex-cloud.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/setup-codex-cloud.sh b/scripts/setup-codex-cloud.sh index de010dd12b..ec0e108534 100755 --- a/scripts/setup-codex-cloud.sh +++ b/scripts/setup-codex-cloud.sh @@ -271,14 +271,16 @@ trap - EXIT profile_source='[ -f "$HOME/.clinical-kb-codex-cloud.sh" ] && . "$HOME/.clinical-kb-codex-cloud.sh"' for shell_profile in "$HOME/.bashrc" "$HOME/.profile" "$HOME/.bash_profile"; do touch "$shell_profile" - if ! grep -Fq '.clinical-kb-codex-cloud.sh' "$shell_profile"; then - profile_existing="$(<"$shell_profile")" - if [[ -n "$profile_existing" ]]; then - printf '# PsychSift Codex Cloud runtime\n%s\n\n%s\n' "$profile_source" "$profile_existing" > "$shell_profile" - else - printf '# PsychSift Codex Cloud runtime\n%s\n' "$profile_source" > "$shell_profile" - fi + profile_existing="$(<"$shell_profile")" + profile_existing="$(printf '%s\n' "$profile_existing" | grep -Fvx '# PsychSift Codex Cloud runtime' || true)" + profile_existing="$(printf '%s\n' "$profile_existing" | grep -Fvx "$profile_source" || true)" + profile_candidate="$(mktemp "${shell_profile}.XXXXXX")" + if [[ -n "$profile_existing" ]]; then + printf '# PsychSift Codex Cloud runtime\n%s\n\n%s\n' "$profile_source" "$profile_existing" > "$profile_candidate" + else + printf '# PsychSift Codex Cloud runtime\n%s\n' "$profile_source" > "$profile_candidate" fi + mv -f "$profile_candidate" "$shell_profile" done # Test harness only: write the runtime profile + shell policy, then stop before From fc2164c5c71f14dc03194a9cb3b5ab46f68e83ae Mon Sep 17 00:00:00 2001 From: "qodo-code-review[bot]" <151058649+qodo-code-review[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 15:21:26 +0000 Subject: [PATCH 14/20] =?UTF-8?q?fix:=203=20findings=20=E2=80=94=20Validat?= =?UTF-8?q?e=20Node=20version=20before=20creating=20shims;=20Allow=20PAT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Validate Node version before creating shims - Allow PATH fallback when nvm has no Node - Resolve split Node command installations --- scripts/install-codex-cloud-command-shims.sh | 31 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/scripts/install-codex-cloud-command-shims.sh b/scripts/install-codex-cloud-command-shims.sh index 82085df3e6..461e891f21 100644 --- a/scripts/install-codex-cloud-command-shims.sh +++ b/scripts/install-codex-cloud-command-shims.sh @@ -19,9 +19,20 @@ runtime_profile="$HOME/.clinical-kb-codex-cloud.sh" # shellcheck source=/dev/null source "$runtime_profile" +node_version_supported() { + local version="$1" + local actual_major actual_minor actual_patch + [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || return 1 + IFS=. read -r actual_major actual_minor actual_patch <<< "$version" + (( actual_major < 25 )) || return 1 + (( actual_major > 24 )) && return 0 + (( actual_minor > 15 )) && return 0 + (( actual_minor == 15 && actual_patch >= 0 )) +} + resolved_node_version="" if command -v nvm >/dev/null 2>&1; then - resolved_node_version="$(nvm version "$expected_node_major")" + resolved_node_version="$(nvm version "$expected_node_major" 2>/dev/null || true)" fi if [[ -n "$resolved_node_version" && "$resolved_node_version" != "N/A" ]]; then node_bin="$NVM_DIR/versions/node/$resolved_node_version/bin" @@ -34,11 +45,25 @@ else fallback_path="${fallback_path%:}" fallback_node="$(PATH="$fallback_path" command -v node 2>/dev/null || true)" [[ -n "$fallback_node" ]] || fail "Node ${expected_node_major} is unavailable through nvm or PATH." + fallback_node_version="$($fallback_node -p 'process.versions.node' 2>/dev/null || true)" + node_version_supported "$fallback_node_version" || fail "Node ${expected_node_major}.x >=24.15.0 and <25 is required; detected ${fallback_node_version:-unavailable}." node_bin="$(cd "$(dirname "$fallback_node")" && pwd)" fi +node_version="$($node_bin/node -p 'process.versions.node' 2>/dev/null || true)" +node_version_supported "$node_version" || fail "Node ${expected_node_major}.x >=24.15.0 and <25 is required; detected ${node_version:-unavailable}." mkdir -p "$HOME/.local/bin" for command_name in node npm npx; do - [[ -x "$node_bin/$command_name" ]] || fail "${command_name} is unavailable in Node ${expected_node_major}." + if [[ "$command_name" = node ]]; then + command_path="$node_bin/node" + else + command_path="" + if [[ -x "$node_bin/$command_name" ]]; then + command_path="$node_bin/$command_name" + else + command_path="$(PATH="${fallback_path:-$PATH}" command -v "$command_name" 2>/dev/null || true)" + fi + fi + [[ -x "$command_path" ]] || fail "${command_name} is unavailable in Node ${expected_node_major}." cat > "$HOME/.local/bin/$command_name" < Date: Fri, 16 Oct 2026 15:21:30 +0000 Subject: [PATCH 15/20] fix: Report Cloud profile re-exec failures --- scripts/check-codex-cloud-setup.mjs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/check-codex-cloud-setup.mjs b/scripts/check-codex-cloud-setup.mjs index 78d0c07c90..8c3996827f 100644 --- a/scripts/check-codex-cloud-setup.mjs +++ b/scripts/check-codex-cloud-setup.mjs @@ -1371,6 +1371,13 @@ if (isDirectEntrypoint(import.meta.url)) { ], { cwd: repoRoot, stdio: "inherit" }, ); + if (reexec.error) { + console.error( + `[Codex Cloud Check] FAIL: could not re-exec through bash to load ${runtimeProfilePath}: ${reexec.error.message}`, + ); + } else if (reexec.signal) { + console.error(`[Codex Cloud Check] FAIL: bash re-exec was terminated by signal ${reexec.signal}.`); + } process.exitCode = reexec.status ?? 1; } else { const errors = validateCodexCloudSetup(); From b9d688ca63e4a47a97f4b6bc898a2812b3ea8943 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Sat, 17 Oct 2026 00:26:57 +0800 Subject: [PATCH 16/20] fix(codex-cloud): unbreak CI and close open review findings on #3587 (#3588) * fix(codex-cloud): unbreak CI and close open review findings on #3587 - Treat a blank HEALTH_DEEP_PROBE_SECRET as unset. The offline test wrapper now blanks it, and the strict min(16) rule made every route importing env throw, which failed the unit-coverage and Playwright build jobs. A non-blank value must still be 16+ characters, and an unset secret keeps the deep probe closed. - Shim installer: require Node major 24 (22.x and 20.x no longer pass the fallback check), and skip $HOME/.local/bin in every PATH lookup so a shim can never resolve to itself. - Profile relocation: drop the old separator so reruns do not add blank lines. - Bring the contract checker and tests in line with the shim and profile changes already on this branch. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_016NaMorGX7ibPrednN1p5qA * fix(codex-cloud): stop shim PATH cleanup hanging on home paths with glob characters The loop condition matched "$HOME/.local/bin" literally, but the replacement treated $HOME as a pattern, so a home like /tmp/user[1] left the entry in place and the loop never ended. Quote the pattern, and add a regression test that hangs on the old code. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_016NaMorGX7ibPrednN1p5qA * fix: Remove shim PATH entries using literal comparison * fix(codex-cloud): match the literal-comparison PATH cleanup in the setup contract check The shim PATH cleanup now compares each entry literally (no glob replacement), so the static contract check looks for that form instead of the old replacement text. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_016NaMorGX7ibPrednN1p5qA --------- Co-authored-by: Claude Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com> --- scripts/check-codex-cloud-setup.mjs | 7 +++- scripts/install-codex-cloud-command-shims.sh | 42 +++++++++++++------- scripts/setup-codex-cloud.sh | 2 + src/lib/env.ts | 4 +- tests/codex-cloud-setup.test.ts | 21 +++++++--- tests/env.test.ts | 21 ++++++++++ 6 files changed, 74 insertions(+), 23 deletions(-) diff --git a/scripts/check-codex-cloud-setup.mjs b/scripts/check-codex-cloud-setup.mjs index 8c3996827f..78dc144b46 100644 --- a/scripts/check-codex-cloud-setup.mjs +++ b/scripts/check-codex-cloud-setup.mjs @@ -1081,13 +1081,16 @@ function validateMaintenanceAndCommandShims(sources, errors) { } for (const [pattern, message] of [ [/nvm version/, "Cloud command shims must resolve the selected Node version without following their own wrappers."], - [/clean_path=.*\.local.*bin/, "Cloud command shims must remove their directory before running child npm scripts."], + [ + /\[\[ "\\\$path_entry" == "\\\$HOME\/\.local\/bin" \]\] && continue[\s\S]*clean_path\+="\\\$path_entry"/, + "Cloud command shims must remove their directory before running child npm scripts.", + ], [/mkdir -p "\$HOME\/\.local\/bin"/, "Cloud command shims must create their destination directory."], [/\.clinical-kb-codex-cloud\.sh/, "Cloud command shims must load the generated profile."], ]) { requireMatch(errors, commandShims, pattern, message); } - if (!commandShims.includes('exec "$node_bin/$command_name" "\\$@"')) { + if (!commandShims.includes('exec "$command_path" "\\$@"')) { errors.push("Cloud command shims must execute absolute Node commands."); } } diff --git a/scripts/install-codex-cloud-command-shims.sh b/scripts/install-codex-cloud-command-shims.sh index 461e891f21..1afa584ffc 100644 --- a/scripts/install-codex-cloud-command-shims.sh +++ b/scripts/install-codex-cloud-command-shims.sh @@ -24,12 +24,26 @@ node_version_supported() { local actual_major actual_minor actual_patch [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || return 1 IFS=. read -r actual_major actual_minor actual_patch <<< "$version" - (( actual_major < 25 )) || return 1 - (( actual_major > 24 )) && return 0 + (( actual_major == 24 )) || return 1 (( actual_minor > 15 )) && return 0 (( actual_minor == 15 && actual_patch >= 0 )) } +# Existing shims must never be picked as their own targets, so every PATH lookup below skips +# $HOME/.local/bin. +fallback_path="" +path_entry_seen=false +IFS=: read -r -a path_entries <<< "$PATH" +for path_entry in "${path_entries[@]}"; do + [[ "$path_entry" == "$HOME/.local/bin" ]] && continue + if $path_entry_seen; then + fallback_path+=: + fi + fallback_path+="$path_entry" + path_entry_seen=true +done +unset path_entries path_entry path_entry_seen + resolved_node_version="" if command -v nvm >/dev/null 2>&1; then resolved_node_version="$(nvm version "$expected_node_major" 2>/dev/null || true)" @@ -37,12 +51,6 @@ fi if [[ -n "$resolved_node_version" && "$resolved_node_version" != "N/A" ]]; then node_bin="$NVM_DIR/versions/node/$resolved_node_version/bin" else - fallback_path=":$PATH:" - while [[ "$fallback_path" == *":$HOME/.local/bin:"* ]]; do - fallback_path="${fallback_path//:$HOME\/.local\/bin:/:}" - done - fallback_path="${fallback_path#:}" - fallback_path="${fallback_path%:}" fallback_node="$(PATH="$fallback_path" command -v node 2>/dev/null || true)" [[ -n "$fallback_node" ]] || fail "Node ${expected_node_major} is unavailable through nvm or PATH." fallback_node_version="$($fallback_node -p 'process.versions.node' 2>/dev/null || true)" @@ -60,7 +68,7 @@ for command_name in node npm npx; do if [[ -x "$node_bin/$command_name" ]]; then command_path="$node_bin/$command_name" else - command_path="$(PATH="${fallback_path:-$PATH}" command -v "$command_name" 2>/dev/null || true)" + command_path="$(PATH="$fallback_path" command -v "$command_name" 2>/dev/null || true)" fi fi [[ -x "$command_path" ]] || fail "${command_name} is unavailable in Node ${expected_node_major}." @@ -70,12 +78,18 @@ set -Eeuo pipefail # Generated by scripts/install-codex-cloud-command-shims.sh. Re-running setup # or maintenance replaces this wrapper through the same idempotent command. . "$runtime_profile" -clean_path=":\$PATH:" -while [[ "\$clean_path" == *":\$HOME/.local/bin:"* ]]; do - clean_path="\${clean_path//:\$HOME\/.local\/bin:/:}" +clean_path="" +path_entry_seen=false +IFS=: read -r -a path_entries <<< "\$PATH" +for path_entry in "\${path_entries[@]}"; do + [[ "\$path_entry" == "\$HOME/.local/bin" ]] && continue + if \$path_entry_seen; then + clean_path+=: + fi + clean_path+="\$path_entry" + path_entry_seen=true done -clean_path="\${clean_path#:}" -clean_path="\${clean_path%:}" +unset path_entries path_entry path_entry_seen if [[ -n "\$clean_path" ]]; then export PATH="$node_bin:\$clean_path" else diff --git a/scripts/setup-codex-cloud.sh b/scripts/setup-codex-cloud.sh index ec0e108534..21f291a57b 100755 --- a/scripts/setup-codex-cloud.sh +++ b/scripts/setup-codex-cloud.sh @@ -274,6 +274,8 @@ for shell_profile in "$HOME/.bashrc" "$HOME/.profile" "$HOME/.bash_profile"; do profile_existing="$(<"$shell_profile")" profile_existing="$(printf '%s\n' "$profile_existing" | grep -Fvx '# PsychSift Codex Cloud runtime' || true)" profile_existing="$(printf '%s\n' "$profile_existing" | grep -Fvx "$profile_source" || true)" + # Drop the separator a previous run wrote after the block so reruns stay idempotent. + profile_existing="$(printf '%s\n' "$profile_existing" | sed '/./,$!d')" profile_candidate="$(mktemp "${shell_profile}.XXXXXX")" if [[ -n "$profile_existing" ]]; then printf '# PsychSift Codex Cloud runtime\n%s\n\n%s\n' "$profile_source" "$profile_existing" > "$profile_candidate" diff --git a/src/lib/env.ts b/src/lib/env.ts index da38cc4875..55a3e57816 100644 --- a/src/lib/env.ts +++ b/src/lib/env.ts @@ -71,7 +71,9 @@ const envSchema = z .optional(), ), SUPABASE_DB_URL: z.string().url().optional(), - HEALTH_DEEP_PROBE_SECRET: z.string().min(16).optional(), + // Blank means unset (offline wrappers blank inherited secrets); an unset secret keeps the + // deep probe closed, and a non-blank value must still be at least 16 characters. + HEALTH_DEEP_PROBE_SECRET: z.preprocess(coerceBlankEnv, z.string().min(16).optional()), // Inbound webhook receivers. Each shared secret gates a machine-to-machine // endpoint under /api/webhooks/* and fails closed when unset (the route 503s // rather than trusting an unauthenticated caller). See docs/webhooks.md. diff --git a/tests/codex-cloud-setup.test.ts b/tests/codex-cloud-setup.test.ts index 942b264a44..d67f9836c1 100644 --- a/tests/codex-cloud-setup.test.ts +++ b/tests/codex-cloud-setup.test.ts @@ -690,7 +690,9 @@ describe("Codex Cloud environment contract", () => { new URL("../scripts/delete-codex-cloud-branch-with-pat.sh", import.meta.url), "utf8", ); - expect(setup).toContain("if ! grep -Fq '.clinical-kb-codex-cloud.sh'"); + expect(setup).toContain('profile_source=\'[ -f "$HOME/.clinical-kb-codex-cloud.sh" ]'); + expect(setup).toContain('grep -Fvx "$profile_source"'); + expect(setup).toContain("sed '/./,$!d'"); expect(setup).toContain('if [[ "$actual_version" != "$expected_version" ]]'); expect(setup).toContain('expected_node_range="$(sed'); expect(setup).toContain('if ! node_version_supported "$actual_node_version"; then'); @@ -753,8 +755,8 @@ describe("Codex Cloud environment contract", () => { } expect(commandShims).toContain('nvm version "$expected_node_major"'); expect(commandShims).toContain('node_bin="$NVM_DIR/versions/node/$resolved_node_version/bin"'); - expect(commandShims).toContain('while [[ "\\$clean_path" == *":\\$HOME/.local/bin:"* ]]; do'); - expect(commandShims).toContain('clean_path="\\${clean_path//:\\$HOME\\/.local\\/bin:/:}"'); + expect(commandShims).toContain('IFS=: read -r -a path_entries <<< "\\$PATH"'); + expect(commandShims).toContain('[[ "\\$path_entry" == "\\$HOME/.local/bin" ]] && continue'); expect(commandShims).toContain('if [[ -n "\\$clean_path" ]]; then'); expect(commandShims).toContain('export PATH="$node_bin"'); expect(commandShims).toContain('. "$runtime_profile"'); @@ -769,8 +771,10 @@ describe("Codex Cloud environment contract", () => { expect(patDelete).toContain("core.hooksPath=/dev/null"); }); - it("removes every adjacent command-shim PATH entry", () => { - const home = temporaryDirectory("codex-cloud-shims-"); + it("removes every adjacent command-shim PATH entry, including bracketed home paths", () => { + const homeRoot = temporaryDirectory("codex-cloud-shims-"); + const home = path.join(homeRoot, "home[1]"); + mkdirSync(home, { recursive: true }); const bashHome = bashPathEntry(home); const nodeVersion = "v24.19.0"; const nodeBin = path.join(home, ".nvm", "versions", "node", nodeVersion, "bin"); @@ -778,7 +782,12 @@ describe("Codex Cloud environment contract", () => { mkdirSync(nodeBin, { recursive: true }); for (const command of ["node", "npm", "npx"]) { const executable = path.join(nodeBin, command); - writeFileSync(executable, '#!/usr/bin/env bash\nprintf "%s\\n" "$PATH"\n'); + writeFileSync( + executable, + command === "node" + ? `#!/usr/bin/env bash\nif [[ "\${1:-}" = "-p" ]]; then printf "%s\\n" "${nodeVersion.slice(1)}"; else printf "%s\\n" "$PATH"; fi\n` + : '#!/usr/bin/env bash\nprintf "%s\\n" "$PATH"\n', + ); chmodSync(executable, 0o755); } writeFileSync( diff --git a/tests/env.test.ts b/tests/env.test.ts index 2b5fca1588..0e08d9c06c 100644 --- a/tests/env.test.ts +++ b/tests/env.test.ts @@ -20,3 +20,24 @@ describe("developer-area access-key environment parsing", () => { } }); }); + +describe("deep-probe secret environment parsing", () => { + afterEach(() => { + vi.unstubAllEnvs(); + vi.resetModules(); + }); + + it("treats a blank secret as unset, as the offline test wrapper leaves it", async () => { + vi.stubEnv("HEALTH_DEEP_PROBE_SECRET", ""); + + await expect(import("@/lib/env")).resolves.toMatchObject({ + env: { HEALTH_DEEP_PROBE_SECRET: undefined }, + }); + }); + + it("still rejects a non-blank secret shorter than 16 characters", async () => { + vi.stubEnv("HEALTH_DEEP_PROBE_SECRET", "too-short"); + + await expect(import("@/lib/env")).rejects.toThrow(); + }); +}); From ff8c5ef28fdd348e4ef8d652e8021c5fe7765969 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 16:46:55 +0000 Subject: [PATCH 17/20] test(codex-cloud): policy-only harness now expects the Cloud block in shell profiles #3587 writes the Cloud profile source into .bashrc/.profile/.bash_profile before the policy-only harness stops, so the relocation can be exercised without a real runtime. The harness isolation test still asserted those files were never created, which failed both of its cases in unit coverage partition 2. Assert the block is present instead; nothing outside the redirected HOME changes and no runtime is probed or installed. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_016NaMorGX7ibPrednN1p5qA --- tests/codex-cloud-policy-harness.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/codex-cloud-policy-harness.test.ts b/tests/codex-cloud-policy-harness.test.ts index 5464d1342e..a21349e399 100644 --- a/tests/codex-cloud-policy-harness.test.ts +++ b/tests/codex-cloud-policy-harness.test.ts @@ -119,8 +119,11 @@ describe("Codex Cloud policy-only harness runtime isolation", () => { expect(config).toContain(test.config); expect(config).toContain("[shell_environment_policy]"); expect(existsSync(path.join(test.home, ".clinical-kb-codex-cloud.sh"))).toBe(true); + // Setup now puts the Cloud profile source at the top of each shell profile before the harness stops, + // so the relocation can be tested without a real runtime. Only files inside the redirected HOME change. for (const profile of [".bashrc", ".profile", ".bash_profile"]) { - expect(existsSync(path.join(test.home, profile))).toBe(false); + const contents = readFileSync(path.join(test.home, profile), "utf8"); + expect(contents).toContain('. "$HOME/.clinical-kb-codex-cloud.sh"'); } }); From 9b03ee60fd919e2db77a177e81388ffcaa8f2586 Mon Sep 17 00:00:00 2001 From: "qodo-code-review[bot]" <151058649+qodo-code-review[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 16:50:13 +0000 Subject: [PATCH 18/20] fix: Assert the complete Cloud profile block at the top --- tests/codex-cloud-policy-harness.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/codex-cloud-policy-harness.test.ts b/tests/codex-cloud-policy-harness.test.ts index a21349e399..25c6186651 100644 --- a/tests/codex-cloud-policy-harness.test.ts +++ b/tests/codex-cloud-policy-harness.test.ts @@ -121,9 +121,12 @@ describe("Codex Cloud policy-only harness runtime isolation", () => { expect(existsSync(path.join(test.home, ".clinical-kb-codex-cloud.sh"))).toBe(true); // Setup now puts the Cloud profile source at the top of each shell profile before the harness stops, // so the relocation can be tested without a real runtime. Only files inside the redirected HOME change. + const expectedProfileBlock = + '# PsychSift Codex Cloud runtime\n[ -f "$HOME/.clinical-kb-codex-cloud.sh" ] && . "$HOME/.clinical-kb-codex-cloud.sh"\n'; for (const profile of [".bashrc", ".profile", ".bash_profile"]) { const contents = readFileSync(path.join(test.home, profile), "utf8"); - expect(contents).toContain('. "$HOME/.clinical-kb-codex-cloud.sh"'); + expect(contents.startsWith(expectedProfileBlock)).toBe(true); + expect(contents.split(expectedProfileBlock).length - 1).toBe(1); } }); From adf52eac1c17e96dda89dca7657689f1cd39b206 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 16:55:31 +0000 Subject: [PATCH 19/20] fix(codex-cloud): align the policy-only harness test with profile prepending and check the npm fallback The policy-only harness test still asserted that setup leaves .bashrc, .profile and .bash_profile untouched, but this PR now writes the Cloud profile block to the top of each before the harness stops (its own setup test depends on that). Assert the new behaviour: the block is first in every profile, and the runtime-call log still shows no runtime was probed or installed. This is what failed Unit coverage partition (2). Also address the open CodeRabbit finding on the shim installer: when the chosen Node install has no npm or npx and the installer falls back to PATH, require the repository's npm major (package.json engines.npm) instead of accepting any version. Adds a test for both outcomes. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01Hg9knRJzMaDsgMgtSHmtyh --- scripts/install-codex-cloud-command-shims.sh | 9 ++++ tests/codex-cloud-policy-harness.test.ts | 7 ++- tests/codex-cloud-setup.test.ts | 45 ++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/scripts/install-codex-cloud-command-shims.sh b/scripts/install-codex-cloud-command-shims.sh index 1afa584ffc..1aad4edb4f 100644 --- a/scripts/install-codex-cloud-command-shims.sh +++ b/scripts/install-codex-cloud-command-shims.sh @@ -13,6 +13,9 @@ cd "$repo_root" expected_node_major="$(tr -cd '0-9' < .node-version)" [[ -n "$expected_node_major" ]] || fail "Could not read the Node major from .node-version." +expected_npm_major="$(sed -n 's/.*"npm"[[:space:]]*:[[:space:]]*"\([0-9][0-9]*\)\.x".*/\1/p' package.json | head -n 1)" +[[ -n "$expected_npm_major" ]] || fail "Could not read the npm major from package.json engines.npm." + runtime_profile="$HOME/.clinical-kb-codex-cloud.sh" [[ -f "$runtime_profile" ]] || fail "The generated Cloud runtime profile is unavailable; run setup first." @@ -69,6 +72,12 @@ for command_name in node npm npx; do command_path="$node_bin/$command_name" else command_path="$(PATH="$fallback_path" command -v "$command_name" 2>/dev/null || true)" + # A PATH fallback may be an older installation, so it must meet the repository's npm range. + if [[ -x "$command_path" ]]; then + fallback_tool_version="$("$command_path" --version 2>/dev/null | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -n 1 || true)" + [[ "${fallback_tool_version%%.*}" = "$expected_npm_major" ]] || + fail "${command_name} ${expected_npm_major}.x is required (package.json engines.npm); the PATH fallback is ${fallback_tool_version:-unavailable}." + fi fi fi [[ -x "$command_path" ]] || fail "${command_name} is unavailable in Node ${expected_node_major}." diff --git a/tests/codex-cloud-policy-harness.test.ts b/tests/codex-cloud-policy-harness.test.ts index 5464d1342e..6d377d6292 100644 --- a/tests/codex-cloud-policy-harness.test.ts +++ b/tests/codex-cloud-policy-harness.test.ts @@ -119,8 +119,13 @@ describe("Codex Cloud policy-only harness runtime isolation", () => { expect(config).toContain(test.config); expect(config).toContain("[shell_environment_policy]"); expect(existsSync(path.join(test.home, ".clinical-kb-codex-cloud.sh"))).toBe(true); + // Setup now puts the Cloud profile at the top of each shell profile before the harness stops, + // so a non-interactive early return cannot skip it. That is shell configuration only: the + // runtime-call log above still proves no runtime was probed or installed. for (const profile of [".bashrc", ".profile", ".bash_profile"]) { - expect(existsSync(path.join(test.home, profile))).toBe(false); + const contents = readFileSync(path.join(test.home, profile), "utf8"); + expect(contents.startsWith("# PsychSift Codex Cloud runtime\n")).toBe(true); + expect(contents).toContain('. "$HOME/.clinical-kb-codex-cloud.sh"'); } }); diff --git a/tests/codex-cloud-setup.test.ts b/tests/codex-cloud-setup.test.ts index d67f9836c1..d16e69d29e 100644 --- a/tests/codex-cloud-setup.test.ts +++ b/tests/codex-cloud-setup.test.ts @@ -815,6 +815,51 @@ describe("Codex Cloud environment contract", () => { expect(resolvedPath).toEqual(expect.arrayContaining(["/usr/bin", "/bin"])); }, 120_000); + it("only accepts a PATH fallback npm and npx that meet the repository npm range", () => { + const home = temporaryDirectory("codex-cloud-shim-npm-home-"); + const bashHome = bashPathEntry(home); + const nodeVersion = "v24.19.0"; + const nodeBin = path.join(home, ".nvm", "versions", "node", nodeVersion, "bin"); + mkdirSync(nodeBin, { recursive: true }); + // This Node install has no npm or npx, so the installer must look elsewhere on PATH. + const node = path.join(nodeBin, "node"); + writeFileSync( + node, + `#!/usr/bin/env bash\nif [[ "\${1:-}" = "-p" ]]; then printf "%s\\n" "${nodeVersion.slice(1)}"; fi\n`, + ); + chmodSync(node, 0o755); + writeFileSync( + path.join(home, ".clinical-kb-codex-cloud.sh"), + [`export NVM_DIR="${bashHome}/.nvm"`, `nvm() { printf '${nodeVersion}\\n'; }`, ""].join("\n"), + ); + + const installWithFallbackNpm = (npmVersion: string) => { + const fallbackBin = temporaryDirectory("codex-cloud-shim-npm-path-"); + for (const command of ["npm", "npx"]) { + const executable = path.join(fallbackBin, command); + writeFileSync(executable, `#!/usr/bin/env bash\nprintf "%s\\n" "${npmVersion}"\n`); + chmodSync(executable, 0o755); + } + return spawnSync(bashCommand, ["scripts/install-codex-cloud-command-shims.sh"], { + cwd: repoRoot, + encoding: "utf8", + env: { + ...process.env, + HOME: bashHome, + PATH: `${bashPathEntry(fallbackBin)}:${bashPathList(process.env.PATH || "")}`, + }, + }); + }; + + const older = installWithFallbackNpm("10.9.0"); + expect(older.status).toBe(1); + expect(older.stderr).toContain("npm 11.x is required"); + expect(older.stderr).toContain("10.9.0"); + + const supported = installWithFallbackNpm("11.17.0"); + expect(supported.status, supported.stderr || supported.stdout).toBe(0); + }, 120_000); + it("prefers the exact Python 3.12 interpreter over an older python3 alias", () => { const home = temporaryDirectory("codex-cloud-python-home-"); const bin = temporaryDirectory("codex-cloud-python-"); From 94a24f7cc322aa14347a02b33712b70ce52f2329 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 17:19:26 +0000 Subject: [PATCH 20/20] fix(codex-cloud): quote Node paths in shim installer version probes A supported Node under a directory containing spaces was word-split during the version check, so setup failed before writing the shims. Adds a test with a spaced home directory (fails on the old code, passes now). Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_016NaMorGX7ibPrednN1p5qA --- scripts/install-codex-cloud-command-shims.sh | 4 +-- tests/codex-cloud-setup.test.ts | 31 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/scripts/install-codex-cloud-command-shims.sh b/scripts/install-codex-cloud-command-shims.sh index 1aad4edb4f..5acf0ca43a 100644 --- a/scripts/install-codex-cloud-command-shims.sh +++ b/scripts/install-codex-cloud-command-shims.sh @@ -56,11 +56,11 @@ if [[ -n "$resolved_node_version" && "$resolved_node_version" != "N/A" ]]; then else fallback_node="$(PATH="$fallback_path" command -v node 2>/dev/null || true)" [[ -n "$fallback_node" ]] || fail "Node ${expected_node_major} is unavailable through nvm or PATH." - fallback_node_version="$($fallback_node -p 'process.versions.node' 2>/dev/null || true)" + fallback_node_version="$("$fallback_node" -p 'process.versions.node' 2>/dev/null || true)" node_version_supported "$fallback_node_version" || fail "Node ${expected_node_major}.x >=24.15.0 and <25 is required; detected ${fallback_node_version:-unavailable}." node_bin="$(cd "$(dirname "$fallback_node")" && pwd)" fi -node_version="$($node_bin/node -p 'process.versions.node' 2>/dev/null || true)" +node_version="$("$node_bin/node" -p 'process.versions.node' 2>/dev/null || true)" node_version_supported "$node_version" || fail "Node ${expected_node_major}.x >=24.15.0 and <25 is required; detected ${node_version:-unavailable}." mkdir -p "$HOME/.local/bin" for command_name in node npm npx; do diff --git a/tests/codex-cloud-setup.test.ts b/tests/codex-cloud-setup.test.ts index d16e69d29e..1671482ffa 100644 --- a/tests/codex-cloud-setup.test.ts +++ b/tests/codex-cloud-setup.test.ts @@ -815,6 +815,37 @@ describe("Codex Cloud environment contract", () => { expect(resolvedPath).toEqual(expect.arrayContaining(["/usr/bin", "/bin"])); }, 120_000); + it("probes a supported Node installed under a directory containing spaces", () => { + const homeRoot = temporaryDirectory("codex-cloud-shim-space-"); + const home = path.join(homeRoot, "home with spaces"); + mkdirSync(home, { recursive: true }); + const bashHome = bashPathEntry(home); + const nodeVersion = "v24.19.0"; + const nodeBin = path.join(home, ".nvm", "versions", "node", nodeVersion, "bin"); + mkdirSync(nodeBin, { recursive: true }); + for (const command of ["node", "npm", "npx"]) { + const executable = path.join(nodeBin, command); + writeFileSync( + executable, + command === "node" + ? `#!/usr/bin/env bash\nif [[ "\${1:-}" = "-p" ]]; then printf "%s\\n" "${nodeVersion.slice(1)}"; fi\n` + : '#!/usr/bin/env bash\nprintf "%s\\n" "$PATH"\n', + ); + chmodSync(executable, 0o755); + } + writeFileSync( + path.join(home, ".clinical-kb-codex-cloud.sh"), + [`export NVM_DIR="${bashHome}/.nvm"`, `nvm() { printf '${nodeVersion}\\n'; }`, ""].join("\n"), + ); + + const install = spawnSync(bashCommand, ["scripts/install-codex-cloud-command-shims.sh"], { + cwd: repoRoot, + encoding: "utf8", + env: { ...process.env, HOME: bashHome, PATH: bashPathList(process.env.PATH || "") }, + }); + expect(install.status, install.stderr || install.stdout).toBe(0); + }, 120_000); + it("only accepts a PATH fallback npm and npx that meet the repository npm range", () => { const home = temporaryDirectory("codex-cloud-shim-npm-home-"); const bashHome = bashPathEntry(home);