You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat(vm-agent): thread origin marker from injected prompt block to message reporter
- startAgentWithPrompt emits SAM-injected instructions as a separate ACP block
carrying _meta{sam.origin:system}; create-session body accepts injectedInstructions
- ExtractMessages reads the in-memory marker and sets ExtractedMessage.Origin
- Origin flows through MessageReportEntry -> outbox (additive origin column +
idempotent migration) -> batch payload to the control plane
- Go tests for marker extraction, outbox persist/forward, migration idempotency
* feat(api,web): persist + collapse origin=system injected messages
- producer: buildInjectedInstructions() splits the get_instructions reminder out
of the visible prompt; startAgentSessionOnNode sends it as injectedInstructions
- API: MessageEntrySchema.origin; toProjectDataMessages forwards it
- DO: additive migration 024 (ALTER TABLE chat_messages ADD COLUMN origin, no DROP);
persistMessageBatch INSERT + getMessages SELECT + row parsers carry origin
- web: ChatMessageResponse.origin + UserMessage.origin; chatMessagesToConversationItems
maps it; AcpConversationItemView collapses origin=system behind a chevron disclosure
- tests: producer split, DO origin persist/read (workers), web collapse component;
updated task-runner prompt tests for the split
Persisted path only; live-broadcast hiding deferred (SDK strips _meta outbound).
* feat: finish injected message origin propagation
* test: audit injected context disclosure
* test: account for origin migration
* test: preserve prompt origin contracts
* fix(origin): gate system-origin marker to trusted prompts; address review findings
Specialist review fixes for the injected-message origin feature:
- security: only honor _meta[sam.origin]=system from the SAM control-plane
initial prompt; strip it from untrusted browser/gateway + follow-up prompts
so a viewer cannot hide their own content from search/dedup/topic/attention.
HandlePrompt gains trustedSource; regression test added.
- ui: fix invisible focus ring (ring-accent-primary -> ring-focus-ring);
harden Playwright audit (mount wait, boolean open, robust selector).
- api: emit origin:null on the single-message message.new broadcast for a
stable contract vs messages.batch.
- tests: add dedup-bypass, conversion origin-mapping, DO topic-exclusion, and
attention-exclusion regressions.
- docs: CLAUDE.md Recent Changes + architecture overview.md; migration comment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove dead buildAgentStartPromptPayload
task-completion-validator flagged the old combined-prompt helper as dead code
(rule 01): no production caller remains after the visible/injected prompt split.
Removed the function and its test; retest the visible-prompt helper asserts the
reminder is NOT concatenated into the visible prompt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: drop unrelated prettier reflow from project-data/index + node-agent
The origin commit reformatted the entire ProjectData DO index (799->1309 lines)
and node-agent.ts as a side effect, which (a) tripped the 800-line file-size hard
gate and (b) buried a 1-line functional change under ~490 lines of churn. The repo
does not enforce prettier in CI (main ships the dense style), so this restores the
status-quo formatting and keeps only the real origin changes:
- index.ts: persistMessageBatch input type gains `origin?`
- node-agent.ts: startAgentSessionOnNode gains `injectedInstructions?` forwarded
to the vm-agent create-session body
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: re-trigger checks with corrected preflight classification
Reclassified as cross-component (not external-api-change); no code change.
* fix(origin): forward origin through project-data service to the DO
Staging E2E revealed the injected origin=system message persisted with
origin=null: the service-layer persistMessageBatch (project-data.ts) re-mapped
batch messages before the DO RPC and dropped `origin` — a missing-propagation
bug at a boundary no test covered (vm-agent tests, DO worker tests, and the
un-run CI worker tests each mock only one side). Add origin to the param type
and the re-map, plus a service-layer unit regression test (runs in CI, unlike
the DO worker tests) asserting origin reaches the stub.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: post-mortem for origin service-boundary drop + CI worker-test gap backlog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Raphaël Titsworth-Morin <raphael@raphaeltm.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CLAUDE.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -241,6 +241,7 @@ Tasks tracked as markdown in `tasks/` (backlog -> active -> archive). See `tasks
241
241
242
242
Use the `/changelog` skill for structured queries.
243
243
244
+
- origin-tag-injected-messages: SAM-injected prompt text (e.g. the `get_instructions` reminder) is no longer concatenated into the visible user prompt. It is passed separately as `injectedInstructions` on the vm-agent create-session HTTP body (`startAgentSessionOnNode` → `buildInitialPromptParams`), emitted as a second ACP prompt block tagged `_meta["sam.origin"]="system"`. The vm-agent honors that marker ONLY from a trusted control-plane prompt (`HandlePrompt(..., trustedSource)`) — browser viewer prompts have it stripped so a user cannot hide their own content. Origin propagates through the messagereport outbox (new `origin` column), the ProjectData DO `chat_messages` table (additive migration `024-chat-message-origin`, NULL/absent = `user`), `ChatMessageResponse`, and the live `session/update` broadcast. The web collapses `origin=system` user messages behind a `<details>` "Show system context" disclosure (`AcpConversationItemView`). `origin=system` content is excluded from user-content dedup, LIKE/FTS search (materialization filters it out of `chat_messages_grouped`), topic auto-capture, and attention resolution.
244
245
- chat-full-load-timeline-jump: Project chat loads the FULL conversation on open (`getSessionMessageLimit` split into a small default page size `CHAT_SESSION_MESSAGE_LIMIT` for the 3s poll/load-more and a large `CHAT_SESSION_MESSAGE_MAX` ceiling the initial load requests; new `DEFAULT_CHAT_SESSION_MESSAGE_MAX`). The 30 MiB RPC size guard + `hasMore` "Load earlier" remain the fallback for oversized sessions. Timeline jump-to-message now anchors by messageId+timestamp with a `loadUntil` fallback (no more dead clicks), every entry kind (user message, status update, activity) is clickable, and the jumped-to message flashes (`.sam-message-highlight`). Removed the now-dead `messageIndex`/`messageIndexMap` from the timeline.
245
246
- skills-profile-override-layer: Skills as a first-class profile-override layer (skill → profile → project → platform); additive migration `0063_skills.sql` adds `skills`, `skill_runtime_env_vars`, `skill_runtime_files` and `tasks.skill_id`/`tasks.skill_hint`/`triggers.skill_id`; shared mappers in `profile-fields.ts`/`profile-runtime-assets.ts`; CRUD + runtime routes under `/api/projects/:projectId/skills`; resolution wired through task/trigger/MCP/dispatch + workspace runtime asset injection; Skills UI + chat/task skill selectors in `apps/web`
246
247
- explicit-sam-provider-selection: Require explicit opt-in to SAM as AI provider via `providerMode: 'sam'`; three-mode agent auth (user-api-key, oauth, sam); AI proxy auth gate on all endpoints including /models
'SELECT id, role, content, created_at FROM chat_messages WHERE session_id = ? ORDER BY created_at ASC, sequence ASC',
37
+
"SELECT id, role, content, created_at FROM chat_messages WHERE session_id = ? AND COALESCE(origin, 'user') != 'system' ORDER BY created_at ASC, sequence ASC",
39
38
sessionId
40
39
)
41
40
.toArray()
42
41
.map((row)=>parseMaterializationToken(row));
43
42
44
43
if(tokens.length===0){
45
-
sql.exec(
46
-
'UPDATE chat_sessions SET materialized_at = ? WHERE id = ?',
47
-
Date.now(),
48
-
sessionId
49
-
);
44
+
sql.exec('UPDATE chat_sessions SET materialized_at = ? WHERE id = ?',Date.now(),sessionId);
0 commit comments