Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/registry-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Asks npm what it actually holds, and opens an issue when it disagrees with this tree.
#
# NOT a step of `x verify`, and it must never become one. The gate is the shippability contract and
# runs on free runners; a step that resolves the network makes green depend on something the runner
# does not control. More to the point, a gate step could not do this job anyway: the three states
# this catches all appear BETWEEN commits, not at one.
#
# The state it exists for: a package added after a release run is unpublished until a human
# bootstraps it, and nothing says so until the next release reaches it and aborts with everything
# ahead of it already published irreversibly. `@ultimat3/flags` sat that way until 2.0.0 and
# `@ultimat3/scraping` until 2026-08-19, each while the docs described the other.

name: registry-audit

on:
schedule:
# Daily, well away from the hour a release is likely to be cut by hand.
- cron: '17 6 * * *'
workflow_dispatch:

# Read-only: it resolves npm and may open an issue. It never publishes, and it holds no
# `id-token`, so it cannot be a path to the registry even if it is compromised.
permissions:
contents: read
issues: write

concurrency:
group: registry-audit
cancel-in-progress: true

jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup

- name: audit the registry
id: audit
# `pipefail` is load-bearing: without it `tee` decides the step's exit status, the audit's
# non-zero is discarded, `outcome` is always `success`, and every step below that keys on
# `failure` never runs — a workflow that reports clean whatever npm says.
shell: bash
run: |
set -o pipefail
bun run scripts/registry-audit.ts --json | tee audit.json
continue-on-error: true
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: open an issue when the registry disagrees
if: steps.audit.outcome == 'failure'
env:
GH_TOKEN: ${{ github.token }}
# One open issue at a time: a daily job that files a duplicate every morning trains everyone
# to ignore it, which is the failure mode this audit exists to correct.
run: |
existing="$(gh issue list --label registry-drift --state open --limit 1 --json number --jq '.[0].number // empty')"
summary="$(jq -r '.summary' audit.json)"
body="$(jq -r '"**" + .summary + "**\n\n" + ([.findings[] | "- `" + .code + "` " + (.at // "") + " — " + .cause + "\n - fix: `" + .fix + "`"] | join("\n"))' audit.json)"
if [ -n "$existing" ]; then
gh issue comment "$existing" --body "$body"
else
gh issue create --label registry-drift --title "registry: $summary" --body "$body"
fi

- name: fail the run so the badge is honest
if: steps.audit.outcome == 'failure'
run: exit 1
18 changes: 11 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ name: release
#
# Two things must be TRUE outside this file for the gate below to be a gate, and both are named in
# PUBLISHING.md as human steps: the `npm-publish` environment needs required reviewers configured in
# Settings → Environments, and `@ultimat3/flags` needs its first manual publish (the derived list
# below now includes it, and trusted publishing cannot bootstrap a package that does not exist yet).
# Settings → Environments, and every package in the derived list needs a trusted publisher plus its
# first manual publish. Trusted publishing cannot bootstrap a package that does not exist yet, so a
# package added AFTER a release run is unpublished until a human bootstraps it — and this run will
# reach it and abort with everything ahead of it already published irreversibly.
# `bun run scripts/registry-audit.ts` answers whether that is owed, before a release finds out.

on:
release:
Expand Down Expand Up @@ -139,11 +142,12 @@ jobs:
# imports it — and the list is DERIVED, never kept by hand.
#
# It used to be seven hand-written steps of `-w` flags, and `@ultimat3/flags` was on none of
# them. That is why the registry answers 404 for it while the other 28 are published: flags
# declares the same `publishConfig` as its siblings, every consumer resolves it through the
# workspace, and so nothing in this repo could notice. The missing entry was the symptom; a
# list that has to match a derived one is the defect, and adding one line would have fixed
# today and re-broken on the next package somebody adds.
# them, so the registry answered 404 for it while its siblings published: flags declares the
# same `publishConfig`, every consumer resolves it through the workspace, and nothing in this
# repo could notice. The missing entry was the symptom; a list that has to match a derived one
# is the defect, and adding one line would have fixed that day and re-broken on the next
# package somebody added — which is exactly what happened to `@ultimat3/scraping`, added after
# the 2.0.0 run and 404 until it was bootstrapped by hand on 2026-08-19.
#
# `scripts/list-workspaces.ts` reads the real package.json files rather than the tier table,
# so a package that exists on disk cannot be invisible here — and `create-ultimate` lands last
Expand Down
11 changes: 0 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,6 @@

</div>

> **Status: 3.0.0 — repository, `v3.0.0` tag and npm all agree**, `As of 2026-08-19`. 29 `@ultimat3/*` packages plus the unscoped `create-ultimate` — 30 in all — are **versioned** in lockstep at 3.0.0 (one version, one commit, one tag) and **published** at 3.0.0, every one by [`release.yml`](.github/workflows/release.yml) over OIDC with a provenance attestation. `bunx create-ultimate myapp` gives you 3.0.0. **3.0.0 is a major**: [CHANGELOG.md](CHANGELOG.md)'s 3.0.0 section carries 10 entries marked `BREAKING —` from a five-agent bug sweep, and no codemod ships with them, so each is a manual edit its entry names ([Upgrading](https://github.com/developerz-ai/ultimate/wiki/Upgrading)). 2.0.0 was the first major and carried 33. Semver applies — a breaking change to a documented API needs a major. That is what the version number means: a stable API under semver, not a promise about your infrastructure.

| Fact | Check it, never this table |
|---|---|
| what npm serves | `npm view @ultimat3/core version` |
| the tarball is attested, and by whom | `npm view @ultimat3/core@3.0.0 dist.attestations _npmUser` |
| the 30 names that move together | `bun run scripts/release-workflow.ts --json` |
| the repository is stamped at one version | `bun run scripts/release.ts --check 3.0.0` |

Release history worth knowing: 1.0.0 was the manual bootstrap; 1.1.0 was the first release the workflow published over OIDC; **2.0.0 was hand-published** — no trusted publisher was attached for the OIDC exchange to verify against — so it is the one release whose tarballs carry no attestation; 3.0.0 is the first the workflow has published since 1.2.0. **No publication holes**: `@ultimat3/scraping` was the last one and it is closed, bootstrapped by hand at 2.0.0 (`npm publish --access public --provenance=false`), the one-time step every package needs before a trusted publisher can attach ([PUBLISHING.md](PUBLISHING.md)).

## Built by agents, for agents, maintained by agents

Nobody writes this code by hand anymore, and the framework is designed for that rather than
Expand Down
Loading