Skip to content

prompt: cache-stable assembly (2a) — task-anchored date + memory at tail#194

Merged
torrmal merged 4 commits into
feat/act-and-surface-assumptionsfrom
feat/cache-stable-prompt
Jun 19, 2026
Merged

prompt: cache-stable assembly (2a) — task-anchored date + memory at tail#194
torrmal merged 4 commits into
feat/act-and-surface-assumptionsfrom
feat/cache-stable-prompt

Conversation

@torrmal

@torrmal torrmal commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary (Phase 2a)

Make Anton's system-prompt prefix byte-stable across a task's turns so providers can prefix-cache it and behavior is deterministic.

Changes

  • Task-anchored, date-only stamp. ChatSessionConfig.clock (e.g. the conversation's created_at) replaces the per-turn datetime.now() minute clock in _build_system_prompt. Same task → identical date every turn → the prefix stops changing each minute. Falls back to today's date for the CLI. The agent fetches precise time via a tool when it needs it.
  • Memory snapshot moved to the volatile tail. The cortex memory block is relevance-filtered per user message (changes every turn), so it now sits at the very end of the system prompt — everything above it (identity, discipline, tools, project/datasource/skills, suffix) stays cacheable.

Notes

  • This is the low-risk half of Phase 2: byte-stable content + determinism. It does not add cache_control markers — Anthropic still needs those to actually cache (Phase 2b); OpenAI-compatible providers auto-cache identical prefixes and benefit immediately.
  • Behavioral change to validate: memory is now at the end of the system prompt (recency position) rather than mid-prompt.
  • Stacked on feat/act-and-surface-assumptions (prompt: act-first posture (do first, surface assumptions) + execution discipline #193) — merge that first; this PR's base will retarget to staging after.
  • Pairs with cowork-server PR (harness passes clock=conversation.created_at).

🤖 Generated with Claude Code

Make the system-prompt prefix byte-stable across a task's turns so providers
can prefix-cache it (and so behavior is deterministic):
- date is task-anchored + date-only (ChatSessionConfig.clock, e.g. the
  conversation's created_at) instead of a per-turn minute clock;
- the relevance-filtered memory snapshot moves to the very end (volatile
  tail) so it never invalidates the stable content above it.

Stacked on the act_first branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread anton/core/session.py Outdated
# every turn so the system-prompt prefix stays cache-stable; a per-turn
# wall clock with minute precision would invalidate the cache each turn.
# The agent fetches precise time via a tool when it actually needs it.
_now = self._clock or _dt.datetime.now()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@torrmal I understand the need for prefix caching, but with Cowork, we will be passing the date/time when the task (conversation) created here, but according to the system prompt template that we have, this will be indicated to the agent as the current date and time. Do we need to change this template somehow? Otherwise, say that a user came back to a conversation days or even weeks later, that will still be treated as the 'current' date and time, yes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, yes, you are right let me fix that

Rework _summarize_history:
- 3b-light: frame the summary as REFERENCE ONLY (latest user message wins;
  don't resume superseded/cancelled work) — protects Anton's auto-continue
  verifier from resurrecting stale tasks after a compaction.
- 3b-full: emit a structured STATE RECORD (Goal/Constraints/Completed/Active
  state/Blocked/Decisions/Remaining) instead of freeform bullets, and UPDATE a
  prior summary in place (via a sentinel marker) rather than summarizing a
  summary, so 'Remaining' work survives across compactions.

Stacked on the cache-stable-prompt chain.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
torrmal and others added 2 commits June 19, 2026 12:55
compaction: structured, reference-only, in-place summary (Phase 3b)
…mmary keeps dates

PR feedback: anchoring the date to created_at but labeling it 'current' meant a
conversation resumed days/weeks later reported the wrong current time. Fix:
- prefix carries a FIXED 'Conversation started: {date}' line (cache-stable);
- the real wall clock is emitted in the volatile tail ('Current date and time: …'),
  recomputed each turn, so it's always accurate and never busts the cached prefix;
- rename ChatSessionConfig.clock → started_at to match;
- the 3b summarizer now preserves key event dates so the timeline survives compaction
  (per-message timestamps come from the harness embedding each message's created_at).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@torrmal

torrmal commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Good catch — addressed. The date is no longer anchored-as-"current".

What changed:

  • The cache-stable prefix now carries only a fixed Conversation started: {date} line (from created_at) — it never changes across turns, so it doesn't bust the prefix cache.
  • The real wall clock is emitted in the volatile tail (Current date and time: …), recomputed every turn — so a conversation resumed days/weeks later reports the actual now, not the creation date.
  • ChatSessionConfig.clockstarted_at to match the new semantics.

Plus, per your "what time was something said" point: the cowork-server harness now embeds each message's created_at into history as [YYYY-MM-DD HH:MM] (absolute → fixed per message → still cache-safe), and the compaction summarizer is told to preserve key event dates so the timeline survives compaction. (cowork-server PR #71.)

So: prefix = started, history = per-message stamps, tail = live now — full temporal grounding, cache intact.

@torrmal torrmal merged commit 1cf63e1 into feat/act-and-surface-assumptions Jun 19, 2026
1 check passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants