Files
boxmaker/docs/plans/M5d2/09-memoryd-summary-index.md
T
kyleandGrok 4.6 df987c3058 docs: M5d-2 checklist: given-test lifetimes and cron AND
session_slot and the scheduler tests held a temporary JSON Value across
statements (E0716). Cron now pins DOM and DOW as AND, which the given tests
had not. Gate counts from task 04 on move up by one.

Co-Authored-By: Grok 4.6 <noreply@x.ai>
2026-10-03 01:31:07 -07:00

5.5 KiB

M5d-2 task 09: index ToolSummary as kind summary

Branch: m5d2. Check it: git branch --show-current prints m5d2 and git status --short is empty; otherwise stop. Never switch branch. Commit subject: memoryd: index ToolSummary as kind summary Log row: the Task cell is M5d2/09-memoryd-summary-index.

Goal

memoryd indexes LogRecord::ToolSummary content as kind summary, with that record's class and untrusted (spec 4.3, P26). recall finds it and tags memory or memory-tainted as for any other session hit. Raw ToolResult bodies stay unindexed.

index_record today has _ => {}. It compiles. This task adds the arm.

Every place that changes

Place What happens there
crates/memoryd/src/index.rs ToolSummary arm (edit I1); module doc
crates/memoryd/tests/tool_summary_index.rs new, given
everything else no change: not recall.rs headers (role "summary" uses the existing "the assistant said" branch)

Files

  • Copy, from docs/plans/M5d2/files/ (the same path under it): the new test crates/memoryd/tests/tool_summary_index.rs.
  • Modify: crates/memoryd/src/index.rs, docs/implementer-log.md.
  • Do not touch: any other file. Do not edit tests/support/logs.rs.

Facts you need

  • Kind summary. Set kind: "summary".to_string() on the Source, not the log's "session". Role "summary". Time from the record. class / untrusted from the ToolSummary, not from base (the rolling session label). Skip when summary.class > self.max_class, even if base.class is still Private. Skip when content.trim() is empty.
  • The existing if base.class > self.max_class stays. A secret ToolResult raises the rolling label before the next record, so a following secret summary is also skipped that way. Still check the summary's own class.
  • Do not add ToolSummary to the rolling-label update in index_log (that loop still looks at ToolResult only). The result already carried the same labels.
  • Recall headers. kind "summary" is not moved / dropped / noted, so the tag is memory or memory-tainted. Role "summary" is not owner or call, so the line says the assistant said. The given tests look for memory · session mm-a and memory-tainted.
  • The items the edits use. This table is complete.
    Item What it does
    self.add FTS row plus sources
    Source kind / role / class / untrusted

The edits, exactly

Each quoted "before" block occurs exactly once.

crates/memoryd/src/index.rs

I1. After the Assistant arm, before _ => {}. The lines

            }
            _ => {}
        }
        Ok(())
    }

become

            }
            LogRecord::ToolSummary {
                time,
                content,
                class,
                untrusted,
                ..
            } if !content.trim().is_empty() && *class <= self.max_class => {
                let src = Source {
                    kind: "summary".to_string(),
                    time: time.to_rfc3339(),
                    role: "summary".to_string(),
                    class: *class,
                    untrusted: *untrusted,
                    ..base.clone()
                };
                self.add(content, &src)?;
            }
            _ => {}
        }
        Ok(())
    }

DataClass already implements Ord (Public < Private < Secret). If <= does not compile, stop.

Optionally update the module doc "never a tool's result" to say summaries of opted-in results are indexed. A comment that does not fit its code: stop.

Steps

  • 1. Copy the given test.

    cp docs/plans/M5d2/files/crates/memoryd/tests/tool_summary_index.rs crates/memoryd/tests/
    
  • 2. See it fail. cargo test -p memoryd --test tool_summary_index, timeout 600000 ms: the tests compile (ToolSummary exists) and a_tool_summary_is_found_as_kind_summary fails: (no matches for "tea") or the unique phrase is missing. the_raw_tool_result_is_still_not_indexed may pass (results were already unindexed).

  • 3. The edit. I1. cargo check -p memoryd prints no error and no warning.

  • 4. The tests. cargo test -p memoryd --test tool_summary_index --test recall: every test passes, 5 in tool_summary_index.

  • 5. Check. git diff --stat lists exactly crates/memoryd/src/index.rs.

  • 6. Run the gate. cargo fmt --all, then make gate, timeout 600000 ms. Last line gate: ok. Test count 1568 (1563 before, plus 5).

  • 7. Log and commit. Task cell M5d2/09-memoryd-summary-index. Stage with git add crates/memoryd docs/implementer-log.md Cargo.lock, then commit as AGENTS.md says.

Done when

  • make gate prints gate: ok with 1568 tests.
  • git diff HEAD~1 --stat lists only crates/memoryd/src/index.rs, crates/memoryd/tests/tool_summary_index.rs and the log.

Stop and report if

  • The branch check fails; a "before" block is not found exactly once; step 2 differs; cargo check warns; a test fails; the gate count is not 1568; you index ToolResult content; you leave kind as "session"; a secret summary is searchable on a private index.

What the given tests pin

A summary's content is found and tagged memory · session …; the raw tool body is not; an untrusted summary taints the recall (memory-tainted); a trusted summary does not taint; a secret summary is skipped when max_class is Private.