Skip to content

feat: harden native plugin publishing lifecycle - #11

Merged
myagentdojo merged 44 commits into
mainfrom
codex/fix-release-bootstrap
Aug 6, 2026
Merged

myagentdojo merged 44 commits into
mainfrom
codex/fix-release-bootstrap

Conversation

@myagentdojo

@myagentdojo myagentdojo commented Aug 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

This PR turns the template's initial release path into a reviewed, fail-closed publishing lifecycle. Recipient plugins start at a clean v0.1.0, while later releases keep every version surface synchronized.

The same candidate commit now flows through deterministic packaging, native installation proof, an immutable tag, GitHub Release publication, and bounded same-tag repair. Repository safeguards and publishing-system canaries expose missing configuration instead of assuming the repository is ready.

Design decisions

  • Derive one deterministic, regular-file-only payload inventory for packaging and proof. Reject symlinks, special files, and path escapes.
  • Separate native metadata validation from the stricter directory-readiness text profile. Passing local validation makes no public-directory publication claim.
  • Keep Release Please responsible for the reviewed version PR. Bind the release workflow to the exact merged candidate SHA before proof, tagging, or asset repair.
  • Require releasable PR titles when installable payload bytes change. Restrict the Release Please exemption to trusted automation identity and branch evidence.
  • Prove Claude and Codex install, cache, update, rollback, enabled-state, and trust boundaries in isolated homes.
  • Require public and private hosted Git canaries only when publishing machinery changes. Treat deleted publishing files as triggers.
  • Verify tag rules, branch settings, required checks, Actions permissions, and workflow privilege through a read-only readiness command.

Session-settled decisions carried from planning: use reviewed Release Please maintenance, immutable candidate refs, conditional hosted canaries, native harness evidence, and explicit deferred directory-publication boundaries.

Validation

  • bun run prove:all: 190 passed, 4 skipped, 0 failed.
  • Deterministic distribution, generated-file, release-metadata, QuickJS compatibility, and DX proofs passed.
  • Focused regression proof covered bootstrap projection subsets, deleted canary paths, trusted Release Please identity, and CI merge-SHA isolation.
  • Fallow reported two overlapping duplication signals for one local CLI option parser. The parser stays local to avoid widening this PR into a shared abstraction.
  • Hosted canary classification passed and correctly required qualification. Qualification is blocked because the hosted-canary-qualification environment has no CANARY_GH_TOKEN, CANARY_SSH_KNOWN_HOSTS, or CANARY_SSH_PRIVATE_KEY secrets.

Release sequencing

Merge this PR before release PR #10. Keep #10 open so Release Please can rewrite the existing release branch from v0.2.0 to the correct initial v0.1.0.

Related: #10

Summary by CodeRabbit

  • New Features

    • Added portable plugin support with clearer metadata and disabled-by-default Claude activation.
    • Added Codex version-bound hooks and plugin-version validation.
    • Added installation verification for upgrades, rollbacks, trust, and failure recovery.
    • Added release-impact checks, repository readiness validation, and hosted canary qualification.
  • Bug Fixes

    • Improved package integrity checks with complete payload inventories, checksums, and safer archive handling.
    • Strengthened release validation, immutable tag handling, repair workflows, and publication safeguards.
  • Documentation

    • Expanded installation, rollback, release verification, canary, and marketplace guidance.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d06f01d25

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/.release-please-manifest.json
- Start bootstrap with a truly empty changelog
- Validate bootstrap and released changelog states separately
@myagentdojo

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1e3dab318

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread README.md Outdated
- Pin Claude marketplace installs to release tags
Initialization now creates a fresh recipient release history instead of
inheriting the template's. It forces every version surface to 0.1.0,
empties the Release Please manifest and changelog, renames the release
package to the recipient identity, and regenerates the version-bearing
Codex hook definition with --plugin-version. The Codex hooks file is now
a generated artifact covered by generate:check.

Implements U1 (R3, R12; AE1; KTD4).
Centralize plugin payload discovery in a single strict walker that
rejects symlinks, special files, and realpath escapes before any copy,
returns a deterministic sorted inventory, and copies regular files only
with preserved modes. Packaging and distribution proof now derive their
expected archive members from that shared inventory and assert exact
membership plus byte-for-byte equality against the source, replacing the
hand-maintained required-file allowlist.

Implements U2 (R8, R9; AE5; KTD2, KTD5).
Canonical metadata validation now enforces the full generated native
package contract: strict semver with a 64-character bound, structural
HTTPS URL parsing (host required, no embedded credentials, no
unsupported characters), control-character and uniqueness rules, and
normalized starter-prompt checks. The stricter directory-readiness text
subset is named separately and reports the deferred ZIP/assets/identity/
portal/review/approval/publication work as not evaluated, so passing it
never implies public-directory submission readiness.

Generated Claude manifest and marketplace entry both set
defaultEnabled: false as post-inspection defense in depth, with an
exported Claude Code 2.1.154 compatibility marker warning that earlier
clients ignore it. Contract tests consume the canonical validator and
run `claude plugin validate --strict` against the rendered plugin.

Implements U9 (R23, R24, R29, R31, R32, R36; KTD12, KTD16).
Release Please now maintains the version PR only (skip-github-release);
the workflow itself resolves exactly one merged release-PR candidate
bound to github.sha, proving base branch, automation identity, two-parent
merge, and an allowed-projection-only diff, then persists that candidate
record before proof and reuses it idempotently. Compatibility, metadata,
and payload proof run against the pinned candidate SHA even if main
advances. The immutable vX.Y.Z tag is created explicitly at the proven
SHA and verified against the remote before the GitHub Release is created
with --verify-tag --target. Incomplete-publication repair compares each
asset before writing: matching assets are left untouched, missing ones
added, and mismatches fail closed unless an explicit same-tag human
authorization runs under the protected release environment.

Release evidence is renamed from provenance to *.checksums.json bound to
repository, source commit, immutable tag, version, archive name, size,
and SHA-256, and is documented as integrity evidence rather than
independent publisher authenticity.

Implements U3 (R1-R5, R10, R11, R30; AE2-AE4; KTD1-KTD3, KTD9, KTD17).
Add a release-impact classifier that inspects the base-to-head diff and
requires a releasable Conventional Commit title (feat, fix, perf, or a
breaking form) whenever installable payload bytes change. Documentation,
test, and CI-only changes are exempt, and the recognized Release Please
version-only projection (including the node release-type package.json
bump) is exempt so the automated release PR is never blocked. Failures
name the accepted title classes and the changed payload paths.

Implements U4 (R6, R7; AE7; KTD6).
Add a read-only repository-readiness verifier (bun run readiness) that
confirms the safeguards this release design depends on: an immutable v*
tag ruleset restricting deletions and updates with no bypass, the
expected default branch and merge mode, required status checks, Actions
permissions, and that no workflow grants repository administration. Each
classifier fails closed, treating absent, bypassable, unauthorized, or
unqueryable state as not-ready with an exact settings repair hint rather
than assuming the repository is safe.

Implements U5 (R13, R14; KTD3).
Add a hermetic harness-install proof (bun run prove:harness-install) that
installs the tagged payload into isolated Claude and Codex homes and
verifies both report the same version with cache bytes identical to the
independently resolved tagged inventory. Claude proof exercises user,
project, and local scopes, preserves ${CLAUDE_PLUGIN_DATA} through
--keep-data across upgrade, rollback, and restoration, ignores orphaned
cache directories, and asserts the defaultEnabled and 2.1.154
compatibility boundary. Codex proof takes its evidence from marketplace
and plugin list --json (installed path, version, enabled state,
policies), proves local-cache byte replacement, restores prior ref and
enabled state after an injected failure, and keeps hook trust separate
from plugin enablement. Interactive trust, private Git transport, and
hosted fresh-task cases are skipped with recorded reasons. The proof
writes only to temporary isolated homes and stays out of prove:all so
the CI gate remains non-flaky.

Implements U6 (R15-R20, R25-R29, R33-R35; AE6, AE8-AE10;
KTD2, KTD7, KTD10, KTD13, KTD15, KTD16, KTD18, KTD19).
Hosted public and private Git-repository canaries now run only when the
template's publishing machinery changes, classified from the base-to-head
diff; recipient payload-only changes stay on hermetic proof alone. Canary
authorization binds the real Git transport identity used to push (SSH
greeting or HTTPS credential-helper user), failing preflight when it
differs from the intended owner even if the active gh account matches.
Each qualifying source SHA publishes to a unique immutable
refs/heads/candidate/<sha> ref per canary repo, never advancing a shared
branch or rewriting history, and the candidate is installed through each
native harness and compared to the source SHA. Results make no
universal-directory submission claim.

Implements U7 (R21, R22; KTD8, KTD11).
Rewrite the README and reviewed-release ADR to describe only proven
behavior. Release maintenance is separated from publication: Release
Please maintains the version PR, and the workflow binds one candidate
commit through proof, immutable tag, and release. Repair names an exact
existing tag and distinguishes incomplete-publication repair from a new
release. Integrity evidence is renamed from provenance to checksums.
Native install, upgrade, rollback, and trust recipes follow the proven
ordered flow per host, Codex support is scoped to the CLI and ChatGPT
desktop app, and the Git-marketplace path is separated from the deferred
OpenAI universal-directory and Anthropic community submissions.

Implements U8 (R3-R5, R10, R11, R15-R22, R26-R37;
KTD1-KTD10, KTD15-KTD19).
The implementation-ready, adversarially reviewed plan that units U1-U9
were built from.
@myagentdojo

Copy link
Copy Markdown
Owner Author

@codex review

@myagentdojo
myagentdojo had a problem deploying to hosted-canary-qualification August 5, 2026 13:51 — with GitHub Actions Failure

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d00e0fbcdb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/release.yml Outdated
Comment thread scripts/ship-canary.ts Outdated
Comment thread scripts/release-impact.ts
- Accept valid bootstrap release projections
- Classify deleted publishing paths
- Bind release exemptions to trusted automation identity
@myagentdojo
myagentdojo had a problem deploying to hosted-canary-qualification August 5, 2026 14:03 — with GitHub Actions Failure
@myagentdojo myagentdojo changed the title fix: bootstrap the initial plugin release feat: harden native plugin publishing lifecycle Aug 5, 2026
@myagentdojo

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 64b60eaf67

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/release.yml Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fac5e40f17

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/repository-readiness.ts
@myagentdojo

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb182a3c5e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread README.md Outdated
@myagentdojo
myagentdojo merged commit 904d0cf into main Aug 6, 2026
13 checks passed
myagentdojo added a commit that referenced this pull request Aug 20, 2026
… Brain (#53)

* feat(dev): detect an orphaned development cache and add a dev-mode skill

Backport of my-second-brain-plugin #11 (1a192dc).

Walks the development cache to a bounded depth and reports dangling
links, unreadable paths, and depth-exceeded paths as an orphaned or
unverifiable cache, rather than letting an unwalkable tree read as a
clean result.

Adds the dev-mode skill as the user-facing half of the Development
Installation lifecycle already shipped in #50.

Vault-specific skills from the originating commit (new-note,
new-project, ultragoal) are omitted; only dev-mode is generic.

* fix(dev): require an explicit recovery step on every lifecycle error

Backport of my-second-brain-plugin #12 (057ab2f).

Makes nextAction a required constructor parameter on every
ClaudeDevelopmentInstallationError, so no lifecycle failure reaches a
caller without naming the step that repairs it. A default here would
silently name one command as the recovery for every failure, including
that command's own.

Bun strips types without checking them, so next-action-contract.test.ts
is the enforcement: it scans every construction site, including the
helper-fed sites whose first argument is options.code, and rejects a
recovery step that is a bare rerun of the failing command.

* fix(dev): let check read a profile installed from another checkout

Backport of my-second-brain-plugin #13 (312f0f1).

The restoration snapshot lives inside the checkout that captured it, so
a second checkout never holds one for an installation it did not
create. check there now reports the link mismatch it can see rather
than refusing for want of a snapshot that was never its to hold. The
own-checkout case keeps the opposite, fail-closed contract.

The originating fixture hardcoded the plugin name; it now reads the
name from plugin.config.json, matching orphan-detection.test.ts, so the
mismatch fires under any template plugin identity.

---------

Co-authored-by: Nathan Vale <hi@nathanvale.com>
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.

2 participants