feat(409): the reporting reflex reaches every surface a session reads (#4012)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / integration (push) Successful in 53s
CI & Build / TypeScript typecheck (push) Successful in 55s
CI & Build / Python tests (push) Successful in 1m28s
CI & Build / Build & push image (push) Successful in 31s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / integration (push) Successful in 53s
CI & Build / TypeScript typecheck (push) Successful in 55s
CI & Build / Python tests (push) Successful in 1m28s
CI & Build / Build & push image (push) Successful in 31s
Step 3 of milestone 409 "Response shapes". Step 2's reporting-back skill only helps if it fires, and only exists in the Claude Code plugin. - scribe_static_context.md and using-scribe (new reflex 11) say: report back in a shape the operator can read, placed from the `placement` block rather than memory, and point at the reporting-back skill. using-scribe also lists it among the sibling process-skills. - update_task returns a one-line `report_back` cue when a task is closed (done or cancelled). A tool response is the only surface every MCP client sees, at the moment the report is about to be written. - _INSTRUCTIONS takes no line: there is no budget without trading out a session-start reflex. The decision is recorded in server.py's comment block so it is not re-litigated blind. - Guards: test_instruction_surfaces_agree pins the reflex and the placement pointer on both plugin surfaces; a tool test pins the cue on closing statuses and its absence on every other update. Plugin version minted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,13 @@ from quart import Quart
|
||||
# competing for the last ~68 characters, so an addition here is a trade, never
|
||||
# an append.
|
||||
#
|
||||
# Milestone 409 step 3 (reporting back to the operator in a readable shape)
|
||||
# took NO line here, deliberately: there is no room without trading out a
|
||||
# session-start reflex, and the moment it applies is when a task closes. So it
|
||||
# rides in-band instead — update_task returns `placement` and a one-line
|
||||
# `report_back` cue on done/cancelled, which every MCP client sees — with the
|
||||
# full shapes in the reporting-back skill and the static context.
|
||||
#
|
||||
# Milestone 317 (a note's own verify_with / expires_when, and the sweep over
|
||||
# them) was DECLINED a line, deliberately, by the operator — not overlooked.
|
||||
# The reasoning, so it is not re-litigated blind: this is a map, and its own
|
||||
|
||||
@@ -271,6 +271,9 @@ async def update_task(
|
||||
work sits and what comes next — read them from here rather than
|
||||
reconstructing them, because a remembered milestone title or "next step"
|
||||
reads exactly like a real one when it is wrong.
|
||||
|
||||
Closing a task (done or cancelled) also returns `report_back`: a one-line
|
||||
reminder of what the reply to the operator should cover.
|
||||
"""
|
||||
uid = current_user_id()
|
||||
fields: dict = {}
|
||||
@@ -308,7 +311,10 @@ async def update_task(
|
||||
await systems_tools.attach_systems(
|
||||
uid, getattr(note, "user_id", uid) or uid, data, task_id, note.project_id
|
||||
)
|
||||
return await placement_svc.attach_placement(uid, data, note)
|
||||
await placement_svc.attach_placement(uid, data, note)
|
||||
if status in _CLOSING_STATUSES:
|
||||
data["report_back"] = REPORT_BACK_CUE
|
||||
return data
|
||||
|
||||
|
||||
async def add_task_log(task_id: int, content: str) -> dict:
|
||||
@@ -344,6 +350,17 @@ async def add_task_log(task_id: int, content: str) -> dict:
|
||||
return data
|
||||
|
||||
|
||||
# The in-band half of milestone 409 step 3. The reporting-back skill and the
|
||||
# static context carry the full shapes, but both live only in the Claude Code
|
||||
# plugin; a tool response reaches every MCP client, at the moment a piece of
|
||||
# work closes, which is exactly when the report is about to be written. One
|
||||
# line on purpose: a template here would be read as the reply itself.
|
||||
_CLOSING_STATUSES = ("done", "cancelled")
|
||||
REPORT_BACK_CUE = (
|
||||
"Reporting this to the operator? Say where it sits (from `placement`), "
|
||||
"what now works, what needs them, and what comes next."
|
||||
)
|
||||
|
||||
_ITEM_KEYS = {"title", "body", "type", "status", "priority", "kind", "tags", "system_ids"}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user