feat(memory): missions remember their verdicts, per repository
Until now missions wrote no memory. The chat path records every turn into the claw's .brain, but a mission's crew is minted per mission, so a brain keyed by agent would be written once and never read. What persists across missions is the repository: mission_memory keeps one .brain per repo_id, writes each judge verdict into it (reason when met, sanitized guidance when not — the operator reason may quote the acceptance text), and recalls against the next phase's task text into the brief, under a heading all three executors carry because it rides on the task. Recall is BM25 over the keyword index, no embedder; the harness asserts the brief carries the section once the repo has one judged mission behind it, and says 'first mission' rather than failing before that. OpenClaw's flush-before-compaction was the other half of this item and is moot here: the chat loop has no compaction and already remembers both halves of every turn. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WZb5A2kfVfjpdwSochkuHz
This commit is contained in:
co-authored by
Claude Opus 5
parent
76ac3714f1
commit
13f7fb3aff
@@ -355,6 +355,9 @@ assert_microvm() { # <token> <mission> <report>
|
||||
# calls at all, and none of them may have been a write.
|
||||
assert_verifier_read_only "$mission" microvm
|
||||
|
||||
# Project memory: the brief carries earlier verdicts on this repository.
|
||||
assert_project_memory "$mission" microvm
|
||||
|
||||
# And the verdict: judged, and by whom. `independent` is only true when the
|
||||
# judge came from a different provider family than the agent.
|
||||
indep=$(ssh "$HOST" "docker exec clawmates_postgres_1 psql -U postgres -d clawmates -tAc \
|
||||
@@ -900,6 +903,34 @@ assert_verifier_read_only() { # <mission> <label>
|
||||
esac
|
||||
}
|
||||
|
||||
# Did this mission's brief carry what earlier missions on the same repository
|
||||
# learned? `mission_memory` writes every judge verdict into a per-repo brain
|
||||
# and recalls against the next phase's task, so once the repo has ONE judged
|
||||
# mission behind it, the section must be in the prompt. Two branches, because
|
||||
# the first mission on a repo has nothing to recall and must not fail for it:
|
||||
# the earlier-verdict count is what decides which branch is the truth.
|
||||
assert_project_memory() { # <mission> <label>
|
||||
local counts earlier carried
|
||||
counts=$(ssh "$HOST" "docker exec clawmates_postgres_1 psql -U postgres -d clawmates -tAc \
|
||||
\"select (select count(*) from mission_phase_evaluations e
|
||||
join missions m on m.id = e.mission_id
|
||||
where m.repo_id = (select repo_id from missions where id='$1')
|
||||
and e.mission_id <> '$1' and e.error is null
|
||||
and e.created_at < (select created_at from missions where id='$1'))::text
|
||||
|| ' ' ||
|
||||
(select count(*) from mission_events
|
||||
where mission_id='$1' and kind='prompt.composed'
|
||||
and detail->>'text' like '%What past missions on this repository learned%')::text;\"" \
|
||||
| head -1 | tr -d '\r')
|
||||
earlier=${counts%% *}; carried=${counts##* }
|
||||
case "$earlier:$carried" in
|
||||
0:0) pass "$2-memory: first judged mission on this repo — nothing to recall, nothing carried" ;;
|
||||
0:*) fail "$2-memory: the brief carried project memory but no earlier verdict exists for this repo" ;;
|
||||
*:0) fail "$2-memory: $earlier earlier verdict(s) on this repo and the brief carried NONE — recall is not reaching the prompt" ;;
|
||||
*) pass "$2-memory: $earlier earlier verdict(s) on this repo; the brief carried the recalled section" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ── Scenario: a model sizes the team ─────────────────────────────
|
||||
#
|
||||
# Slice 5. The planner proposes a roster for THIS mission, a human approves it,
|
||||
|
||||
Reference in New Issue
Block a user