Two places where a release control is documented as enforced but is not. Both surfaced during the PR/issue audit (see #7); both are gate-hardening rather than external evidence, so they do not belong on #7's Phase 0 checklist.
1. OPENDATING_RELEASE_APPROVED is not restricted to a release manager
docs/DEPLOYMENT.md states that only an authorized release manager may set the production approval variable, and lists it as gate 4:
- an authorized release manager explicitly sets the production approval variable.
scripts/release/assert-release-ready.mjs only does:
if (process.env.OPENDATING_RELEASE_APPROVED !== 'true') {
fail('Release approval is available only in the protected release environment.');
}
Nothing restricts who can set it, and no workflow scopes it to release-manager execution. Anyone who can run the submit scripts — locally or in a workflow — satisfies gate 4.
Fix: bind it to a protected GitHub environment with required reviewers, so the variable can only exist in a run an authorized approver released; or relax the documented claim to match what is actually enforced.
2. Audit exceptions do not validate provenance
scripts/check-production-audit.mjs allows an advisory when the package name, affectedRange, and resolved advisoryIds match an entry in security/audit-exceptions.json. It does not validate why the advisory is reachable.
The rationale in that file narrows the exemption to the Metro/CLI/image-inspection build subgraph. But entries exist for packages that ship runtime code — expo, react-native, react-native-reanimated, react-native-worklets — so the matcher will also accept a future advisory on those packages that has nothing to do with the build subgraph, as long as the ID and range line up.
The current 14 advisories are genuinely build-path only, so this is not an active exposure. It is a matcher that will not notice when that stops being true, on a file that expires 2026-09-30 and will be renewed under time pressure.
Fix: record the affected-path provenance per exception and validate it, or split runtime-shipping packages into their own exception set with their own reachability evidence.
Provenance
Both raised by CodeRabbit on #10, which was closed unmerged; neither was carried into #11.
Two places where a release control is documented as enforced but is not. Both surfaced during the PR/issue audit (see #7); both are gate-hardening rather than external evidence, so they do not belong on #7's Phase 0 checklist.
1.
OPENDATING_RELEASE_APPROVEDis not restricted to a release managerdocs/DEPLOYMENT.mdstates that only an authorized release manager may set the production approval variable, and lists it as gate 4:scripts/release/assert-release-ready.mjsonly does:Nothing restricts who can set it, and no workflow scopes it to release-manager execution. Anyone who can run the submit scripts — locally or in a workflow — satisfies gate 4.
Fix: bind it to a protected GitHub environment with required reviewers, so the variable can only exist in a run an authorized approver released; or relax the documented claim to match what is actually enforced.
2. Audit exceptions do not validate provenance
scripts/check-production-audit.mjsallows an advisory when the package name,affectedRange, and resolvedadvisoryIdsmatch an entry insecurity/audit-exceptions.json. It does not validate why the advisory is reachable.The rationale in that file narrows the exemption to the Metro/CLI/image-inspection build subgraph. But entries exist for packages that ship runtime code —
expo,react-native,react-native-reanimated,react-native-worklets— so the matcher will also accept a future advisory on those packages that has nothing to do with the build subgraph, as long as the ID and range line up.The current 14 advisories are genuinely build-path only, so this is not an active exposure. It is a matcher that will not notice when that stops being true, on a file that expires 2026-09-30 and will be renewed under time pressure.
Fix: record the affected-path provenance per exception and validate it, or split runtime-shipping packages into their own exception set with their own reachability evidence.
Provenance
Both raised by CodeRabbit on #10, which was closed unmerged; neither was carried into #11.