Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
1a10772
chore: record delivery binding for auto-close-linked
LeXwDeX Sep 3, 2026
1eca66a
chore: record delivery binding for auto-close-linked
LeXwDeX Sep 3, 2026
ff2dcc0
chore(ci): add dev-layer issue auto-close workflow
LeXwDeX Sep 3, 2026
d781085
Merge pull request #520 from LeXwDeX/feat/519-auto-close-linked
LeXwDeX Sep 3, 2026
320e640
chore: record delivery binding for summary-diff-continue
LeXwDeX Sep 3, 2026
9ffc93f
fix: skip oversized summary diffs individually and drop the dead summ…
LeXwDeX Sep 3, 2026
898cc0b
chore: record delivery binding for summary-diff-continue
LeXwDeX Sep 3, 2026
9cebd98
Merge pull request #526 from LeXwDeX/fix/525-summary-diff-continue
LeXwDeX Sep 3, 2026
772ea03
fix: dedupe byte-identical durable event appends without consuming seq
LeXwDeX Sep 3, 2026
b111b2a
Merge pull request #527 from LeXwDeX/fix/523-event-idempotency-gate
LeXwDeX Sep 3, 2026
6e3eedf
chore: record delivery binding for specgit-bootstrap-wrapper
LeXwDeX Sep 3, 2026
3976319
chore: record delivery binding for specgit-bootstrap-wrapper
LeXwDeX Sep 3, 2026
1988228
chore(specgit): add safe bootstrap wrapper
LeXwDeX Sep 3, 2026
1b42e5d
Merge pull request #532 from LeXwDeX/feat/521-specgit-bootstrap-wrapper
LeXwDeX Sep 3, 2026
1246106
chore: record delivery binding for specgit-bootstrap-rollback
LeXwDeX Sep 3, 2026
f0ab55a
chore: record delivery binding for specgit-bootstrap-rollback
LeXwDeX Sep 3, 2026
ae4497e
fix(specgit): restore failed bootstrap record
LeXwDeX Sep 3, 2026
8711c13
Merge pull request #533 from LeXwDeX/feat/530-specgit-bootstrap-rollback
LeXwDeX Sep 3, 2026
e328a03
chore: record delivery binding for specgit-branch-type-preflight
LeXwDeX Sep 3, 2026
f08de04
chore: record delivery binding for specgit-branch-type-preflight
LeXwDeX Sep 3, 2026
d162166
fix(specgit): reject unsupported branch types
LeXwDeX Sep 3, 2026
06e0957
Merge pull request #534 from LeXwDeX/feat/529-specgit-branch-type-pre…
LeXwDeX Sep 3, 2026
888d867
chore: record delivery binding for specgit-pr-base-dev
LeXwDeX Sep 3, 2026
ece348b
chore: record delivery binding for specgit-pr-base-dev
LeXwDeX Sep 3, 2026
cd6bcc1
fix(specgit): target delivery PRs at dev
LeXwDeX Sep 3, 2026
62a30ef
Merge pull request #535 from LeXwDeX/feat/528-specgit-pr-base-dev
LeXwDeX Sep 3, 2026
661ebf8
chore: record delivery binding for macos-integrity-boundary
LeXwDeX Sep 3, 2026
d28250a
chore: record delivery binding for macos-integrity-boundary
LeXwDeX Sep 3, 2026
54ad103
fix(release): separate macOS integrity boundaries
LeXwDeX Sep 3, 2026
28f14d2
Merge pull request #536 from LeXwDeX/feat/498-macos-integrity-boundary
LeXwDeX Sep 3, 2026
d5f2ba9
chore: record delivery binding for event-retention-reclamation
LeXwDeX Sep 4, 2026
743d99f
chore: record delivery binding for event-retention-reclamation
LeXwDeX Sep 4, 2026
93341c1
chore: record delivery binding for native-tool-settlement
LeXwDeX Sep 4, 2026
8b76952
chore: record delivery binding for native-tool-settlement
LeXwDeX Sep 4, 2026
1d37a58
fix(session): settle native tools before compaction
LeXwDeX Sep 4, 2026
8d99729
docs(release): describe native tool settlement and integrated fixes
LeXwDeX Sep 4, 2026
4508e67
chore: record delivery binding for native-tool-settlement
LeXwDeX Sep 4, 2026
43894ec
test(core): isolate local npm fixtures from online audit
LeXwDeX Sep 4, 2026
e03ad87
test(session): share native compaction processor setup
LeXwDeX Sep 4, 2026
93959af
chore: reconcile native tool delivery with dev
LeXwDeX Sep 4, 2026
dbc0fab
docs(adr): accept #524 residue scrub and sqlite reclamation decision
LeXwDeX Sep 4, 2026
16c86e3
feat(core): reclaim deleted event aggregates
LeXwDeX Sep 4, 2026
fd4c769
test(core): disable npm audit in install fixtures
LeXwDeX Sep 4, 2026
2a9dac6
test(opencode): pin database vacuum help
LeXwDeX Sep 4, 2026
e37d805
test(opencode): terminate MCP process probe
LeXwDeX Sep 4, 2026
da0f73f
Merge pull request #537 from LeXwDeX/feat/524-event-retention-reclama…
LeXwDeX Sep 4, 2026
82df444
chore: record delivery binding for preserve-npm-lock
LeXwDeX Sep 4, 2026
e4fb342
chore: record delivery binding for preserve-npm-lock
LeXwDeX Sep 4, 2026
e91b508
fix(core): preserve npm lock for local plugin SDK
LeXwDeX Sep 4, 2026
8060765
Merge pull request #542 from LeXwDeX/feat/541-preserve-npm-lock
LeXwDeX Sep 4, 2026
00695da
chore(release): reconcile native fix with dev
LeXwDeX Sep 4, 2026
711e7b5
Merge pull request #539 from LeXwDeX/fix/538-native-tool-settlement
LeXwDeX Sep 4, 2026
28461ee
chore: record delivery binding for stable-release
LeXwDeX Sep 4, 2026
3100332
chore: record delivery binding for stable-release
LeXwDeX Sep 4, 2026
0e6c95c
docs(release): record accepted v1.0.40 evidence
LeXwDeX Sep 4, 2026
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
53 changes: 53 additions & 0 deletions .github/releases/v1.0.40.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
## opencode {VERSION}

{Prerelease/Stable} release from `{branch}` branch. Native LLM requests now settle local tools before automatic compaction can close the stream. This release also includes the reviewed event-storage, summary-diff, delivery, and macOS installer fixes already integrated into dev.

---

### 🐛 Bug Fixes

- **Tools survive automatic compaction, #539**: a high-usage `step-finish` could abort a slow local tool before its result reached the session processor. Native LLM now delivers all local tool results before terminal events. Parallel tools settle completely; explicit user cancellation still interrupts execution.
- **Summary diffs retain later small entries, #526**: skip an oversized diff individually instead of dropping every following entry. Remove the unused legacy `session.summary_diffs` column through a tested database migration.
- **Identical durable events no longer consume storage or sequence numbers, #527**: suppress byte-identical fresh appends within the same aggregate/type while preserving explicit-sequence replay. Batch results retain input alignment; legacy rows require no hash backfill.
- **Config startup preserves npm lock files, #542**: keep an existing lock unchanged when the plugin SDK resolves entirely from local or bundled packages. Mixed registry requests and genuine package changes still regenerate the lock.

---

### 🏗️ Architecture / Refactor

- **Deleted-session storage reclamation, #537**: remove durable event residue for deleted aggregates, wire cleanup into session deletion, and add tested SQLite reclamation support. This release does not run the deferred #531 maintenance operation on the user's existing database.

---

### ⚙️ CI / Engineering

- **Delivery tracking, #520 and #532 through #535**: close linked issues after dev merges, preserve repository-specific SpecGit harness files, restore failed bootstrap state, reject unsupported branch types before remote writes, and verify that delivery PRs target dev.
- **macOS installation verification, #536**: verify release archive checksums before extraction and validate the installed binary's signature after quarantine clearing and re-signing. Added a negative checksum control and a real macOS installation acceptance test.
- **Local npm fixture isolation, #540**: keep real package-installation regressions independent of online vulnerability-audit latency while retaining their assertions and deadlines.

---

### 🧪 Test Summary

```
Release integration CI (PR #539, 00695dab86):
core: 1225 pass, 6 skip, 0 fail
opencode: 4429 pass, 23 skip, 1 todo, 0 fail
HttpAPI coverage / auth / effect: 230 pass each, no failures or missing routes
Generated client and SDK freshness: passed
Typecheck, DAG core gate, Linux and Windows E2E: passed

Merged native/session/TUI regressions: 36 pass, 0 fail
Merged npm regressions: 8 pass, 0 fail
Merged opencode package typecheck: passed
```

---

### 🔍 Verification

The slow-tool regression was observed failing before the fix and passing afterward through the real session processor and a local HTTP model endpoint. Additional cases cover parallel local tools and explicit cancellation. Independent Standards, Spec and merge reviews found no code blockers. The integration statistics above come from the accepted [PR #539 CI](https://github.com/LeXwDeX/OpenCode-GraphAgent/actions/runs/33894718562), including generated client/SDK freshness and all three HttpAPI modes. [Typecheck, lint and DAG core](https://github.com/LeXwDeX/OpenCode-GraphAgent/actions/runs/33894718548), both E2E platforms and SpecGit 1.10.1 acceptance also passed before merge to dev. The release branch preserves that accepted runtime tree; [release PR #544](https://github.com/LeXwDeX/OpenCode-GraphAgent/pull/544) carries its own binding and main-targeted gates. Reported model usage in the regression is deterministic test input; no live model context limit is inferred from it.

---

**Full changelog:** [`{previous_tag}`...`{current_tag}`](https://github.com/LeXwDeX/OpenCode-GraphAgent/compare/{previous_tag}...{current_tag})
7 changes: 7 additions & 0 deletions .github/workflows/ci-typecheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@ jobs:
working-directory: packages/opencode
run: bun run test:dag-core
timeout-minutes: 10

# #498 B1: archive integrity boundary of the `oc` installer — SHA256SUMS
# must be verified before extraction and fail closed on mismatch.
# Zero network (stub curl); portable across bash hosts.
- name: Run oc install boundary tests
run: bash script/oc-install-boundary.test.sh
timeout-minutes: 5
98 changes: 98 additions & 0 deletions .github/workflows/dev-issue-autoclose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# ============================================================================
# 🧹 Dev · Issue Auto-Close
# ----------------------------------------------------------------------------
# Purpose: Mirror GitHub's native issue auto-close for PRs merged into `dev`.
# Native auto-close (`Closes #n` in the PR body) only fires when a PR
# merges into the DEFAULT branch (`main`). This repo delivers into
# `dev` first (two-tier Git Workflow), so dev-delivered issues would
# otherwise stay open until manual close (#433/#472/#496/#517 et al.).
# Trigger: `pull_request: types: [closed]`. The job-level `if` gates actual
# work to MERGED PRs whose base is `dev`; merges to `main` keep
# GitHub's native auto-close (no overlap).
# Jobs : autoclose — single Linux runner, pure event payload + `gh` CLI.
# No `actions/checkout`, no third-party actions. The PR body reaches
# the script ONLY via `env:` (script-injection safety); refs are
# matched case-insensitively against the official closing keywords
# followed by bare `#n` (plain-text scan of the whole body, matching
# GitHub's own scanner — refs inside fenced code blocks are included,
# best-effort native parity). Shared issue/PR number space guards:
# numbers resolving to a pull request are skipped, nonexistent
# numbers are skipped, already-CLOSED issues are skipped (no
# duplicate comments). Survivors are closed as `completed` with a
# comment naming the delivery PR.
# Notes : The whole matrix (extraction + guards) is exercised by the dry-run
# harness under /tmp/dev-issue-autoclose/ (see issue #519 evidence).
# Runs on every PR close event; non-dev or unmerged closes exit at
# the job-level `if` without consuming a runner step.
# ============================================================================

name: 🧹 Dev · Issue Auto-Close

on:
pull_request:
types: [closed]

permissions:
contents: read
issues: write
pull-requests: read

jobs:
autoclose:
name: Auto-close linked issues
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev'
runs-on: ubuntu-latest
steps:
- name: Close linked issues referenced in the PR body
env:
GH_TOKEN: ${{ github.token }}
PR_BODY: ${{ github.event.pull_request.body }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_URL: ${{ github.event.pull_request.html_url }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail

if [ -z "$PR_BODY" ]; then
echo "dev-issue-autoclose: PR #$PR_NUMBER has no body; nothing to do"
exit 0
fi

# Official closing keywords + bare #n, case-insensitive, deduped.
# Plain-text scan of the whole body (code fences included) mirrors
# GitHub's own scanner; qualified `owner/repo#n` and URL refs do not
# match (whitespace must sit directly before `#`).
refs=$(printf '%s' "$PR_BODY" \
| grep -oiE '\b(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)[[:space:]]+#[0-9]+\b' \
| grep -oE '#[0-9]+\b' \
| tr -d '#' \
| sort -nu \
|| true)

if [ -z "$refs" ]; then
echo "dev-issue-autoclose: PR #$PR_NUMBER body has no closing-keyword refs; nothing to do"
exit 0
fi

echo "dev-issue-autoclose: PR #$PR_NUMBER -> refs: $(echo "$refs" | tr '\n' ' ')"

for n in $refs; do
# Shared issue/PR number space: skip numbers that resolve to a PR.
if gh pr view "$n" --repo "$REPO" >/dev/null 2>&1; then
echo "dev-issue-autoclose: #$n is a pull request; skipping"
continue
fi
# Skip numbers that do not exist as issues.
if ! state=$(gh issue view "$n" --repo "$REPO" --json state --jq .state 2>/dev/null); then
echo "dev-issue-autoclose: #$n not found; skipping"
continue
fi
# Skip already-closed issues (no duplicate comments).
if [ "$state" = "CLOSED" ]; then
echo "dev-issue-autoclose: #$n is already CLOSED; skipping (no duplicate comment)"
continue
fi
gh issue close "$n" --repo "$REPO" --reason completed \
--comment "Auto-closed: delivery PR #$PR_NUMBER ([view]($PR_URL)) merged into \`dev\` with a closing keyword for #$n in its body. GitHub's native auto-close only fires on the default branch (\`main\`); this mirrors it for the dev integration layer ([#519](https://github.com/$REPO/issues/519))."
echo "dev-issue-autoclose: #$n closed (reason: completed) by delivery PR #$PR_NUMBER"
done
11 changes: 11 additions & 0 deletions .github/workflows/release-fork.yml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,17 @@ jobs:
fi
done

# #498 B2: macOS release acceptance — after the installer-style xattr +
# ad-hoc re-sign mutation, assert codesign validity and executable smoke.
# The installed binary's hash is intentionally NOT compared to the
# archive payload (ad-hoc re-signing can rewrite bytes, so byte equality
# is not a stable signature-validity boundary and differing hashes are
# legitimate); no post-sign digest.
- name: macOS Install Acceptance
if: matrix.name == 'macos' && (inputs.platforms == '' || contains(inputs.platforms, matrix.name))
run: bash script/oc-macos-acceptance.test.sh packages/opencode/dist/opencode-darwin-arm64.zip
timeout-minutes: 10

- name: Upload Artifacts
if: inputs.platforms == '' || contains(inputs.platforms, matrix.name)
uses: actions/upload-artifact@v4
Expand Down
10 changes: 5 additions & 5 deletions .specgit.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
version: 1
delivery: sync-v1-0-39
delivery: stable-release
context:
kind: branch
branch: chore/517-sync-v1-0-39
branch: chore/543-stable-release
issues:
- 517
- 543
issueKinds:
- issue: 517
- issue: 543
kind: kind::chore
pr: 518
pr: 544
11 changes: 10 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ feat/**, fix/** ──PR(Typecheck + Unit Tests 门禁)──▶ dev ──push
新功能开发、Debug 等一切交付范畴恒定走此循环;后续所有工作必须遵守该方案,不得另起流程:

1. **确立条目**:明确条目的内容、范围、类型(`feat`/`fix`/…)。一个 issue = 一个可独立验证的 WHY,无法独立验证的先拆分再立项。
2. **SpecGit 立项**:`specgit issue <title-or-number>` 创建/复用 issues 批次,确立交付分支与草稿 PR 脚手架(`.specgit.yaml` 绑定);立项前先查重,避免同一 WHY 双开。
2. **SpecGit 立项**:`script/specgit-bootstrap.sh <title-or-number>` 创建/复用 issues 批次,确立交付分支与草稿 PR 脚手架(`.specgit.yaml` 绑定);立项前先查重,避免同一 WHY 双开。wrapper 是 canonical 入口(见 "SpecGit harness local specializations");直跑裸 `specgit issue` 预期被 harness currency gate 以 `harness_stale` (exit 2) 拒绝
3. **超流执行**:安排 DAG workflow(超流)承载实现——并行开发 + 多角度 Review + 复合(synthesize),其产出作为交付证据基线。
4. **PR 过门禁**:SpecGit 发起/推进 PR,过 TDD 与 CI 门禁(Typecheck、Unit Tests、DAG gate;`specgit finish` exit 0 是唯一 "done")。
5. **修复门禁问题**:门禁失败在交付分支修代码/测试,永远不削弱门禁本身。
Expand Down Expand Up @@ -273,6 +273,15 @@ Kept OUTSIDE the managed block so `specgit init`/`--force` never rewrites them;
- The wait script hand-parses `spec_git/policy.yaml` (minimal line-based parse) instead of importing the `yaml` package: no root-reachable `yaml` exists under workspace catalog isolation, so `import { parse } from 'yaml'` would fail to resolve on the runner.
- `spec_git/policy.yaml` `required_checks` uses the template's canonical check IDs (`unit-tests`, `e2e-tests`), not display names.

#### specgit-bootstrap wrapper (canonical `specgit issue` entry, #521)

`script/specgit-bootstrap.sh <specgit issue args...>` is THE canonical way to run `specgit issue` in this repository. Bare `specgit issue` is expected to fail with `harness_stale` (exit 2) whenever the pinned CLI's harness template moves — the wrapper satisfies that gate safely: it snapshots the full init write surface to a temp dir outside the repo, runs `specgit init --force --no-protect` (hardcoded, offline), then `specgit issue "$@"` with arguments, exit status, and diagnostics passed through verbatim, and restores the specialized bytes above on success and every failure path (EXIT/INT/TERM/HUP), verifying each file byte-for-byte via `git hash-object`.

- Never run bare `specgit init --force` here: it overwrites the six specialized bytes; the wrapper exists to make that refresh transient.
- Fail-closed rejections: dirty write-surface paths (tracked/staged/untracked) → exit 2 with the offending paths listed; no SpecGit binding (`.specgit.yaml` or `spec_git/policy.yaml` missing) → exit 3; restore hash mismatch → exit 3 with the snapshot kept for forensics. Rejection paths print plain `specgit-bootstrap:` stderr lines and NEVER produce a `--json` envelope.
- The inner `.specgit.yaml` delivery record is rolled back to its pre-run bytes when the inner `specgit issue` exits nonzero (or a signal/init failure interrupts); a successful call keeps the new binding. Record-restore failure keeps the forensic snapshot and exits 3, overriding the inner exit code. Branches, commits, and remote side effects are never undone (#530).
- Managed-block guidance referencing bare `specgit issue` commands is superseded by this section for this repository. Behavior tests: `bash script/specgit-bootstrap.test.sh` (stubbed CLI, zero network; not CI-wired).

<!-- specgit:block:start -->
## SpecGit delivery harness

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ All upstream capabilities (multi-provider, built-in LSP, client/server architect

Prebuilt CLI binaries (Linux / macOS / Windows, with SHA256SUMS) are published on the [releases page](https://github.com/LeXwDeX/OpenCode-GraphAgent/releases). Builds from `main` are formal releases; builds from `dev` are prereleases.

Release acceptance enforces two distinct integrity boundaries:

- **Archive integrity (before extraction)**: the `oc` installer verifies the release `SHA256SUMS` entry before unpacking and refuses to extract on mismatch. If upstream serves no `SHA256SUMS`, it installs with a warning (GitHub HTTPS transport only).
- **Post-install signature validity (macOS)**: the installer clears quarantine attributes (`xattr -cr`) and ad-hoc re-signs (`codesign -fs -`); acceptance then asserts `codesign --verify` passes and the binary runs. The installed binary's hash is intentionally **not** compared to the archive payload — ad-hoc signing can rewrite the binary's bytes, so differing hashes are legitimate. No post-signature digest is published (cross-version reproducibility of codesign output has not been established, and no supported reproducibility matrix exists).

From source (requires [Bun](https://bun.sh) 1.3+):

```bash
Expand Down
5 changes: 5 additions & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ DAG 相关的东西都放在 `.opencode/` 下,在 opencode 配置目录(`OPE

预构建 CLI 二进制(Linux / macOS / Windows,附 SHA256SUMS)发布在 [releases 页面](https://github.com/LeXwDeX/OpenCode-GraphAgent/releases)。从 `main` 构建的是正式版;从 `dev` 构建的是预发布版。

发布验收维护两条相互独立的完整性边界:

- **归档完整性(解包前)**:`oc` 安装器在解包前校验 release 的 `SHA256SUMS` 条目,不匹配则拒绝解包。若上游未提供 `SHA256SUMS`,则告警后继续安装(仅依赖 GitHub HTTPS 传输安全)。
- **安装后签名有效性(macOS)**:安装器清除 quarantine 属性(`xattr -cr`)并做 ad-hoc 重签名(`codesign -fs -`),验收断言 `codesign --verify` 通过且二进制可执行。安装后的二进制 hash **有意**不与归档 payload 对比——ad-hoc 签名可能改写二进制字节,两者 hash 即使不同也属正常。也不发布签名后 digest(codesign 输出的跨版本可复现性尚未确立,亦无受支持的可复现性矩阵)。

从源码构建(需要 [Bun](https://bun.sh) 1.3+):

```bash
Expand Down
Loading
Loading