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
41 changes: 41 additions & 0 deletions .github/workflows/beads-contract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: beads-contract

# Nothing is vendored from upstream Beads. This checks the latest stable bd release against the
# plugin's contract daily, and fails when a newer release has not been reviewed yet.
# Independent MAIN source comparison is informational; unavailable evidence fails only its job.
on:
schedule:
- cron: '0 9 * * *'
Expand Down Expand Up @@ -64,3 +65,43 @@ jobs:
echo "::error::Beads $VERSION passes the contract but is newer than the validated $validated. Review its upgrade notes against docs/beads-artifact-policy.md, then update beads.validated in package.json and the README compatibility table."
exit 1
fi

source-comparison:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false

- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.3.14

- name: Compare upstream MAIN sources
env:
GH_TOKEN: ${{ github.token }}
run: |
status=0
bun scripts/check-beads-integration.ts > "$RUNNER_TEMP/beads-source.json" || status=$?
printf '%s\n' "$status" > "$RUNNER_TEMP/beads-source.exit"
exit "$status"

- name: Summarize upstream MAIN comparison
if: ${{ always() }}
run: |
{
printf '## Upstream MAIN source comparison\n\n'
printf 'Development-source information only; tagged CLI compatibility is independent.\n\n'
if [[ -f "$RUNNER_TEMP/beads-source.exit" ]]; then
printf 'Collector exit status: %s\n\n' "$(cat "$RUNNER_TEMP/beads-source.exit")"
else
printf 'Comparison unavailable: collector did not finish.\n\n'
fi
if [[ -s "$RUNNER_TEMP/beads-source.json" ]]; then
printf '````json\n'
cat "$RUNNER_TEMP/beads-source.json"
printf '\n````\n'
fi
} >> "$GITHUB_STEP_SUMMARY"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Version **2.0.0** is the stable line.
| Component | Supported | Evidence |
| --- | --- | --- |
| OpenCode | `>=2.2.6 <2.3` | Exact 2.2.6 native-host qualification plus one genuine model workflow |
| `bd` CLI | 1.3.1 through 1.x | 1.3.1 contract baseline |
| `bd` CLI | 1.3.1 through 1.x | 1.3.4 contract baseline |

A compatible range is admission, not proof that every future patch was tested. The plugin refuses to register on hosts outside the range. Older hosts: see [Compatibility](docs/user-guide.md#compatibility).

Expand Down Expand Up @@ -89,7 +89,7 @@ The agent claims the issue atomically and appends checkpoints under the actual s

## Authorship and license

This is an independent project maintained by Matt Jackson. It began as a fork of [Josh Thomas's `opencode-beads`](https://github.com/joshuadavidthomas/opencode-beads), and the original work remains credited to its author. It vendors nothing from upstream Beads; each Beads release is checked against the `bd` behavior the plugin relies on.
This is an independent project maintained by Matt Jackson. It began as a fork of [Josh Thomas's `opencode-beads`](https://github.com/joshuadavidthomas/opencode-beads), and the original work remains credited to its author. It vendors nothing from upstream Beads; the daily/manual maintenance workflow checks tagged CLI compatibility and independently compares reviewed upstream integration sources with current MAIN. Completed source changes are informational; adoption remains a human decision.

opencode-beads is licensed under the MIT license. See [`LICENSE`](LICENSE).

Expand Down
23 changes: 23 additions & 0 deletions docs/beads-1.3.4-review-2026-11-09.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Beads 1.3.4 review — 2026-11-09

Reviewed from plugin 2.0.0 source `bb496c1bc0b05a4131856c90106f05748e396d57`. Disposition: validate exactly Beads 1.3.4, retaining minimum 1.3.1. No adapter runtime, packaged guidance, API or dependency change is needed for the reviewed deltas. This is CLI compatibility evidence, not a guarantee about every upstream storage topology or an operator upgrade.

## Reviewed deltas and disposition

- [1.3.2 release/upgrade notes](https://github.com/gastownhall/beads/releases/tag/v1.3.2): retention, backup, concurrent blocked-state recheck, least-privilege connections and export fixes belong to the installed CLI. The migration0059 stored-blockedness warning can affect ready results in older adopted stores; the upstream notes prescribe `bd recompute-blocked` for affected workspaces. The adapter must report CLI results honestly, not recompute or repair them itself. No operator action was performed here.
- [1.3.3 release](https://github.com/gastownhall/beads/releases/tag/v1.3.3) and [tagged changelog, including rc.1 upgrade notes and known issues](https://github.com/gastownhall/beads/blob/v1.3.3/CHANGELOG.md): `.beads/.env` allowlisting, user-owned mail delegation and remote URL refusal are upstream boundaries. The plugin invokes the installed CLI with project context and explicit executor attribution; it does not parse these settings or implement mail/remote transport. `src/prime.ts` retains stdout and stderr on failures, unlike the cited Gas City stderr-only failure. No new environment or routing layer is warranted.
- [Exact-id deletion change](https://github.com/gastownhall/beads/blob/v1.3.4/cmd/bd/delete.go) and rules-compaction confirmation changes: the eleven typed operations in `src/continuity.ts` do not implement deletion or rules compaction. `src/workflows.ts` delivers scoped command guidance rather than parsing either changed JSON shape. Existing target/effect and authority guidance remains applicable; no prompt change is required.
- Database timestamp preservation, proxy startup, doctor cleanup, GitHub sync, history compaction and security dependency fixes remain CLI-owned. The adapter neither identifies proxy children from their config filename nor reimplements these internals. The changelog's remaining shared-endpoint credential, stale-local-copy sync and server reset-data issues remain upstream limitations; validation does not claim their repair, confinement or universal store safety. No downstream mitigation, credential/config change or store experiment was undertaken.
- [1.3.4 release](https://github.com/gastownhall/beads/releases/tag/v1.3.4) and [tagged environment loader/tests](https://github.com/gastownhall/beads/blob/v1.3.4/cmd/bd/envfile_test.go): the exact `GT_ROOT` key is admitted again, shell environment still wins, and other `GT_*` keys remain refused. The [loader](https://github.com/gastownhall/beads/blob/v1.3.4/cmd/bd/main.go) delegates admission upstream. This fixes the 1.3.3 rig notice/formula-discovery regression; no local workaround is needed.
- **Migration0062 warning retained:** 1.3.4 does not include the [events restoration fix](https://github.com/gastownhall/beads/issues/7039). Its [upgrade notes](https://github.com/gastownhall/beads/blob/v1.3.4/CHANGELOG.md) say not to run `bd compact` or `bd flatten` on clones that adopted that migration by pull/bootstrap or were cloned afterward: these can erase history needed for recovery. The plugin's compact command explicitly distinguishes semantic `bd admin compact` from Dolt-history squashing. No local migration guard, backfill, history compaction or live-store test is justified by this review.

The [tagged comparison](https://github.com/gastownhall/beads/compare/v1.3.1...v1.3.4), including the loader, exact-id deletion and migration timestamp changes, was inspected against the prime/guard/typed-operation/workflow seams and artifact policy. No new migration file or embedded engine change is claimed by these patch releases; existing guard behavior and its 1.3.1 refusal fixtures remain unchanged.

## Evidence and separate baselines

[Scheduled run 42591441654](https://github.com/snarkipus/opencode-beads/actions/runs/42591441654) installed exact bd 1.3.4 (`7ef2fd05e: HEAD@7ef2fd05eb0c`), passed Check bd contract, and failed only Require review of new Beads releases because validated metadata was still 1.3.1. The retained receipt is `/opt/data/research/opencode-beads-1.3.4-status/latest-scheduled.log`. This exercises the existing disposable contract, including actual guard, prime, init/setup, typed operations and actor/outcome assertions. Native OpenCode qualification's 1.3.4 fixture is separate evidence and is not the release-note review.

The artifact policy's Beads 1.3.1 comparison is historical integration evidence and stays intact. CLI validation does not advance `docs/claude-code-integration-inventory.json`, adopt upstream source, raise the supported minimum, change package 2.0.0, or publish a release. No real store was migrated or used as a fixture.


Local candidate verification on 2026-11-09 ran the unchanged `bun run test:bd-contract` once with exact bd 1.3.4 (`7ef2fd05e: HEAD@7ef2fd05eb0c`) and actor `codex:d1075a97`: **contract satisfied**. All stores used by that command were disposable under the environment scratch directory; the real tracker was not a fixture. The full receipt is `/opt/data/research/opencode-beads-upstream-maintenance-implementation/bd-contract.log`. No live Actions source-comparison execution is established by this CLI receipt.
3 changes: 3 additions & 0 deletions docs/beads-artifact-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Status: current policy for the published 2.x line. The package vendors no upstream Beads artifacts. It ships project-owned adaptations under `assets/oc-beads/` (one skill, 15 corpus resources, CODE_MODE and the adapted ADR, 17 explicit links), 30 native commands and the typed `beads` operations, rather than an upstream executable or host-specific integration. The installed `bd` CLI remains the execution and data owner, and `bd init` owns the shared `.agents/skills/beads`. The sections below are dated rationale and evidence: earlier stable exclusion and one-bead descriptions, and "candidate", "unpublished" or "withheld" wording, describe the state when they were written. Current behavior is defined by the canonical specs; see the [documentation index](README.md).

Current maintenance: the daily/manual `beads-contract` workflow defines independent tagged-CLI and advisory MAIN source-comparison jobs, with collector JSON and exit status in the Actions summary. Completed source comparisons are informational successes; unavailable evidence fails only the independent source job, never a product/release prerequisite. Adoption and reviewed source-baseline changes require explicit human disposition under the [canonical upstream-review spec](../openspec/specs/upstream-review/spec.md). The [1.3.4 CLI review](beads-1.3.4-review-2026-11-09.md) leaves the historical 1.3.1 integration comparison and marketplace-main inventory intact. The dated source-only acceptance below remains historical evidence, not proof of workflow execution.


Historical policy summary, preserved for release provenance:

Status: current stable implementation policy, under review in the [full integration decision packet](claude-code-integration-analysis.md). Owner selections for an opt-in beta/next redesign are recorded; task 2.1 supplied the accepted guidance assets and the tasks 2.2/3.3 candidate adds package inclusion and skill registration. All 30 command definitions now register through native precedence; runtime qualification remains unexecuted. Revised for 1.0.0 by `opencode-beads-w5y`. The package vendors no upstream Beads artifacts. The current source package includes the project-owned adaptations under `assets/oc-beads/`; the published stable artifact remains separate. Earlier revisions were the OpenCode V2 port (`opencode-beads-2zs`), the 0.9.0 contract (`opencode-beads-98l`), and the retired 0.8.0 companion lifecycle decision.
Expand Down
6 changes: 4 additions & 2 deletions docs/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,19 @@ Remove the `plugins` entry to unload the plugin. Cleanup aborts owned context/pr
| OpenCode (historical beta.5) | `>=2.1.1 <2.2` | 2.1.1 (bounded accepted evidence) |
| OpenCode (2.0.0) | `>=2.2.6 <2.3` | 2.2.6 (accepted native and genuine-model qualification) |
| OpenCode (stable 1.0.2 historical) | 2.0.26 | 2.0.26 |
| `bd` CLI | 1.3.1 through 1.x | 1.3.1 |
| `bd` CLI | 1.3.1 through 1.x | 1.3.4 |
| Bun (OpenCode host runtime) | >=1.3.14 | 1.4.2 |

Version 2.0.0 type-checks against `@opencode/plugin` 2.2.6 and declares optional peer range `>=2.2.6 <2.3`. Admission does not qualify future patches. Native qualification used Beads 1.3.4 as its fixture CLI; the supported-minimum contract evidence remains 1.3.1. See the [2.2.6 qualification](opencode-22-qualification-5rj2.md) and the [OpenCode integration reference](opencode-sdk-contract.md). The `bd` baseline was reviewed against Beads v1.3.1 (commit `c1c4b642ac1c08d8c828007a1c2f96e47e43ef7c`).
Version 2.0.0 type-checks against `@opencode/plugin` 2.2.6 and declares optional peer range `>=2.2.6 <2.3`. Admission does not qualify future patches. Native qualification used Beads 1.3.4 as its fixture CLI; the supported-minimum contract evidence remains 1.3.1. See the [2.2.6 qualification](opencode-22-qualification-5rj2.md) and the [OpenCode integration reference](opencode-sdk-contract.md). The current CLI baseline was reviewed against Beads v1.3.4; see the [2026-11-09 release review](beads-1.3.4-review-2026-11-09.md). The historical integration comparison remains Beads v1.3.1 (commit `c1c4b642ac1c08d8c828007a1c2f96e47e43ef7c`), separately from CLI validation and the reviewed marketplace-main inventory.

## Tracking upstream Beads

The package vendors nothing from upstream. It depends on the installed `bd` CLI at runtime: `bd prime` supplies the current workflow, and the schema migration guard enforces the supported `bd` range.

[`scripts/bd-contract.ts`](../scripts/bd-contract.ts) checks a real `bd` against everything the plugin relies on. CI runs it against the validated release from `package.json` (`beads.validated`). The scheduled `beads-contract` workflow runs it daily against the latest stable Beads release and fails if that release breaks the contract or is newer than the validated one. When a new release appears, review its upgrade notes, then update `beads.validated` and the compatibility table. The [artifact policy](beads-artifact-policy.md) records why upstream artifacts are not vendored.

The daily/manual `beads-contract` workflow also has an independent source-comparison job using `scripts/check-beads-integration.ts`. Its step summary contains the collector JSON and exit status: immutable reviewed baseline/candidate commits, selected paths and source/diff links. Completed changed and unchanged comparisons succeed informationally; unavailable retrieval/comparison fails that job and is never reported as unchanged. Neither job depends on the other, and these maintenance checks are not product/release prerequisites. No GitHub issues, automatic adoption or baseline advancement occur. A maintainer must explicitly disposition changes before updating the reviewed inventory. Schedules use the default branch; an authorized manual run can select a published branch with `--ref` when the workflow exists on default.

## Troubleshooting

- **No Beads context:** Run `bd prime`. Install `bd` if missing or run `bd init` if the project has no Beads workspace.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
},
"beads": {
"minimum": "1.3.1",
"validated": "1.3.1"
"validated": "1.3.4"
},
"peerDependencies": {
"@opencode/plugin": ">=2.2.6 <2.3"
Expand Down
4 changes: 2 additions & 2 deletions tests/docs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ describe("documentation contracts", () => {
expect(userGuide).toContain("| OpenCode (historical beta.5) | `>=2.1.1 <2.2` | 2.1.1 (bounded accepted evidence) |");
expect(userGuide).toContain(`| OpenCode (${packageManifest.version}) | \`>=2.2.6 <2.3\` | 2.2.6 (accepted native and genuine-model qualification) |`);
expect(userGuide).toContain("| OpenCode (stable 1.0.2 historical) | 2.0.26 | 2.0.26 |");
expect(userGuide).toContain("| `bd` CLI | 1.3.1 through 1.x | 1.3.1 |");
expect(userGuide).toContain("| `bd` CLI | 1.3.1 through 1.x | 1.3.4 |");
expect(readme).toContain("| OpenCode | `>=2.2.6 <2.3` |");
expect(readme).not.toContain("The candidate has not passed live host qualification");
expect(readme).toContain("Upgrade OpenCode before changing the plugin pin");
Expand Down Expand Up @@ -344,7 +344,7 @@ describe("documentation contracts", () => {

test("records the retired vendoring decision and the historical baselines", () => {
expect(userGuide).toContain("The package vendors nothing from upstream.");
expect(userGuide).toContain("The `bd` baseline was reviewed against Beads v1.3.1");
expect(userGuide).toContain("The historical integration comparison remains Beads v1.3.1");
expect(userGuide).toContain("c1c4b642ac1c08d8c828007a1c2f96e47e43ef7c");
expect(artifactPolicy).toContain("The package vendors no upstream Beads artifacts.");
expect(artifactPolicy).toContain("| `agents/task-agent.md` | Retired in 1.0.0 (`opencode-beads-w5y`) |");
Expand Down
20 changes: 20 additions & 0 deletions tests/release.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,26 @@ describe("release artifact identity", () => {
expect(workflow).not.toMatch(/npm publish\s*(?:\n|$)/);
});

test("keeps source comparison independent and reports even unavailable collection", async () => {
const workflow = await fs.readFile(join(projectDirectory, ".github/workflows/beads-contract.yml"), "utf8");
expect(workflow).toContain("schedule:");
expect(workflow).toContain("workflow_dispatch:");
expect(workflow.match(/^ [a-z-]+:$/gm)?.filter(line => line === " contract:" || line === " source-comparison:")).toHaveLength(2);
expect(workflow).not.toMatch(/\bneeds:|continue-on-error:|(?:issues|checks):\s*write/);
const source = workflow.split(" source-comparison:")[1]!;
expect(source).toContain("bun scripts/check-beads-integration.ts");
expect(source).toContain('exit "$status"');
expect(source).toContain("if: ${{ always() }}");
expect(source).toContain('>> "$GITHUB_STEP_SUMMARY"');
expect(source).not.toMatch(/install-bd|test:bd-contract|::(?:error|warning)::/);
expect(workflow).toContain("Require review of new Beads releases");
for (const name of ["ci.yml", "release.yml"]) {
const product = await fs.readFile(join(projectDirectory, ".github/workflows", name), "utf8");
expect(product).not.toContain("source-comparison");
expect(product).not.toContain("beads-contract.yml");
}
});

test("hardens workflow dependencies, credentials, caching, and update cooldowns", async () => {
const workflowNames = ["ci.yml", "release.yml", "beads-contract.yml"];
const workflows = await Promise.all(
Expand Down
Loading
Loading