Task Breakdown: Memory, context files & the load meter
Ordered tasks derived from
plan.md. Each task names the files to create or modify, what "done" means, and its phase. Execute top to bottom. Every task ships with its tests (Constitution VI).
Feature ID: AW-07-memory-context
Spec: ./spec.md · Plan: ./plan.md
Status: Draft
Last updated: 2026-09-06
How to use
- Tasks are sequential unless marked
(parallel). - Repo root is the monorepo root; every path below is relative to it.
- Commands run from the directory named in the task.
developmust be green after each phase, not each task — but no task may leave a type error or a failing existing test behind.- Add new tasks at the bottom rather than renumbering.
Phase P1 — Memory facts, end to end (no prompt changes)
P1 touches nothing an agent receives. It adds a table, a service, a controller and a page section. If P1 shipped alone, users could curate memory before anything read it.
P1.a — Contracts and data model
-
T1. Fact + context-file + load-report contracts. Create
packages/contracts/src/memory/memory-fact.types.ts,packages/contracts/src/memory/context-file.types.ts,packages/contracts/src/memory/context-load.types.tsandpackages/contracts/src/memory/index.ts; re-export frompackages/contracts/src/index.ts. Constants exactly as listed in plan §3.7 —MEMORY_FACT_BODY_MAX = 500,MEMORY_FACT_ACTIVE_MAX = 2000,MEMORY_FACT_PROPOSED_MAX = 200,MEMORY_FACT_PINNED_MAX = 20,MEMORY_FACT_RECALL_TOP_K = 8,MEMORY_FACT_RECALL_MIN_SCORE = 0.72,MEMORY_FACT_SEARCH_TOP_K = 50,MEMORY_FACT_SEARCH_MIN_SCORE = 0.55,MEMORY_FACT_RECALL_MAX_TOKENS = 1200,MEMORY_FACT_FORGET_RETENTION_DAYS = 30,WORKSPACE_CONTEXT_FILE_SLUGS,CONTEXT_FILE_LOAD_MODES,MAX_ALWAYS_LOADED_WORKSPACE_FILES = 3,CONTEXT_FILE_REVISION_KEEP = 20,CONTEXT_FILE_REVISION_KEEP_DAYS = 30. Done when:pnpm --filter @ever-works/contracts buildemits declarations with no conditional-spread DTS failure, and the constants are importable from@ever-works/contracts. -
T2.
MemoryFactentity. Createpackages/agent/src/entities/memory-fact.entity.ts; export frompackages/agent/src/entities/index.ts. Columns and constraints per plan §3.1, includingscope/agentIdCHECK, the 500-char CHECK,embeddingdeclaredsimple-jsonnumber[] | null,embeddingModel,embeddingDims,pinned,recallCount,lastRecalledAt,supersedesFactId,forgottenAt, and thetenantId/organizationIdscope pair matching sibling entities. Done when:pnpm --filter @ever-works/agent buildpasses and the entity is picked up by the TypeORM entity list. -
T3. Context-file shared types module. Create
packages/agent/src/entities/context-file-types.tsholding the slug union, default load modes per slug, and the always-loaded cap — the same rolepackages/agent/src/entities/kb-types.tsplays for the Knowledge Base. Re-export the contract constants rather than redeclaring the numbers. Done when: no numeric literal for a limit appears twice in the repo. -
T4. Migration —
memory_facts. Fromapps/api/, authorapps/api/src/migrations/1791070000000-CreateMemoryFacts.ts. Branch onqueryRunner.connection.options.type === 'postgres'forvector(1536)vsTEXT, and create theivfflat … vector_cosine_ops WITH (lists = 100)index on Postgres only — copy the shape fromapps/api/src/migrations/1779975000000-CreateWorkKnowledgeChunks.ts. Createidx_memory_facts_owner_status,idx_memory_facts_agent,idx_memory_facts_forgotten_at, and the partial uniqueuq_memory_facts_body. Done when:pnpm typeorm migration:runapplies cleanly on Postgres and on SQLite,down()drops indexes then the table, and the generated SQL contains noDROP COLUMNand no rename. -
T5.
MemoryFactRepository. Createpackages/agent/src/database/repositories/memory-fact.repository.tsbesidememory-folder.repository.ts. Methods:listForOwner,countByStatus,findOwned,create,update,setStatus,forgetAll,searchSemantic(ANN with the score threshold, alwaysWHERE user_id = … AND organization_id IS NOT DISTINCT FROM …),searchLiteral,dueForPurge,dueForReembed. Done when: every query is owner-scoped and there is no code path that can read a row outside the caller's workspace. Test:packages/agent/src/database/repositories/__tests__/memory-fact.repository.spec.tsplus a Postgres integration spec proving the scope predicate is present in the emitted SQL, mirroringagent.repository.organization-scope-sql.integration.spec.ts.
P1.b — Service layer
-
T6.
MemoryFactService. Createpackages/agent/src/services/memory-fact.service.ts; export frompackages/agent/src/services/index.ts. Enforces: body trim + 1–500 chars; 2,000 active cap; 200 proposal cap; 20 pin cap;origin-driven initial status (human →active, agent →proposed);scope/agentIdcoherence; soft forget withforgottenAt; restore inside 30 days;forgetAllrequiring the caller to have already passed the confirm gate; and an activity row on every mutation. Enqueues embedding throughMEMORY_FACT_EMBED_DISPATCHER(T13) and tolerates anullreturn. Done when:forgetAllprovably touches onlymemory_facts. Test:packages/agent/src/services/__tests__/memory-fact.service.spec.tscovering every bound and both status paths. -
T7.
MemoryFactSearchService. Createpackages/agent/src/services/memory-fact-search.service.ts. Embeds the query throughAiFacadeService.embed(); runs the ANN leg and the literal leg; fuses, dedupes by id, floors literal hits at the threshold so they always survive; returns{ results, semantic }. Probes embedding availability and vector support and returnssemantic: falserather than throwing. Done when: with the AI facade mocked to throw, search still returns literal results. Test:packages/agent/src/services/__tests__/memory-fact-search.spec.ts. -
T8. Activity action types. Append to
packages/agent/src/entities/activity-log.types.ts:MEMORY_FACT_CREATED,MEMORY_FACT_UPDATED,MEMORY_FACT_FORGOTTEN,MEMORY_FACT_RESTORED,MEMORY_FACT_ACCEPTED,MEMORY_FACT_DISCARDED,MEMORY_FACTS_CLEARED,CONTEXT_FILE_UPDATED,CONTEXT_FILE_RESTORED,CONTEXT_FILE_MODE_CHANGED,CONTEXT_BUDGET_EXCEEDED. Append only — reorder nothing, remove nothing. Done when: no migration is required (the column isvarchar(50)), and a comment in the file says so.
P1.c — API
-
T9.
MemoryFactsController+ module. Createapps/api/src/memory-facts/memory-facts.module.ts,apps/api/src/memory-facts/memory-facts.controller.tsandapps/api/src/memory-facts/dto/(create-memory-fact.dto.ts,update-memory-fact.dto.ts,list-memory-facts.query.dto.ts,forget-all.dto.ts). Register the module inapps/api/src/api.module.ts. Routes, throttles and error codes exactly as plan §4.1. Organization comes fromScopeContextService;@UseGuards(AuthSessionGuard);@CurrentUser(); full Swagger decorators. Done when:POST /api/memory/facts/forget-allwith any confirm string other thanFORGET ALLreturns 422 and changes nothing. Test:apps/api/src/memory-facts/memory-facts.controller.spec.ts— auth, scoping, 404 on a cross-workspace id, 409 at the caps, 410 on a too-late restore, 422 on a bad confirm, throttle metadata asserted. -
T10. Web API client + server actions. Create
apps/web/src/lib/api/memory-facts.ts(mirroringapps/web/src/lib/api/memory.ts) andapps/web/src/app/actions/memory-facts.ts(mirroringapps/web/src/app/actions/skills.ts). Done when: the client is server-only and stamps the workspace selector header like its sibling. -
T11. BFF proxy routes. Create
apps/web/src/app/api/memory/facts/route.ts,.../facts/[id]/route.ts,.../facts/[id]/forget/route.ts,.../facts/[id]/restore/route.ts,.../facts/[id]/accept/route.ts,.../facts/[id]/discard/route.ts,.../facts/forget-all/route.ts,.../facts/stats/route.ts, copying the header/scope handling inapps/web/src/app/api/memory/route.ts. Done when: each has aroute.unit.spec.tsbeside it, as the existing memory proxies do.
P1.d — Background work
-
T12. Embed dispatcher symbol. Create
packages/agent/src/tasks/memory-fact-embed-dispatcher.tsandpackages/agent/src/tasks/memory-fact-embed.types.tsfollowingpackages/agent/src/tasks/kb-embed-document-dispatcher.ts. Export from the package's tasks barrel. Done when: the interface returnsPromise<string | null>and its docblock states thatnullmeans "stays unembedded, sweep will catch it". -
T13. Embed task. Create
packages/tasks/src/tasks/trigger/memory-fact-embed.task.ts; register inpackages/tasks/src/tasks/trigger/index.ts; implement the producer side inpackages/tasks/src/trigger/trigger.service.tsnext todispatchKbEmbedDocument. Give it aqueue:config so a bulk import cannot saturate the runtime. Done when: re-running the task for the same fact is a no-op, and no file outsidepackages/tasksimports a runtime SDK. -
T14. GC / sweep task. Create
packages/agent/src/tasks/memory-fact-gc-dispatcher.tsandpackages/tasks/src/tasks/trigger/memory-fact-gc.task.tsas a scheduled task on cron13 4 * * *; register it in the trigger index. Purges facts forgotten more than 30 days ago, prunes context-file revisions past the keep rule (a no-op until P2), and re-embeds up to 500 facts per tick whoseembeddingModeldiffers from the resolved default. Done when: the cadence does not collide with the existing42 3,23 */2or37 8crons in that folder. Test:packages/agent/src/services/__tests__/memory-fact-gc.spec.ts.
P1.e — Web surface
-
T15. Memory rail. Create
apps/web/src/components/memory/MemoryRail.tsx(+MemoryRail.unit.spec.tsx); export fromapps/web/src/components/memory/index.ts. SectionsFacts,Context files,Agents,Also here; counts; the ⟳ always-loaded marker (inert until P2);g f/g c/g ajumps. Done when: every existing panel is still reachable, now under "Also here". -
T16.
FactsPanel+FactRow+FactComposer. Createapps/web/src/components/memory/FactsPanel.tsx,FactRow.tsx,FactComposer.tsx(+ a.unit.spec.tsxeach). All states from spec §6.2–§6.3: loaded, searching (semantic and degraded), empty, no results, over capacity, loading skeletons (six rows), pagination. Relevance bar in search mode. Provenance line. Row actions and the⋯menu. Optimistic pin/forget/restore with rollback; non-optimistic edits. Done when: the search box is focusable and accepts typing before the first page resolves, and nothing shifts layout when it lands. -
T17.
ForgetAllDialog. Createapps/web/src/components/memory/ForgetAllDialog.tsx(+ spec). Blast-radius paragraph before the field; the confirm button disabled until the field contains exactlyFORGET ALL;Esccancels and never confirms; focus returns to the trigger on close. -
T18. Wire the Memory page. Modify
apps/web/src/app/[locale]/(dashboard)/memory/page.tsxto add a.catch()-guarded facts fetch, andapps/web/src/components/memory/MemoryShell.tsxto render the rail and route the section body. Existing panels move under "Also here" with no change to their internals. Done when:flow-memory-ui-journey.spec.ts,flow-org-memory-page-deep.spec.tsandflow-memory-consolidation-deep.spec.tsstill pass unmodified. -
T19. Chat capture tool (human turn). Create
apps/web/src/lib/ai/tools/memory-facts.tools.tswith arememberFacttool; register it inapps/web/src/lib/ai/tools/tool-selection.ts. The tool writes an active fact (originuser) because the author is the human in their own conversation, and returns the stored wording so the assistant can read it back in one line. Done when:tool-selection.unit.spec.tsshows the tool is offered for "remember…" phrasings and not for unrelated turns.
P1.f — i18n and tests
-
T20. i18n keys for P1. Add
dashboard.memoryPage.factsanddashboard.memoryPage.forgetAllDialogtoapps/web/messages/en.jsonwith every key listed in plan §8. Mirror the keys into the 20 sibling locale files inapps/web/messages/. Done when: no leaf key name contains a literal., every leaf is camelCase, and no component in T15–T19 contains a literal English string. -
T21. End-to-end — facts journey.
(parallel with T22)Createapps/web/e2e/flow-memory-facts-journey.spec.ts: add → search → edit → forget → undo → restore from Forgotten, plus the empty and no-result states. Prefer container-scopedgetByRolequeries — unscoped*ByRoleis the known flake family in this app. -
T22. End-to-end — forget all. Create
apps/web/e2e/flow-memory-forget-all.spec.ts: the typed confirm gate, the blast-radius copy, and an assertion that a context file body and an agent file body are byte-identical after the wipe. -
T23. End-to-end — degraded search. Create
apps/web/e2e/flow-memory-facts-degraded-search.spec.ts: with the embedding provider unavailable, literal search returns results, the note renders with its settings link, and no console error is raised (the hydration-error assertion in the shared spec helper stays green). -
T24. P1 gate. Run from the repo root:
pnpm format && pnpm lint && pnpm type-check && pnpm test && pnpm build. Done when: green, anddocs/specs/features/agent-workspace/TRACKER.mdrow AW-07 readsSpec: Draft/Impl: In progresswith the branch link.
Phase P2 — Context files, the load meter, injection
P2 changes what agents receive. Land it behind the telemetry in T40 and watch for a week before starting P3.
P2.a — Data model
-
T25.
WorkspaceContextFileentity + migration. Createpackages/agent/src/entities/workspace-context-file.entity.ts(export from the entities barrel) andapps/api/src/migrations/1791070100000-CreateWorkspaceContextFiles.ts. Columns per plan §3.2; unique(userId, organizationId, slug). No seed migration — rows are created lazily on first read. -
T26.
ContextFileRevisionentity + migration. Createpackages/agent/src/entities/context-file-revision.entity.tsandapps/api/src/migrations/1791070200000-CreateContextFileRevisions.ts. Columns per plan §3.3; index(targetType, targetId, fileKey, createdAt DESC). -
T27.
agents.notes_md+ migration. Modifypackages/agent/src/entities/agent.entity.tsto addnotesMdbesideagentYml; createapps/api/src/migrations/1791070300000-AddAgentNotesMd.ts(ADD COLUMN "notes_md" text NULL). -
T28. Repositories.
(parallel with T27)Createpackages/agent/src/database/repositories/workspace-context-file.repository.tsand.../context-file-revision.repository.tswith owner-scoped queries and the retention prune (keep newest 20 OR younger than 30 days). Test: a spec each under the repositories'__tests__/folder.
P2.b — The assembler and the meter
-
T29.
truncateMiddleOut. Modifypackages/agent/src/agents/prompt-assembler.service.tsto add and exporttruncateMiddleOut(text, capTokens)returning{ text, skipped: { startChar, endChar, chars } | null }with the 70/30 split and the marker line. Do not touchtruncateTailFirst. Test:packages/agent/src/agents/__tests__/truncate-middle-out.spec.ts— under cap, exactly at cap, one char over, far over, empty, marker length counted inside the cap, idempotence. -
T30. Extract
measureSegments. Modifyprompt-assembler.service.tsto hoist the pure segment-measurement logic into an exportedmeasureSegments(input): SegmentMeasurement[], and makeassemble()call it. Behaviour must be unchanged for every existing input. Done when:packages/agent/src/agents/__tests__/prompt-assembler.service.spec.tsandprompt-assembler-file-manifest.spec.tspass without edits. -
T31. New segments and caps. Modify
prompt-assembler.service.ts: addnotes,workspace-contextandmemory-factstoPROMPT_SEGMENTSin the order given in plan §2.3; setSEGMENT_TOKEN_CAPSto the FR-47 numbers (identity1200,role1200,notes1500,capabilities400,operating-loop800,workspace-context1500,memory-facts1200,scope-advanced-prompts600); raiseTOTAL_SYSTEM_TOKEN_TARGETto17_000; route the authored-file segments throughtruncateMiddleOutand leave the feed-shaped ones ontruncateTailFirst. Fence the two new untrusted segments withneutralizeInjectedBlockexactly as the skills segment is fenced. Test:packages/agent/src/agents/__tests__/prompt-assembler-budgets.spec.tsasserting each cap, the total, and that the sum of caps (16,850) is below the total. -
T32.
ContextFileService. Createpackages/agent/src/services/context-file.service.ts; export from the services barrel.getOrCreate(slug),write(slug, body, expectedHash?),setLoadMode(slug, mode),listRevisions,restoreRevision. Enforces the 64 KB bound (reuseMAX_FILE_BYTES's value),assertNoSecretsfrompackages/agent/src/utils/secret-scan.tsin hard-reject mode, theexpectedHashconflict returning the current hash and the current body, the three-always-loaded cap, the proportional split of the shared 1,500-token budget, and a revision row on every write. Test:packages/agent/src/services/__tests__/context-file.service.spec.ts. -
T33.
ContextBudgetService. Createpackages/agent/src/agents/context-budget.service.ts. Builds aContextLoadReportfor one agent from saved bodies by callingmeasureSegments— no second implementation of the budget maths. States:under(<90 %),near(90–100 %),over(>100 %). Test:packages/agent/src/agents/__tests__/context-budget.service.spec.tsincluding an equivalence test that the report equalsassemble()'s own numbers for identical inputs (spec FR-50), and boundary tests at 89.9 / 90 / 100.1 %. -
T34.
NOTES.mdin the agent-file service. Modifypackages/agent/src/agents/agent-file.service.ts: add'NOTES.md'toAgentFileNameand toAGENT_FILE_NAMES(position 3), map it tonotesMdin the column switch, and append it tohashOf's concat at the end with a new sentinel. Test:packages/agent/src/agents/__tests__/agent-file-notes.spec.ts— read/write round trip, path allow-list unchanged for every other value, cross-agent write rejected, and the ETag-stability regression from plan §3.4 (a read before the change and a write after it must not conflict). The existingpackages/agent/src/agents/__tests__/agent-file.service.spec.tsmust stay green unmodified. -
T35. Facts recall into the run. Create
packages/agent/src/services/memory-fact-recall.service.tsand wire it intopackages/agent/src/agents/agent-run.service.tsas thememory-factssegment input (the provider-backedresolveMemoryRecallcall at line 398 stays exactly as it is — both blocks may be present). Pinned first, then top-8 above 0.72, capped at 1,200 tokens dropping whole facts lowest-score-first, loud-empty note when recall is on and nothing matched, nothing at all whenagent.memoryRecallEnabled === false, and a 2,000 ms best-effort timeout that logs and continues. Test:packages/agent/src/services/__tests__/memory-fact-recall.spec.ts. -
T36.
agent_runs.context_load. Modifypackages/agent/src/entities/agent-run.entity.tsto addcontextLoad?: RunContextLoad | null(simple-json, nullable); createapps/api/src/migrations/1791070400000-AddAgentRunContextLoad.ts; write it fromAgentRunServiceafter assembly. Done when: existing runs read backnullwith no error.
P2.c — API and tools
-
T37.
ContextFilesController+ module. Createapps/api/src/context-files/context-files.module.ts,context-files.controller.tsanddto/; register inapps/api/src/api.module.ts. Routes per plan §4.2. Test:apps/api/src/context-files/context-files.controller.spec.ts— unknown slug 404s (never 500s), conflict response carriescurrentHashand the current body, load-mode 422 names the current three always-loaded files, revision restore creates a new revision. -
T38. Agent-file endpoint extensions. Modify
apps/api/src/agents/agents.controller.ts: acceptNOTES.md; addGET /api/agents/:id/files/:name/revisions,POST /api/agents/:id/files/:name/revisions/:revisionId/restore,GET /api/agents/:id/context-load,GET /api/agents/:id/files/:name/load-report. Test: createapps/api/src/agents/agents.controller.context.spec.ts— the module uses topic-scoped controller specs (agents.controller.environment.spec.ts,.runtime.spec.ts,.session-detail.spec.ts); there is no singleagents.controller.spec.tsto extend. -
T39. Agent tools for context files. Modify
packages/agent/src/agents/agent-tool.service.tsbeside the pushes at lines 412–413: addgetContextFile({ slug })(on-demand slugs only; always-loaded slugs return a pointer note; body neutralised and fenced) andupdateContextFile({ slug, body })gated onAgentPermissions.canEditAgentFiles— not offered at all without the grant. Add arememberFactrun-time tool that writes proposed facts only. Test: extend the agent-tool suite underpackages/agent/src/agents/__tests__/— unknown slug returns a typed refusal rather than throwing; the write tool is absent without the grant; the remember tool can never produce anactivefact. -
T40. Truncation telemetry. Modify
packages/agent/src/agents/agent-run.service.tsto write oneAgentRunLogrow per truncating run (levelWARN, stepcontext-budget, metadata{ segment, capTokens, originalTokens, truncatedTokens, skippedChars }) and thememory-recall/memory-capturelines from plan §9.2. Emit the analytics events from plan §9.3 throughpackages/monitoring. Done when: a run with an over-budget Notes file produces exactly onecontext-budgetrow, not one per segment pass.
P2.d — Web surface
-
T41.
LoadMeter. Createapps/web/src/components/memory/LoadMeter.tsx(+LoadMeter.unit.spec.tsx). The only place the three states are styled. Renders used / budget / percentage / skipped tokens, the authoring rule line, and an assistive-technology text summary ("Notes: 1,500 of 1,500 tokens used, 2,600 tokens skipped"). -
T42.
ContextFilePanel,ContextFileEditor,ContextFilePreview. Create the three components underapps/web/src/components/memory/(+ a spec each). Write/Preview toggle, load-mode control, save, history link, conflict banner with Compare / Reload / Keep, and the marked skipped block — hatched fill plus strike-through plus label, never colour alone (WCAG 2.2 AA 1.4.1).n/Njump between skipped blocks. Done when: the marked block states its character count and line range. -
T43.
AgentContextReport. Createapps/web/src/components/memory/AgentContextReport.tsx(+ spec) rendering the fourteen segments of spec §6.7 with empty and error states. -
T44. Web clients, actions and BFF routes for context files. Create
apps/web/src/lib/api/context-files.ts,apps/web/src/app/actions/context-files.ts, and the routesapps/web/src/app/api/context-files/route.ts,.../[slug]/route.ts,.../[slug]/load-mode/route.ts,.../[slug]/revisions/route.ts,.../[slug]/revisions/[revisionId]/restore/route.ts,apps/web/src/app/api/agents/[id]/context-load/route.ts— each with aroute.unit.spec.ts. -
T45. Memory page — context files and agents sections. Modify
apps/web/src/components/memory/MemoryShell.tsxandapps/web/src/app/[locale]/(dashboard)/memory/page.tsxto render the six workspace files and the per-agent file tree in the rail, withContextFilePanelas the section body. -
T46. Agent instructions tab. Modify
apps/web/src/components/agents/AgentInstructionsEditor.tsxandapps/web/src/app/[locale]/(dashboard)/agents/[id]/instructions/page.tsx: add the Notes pill (sixth), theLoadMeterunder the textarea, the Write/Preview toggle, andAgentContextReportabove the pills. Keep the 800 ms autosave; fetch the load report on a separate 400 ms debounce. Relabel pills to captions (Identity,Role,Notes,Operating loop,Tools,Manifest) with the filename as secondary text — filenames themselves do not change. Done when:apps/web/e2e/agent-instruction-files-ui.spec.tsstill passes, adjusted only for the added pill. -
T47. i18n keys for P2. Add
dashboard.memoryPage.contextFiles,dashboard.memoryPage.loadMeter,dashboard.memoryPage.agentContextand thedashboard.agentsPage.instructions.*additions toapps/web/messages/en.jsonand the 20 sibling locale files, per plan §8. -
T48. End-to-end — load meter.
(parallel with T49)Createapps/web/e2e/flow-context-files-load-meter.spec.ts: small file → meter under; oversized body → meter over with the skipped-token count; Preview shows the marked block with its character count and line range;n/Nnavigate between blocks. -
T49. End-to-end — agent context report. Create
apps/web/e2e/flow-agent-context-report.spec.ts: fourteen segments with their budgets, the Notes pill present, and the report agreeing with the single-file meter for the same file. -
T50. End-to-end — conflict. Create
apps/web/e2e/flow-context-file-conflict.spec.ts: two contexts save the same file; the second is refused and the typed text survives in the editor. -
T51. P2 gate.
pnpm format && pnpm lint && pnpm type-check && pnpm test && pnpm buildfrom the root, plus a manual check thatflow-agent-memory-lifecycle.spec.tsand the other four must-stay-green suites listed in plan §10.3 are untouched and passing.
Phase P3 — Ask an agent, revisions UI, agent-written facts
-
T52.
composeMessageon the chat context. Modifyapps/web/src/components/ai/ChatProvider.tsxto addcomposeMessage(text, attachments?)toChatContextValue— sets the composer draft without sending. Existing callers are untouched (sendMessagekeeps its signature). Test: extendapps/web/src/components/ai/ChatProvider.unit.spec.ts. -
T53.
'context-file'attachment kind. Modifyapps/web/src/lib/ai/attachments.tsto widenChatAttachmentRef['kind'], andapps/web/src/components/ai/ChatAttachments.tsxto render the chip and, on click, open the existing preview overlay with the file's budgeted text rendered byContextFilePreview— reused, not reimplemented. Done when:formatAttachmentsBlock's sanitiser is unchanged and its existing spec still passes. -
T54.
AskAnAgentButton. Createapps/web/src/components/memory/AskAnAgentButton.tsx(+ spec) and mount it inContextFilePanelandAgentInstructionsEditor. CallsuseChatPanel()?.setOpen(true)thencomposeMessage(...). Pre-fill: agent file →@{agent-slug} update your {File} file:; workspace file →Update the {File} context file:with an optional agent picker and no agent addressed by default. Done when: the message is composed and not sent. -
T55. Chat tools for context files. Create
apps/web/src/lib/ai/tools/context-files.tools.ts(readContextFile,updateContextFile); register inapps/web/src/lib/ai/tools/tool-selection.ts. When the addressed agent lackscanEditAgentFiles, the assistant returns the proposed change as a diff with Apply / Discard instead of writing. Test:context-files.tools.unit.spec.tsplus a case intool-selection.unit.spec.ts. -
T56. Revision history dialog. Create
apps/web/src/components/memory/ContextFileHistoryDialog.tsx(+ spec); mount fromContextFilePanelandAgentInstructionsEditor. Lists revisions with author and time; restore writes a new revision. -
T57. Proposed-fact review surface. Extend
apps/web/src/components/memory/FactsPanel.tsxwith the Proposed filter body: the proposal card, its "Proposed by {agent} during run {id}" line linking to the run, and Accept / Discard. Surface the backlog-full state. Done when: a proposed fact is provably never returned by recall (asserted in T35's suite). -
T58. i18n keys for P3. Add
dashboard.memoryPage.askAnAgenttoapps/web/messages/en.jsonand the 20 sibling locale files, per plan §8. -
T59. End-to-end — ask an agent. Create
apps/web/e2e/flow-ask-an-agent-update-file.spec.ts: the button opens the panel, the chip is present, the message is pre-filled and not sent, and the chip expands to exactly the budgeted text including the marked skipped block. -
T60. P3 gate + docs.
pnpm format && pnpm lint && pnpm type-check && pnpm test && pnpm build. Add the user-facing pagedocs/features/memory-and-context.mdand link it fromdocs/features/index.mdandapps/docs/sidebarsPlatform.ts. Add the Context file row to the vocabulary table indocs/specs/features/agent-workspace/README.md§1. Updatedocs/specs/features/agent-workspace/TRACKER.mdrow AW-07 and set this spec's status toImplemented, the plan and tasks toDone.
Definition of done
- Every checkbox above ticked.
- Every acceptance criterion in
spec.md§8 demonstrated by a named test. pnpm format:check,pnpm lint,pnpm type-check,pnpm testandpnpm buildgreen from the repo root.pnpm --filter ever-works-docs buildproduces no broken-link warning.- The five must-stay-green suites in plan §10.3 pass unmodified — the proof that the additive rule held.
- No leaf i18n key contains a literal
.; no component carries a literal English string. - Every constitution gate in
plan.md§12 confirmed against the merged code.