From ccc6d20eb5a327100cf3aefca768d0437ea19bb7 Mon Sep 17 00:00:00 2001 From: Lex Date: Tue, 8 Sep 2026 17:51:15 +0800 Subject: [PATCH 1/8] chore: record delivery binding for memory-activation --- .specgit.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.specgit.yaml b/.specgit.yaml index 4f88adecb..e764ad553 100644 --- a/.specgit.yaml +++ b/.specgit.yaml @@ -1,11 +1,11 @@ version: 1 -delivery: main-release-1042 +delivery: memory-activation context: - kind: branch - branch: chore/579-main-release-1042 + kind: worktree + label: delivery + branch: fix/581-memory-activation issues: - - 579 + - 581 issueKinds: - - issue: 579 - kind: kind::chore -pr: 580 + - issue: 581 + kind: kind::fix From a68014a6734572768b14ce549a5dea1cdf1261f2 Mon Sep 17 00:00:00 2001 From: Lex Date: Tue, 8 Sep 2026 17:51:24 +0800 Subject: [PATCH 2/8] chore: record delivery binding for memory-activation --- .specgit.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.specgit.yaml b/.specgit.yaml index e764ad553..5175e4629 100644 --- a/.specgit.yaml +++ b/.specgit.yaml @@ -9,3 +9,4 @@ issues: issueKinds: - issue: 581 kind: kind::fix +pr: 582 From f7fa89547d60755a2ff801e885f7b7051cdb5a13 Mon Sep 17 00:00:00 2001 From: Lex Date: Tue, 8 Sep 2026 17:55:41 +0800 Subject: [PATCH 3/8] fix(memory): finish activation after init self-heal --- packages/opencode/src/memory/memory.ts | 11 ++++-- .../memory/memory-init-stamp-selfheal.test.ts | 39 +++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/packages/opencode/src/memory/memory.ts b/packages/opencode/src/memory/memory.ts index eddb46639..05c7b2fe7 100644 --- a/packages/opencode/src/memory/memory.ts +++ b/packages/opencode/src/memory/memory.ts @@ -841,7 +841,10 @@ export const layer: Layer.Layer< const setEnabledUnsafe = Effect.fn("Memory.setEnabledUnsafe")(function* (enabled: boolean) { const initial = yield* configuration() - if (!initial) { + // statusReason can repair a missing init stamp. Re-read before deciding + // activation is blocked so this same command can enable or repair the model. + const ready = initial ?? (enabled ? yield* statusReason().pipe(Effect.andThen(configuration)) : undefined) + if (!ready) { if (!enabled) return "Memory remains off" // #350: a /memory on that cannot activate must say WHY โ€” the bare // "remains off" sent users to guess (real case: an initialized git @@ -849,11 +852,11 @@ export const layer: Layer.Layer< // disabled Memory). return (yield* statusReason()) ?? "Memory remains off" } - const value = initial.loaded - ? initial + const value = ready.loaded + ? ready : yield* Effect.gen(function* () { yield* initUnsafe() - return (yield* configuration()) ?? initial + return (yield* configuration()) ?? ready }) if (!value.loaded) return "Memory remains off" as const const loaded = value.loaded diff --git a/packages/opencode/test/memory/memory-init-stamp-selfheal.test.ts b/packages/opencode/test/memory/memory-init-stamp-selfheal.test.ts index 19df6842c..9cab14312 100644 --- a/packages/opencode/test/memory/memory-init-stamp-selfheal.test.ts +++ b/packages/opencode/test/memory/memory-init-stamp-selfheal.test.ts @@ -76,6 +76,42 @@ const layer = Layer.mergeAll(Memory.layer.pipe(Layer.provideMerge(base)), CrossS const it = testEffect(layer) describe("memory /init stamp self-heal", () => { + for (const configured of ["missing", "disabled", "unavailable-model"]) { + it.live( + `first enable completes after self-healing with ${configured} project config`, + () => + Effect.gen(function* () { + const dir = yield* tmpdirScoped({ git: true }) + yield* provideInstance(dir)( + Effect.gen(function* () { + const project = yield* Project.Service + const memory = yield* Memory.Service + const config = yield* MemoryConfig.Service + const { project: info } = yield* project.fromDirectory(dir) + fs.writeFileSync(path.join(info.worktree, "AGENTS.md"), "# project guide\n") + if (configured !== "missing") { + yield* config.writeProject(info.worktree, { + schema_version: 1, + enabled: configured === "unavailable-model", + model: configured === "unavailable-model" ? "missing/model" : "openai/gpt-5.2", + topic_limit: 10, + turn_interval: 5, + injection: { max_topics: 3, max_tokens: 1_200 }, + }) + } + + expect(yield* memory.setEnabled(true)).toBe("Memory on") + expect((yield* project.get(info.id))?.time.initialized).toBeDefined() + expect((yield* config.load(info.worktree))?.config.enabled).toBe(true) + expect((yield* config.load(info.worktree))?.config.model).toBe("openai/gpt-5.2") + expect(yield* memory.status()).toBe("Memory on") + }), + ).pipe(Effect.provide(testInstanceStoreLayer)) + }), + { timeout: 30_000 }, + ) + } + it.live( "statusReason stamps the project when AGENTS.md already exists", () => @@ -117,6 +153,9 @@ describe("memory /init stamp self-heal", () => { const reason = yield* memory.statusReason() expect(reason).toContain("/init") + expect(yield* memory.setEnabled(true)).toContain("/init") + expect(yield* memory.setEnabled(false)).toBe("Memory remains off") + expect((yield* project.get(info.id))?.time.initialized).toBeUndefined() // #415 diagnostics: the blocker carries the actual row state so a // stale identity (worktree pointing at a deleted clone) is visible. expect(reason).toContain("time_initialized") From 3b0d9da982865a90d892523ac4c704aed5ef6160 Mon Sep 17 00:00:00 2001 From: Lex Date: Tue, 8 Sep 2026 17:57:42 +0800 Subject: [PATCH 4/8] docs: prepare memory activation release notes --- .github/releases/v1.0.43.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/releases/v1.0.43.md diff --git a/.github/releases/v1.0.43.md b/.github/releases/v1.0.43.md new file mode 100644 index 000000000..10124042c --- /dev/null +++ b/.github/releases/v1.0.43.md @@ -0,0 +1,32 @@ +## opencode {VERSION} + +{Prerelease/Stable} release from `{branch}` branch. Memory can now be enabled on the first request after repairing a missing project initialization stamp. + +--- + +### ๐Ÿ› Bug Fixes + +- **Memory activation**: when a git project already has a non-empty AGENTS.md but its initialization stamp is missing, `/memory on` now repairs the stamp and completes activation in the same request. Missing configuration, disabled configuration, and an unavailable configured model follow the normal initialization and model-reselection paths. Projects without initialization evidence remain blocked ([#581](https://github.com/LeXwDeX/OpenCode-GraphAgent/issues/581)). + +--- + +### ๐Ÿงช Test Summary + +``` +Memory, search, server wiring: 116 pass, 0 fail +Activation regression: 5 pass, 0 fail (included above) +opencode typecheck: passed +lint: 4846 warnings, 0 errors; existing 4850 cap unchanged +``` + +--- + +### ๐Ÿ” Verification + +Local verification used Bun 1.3.14. The activation regression failed before the fix and now checks the first command response, persisted enabled state, replacement model, initialization stamp, and subsequent status. An independent review reran the focused regression and inspected the controller, identity fence, locks, and generation-based persistence. The memory suite also covers admission, identity migration, cross-process persistence, search, model wire format, and production server dependency wiring. + +Integration and promotion require current-head CI and SpecGit acceptance. The release workflow validates reference templates and builds Linux, macOS, and Windows archives with SHA256SUMS. Real external model-provider quality and existing user memory content are outside this verification. + +--- + +**Full changelog:** [`{previous_tag}`...`{current_tag}`](https://github.com/LeXwDeX/OpenCode-GraphAgent/compare/{previous_tag}...{current_tag}) From 75286b13a672943ce96e1b922be1865d5887daf8 Mon Sep 17 00:00:00 2001 From: Lex Date: Wed, 9 Sep 2026 08:33:55 +0800 Subject: [PATCH 5/8] chore: record delivery binding for memory-release --- .specgit.yaml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.specgit.yaml b/.specgit.yaml index 5175e4629..3e9d0d3d5 100644 --- a/.specgit.yaml +++ b/.specgit.yaml @@ -1,12 +1,11 @@ version: 1 -delivery: memory-activation +delivery: memory-release context: kind: worktree - label: delivery - branch: fix/581-memory-activation + label: promotion + branch: chore/583-memory-release issues: - - 581 + - 583 issueKinds: - - issue: 581 - kind: kind::fix -pr: 582 + - issue: 583 + kind: kind::chore From c6460fa4dea4af707e5ea257d4359b110fe2d546 Mon Sep 17 00:00:00 2001 From: Lex Date: Wed, 9 Sep 2026 08:34:02 +0800 Subject: [PATCH 6/8] chore: record delivery binding for memory-release --- .specgit.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.specgit.yaml b/.specgit.yaml index 3e9d0d3d5..1f16da49f 100644 --- a/.specgit.yaml +++ b/.specgit.yaml @@ -9,3 +9,4 @@ issues: issueKinds: - issue: 583 kind: kind::chore +pr: 584 From b6535ed8773148494da9181af4fb3bbe320b3a41 Mon Sep 17 00:00:00 2001 From: Lex Date: Wed, 9 Sep 2026 08:35:04 +0800 Subject: [PATCH 7/8] docs: record memory release CI evidence --- .github/releases/v1.0.43.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/releases/v1.0.43.md b/.github/releases/v1.0.43.md index 10124042c..ad255a5de 100644 --- a/.github/releases/v1.0.43.md +++ b/.github/releases/v1.0.43.md @@ -15,7 +15,11 @@ ``` Memory, search, server wiring: 116 pass, 0 fail Activation regression: 5 pass, 0 fail (included above) -opencode typecheck: passed +CI opencode suite: 4574 pass, 0 fail, 23 existing skips, 1 existing todo +CI workspace typechecks: 29/29 passed +CI DAG coverage gate: 820 pass, existing coverage floors met +CI HttpAPI composite: 3 x 230 pass, 0 fail, 0 skip, 0 missing +CI E2E: Linux 21 pass; Windows 21 pass lint: 4846 warnings, 0 errors; existing 4850 cap unchanged ``` @@ -25,7 +29,9 @@ lint: 4846 warnings, 0 errors; existing 4850 cap unchan Local verification used Bun 1.3.14. The activation regression failed before the fix and now checks the first command response, persisted enabled state, replacement model, initialization stamp, and subsequent status. An independent review reran the focused regression and inspected the controller, identity fence, locks, and generation-based persistence. The memory suite also covers admission, identity migration, cross-process persistence, search, model wire format, and production server dependency wiring. -Integration and promotion require current-head CI and SpecGit acceptance. The release workflow validates reference templates and builds Linux, macOS, and Windows archives with SHA256SUMS. Real external model-provider quality and existing user memory content are outside this verification. +The CI counts above come from the accepted integration candidate `3b0d9da982` in [PR #582](https://github.com/LeXwDeX/OpenCode-GraphAgent/pull/582): [Typecheck and DAG gates](https://github.com/LeXwDeX/OpenCode-GraphAgent/actions/runs/34212878713), [unit, HttpAPI and E2E gates](https://github.com/LeXwDeX/OpenCode-GraphAgent/actions/runs/34212878737). Both Standards and Spec reviews found no blocking implementation findings, and SpecGit acceptance passed before dev integration. A compiled debug CLI also returned `Memory on` on the first request against a fresh isolated database and retained that status after process restart. + +Main promotion is separately gated by its current-head CI and SpecGit acceptance. The release workflow validates reference templates and builds Linux, macOS, and Windows archives with SHA256SUMS. Real external model-provider quality and existing user memory content are outside this verification. --- From 945466f4b77cd3ea81768541738e89942c3fae10 Mon Sep 17 00:00:00 2001 From: Lex Date: Wed, 9 Sep 2026 09:04:35 +0800 Subject: [PATCH 8/8] chore: record delivery binding for memory-release --- .specgit.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.specgit.yaml b/.specgit.yaml index 1f16da49f..c35fb919a 100644 --- a/.specgit.yaml +++ b/.specgit.yaml @@ -1,11 +1,11 @@ version: 1 delivery: memory-release context: - kind: worktree - label: promotion + kind: branch branch: chore/583-memory-release issues: - 583 + - 585 issueKinds: - issue: 583 kind: kind::chore