Skip to content

feat(release): build the npm publishing path for all eight packages - #223

Merged
beyondnetPeru merged 2 commits into
developfrom
docs/gaps-component-assessment
Jul 27, 2026
Merged

feat(release): build the npm publishing path for all eight packages#223
beyondnetPeru merged 2 commits into
developfrom
docs/gaps-component-assessment

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

Pull Request Summary

Builds the npm publishing path that never existed. No version is bumped here — this ships the path; shipping 1.2.0 is a separate, deliberate act.

The problem. Seven of the eight public packages had no automated way to reach the registry. sdk-cli-release.yml publishes src/sdk/cli and nothing else; ci-cd.yml's publish-npm published the same directory again with --tag beta, no provenance, and the token written into a .npmrc via npm config set. Everything else — including @beyondnet/evolith-mcp, which carries the 2026-07-23 security wave — was published by hand from a developer machine. That is why all eight versions on the registry have no dist.attestations (GT-570).

.harness/scripts/release/plan-npm-release.mjs — the decision of what to publish, deliberately separated from the workflow so it is inspectable and testable without a registry, a token or a runner:

  • Dependency order over the internal @beyondnet/evolith-* edges, so a consumer never publishes before something it resolves from the registry.
  • Idempotent — a version already on the registry is skipped, so a partial failure resumes without republishing.
  • Never vacuous — resolving zero packages throws rather than emitting an empty plan.
  • Pure core, I/O at the edges. 11 unit tests, including a negative case for the empty set and one asserting a cycle throws instead of yielding a guessed order.

.github/workflows/npm-release.yml — all eight workspaces, dependency order, --provenance with id-token: write.

dry_run defaults to true, and that is the point. The audit's finding was that this path had never run end to end. A rehearsable mode is how that stops being true without betting a registry version on the first attempt. The dry run resolves, builds, packs and reports tarball contents — it just does not publish.

Other properties chosen on purpose: the token travels via NODE_AUTH_TOKEN, never npm config set; after publishing, the version is verified against the registry rather than trusted from an exit code; a failure stops before the failed package's consumers; the planner self-test runs on the runner before the planner is trusted; and mcp-server is rebuilt from a deleted tsbuildinfo, because nest build exits 0 while emitting nothing when that file is stale — an empty package is not something to discover after publishing.

Retires publish-npm from ci-cd.yml, with the reasoning left in place.

Already surfaced by running the planner against the live registry: @beyondnet/evolith-sdk is 2.0.0 in the tree and was never published. That is the monorepo fracture the audit described, now measured — cli and mcp-server pin ^1.1.0 and resolve the registry tarball.

Evolith Core Quality Gates

  • Bilingual Parity: no prose documents touched — one script, one test, two workflows.
  • Validation Scripts: 01-validate-docs.mjs green (via ci-runner governance).
  • Bilingual Validation: 04-check-bilingual-parity.mjs green (via ci-runner governance).
  • Agnosticism: no new dependency; the planner uses only node builtins.

Verification

Planner tests 11/11 · plan-npm-release.mjs run against the live registry · both workflows parse · 40-validate-path-literals 117 literals / 203 files exit 0 · ci-runner.mjs governance 17/17 exit 0.

Linked ADRs / Issues

  • Link to ADR: —
  • Link to Issue: GT-570 (unblocks), related GT-623

Conventional Commits

  • Title and commits follow Conventional Commits.

🤖 Generated with Claude Code

beyondnetPeru and others added 2 commits July 27, 2026 07:08
Seven of the eight public packages had no automated way to reach the registry.
`sdk-cli-release.yml` publishes `src/sdk/cli` and nothing else; `ci-cd.yml`'s
`publish-npm` published the same directory again, with `--tag beta`, no
provenance, and the token written into a .npmrc via `npm config set`. Everything
else — including @beyondnet/evolith-mcp, which carries the 2026-07-23 security
wave — was published by hand from a developer machine. That is why all eight
versions on the registry have no `dist.attestations` (GT-570).

Adds `.harness/scripts/release/plan-npm-release.mjs`: the decision of WHAT to
publish, deliberately separated from the workflow so it is inspectable and
testable without a registry, a token or a runner. Topological order over the
internal `@beyondnet/evolith-*` edges, so a consumer never publishes before
something it resolves from the registry. Idempotent — a version already on the
registry is skipped, so a partial failure resumes without republishing. Never
vacuous — resolving zero packages throws rather than emitting an empty plan.
Pure core, I/O at the edges. 11 unit tests including a negative case for the
empty set and one asserting a cycle throws instead of yielding a guessed order.

Adds `.github/workflows/npm-release.yml`: all eight workspaces, dependency
order, `--provenance` with `id-token: write`.

`dry_run` defaults to **true**, and that is the point. The audit's finding was
that this path had never run end to end; a rehearsable mode is how that stops
being true without betting a registry version on the first attempt. The dry run
resolves, builds, packs and reports tarball contents — it just does not publish.

Other properties chosen on purpose: the token travels via NODE_AUTH_TOKEN, never
`npm config set`; after publishing, the version is verified against the registry
rather than trusted from an exit code; a failure stops before the failed
package's consumers; the planner self-test runs on the runner before the planner
is trusted; and mcp-server is rebuilt from a deleted tsbuildinfo, because
`nest build` exits 0 while emitting nothing when that file is stale and an empty
package is not something to discover after publishing.

Retires `publish-npm` from ci-cd.yml, with the reasoning left in place.

Already surfaced by running the planner against the real registry:
@beyondnet/evolith-sdk is 2.0.0 in the tree and was never published — the
monorepo fracture the audit described, now measured. cli and mcp-server pin
^1.1.0 and resolve the registry tarball.

No version was bumped here. This commit builds the path; shipping 1.2.0 is a
separate, deliberate act.

Verified: planner tests 11/11, `plan-npm-release.mjs` against the live registry,
both workflows parse, 40-validate-path-literals 117 literals / 203 files exit 0,
ci-runner governance 17/17 exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru requested a review from a team as a code owner July 27, 2026 12:09
@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.

@github-actions

Copy link
Copy Markdown

📊 Bilingual Coverage Impact

PR Changes

  • Paired EN/ES files modified: 0
  • New EN files needing ES translation: 0

Repository Coverage

Metric Value
Total EN files 522
Total ES files 496
Paired files 0
Coverage 0%

Good: All EN changes have ES counterparts.


Generated by GitHub Actions

@beyondnetPeru
beyondnetPeru merged commit 5185c4d into develop Jul 27, 2026
29 of 31 checks passed
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