diff --git a/AGENTS.md b/AGENTS.md index ed2c835..dbc50ca 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -186,8 +186,10 @@ cya "your natural language request here" cya --help cya --explain-context "show me what context would be collected" -# Memory features (0003) +# Memory features (0003 + 0005) cya retrospect # Guided reflection session +# Current memory implementation is Profile 0 (see CYA-WP-0005 and MemoryVision "Profile 0 Baseline"). +# Future Profiles 1–3 (verbal self-improvement, hierarchical synthesis, procedural rules) are tracked in that workplan. # Tests python -m pytest tests/ -q diff --git a/MemoryVision.md b/MemoryVision.md index 448ad57..186b65e 100644 --- a/MemoryVision.md +++ b/MemoryVision.md @@ -133,6 +133,69 @@ See also the full research artifact and CYA-WP-0005 for acceptance criteria and --- +## Profile 0 Baseline (Post-0003 / Current Shipped) + +**Status:** Shipped and stable as the production memory implementation (CYA-WP-0002 T02 real JSON + CYA-WP-0003 contextual activation + retrospection extensions). This is the explicit foundation on which Profiles 1–3 will be built. + +**Guiding Principle (Profile 0):** Deliver real, user-controlled, contextually activated, longitudinally improving memory *today* using a high-quality local approximation, while keeping the integration seam (profile, kinds, activation_context, provenance, phase hints) completely stable and ready for eventual replacement by full phase-memory planners, graph store, and lifecycle rules. No hidden state; everything is user-inspectable and user-owned. + +### Backing Store & Persistence +- Location: `~/.config/cya/memory/.json` (one file per scope, default "cwd"). +- Format: Simple list of dict records. Fully human-readable and editable by the user. +- Fields per record (typical): `key`, `value`, `ts` (epoch), `scope`, `profile`, `kind`. +- User can `cat`, edit, or delete these files at any time; `cya` will respect the changes on next run. +- When full phase-memory is wired, this backing will be replaced by the durable graph/event store while preserving the exact same high-level port behavior and return shapes. + +### Public API (the stable cya ↔ phase-memory seam) +All entry points live in `src/cya/memory/__init__.py`: + +- **Constants** (standard kinds used by cya and `cya retrospect`): + - `KIND_PREFERENCE` + - `KIND_RETROSPECTION` + - `KIND_INTERACTION_GOAL` + +- **Core functions** (signatures as of 2026-05, all support `profile` for future multi-profile use): + - `remember_preference(key, value, scope="cwd", *, profile=None, ttl=None, kind=KIND_PREFERENCE)` + - `recall_preferences(scope="cwd", task_class=None, *, kinds=None, profile=None, limit=50, activation_context=None) -> dict` + - Returns: `{"items": [...], "provenance": [...], "phase": "fluid", "profile": ..., "note": "..."}` + - `forget(scope="cwd", keys=None, *, profile=None)` + - `export_memory(scope="cwd", *, profile=None, kinds=None) -> dict` (includes `by_kind` counts, `provenance_summary`, `phases` list) + - `remember_retrospection_outcome(...)` — convenience wrapper that chooses the right kind for higher-order memory from reflection sessions. + +**Activation logic (0003):** When `activation_context` (populated by the orchestrator from `ContextEnvelope` with `cwd` + git root) is supplied to `recall_preferences`, items whose `scope` or `profile` matches are boosted to the front of the result list. This makes directory/project-bound memory feel proactive without any user having to explicitly recall it. + +**Retrospection as first-class input (0003):** `cya retrospect` (guided flow) produces records with special kinds that receive preferential activation in future turns. These are the seed for the self-improving loop described in the 2026-05 research. + +**Guaranteed properties of every call:** +- Rich `provenance` array always present (source, count, activation_context, etc.). +- `phase` hint returned (currently always "fluid" for the local store; will become meaningful once phase-memory lifecycle is wired). +- Graceful degradation: on any error the ports log a loud warning to stderr and return safe empty/default values. Never crash the assistance path. +- All memory influence is visible via `--explain-context`. + +### Safety & Explainability Invariants (non-negotiable for Profile 0 and all future profiles) +- Memory signals are **only additive** to caution. They may append rationale or force confirmation in the rule-based `RiskClassifier`, but they never downgrade a risk level or bypass mandatory explicit user confirmation for non-SAFE commands. +- Every memory-influenced response can explain exactly which items were activated, why (activation_context match, kind boost, recency, retrospection provenance), and what phase they came from. +- Users can always opt out per-request (`--no-memory` or equivalent) or globally inspect/forget via the ports + future `cya memory` subcommands. + +### Usage Sites in the Current System +- `src/cya/orchestrator.py`: Calls `recall_preferences` with activation_context on every assistance request; injects results into the `ContextEnvelope` passed to the LLM; renders memory influence in `--explain-context` panels. +- `src/cya/cli/main.py` (retrospect subcommand): Uses `recall_preferences` + `remember_retrospection_outcome` to close the user-driven continuous optimization loop. +- Risk classifier: Receives memory context and applies only the "increase caution" rules. + +### Relationship to Profiles 1–3 and phase-memory +Profile 0 is deliberately a **complete, usable, production-quality local implementation** of the seam defined in the 0002 T01 contract (refined in 0003). It already delivers the INTENT/SCOPE vision for contextual + longitudinal memory with excellent explainability and zero hidden state. + +Future profiles will layer on top: +- Profile 1 adds verbal reflection storage + preferential activation (mostly a small delta on existing retrospection kinds + `cya retrospect`). +- Profile 2 adds episodic capture + synthesis passes (new kinds + calls into phase-memory reflection planners). +- Profile 3 adds procedural rules + meta-policy evolution (new tier + strong proposal/audit UX + safety guardrails). + +All of them must continue to satisfy the invariants above and must continue to work against the exact same port signatures (or compatible extensions). + +**See:** `history/2026-05-28-CYA-Agentic-Memory-Research-Variations.md` (research + mappings), CYA-WP-0005 T01–T03, `docs/cya-memory-activation-and-retrospection-concept.md`, current `src/cya/memory/__init__.py` (the reference implementation), and the 0002 integration contract below (the original seam that Profile 0 realizes). + +--- + ## cya ↔ phase-memory Integration Contract (CYA-WP-0002 T01) **Date:** 2026-05-26 (ralph iter 1) diff --git a/README.md b/README.md index 7d952b3..db570cf 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ Memory also feeds the safety layer: a "never auto-run" preference you set during - Activation is automatic based on cwd + git root (with full provenance). - Retrospection outcomes are stored with special kinds (`retrospection`, `interaction_goal`) and get preferential treatment in future context building. - Everything is designed to be replaced/enriched by a full `phase-memory` implementation later (see MemoryVision.md). +- Current implementation is formally **Profile 0** (post-0003 local JSON + activation + retrospection loop). See CYA-WP-0005 and the "Profile 0 Baseline" section in MemoryVision.md for the exact definition and the roadmap to Profiles 1–3 (self-improving verbal reflections, hierarchical synthesis, and procedural rules). See: - `docs/cya-memory-activation-and-retrospection-concept.md` (the T01 design) diff --git a/SCOPE.md b/SCOPE.md index 0842cb7..81ace2d 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -13,6 +13,7 @@ Four implementation slices have been delivered: - **CYA-WP-0001 (Console-Native MVP)**: Core CLI, bounded context collection, rule-based safety with mandatory confirmation, LLMAdapter Protocol seam, basic orchestrator. - **CYA-WP-0002 (Memory Integration)**: Real user-controlled, persisting memory (scoped JSON) behind explicit ports, wired into context and safety. - **CYA-WP-0003 (Contextual Activation & Retrospection)**: Directory/project-bound automatic memory activation, `cya retrospect` guided reflection sessions, retrospection outcomes feeding future behavior (continuous user-driven optimization loop). +- **Profile 0 baseline (post-0003, formalized in CYA-WP-0005 T02)**: The current shipped memory implementation (local JSON + kinds + activation_context + provenance + retrospection helper) is now explicitly documented as **Profile 0** — the stable, high-quality foundation for future self-improving profiles 1–3. See MemoryVision.md for the full baseline description. - **CYA-WP-0004 (Dev-Head Install & Release Packaging)**: Reliable installation from development head (`make dev-install`, direct `git+` installs), dynamic versioning via `setuptools_scm`, clean distribution package building (`python -m build` + verification), lightweight release process, and supporting documentation/Makefile. Core capabilities now include: @@ -20,9 +21,9 @@ Core capabilities now include: - Bounded, transparent local context collection. - Genuine rule-based (memory-aware) risk classification with mandatory confirmation. - Stable `LLMAdapter` Protocol. -- Real, user-controlled, contextually activated memory (directory/project scoped) with retrospection support. +- Real, user-controlled, contextually activated memory (Profile 0: directory/project scoped local JSON with kinds, activation_context, provenance, and retrospection outcomes as higher-order memory). - Automatic memory activation based on working directory/git root. -- `cya retrospect` for structured reflection and goal setting. +- `cya retrospect` for structured reflection and goal setting (the seed of the continuous optimization loop). - Full developer workflow: dev-head install, testing, building distribution packages, and a documented release process. - Transparent, inspectable behavior via `--explain-context`. diff --git a/src/cya/memory/__init__.py b/src/cya/memory/__init__.py index 91f160d..49b6a47 100644 --- a/src/cya/memory/__init__.py +++ b/src/cya/memory/__init__.py @@ -1,18 +1,29 @@ -"""phase-memory ports (T05 → T02) — cya seam to phase-memory (markitect). +"""phase-memory ports — cya seam to phase-memory (markitect). -See CYA-WP-0002 T01 contract in MemoryVision.md for full details. This module is the explicit, inspectable boundary. All memory for -assistance (preferences, project context, etc.) flows through here. +assistance (preferences, project context, retrospection outcomes, etc.) +flows through here. -Current state (T01 complete): signatures refined per phase-memory -architecture (phases: ephemeral/fluid/stabilized/rigid; kinds incl. -preference; planners for lifecycle/activation; low-level ports: -MemoryGraphStore, MemoryEventLog, PolicyGateway, etc.). Implementations -remain no-op + loud warn until T02 wires real delegation. +**Profile 0 (current shipped baseline, post CYA-WP-0003):** +Real user-controlled local JSON backing (~/.config/cya/memory/.json) +with full support for kinds (preference, retrospection, interaction_goal), +activation_context (cwd + git root boosting), provenance in every return, +remember_retrospection_outcome helper, by_kind export, and graceful +degradation. This already delivers contextual activation and a continuous +user-driven optimization loop via `cya retrospect`. -Operator direction (2026-05): keep the seam minimal and replaceable; -no hidden stores, full explainability via provenance + dry-run plans -in recall results. +See: +- MemoryVision.md → "Profile 0 Baseline (Post-0003)" section for the + complete description of the current implementation and invariants. +- CYA-WP-0005 (especially T02) for formalization of this as the stable + foundation for Profiles 1–3. +- CYA-WP-0002 T01 contract (below in this file's history + MemoryVision) + for the original seam definition. + +The public API signatures are stable. Future phase-memory integration will +replace the local JSON backing and add planners/synthesis/procedural support +while preserving (or compatibly extending) this surface and all +explainability/safety guarantees. """ from __future__ import annotations diff --git a/src/cya/orchestrator.py b/src/cya/orchestrator.py index 825e2f0..17d46fa 100644 --- a/src/cya/orchestrator.py +++ b/src/cya/orchestrator.py @@ -1,20 +1,24 @@ -"""Assistance orchestrator (T06). +"""Assistance orchestrator. The piece that turns raw user intent + collected context into a well-formed -request for the LLM adapter (T04), then turns the adapter response into the +request for the LLM adapter, then turns the adapter response into the final terminal output the user sees. -Responsibilities in this slice: -- Own the end-to-end happy path after Typer argument parsing. -- Coordinate context collector (T02), risk classifier (T03), and LLMAdapter (T04). -- Keep the CLI surface (main.py) thin — it should only do argument parsing, - help/version, and delegation to this orchestrator. -- Be testable in isolation with the FakeLLMAdapter (critical for T07). +Key responsibilities: +- Coordinate context collector, memory (Profile 0 via recall with activation_context), + rule-based risk classifier, and LLMAdapter. +- Wire memory influence into every assistance cycle and `--explain-context`. +- Own the `cya retrospect` flow that feeds higher-order memory back into the system. +- Keep the CLI surface thin. -This module is the natural home for future prompt framing, context packing -with token awareness, safety charter injection, and response post-processing. +**Memory note (Profile 0):** This module is the primary consumer of the +stable memory ports defined in src/cya/memory/__init__.py. All calls use +activation_context derived from the current working directory + git root. +See MemoryVision.md "Profile 0 Baseline" and CYA-WP-0005 for the evolution +path to Profiles 1–3. -See workplan CYA-WP-0001-T06. +See workplan CYA-WP-0001 (core) + CYA-WP-0003 (memory wiring + retrospect) ++ CYA-WP-0005 (profile formalization). """ from __future__ import annotations diff --git a/tests/test_memory.py b/tests/test_memory.py index 8725ccc..4691c98 100644 --- a/tests/test_memory.py +++ b/tests/test_memory.py @@ -167,6 +167,39 @@ def test_recall_with_kinds_and_activation_context(isolated_memory): assert KIND_INTERACTION_GOAL in kinds or "retrospection" in kinds +# --------------------------------------------------------------------------- +# CYA-WP-0005 T02 — Explicit Profile 0 baseline assertions +# --------------------------------------------------------------------------- +# These tests document and assert the characteristics of the current shipped +# memory implementation, now formally named "Profile 0" (see MemoryVision.md +# "Profile 0 Baseline (Post-0003)" and CYA-WP-0005). +# All future profiles (1–3) must continue to satisfy these behaviors / invariants +# while layering on synthesis, procedural rules, etc. + +def test_profile_0_provenance_and_note_markers(isolated_memory): + """Profile 0 must always surface its local JSON nature and T02+0003 heritage in observability.""" + remember_preference("p0_marker", "value", scope="p0-test") + + data = recall_preferences(scope="p0-test") + prov = data.get("provenance", [{}])[0] + note = data.get("note", "") + + assert "cya-local-memory" in prov.get("source", "") + assert "T02+0003" in prov.get("source", "") or "local json" in note.lower() + assert data.get("phase") == "fluid" + + +def test_profile_0_kinds_and_activation_context_supported(isolated_memory): + """Profile 0 fully supports the seam used by Profiles 1–3 (kinds + activation_context).""" + remember_retrospection_outcome("p0_retro", "remember this pattern", scope="p0-proj") + act = {"cwd": "p0-proj", "profile": "default"} + + data = recall_preferences(scope="p0-proj", kinds=["retrospection"], activation_context=act) + + assert len(data["items"]) >= 1 + assert data.get("activation_context") is None or isinstance(data.get("provenance"), list) # provenance always present + + # --------------------------------------------------------------------------- # T04 (0003) — Retrospection outcome tests # --------------------------------------------------------------------------- diff --git a/workplans/CYA-WP-0005-agentic-memory-profiles-and-phase-memory-feedback.md b/workplans/CYA-WP-0005-agentic-memory-profiles-and-phase-memory-feedback.md index ba10ced..2e05442 100644 --- a/workplans/CYA-WP-0005-agentic-memory-profiles-and-phase-memory-feedback.md +++ b/workplans/CYA-WP-0005-agentic-memory-profiles-and-phase-memory-feedback.md @@ -72,9 +72,11 @@ completed: "2026-05-28 ralph iter 1" ```task id: CYA-WP-0005-T02 -status: todo +status: done priority: high state_hub_task_id: "669c0d9e-f2ba-4655-a0b9-c104f5545859" +started: "2026-05-28 ralph iter 2" +completed: "2026-05-28 ralph iter 2" ``` **Description**: Treat the current post-0003 memory implementation (local JSON, kinds, activation_context, retrospection helper, provenance, safety integration, `cya retrospect`) as **Profile 0**. Document it clearly so Profiles 1–3 have a stable "from here" point. Update all relevant docs and code headers.