Skip to content

I3301 — A Claude Code session that stops with an active task is told what the task still owes

Wire the provider's Stop event to a generated shim that reads the active task's owed obligations from the running shared server's obligations capability and reports them, never blocking a stop.

BLOCKED wave 1 · p3 · implementation profile · parallel safe

Part of a-provider-carries-the-contract-natively — Each agent client carries the contract through its own extension points, generated once and checked for drift.

Blocked. This issue cannot start until I3304 is done. The status is derived from that, not declared.

Objective

Wire the provider's Stop event to a generated shim that reads the active task's owed obligations from the running shared server's obligations capability and reports them, never blocking a stop.

Why

Prevention instead of after-the-fact detection was the owner's ask (10-02, 10-08); the edit-time judgement exists (I2735, case 3069) and is wired by I3322; the finish-time half does not. Rebound to the new intent criterion #stop-reports-owed. It does not serve #unclaimed-edit-refused, because it does not touch the edit guard. Claude Code's Stop event fires per turn, and finish --check is a cold shell start whose owed list disagreed with finish in field report #19, so the obligations capability is the source. The acceptance criterion that named finish --check was removed for the server-backed criteria. Proposed in ADR 0214 (A provider's native extension points carry the contract as generated projections; Majordomus neither embeds nor patches the worker's runtime) (proposed; it carries no authority until the owner accepts it). Sources: chatgpt-majordomus:c193#1.

Current state

.claude/settings.json wires UserPromptSubmit, SessionStart, SessionEnd, PreCompact; no Stop hook.

Desired state

A Stop shim generated with the others; a case proves the owed list reaches the session.

Scope

  • lib/capture.sh
  • .claude/hooks
  • share/providers.yaml
  • apps/majordomus-cli/src/capability/builtin/obligations.rs

Dependencies

Acceptance criteria

  • A stop with no task returns nothing and costs under the hook budget
  • The Stop hook never blocks; the owed list reaches the person through the Stop output's user-visible message, and the model receives it in the next UserPromptSubmit context; both behaviours are verified against the detected Claude Code version and recorded in share/providers.yaml
  • The owed list is read from the running shared server's obligations capability (obligation_closure), not from a cold finish --check; with no server the hook prints nothing and starts nothing
  • A case proves the hook's owed list matches what finish refuses on, including note-integrity (field report #19)

Validation

  • bash test/run.sh 54_session_lifecycle_hooks
  • bash test/run.sh 170_provider_lifecycle_declared

Evidence required

  • case_a_stop_reports_what_is_owed

Evidence

None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.

Timeline

started
—
verified
—
completed
—

Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.

Canonical record: .ai/repo/project/issues/I3301.yaml. Read it back with majordomus plan show I3301.

Searches the titles and descriptions of every page this site publishes.