docs(6206): routes/plugin comments drop record and milestone citations
The pre-tool rules docstring says why action rules need their own surface instead of narrating that they once lived in the preload; the write-path checkpoint note states the reason the hook never blocks rather than whose decision it was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+33
-35
@@ -72,14 +72,14 @@ async def session_context():
|
||||
unbound repo yields a "bind this repo" hint instead. This is how the
|
||||
active project is determined — the plugin never pins a project id.
|
||||
project_id (optional int) — the project named directly, and the only
|
||||
key a caller outside a git repo has (#4085): the plugin's hooks
|
||||
key a caller outside a git repo has: the plugin's hooks
|
||||
send it when a `.scribe` marker file names a project. Takes
|
||||
precedence over `repo`. Access-checked like any other read — an id
|
||||
this account cannot read loads no project rather than failing.
|
||||
source (optional str) — the host's SessionStart source (startup,
|
||||
resume, compact, clear, fork); decides what the claim section says.
|
||||
session_id (optional str) — the session's id, so a claim bound to it
|
||||
reads as this session's own (milestone 381).
|
||||
reads as this session's own.
|
||||
"""
|
||||
project_id, _repo, unbound_repo = await _project_scope()
|
||||
result = await plugin_ctx_svc.build_session_context(
|
||||
@@ -109,7 +109,7 @@ async def autoinject_retrieve():
|
||||
project_id (opt) — explicit project scope override (ad-hoc/testing).
|
||||
exclude_ids (opt) — comma-separated note ids already injected this
|
||||
session; skipped so each note injects at most once.
|
||||
ctx (opt) — the tail of the last assistant reply (#4364). The
|
||||
ctx (opt) — the tail of the last assistant reply. The
|
||||
notes AND rule arms append it to a short prompt,
|
||||
so a follow-up like "yes do that" still names
|
||||
what it is about — and a rule or lesson arrives
|
||||
@@ -119,22 +119,22 @@ async def autoinject_retrieve():
|
||||
(opt) session. SHARED with /prior-art and /tool-rules on
|
||||
purpose: one session keeps ONE rule ledger, so a
|
||||
rule named by any arm is not re-announced by
|
||||
another. Ages out (#3751), so salience decays.
|
||||
another. Ages out, so salience decays.
|
||||
held_rule_ids — comma-separated rule ids the session actually
|
||||
(opt) OPENED, observed from the `get_rule` call itself
|
||||
rather than claimed. A rule on exclude_rule_ids
|
||||
was NAMED; a rule here was READ, and the two say
|
||||
different things about what the reader holds —
|
||||
so they get different lines (#4100). Shares the
|
||||
so they get different lines. Shares the
|
||||
ledger directory and the same clear-on-compact.
|
||||
shapes_seen (opt) — comma-separated reply-shape keys this session was
|
||||
already shown in full (milestone 500). The core
|
||||
already shown in full. The core
|
||||
goes out in full when `core` is absent, as its
|
||||
one-line reminder when present; the hook's
|
||||
ledger is swept on compaction, which is how the
|
||||
full core comes back after one.
|
||||
|
||||
THE TURN'S REPLY SHAPE COMES FIRST (milestone 500 step 3). Every turn ends
|
||||
THE TURN'S REPLY SHAPE COMES FIRST. Every turn ends
|
||||
in a reply and this is the last point before it is written, so the core
|
||||
shape and whatever is mounted on `reply.report` lead the payload. Fresh
|
||||
shape keys come back as `shape_keys` for the ledger.
|
||||
@@ -165,7 +165,7 @@ async def autoinject_retrieve():
|
||||
g.user.id, q, project_id=project_id, exclude_ids=exclude_ids, context=ctx,
|
||||
)
|
||||
# The one place both arms' lines meet, so the one place a lesson and a
|
||||
# rule arriving TOGETHER can be counted (#4637). Keyed on the operator's
|
||||
# rule arriving TOGETHER can be counted. Keyed on the operator's
|
||||
# prompt — the situation — and fails open to "".
|
||||
proposal = await lesson_rules_svc.co_surfaced(
|
||||
g.user.id, result.get("lesson_ids") or [], rules.get("shown_rule_ids") or [],
|
||||
@@ -191,13 +191,13 @@ async def autoinject_retrieve():
|
||||
@login_required
|
||||
@memoized_query_embeddings
|
||||
async def pre_tool_rules():
|
||||
"""Standing rules for the plugin's PreToolUse hook on ACTIONS (#3476).
|
||||
"""Standing rules for the plugin's PreToolUse hook on ACTIONS.
|
||||
|
||||
Answers "does a recorded rule speak to the command about to be run?" — the
|
||||
sibling of /prior-art, which can only answer that question about a code
|
||||
write. Rules about which tool to reach for (don't curl the forge, don't
|
||||
stand up a stack, don't run the suite locally) had no retrieval surface at
|
||||
all before this, which is why they all had to live in the resident preload.
|
||||
stand up a stack, don't run the suite locally) have no other retrieval
|
||||
surface: no code write ever happens for them to ride on.
|
||||
|
||||
Titles + trigger only, never the statement: the hint says a rule may apply
|
||||
and hands over `get_rule(id)`. One rule at most (RULEHINT_LIMIT), and empty
|
||||
@@ -219,18 +219,17 @@ async def pre_tool_rules():
|
||||
held_rule_ids (opt) — rule ids the session actually OPENED, as
|
||||
against merely named. Named and read are
|
||||
different claims about the reader's
|
||||
context, so they get different lines
|
||||
(#4100).
|
||||
context, so they get different lines.
|
||||
root, cwd (opt) — the repo's absolute root and the command's
|
||||
working directory. They turn the paths the
|
||||
command names into repo-relative ones, for
|
||||
the rulings arm (milestone 444).
|
||||
the rulings arm.
|
||||
seen_ruling_systems (opt) — comma-separated System ids whose rulings
|
||||
were already shown this session, by either
|
||||
arm; those get a one-line reference. SHARED
|
||||
with /prior-art, like exclude_rule_ids.
|
||||
|
||||
Returns `context`, `rule_ids`, and `checkpoint` (#4214, milestone 419),
|
||||
Returns `context`, `rule_ids`, and `checkpoint`,
|
||||
plus `ruling_system_ids` — the Systems whose rulings were shown in full on
|
||||
this call — when there were any.
|
||||
|
||||
@@ -268,7 +267,7 @@ async def pre_tool_rules():
|
||||
@plugin_bp.get("/moment-tools")
|
||||
@login_required
|
||||
async def moment_tools():
|
||||
"""The tools whose calls can deliver a mounted rule (milestone 458 step 4).
|
||||
"""The tools whose calls can deliver a mounted rule.
|
||||
|
||||
Read by the plugin's catch-all PreToolUse hook once per session window and
|
||||
kept on disk, so a call that cannot reach a mounted rule costs no request.
|
||||
@@ -282,7 +281,7 @@ async def moment_tools():
|
||||
@plugin_bp.post("/moment")
|
||||
@login_required
|
||||
async def moment():
|
||||
"""The rules mounted on the moments this tool call reaches (milestone 458).
|
||||
"""The rules mounted on the moments this tool call reaches.
|
||||
|
||||
Body: the PreToolUse event as Claude Code delivers it — `tool_name` and
|
||||
`tool_input` are read, nothing else. Sent whole because which input field
|
||||
@@ -298,7 +297,7 @@ async def moment():
|
||||
`moments` (the names reached). A lookup, not a ranked search: no
|
||||
retrieval_logs row; each fresh rule is recorded surfaced with its moment.
|
||||
|
||||
A moment that carries a default reply shape (milestone 500) brings it too,
|
||||
A moment that carries a default reply shape brings it too,
|
||||
ahead of the rules: in full unless `shapes_seen` names it, then as its
|
||||
reminder. `shape_keys` are the ones sent in full, for the hook's ledger.
|
||||
"""
|
||||
@@ -330,7 +329,7 @@ async def moment():
|
||||
@plugin_bp.post("/rule-opened")
|
||||
@login_required
|
||||
async def rule_opened():
|
||||
"""A session opened a rule shortly after these acts (milestone 458 step 7).
|
||||
"""A session opened a rule shortly after these acts.
|
||||
|
||||
Body: `{"rule_id", "session_id", "acts": [<PreToolUse event>, ...]}` —
|
||||
the calls the plugin saw in the window before the `get_rule`. Each is
|
||||
@@ -360,16 +359,15 @@ async def rule_opened():
|
||||
@login_required
|
||||
@memoized_query_embeddings
|
||||
async def reply_rules():
|
||||
"""Whether the reply that ends a turn is held for one read (milestone 458).
|
||||
"""Whether the reply that ends a turn is held for one read.
|
||||
|
||||
Called by the plugin's Stop hook with the finished reply. Two halves: the
|
||||
rules MOUNTED on the reply moments (`reply.report`, and `reply.ask` when
|
||||
the reply asks something), and the reply text against every rule's
|
||||
trigger — the backstop for whatever the earlier arms missed.
|
||||
|
||||
ONE END-OF-TURN REQUEST (milestone 500 step 4): a reply that closed tasks
|
||||
is also checked here for the completion sections (services/report_check),
|
||||
which used to be a Stop hook and an endpoint of its own. Both holds fold
|
||||
ONE END-OF-TURN REQUEST: a reply that closed tasks is also checked here
|
||||
for the completion sections (services/report_check). Both holds fold
|
||||
into one `reason`; `report_check` says what the section check recorded, so
|
||||
the hook knows the rewrite is one to report.
|
||||
|
||||
@@ -447,7 +445,7 @@ async def write_path_prior_art():
|
||||
exclude_ids (opt) — comma-separated REUSE-class ids already surfaced
|
||||
this session.
|
||||
exclude_sync_ids (opt) — comma-separated SYNC-class ids (snippets
|
||||
recorded AT the edited file, #2708) already
|
||||
recorded AT the edited file) already
|
||||
surfaced. A separate channel on purpose: a reuse
|
||||
hint shown early must not suppress the record-sync
|
||||
nudge when the recorded file is edited later.
|
||||
@@ -458,31 +456,31 @@ async def write_path_prior_art():
|
||||
every subsequent write.
|
||||
held_rule_ids (opt) — RULE ids the session actually OPENED, as
|
||||
against merely named; drives the third
|
||||
reference wording (#4100).
|
||||
reference wording.
|
||||
exclude_derive (opt) — comma-separated derive keys (a derive group id
|
||||
or `canon:<snippet_id>`) already named this
|
||||
session by the ledger arm (#2900); its own
|
||||
session by the ledger arm; its own
|
||||
channel, like the two above.
|
||||
seen_ruling_systems (opt) — System ids whose rulings were already shown
|
||||
this session (milestone 444); shared with
|
||||
this session; shared with
|
||||
/tool-rules. The response's `ruling_system_ids`
|
||||
are the ones shown in full on this call.
|
||||
(Returns a `checkpoint` block on the same contract as /tool-rules —
|
||||
see that endpoint. The write-path HOOK deliberately does not act on
|
||||
it: scribe_prior_art.sh carries a tested property that it never
|
||||
returns a permissionDecision, on the operator's decision that a recall
|
||||
aid may not stand in the way of a write. The block is computed and
|
||||
returns a permissionDecision, because a recall aid must not stand in
|
||||
the way of a write. The block is computed and
|
||||
returned so that decision can be revisited with evidence rather than
|
||||
re-argued, and so a change of mind is a hook edit and not a feature.)
|
||||
|
||||
shapes (opt) — comma-separated `kind:name` definitions the hook
|
||||
found in (or enclosing) the payload, kind being
|
||||
css|sym. The shape ledger's write-path feed
|
||||
(#2791): when the session recently PULLED a
|
||||
css|sym. The shape ledger's write-path feed:
|
||||
when the session recently PULLED a
|
||||
snippet this payload references or resembles,
|
||||
these carry it as a proposal — evidence for the
|
||||
agent's own end-of-turn judgment, never a
|
||||
verdict (milestone 439). Honoured only for a
|
||||
verdict. Honoured only for a
|
||||
caller allowed to write — a read-scoped key still
|
||||
gets the hint, and never changes the ledger on a
|
||||
GET.
|
||||
@@ -537,7 +535,7 @@ def _parse_shapes(raw: str) -> list[tuple[str, str]]:
|
||||
@plugin_bp.get("/shape-check")
|
||||
@login_required
|
||||
async def shape_check():
|
||||
"""The end-of-turn question (milestone 439): what did this turn write that
|
||||
"""The end-of-turn question: what did this turn write that
|
||||
nobody has judged?
|
||||
|
||||
The client's write hooks keep a ledger of the definitions each turn wrote;
|
||||
@@ -602,7 +600,7 @@ async def shape_check():
|
||||
@plugin_bp.get("/claim-session")
|
||||
@login_required
|
||||
async def claim_session():
|
||||
"""Bind the harness's session id to the caller's live claim on a task (milestone 381).
|
||||
"""Bind the harness's session id to the caller's live claim on a task.
|
||||
|
||||
Called by `scribe_claim_session.sh` after `update_task` / `add_task_log`.
|
||||
The server has already stamped the claim on that write; this only says
|
||||
@@ -631,7 +629,7 @@ async def claim_session():
|
||||
@plugin_bp.get("/release-session")
|
||||
@login_required
|
||||
async def release_session():
|
||||
"""Release the claims a session held, as it ends (milestone 381 step 4).
|
||||
"""Release the claims a session held, as it ends.
|
||||
|
||||
Called by `scribe_session_end.sh`. Best-effort by design: SessionEnd does
|
||||
not fire on a crash, so the claim's lease — not this call — is what makes a
|
||||
|
||||
Reference in New Issue
Block a user