Project Memory: serve proposals, drop codemap

Task 6291 · Done · Epic · created · updated

Implement the five improvements from the Project Memory audit (Task 6283; the audit report is attached). The audit scanned 251 memory-ON runner sessions (2026-10-11..14): only 21 distinct non-codemap units ever reached a prompt, codemap chunks were 42% of injected bytes with zero reads, 24 of 74 search/read tool calls failed on argument names, 16 accepted runner proposals never became injectable, and memory_feedback was called once. The five changes below are one coherent flywheel fix; each is independently shippable. 1. Serve proposals, stop auto-serving settle narrative. Flip the injectable-on-accept rule in apps/api/app/project_memory/vocabulary.py (INJECTABLE_ON_ACCEPT feeds, line ~23; consumers curate.py ~266, distill.py ~189): a runner's memory_propose unit (gotcha with repro, recipe, env, qa) becomes injectable on accept after the existing secret and canon checks; a settle-mined qa unit (recon_map.recon[] mining in curate.py settle_candidates) is accepted but NOT injectable until corroborated (curate.py corroborate). Keep distilled units as they are unless the Planner finds a reason otherwise. 2. Take codemap out of prompts and search; retire old generations. Codemap units never fill a prompt slot (select.py ~151-152: exclude, do not just sort last) and never rank in memory_search results unless kind=codemap is requested explicitly. Keep them for the hook tier on a Read/Glob of their exact directory (tools/project_memory_tier.py). When tools/project_memory_node.py re-maps a directory, the capture path (apps/api/app/project_memory/capture.py _candidates, insert-only today) retires that directory's previous chunks in the same write. 3. Demote on use, not just on age; make gotchas verifiable. (a) Record an injection count per unit (events.py ~65-68 stores only last_injected_at today) and drop `injectable` after 20 injections with zero read/followed/non-provisional cited events; expose the count in Project > Memory. (b) In gates.py: refuse a gotcha or qa whose body names a repo path (backticked path or file:line) but carries no `paths`, OR auto-fill `paths` from those backticked paths, so the node-side stale verifier can check it (mem-2 was followed 170 times after its fix landed because it had no paths). (c) Add a time-bound gate beside _TASK_STATE in gates.py: a body or title matching "yet", "what is left", "next ", "head is", "currently", "so far", "still" is state, not a fact, and is rejected with reason `time_bound`. 4. Make the tools impossible to misuse, and the hook line free to use. In apps/jaahd/agent_vocabulary.py (verb table ~676-722, arg handling ~1519-1536): accept the aliases runners keep guessing (`query`->`q`, `id`/`unit_id`->`unit`, `action`->`verdict`) and answer any other unknown argument with a malformed_call-style error that names the accepted argument, instead of silently dropping it or returning a bare bad_request. For the hook tier: carry a short lead (first sentence, <=200 chars) of each unit's body in the bundle (bundle.py _entry ~84-91) and render it on the [memory] line (tools/project_memory_tier.py ~348-352) so a surfacing informs without a memory_read round trip. Respect the router's existing 60-line cap. 5. Close the trust loop at settle. Collect votes where the runner already is: the settle call (or the Stop hook before it) takes a structured list of injected units used and units found wrong, and the CP mints confirm/flag votes from it (routes/agent_memory.py feedback path ~279-316). Mint `followed` from real use (the unit's own command string appearing in a Bash call, or its mem-N in the settle summary), not from path overlap (tools/context_router.py ~806-815). Update comparison.py read_rate (~183-237) so "used" reflects the new semantics. In Project > Memory (apps/web/src/components/projects/ProjectMemoryTab.tsx ~186-208) show injected/used/followed counts with a sort, so an operator can retire dead units by eye. Merge the duplicate pairs the audit found (mem-6130/mem-11178, mem-2/mem-3) via the existing near-duplicate path once it is exercised. Out of scope: the two immediate data fixes (purging mem-7834's login triple and retiring mem-2/mem-3) are operator actions in Project > Memory, not code in this epic; profiling the node-side codemap job and curate/nightly cron cost; changing the OFF-arm behaviour (memory OFF must remain byte-identical, see apps/api/tests/memory_off_fixture.py); any new memory kind; org-scoped memory. Done means: - A memory_propose gotcha/recipe/env/qa that passes the gates is served in the next dispatch prompt of the same project without corroboration; a settle-mined qa unit is not served until corroborated (test in apps/api/tests/test_project_memory_*.py). - No codemap unit appears in a composed dispatch prompt's PROJECT MEMORY section, and memory_search without kind=codemap returns none; re-mapping a directory leaves exactly one generation of its chunks accepted. - A unit injected 20 times with no use event is no longer injectable; a gotcha naming a repo path without `paths` is rejected or auto-pathed; a body matching the time-bound patterns is rejected with reason `time_bound` (gate tests). - memory_search with `query`, memory_read with `id`, memory_feedback with `action` all succeed; an unknown argument returns an error naming the accepted one (apps/jaahd tests). A hook [memory] line carries the unit's lead text (tools/tests/test_context_router_memory.py). - A settle that names used and wrong units produces confirm/flag votes visible as trust changes; `followed` is minted only from command-string or mem-N use; Project > Memory shows and sorts by injected/used counts (web test). - Memory OFF parity fixture unchanged. ./dc check full green.

Subtasks

  • [business_analysis] Project Memory: serve proposals, drop codemap Done
    PRD settled: 19 asks from the 5 Project Memory audit fixes (serve proposals, drop codemap, use-based demotion + time_bound/paths gates, tool aliases + hook lead, settle votes). 18 in scope with oracles, E5 no-code (mem-6130 already stale). OFF goldens untouched. Assumptions in PRD §2.
  • [architecture] Project Memory: serve proposals, drop codemap Done
    7 independent children: serve proposals (+backfill); codemap out of prompt/search + whole-dir batching w/ complete-set retirement; time_bound + path autofill gates; shared used predicate → demotion/read_rate/console sort; strict memory args+aliases; hook lead + command-only followed; settle votes (source settle) + summary followed.
  • [plan] Project Memory: serve proposals, drop codemap Done
    Split by the Architect's runtime/acceptance boundaries into 7 coder children (6296-6302), one phase "Core"; only edge 6302→6296 serialises the two migrations. Critic tightened backfill negatives + settle-failure ACs. No Required checks line (mem-11178).
  • Serve memory proposals on accept Done
    memory_propose units now served on accept; settle-mined units wait for corroboration. Backfill flips eligible proposals. PR #5440 merged, Jaah Deploy succeeded. Full gate green pre-rebase; post-rebase only red stage is a vitest case already red on develop. AC-A4 dev chip not observable (dev has no propose units).
  • Drop codemap from prompts and search Done
    Codemap excluded from prompts and runner memory_search (kind=codemap still works), superseded codemap generations retired per directory, node packs whole directories. Full gate green; PR #5437 merged; deploy 38604561138 succeeded. Dev runner probe unverified: dev operator account isn't a Gmind member.
  • Add time bound and path-fill gates Done
    Added the time_bound exclusion gate and the gotcha/qa path auto-fill. ./dc check full is green; PR #5439 merged as 190c64c; Jaah Deploy 38605239487 succeeded. Deferred: R-C4's word list also rejects lasting uses of "still"/"yet".
  • Demote unused units; console usage sort Done
    Nightly demotes never-used units (20 injections, 0 use); one shared USE definition for read_rate, demotion and the console; Memory tab gains Used/Followed and a server-side sort. Full gate green, PR #5448 merged, Jaah Deploy succeeded, verified on dev at 360/768/1280. UX follow-ups are in the report (mem-2, mem-10065).
  • Memory tool argument aliases, strict refusal Done
    memory_* tools now accept query/id/unit_id/action aliases and refuse other args with a named malformed_call before any CP call (0.75 cutoff via aliases so qry→q). PR #5436 merged b26784ba3; Jaah Deploy 38603938492 success. Full gate green bar one xdist worker crash in test_fixture_db (passes 37/37 alone). F1 deferred.
  • Hook memory line lead; command-only followed Done
    Bundle entries carry a first-sentence `lead`, shown as `mem-N │ kind │ title — lead`; `followed` now comes only from the unit's own command (env prefixes stripped). Full gate green, PR #5438 merged, Jaah Deploy succeeded. Dev-flow probe (dev task 5007) never dispatched: unverified. mem-2 used.
  • Settle trust votes and summary followed Done
    task_settle memory_used/memory_wrong votes (source settle, via extracted cast_vote) + summary mem-N followed; full gate green, PR #5449 merged, Jaah Deploy ok. Dev runner flow unobserved (dev dispatch stalled). mem-11867 held.
  • [finish] Project Memory: serve proposals, drop codemap Done
    All 7 coders merged (#5436-5440, 5448, 5449), deploys green; 298+251+10 tests re-run pass; OFF parity held; dev Memory sort/counts work. Filed 6315 (inferred-path stale flag, repro time_bound, propose codemap) and 6316 (Memory tab UX). mem-2, mem-11178 used.
  • Memory serving: fix inferred-path stale flags Done
    Fixed D1–D5 (inferred-path stale flags, proposed codemap 422 + unserve, repro-safe time_bound, restored backfill 202610142200, runner text). Full gate green (mem-2); PR #5455 merged; Jaah Deploy 38625182342 success. Deferred: D1 limited to inferred paths (needs a column).
  • Project › Memory tab: usability fixes seen Done
    Memory tab: Live default (status=live), no Cancel/Save bar, one-line counts, zero-sort note, folded codemap chunks. Full gate green; PR #5454 merged; dev deploy 38625182342 green (own run superseded); dev visual check at 360/768/1280 clean. mem-2 used.

Artifacts

Attachments

Activity

  • Created
  • Updated
  • Runner started
  • Ready
  • Ready
  • Ready
  • Runner started
  • Runner ended (done)
  • Runner started
  • Runner ended (done)
  • Runner started
  • Draft
  • Draft
  • Draft
  • Draft
  • Draft
  • Draft
  • Draft
  • Draft
  • Ready
  • Ready
  • Ready
  • Ready
  • Ready
  • Ready
  • Ready
  • Ready
  • Runner ended (done)
  • Runner started
  • Runner started
  • Runner started
  • Runner started
  • Runner started
  • Runner started
  • Runner ended (done)
  • Runner ended (done)
  • Runner ended (done)
  • Runner ended (done)
  • Runner ended (done)
  • Runner started
  • Runner ended (done)
  • Runner ended (done)
  • Runner started
  • Ready
  • Ready
  • Runner ended (done)
  • Runner started
  • Runner started
  • Runner ended (done)
  • Runner ended (done)
  • Runner ended (done)