# M5a task 22: the answers to a note say where it went **Branch:** `m5a` (run `git switch m5a`; `git status --short` must be empty, otherwise stop) **Commit subject:** `memoryd: note answers name notes.md and the file that was not changed` ## Goal A fix for what the M5a device check showed (2026-09-25). In a session that has read untrusted content, an `add` to `memory.md` or `user.md` is saved as an untrusted note instead. `memoryd` answered `saved as a note (untrusted): this session has read untrusted content`, and a `note` answered `noted (untrusted)`. Both times the model told the owner "Added to memory.md", which was false. The new answers name `notes.md`, and for an `add` also the file that was not changed (M5a spec, section 3, as changed in `0e5b1d2`): | Case | Before | After | |---|---|---| | `note`, clean session | `noted` | `saved in notes.md` | | `note`, untrusted session | `noted (untrusted)` | `saved in notes.md, marked untrusted: this session has read untrusted content` | | `add`, untrusted session | `saved as a note (untrusted): this session has read untrusted content` | `not added to memory.md: this session has read untrusted content, so it was saved in notes.md as an untrusted note` (`user.md` for the other file) | Nothing else changes: the note written to `notes.md`, its header and the journal stay the same. ## Files - Copy: **new versions** of the given `crates/memoryd/tests/edit.rs` and `crates/memoryd/tests/serve.rs`, from `docs/plans/M5a/files/` (the same paths under it). Do not copy `edit.rs-task06` or `serve.rs-task10`; they are the older versions. - Modify: `crates/memoryd/src/edit.rs`, `docs/implementer-log.md` ## The edits, exactly All in `crates/memoryd/src/edit.rs`. Nothing else in the file changes. **1.** The three lines ```rust /// The answer when an untrusted session's `add` became a note. pub const SAVED_AS_NOTE: &str = "saved as a note (untrusted): this session has read untrusted content"; ``` become ```rust /// The answer when an untrusted session's `add` became a note. It names the file it did not change: /// on the device the model read a shorter answer as success. pub fn saved_as_note(file: MemoryFile) -> String { format!( "not added to {}: this session has read untrusted content, so it was saved in notes.md as an untrusted note", file.name() ) } /// The answer to a `note` from a session that has not read untrusted content. pub const NOTED: &str = "saved in notes.md"; /// The answer to a `note` from a session that has read untrusted content. pub const NOTED_UNTRUSTED: &str = "saved in notes.md, marked untrusted: this session has read untrusted content"; ``` The `format!` string stays on one line, longer than 100 characters; `cargo fmt` leaves it so. **2.** In `apply`, the comment line ```rust // replaced by SAVED_AS_NOTE; any other action -> Err(untrusted_refusal(file)). ``` becomes ```rust // replaced by saved_as_note(file); any other action -> Err(untrusted_refusal(file)). ``` and, a few lines below it, the line ```rust answer: SAVED_AS_NOTE.to_string(), ``` becomes ```rust answer: saved_as_note(file), ``` **3.** In `noted`, the two lines ```rust "noted (untrusted)" ``` and ```rust "noted" ``` become `NOTED_UNTRUSTED` and `NOTED`, so the block reads: ```rust answer: if ctx.untrusted { NOTED_UNTRUSTED } else { NOTED } .to_string(), ``` After the edits, `grep -rn SAVED_AS_NOTE crates/` prints nothing. ## Steps - [ ] **1. Copy the two tests:** `cp docs/plans/M5a/files/crates/memoryd/tests/edit.rs docs/plans/M5a/files/crates/memoryd/tests/serve.rs crates/memoryd/tests/` - [ ] **2. See them fail.** `cargo test --no-fail-fast -p memoryd --test edit --test serve`. Expected: four tests fail, `a_note_is_labelled_by_the_session` and `an_untrusted_session_can_take_notes_but_not_change_identity` in `edit`, and `an_untrusted_session_writes_notes_not_identity` and `review_holds_identity_writes_but_not_notes` in `serve`. Every other test passes. - [ ] **3. Make the edits.** Run `cargo fmt --all`. - [ ] **4. See them pass.** The command from step 2: every test passes. Then `cargo test -p memoryd`: every suite passes. - [ ] **5. Run the gate.** `make gate`, with a shell timeout of at least 600000 ms. Expected last line: `gate: ok`, with 944 tests, the same as after task 21 (this task changes tests, adds none). - [ ] **6. Log and commit.** `git add crates/memoryd docs/implementer-log.md && git commit` ## Done when - `make gate` prints `gate: ok` with 944 tests, and `grep -rn SAVED_AS_NOTE crates/` prints nothing. ## Stop and report if - Any quoted block is not in the file exactly as shown. - Step 2 shows a different set of failing tests than the four named. - A test other than these four fails after the edits. Do not change a test.