Skip to content

release: publish mem-mcp v0.1.1 and bootstrap npm Trusted Publishing #122

Closed

Description

@PeterGuy326

Release decision

Decision: DEC-MEM-122 (2026-08-31)

The founder authorizes a new immutable patch release, v0.1.1, and the first public npm publication of @fullstack-ai-infra/mem-mcp@0.1.1 after every gate below is satisfied. This supersedes only the deferred npm portion of #113; it does not change, move, rebuild, or republish v0.1.0.

User outcome

A user can install @fullstack-ai-infra/mem-mcp@0.1.1 from npm without approving a dependency lifecycle script. The first explicit mem-mcp invocation downloads the matching GitHub Release binary only after verifying its checksum; later invocations reverify and reuse a valid cache without redownloading the binary. Bootstrap diagnostics stay on stderr so MCP stdio stdout remains clean. Future npm releases use GitHub Trusted Publishing rather than a long-lived npm token.

Dependencies and sequence

  1. fix(ci): validate release action pins #118 must receive independent approval, pass required checks on its exact head, and squash-merge normally.
  2. fix(npm): verify release binary checksums #120 must close both checksum verification fix(npm): verify release binary checksum before install (v0.1.1 blocker) #119 and npm 12 lazy bootstrap fix(npm): run checksum-verified binary bootstrap without lifecycle scripts #123, then be current with the resulting main, receive independent approval, pass required checks on its exact final head, and squash-merge normally.
  3. governance: protect stable release tags before v0.1.1 #121 is complete: active refs/tags/v* protection permits creation and blocks update/deletion with no bypass.
  4. A dedicated release-preparation PR starts from the latest main, synchronizes all 0.1.1 version surfaces, and is independently approved and squash-merged normally.
  5. Create annotated v0.1.1 exactly once on the reachable release merge commit. The protected tag starts the repository Release workflow.
  6. Verify the GitHub Release and all six binaries plus mem-mcp-checksums.txt before npm publication. npm must be last because the first-run wrapper bootstrap fetches releases/download/v${package.version}.
  7. Bootstrap the nonexistent npm package using interactive account 2FA or a one-day, scope-only granular token. Publish once with --access public, read the public registry back, and perform a real clean-prefix install.
  8. After the package exists, configure its npm Trusted Publisher for GitHub org bytefolk, repository mem, exact workflow filename release.yml, no environment, action npm publish. Add the OIDC publish job through a separate independently reviewed PR; revoke the bootstrap token immediately after it is no longer needed. A later patch must exercise the OIDC path before token-based publishing is disabled.

Release-preparation acceptance criteria

  • Move the relevant CHANGELOG.md [Unreleased] entries into [0.1.1] - 2026-08-31, retaining an empty Unreleased section and correct comparison links.
  • Synchronize the single-version monorepo surfaces, including:
    • npm/package.json, npm/server.json
    • server/cmd/mem-mcp/main.go
    • worker/pyproject.toml, worker/uv.lock, worker/mem_worker/__init__.py, worker/README.md
    • web/package.json, web/package-lock.json
    • Helm Chart.yaml, image tags in values and the production example
    • current-facing deployment/release documentation
  • Update docs/maintainers/releasing.md so it no longer claims the existing GitHub Release workflow and npm channel do not exist; document bootstrap publication, GitHub-Release-before-npm ordering, checksum verification, Trusted Publisher migration, and rollback.
  • The exact release PR head passes every required repository check and the complete applicable local validation ledger.
  • npm test, syntax checks, and npm pack --dry-run --ignore-scripts pass from the exact candidate.
  • A clean npm 12 unpublished-package test installs without allowScripts, proves the first explicit wrapper invocation checksum-bootstraps with diagnostics only on stderr, proves valid-cache reuse, and proves fail-closed mismatch repair without mutating a Release or registry.

Publication acceptance criteria

  • The release merge commit is clean, reachable from origin/main, and all required checks passed on that exact commit.
  • v0.1.1 is a new annotated tag on that one commit and cannot be updated or deleted.
  • GitHub Release is non-draft/non-prerelease and contains exactly six expected platform binaries plus one checksum manifest; every checksum verifies.
  • The npm scope membership and publish authority are verified without exposing credentials.
  • npm publish --access public --tag latest succeeds once for 0.1.1; no attempt is made to publish 0.1.0.
  • Public npm view and registry metadata return name/version/dist integrity/repository correctly and latest=0.1.1.
  • A clean npm 12 consumer install runs no package lifecycle script; the first explicit mem-mcp --help downloads the matching v0.1.1 asset, verifies its checksum, keeps bootstrap output on stderr, and succeeds.
  • The release receipt records workflow URL, tag/commit identity, Release assets/checksums, npm metadata/integrity, clean-install evidence, and confirms v0.1.0 identities were unchanged.
  • Trusted Publisher settings and the follow-up OIDC workflow PR are linked here; any bootstrap granular token is revoked once safe.

Validation commands

  • Repository test matrix and PR-required checks.
  • gh release view/download v0.1.1 -R bytefolk/mem and sha256sum --check mem-mcp-checksums.txt.
  • npm view @fullstack-ai-infra/mem-mcp@0.1.1 ... --json --userconfig=/dev/null.
  • Clean temporary npm 12 prefix installation with an empty user config and no allowScripts, followed by mem-mcp --help with stdout/stderr captured separately.

Explicit non-goals and red lines

No runtime feature expansion, PyPI/MCP Registry/Smithery work, admin merge, self-review, force push, direct push to main, tag rewrite/deletion/recreation, republishing 0.1.0, long-lived npm token, token in source/log/chat, or claiming Trusted Publishing is verified before a real OIDC publication.

Activity

  1. added
    type:maintenanceMaintenance, tooling, refactoring, or repository work
    evidence:e3-reproducedMaintainer reproduced with deterministic steps
    status:readyScope and acceptance criteria are ready for development
    area:mcpModel Context Protocol integration
    area:infraCI, release, packaging, and repository infrastructure
    priority:p0Required for the next shared product proof
    on Aug 31, 2026
  2. PeterGuy326 commented on Aug 31, 2026

    @PeterGuy326
    CollaboratorAuthor

    Additive npm 12 gate (2026-08-31): #123 is now a P0 dependency of this release. npm 12 blocks dependency postinstall scripts by default; the current unpublished wrapper installs without its binary and then exits 1. PR #120 must therefore also close #123 by removing publication-time reliance on postinstall and performing the same checksum-verified bootstrap on the first explicit mem-mcp invocation, with all bootstrap diagnostics on stderr. v0.1.1 release preparation and publication must use #120's new exact final head, rerun CI, and include an npm 12 clean-tarball/first-run acceptance test.

  3. PeterGuy326 commented on Aug 31, 2026

    @PeterGuy326
    CollaboratorAuthor

    Pre-publication tag-authority hardening receipt (2026-08-31): a second active tag ruleset, ID 21899500 (Restrict stable release tag creation), now matches refs/tags/v* and applies only the creation rule. Its sole bypass is RepositoryRole admin (database ID 5, mode always), verified by REST and GraphQL readback. Therefore a write-level reviewer cannot create a release tag; an administrator can create the annotated release tag exactly once. Existing immutability ruleset 21888356 remains active and byte-for-byte unchanged: refs/tags/v*, update + deletion rules, bypass_actors=[], current_user_can_bypass=never. The two rulesets aggregate, so even administrators cannot update or delete the tag after creation. No test tag was created. This preserves #121 and DEC-MEM-122 semantics while safely allowing a third write-level CODEOWNER without granting release authority.

  4. PeterGuy326 commented on Aug 31, 2026

    @PeterGuy326
    CollaboratorAuthor

    Pre-tag execution receipt — v0.1.1

    The release candidate has cleared the final pre-tag gate.

    • Release PR: chore(release): prepare v0.1.1 candidate #130, exact reviewed head cd05ec93302d2e60a8bf2820c560cd12f1028443.
    • Independent CODEOWNER approval: Bindy-lbb review 5063620382 on that exact head.
    • Normal squash merge, no admin bypass: cc727db0bc72655f299166de1f60756f5c686cc7; current refs/heads/main resolves to the same SHA.
    • Exact-main push verification:
      • CI run 33363876200: 9/9 jobs SUCCESS.
      • Validate Agent memory run 33363876177: 5/5 jobs SUCCESS.
      • Dependency graph run 33363879142: 1/1 job SUCCESS.
      • Total 3/3 suites and 15/15 check runs completed successfully; no failure, cancellation, skip, neutral, or pending result. The PR-only title/link policy passed on chore(release): prepare v0.1.1 candidate #130 and does not emit on push.
    • scripts/validate_release_version.sh 0.1.1: PASS from a clean detached checkout of the merge commit.
    • Stable-tag enforcement read back immediately before creation:
      • ruleset 21888356 is active on refs/tags/v*, prohibits update and deletion, and has no bypass actor;
      • ruleset 21899500 is active on refs/tags/v*, restricts creation, and permits the current repository admin role to create once.
    • Version-absence gate: remote refs/tags/v0.1.1 is absent; GitHub Release v0.1.1 is absent; npm @fullstack-ai-infra/mem-mcp@0.1.1 is absent.
    • Clean npm candidate inventory: 6 expected files only; dry-pack integrity sha512-BcHfdCgEuG58+QZMyaDz+mz6TtH9t8nMppmTHOq1JQCxxzoQRPu1ph3eAMHfkkI1ufD9JXHQ1LMaei0VaTfUrA==.

    The next action is the first and only creation of annotated tag v0.1.1 on cc727db0bc72655f299166de1f60756f5c686cc7. The tag will not be moved, deleted, or recreated. GitHub Release and npm publication remain blocked until their respective read-back gates pass.

  5. waterbro-8 commented on Sep 1, 2026

    @waterbro-8
    Collaborator

    Ledger reconciliation against observable state (2026-09-01)

    The checkboxes on this issue no longer describe reality in either direction, so recording what can be checked externally:

    Step 7 — done. @fullstack-ai-infra/mem-mcp@0.1.1 is published: latest = 0.1.1, created 2026-08-31T16:53Z. Note the package name is @fullstack-ai-infra/mem-mcp (from npm/package.json), which is worth stating because searching for mem-mcp or a @bytefolk/... scope returns E404 and reads as "never published".

    Step 8 — not started, and it is the larger half. Trusted Publishing cannot currently work from this repository's pipeline at all; confirmed in-repo at the current main:

    • no job in .github/workflows/release.yml runs npm publish — the workflow's only publish step is "Publish verified Release" (the GitHub Release itself), and its top-level permissions: is just contents: read;
    • no workflow anywhere requests id-token: write, which OIDC-backed publishing requires.

    So "the OIDC publish job arrives through a separate independently reviewed PR" is still an open implementation task, not a pending setting change. Someone has to write the job and the npm-side Trusted Publisher has to be pointed at org fullstack-ai-infra / repo mem / release.yml / no environment / action npm publish.

    Acceptance list is stale in the other direction too. [Unreleased] → [0.1.1] - 2026-08-31 and the version-surface sync are checked [ ], but CHANGELOG.md on main already shows ## [0.1.1] - 2026-08-31 with an empty ## [Unreleased] above it, and npm/package.json already reads 0.1.1. Those read as done-but-unticked, which will make the next person redo work that landed.

    One acceptance test I could not run here, stated as a gap rather than a pass. "Perform a real clean-prefix install" against registry.npmjs.org is not executable from this machine: outbound access to the npm registry only works through a local proxy that is currently down, and a direct install produced no node_modules. The mirror registry has synced the package metadata but its tarball URL returns 404, so even the mirror cannot serve the artifact from here. The User-outcome sentence — install without approving a dependency lifecycle script, then verify-checksum-then-download on first mem-mcp invocation, with diagnostics confined to stderr — therefore remains unverified by me, and needs one run from a network that can reach npm.

  6. sun-970 commented on Sep 1, 2026

    @sun-970
    Contributor

    Step 8 implementation: PR #146 adds the npm-publish job to the release workflow using Trusted Publishing (OIDC).

    Changes:

    • id-token: write permission for OIDC token exchange
    • New npm-publish job that runs after GitHub Release verification
    • Version validation, npm test suite, and publication verification
    • Documentation update with Trusted Publisher setup instructions

    npm-side setup still required: Configure Trusted Publisher on npmjs.com for org fullstack-ai-infra, repo mem, workflow release.yml, no environment, action npm publish.

  7. PeterGuy326 commented on Sep 1, 2026

    @PeterGuy326
    CollaboratorAuthor

    Trusted Publishing route reconciliation (2026-09-01T16:54Z)

    Published state is stable: the public GitHub Release is v0.1.1, and npm @fullstack-ai-infra/mem-mcp has latest=0.1.1. Source/package state is not proof that OIDC is complete.

    PR #146 is now CLOSED under bytefolk/.github#24 AC-004 because its exact head cannot satisfy the repository release gates. The closure trace is #146 (comment) .

    PR #152 is the clean replacement candidate, not an accepted or executable route. Before it can be review-ready it must resolve at least:

    No npm login, token, membership, Trusted Publisher setting, publish, dist-tag, deprecation, or other registry write was performed. bytefolk/.github#22 remains the controlling HOLD for any npm-side action.

  8. waterbro-8 commented on Sep 3, 2026

    @waterbro-8
    Collaborator

    The clean-install AC is executable from this machine after all — ran it. 3 sub-claims pass, 1 is still environment-blocked (2026-09-03)

    Retracting my own 2026-09-01 disclosure first: outbound to registry.npmjs.org now works without the (down) local proxy, so "perform a real clean-prefix install" is testable here. Evidence against the published artifact — fresh prefix, fresh cache, fresh $HOME, --userconfig=/dev/null, npm 12, no --allow-scripts anywhere:

    • PASS — install runs no lifecycle script. npm install @fullstack-ai-infra/mem-mcp@0.1.1 → rc=0, added 1 package, and audited 2 packages, found 0 vulnerabilities. No lifecycle script executed and none had to be approved. node_modules/.bin/mem-mcp is present.
    • PASS — stdout stays clean. The first explicit invocation, mem-mcp --help, produced 0 bytes on stdout and 320 bytes on stderr, all of it bootstrap diagnostics. So the User-outcome clause "bootstrap diagnostics stay on stderr so MCP stdio stdout remains clean" holds on the published 0.1.1, not only in unit tests.
    • PASS — the failure path is fail-closed (observed, not asserted). The download hit its 60 s timeout → rc=1, failed to download and verify the platform binary, then retry the command, or build manually …. No partial binary, no poisoned cache, no stdout leakage.
    • STILL UNVERIFIED HERE — the asset fetch itself, i.e. checksum verification against mem-mcp-checksums.txt, valid-cache reuse, and fail-closed mismatch repair. github.com:443 is filtered on this network while codeload.github.com:443 and api.github.com:443 both connect, so it is domain-specific rather than a general outage. One run from any network that reaches github.com closes this line.

    Incidental, so nobody files a wrong bug off that error text: the URL is https://github.com/fullstack-ai-infra/mem/releases/download/v0.1.1/.... That old org coordinate is not a source defect — main:npm/install.js:34 already reads bytefolk/mem; the string is baked into the immutable artifact published 2026-08-31. It survives on the org-rename redirect and disappears at the next publish.

    What is done and readable. v0.1.1 is a non-draft, non-prerelease Release carrying exactly six platform binaries plus mem-mcp-checksums.txt; the tag exists; npm @fullstack-ai-infra/mem-mcp reports latest=0.1.1, created 2026-08-31T16:53Z. Steps 1–6 are satisfied by observable state, as are step 7's publish and public registry read-back — but not step 7's "real clean-prefix install" line in full (see the four bullets above), and not step 8 at all.

    Why this issue is nonetheless not finished: the Trusted Publishing half has never actually published. npm-publish.yml is on main (merged via #152 at 2026-09-02T16:44Z) with the right shape — permissions: contents: read + id-token: write, no NPM_TOKEN, checkout pinned by SHA, gated on the GitHub Release existing — but the newest tag is still v0.1.1 (2026-08-31) and the public registry still reports exactly one version. So the OIDC path has run zero times. Per this issue's own red line, Trusted Publishing cannot be claimed verified before a real OIDC publication, and the npm-side Trusted Publisher remains gated by bytefolk/.github#22. Token revocation is likewise not something I can read from outside; I'm not claiming it either way.

    Bookkeeping, stale in both directions. All 15 acceptance checkboxes are unticked, and at least two describe work that already landed: CHANGELOG.md has the entries genuinely moved into ## [0.1.1] - 2026-08-31 (line 34), and npm/package.json already reads 0.1.1. One caution against a mechanical re-read: ## [Unreleased] (line 8) is not empty today — it carries three later items (the bytefolk coordinate migration and two Security entries). That is normal accumulation after the release cut, not a missed step, so the AC's "retaining an empty Unreleased section" should be understood as satisfied-at-cut-time rather than re-checked against the current file. Worth the owner reconciling the list against reality — unticked-but-done reads as "redo this", and ticking everything would imply the OIDC step happened.

    Not an acceptance, not a review vote, no approval or state change implied.

  9. waterbro-8 commented on Sep 3, 2026

    @waterbro-8
    Collaborator

    v0.1.2 under Trusted Publishing: what is measured, what is founder-only, and what the release commit has to touch

    Read out of main@1332bf46 today, alongside the 2026-09-03 instruction to release v0.1.2 with the .github#22 HOLD cleared first and the npm package name staying @fullstack-ai-infra.

    1. The npm blocker is now confirmed by an executed run, not by inference

    npm-publish.yml was dispatched on 2026-09-02T16:46Z (run 33657001768, version=v0.1.0 -- a rehearsal against the already-published tag, so it wrote nothing new). It got as far as composing the tarball and then:

    npm error code ENEEDAUTH
    npm error need auth This command requires you to be logged in to https://registry.npmjs.org/
    npm error need auth You need to authorize this machine using `npm adduser`
    

    That is the expected shape of "OIDC token presented, no Trusted Publisher on the package to exchange it for a token". The workflow asks for id-token: write at .github/workflows/npm-publish.yml:20 and publishes at :71 with npm publish --provenance --access public, deliberately carrying no NPM_TOKEN (:68-69). Nothing in this repository can close that gap; the record has to be created on the npm side, which is the founder-only step.

    2. Three facts for whoever creates the record, read off the workflow as it stands

    • The file name is exactly npm-publish.yml, so the publisher's "Workflow file" field matches the instruction as given.
    • The job declares no environment: anywhere in the file. npm matches the environment too, so the record must be created with the environment field left empty. This matters because [Release] Migrate mem-mcp to @bytefolk/mem-mcp v0.1.2 #153's plan calls for a workflow with an npm-release environment: if that change lands first and the publisher was created without an environment (or vice versa), the exchange fails with the same ENEEDAUTH as above and looks like a credentials problem.
    • The GitHub coordinates are owner bytefolk, repository mem, package @fullstack-ai-infra/mem-mcp. The npm scope and the GitHub org are allowed to differ here -- the scope is an npm namespace, not a claim about who owns the repo, which is the same distinction fix(npm): follow the registry identifier to the bytefolk namespace #162 encodes for the registry identifier.

    One documentation defect while this is open: .github/workflows/npm-publish.yml:70 still says the publisher is configured for org=fullstack-ai-infra. It is only a comment, but it is the first thing the person creating the record will read, and it is now wrong. Deliberately not folded into #162, whose diff is the registry identifier only.

    3. What the release-preparation PR has to synchronize, measured

    scripts/validate_release_version.sh 0.1.2 fails against current main (rc=1, first line ERROR: npm/package.json: expected 1 occurrence(s) of: "version": "0.1.2",), and passes for 0.1.1, so the gate itself is live rather than decorative. The surfaces it pins, all of which must move in one commit:

    surface checked form
    npm/package.json, npm/server.json exact "version": "X", line
    server/cmd/mem-mcp/main.go exact line including its trailing // synced with npm/@fullstack-ai-infra/mem-mcp version comment
    worker/pyproject.toml, worker/mem_worker/__init__.py, worker/README.md version line, __version__, and the expected-output snippet
    worker/uv.lock mem-worker occurring exactly once at that version
    web/package.json, web/package-lock.json top-level version plus the lock's line 3 and line 9
    deploy/helm/mem/Chart.yaml version: and appVersion:
    deploy/helm/mem/values.yaml, values-production.example.yaml exactly three tag: lines each, all at that version
    docs/DEPLOYMENT.md export MEM_VERSION=X
    CHANGELOG.md ## [X] - YYYY-MM-DD must be the first versioned section, exactly once, with one [X]: comparison link terminating at vX, and an [Unreleased]: .../compare/vX...HEAD link

    4. Sequence I would hold to, and where it currently waits

    1. build(deps-dev): bump browserslist from 4.28.2 to 4.28.8 in /web #159 into main. Web → Audit dependencies is red on main@1332bf46 itself (browserslist <=4.28.6, GHSA-73wf-gq98-2v4g), so every PR in the queue inherits one failing required check. Details and readback are on chore(codeowners): add third independent reviewer #138; build(deps-dev): bump browserslist from 4.28.2 to 4.28.8 in /web #159 needs a code-owner approval, which is the same two people this org has.
    2. Founder: npm Trusted Publisher record per section 2, and the .github#22 HOLD (npm whoami, org role, 2FA, package-name control from the authorized machine) -- those are the registry-write preconditions build(server): remediate Go dependency security alerts #22 lists and no local work substitutes for them.
    3. Content decision for 0.1.2. Nothing should be in the release that has not been accepted; the candidates currently green-but-unmerged are fix(web): make the proxy the single authority for the shared security headers #161 (proxy security headers, fix(web): nginx drops security headers on /assets/ and duplicates Referrer-Policy on proxied API responses #135/hardening(web): reconcile nginx and API security-header ownership #136) and fix(npm): follow the registry identifier to the bytefolk namespace #162 (registry identifier, half of [Release] Migrate mem-mcp to @bytefolk/mem-mcp v0.1.2 #153). If neither is merged before the tag, v0.1.2 is a version bump over the same code as v0.1.1 plus whatever else lands, and that is worth saying out loud rather than discovering at the tag.
    4. Release-prep PR from a green main, per release: publish mem-mcp v0.1.1 and bootstrap npm Trusted Publishing #122's own step 4, then the annotated tag exactly once on the reachable merge commit.
    5. GitHub Release readback before npm, as step 6 of this issue requires -- npm/install.js:615 builds releases/download/v<version> and asks for assets by name at first run (mem-mcp-checksums.txt is npm/install.js:35), so the binaries and mem-mcp-checksums.txt must exist and be named what the installer asks for before npm goes out.
    6. npm publish last, then the clean-prefix install and the OIDC/provenance readback this issue exists to measure.

    5. What I did not do

    No tag, no release, no workflow_dispatch, no version-sync PR opened from a red main, no npm-side action, and no status or label change on this issue. Step 1 above is the only thing on the repository side standing between today and a release, and it needs an approval from @PeterGuy326 or @Bindy-lbb rather than more work from me.

  10. waterbro-8 commented on Sep 3, 2026

    @waterbro-8
    Collaborator

    对我在本条 issue 上给的"依据"做一次更正 + 升级。 仍是自动化验证回读,不是验收、不投票、不合并、不发版。

    1. 更正一处:那条 ENEEDAUTH 不能证明"缺 Trusted Publisher 记录"

    我之前的写法是"09-02 的演练失败在 ENEEDAUTH ⇒ 所以 npm 侧缺记录"。这个推理跳步了,而且我把一次中间读取判错过一次,这里给出完整准确的形状:

    • run 33657001768,由 @PeterGuy326 触发(event=workflow_dispatch,actor=PeterGuy326),workflow 文件取自 main(head_sha 1332bf46),input version=v0.1.0;
    • step 2 Resolve release tag、step 3 Check out exact tag commit(→ d2dd534,v0.1.0 的 commit)、step 4 Require the GitHub Release (G1) to exist全部 success;
    • step 6 npm publish --provenance --access public 从 16:46:52.564 到报错只花 0.6 秒,输出是 npm error code ENEEDAUTH / need auth This command requires you to be logged in to https://registry.npmjs.org/,没有任何来自 registry 的响应体。

    我一度怀疑是仓库/org 级把 id-token 权限压掉了(runner 的 GITHUB_TOKEN Permissions 横幅只打了 Contents: read / Metadata: read)。这个假设已经被下面的正向证据排除,不要按它去查设置。

    2. 升级:同一 org 里已有一次成功的 OIDC Trusted Publishing

    @fullstack-ai-infra/digital-employee@0.6.0 的注册表公开元数据:

    dist: { …, attestations: { url: "…/attestations/@fullstack-ai-infra%2fdigital-employee@0.6.0",
                               provenance: { predicateType: "https://slsa.dev/provenance/v1" } } }
    _npmUser: { name: "GitHub Actions", email: "npm-oidc-no-reply@github.com",
                trustedPublisher: { id: "github", oidcConfigId: "oidc:b5e38816-d6ef-4103-8eae-1ce7e8682a24" } }
    time["0.6.0"] = 2026-08-28T17:26:27.245Z
    

    对应该次发布的 job 是 digital-employee run 33193084146 / job 98928568129(npm-root),它的 GITHUB_TOKEN Permissions 横幅同样只有 Contents: read / Metadata: read —— 也就是说那张横幅本来就不列 id-token,拿它判断"id-token 没发下来"是错的读法。结论:

    • org 层面 OIDC → npm 这条路是通的,release.yml 里 id-token: write 的写法(:297-299、:377-379)是有成功先例的形状;
    • 因此 mem 这边缺 npm 记录仍然是最可能的解释,只是现在支撑它的是同 org 的成功样本,不是一条错误码。

    3. 一条新的、直接改变计划的事实:mem 在 npm 上那个包从来不是 CI 发的

    @fullstack-ai-infra/mem-mcp  time["0.1.1"] = 2026-08-31T16:53:10.064Z
                                 _npmUser.name = "huyizhou326"     ← 个人 npm 账号
                                 dist 里 attestations = 不存在
    GitHub Release v0.1.1 published_at = 2026-08-31T06:34:08Z      ← 早约 10 小时
    

    (邮箱字段注册表公开可查,这里不复述。)

    含义两条:(a) npm-publish.yml 这条 OIDC 路至今零次成功,v0.1.1 是手工 npm publish 上去的,所以它没有 provenance;(b) 也就是说"今天就能把 0.1.2 发出去"存在一条已在使用的手工退路——但那条退路正是 .github#22 HOLD 要结束的东西,用它发出来的包仍然没有 attestation。这两个选择要在打 tag 之前说明白,不要事后被当成"OIDC 已经生效"。

    4. 陷阱:那条"无害的演练"补上凭据后会真的发出去一个版本

    @fullstack-ai-infra/mem-mcp  versions = ["0.1.1"]     ← 没有 0.1.0
                                 dist-tags = { latest: "0.1.1" }
                                 time["0.1.0"] 不存在
    GitHub 侧 v0.1.0 tag 和 Release 都存在(step 4 的 G1 门因此 PASS)
    

    09-02 那次 workflow_dispatch 传 version=v0.1.0 之所以"什么都没写",只是因为凭据在 0.6 秒时失败,不是因为 0.1.0 已经存在。所以一旦 Trusted Publisher 记录建好,同一行演练命令会把 npm 上从未有过的 0.1.0 真发出去——它对应 d2dd534(#117 那个提交)构建的二进制集,不是今天的代码,而 registry 上的版本号一旦占用就很难收回(npm 对 unpublish 和同版本重发有硬性时间限制——这条是政策记忆,不是本次实测)。

    要复现"认证是否打通"这个目的,请把 dispatch 的 version 指到一个registry 上已存在的版本(如 v0.1.1):那样最坏结果是 E409/版本冲突,而不是往公开记录里塞一个过期版本。

    5. 建记录时会撞到的两个具体点

    1. GitHub 侧 environment 已经存在两个:npm-publish(created 2026-08-31T09:46:16Z)和 npm-release(created 2026-09-01T17:31:13Z)。而 npm-publish.yml 的 job 两个都没声明(全文只有 permissions/concurrency/jobs,无 environment: 键)。npm 的 Trusted Publisher 记录里 environment 字段要和 job 的实际状态一致:要么记录留空 + 文件保持无 environment,要么同一次改动里给 job 加 environment: 并把它写进记录。分开做就会出现"记录建了、发布仍然 ENEEDAUTH"。
    2. de 那条已有记录可能是改名前建的。上面那次成功发布的日志里 GH_REPO: fullstack-ai-infra/digital-employee,而 org 是 09-02 才改成 bytefolk 的。npm 匹配的是 OIDC token 里的 GitHub org 名。我没有 npm 侧读权限,这条没验证——请建记录的人顺手在同一个页面确认 de 那条记录改没改,否则 mem 建好了、de 下一次发版反而挂。

    6. 我读不到 / 没做的

    • 读不到:GET /repos/bytefolk/mem/actions/permissions/workflow、/orgs/bytefolk/actions/permissions/workflow、…/actions/secrets 全部 403(需要 admin 或对应的 fine-grained policies 权限);npm 侧任何记录与角色都没有凭据可读。
    • 没做:没有自己 dispatch 过 npm-publish.yml(第 1 节那次是 @PeterGuy326 09-02 跑的)、没建 environment、没建/改 secret、没改任何设置、没碰 npm-publish.yml、没打 tag、没发 release、没改任何人的评论。
    • 可做但没做:在某个分支上加一次不碰 npm publish 的 OIDC 探测(只打印 ACTIONS_ID_TOKEN_REQUEST_TOKEN 存在与否,不打印 token),用来单独确认 mem 自己的仓级设置也能签发 token。要就说,我推分支 + dispatch,一次跑完给回读。
  11. PeterGuy326 commented on Sep 10, 2026

    @PeterGuy326
    CollaboratorAuthor

    Release decision recorded: #153 (comment)

    The target is now @bytefolk/mem-mcp@0.1.2; the 2026-09-03 keep-old-scope instruction is superseded. Old @fullstack-ai-infra/mem-mcp@0.1.1 remains the rollback/install path and will not be unpublished. Source/release preparation proceeds under #153; npm authentication currently returns ENEEDAUTH, so ownership, bootstrap, OIDC, clean-install and promotion gates remain open.

  12. PeterGuy326 commented on Sep 10, 2026

    @PeterGuy326
    CollaboratorAuthor

    Closing as completed / superseded by #153. Re-verified against the live registry, tag and release objects today rather than against the delivery notes.

    What actually shipped

    Step Evidence Verdict
    Tag on the intended commit refs/tags/v0.1.1 → annotated tag object c2ecc1c49ff8bbe13b9d7800bc910e4b7ac99b74, message Release v0.1.1, dereferencing to commit cc727db0bc72655f299166de1f60756f5c686cc7 — the exact commit #130 named done
    Release with per-platform binaries Release v0.1.1, published 2026-08-31T06:34:08Z, assets: mem-mcp-darwin-amd64, mem-mcp-darwin-arm64, mem-mcp-linux-amd64, mem-mcp-linux-arm64, mem-mcp-windows-amd64.exe, mem-mcp-windows-arm64.exe — six binaries done
    Checksums mem-mcp-checksums.txt present as a seventh release asset done
    npm publication registry.npmjs.org/@fullstack-ai-infra/mem-mcp → dist-tags.latest = 0.1.1 done
    npm Trusted Publishing (OIDC) versions["0.1.1"].dist.attestations is absent; the publish was performed by a personal npm account, not an OIDC-federated one not done

    So the release half of this issue is delivered and the bootstrap half is not. That is precisely the split #153 was filed for, and my comment here on 2026-09-10 already redirected the remaining work there. Keeping this open as well would mean two live issues tracking one outstanding step, with this one carrying priority:p0 and status:ready labels that no longer describe actionable work — the actionable work is #153's.

    Why this is "superseded" and not "fully completed"

    I am not closing this as though every acceptance criterion passed. The OIDC step never succeeded, and attestations: false on the published tarball is the durable proof of that. Anyone auditing supply-chain provenance for @fullstack-ai-infra/mem-mcp@0.1.1 should know there is no npm attestation linking it to a GitHub Actions run — the provenance story for 0.1.1 is the release checksums file plus the tag, not Sigstore.

    Note on the labels

    This issue currently carries type:maintenance, evidence:e3-reproduced, status:ready, area:mcp, area:infra, priority:p0. area:distribution is not a valid area under docs/maintainers/triage.md (the taxonomy is server/worker/web/cli/mcp/docs/infra), and whoever triaged this already used area:mcp + area:infra instead, which is the correct mapping — no change needed. The e3-reproduced level is consistent with the table above: each row is a live query against a tag object, a release object or the public npm registry, not a restatement of the plan.

    Follow-up lives in #153. Nothing else is outstanding here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:infraCI, release, packaging, and repository infrastructurearea:mcpModel Context Protocol integrationevidence:e3-reproducedMaintainer reproduced with deterministic stepspriority:p0Required for the next shared product proofstatus:readyScope and acceptance criteria are ready for developmenttype:maintenanceMaintenance, tooling, refactoring, or repository work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions