Skip to content

Commit 3082eb0

Browse files
authored
Merge pull request #486 from dmoliveira/fix/gateway-hook-stderr-overlay
Harden gateway hook error surfacing and build typing
2 parents a939660 + e2f36a5 commit 3082eb0

16 files changed

+930
-36
lines changed

docs/command-handbook.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ This index is sourced from `opencode.json` and is used as the complete catalog r
488488
/rules - Inspect conditional rules (status|explain|disable-id|enable-id|doctor)
489489
/safe-edit - Plan semantic safe-edit execution (status|plan|doctor)
490490
/session - Inspect indexed sessions (list|show|search|handoff|doctor)
491-
/ship - Run release intent preflight with safety gates and policy-aware reviewer routing
491+
/ship - Run release intent preflight, readiness diagnostics, delivery/release context summaries, and policy-aware reviewer routing (doctor|create-pr)
492492
/stack - Apply cross-command profile bundles
493493
/telemetry - Manage telemetry forwarding (status|doctor|profile|enable|disable|set)
494494
/todo - Inspect todo compliance state (status|enforce)

docs/plan/current-roadmap-tracker.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,16 @@ Delivered:
145145
- added lease-backed writer guarantee diagnostics and surfaced disjoint write parallel candidates
146146
- enabled a tiny lease-backed write-capable parallel allowlist for disjoint `implement` lanes
147147
- added lane-level `lease_identity` metadata and enforced it for writer activation
148+
- started E4 ops automation readiness diagnostics with `/ship doctor` and umbrella `/doctor` coverage for canonical issue/PR/release/hotfix flows
149+
- added canonical `/delivery` handoff summaries to `/ship doctor` and `/ship create-pr --issue <id>` template generation
150+
- added latest-closure follow-up linkage auditing to `/hotfix doctor` so umbrella diagnostics can surface incident follow-up drift
151+
- added latest-run status summaries and stalled-handoff warnings to `/delivery doctor`
152+
- added `/release-train draft` narrative pickup to `/ship doctor` and `/ship create-pr` template generation
153+
- added umbrella `/doctor` ops-readiness aggregation across delivery, ship, release-train, and hotfix surfaces
148154

149155
Remaining:
150156
- broaden write-capable parallelism beyond the tiny `implement` allowlist only when stronger lane-level lease identity and ownership guarantees exist
157+
- deepen E4 from readiness diagnostics into higher-touch issue/PR/release/hotfix workflow automation without introducing overlapping command surfaces
151158

152159
## Doing Now
153160

@@ -163,6 +170,7 @@ Remaining:
163170
| AI-native autopilot orchestration design | doing | New design plan in `docs/plan/ai-native-autopilot-orchestration-plan.md` proposes autonomous task claims, same-worktree write leases, hard completion gates, policy injection, and retry routing for lower-touch autopilot execution; first execution slice now lives in `docs/plan/ai-autopilot-completion-gates-execution-plan.md` and is intentionally `/autopilot` + shared task-metadata first, with `/autoflow` convergence documented as follow-up adoption work rather than current-slice behavior. |
164171
| Gateway E2E parity refinements | doing | Tighten fail-closed behavior for critical hooks, isolate hook execution failures, align continuity wording with canonical commands, and remove hard-coded agent metadata discovery. |
165172
| E13 lane lease identity | doing | Active implementation tracker lives at `docs/plan/e13-shared-memory-swarm-plugin-ops-plan.md`; current slice adds lane-level lease identity to writer activation. |
173+
| E13 ops automation readiness diagnostics | doing | First E4 slice adds `/ship doctor`, umbrella `/doctor` coverage, and refreshed handbook/quickstart guidance so canonical issue/PR/release/hotfix automation can be audited before deeper automation lands. |
166174

167175
## Done Recently
168176

docs/plan/docs-automation-summary.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Generated artifact that tracks docs-automation publication coverage.
1010
- reason_groups: none
1111
- recommended_next_step: none
1212

13-
- generated_at_utc: 2026-03-13T01:06:12Z
13+
- generated_at_utc: 2026-03-13T10:42:30Z
1414
- indexed_release_count: 22
1515
- latest_indexed_release: v0.4.21
1616
- publication_target_coverage: 3/3
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# E13 Ops Automation Readiness Slice - 2026-03-13
2+
3+
Status: `doing`
4+
Branch: `feat/ops-automation-slice-1`
5+
Worktree: `/Users/cauhirsch/Codes/Projects/my_opencode-wt-ops-automation-slice-1`
6+
7+
## Why this slice first
8+
9+
E13 still lists operations automation expansion as a P0 gap. The current runtime already has canonical commands for the main operator lanes:
10+
11+
- issue delivery: `/delivery`
12+
- release PR prep: `/ship`
13+
- release packaging/publish: `/release-train`
14+
- incident response: `/hotfix`
15+
16+
The immediate gap is not missing commands. It is missing cross-surface readiness visibility before operators depend on those commands more heavily.
17+
18+
## Open requirements extracted from current docs
19+
20+
- improve issue, PR, release, and hotfix automation without creating a second overlapping command family
21+
- keep canonical commands as the source of truth
22+
- land docs, diagnostics, and validation in the same slice when workflow behavior changes
23+
- make the first slice small enough to ship quickly, then deepen toward higher-touch automation later
24+
25+
Primary source references:
26+
27+
- `docs/plan/e13-shared-memory-swarm-plugin-ops-plan.md`
28+
- `docs/plan/current-roadmap-tracker.md`
29+
- `docs/plan/release-milestone-automation-runbook.md`
30+
31+
## First-slice scope
32+
33+
1. add `/ship doctor` so PR/release readiness can be audited directly from the canonical ship surface
34+
2. wire `/ship doctor` into umbrella `/doctor`
35+
3. refresh operator docs so the canonical issue/PR/release/hotfix path is easier to discover
36+
4. add selftest coverage for the new readiness path
37+
38+
## Explicit non-goals
39+
40+
- no new top-level ops command
41+
- no issue creation wrapper yet
42+
- no automatic PR/release execution beyond current guarded flows
43+
- no hotfix workflow redesign in this slice
44+
45+
## Next slice candidates after this lands
46+
47+
1. add higher-touch delivery-to-ship handoff summaries from canonical runtime state
48+
2. add release PR scaffolding that consumes delivery/workflow evidence directly
49+
3. add deterministic hotfix-to-followup issue linkage audits in umbrella doctor output
50+
51+
## Follow-up landed in same worktree
52+
53+
- `/ship doctor` now surfaces the latest canonical `/delivery` run summary when runtime state exists
54+
- `/ship create-pr --issue <id>` can inject the matched delivery handoff summary into the generated PR template without adding a new command family
55+
- `/hotfix doctor` now audits the latest closure for follow-up linkage completeness so umbrella `/doctor` can surface incident follow-up drift through canonical command wiring
56+
- `/delivery doctor` now surfaces the latest run summary and warns when the issue flow is stalled in `handoff-pending` or failed workflow states
57+
- `/ship create-pr` now injects `/release-train draft --include-milestones` context into the PR template so release PRs start from the latest canonical release narrative
58+
- umbrella `/doctor` now exposes an aggregated ops readiness summary across `/delivery`, `/ship`, `/release-train`, and `/hotfix`

docs/plan/e13-shared-memory-swarm-plugin-ops-plan.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Status: doing
2727
| E1 Local shared memory runtime | P0 | doing | add durable local shared memory with deterministic retrieval | initial slice is schema + command/runtime baseline |
2828
| E2 Swarm coordination on current runtime | P0 | doing | layer multi-agent coordination on `workflow`, `claims`, `reservation`, and `agent-pool` | prototype lives under `/workflow swarm` first |
2929
| E3 Plugin platform expansion | P1 | pending | turn `gateway-core` into a safer plugin-pack platform | keep MCP out of scope |
30-
| E4 Operations automation expansion | P0 | pending | improve issue, PR, release, and hotfix automation | route through existing canonical commands |
30+
| E4 Operations automation expansion | P0 | doing | improve issue, PR, release, and hotfix automation | route through existing canonical commands; first slice is readiness diagnostics across `/delivery`, `/ship`, `/release-train`, and `/hotfix` |
3131

3232
## E1 Local shared memory runtime
3333

@@ -92,3 +92,9 @@ Status: doing
9292
| 2026-03-10T17:20:00Z | E2 writer lease diagnostics | doing | Added lease-backed writer guarantee checks and surfaced disjoint write parallel candidates without enabling writer parallel execution. |
9393
| 2026-03-10T17:35:00Z | E2 tiny writer allowlist | doing | Enabled lease-backed parallel activation for disjoint `implement` lanes while keeping all other writer lanes serialized. |
9494
| 2026-03-10T17:50:00Z | E2 lane lease identity | doing | Added lane-level `lease_identity` metadata and enforced it for write-capable activation paths. |
95+
| 2026-03-13T21:10:00Z | E4 ops automation diagnostics slice | doing | Added `/ship doctor` and umbrella `/doctor` coverage so issue, PR, release, and hotfix automation can be audited from canonical commands before deeper workflow automation lands. |
96+
| 2026-03-13T21:20:00Z | E4 delivery-to-ship handoff summary | doing | Added canonical `/delivery` runtime summary pickup in `/ship doctor` plus `/ship create-pr --issue <id>` template enrichment for matched delivery runs. |
97+
| 2026-03-13T21:28:00Z | E4 hotfix follow-up audit | doing | Added latest-closure follow-up linkage auditing in `/hotfix doctor` so umbrella `/doctor` can surface incident follow-up drift through canonical command wiring. |
98+
| 2026-03-13T21:31:00Z | E4 delivery doctor status audit | doing | Added latest-run delivery summaries plus handoff-pending/workflow-failed warnings in `/delivery doctor` so issue-flow drift surfaces through canonical diagnostics. |
99+
| 2026-03-13T21:36:00Z | E4 release narrative enrichment | doing | Added `/release-train draft` context pickup in `/ship doctor` and `/ship create-pr` so release PR templates start from canonical release narrative plus milestone context. |
100+
| 2026-03-13T21:40:00Z | E4 umbrella ops readiness summary | doing | Added aggregated ops readiness output in umbrella `/doctor` so delivery, ship, release-train, and hotfix drift surfaces in one operator-facing summary. |

docs/quickstart.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Before you start a task, create a dedicated git worktree branch from the current
4444
/workflow template init ship --json
4545
/delivery start --issue issue-900 --role coder --workflow <workflow.json> --execute --json
4646
/delivery status --json
47+
/ship doctor --json
4748
/init-deep --max-depth 2 --json
4849
/autopilot go --goal "finish current objective" --json
4950
/autoflow start <plan.md> --json
@@ -53,6 +54,9 @@ Before you start a task, create a dedicated git worktree branch from the current
5354
Use this split to stay consistent:
5455

5556
- `/delivery` for normal issue-to-close work
57+
- `/ship` to preflight PR/release readiness before opening or updating a release PR
58+
- `/ship create-pr --issue <id>` when you want the PR template to inherit the latest canonical `/delivery` handoff context for that issue
59+
- `/ship create-pr --issue <id>` also pulls in current `/release-train draft` context so the PR body starts from the latest release narrative
5660
- `/workflow` when you need direct workflow validation or resume controls
5761
- `/autopilot` for open-ended autonomous execution
5862
- `/autoflow` for plan markdown execution

plugin/gateway-core/dist/hooks/notify-events/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ function terminalNotifierPath() {
221221
else {
222222
terminalNotifierBin = null;
223223
}
224-
return terminalNotifierBin;
224+
return terminalNotifierBin ?? null;
225225
}
226226
function iconPrefix(eventName, mode) {
227227
const emoji = EMOJI_BY_EVENT[eventName];

plugin/gateway-core/dist/hooks/shared/hook-failure.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,14 @@ export function isIntentionalHookBlock(error) {
4343
/(question tool is disabled|task\/todowrite tools are disabled)/i.test(trimmed) ||
4444
/require(?:s|d)? explicit/i.test(trimmed));
4545
}
46+
function shouldSurfaceGatewayHookFailureToStderr() {
47+
return (process.env.CI === "true" ||
48+
process.env.MY_OPENCODE_GATEWAY_HOOK_FAILURE_STDERR === "1");
49+
}
4650
export function surfaceGatewayHookFailure(message) {
51+
if (!shouldSurfaceGatewayHookFailureToStderr()) {
52+
return;
53+
}
4754
const line = `[gateway-core] ${message}\n`;
4855
try {
4956
process.stderr.write(line);

plugin/gateway-core/src/hooks/notify-events/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ function terminalNotifierPath(): string | null {
317317
} else {
318318
terminalNotifierBin = null;
319319
}
320-
return terminalNotifierBin;
320+
return terminalNotifierBin ?? null;
321321
}
322322

323323
function iconPrefix(eventName: NotifyEvent, mode: NotifyIconMode): string {

plugin/gateway-core/src/hooks/shared/hook-failure.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,17 @@ export function isIntentionalHookBlock(error: unknown): boolean {
5252
);
5353
}
5454

55+
function shouldSurfaceGatewayHookFailureToStderr(): boolean {
56+
return (
57+
process.env.CI === "true" ||
58+
process.env.MY_OPENCODE_GATEWAY_HOOK_FAILURE_STDERR === "1"
59+
);
60+
}
61+
5562
export function surfaceGatewayHookFailure(message: string): void {
63+
if (!shouldSurfaceGatewayHookFailureToStderr()) {
64+
return;
65+
}
5666
const line = `[gateway-core] ${message}\n`;
5767
try {
5868
process.stderr.write(line);

0 commit comments

Comments
 (0)