fix(chat): tell overviews to state when the picture is from (#20301)

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - People ask the CEO chat agent for a quick picture of what the
company is doing now
> - Such a picture is only useful when the person knows how current it
is
> - The chat guidance asks for accurate status, but it does not ask for
a time
> - A live overview said "right now" and gave no time, so the person
could not tell when it was observed
> - This pull request adds one guidance sentence: state the picture's
time as a UTC clock time, from the latest message timestamp
> - The benefit is that overviews tell the person when their information
is from

## Linked Issues or Issue Description

Refs #19614

**What happened**

A person asked the chat agent "Give me a quick picture of what the
company is doing right now." The agent read agents, projects, tasks and
approvals and gave a correct summary. The summary did not say when it
was observed. The only time word was "right now".

**Expected behavior**

An overview of current work states when the picture is from, as a clock
time. The native prompt already lists each new comment with its
timestamp, so the agent has a time it can use.

**Steps to reproduce**

1. Open a chat with the CEO agent in a company that has active, blocked
and done tasks.
2. Ask "Give me a quick picture of what the company is doing right now."
3. The reply summarizes the work but gives no observation time.

## What Changed

- `AGENT_CHAT_DIRECTIVE` status-update guidance: when the agent
describes what the company, a project or agents are doing now, it states
a UTC clock time, such as "As of 15:26 UTC". It uses the latest
message's timestamp unless a record it read gives a later time.
- A regression test checks that the directive contains this guidance.

## Verification

- `cd server && npx vitest run src/__tests__/agent-conversations.test.ts
src/__tests__/heartbeat-list.test.ts` passes (includes the prompt-size
limits).
- The chat-catalog eval `activity.company-overview` now grades a real
observation time (stacked eval PR on `chat-eval/master-candidate`). This
fix is cherry-picked onto that eval branch for the next live run. No
live run has used it yet.

## Risks

- Low risk. This is one guidance sentence. Overviews get one extra
clause with a time.
- The time is the message time, not a server clock read. Reads happen
seconds after the message, so the difference is small.

## Model Used

- Anthropic Claude Opus 5.5 (`claude-opus-5-5`), with tool use and code
execution in Claude Code.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DottaandClaude Opus 5.5 authored and GitHub committed 2026-11-09 10:56:38 -06:00
1 parent 12523fb677
commit 0cf70c9d0c
2 files changed
+6 -1

No files matched your search

@@ -1021,6 +1021,11 @@ describe("chat prompt policy", () => {
expect(AGENT_CHAT_DIRECTIVE).toContain("to your own /permissions page, where they can turn on hiring for you");
});
it("tells chat overviews to state their observation time from the message timestamp", () => {
expect(AGENT_CHAT_DIRECTIVE).toContain("say when that picture is from as a clock time in UTC, such as \"As of 15:26 UTC\"");
expect(AGENT_CHAT_DIRECTIVE).toContain("Use the time of the person's latest message, which this prompt lists with each new comment");
});
it("tells chat to link the agent profile page that holds a control, including the unlisted API keys page", () => {
expect(AGENT_CHAT_DIRECTIVE).toContain("/<prefix>/agents/<urlKey or id>/api-keys for API keys");
expect(AGENT_CHAT_DIRECTIVE).toContain("The API keys page is not in the profile's navigation");
+1 -1
View File
@@ -134,7 +134,7 @@ This conversation and your credentials belong to one company. A task identifier
Tasks and projects in this company can be private. A private task is hidden from you unless you have access to it: your searches, lists and direct lookups leave it out or return not found, even when the person who asks can open it. So when the person refers to a task in this company that one search does not find, especially one they call private, it may be private rather than missing. Do not search for it further through other tools, endpoints, files or activity records, and do not guess its content. Say that this chat cannot see that task, possibly because it is private, and that if they want you to work on it they can open the task and share it with you from its sharing controls, or paste the parts they want here.
For status updates, distinguish recorded task status from active execution and verified progress. Read the latest relevant comments and run outcome before explaining a blocker or claiming work is underway. Use the advertised API tools for another task's details when needed. A completed dependency does not prove a block is stale; report the assignee's recorded reason. Agent configuration may be redacted: an empty configuration object without configuration-read permission does not prove settings are disabled or at their defaults. If the evidence is unavailable, say what you could verify and what remains unknown rather than guessing or recommending a status change.
For status updates, distinguish recorded task status from active execution and verified progress. Read the latest relevant comments and run outcome before explaining a blocker or claiming work is underway. Use the advertised API tools for another task's details when needed. A completed dependency does not prove a block is stale; report the assignee's recorded reason. Agent configuration may be redacted: an empty configuration object without configuration-read permission does not prove settings are disabled or at their defaults. If the evidence is unavailable, say what you could verify and what remains unknown rather than guessing or recommending a status change. When you describe what the company, a project or agents are doing now, say when that picture is from as a clock time in UTC, such as "As of 15:26 UTC". Use the time of the person's latest message, which this prompt lists with each new comment, unless a record you read gives a later time. Words such as "right now" do not tell the person how current the picture is.
Keep discussion here and leave the conversation available for the next message. Link handed-off tasks in your reply; do not make this conversation blocked by their completion or wait for them. Paperclip will bring completed handed-off tasks back as a new input here so you can explain the result and link it without another user message. After creating an assigned task, let its own run execute the work; do not create its deliverables or change its execution status from this chat. Reply normally and end your turn; Paperclip manages the conversation waiting state. Do not change its status, create a review confirmation just to finish a reply, mark it complete, or poll for another reply. An accepted plan authorizes handoff to execution tasks, never implementation on this conversation. Honor normal approvals. Ask mode is non-mutating. Plan mode supports research and writing/revising the plan; hand off for execution only through the normal authorized workflow.`;