From eaf50728573945d2713e92b0e72b24431d0e6d6e Mon Sep 17 00:00:00 2001 From: Raghu Betina Date: Tue, 22 Sep 2026 21:03:51 -0500 Subject: [PATCH 1/2] Record plugin 0.4.0 publication Keep package, catalog, and local smoke observations with their sources. --- evidence/2026-09-22-plugin-0.4.0-release.md | 26 +++++++++++++++++++++ evidence/README.md | 1 + 2 files changed, 27 insertions(+) create mode 100644 evidence/2026-09-22-plugin-0.4.0-release.md diff --git a/evidence/2026-09-22-plugin-0.4.0-release.md b/evidence/2026-09-22-plugin-0.4.0-release.md new file mode 100644 index 0000000..0a8ca31 --- /dev/null +++ b/evidence/2026-09-22-plugin-0.4.0-release.md @@ -0,0 +1,26 @@ +# Plugin 0.4.0 publication + +Observed September 22, 2026 in America/Chicago; provider timestamps fall on September 23 UTC. + +Protected tag `claude-v0.4.0` selected Skills `5f544bff149173a249899d2b5dfd403057cc5a30` and published +`@firstdraft.com/claude-code@0.4.0` directly to `latest` through +[GitHub trusted publishing](https://github.com/firstdraft/skills/actions/runs/35808094004). The package bundles CLI +`0.4.0` from `a555f8d39862109b8c28b392c0439470e88f4ba8`; the workflow matched all 27 CLI files to its published package. + +The registry plugin's SHA-256 is `7f796017074ecbfd5a5459f7686a615f53dbb3c95525ca2594601128e706748d`, matching the +selected compatibility declaration and locally packed candidate. Public installation and npm signature/attestation +verification passed. Both packages' `latest` tags selected `0.4.0`; their `next` tags remained `0.3.0`. + +Catalog `9c1774c7094f20d76248dfec86a09857be29256f` selected the published plugin after publication. Its +[selection-only CI](https://github.com/firstdraft/skills/actions/runs/35808399252) passed. This does not establish +refresh of an existing agent installation or a new authenticated agent session. + +The packed candidate's CLI compiled the existing reviewed Reading List Plan against deployed service `2bfdf6bf`. +Zero-flag Compilation wrote 360 files into the local folder and preserved the planning state under +`.firstdraft/design/`. Generated setup, Rails boot, a browser write, and a local source edit followed by refresh +passed. The analysis warning and two known gaps remained disclosed. The smoke used no Codespace, GitHub Publication, +native build, tunnel, or Revyl device. Its task-only service token was revoked and local processes were stopped. + +The coordinated [release report](https://github.com/firstdraft/firstdraft/blob/main/docs/solutions/2026-09-22-local-release.md) +owns the complete release receipt and post-publication Drawing Board follow-up. Earlier source and journey records +remain observations of their own revisions and package bytes. diff --git a/evidence/README.md b/evidence/README.md index d2d1963..53b35ce 100644 --- a/evidence/README.md +++ b/evidence/README.md @@ -35,6 +35,7 @@ The source/public split observed at the start of this documentation change is ca | Record | Observed boundary | |---|---| +| [`2026-09-22-plugin-0.4.0-release.md`](2026-09-22-plugin-0.4.0-release.md) | GitHub publication directly to latest, exact registry bytes and provenance, catalog selection, and one local compile-and-boot smoke | | [`2026-09-22-npm-promotion-retirement.md`](2026-09-22-npm-promotion-retirement.md) | Revoked the promotion token, removed its GitHub secret and environment, disabled the legacy workflow, and restored the CLI's restrictive publishing policy while preserving GitHub trusted publishing | | [`2026-09-15-shared-plugin-0.2.4-default-promotion.md`](2026-09-15-shared-plugin-0.2.4-default-promotion.md) | Protected-tag promotion, one plugin write with bounded stale-read reconciliation, and independent final tags/archive hashes; [machine receipt](2026-09-15-shared-plugin-0.2.4-default-promotion.json) | | [`2026-09-15-shared-plugin-0.2.4-publication.md`](2026-09-15-shared-plugin-0.2.4-publication.md) | Protected publication, delayed registry visibility, verified provenance, exact registry-package adapters, and observed staging readiness before catalog/default promotion; [machine receipt](2026-09-15-shared-plugin-0.2.4-publication.json) | From c9213052ba4c5841a8901f9da40d938b6acbd4dc Mon Sep 17 00:00:00 2001 From: Raghu Betina Date: Tue, 22 Sep 2026 21:11:11 -0500 Subject: [PATCH 2/2] Isolate release order from the live catalog The unpublished-candidate test mixed fake registry data with the live catalog. Give it a local fixture so a valid catalog release cannot break the test. Keep public release links accessible to all readers. --- evidence/2026-09-22-plugin-0.4.0-release.md | 6 +++--- test/plugin-release-order.test.mjs | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/evidence/2026-09-22-plugin-0.4.0-release.md b/evidence/2026-09-22-plugin-0.4.0-release.md index 0a8ca31..14e7b3e 100644 --- a/evidence/2026-09-22-plugin-0.4.0-release.md +++ b/evidence/2026-09-22-plugin-0.4.0-release.md @@ -21,6 +21,6 @@ Zero-flag Compilation wrote 360 files into the local folder and preserved the pl passed. The analysis warning and two known gaps remained disclosed. The smoke used no Codespace, GitHub Publication, native build, tunnel, or Revyl device. Its task-only service token was revoked and local processes were stopped. -The coordinated [release report](https://github.com/firstdraft/firstdraft/blob/main/docs/solutions/2026-09-22-local-release.md) -owns the complete release receipt and post-publication Drawing Board follow-up. Earlier source and journey records -remain observations of their own revisions and package bytes. +[Drawing Board PR #49](https://github.com/firstdraft/drawing-board/pull/49) merged the released tooling pins after +publication. Its container check and prebuild establish fallback availability, not a fresh Codespace journey. +Earlier source and journey records remain observations of their own revisions and package bytes. diff --git a/test/plugin-release-order.test.mjs b/test/plugin-release-order.test.mjs index 9174ce0..d39f512 100644 --- a/test/plugin-release-order.test.mjs +++ b/test/plugin-release-order.test.mjs @@ -1,6 +1,5 @@ import assert from "node:assert/strict"; import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; -import { fileURLToPath } from "node:url"; import { tmpdir } from "node:os"; import path from "node:path"; import test from "node:test"; @@ -149,11 +148,22 @@ test("prospective release order rejects incoherent current identities", () => { ); }); -test("unpublished candidate reconciliation reads npm, fetched tags, and the catalog", async () => { +test("unpublished candidate reconciliation reads npm, fetched tags, and the catalog", async (t) => { + const root = await mkdtemp(path.join(tmpdir(), "firstdraft-unpublished-candidate-")); + t.after(() => rm(root, { force: true, recursive: true })); + await mkdir(path.join(root, "release")); + await mkdir(path.join(root, ".claude-plugin")); + await writeFile(path.join(root, "release", "compatibility.json"), JSON.stringify({ + version: "0.4.0", + plugin_source: { package: "@firstdraft.com/claude-code" }, + })); + await writeFile(path.join(root, ".claude-plugin", "marketplace.json"), JSON.stringify({ + plugins: [{ version: "0.2.5", source: { package: "@firstdraft.com/claude-code" } }], + })); const invocations = []; const result = await checkPluginReleaseOrder({ requireCurrentTag: false, - root: fileURLToPath(new URL("../", import.meta.url)), + root, spawn(command, arguments_, options) { invocations.push([command, arguments_, options]); if (command === "git") {