Skip to content

fix: make memory opt-in and preserve pressure compaction - #580

Merged
pedronauck merged 2 commits into
mainfrom
fix/issue-561-memory-opt-in-extractor
Sep 9, 2026
Merged

pedronauck merged 2 commits into
mainfrom
fix/issue-561-memory-opt-in-extractor

Conversation

@pedronauck

@pedronauck pedronauck commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

What & why

Fixes #561.

CompozyOS is a control plane. Starting a daemon or completing an ordinary turn should not opt an operator into persistent memory extraction or background dreaming. memory.enabled and the existing independent roles.dream.enabled now default to false. To opt in, set [memory] enabled = true in the daemon configuration and restart; enable [roles.dream] enabled = true separately for dreaming. Existing explicit settings retain their meaning, and no user configuration or stored memory is rewritten or deleted.

The opt-in path is also repaired. Previously, the extractor discarded the entire JSONL batch on its first invalid line, treated common no-memory answers as parse failures, and stopped the child with a misleading completion detail before parsing was accounted for. The timeout reported in the issue is a separate execution deadline, not a JSON-parser consequence.

  • The prompt requests {"no_candidates":true}. Conventional empty answers, an empty array, and JSONL fences are handled deliberately. Unknown prose and malformed candidates remain line-numbered failures.
  • Valid candidates survive a mixed batch and reach the existing inbox/controller. The batch records memory.extractor.failed, not a false completed event.
  • A successful semantic terminal is required before candidate admission. Interrupted/error output remains in redacted diagnostics; cancellation, truncation, or missing terminal is a failure.
  • Child stop causes distinguish parsed output, extraction failure, and timeout. Extraction-stage failures enter the existing DLQ and failure listing with parent session/workspace/agent identity and redacted diagnostics. Raw model output cannot be replayed as a normalized candidate inbox.
  • Session pressure compaction remains under session.compaction.enabled, independently of persistent memory. Factory boot retains private checkpoint WAL storage and resume-only coverage. Only actual pressure can launch its summary child; no public memory provider or session-end worker is registered. An explicit checkpoint-role opt-out or failed summary leaves uncovered events unarchived.
  • Public background-role status and invocation use the same daemon/workspace memory gate. Effective memory roles honor the memory switch. Dream eligibility is checked before consolidation gates or state-changing work; enabling memory alone leaves dreaming off, and enabled runtime instances retain live/workspace dream routing.

How you verified it

Implemented and reviewed with Codex, GPT-6-Astra, high reasoning. Checked head: 5e90cd6.

  • Reproduced the original parser defect using a Go source overlay and the same canonical output-contract test: invalid N/( responses and loss of valid candidates around malformed output. The fixed cases passed with -race.
  • Full config, extractor, and consolidation suites passed. Capped daemon reruns covered changed extractor, role, and lifecycle behavior. An unchanged boot-barrier timeout under shared host load passed its standalone retry without changing the deadline or assertions.
  • Canonical checkpoint/compaction suites passed, including factory-role suppression, rejection of uncovered disabled-summary requests, session hook/archive behavior, and crash-safe compaction integration. Scope detail is in the QA report below.
  • Real daemon/ACP-subprocess E2E verified zero default extractor/dream sessions and extraction events, opted-in no-candidate success, persistence of a valid candidate beside malformed output, HTTP failure identity, CLI extractor status, UDS drain/trigger behavior, deliberate built-in/workspace dreaming, live model application, catalog parity, and next-session recall.
  • Factory boot + pressure + ACP disconnect/recovery passed (9.770 s; package 11.925 s): one pressure summary child, covered archive, retained history, checkpoint-backed replay without raw duplication, and no background memory children.
  • Existing skills-only daemon boot integration verified current shared schema-stream heads while memory remains disabled.
  • Review remediation race checks passed: daemon roles/extractor/checkpoints (6.990 s), core/HTTP/UDS health and settings. Active-memory health fixtures explicitly opt in, preserving all original assertions.
  • The owner generator go run ./cmd/compozy-codegen all completed without generated drift.
  • The initial local make gate found a trailing blank line, which was corrected. The owner explicitly requested publication with the full gate delegated to CI; a clean full local gate is not claimed. All required CI checks remain delivery requirements.

Final heavy checks used GOMAXPROCS=4, COMPOZY_GO_TEST_P=1, and COMPOZY_GO_LINT_CONCURRENCY=2 through mise exec. Manual Go tests retained -race -p=1 -parallel=4; integration also used the repository's modernc checkptr setting. The E2E runner acquired the repository's machine-wide verification lock. The short isolated lab used 57-byte daemon and at-most-88-byte harness sockets. Both labs completed targeted teardown with clean: true. The strict QA audit has one remaining criterion, C14 (full local gate), delegated to CI by the owner; it found zero other blockers or warnings.

QA evidence and cross-surface audit.

Impact

Existing keys, CLI verbs, HTTP/UDS routes, native tool IDs, and response shapes remain. Global/profile/workspace configuration precedence is retained under the daemon memory master switch. No SQLite shape or migration changes are required; disabled boot still applies memory schema migrations. This preserves SD-013 user state and public-surface compatibility while intentionally changing omitted defaults.

Site configuration/memory references, the official Compozy skill reference, affected QA scenarios, and a release note co-ship. Web uses the existing controls and contracts. Retrieval algorithms (#562) and startup tool-manual policy (#563) are unchanged.

Limits: deterministic ACP fixtures prove daemon/process/protocol behavior, not live-provider reliability or timeout frequency. Provider-native compaction was not exercised; the factory pressure/resume check exercises Compozy checkpoint coverage and degraded replay.


  • Full local gate delegated to CI at the owner's explicit request; required current-head CI checks must pass before delivery
  • New or changed behavior is covered by tests, or I explained above why not
  • If an agent wrote or co-wrote this, I named it above and verified the result myself

@vercel

vercel Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
compozy-site Ready Ready Preview Sep 9, 2026 5:28pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 16 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 8 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 855e7c37-877f-4a29-873b-6d657a1ce07f

📥 Commits

Reviewing files that changed from the base of the PR and between 9b422f1 and 5e90cd6.

⛔ Files ignored due to path filters (11)
  • .release-notes/memory-opt-in-extractor-1788969402.md is excluded by !**/*.md
  • docs/qa/reports/2026-09-09-issue-561-memory-opt-in.md is excluded by !**/*.md
  • docs/qa/scenarios/MS-016.md is excluded by !**/*.md
  • docs/qa/scenarios/MS-019.md is excluded by !**/*.md
  • docs/qa/scenarios/RT-migrate-memory-stream-when-disabled.md is excluded by !**/*.md
  • docs/qa/scenarios/RT-pressure-context-compaction.md is excluded by !**/*.md
  • packages/site/content/docs/configuration/config-toml.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/memory/dream.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/memory/index.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/memory/system.mdx is excluded by !**/*.mdx
  • skills/compozy/references/memory.md is excluded by !**/*.md
📒 Files selected for processing (49)
  • internal/api/core/handler_edge_cases_test.go
  • internal/api/core/memory_workspace_test.go
  • internal/api/httpapi/memory_test.go
  • internal/api/udsapi/memory_test.go
  • internal/config/config_memory_defaults.go
  • internal/config/config_test.go
  • internal/config/memory_v2_config_test.go
  • internal/config/merge_test.go
  • internal/config/roles.go
  • internal/config/roles_test.go
  • internal/daemon/boot.go
  • internal/daemon/boot_checkpoint.go
  • internal/daemon/boot_memory_catalog.go
  • internal/daemon/boot_memory_session.go
  • internal/daemon/boot_publish.go
  • internal/daemon/checkpoint_summary_runtime.go
  • internal/daemon/checkpoint_summary_summarizer.go
  • internal/daemon/checkpoint_summary_summarizer_test.go
  • internal/daemon/compaction_resume_integration_test.go
  • internal/daemon/composed_assembler.go
  • internal/daemon/daemon_memory_e2e_integration_test.go
  • internal/daemon/daemon_runtime_state.go
  • internal/daemon/daemon_shutdown_resources.go
  • internal/daemon/daemon_test.go
  • internal/daemon/memory_extractor_failure.go
  • internal/daemon/memory_extractor_fork.go
  • internal/daemon/memory_extractor_output.go
  • internal/daemon/memory_runtime.go
  • internal/daemon/memory_runtime_test.go
  • internal/daemon/role_fallback.go
  • internal/daemon/role_fallback_test.go
  • internal/daemon/role_resolver.go
  • internal/daemon/role_resolver_integration_test.go
  • internal/daemon/role_resolver_test.go
  • internal/daemon/role_status.go
  • internal/daemon/role_status_test.go
  • internal/daemon/runtime_dream_dependencies.go
  • internal/memory/checkpoint_summary.go
  • internal/memory/checkpoint_summary_test.go
  • internal/memory/checkpoint_summary_update.go
  • internal/memory/consolidation/runtime.go
  • internal/memory/consolidation/runtime_test.go
  • internal/memory/consolidation/runtime_trigger.go
  • internal/memory/contract/types.go
  • internal/memory/extractor/runtime_process.go
  • internal/memory/extractor/runtime_test.go
  • internal/memory/prompts/extract.v1.tmpl
  • internal/settings/service_test.go
  • internal/testutil/e2e/config_seed.go

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR makes persistent memory and dreaming explicit opt-ins while preserving pressure-triggered session compaction independently. The latest remediation:

  • Requires a semantic successful terminal event before extractor output can be admitted.
  • Preserves interrupted partial output only as failure diagnostics.
  • Applies the effective memory master gate consistently to role invocation and public role status.
  • Adds API, daemon, and end-to-end regression coverage for disabled defaults, interrupted extraction, and pressure compaction.

Confidence Score: 5/5

The PR appears safe to merge because both previous findings are now resolved and no actionable regression was identified in the latest changes.

The previously outstanding extractor finding is fully fixed: channel closure without a terminal event now fails, unsuccessful stop reasons are rejected, and partial output is retained only for diagnostics rather than candidate admission. The role-status finding was manually resolved and the current projection now shares the effective memory gate used by invocation.

Important Files Changed

Filename Overview
internal/daemon/memory_extractor_output.go Requires successful semantic termination and preserves partial output as diagnostics when extraction is interrupted.
internal/daemon/role_resolver.go Centralizes effective role enablement under the daemon and workspace memory gates while retaining the pressure-compaction exception.
internal/daemon/role_status.go Projects the same effective memory-role state used by runtime invocation.
internal/daemon/daemon_memory_e2e_integration_test.go Adds runtime coverage for role status and terminal-less extractor failure without candidate persistence.
docs/qa/reports/2026-09-09-issue-561-memory-opt-in.md Records the review remediation and targeted regression evidence.

Reviews (2): Last reviewed commit: "fix: reject interrupted extraction and p..." | Re-trigger Greptile

Comment thread internal/daemon/memory_extractor_fork.go
Comment thread internal/daemon/role_resolver.go Outdated
@pedronauck
pedronauck merged commit 246b7ab into main Sep 9, 2026
44 of 48 checks passed
@pedronauck
pedronauck deleted the fix/issue-561-memory-opt-in-extractor branch September 9, 2026 17:39
@pedronauck pedronauck mentioned this pull request Sep 9, 2026
This was referenced Sep 27, 2026

This branch was successfully deployed

1 active deployment
Preview — 5e90cd60 Deployed Sep 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory extractor fails every extraction when the child answers in prose: the JSONL parser rejects the whole batch on the first non-JSON line

1 participant