Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
054232c
📝 Add v0.1.3 write-planning execution plan, clippy validation rule, a…
ebigunso Jul 2, 2026
338cd2c
✨ Add public write-plan type surface for remember intake (prepare/val…
ebigunso Jul 2, 2026
820dd6b
✨ Add deterministic write-plan prepare helpers with UUIDv5 stable IDs
ebigunso Jul 2, 2026
d8c079b
✨ Add write-plan validator with provenance, link-target, and idempote…
ebigunso Jul 2, 2026
f243d31
📝 Record Wave 2 progress in v0.1.3 plan
ebigunso Jul 2, 2026
0e865f3
✨ Wire prepare/validate/commit write-plan path through facade with id…
ebigunso Jul 2, 2026
03961be
🧪 Add v0.1.3 write-planning acceptance integration tests
ebigunso Jul 2, 2026
cd30f5e
📝 Document prepare/validate/commit write path and record v0.1.3 imple…
ebigunso Jul 2, 2026
a532c7c
🐛 Enforce plan-declared vector targets at commit and address review f…
ebigunso Jul 2, 2026
913e4a1
📝 Record Waves 3-5 completion and review approval in v0.1.3 plan
ebigunso Jul 2, 2026
37d59bb
📝 Close out v0.1.3 plan with green CI evidence and stage review lessons
ebigunso Jul 2, 2026
006e89d
🐛 Fix repair-marker duplication, dead commit option, timestamp determ…
ebigunso Jul 2, 2026
72f58d0
🐛 Report full stats target set in outcomes and clarify idempotency-ke…
ebigunso Jul 3, 2026
162aaf6
📝 Record reboot resolution of local Qdrant idle-stall constraint
ebigunso Jul 3, 2026
7195c9d
🐛 Preserve plan-level validation errors on empty write plans and clar…
ebigunso Jul 3, 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
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ tokio = { version = "1.52.1", features = ["full"] }
async-trait = "0.1.86"

# Utils
uuid = { version = "1.23.1", features = ["v4", "serde"] }
uuid = { version = "1.23.1", features = ["v4", "v5", "serde"] }
chrono = { version = "0.4.44", features = ["serde"] }

[dev-dependencies]
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,27 @@ This is useful when you want to:
- make tests deterministic
- integrate another embedding API

## Write path

Character Memory separates planning from persistence. Use `prepare` to build an inspectable `RememberWritePlan`, `validate_plan` to check it against the current graph, and `commit` to persist it. `prepare` and `validate_plan` do not write graph objects, vector entries, retrieval statistics, or raw source data.

```rust
let input = RememberInput::new("caller-provided note or transcript reference");

let plan = memory.prepare(input, PrepareOptions::default()).await?;
let validation = memory.validate_plan(&plan).await?;

if validation.iter().all(|candidate| candidate.status == CandidateValidationStatus::Valid) {
let outcome = memory.commit(plan, CommitOptions::default()).await?;
}
```

`commit` revalidates the plan before writing. Graph-authoritative objects, links, provenance, lifecycle, and currentness are critical writes; vector indexing and retrieval-stat updates are repairable and are reported in `RememberOutcome`.

For callers that already have structured drafts, `remember(RememberDraft)` remains the convenience wrapper and routes through the same graph-authoritative commit machinery.

The write path is deliberately not an extraction system. Character Memory core does not infer preferences, commitments, corrections, character signals, thread membership, or entity identity from raw text. It does not store raw logs, and `raw_ref` values remain opaque caller-managed provenance pointers. Candidates in a `RememberWritePlan` are not memory until a valid plan is committed.

## Backends

The default implementation is backed by Qdrant and an Oxigraph HTTP service.
Expand Down
69 changes: 69 additions & 0 deletions docs/coding-agent/lessons.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,28 @@ Purpose:

## Entries

## 2026-07-03 - Skip-On-Stall Integration Tests Can Mask Unexecuted Bodies In Green Runs [tags: validation, ci]

Context:
- Plan: v0.1.3 remember intake write planning
- Task/Wave: Task_7 review / Task_4b re-review
- Roles involved: Reviewer | Orchestrator

Symptom:
- Integration tests that self-skip on the documented local Qdrant idle-stall report `ok`, so a green local target run can include tests whose bodies never executed.

Root cause:
- Skip-on-infra-stall is implemented as an early return inside the test body, invisible to the test harness result.

Fix applied:
- Reviewer performed targeted reruns of the specific tests under review and confirmed absence of skip messages; Linux CI remains the authoritative full-suite arbiter.

Prevention:
- When local evidence matters for a specific test, rerun it in a targeted invocation and confirm no skip message was printed for it. Treat aggregate green local runs with skip messages as incomplete evidence.

Evidence:
- Task_4b re-review confirmed full-body execution of all three new tests via targeted reruns; PR #55 CI green.

## 2026-07-03 - Qdrant Builder .timeout() Is A Server-Side Operation Parameter, Not A Client Bound [tags: tooling, validation]

Context:
Expand Down Expand Up @@ -63,6 +85,9 @@ Prevention:
- If guardrail/facade integration tests fail locally at the remember stage with vector_indexing_failure timeouts, run the canary test first; if it fails, treat the machine as affected and rely on CI instead of re-diagnosing.
- Re-run the canary after Docker Desktop, Windows, or network-stack updates to detect recovery or regression.

Resolution (2026-07-03):
- A full OS reboot resolved the condition. Immediately after boot the canary showed a transitional mode (post-idle upsert succeeded on retry in ~40s); after the system settled, the canary passes (<1s post-idle upsert) and the full local cargo test suite is green (guardrail tests 4.6s for all three, previously 45–70s each). Root cause remains unpinned but is confirmed to live in transient host networking state that survives Docker restarts and daemon recreation but not a reboot. If symptoms recur: run the canary, and reboot before deeper diagnosis.

Evidence:
- Full falsification matrix in the stabilization plan Decision Log (entries 2–6).

Expand All @@ -87,6 +112,50 @@ Prevention:

Evidence:
- Both overwritten Decision Log entries in the stabilization plan were restored in follow-up edits.
## 2026-07-02 - Use 127.0.0.1 Instead Of localhost For Local Qdrant gRPC [tags: tooling, validation]

Context:
- Plan: v0.1.3 remember intake write planning
- Task/Wave: Task_1 required validation
- Roles involved: Orchestrator | Worker

Symptom:
- Qdrant-backed integration tests hung to gRPC timeouts ("The operation was cancelled Timeout expired") or intermittent ConnectionRefused, while REST on 6333 responded in <100ms. One run crashed the Qdrant container (exit 255).

Root cause:
- `QDRANT_CONNECTION_STRING=http://localhost:6334` resolves to IPv6 `::1` inside tonic; the Docker Desktop port proxy accepts the TCP connect on `::1` but does not reliably forward HTTP/2 traffic, so gRPC calls stall until client timeout. `127.0.0.1` works instantly.

Fix applied:
- Pinned `QDRANT_CONNECTION_STRING=http://127.0.0.1:6334` in the local gitignored .env.

Prevention:
- Prefer `127.0.0.1` over `localhost` in local service connection strings for gRPC clients targeting Docker Desktop published ports on Windows.
- When gRPC times out but REST on the sibling port is fast, test IPv4 vs IPv6 connect paths before suspecting the service.

Evidence:
- initialization_tests: 30s timeout failure with localhost vs 10s pass with 127.0.0.1 override; unit suite unchanged.

## 2026-07-02 - Verify Failures Against Baseline HEAD Before Blaming New Code [tags: validation, workflow]

Context:
- Plan: v0.1.3 remember intake write planning
- Task/Wave: Task_1 required validation
- Roles involved: Orchestrator

Symptom:
- Full `cargo test` failed during Task_1 validation in v0.1.2 integration tests, initially indistinguishable from a Task_1 regression.

Root cause:
- Environmental degradation (see IPv6/localhost entry) unrelated to the change under validation.

Fix applied:
- Stashed the task's src/ changes, reran the failing target on baseline HEAD, observed identical failures, restored the stash.

Prevention:
- When required validation fails in tests untouched by the current task, run the same target against baseline HEAD (stash/worktree) to classify the failure as pre-existing vs regression before remediation.

Evidence:
- Baseline HEAD produced the identical 1-pass/2-fail result on tests/v0_1_2_retrieval_guardrails_tests.rs.

## 2026-06-14 - Prefer Root-Cause Fixes Over Symptom Patches [tags: maintainability, review, validation]

Expand Down
Loading
Loading