Skip to content

chore: harden bootstrap release automation - #42

Merged
anandpant merged 2 commits into
mainfrom
chore/harden-bootstrap-release
Jul 12, 2026
Merged

chore: harden bootstrap release automation#42
anandpant merged 2 commits into
mainfrom
chore/harden-bootstrap-release

Conversation

@anandpant

Copy link
Copy Markdown
Contributor

Summary

Stacks on #41. Fixes four defects an adversarial review found in the one-time npm "bootstrap publish" flow (.github/workflows/release.yml job bootstrap-package, scripts/reconcile-bootstrap-release.mjs, scripts/check-release-policy.mjs, docs/RELEASING.md):

  1. Revoke step could go green with a live token. A single transient npm whoami failure took the "already non-authenticating" branch and exited 0 without revoking. The step now probes liveness 3x with backoff both before and after revocation, and hard-fails on any mixed/inconclusive result — it only exits 0 when no publish was attempted and no token was supplied, or the token is verified non-authenticating.
  2. npm token revoke and granular access tokens. Research confirmed npm's December 2025 platform changes made npm CLI 11.16+ revoke granular tokens the same as classic tokens (the current npm-token CLI docs make no distinction). Kept CLI revoke as primary, added a registry DELETE /-/npm/v1/tokens/token/{token} API fallback for defense-in-depth, and made the step hard-fail with an explicit "manually revoke on npmjs.com now" message if both paths fail. Updated docs/RELEASING.md step 10 accordingly.
  3. Missing publish gate assertions. check-release-policy.mjs now asserts the bootstrap-package job's if: requires both workflow_dispatch and the main ref, that publish-prerelease/publish-stable each require NPM_PUBLISH_ENABLED == 'true' and a merged PR, and that the release/non-release branch conditions are correctly split between the two jobs.
  4. Attestation propagation lag hard-failed instead of retrying. A present package with an unpopulated dist.attestations.url now throws the retryable BootstrapUnavailableError instead of the non-retryable BootstrapMismatchError. A present-but-malformed URL still correctly stays a hard mismatch. Added unit tests for lag-then-success, permanent-absence exhaustion, and malformed-URL mismatch.

No identity/version values changed, and no existing check was weakened — only added to.

Test plan

  • pnpm run format — passes (biome), only a pre-existing informational schema-version notice unrelated to this change
  • pnpm exec vitest run scripts/reconcile-bootstrap-release.test.mjs — 6/6 passed
  • pnpm exec nx run-many -t identity-check release-policy-check lint test typecheck build skills-validate package-audit --projects=foundry-ai --outputStyle=static --skip-nx-cache — all 8 targets pass
  • Sanity check: temporarily removed the NPM_PUBLISH_ENABLED clause from publish-prerelease's if:release-policy-check failed with publish-prerelease must require NPM_PUBLISH_ENABLED=true.; restored and reconfirmed it passes

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

anandpant added a commit that referenced this pull request Jul 11, 2026
Three follow-ups from the independent review of PR #42:

1. Removed the registry API fallback (`DELETE /-/npm/v1/tokens/token/{token}`)
   from the npm token revocation step. That endpoint is the classic-token
   API and likely doesn't manage granular access tokens, so it was
   decorative resilience rather than a real fallback. `npm token revoke`
   is now the sole automated revocation mechanism; on failure it hard-fails
   immediately with a manual-revocation error, backstopped as before by the
   pre/post retry liveness probes. Updated check-release-policy.mjs
   assertions to match (assert the hard-fail behavior, assert the classic
   endpoint string is absent).

2. docs/RELEASING.md: note that the bootstrap granular token must be able
   to manage/revoke itself, and that npm's stated plan to restrict
   bypass-2FA/sensitive-action permissions on granular tokens sometime in
   2026 may eventually break CLI self-revocation — in which case the
   workflow step hard-fails by design and the operator must revoke
   manually on npmjs.com immediately.

3. .github/workflows/ci.yml: dropped the `branches: [main]` filter from
   the `pull_request` trigger so stacked PRs (base != main, like this one
   and PR #43) actually get the full CI check suite. push stays
   main-only; workflow_dispatch unchanged. Confirmed release-policy-check
   is unaffected since it only parses release.yml.

Verification: pnpm run format, the reconciliation test file (6/6), and
nx run-many -t identity-check release-policy-check lint test typecheck
--projects=foundry-ai all pass.

anandpant commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Jul 12, 10:18 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jul 12, 10:19 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jul 12, 10:19 PM UTC: @anand-testcompare merged this pull request with Graphite.

@anandpant
anandpant changed the base branch from chore/shipit-foundry-ai-identity to graphite-base/42 July 12, 2026 22:18
@anandpant
anandpant changed the base branch from graphite-base/42 to main July 12, 2026 22:18
Fixes four defects found in adversarial review of the PR #41 one-time
npm bootstrap publish flow:

1. The npm token revocation step could exit green on a single transient
   `npm whoami` failure without ever attempting revocation. It now
   probes liveness 3x with backoff before and after revocation, and
   hard-fails on any mixed or inconclusive result instead of guessing.

2. `npm token revoke` historically wasn't guaranteed to manage granular
   access tokens. As of npm's December 2025 platform changes, npm CLI
   11.16+ revokes granular tokens uniformly with classic tokens; the
   step keeps that as primary, adds a registry DELETE API fallback for
   defense-in-depth, and hard-fails with explicit manual-revocation
   instructions if both paths fail.

3. check-release-policy.mjs didn't assert the actual publish gates:
   bootstrap requiring both workflow_dispatch and the main ref,
   publish-prerelease/publish-stable requiring NPM_PUBLISH_ENABLED and
   a merged PR, and the release/non-release branch split between them.

4. A published package whose attestation URL hadn't propagated yet
   threw a non-retryable BootstrapMismatchError instead of the
   retryable BootstrapUnavailableError, causing reconciliation to fail
   immediately on ordinary propagation lag. A present-but-malformed URL
   still correctly stays a hard mismatch. Added tests for lag-then-
   success, permanent-absence exhaustion, and malformed-URL mismatch.

Verification: pnpm run format, the reconciliation test file, and
nx run-many -t identity-check release-policy-check lint test typecheck
build skills-validate package-audit --projects=foundry-ai all pass.
Manually confirmed release-policy-check fails when the
NPM_PUBLISH_ENABLED gate is removed, then passes again once restored.
Three follow-ups from the independent review of PR #42:

1. Removed the registry API fallback (`DELETE /-/npm/v1/tokens/token/{token}`)
   from the npm token revocation step. That endpoint is the classic-token
   API and likely doesn't manage granular access tokens, so it was
   decorative resilience rather than a real fallback. `npm token revoke`
   is now the sole automated revocation mechanism; on failure it hard-fails
   immediately with a manual-revocation error, backstopped as before by the
   pre/post retry liveness probes. Updated check-release-policy.mjs
   assertions to match (assert the hard-fail behavior, assert the classic
   endpoint string is absent).

2. docs/RELEASING.md: note that the bootstrap granular token must be able
   to manage/revoke itself, and that npm's stated plan to restrict
   bypass-2FA/sensitive-action permissions on granular tokens sometime in
   2026 may eventually break CLI self-revocation — in which case the
   workflow step hard-fails by design and the operator must revoke
   manually on npmjs.com immediately.

3. .github/workflows/ci.yml: dropped the `branches: [main]` filter from
   the `pull_request` trigger so stacked PRs (base != main, like this one
   and PR #43) actually get the full CI check suite. push stays
   main-only; workflow_dispatch unchanged. Confirmed release-policy-check
   is unaffected since it only parses release.yml.

Verification: pnpm run format, the reconciliation test file (6/6), and
nx run-many -t identity-check release-policy-check lint test typecheck
--projects=foundry-ai all pass.
@anandpant
anandpant force-pushed the chore/harden-bootstrap-release branch from 34be614 to 2e9eff3 Compare July 12, 2026 22:18
@anandpant
anandpant merged commit 8390129 into main Jul 12, 2026
5 checks passed
@anandpant
anandpant deleted the chore/harden-bootstrap-release branch July 12, 2026 22:19
anandpant added a commit that referenced this pull request Jul 12, 2026
…43)

## Summary
- Adds opt-in `traceParent`/`traceState` config fields (`FOUNDRY_TRACE_PARENT`/`FOUNDRY_TRACE_STATE` env vars) alongside the existing `attributionRid`, per Palantir's [LLM-provider compatible APIs docs](https://www.palantir.com/docs/foundry/aip/llm-provider-compatible-apis), which state in-platform observability requires these W3C trace-context headers.
- Forwards `traceParent`/`traceState` headers (exact casing per Palantir docs) from all three provider factories (OpenAI, Anthropic, Google) when configured; `headers` stays `undefined` when nothing is set, so request headers are byte-identical to today when the new vars are unset.
- Validates `traceParent` against the W3C `traceparent` format, reusing the config module's existing error style.
- Adds config/header unit tests (absent, valid, whitespace-only, invalid) mirroring the existing `attributionRid` coverage.
- Updates all docs surfaces that enumerate `FOUNDRY_ATTRIBUTION_RID` (root README, package README, usage docs, examples README, skill docs) to also cover the new vars, plus a note that third-party OAuth2 apps need the `api:use-language-models-execute` scope.

Stacked on #42, based on `chore/harden-bootstrap-release`.

## Test plan
- [x] `pnpm run format`
- [x] `pnpm exec nx run-many -t identity-check release-policy-check lint test typecheck build skills-validate package-audit --projects=foundry-ai --outputStyle=static --skip-nx-cache` — all targets pass (48 tests, build/typecheck/lint/identity-check/release-policy-check/skills-validate/package-audit all green)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant