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
72 changes: 72 additions & 0 deletions .agents/plans/02-eval-engineering/evidence/phase-9-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Phase 9 architecture synthesis

## Arena decision

Three candidates converged on a separate manual canary gate. The independent judge
selected the exact-artifact, write-once record base and grafted tag-only publication,
ActorIdentity-shaped evidence, checklist expiry, redacted artifact hashes, and an
exact canary digest inside the final release decision input.

## Operator flow

```bash
bun run build
bun pm pack --destination .release-artifacts
bun run eval:canary -- prepare \
--artifact .release-artifacts/opencode-plugin-flow-<version>.tgz \
--out .release-artifacts/canary-<version>

# Run the prepared local-plugin fixture in OpenCode and save its session evidence.
bun run eval:canary -- record \
--prepared .release-artifacts/canary-<version>/prepared.json \
--status passed --operator <maintainer> \
--host-config <json> --actors <json> --checks <json> \
--project-path <fixture> --session <json> --transcript <json>

# Reissue the decision with the reviewed canary in its input hash.
bun run qualify -- --report <report> --catalog <catalog> --artifact <tgz> \
--canary evals/canary/<version>.json
```

`prepare` is non-claiming. It copies the exact tarball, extracts its validated
`dist/index.js` into a project-local `.opencode/plugins/flow.js`, pins the local
plugin dependencies, creates a small canary workspace, and writes the immutable
checklist/artifact preparation manifest outside Git under `.release-artifacts`.

`record` redacts JSON-shaped session and transcript evidence, removes workspace and
session identifiers, writes sanitized artifacts, and then publishes exactly one
canonical `evals/canary/<version>.json`. Byte-identical replay succeeds; a changed
record conflicts. Passed, failed, and incomplete attempts are all durable evidence.

## Record and gate

The strict canary record binds:

- full `ArtifactIdentity` and `v<packageVersion>` tag;
- exact checklist version, hash, and required check set;
- passed, failed, or incomplete status;
- explicit operator, recorded time, and checklist-derived 72-hour expiry;
- host configuration digest and manager/reviewer `ActorIdentity` observations;
- relative sanitized session/transcript paths, byte counts, and SHA-256 digests;
- its own canonical record hash.

Passed requires every check true, both sanitized artifacts, at least one actor, and
fresh internally consistent timestamps. Failed requires at least one false check.
Incomplete can preserve partial evidence but never qualifies publication.

The scheduled evaluation decision remains `canarySha256: null`. After manual canary
recording, qualification validates the exact artifact/tag/fresh passed canary and
writes a distinct canary-bound decision record. `decisionInputSha256` includes
`canarySha256`, so a canary cannot be attached to an older decision after the fact.

## Workflow

`release.yml` runs on main and `v*` tags. Main rebuilds and checks the package,
reports missing release decision/canary as `INCONCLUSIVE`, and has no publish job.
Tags rebuild the tarball from the tagged checkout and require an exact VERIFIED
canary-bound decision plus the fresh passed `evals/canary/<version>.json` from that
same checkout before npm or GitHub publication. The temporary Phase 5 stop is
deleted; publication remains tag-only.

No release is requested in this phase. The manual canary and canary-bound decision
remain pending for the maintainer-run OpenCode session.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"schemaVersion": 1,
"status": "incomplete",
"reason": "maintainer-run-opencode-canary-pending",
"releaseTag": "v8.1.1",
"artifact": {
"packageVersion": "8.1.1",
"sourceCommit": "647729c87d98fd773bc57355b31b2ac6ea7ab958",
"sourceTreeSha256": "sha256:cfbda87999aeffcfaaf1571d44ada3155e4ab5812e64c6bc7ac5129d8a3c9dcb",
"tarballSha256": "sha256:ea83bd80ae830781cc63983eb3b7138ce4d9e3f8fa21d94a753d16fcb85fcc24",
"unpackedManifestSha256": "sha256:60ae7a2de693c735bbace6cc331f556210673ec0e83fbc17d01fe6c752bd430a"
},
"artifactSha256": "sha256:3e5c3dca41ddeb6424a5f876005db56a2c5a1bb5466b99c148f539f77901d304",
"checklistVersion": "phase9-canary-v1",
"checklistSha256": "sha256:bcaa925277568ce9b67c50f0785c3bfbadfa5bb40a6f36b39fad63c21a605110",
"pluginEntrySha256": "sha256:43ff17acb2d51279e28b806fdb7022b2f5d065bd8ee4ba2ae121542937420dfc",
"preparedSha256": "sha256:8fad620fe38ff76a109a11baa5d71d8c045046e8aa840e70fa186b2ff455a844",
"fixtureHost": "opencode-1.18.6",
"fixtureAutoLoadVerified": true,
"fixtureObservedSurfaces": [
"flow-reviewer",
"flow-auto",
"flow-status"
],
"dryRunVerdict": "INCONCLUSIVE",
"strictTagGateBlocked": true,
"expectedCanaryPath": "evals/canary/8.1.1.json",
"expectedDecisionState": "VERIFIED with matching non-null canarySha256",
"releaseRequested": false
}
38 changes: 38 additions & 0 deletions .agents/plans/02-eval-engineering/evidence/phase-9-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Phase 9 Interrogate review and canary handoff

Phase 9 replaces the temporary unconditional release stop with an exact manual
canary protocol. Preparation validates and copies the tarball, extracts its bundled
entry into a project-local OpenCode plugin fixture, pins dependencies, and writes a
versioned checklist manifest outside Git. Direct OpenCode 1.18.6 inspection proved
that the fixture auto-loads the exact local plugin and exposes Flow's reviewer and
commands.

Recording accepts passed, failed, or incomplete outcomes. It requires the exact
check set, explicit operator, host digest, ActorIdentity-shaped manager/reviewer
evidence, and checklist-derived 72-hour expiry. Session and transcript JSON are
scrubbed for credentials, workspace paths, and runtime IDs before immutable
artifact and record publication. Byte-identical replay succeeds and changed bytes
conflict.

Release decisions now carry `canarySha256`, and `decisionInputSha256` includes it.
The scheduled canary-null decision remains separate; after the manual run the
maintainer reruns qualification to create a hash-suffixed canary-bound decision.
Strict tag verification recomputes that input hash, checks the full rebuilt
ArtifactIdentity, reads the fresh passed canary and sanitized artifacts from the
tagged checkout, and stops before any publish step on mismatch.

The release workflow now verifies on main and tags. Main has read-only contents
permission, reports missing release evidence as `INCONCLUSIVE`, and has no publish
job path. The tag-only release job has scoped write/id-token permissions and depends
on deterministic verification before npm or GitHub publication. The temporary
`canary-not-enabled` step is removed.

The non-model runtime proof packed the current bytes, generated the fixture,
observed Flow surfaces on the pinned host, returned `INCONCLUSIVE` in dry-run, and
failed strict verification as required. No canary record, canary-bound decision,
tag, or release was fabricated. The final phase remains `INCONCLUSIVE` until the
maintainer completes the prepared OpenCode checklist.

The full repository gate passes 520 tests with one intentional live-smoke skip.
The final four-model review found no unresolved blocker in the implemented
infrastructure; the human canary stop remains open by design.
10 changes: 10 additions & 0 deletions .agents/plans/02-eval-engineering/phase-9-release-alignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,13 @@ rebuild the same tarball hash and preserve deterministic checks in the publish j

Stop gate. This final phase remains `INCONCLUSIVE` until the maintainer completes
the canary. It does not block Phases 0 through 8.

## Outcome

Infrastructure implemented and verified. Exact-artifact preparation, strict
passed/failed/incomplete records, sanitized evidence, expiry, canary-bound decision
hashes, main dry-run verification, and tag-only strict publication are live. The
prepared fixture loads Flow on OpenCode 1.18.6. The phase remains `INCONCLUSIVE`
because the maintainer-run canary and resulting canary-bound decision are pending;
no release was requested. See `evidence/phase-9-architecture.md`,
`evidence/phase-9-review.md`, and `evidence/phase-9-preparation.json`.
5 changes: 5 additions & 0 deletions .audit/eval-engineering.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,8 @@ ts phase decision why evidence result
2026-08-25T08:55:41Z phase-8 expanded mutation-tested hidden coverage new tasks need executable controls and explicit contamination boundaries before producing useful evidence evals/benchmarks.ts; tests/benchmark-reporting.test.ts VERIFIED 5 cases, 12 rejected mutations, known-good implementations pass
2026-08-25T08:55:41Z phase-8 kept coverage promotion closed uncalibrated cases cannot silently become release regressions evals/benchmark-run.ts catalog policy; .agents/plans/02-eval-engineering/evidence/phase-8-review.md VERIFIED every benchmark case remains report-only; no legacy backfill
2026-08-25T08:55:41Z phase-8 ran Deslop, four-model Interrogate, and full repository gate trend and coverage changes must remain reviewable and regression-free bun run check VERIFIED 509 pass, 1 skip, 0 fail; no unresolved blocker
2026-08-25T09:30:36Z phase-9 selected exact canary and release binding through Architect and Arena tag publication needs a human stop gate bound into the final decision input without making main a publisher .agents/plans/02-eval-engineering/evidence/phase-9-architecture.md VERIFIED ActorIdentity evidence, 72h expiry, canarySha256 decision binding, tag-only publish
2026-08-25T09:30:36Z phase-9 implemented exact-artifact prepare, record, and verify the maintainer needs a rerunnable fixture and write-once sanitized evidence instead of a prose attestation scripts/eval-canary.ts; tests/eval-canary.test.ts VERIFIED strict record boundary, redaction, immutable replay/conflict, local plugin fixture
2026-08-25T09:30:36Z phase-9 bound release decisions and workflow to the fresh canary a canary cannot be grafted onto an older decision and main must have no publication authority scripts/qualify-release.ts; scripts/release-metadata.ts; .github/workflows/release.yml VERIFIED decision input recomputation, main dry-run, strict tag gate, scoped permissions
2026-08-25T09:30:36Z phase-9 prepared and drove the exact fixture without fabricating the human result the infrastructure must be proven while the manual stop remains honest .agents/plans/02-eval-engineering/evidence/phase-9-preparation.json INCONCLUSIVE exact artifact loads on OpenCode 1.18.6; canary and canary-bound decision pending
2026-08-25T09:30:36Z phase-9 ran Deslop, four-model Interrogate, workflow checks, and full repository gate the final release boundary must be reviewable and regression-free bun run check; actionlint; strict canary dry-run VERIFIED 520 pass, 1 skip, 0 fail; strict tag gate blocks pending canary
72 changes: 57 additions & 15 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ name: Release

on:
push:
branches:
- main
tags:
- 'v*'

permissions:
contents: write
id-token: write
contents: read

jobs:
decide:
Expand All @@ -28,16 +29,58 @@ jobs:
tag="v${version}"
echo "tag=${tag}" >> "$GITHUB_OUTPUT"

if [[ "${GITHUB_REF_NAME}" != "${tag}" ]]; then
echo "::error::Release tag/version mismatch: tag=${GITHUB_REF_NAME}, package.json=${version}."
exit 1
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
if [[ "${GITHUB_REF_NAME}" != "${tag}" ]]; then
echo "::error::Release tag/version mismatch: tag=${GITHUB_REF_NAME}, package.json=${version}."
exit 1
fi
echo "publish=true" >> "$GITHUB_OUTPUT"
else
echo "publish=false" >> "$GITHUB_OUTPUT"
fi
echo "publish=true" >> "$GITHUB_OUTPUT"

release:
verify-main-and-tag:
needs: decide
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
package-manager-cache: false

- name: Set up Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.14

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Run deterministic checks
run: bun run check

- name: Rebuild release candidate
run: bun pm pack --destination .

- name: Report release evidence readiness without publishing
shell: bash
run: |
set -euo pipefail
tarball="$(ls opencode-plugin-flow-*.tgz)"
bun run release:metadata -- --artifact "$tarball"
bun run eval:canary -- verify --artifact "$tarball" --mode dry-run

release:
needs: [decide, verify-main-and-tag]
if: needs.decide.outputs.publish == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -78,20 +121,19 @@ jobs:
set -euo pipefail
bun pm pack --destination .

- name: Verify exact VERIFIED V2 artifact decision
- name: Verify exact VERIFIED V2 artifact decision and fresh canary
shell: bash
run: |
set -euo pipefail
version="$(node -p "require('./package.json').version")"
tarball="$(ls opencode-plugin-flow-*.tgz)"
bun run release:metadata -- --tag "${{ needs.decide.outputs.tag }}" --notes-file release-notes.md --artifact "$tarball"
bun run release:metadata -- \
--tag "${{ needs.decide.outputs.tag }}" \
--notes-file release-notes.md \
--artifact "$tarball" \
--canary "evals/canary/${version}.json"
shasum -a 256 "$tarball" > "${tarball}.sha256"

# Temporary Phase 5 stop: the exact manual OpenCode canary is owned by Phase 9.
- name: Require Phase 9 canary
run: |
echo "::error::Release blocked: canary-not-enabled until Phase 9 release alignment is implemented."
exit 1

- name: Publish to npm
shell: bash
run: |
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"clean": "bun run scripts/clean-dist.ts",
"eval": "bun run evals/run.ts",
"eval:smoke": "bun run evals/run.ts -- --repeat 1",
"eval:canary": "bun run scripts/eval-canary.ts",
"benchmark": "bun run evals/benchmark-run.ts",
"lint": "bunx biome check biome.json src tests scripts evals --files-ignore-unknown=true --vcs-use-ignore-file=true",
"release:metadata": "bun run scripts/release-metadata.ts",
Expand Down
Loading