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
3 changes: 2 additions & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"plugins": [
{
"name": "harness-native-plugin-prototype",
"description": "Dependency-closed skills using a verified, plugin-managed Bun runtime",
"displayName": "Harness Plugin Prototype",
"description": "Portable Bun skills and a guided native capability tour for Claude Code and Codex",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"author": {
"name": "Prototype"
},
Expand Down
20 changes: 20 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,23 @@ _Avoid_: Package registry, artifact store
**Release**:
An immutable, versioned Plugin Payload made available for production installation.
_Avoid_: Main build, CI artifact, merged commit

**Capability Tour**:
One shared model-only skill that reports declarations, direct mechanics, current-session observation, external qualification status, and skill-seeded native delegation separately. It never reads, ingests, or infers private qualification receipts, and its default result is not an automated native-qualification claim. It uses one skill-local reviewer prompt with generic host delegation and an inline fallback; it has no standalone agent.
_Avoid_: Capability runner, agent package

**Lifecycle Mechanics Proof**:
The dependency-free `SessionStart`/`Stop` sidecar and plugin-owned drift fixture. It emits one bounded start context, stays silent on a clean Stop and active re-entry, blocks only a proven fixture mismatch, and otherwise fails open. It is not a production integrity or security guarantee and never sets up the runtime.
_Avoid_: Integrity monitor, security control

**Fresh-Native Qualification Receipt**:
A private, human-operated record from a fresh client profile. It owns native activation, UI identity, exact hook definition trust, host-corroborated delegation, and host-observed lifecycle claims. Raw receipts stay in private XDG state with `0700` directories and `0600` files; only hashes and bounded conclusions may be promoted.
_Avoid_: Automated proof report, transcript

## Capability boundaries

Automated proof binds the source candidate, package and installed payload bytes, declarations, fixture equality, and direct handler behavior. It leaves native activation, trust, UI, and delegation explicitly unproved. Fresh-native qualification binds promoted claims to the exact source commit, archive checksum, packaged payload hash, and installed payload hash. A derived drift copy keeps the source candidate SHA and records a distinct derived payload hash.

Claude installs disabled by default and can run the capability tour and portable skills when hooks are disabled. Codex keeps plugin enablement separate from hook trust: the user reviews the exact hook definition through `/hooks`; disabled or untrusted hooks preserve the same fallback behavior. Qualified platforms are macOS and Linux POSIX hosts. Native Windows support is not claimed.

The capability tour extends the same plugin. It adds no MCP, standalone agent, telemetry, user settings, companion installer, runtime setup hook, or second qualification framework.
30 changes: 25 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,29 @@ diff -qr "$PREFLIGHT_ROOT/repository/plugin" "$INSTALLED_PATH"
jq -e '.installed[] | select(.pluginId == "PLUGIN_NAME@PLUGIN_NAME" and .version == "X.Y.Z")' "$PREFLIGHT_ROOT/codex-plugins-after-add.json"
```

Start an isolated task with `codex -C "$PREFLIGHT_ROOT"` and invoke one installed skill. A missing runtime returns `BUN_MISSING` without mutation. The agent previews the verified repair, asks for approval in plain language, runs `runtime/runtime-exec repair --apply` only after approval, and retries the skill. No lifecycle hook or manual setup command is involved.
Start an isolated task with `codex -C "$PREFLIGHT_ROOT"` and invoke one installed skill. A missing runtime returns `BUN_MISSING` without mutation. The agent previews the verified repair, asks for approval in plain language, runs `runtime/runtime-exec repair --apply` only after approval, and retries the skill. The lifecycle sidecar is a mechanics proof; it never installs, repairs, or configures the runtime.

For a release qualification, keep three bounded task receipts private under `$XDG_STATE_HOME/agent-plugin-template/runtime-custody/` (defaulting `XDG_STATE_HOME` to `~/.local/state`): `claude-cli-<candidate-sha>-<target>.json`, `codex-cli-<candidate-sha>-<target>.json`, and `codex-desktop-<candidate-sha>-<target>.json`. Each receipt records the repository, candidate commit, plugin version, target, runtime-lock digest, bundle-inventory digest, payload digest, and the real `BUN_MISSING` → preview → approved repair → retry journey. The CLI receipts must come from fresh agent tasks; direct launcher execution from `prove:harness-install` is installed-payload mechanics evidence and explicitly does not claim agent workflow proof. Set `humanApprovalClaimed: true` only on receipts created from an actual interaction after the person approves; automated platform and fixture receipts must say `humanApprovalClaimed: false`. The reviewer who approves the protected `release` environment verifies these candidate-bound receipts. Store only their digests and pass/fail conclusions in release notes, never the private raw receipts.
### Fresh native capability qualification

All fresh-native cells remain **UNPROVED** until a person records receipts from fresh Claude and Codex profiles. `prove:harness-install` proves package bytes, declarations, installed bytes, and direct handler mechanics. It explicitly does not prove native activation, hook trust, UI presentation, or native delegation.

Keep raw receipts in the existing private qualification location under `$XDG_STATE_HOME/agent-plugin-template/runtime-custody/`, defaulting `XDG_STATE_HOME` to `~/.local/state`. Create every directory with mode `0700`, create every receipt with mode `0600`, and begin with `umask 077`. Extend the existing per-client receipt with a `nativeCapability` summary; do not create a second receipt framework. Use macOS and Linux POSIX hosts only; this lifecycle proof does not claim native Windows support.

For each client, bind the receipt to the exact source candidate SHA, archive SHA-256 from `*.checksums.json`, packaged payload hash, and independently measured installed payload hash. The packaged and installed hashes must match. A drift receipt also records the source candidate SHA and a distinct derived payload hash. `ship-canary` owns this candidate-lineage check.

Record these bounded cells per client:

- Fresh discovery and branded UI identity.
- Skill-seeded generic native delegation, a correlated handback, and host-owned subagent lifecycle evidence.
- One native `SessionStart` receipt for startup or resume.
- Host-observed zero-output clean `Stop` completion.
- One continuation from a disposable candidate-derived drift copy, with no other blocking Stop hook active.
- Silent `stop_hook_active: true` re-entry and unchanged fixture bytes.
- Capability-tour and existing-skill operation when hooks are disabled or untrusted, with `currentSessionHook: unknown` and no native-activation claim.

Claude qualification starts with the generated disabled plugin, verifies installed bytes, then enables it for a fresh session. Record the fallback in a separate fresh session with hooks disabled. Codex qualification first observes the untrusted fallback, reviews and trusts the exact hook definition through `/hooks`, then uses a second fresh task for activation receipts. A changed Codex definition requires fresh exact-definition review; a version-only release leaves the definition unchanged.

Promote only the receipt SHA-256 values, lineage hashes, platform/client labels, and bounded pass/fail conclusions. Never promote paths, prompts, transcript text, session data, environment dumps, or raw host receipts. The existing files remain `claude-cli-<candidate-sha>-<target>.json`, `codex-cli-<candidate-sha>-<target>.json`, and `codex-desktop-<candidate-sha>-<target>.json`. They also record the real `BUN_MISSING` → preview → approved repair → retry journey. Set `humanApprovalClaimed: true` only after actual human approval; automated platform and fixture receipts use `humanApprovalClaimed: false`.

The replacement recipe below preserves the marketplace source, ref, and prior `enabled` state. Remove the pinned marketplace entry only after target and restoration preflights pass.

Expand Down Expand Up @@ -328,7 +348,7 @@ skill id + arguments + invocation identity
| Skills | Portable Agent Skills content | `/PLUGIN:SKILL` invocation and Claude extensions | `$SKILL` invocation and Codex extensions |
| Runtime | Closed bundles, generated launchers, and one Bun custody engine | Executes the shared launcher | Executes the shared launcher |
| Manifest | Plugin identity only | Claude-native manifest | Codex-native manifest |
| Lifecycle hooks | None | None | None |
| Lifecycle hooks | One shared fail-open mechanics handler | Native `SessionStart`/`Stop` declaration; plugin enablement controls activation | Native `SessionStart`/`Stop` declaration; exact hook definition requires user trust |
| Development refresh | Source and payload | Direct checkout plus `/reload-plugins` | Staged reinstall plus a fresh task |
| Harness-only features | Nothing by default | Keep Claude-only components native | Keep Codex-only components native |

Expand Down Expand Up @@ -504,7 +524,7 @@ bun run ship:canary -- --dry-run --ref origin/main
bun run ship:canary -- --execute --ref origin/main
```

Unprivileged PR CI checks generated manifests with the candidate's own generator. The privileged canary driver executes only trusted base code. It accepts the exact same-repository PR head, binds the active `gh` login and real SSH or HTTPS Git transport identity to trusted canary targets, verifies visibility and the exact source SHA, and never executes candidate code. The private canary receives that source commit. The public canary receives a deterministic root commit containing only `plugin/`, the Claude and Codex marketplace files, and a trusted minimal hosted-proof workflow, so private repository source and history cannot become public. Each target uses `refs/heads/candidate/<published-commit-sha>` and a create-only lease: the missing ref may be created or an identical concurrent winner accepted, but an existing ref cannot be replaced. Execute mode waits for hosted CI, then installs both native Claude and Codex clients through each proven Git remote and compares their caches with the exact published candidate. It never deletes, replaces, or reuses candidate history.
Unprivileged PR CI checks generated manifests with the candidate's own generator. The privileged canary driver executes only trusted base code. It accepts the exact same-repository PR head, binds the active `gh` login and real SSH or HTTPS Git transport identity to trusted canary targets, verifies visibility and the exact source SHA, and never executes candidate code. The private canary receives that source commit. The public canary receives a deterministic root commit containing only `plugin/`, the Claude and Codex marketplace files, and a trusted minimal hosted-proof workflow, so private repository source and history cannot become public. Each target uses `refs/heads/candidate/<published-commit-sha>` and a create-only lease: the missing ref may be created or an identical concurrent winner accepted, but an existing ref cannot be replaced. Execute mode waits for hosted CI, then installs both native Claude and Codex clients through each proven Git remote and compares their caches with the exact published candidate. Candidate qualification lineage additionally binds the source commit, archive checksum, packaged payload hash, and installed payload hash before native claims can be promoted. It never deletes, replaces, or reuses candidate history.

These canaries prove this repository's Git publishing transport and native Git-marketplace installation path. They do not validate or claim OpenAI universal-directory ZIP acceptance, review, approval, or publication.

Expand All @@ -524,6 +544,6 @@ These canaries prove this repository's Git publishing transport and native Git-m
- Publisher-reviewed bundles and dependencies execute with the user's normal Bun and OS capabilities. This is not a sandbox or an untrusted-plugin runtime.
- The build rejects native addons, statically visible computed loaders and direct `eval`/`Function` use, undeclared assets, and runtime package installation. These are deterministic bundle-hygiene checks, not adversarial capability confinement; publisher review owns indirect or obfuscated code, and architecture-layer isolation owns untrusted code (ADR 0006).
- Claude reloads a direct development plugin in the existing session. Codex needs a staged reinstall and fresh task.
- Runtime lifecycle hooks, prewarm, doctor, inventory, and prune commands are intentionally absent.
- The capability-tour `SessionStart`/`Stop` sidecar is a fail-open lifecycle mechanics proof, not a production integrity or security guarantee. Runtime setup hooks, prewarm, doctor, inventory, and prune commands remain absent.
- Managed, workspace-installed, or non-removable plugins require administrator replacement or rollback.
- Vendor plugin specifications change. Recheck the linked official documentation when manifests, discovery, installation, or reload behavior changes.
11 changes: 8 additions & 3 deletions docs/adr/0005-shared-runtime-custody.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ bundle/runtime tampering, argument pass-through, and shared warm reuse.
Platform CI selects and acquires each of the four reviewed assets, runs a
packaged skill, and proves warm execution with custody network denied. Native
Claude and Codex receipts own discovery and the approval/repair/retry journey;
a named private manual receipt owns the bounded Codex Desktop smoke.
a named private manual receipt owns the bounded Codex Desktop smoke. The
capability-tour lifecycle sidecar is proved separately: it never selects,
installs, repairs, or prewarms this runtime.

## Consequences

Expand All @@ -85,5 +87,8 @@ a named private manual receipt owns the bounded Codex Desktop smoke.
verified use works offline.
- The active contract supports Bun only. Another runtime requires a new
decision, not a generic registry or per-skill bootstrap framework.
- There are no lifecycle hooks, prewarm, doctor, inventory, prune, automatic
repair-on-run, or user-managed setup commands.
- The capability tour has one dependency-free, fail-open `SessionStart`/`Stop`
lifecycle mechanics proof. It is not a runtime-custody hook and provides no
production integrity or security guarantee.
- Runtime setup hooks, prewarm, doctor, inventory, prune, automatic repair-on-run,
and user-managed setup commands remain absent.
94 changes: 94 additions & 0 deletions docs/adr/0008-native-plugin-capability-tour.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Extend one plugin with a native capability tour

## Status

Accepted — 2026-08-10.

## Context

The repository needs one truthful tour of shared skills, client-native lifecycle
declarations, branded identity, and native delegation. Automated package and
handler checks can prove bytes and direct mechanics. They cannot prove that a
fresh Claude or Codex client discovered the plugin, presented its identity,
trusted and activated hooks, or delivered a native subagent lifecycle.

Claude and Codex also have asymmetric trust. Claude installs the generated
plugin disabled by default and activates its declarations when the plugin is
enabled. Codex separates plugin enablement from hook trust and requires the user
to review the exact hook definition through `/hooks`.

## Decision

Extend the same plugin as one capability tour.

- Keep one shared model-only skill and one skill-local reviewer prompt.
- Seed one generic native subagent through the client host primitive when
available. Use equivalent read-only inline checks when delegation is
unavailable or fails. Do not package a standalone agent.
- Generate separate Claude and Codex hook declarations around one shared POSIX
handler.
- Limit hooks to `SessionStart` and `Stop`. Show success once at startup or
resume. Stay silent for a clean Stop and active Stop re-entry.
- Use the plugin-owned source/projection pair only as a lifecycle mechanics
proof. Request one continuation only for a proven byte mismatch. Fail open for
malformed input, missing tools, unreadable metadata, or operational doubt.
- Keep the handler dependency-free and mutation-free. It never runs workspace
code or performs runtime setup, repair, prewarm, inventory, or pruning.

The lifecycle mechanics proof is not a production integrity or security
guarantee. It demonstrates bounded host hook behavior only.

## Evidence and trust boundary

Repository tests and candidate-bound automated proofs own generated declaration
bytes, package inventory, fixture equality, direct handler mechanics, archive
identity, and installed payload equality. `prove-harness-install` retains an
explicit `not-proved` native qualification cell unless a bounded external
summary is supplied. Direct execution never becomes a native activation claim.

Fresh native qualification remains human-operated. Raw receipts live in private
XDG state with `0700` directories and `0600` files. Only receipt hashes, lineage
hashes, client/platform labels, and bounded conclusions may be promoted. Paths,
prompts, transcripts, session data, environment dumps, and raw host receipts
remain private.

Each client receipt covers:

- Fresh discovery and UI identity.
- Skill-seeded native delegation with correlated handback and host-owned
lifecycle evidence.
- One native `SessionStart` receipt and host-observed silent clean `Stop`.
- A candidate-derived drift continuation bound to the source candidate SHA and
a distinct derived payload hash, followed by silent re-entry.
- Capability-tour and existing-skill fallback while hooks are disabled or
untrusted, without a native-activation claim.
- Codex exact hook definition trust; Claude records this as not applicable.

`ship-canary` owns candidate lineage. Promoted claims bind to the exact source
commit, archive checksum, packaged payload hash, and independently measured
installed payload hash. Packaged and installed payload hashes must agree. The
derived drift hash must differ.

Qualification cells remain unproved until those receipts exist. Documentation
must not infer native behavior from declarations, direct handler execution, or
historical client runs.

## Exclusions

- No MCP.
- No standalone agent or agent configuration.
- No telemetry.
- No user settings mutation or companion installer.
- No generic capability framework or second qualification framework.
- No hook-driven runtime setup.
- No native Windows claim. Qualification covers macOS and Linux POSIX hosts.

## Consequences

- One capability tour works across both clients while native declarations and
trust remain client-specific.
- Disabled or untrusted hooks do not block the tour or existing skills.
- Static hooks, the skill, reviewer prompt, and assets stay outside the
version-only release projection.
- A changed Codex hook definition requires fresh exact-definition review. A
version-only release does not change the definition.
Loading