feat(tasks): SessionStart reads the claim — a compaction gets its work back (milestone 381 step 3)
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 50s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / Python tests (push) Successful in 1m35s
CI & Build / Build & push image (push) Canceled after 45s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 50s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / Python tests (push) Successful in 1m35s
CI & Build / Build & push image (push) Canceled after 45s
The claim now pays rent to the session that set it. The SessionStart hook sends the host's `source` and the session id; the server renders a claim section by source (task_claims.render_claims): - compact / clear: the work this session had claimed, each with its two latest log entries, so a compacted session resumes from the record rather than from a count of open tasks. - startup / clear: other sessions' live claims (may still be running) and in-progress tasks whose claim went quiet (abandoned mid-task). - fork: the same, framed as "two sessions may now hold this". - resume, or no source sent: nothing. The task sidebar shows a live claim as "Being worked" and a dead one on open work as "Went quiet", so the operator sees a session die mid-task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ from scribe.services import notes as notes_svc
|
||||
from scribe.services import projects as projects_svc
|
||||
from scribe.services import shape_ledger as shape_ledger_svc
|
||||
from scribe.services import snippets as snippets_svc
|
||||
from scribe.services import task_claims as task_claims_svc
|
||||
from scribe.services.access import label_shared_items, owner_names_for
|
||||
from scribe.services.embeddings import (
|
||||
document_title,
|
||||
@@ -3055,7 +3056,8 @@ def _goal_line(goal: str, project_id: int) -> str:
|
||||
|
||||
|
||||
async def build_session_context(
|
||||
user_id: int, project_id: int = 0, unbound_repo: str = ""
|
||||
user_id: int, project_id: int = 0, unbound_repo: str = "",
|
||||
source: str = "", session_id: str = "",
|
||||
) -> dict:
|
||||
"""Render the SessionStart context for a user, optionally project-scoped.
|
||||
|
||||
@@ -3069,6 +3071,12 @@ async def build_session_context(
|
||||
unbound_repo: when the hook sent a repo remote that maps to no project,
|
||||
its normalized key — triggers a one-line "bind this repo" hint so
|
||||
the binding is self-healing.
|
||||
source / session_id: the host's SessionStart `source` and the
|
||||
session's id, when the adapter sends them. They decide what the
|
||||
claim section says (milestone 381 step 3, `task_claims.
|
||||
render_claims`): a compaction gets back the work it had claimed
|
||||
with its latest logs; a new session hears about other sessions'
|
||||
live and abandoned claims; a resume hears nothing.
|
||||
|
||||
Returns {"context": str, "project": dict | None}.
|
||||
|
||||
@@ -3135,6 +3143,17 @@ async def build_session_context(
|
||||
f"`get_design_system({design['id']})` → "
|
||||
f"`resolved_guidance`.",
|
||||
]
|
||||
# The claim section goes after the project block and before any "nothing
|
||||
# loaded" note: claimed work is the most specific thing this session can be
|
||||
# told, and it is true whether or not a project resolved. Best-effort — a
|
||||
# session start never fails on it.
|
||||
try:
|
||||
lines += await task_claims_svc.claims_for_session_start(
|
||||
user_id, project_dict["id"] if project_dict else 0, source, session_id,
|
||||
)
|
||||
except Exception: # noqa: BLE001 - context is best-effort
|
||||
logger.warning("claim section skipped", exc_info=True)
|
||||
|
||||
# Nothing loaded — say which nothing (#4085). This used to hang off the
|
||||
# `if project_id:` above as an `elif`, which meant an id that was SENT and
|
||||
# did not resolve produced no message at all: the outer branch was taken,
|
||||
|
||||
Reference in New Issue
Block a user