Skill Tracer
Skills › Compound Engineering › ce-debug › pipeline-mode.md

pipeline-mode.md

78 lines · skills/ce-debug/references/pipeline-mode.md at 3449230

Open on GitHub

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

1# ce-debug — pipeline mode (non-interactive)
2
3Loaded when `ce-debug` is invoked with `mode:pipeline` by an orchestrator (`ce-babysit-pr`, `lfg`). The skill runs to completion without ever asking the user and returns a structured result the caller composes. The investigation rigor is unchanged. Only the interaction and the fix-authority boundary change.
4

ce-debug — pipeline mode (non-interactive)

Loaded when ce-debug is invoked with mode:pipeline by an orchestrator (ce-babysit-pr, lfg). The skill runs to completion without ever asking the user and returns a structured result the caller composes. The investigation rigor is unchanged. Only the interaction and the fix-authority boundary change.

Raw lines 1 to 4
Names a skill ce-babysit-pr :3
Names a skill lfg :3
5## Authority: you act under the orchestrator's inherited scope
6
7Being invoked by an orchestrator is **not** itself authorization. You mutate under the **inherited** scope the orchestrator holds from the user: **actions** = fix / commit / push on the current branch; **exclusions** = merge, rebase, force-push, approve a gated CI run. That authorized scope is fixed. You may *narrow* it (defer a fix, return `needs-human`) but never *broaden* it. If the only way to make CI green is an excluded action (a rebase or force-push to untangle history, or approving a gated run), that action is outside the authorized scope: **defer as `needs-human`** with a `decision_context`, do not perform it. This is a boundary on the *mechanism* of a change. It sits alongside the convergent/divergent *content* boundary below. A fix can be convergent in content yet still outside the authorized scope in mechanism.
8

Authority: you act under the orchestrator's inherited scope

Being invoked by an orchestrator is not itself authorization. You mutate under the inherited scope the orchestrator holds from the user: actions = fix / commit / push on the current branch; exclusions = merge, rebase, force-push, approve a gated CI run. That authorized scope is fixed. You may narrow it (defer a fix, return needs-human) but never broaden it. If the only way to make CI green is an excluded action (a rebase or force-push to untangle history, or approving a gated run), that action is outside the authorized scope: **defer as needs-human** with a decision_context, do not perform it. This is a boundary on the mechanism of a change. It sits alongside the convergent/divergent content boundary below. A fix can be convergent in content yet still outside the authorized scope in mechanism.

Raw lines 5 to 8
9## Non-interactive overrides (per phase)
11- **Phase 0 (triage):** If an issue fetch fails, do not ask the user to paste content. Proceed with the input you have and note the gap in the return. Do not ask "what have you tried"; infer prior attempts from the input.
12- **Phase 1 (reproduce):** When reproduction cannot run in this environment (a CI- or production-only failure), do not ask for access, artifacts, or a go-ahead. Continue on the best evidence already in reach: the failing job's logs, captured artifacts, the seeded log tails. If a gap-free root cause is still established, the ordinary statuses apply. If not, return `needs-human` with a `decision_context` naming what reproduction requires and what was tried.
13- **Phase 2 (root cause + fix gate):** There is no "Fix it now / Diagnosis only" question. The caller invoked this skill to fix, so **fix by default, but only convergent fixes** (see the boundary below). A divergent fix is deferred, not applied.
14- **Phase 3 (workspace/branch):** Operate on the current branch. The orchestrator decides branch context, so never prompt to create a branch and never prompt about uncommitted work. Commit the fix using the project's commit message conventions already in context; otherwise follow the recent log pattern, then use conventional commits (`fix(ci): <summary>` for a CI failure, `fix: <summary>` otherwise). User override wins. Push the fix. Never weaken, skip, or mock a failing assertion to make it pass. Repair the real issue or defer.
15- **Phase 4 (handoff):** No prompt. Emit the structured return below as the last thing this skill writes, then skip the compound offer. The return ends this skill, not the turn. The caller runs in this same session, and its next step follows the return.
16- **Post-fix simplify and review steps:** Skip them in pipeline to bound cost and nesting depth; the orchestrator scopes review at its own level. Keep the Phase 3 tests.

Non-interactive overrides (per phase)

  • Phase 0 (triage): If an issue fetch fails, do not ask the user to paste content. Proceed with the input you have and note the gap in the return. Do not ask "what have you tried"; infer prior attempts from the input.
  • Phase 1 (reproduce): When reproduction cannot run in this environment (a CI- or production-only failure), do not ask for access, artifacts, or a go-ahead. Continue on the best evidence already in reach: the failing job's logs, captured artifacts, the seeded log tails. If a gap-free root cause is still established, the ordinary statuses apply. If not, return needs-human with a decision_context naming what reproduction requires and what was tried.
  • Phase 2 (root cause + fix gate): There is no "Fix it now / Diagnosis only" question. The caller invoked this skill to fix, so fix by default, but only convergent fixes (see the boundary below). A divergent fix is deferred, not applied.
  • Phase 3 (workspace/branch): Operate on the current branch. The orchestrator decides branch context, so never prompt to create a branch and never prompt about uncommitted work. Commit the fix using the project's commit message conventions already in context; otherwise follow the recent log pattern, then use conventional commits (fix(ci): <summary> for a CI failure, fix: <summary> otherwise). User override wins. Push the fix. Never weaken, skip, or mock a failing assertion to make it pass. Repair the real issue or defer.
  • Phase 4 (handoff): No prompt. Emit the structured return below as the last thing this skill writes, then skip the compound offer. The return ends this skill, not the turn. The caller runs in this same session, and its next step follows the return.
  • Post-fix simplify and review steps: Skip them in pipeline to bound cost and nesting depth; the orchestrator scopes review at its own level. Keep the Phase 3 tests.
Raw lines 9 to 17
Involves a person ask the user :11
18## The fix-authority boundary: convergent vs divergent
20Apply a fix only when it **converges to intended behavior**. That means it repairs the real defect so the code meets its planned/tested intent (a genuine bug: null deref, off-by-one, a broken call, a regression against a test that encodes intended behavior).
22**Defer** (do not apply) any fix that would **diverge from intended behavior**: it would change a deliberate contract, API shape, default, or product/UX decision rather than repair a bug; or the "failure" is a test asserting a deliberate behavior that the fix would reverse; or making CI green would require a product/design call. This mirrors the `ce-resolve-pr-feedback` intent-conflict check. It requires evidence and is rare, and it is never a reason to dodge a real fix. When genuinely unsure whether a failure is a bug or a deliberate-behavior conflict, prefer deferring with a crisp `decision_context` over guessing.

The fix-authority boundary: convergent vs divergent

Apply a fix only when it converges to intended behavior. That means it repairs the real defect so the code meets its planned/tested intent (a genuine bug: null deref, off-by-one, a broken call, a regression against a test that encodes intended behavior).

Defer (do not apply) any fix that would diverge from intended behavior: it would change a deliberate contract, API shape, default, or product/UX decision rather than repair a bug; or the "failure" is a test asserting a deliberate behavior that the fix would reverse; or making CI green would require a product/design call. This mirrors the ce-resolve-pr-feedback intent-conflict check. It requires evidence and is rare, and it is never a reason to dodge a real fix. When genuinely unsure whether a failure is a bug or a deliberate-behavior conflict, prefer deferring with a crisp decision_context over guessing.

Raw lines 18 to 23
Names a skill ce-resolve-pr-feedback :22
24### Emergent trade-offs (when the caller passes a `trajectory`)
26Some divergence is not visible in one pass. It emerges across rounds as **ping-pong**: your fix for A causes B to appear, and the fix for B brings A back. When the orchestrator seeds you with a `trajectory` (`recurring_checks`, `check_recur_max`, `heads_since_progress`), reason over it before fixing again, and do not raise a false alarm:
28- **Progressive failure migration** (A fixed, B appears *once*, you fix B, done) is ordinary multi-step repair. **Keep fixing.** Do not park it.
29- **Oscillation** (the *same* check/invariant returns after a fix aimed at it, defects cycle, or each fix trades one failure for another) means A and B cannot both hold without a larger change. That larger change is a **product/design decision**, so **defer**: apply nothing this round and return `needs-human`, with a `decision_context` that names the two failures in tension, why they cannot be reconciled without a divergent change, the options, and your lean.
30- **Moving-target guard:** if the recurrence traces to an external cause (a base-branch merge, a dep bump, flaky infra) rather than your fixes fighting each other, it is *not* an emergent trade-off. Keep fixing, and note the external cause. Recurrence is only meaningful when your own fixes are what oscillate.
32To defer, name the invariant the fix would need to satisfy and why no bounded convergent change satisfies it. If unsure whether it is genuine oscillation or one more real bug, prefer one more convergent attempt over a premature park.

Emergent trade-offs (when the caller passes a trajectory)

Some divergence is not visible in one pass. It emerges across rounds as ping-pong: your fix for A causes B to appear, and the fix for B brings A back. When the orchestrator seeds you with a trajectory (recurring_checks, check_recur_max, heads_since_progress), reason over it before fixing again, and do not raise a false alarm:

  • Progressive failure migration (A fixed, B appears once, you fix B, done) is ordinary multi-step repair. Keep fixing. Do not park it.
  • Oscillation (the same check/invariant returns after a fix aimed at it, defects cycle, or each fix trades one failure for another) means A and B cannot both hold without a larger change. That larger change is a product/design decision, so defer: apply nothing this round and return needs-human, with a decision_context that names the two failures in tension, why they cannot be reconciled without a divergent change, the options, and your lean.
  • Moving-target guard: if the recurrence traces to an external cause (a base-branch merge, a dep bump, flaky infra) rather than your fixes fighting each other, it is not an emergent trade-off. Keep fixing, and note the external cause. Recurrence is only meaningful when your own fixes are what oscillate.

To defer, name the invariant the fix would need to satisfy and why no bounded convergent change satisfies it. If unsure whether it is genuine oscillation or one more real bug, prefer one more convergent attempt over a premature park.

Raw lines 24 to 33
34## Reporting a deferred (divergent / needs-human) item
36Never write a PR-body section. Never block. Report it so the human sees it after the run:
38- If it maps to an **open review thread**, leave that thread open (and attach the `decision_context` as a reply when a thread reply is in scope).
39- Otherwise, **return it in the `residuals` list** for the caller to place in its single run-report comment. For a bare `ce-debug` invocation with no orchestrator and no PR, file it as a ticket in the project's tracker (detected in Phase 1.4) with enough background to action it standalone. When no tracker is reachable, return it in the structured result and say plainly that nothing else recorded it.
41Return each decision in the shared typed residual contract. Its `sources` enumerate every item this one decision covers: each failing check key with `kind: "check"`, plus the stable ID and kind of every open review thread, comment, or review body represented by the same decision. `decision_context` contains the quoted failure, investigation, decision reason, options with tradeoffs, and nullable recommendation. `thread_urls` includes every owned open thread (every open thread this decision covers) and is empty only when no source is a thread. The caller persists and invalidates the complete source set as one unit, so never split, omit, or summarize which items a decision covers.

Reporting a deferred (divergent / needs-human) item

Never write a PR-body section. Never block. Report it so the human sees it after the run:

  • If it maps to an open review thread, leave that thread open (and attach the decision_context as a reply when a thread reply is in scope).
  • Otherwise, **return it in the residuals list** for the caller to place in its single run-report comment. For a bare ce-debug invocation with no orchestrator and no PR, file it as a ticket in the project's tracker (detected in Phase 1.4) with enough background to action it standalone. When no tracker is reachable, return it in the structured result and say plainly that nothing else recorded it.

Return each decision in the shared typed residual contract. Its sources enumerate every item this one decision covers: each failing check key with kind: "check", plus the stable ID and kind of every open review thread, comment, or review body represented by the same decision. decision_context contains the quoted failure, investigation, decision reason, options with tradeoffs, and nullable recommendation. thread_urls includes every owned open thread (every open thread this decision covers) and is empty only when no source is a thread. The caller persists and invalidates the complete source set as one unit, so never split, omit, or summarize which items a decision covers.

Raw lines 34 to 42
43## Structured return
45The return in pipeline mode is machine-readable (the caller parses it):
47```json
49 "status": "fixed-and-pushed | fixed-not-pushed | diagnosed-no-fix | flaky-infra | needs-human",
50 "summary": "<one line: what happened>",
51 "root_cause": "<causal chain, brief>",
52 "changed_files": ["..."],
53 "head_sha": "<sha of the fix commit, when fixed-and-pushed or fixed-not-pushed>",
54 "residuals": [
55 {
56 "type": "needs-human",
57 "sources": [
58 { "id": "<failing-check-key>", "kind": "check" },
59 { "id": "<owned-open-thread-id, when any>", "kind": "thread" }
60 ],
61 "decision_context": {
62 "quoted_feedback": "<the failure or constraint in tension>",
63 "investigation": "<what was inspected and found>",
64 "decision_reason": "<why no bounded convergent fix is safe>",
65 "options": [ { "option": "<choice>", "tradeoff": "<gain and loss>" } ],
66 "recommendation": "<lean and why, or null>"
67 },
68 "thread_urls": ["<URL for every owned open thread, or empty when none>"]
69 }
70 ]
72```
74- `fixed-and-pushed`: a convergent fix was applied, tests pass, committed, and the push succeeded.
75- `fixed-not-pushed`: the same fix is applied and committed locally, but the push did not happen (no remote, no push access, an authorized scope that excludes pushing, a rejected push). `head_sha` is the local commit; the first residual says why. Never report this as `fixed-and-pushed` (the caller re-snapshots a remote head that has not moved) or as `diagnosed-no-fix` (the fix is applied).
76- `flaky-infra`: a flake or infrastructure failure, not a code defect (the caller may retry).
77- `needs-human`: the failure requires a divergent/product decision; nothing applied; see `residuals`.
78- `diagnosed-no-fix`: root cause found but no safe convergent fix available this run; see `residuals`.

Structured return

The return in pipeline mode is machine-readable (the caller parses it):

{
  "status": "fixed-and-pushed | fixed-not-pushed | diagnosed-no-fix | flaky-infra | needs-human",
  "summary": "<one line: what happened>",
  "root_cause": "<causal chain, brief>",
  "changed_files": ["..."],
  "head_sha": "<sha of the fix commit, when fixed-and-pushed or fixed-not-pushed>",
  "residuals": [
    {
      "type": "needs-human",
      "sources": [
        { "id": "<failing-check-key>", "kind": "check" },
        { "id": "<owned-open-thread-id, when any>", "kind": "thread" }
      ],
      "decision_context": {
        "quoted_feedback": "<the failure or constraint in tension>",
        "investigation": "<what was inspected and found>",
        "decision_reason": "<why no bounded convergent fix is safe>",
        "options": [ { "option": "<choice>", "tradeoff": "<gain and loss>" } ],
        "recommendation": "<lean and why, or null>"
      },
      "thread_urls": ["<URL for every owned open thread, or empty when none>"]
    }
  ]
}
  • fixed-and-pushed: a convergent fix was applied, tests pass, committed, and the push succeeded.
  • fixed-not-pushed: the same fix is applied and committed locally, but the push did not happen (no remote, no push access, an authorized scope that excludes pushing, a rejected push). head_sha is the local commit; the first residual says why. Never report this as fixed-and-pushed (the caller re-snapshots a remote head that has not moved) or as diagnosed-no-fix (the fix is applied).
  • flaky-infra: a flake or infrastructure failure, not a code defect (the caller may retry).
  • needs-human: the failure requires a divergent/product decision; nothing applied; see residuals.
  • diagnosed-no-fix: root cause found but no safe convergent fix available this run; see residuals.
Raw lines 43 to 78