Skip to content

[Release] Release-gate machinery does not enforce two guarantees the docs claim #14

Description

@jongan69

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:

  1. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions