Skill Tracer
Skills › Compound Engineering › ce-debug › return-to-caller.md

return-to-caller.md

58 lines · skills/ce-debug/references/return-to-caller.md at 3449230

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# ce-debug — return-to-caller mode (non-interactive, caller owns the steps after the fix)
2
3Loaded when `ce-debug` is invoked with `mode:return-to-caller` by an orchestrator such as `lfg` on its defect route. The caller asked for the bug fixed and owns everything after the fix: simplify, review, compound, commit of anything further, push, PR, and CI. This skill investigates, fixes, verifies, commits on a feature branch, and returns a structured result. It never pushes and never asks.
4
5This is not `mode:pipeline`. Pipeline mode serves the babysitter on a PR branch it already owns: it is seeded with failing jobs, pushes its own commit, and skips review because the babysitter scopes review. Here nothing is pushed and the caller reviews.
6

ce-debug — return-to-caller mode (non-interactive, caller owns the steps after the fix)

Loaded when ce-debug is invoked with mode:return-to-caller by an orchestrator such as lfg on its defect route. The caller asked for the bug fixed and owns everything after the fix: simplify, review, compound, commit of anything further, push, PR, and CI. This skill investigates, fixes, verifies, commits on a feature branch, and returns a structured result. It never pushes and never asks.

This is not mode:pipeline. Pipeline mode serves the babysitter on a PR branch it already owns: it is seeded with failing jobs, pushes its own commit, and skips review because the babysitter scopes review. Here nothing is pushed and the caller reviews.

Raw lines 1 to 6
Names a skill lfg :3
7## What stays the same
8
9Phases 0 through 3 run as the body defines them, with the investigation rigor unchanged: the causal-chain gate, reproduction, the escalation table, the test-first fix sequence in `references/fix.md`, and the issue-of-record rule. The **Branch** rule in Phase 3 applies in full: on the default branch, detached, or unsure, create a feature branch named from the bug before the first edit and say which branch you moved to. `/lfg fix this bug` invoked on `main` must not commit to `main`. The pre-fix scope record and the fix-owned file list are kept, because the return is built from them: the caller ships only what the user offered, and this return is the only place it can learn what was already in the tree or on the branch before the fix.

What stays the same

Phases 0 through 3 run as the body defines them, with the investigation rigor unchanged: the causal-chain gate, reproduction, the escalation table, the test-first fix sequence in references/fix.md, and the issue-of-record rule. The Branch rule in Phase 3 applies in full: on the default branch, detached, or unsure, create a feature branch named from the bug before the first edit and say which branch you moved to. /lfg fix this bug invoked on main must not commit to main. The pre-fix scope record and the fix-owned file list are kept, because the return is built from them: the caller ships only what the user offered, and this return is the only place it can learn what was already in the tree or on the branch before the fix.

Raw lines 7 to 10
11## What changes
13- **Phase 0:** if an issue fetch fails, continue with the input you have and record the gap in the return. Never ask the user to paste content.
14- **Phase 2 gate:** there is no fix-choice question. The caller's invocation authorized the fix, so proceed to Phase 3 with a **convergent** fix only. A **divergent** fix, one that would reverse a deliberate contract, behavior, or product decision, including a "failing" test that asserts intended behavior, is deferred as `needs-human` with a `decision_context`, never applied. Never route to `ce-brainstorm`; a design problem is a `needs-human` residual. When reproduction cannot run in this environment, continue on the best evidence in reach; if the causal chain still has a gap, return `needs-human` naming what reproduction requires and what was tried.
15- **Phase 3:** apply the fix on the feature branch, verify it as `references/fix.md` defines (red then green where a test can run here; otherwise the reproduction check or characterization that file allows, recorded in the evidence), and commit only the fix-owned files. Follow the project's commit message conventions already in context; otherwise follow the recent log pattern, then conventional commits (`fix: <summary>` for this bug). User override wins. Do not push. A file the fix must touch that already carries the user's uncommitted edits stops the run before the first edit to it: return `blocked` naming the file, with nothing applied, since no commit could separate their edits from the fix and the caller cannot answer for the user. A caller's statement that the user offered those edits does not change this. Edits the caller made itself for the work the user asked for, before invoking this skill, are not the user's. When they sit in a fix-owned file, commit that file with the fix and list it in `pre_fix_scope.caller_edits`; caller edits in other files stay untouched in `dirty_files`. The pre-fix scope record makes this known before Phase 3 edits anything.
16- **Phase 4:** skip the Debug Summary block, the post-fix polish and review steps (`references/post-fix-handoff.md`), the commit/PR routing, and the learning-capture offer. Emit the structured return below as the last thing this skill writes. The return ends this skill, not the turn. The caller runs in this same session, and its next step follows the return.

What changes

  • Phase 0: if an issue fetch fails, continue with the input you have and record the gap in the return. Never ask the user to paste content.
  • Phase 2 gate: there is no fix-choice question. The caller's invocation authorized the fix, so proceed to Phase 3 with a convergent fix only. A divergent fix, one that would reverse a deliberate contract, behavior, or product decision, including a "failing" test that asserts intended behavior, is deferred as needs-human with a decision_context, never applied. Never route to ce-brainstorm; a design problem is a needs-human residual. When reproduction cannot run in this environment, continue on the best evidence in reach; if the causal chain still has a gap, return needs-human naming what reproduction requires and what was tried.
  • Phase 3: apply the fix on the feature branch, verify it as references/fix.md defines (red then green where a test can run here; otherwise the reproduction check or characterization that file allows, recorded in the evidence), and commit only the fix-owned files. Follow the project's commit message conventions already in context; otherwise follow the recent log pattern, then conventional commits (fix: <summary> for this bug). User override wins. Do not push. A file the fix must touch that already carries the user's uncommitted edits stops the run before the first edit to it: return blocked naming the file, with nothing applied, since no commit could separate their edits from the fix and the caller cannot answer for the user. A caller's statement that the user offered those edits does not change this. Edits the caller made itself for the work the user asked for, before invoking this skill, are not the user's. When they sit in a fix-owned file, commit that file with the fix and list it in pre_fix_scope.caller_edits; caller edits in other files stay untouched in dirty_files. The pre-fix scope record makes this known before Phase 3 edits anything.
  • Phase 4: skip the Debug Summary block, the post-fix polish and review steps (references/post-fix-handoff.md), the commit/PR routing, and the learning-capture offer. Emit the structured return below as the last thing this skill writes. The return ends this skill, not the turn. The caller runs in this same session, and its next step follows the return.
Raw lines 11 to 17
Involves a person ask the user :13
Names a skill ce-brainstorm :14
18## Structured return
20The return is machine-readable; the caller parses it and branches on the exact `status` spellings, so never rename, abbreviate, or add to them.
22```json
24 "status": "fixed | diagnosed-no-fix | needs-human | blocked",
25 "summary": "<one line: what happened>",
26 "root_cause": "<the causal chain, trigger to symptom, with file:line references>",
27 "changed_files": ["<fix-owned files, tests included>"],
28 "head_sha": "<sha of the fix commit, when fixed>",
29 "branch": "<branch the fix was committed on, when fixed>",
30 "pre_fix_scope": {
31 "head": "<HEAD before the fix commit>",
32 "dirty_files": ["<files already modified or untracked before Phase 3 that are not fix-owned; left untouched>"],
33 "caller_edits": ["<fix-owned files that already carried the calling session's own uncommitted edits, committed with the fix>"],
34 "commits_beyond_base": ["<commits the branch carried beyond the default branch before the fix, oldest first; empty on a fresh branch>"],
35 "started_on_default_branch": false
36 },
37 "behavior_change": true,
38 "verification_evidence": {
39 "regression_test": "<file and case>",
40 "existing_tests_inspected": ["..."],
41 "tests_added_or_changed": ["..."],
42 "red_before_fix": "<the failure observed before the fix, or the characterization when a red run was impossible>",
43 "verification_run": "<commands and results>",
44 "exception_reason": null
45 },
46 "residuals": [ { "type": "needs-human", "sources": [ ... ], "decision_context": { ... }, "thread_urls": [] } ],
47 "issue_of_record": { "id": "<identifier>", "url": "<url>" },
48 "blockers": [],
49 "standalone_shipping_skipped": true
51```
53- `fixed`: a convergent fix is applied, its regression test went red then green, and the fix-owned files are committed on the feature branch. Nothing was pushed.
54- `diagnosed-no-fix`: the root cause is established but no safe convergent fix exists this run; `residuals` says why.
55- `needs-human`: the fix would be divergent, or the causal chain could not be closed without a decision only a person can make; nothing applied; `residuals` carries the `decision_context` in the same typed residual contract `references/pipeline-mode.md` defines.
56- `blocked`: a required read failed, a fix-owned file carried the user's edits, or the workspace could not be prepared; `blockers` names it and nothing was committed.
58`pre_fix_scope` is present on every return and records what the branch and tree carried before the fix, as observed facts: the pre-fix `HEAD`, the files that were already dirty and are not fix-owned (the fix never touched them), the fix-owned files that carried the calling session's own edits, and the commits beyond the default branch, pushed or not. It carries no verdict about what the user offered; the caller decides that, and this record is what it decides from. `issue_of_record` is `null` when the input carried no ticket. `verification_evidence` is present on every `fixed` return; when `behavior_change` is `false` (a pure test or tooling fix), `exception_reason` says why no red-then-green was possible. `residuals` is an empty array when there are none. Do not invent a residual type; a non-blocking follow-up goes in `summary`.

Structured return

The return is machine-readable; the caller parses it and branches on the exact status spellings, so never rename, abbreviate, or add to them.

{
  "status": "fixed | diagnosed-no-fix | needs-human | blocked",
  "summary": "<one line: what happened>",
  "root_cause": "<the causal chain, trigger to symptom, with file:line references>",
  "changed_files": ["<fix-owned files, tests included>"],
  "head_sha": "<sha of the fix commit, when fixed>",
  "branch": "<branch the fix was committed on, when fixed>",
  "pre_fix_scope": {
    "head": "<HEAD before the fix commit>",
    "dirty_files": ["<files already modified or untracked before Phase 3 that are not fix-owned; left untouched>"],
    "caller_edits": ["<fix-owned files that already carried the calling session's own uncommitted edits, committed with the fix>"],
    "commits_beyond_base": ["<commits the branch carried beyond the default branch before the fix, oldest first; empty on a fresh branch>"],
    "started_on_default_branch": false
  },
  "behavior_change": true,
  "verification_evidence": {
    "regression_test": "<file and case>",
    "existing_tests_inspected": ["..."],
    "tests_added_or_changed": ["..."],
    "red_before_fix": "<the failure observed before the fix, or the characterization when a red run was impossible>",
    "verification_run": "<commands and results>",
    "exception_reason": null
  },
  "residuals": [ { "type": "needs-human", "sources": [ ... ], "decision_context": { ... }, "thread_urls": [] } ],
  "issue_of_record": { "id": "<identifier>", "url": "<url>" },
  "blockers": [],
  "standalone_shipping_skipped": true
}
  • fixed: a convergent fix is applied, its regression test went red then green, and the fix-owned files are committed on the feature branch. Nothing was pushed.
  • diagnosed-no-fix: the root cause is established but no safe convergent fix exists this run; residuals says why.
  • needs-human: the fix would be divergent, or the causal chain could not be closed without a decision only a person can make; nothing applied; residuals carries the decision_context in the same typed residual contract references/pipeline-mode.md defines.
  • blocked: a required read failed, a fix-owned file carried the user's edits, or the workspace could not be prepared; blockers names it and nothing was committed.

pre_fix_scope is present on every return and records what the branch and tree carried before the fix, as observed facts: the pre-fix HEAD, the files that were already dirty and are not fix-owned (the fix never touched them), the fix-owned files that carried the calling session's own edits, and the commits beyond the default branch, pushed or not. It carries no verdict about what the user offered; the caller decides that, and this record is what it decides from. issue_of_record is null when the input carried no ticket. verification_evidence is present on every fixed return; when behavior_change is false (a pure test or tooling fix), exception_reason says why no red-then-green was possible. residuals is an empty array when there are none. Do not invent a residual type; a non-blocking follow-up goes in summary.

Raw lines 18 to 58