@deftai/directive-content 0.95.0 → 0.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QUICK-START.md +2 -0
- package/Taskfile.yml +28 -0
- package/UPGRADING.md +69 -0
- package/commands.md +30 -5
- package/contracts/test-boundary.md +18 -0
- package/docs/consumer-check-contract.md +27 -0
- package/docs/consumer-issue-label-kit.md +211 -0
- package/docs/delivery-attempt.md +173 -0
- package/docs/getting-started.md +2 -0
- package/docs/openclaw-agent-host.md +58 -7
- package/docs/operator-log-hygiene-checklist.md +57 -0
- package/docs/operator-log-hygiene-consumer-pack-stub.md +75 -0
- package/docs/scope-provenance.md +54 -0
- package/docs/test-boundary.md +43 -0
- package/main.md +29 -0
- package/package.json +1 -1
- package/packs/patterns/patterns-pack-0.1.json +10 -0
- package/packs/skills/skills-pack-0.1.json +8 -11
- package/patterns/operator-log-hygiene.md +130 -0
- package/scm/github.md +35 -3
- package/skills/deft-directive-article-review/SKILL.md +17 -6
- package/skills/deft-directive-build/SKILL.md +41 -0
- package/skills/deft-directive-refinement/SKILL.md +1 -3
- package/skills/deft-directive-review-cycle/SKILL.md +166 -12
- package/skills/deft-directive-swarm/SKILL.md +36 -11
- package/skills/deft-directive-swarm/references/core-ops.md +16 -3
- package/skills/deft-directive-swarm/references/core-phase-0.md +40 -15
- package/skills/deft-directive-swarm/references/core-phase-3.md +18 -9
- package/skills/deft-directive-swarm/references/core-phase-4.md +21 -2
- package/skills/deft-directive-swarm/references/core-phase-5-6.md +18 -1
- package/skills/deft-directive-swarm/references/host-claude-code.md +86 -0
- package/skills/deft-directive-swarm/references/host-cursor.md +1 -1
- package/skills/deft-directive-swarm/references/host-openclaw.md +12 -4
- package/skills/deft-directive-triage/SKILL.md +19 -6
- package/skills/deft-directive-xbrief/SKILL.md +0 -1
- package/tasks/cache.yml +31 -0
- package/tasks/engine-invoke.cjs +22 -17
- package/tasks/engine-invoke.test.cjs +30 -0
- package/tasks/verify.yml +30 -0
- package/templates/agent-prompt-preamble.md +15 -4
- package/templates/agents-entry.md +11 -0
- package/templates/swarm-greptile-poller-prompt.md +4 -2
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Operator-log hygiene — structured operator-facing logs (#1940)
|
|
2
|
+
|
|
3
|
+
Guidance for consumer services that humans operate. Declare and keep
|
|
4
|
+
structured, operator-facing logs so outages are diagnosable without a
|
|
5
|
+
week of reactive firefighting.
|
|
6
|
+
|
|
7
|
+
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
8
|
+
|
|
9
|
+
**Load when:** implementing or reviewing services with operator dashboards,
|
|
10
|
+
WARN/ERROR paths operators triage, multi-process / parent-child workers,
|
|
11
|
+
or story AC / probe locked decisions about logging.
|
|
12
|
+
|
|
13
|
+
**Not this pattern:**
|
|
14
|
+
- Directive Product Insights / remote usage analytics — #2603
|
|
15
|
+
- LLM-call telemetry — `patterns/llm-app.md`, `tools/telemetry.md` / #481
|
|
16
|
+
- Framework DDD glossary — `glossary.md` / `deft-directive-glossary`
|
|
17
|
+
|
|
18
|
+
**⚠️ See also**:
|
|
19
|
+
- [../docs/operator-log-hygiene-checklist.md](../docs/operator-log-hygiene-checklist.md) — copy-paste build/probe checklist
|
|
20
|
+
- [../docs/operator-log-hygiene-consumer-pack-stub.md](../docs/operator-log-hygiene-consumer-pack-stub.md) — optional consumer Taskfile/validator stub
|
|
21
|
+
- [./llm-app.md](./llm-app.md) — LLM-specific observability (different lane)
|
|
22
|
+
- [../tools/telemetry.md](../tools/telemetry.md) — general telemetry guidance
|
|
23
|
+
|
|
24
|
+
## Honest value claim
|
|
25
|
+
|
|
26
|
+
This pattern speeds **second systems**, shared language across services, and
|
|
27
|
+
regression prevention when you opt in. It does **not** claim it would have
|
|
28
|
+
avoided any first production week, or that the framework knows your field
|
|
29
|
+
names. Log **shape** stays consumer-owned.
|
|
30
|
+
|
|
31
|
+
## Failure modes (case study)
|
|
32
|
+
|
|
33
|
+
When operator logging is left implicit, the same six deficiencies recur:
|
|
34
|
+
|
|
35
|
+
1. **Happy-path-only terminals** — sessions finish externally (checks, UI)
|
|
36
|
+
while durable logs omit tail events on skip, timeout, supersede, cancel,
|
|
37
|
+
or error exits.
|
|
38
|
+
2. **Missing correlation context** — multi-worker / parent-child designs ship
|
|
39
|
+
without slot, phase, or job-scoped IDs; forensics need archaeology.
|
|
40
|
+
3. **Infrastructure treated as debug-only** — log rotation, flush-before-exit,
|
|
41
|
+
IPC handoff, and boot supervision lack fail-open guards and structured
|
|
42
|
+
events until production crashes.
|
|
43
|
+
4. **Opaque operator text** — WARN/ERROR carry ticket numbers and engineer
|
|
44
|
+
`msg` strings; operators cannot triage severity or whether work continued.
|
|
45
|
+
5. **Dishonest parent/child contracts** — parent logs imply success when IPC
|
|
46
|
+
never delivered; metrics and pollers infer wrong outcomes.
|
|
47
|
+
6. **Hygiene lags the log line** — glossary and plain-English summaries land
|
|
48
|
+
in follow-up issues, not the same PR as the log line.
|
|
49
|
+
|
|
50
|
+
## Positive rules
|
|
51
|
+
|
|
52
|
+
- ! MUST emit terminal / completion events on **all** exit paths for a unit
|
|
53
|
+
of work that has operator-visible lifecycle (success, skip, timeout,
|
|
54
|
+
supersede, cancel, failure) — not only the happy path
|
|
55
|
+
- ! MUST include correlation context for multi-process or pool designs
|
|
56
|
+
(for example job id, slot, phase, parent id) so one incident can be
|
|
57
|
+
reconstructed without log archaeology
|
|
58
|
+
- ! MUST treat infrastructure paths that affect operator truth (rotation,
|
|
59
|
+
flush, IPC handoff, boot supervision) as first-class: fail-open where
|
|
60
|
+
possible, with structured events when they degrade
|
|
61
|
+
- ~ SHOULD give operator-facing WARN/ERROR a stable, queryable shape
|
|
62
|
+
(stable event id + short operator-readable summary fields are common)
|
|
63
|
+
without requiring a Directive-owned schema
|
|
64
|
+
- ~ SHOULD update operator log glossary / plain-English docs in the **same
|
|
65
|
+
PR** that adds or changes operator-facing log lines
|
|
66
|
+
- ? MAY wire a consumer-owned validator into *your* `task check` aggregate
|
|
67
|
+
(see the consumer pack stub) — optional, never default-on in core
|
|
68
|
+
|
|
69
|
+
## Anti-patterns
|
|
70
|
+
|
|
71
|
+
- ⊗ Terminal events only on success while skip/timeout/error paths stay silent
|
|
72
|
+
- ⊗ Multi-worker systems with no job/slot/phase correlation on log lines
|
|
73
|
+
- ⊗ Treating rotation, flush, IPC, or boot supervision as "debug detail"
|
|
74
|
+
with no structured signal when they fail
|
|
75
|
+
- ⊗ Operator-facing WARN/ERROR that only carry ticket numbers or engineer
|
|
76
|
+
free-text with no stable event identity
|
|
77
|
+
- ⊗ Parent logs that claim success when the child message was never delivered
|
|
78
|
+
- ⊗ Landing operator log lines without same-PR hygiene (docs/glossary/shape)
|
|
79
|
+
- ⊗ Assuming Directive core will enforce your log schema or fail `deft check`
|
|
80
|
+
for every consumer by default
|
|
81
|
+
|
|
82
|
+
## Explicit non-goals (thin v1)
|
|
83
|
+
|
|
84
|
+
- ⊗ No core `plan.observability` / setup Phase 2 interview defaults in this
|
|
85
|
+
issue's close path
|
|
86
|
+
- ⊗ No core `deft check` hard-fail for consumers who never opted in
|
|
87
|
+
- ⊗ No prescription or validation of a fixed field set (`operatorSummary`,
|
|
88
|
+
glossary JSON schema, etc.) inside Directive core
|
|
89
|
+
- ⊗ No default-on magic for all "service" project types
|
|
90
|
+
- ⊗ No import of any external project's glossary JSON or validate task as
|
|
91
|
+
framework SoT
|
|
92
|
+
- ⊗ Not Product Insights (#2603) and not LLM-call telemetry (#481)
|
|
93
|
+
|
|
94
|
+
Hard-fail enforcement is allowed only when a **consumer** wires their own
|
|
95
|
+
gate. Log shape remains consumer-owned.
|
|
96
|
+
|
|
97
|
+
## External reference (SLizard — reference only)
|
|
98
|
+
|
|
99
|
+
A production case study lives in **deftai/slizard** (June 2026 postmortem and
|
|
100
|
+
follow-on hygiene work). Cite it as an **external reference implementation**,
|
|
101
|
+
not as Directive schema:
|
|
102
|
+
|
|
103
|
+
| External pointer | Role |
|
|
104
|
+
|------------------|------|
|
|
105
|
+
| SLizard `docs/operator-log-hygiene.md` | Project hygiene write-up |
|
|
106
|
+
| SLizard `docs/operator-log-glossary.json` | Consumer-owned glossary shape |
|
|
107
|
+
| SLizard `task operator-log:validate` | Consumer ship-gate example |
|
|
108
|
+
| SLizard origin issues (e.g. #1394 LD-8, #1402) | How hygiene landed under fire |
|
|
109
|
+
|
|
110
|
+
- ! MUST treat those paths and schemas as **pointers only**
|
|
111
|
+
- ⊗ MUST NOT copy SLizard glossary JSON or validate schema into Directive
|
|
112
|
+
core as a mandatory contract
|
|
113
|
+
- ⊗ MUST NOT close framework work by importing that repo's field names as
|
|
114
|
+
universal requirements
|
|
115
|
+
|
|
116
|
+
## Build and probe
|
|
117
|
+
|
|
118
|
+
Copy-paste AC / probe bullets:
|
|
119
|
+
[`docs/operator-log-hygiene-checklist.md`](../docs/operator-log-hygiene-checklist.md).
|
|
120
|
+
|
|
121
|
+
Optional consumer Taskfile + validator skeleton:
|
|
122
|
+
[`docs/operator-log-hygiene-consumer-pack-stub.md`](../docs/operator-log-hygiene-consumer-pack-stub.md).
|
|
123
|
+
|
|
124
|
+
## Cross-references
|
|
125
|
+
|
|
126
|
+
- #1940 — consumer operator-log hygiene thin v1 (this pattern)
|
|
127
|
+
- #2603 — Product Insights (different lane)
|
|
128
|
+
- #481 — LLM-specific observability (different lane)
|
|
129
|
+
- #1516 — product-pulse health report (adjacent ops UX, not log contract)
|
|
130
|
+
- #829 — skill usage telemetry (framework internal)
|
package/scm/github.md
CHANGED
|
@@ -361,11 +361,17 @@ Agent `edit_files` operations can fail when structured file sections contain Uni
|
|
|
361
361
|
|
|
362
362
|
### Issue Labels
|
|
363
363
|
|
|
364
|
-
**
|
|
364
|
+
**Consumer projects (recommended starter kit, #2611):** use the portable minimal kit in [`docs/consumer-issue-label-kit.md`](../docs/consumer-issue-label-kit.md) (deposit path under `.deft/core/docs/…`). Core labels (`bug`, `enhancement`, `documentation`, `duplicate`, `wontfix`, optional `urgent`), thin epic/tracker/child rules, optional `triaged` + mirror PD knobs (`triageAutoClassify`, `triageLabelMirror.actionLabels`). Prefer existing repo names over inventing twins. ⊗ Do not import the full maintainer taxonomy.
|
|
365
365
|
|
|
366
|
-
**
|
|
366
|
+
**Framework source (`deftai/directive` only):** use the maintainer catalog at repo-root `.github/ISSUE_LABELS.md` (#2609) — full facets, platform, machine/mirror set (`triaged`, `triage:*`). That path is **repository-only** (not deposited under `.deft/core/`); browse the live file on GitHub rather than a relative path from this shipped guide. Do not invent labels outside that catalog.
|
|
367
367
|
|
|
368
|
-
**
|
|
368
|
+
**When no project taxonomy file exists** (fallback shorthand; full kit is the consumer doc above):
|
|
369
|
+
|
|
370
|
+
**Type**: `bug`, `enhancement`, `documentation`, `duplicate`, `wontfix` (prefer existing repo names over inventing `feat` / bare `docs` twins); optional `urgent`
|
|
371
|
+
|
|
372
|
+
**Status / role**: `status:tracker`, `status:child` (parented work), optional `epic` only for multi-ship product roots; project-specific holds as needed
|
|
373
|
+
|
|
374
|
+
**Mirror** (if using `triage:classify -- --mirror`): at least `triaged`; optional `triage:deferred` / `triage:archived` when `actionLabels` maps them
|
|
369
375
|
|
|
370
376
|
### Post-1.0.0 Issue Linking
|
|
371
377
|
|
|
@@ -393,6 +399,32 @@ Following a v1.0.0 release, commits:
|
|
|
393
399
|
- ! Consumer scaffolds and `npm-publish.yml` stay on GitHub-hosted `ubuntu-latest` (Blacksmith is opt-in for consumer orgs; npm `--provenance` requires GH-hosted)
|
|
394
400
|
- ! Agents seeing `runner_capacity_stall` / `RUNNER_CAPACITY_STALL` MUST wait for auto-failover — ⊗ `--skip-ci` as a capacity remedy
|
|
395
401
|
|
|
402
|
+
### Platform status probe + outage attribution (#3180)
|
|
403
|
+
|
|
404
|
+
`pr:watch` / `pr:merge-ready` weather codes (`ci_never_scheduled`, `runner_capacity_stall`, `ci_cancelled_no_failover`, `ci_failures` — see #3167) classify **forge check-run shape**. They do **not** attribute the hold to an upstream platform outage vs repo config. When weather codes fire, CI never starts for HEAD, or many PRs share an empty-check pattern:
|
|
405
|
+
|
|
406
|
+
! **MUST probe public status pages** (v1: open in browser / operator view; gates surface static URLs — no network fetch required):
|
|
407
|
+
|
|
408
|
+
1. **GitHub Status** (Actions, Webhooks): https://www.githubstatus.com/
|
|
409
|
+
2. **Blacksmith Status** (and any Github→Actions / Webhooks mirrors shown there): https://status.blacksmith.sh/
|
|
410
|
+
|
|
411
|
+
**Attribution table** (`attribution` enum for handoffs):
|
|
412
|
+
|
|
413
|
+
| Observation | `attribution` | Agent action |
|
|
414
|
+
|-------------|---------------|--------------|
|
|
415
|
+
| GH Actions and/or Webhooks major/partial outage | `platform` | Treat as platform incident; ⊗ workflow drive-by edits; ⊗ empty-commit thrash past #3167 caps; wait + re-check runs for HEAD + local `task check` |
|
|
416
|
+
| Blacksmith components red while GH Actions green | `capacity` | Runner-provider incident; capacity/failover doctrine (#2672 / #3168) still applies |
|
|
417
|
+
| Both green + still `ci_never_scheduled` on **this PR only** | `repo_config` | Investigate workflow paths, branch filters, required-check names, Actions disabled / org policy |
|
|
418
|
+
| Status unclear or mixed signals | `unknown` | Cap thrash (#3167); BLOCKED with both status URLs; operator decision |
|
|
419
|
+
|
|
420
|
+
! **Anti-thrash during attributed platform outage:** After thrash caps (max 2 re-triggers per #3167), stop automatic empty-commit / close-reopen / rebase loops. Remediation is wait + re-probe HEAD check-runs, not inventing workflow edits to "fix" a global outage.
|
|
421
|
+
|
|
422
|
+
⊗ Merge or `--skip-ci` solely because a status page is red — status is **attribution for wait/thrash policy**, not a second branch-protection oracle (#3180 non-goal).
|
|
423
|
+
⊗ Blame Blacksmith when status pages show GitHub Actions/Webhooks major outage and Blacksmith runners themselves operational.
|
|
424
|
+
⊗ Edit workflows or re-push thrash to "fix" a documented global Actions/webhook outage without status-page probe.
|
|
425
|
+
|
|
426
|
+
**BLOCKED handoff fields** (extend `BLOCKED: ci_weather` in review-cycle): `platform_status_github`, `platform_status_blacksmith`, optional incident URL, `attribution: platform | capacity | repo_config | unknown`. Cross-links: #3167 (weather codes), #3168 (failover arms), #2672 (capacity stall), #2688 (Greptile CLEAN + CI holdout ownership).
|
|
427
|
+
|
|
396
428
|
**Security**:
|
|
397
429
|
- ! Use GitHub Secrets for CI/CD credentials
|
|
398
430
|
- ⊗ Commit secrets to repo
|
|
@@ -112,12 +112,22 @@ Look for lessons applicable to projects that directive-guided agents build:
|
|
|
112
112
|
|
|
113
113
|
### Step 5: Cross-reference open issues
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
- ! If
|
|
118
|
-
- !
|
|
115
|
+
Titles alone are insufficient for ownership verdicts (evidence: #3163). Body-level reads are mandatory.
|
|
116
|
+
|
|
117
|
+
- ! Shortlist open **issues** only: prefer `gh issue list --repo deftai/directive --state open --limit 100` (issues, not PRs). If using REST `gh api repos/deftai/directive/issues?state=open&per_page=100`, **exclude** entries that have a `pull_request` field — GitHub's issues list mixes PRs in; never treat a PR as an owning issue for dedupe
|
|
118
|
+
- ! For each suggestion from Step 4, identify candidate related/owning issues (title scan, semantic match, prior citations) from the issue-only shortlist
|
|
119
|
+
- ! For every issue claimed as related or owning: read the **full issue body**. If the body is a stub or pointer-only, also read recent comments (REST `issues/<N>/comments`) before judging ownership
|
|
120
|
+
- ! Prefer local cache when present: `.deft-cache/github-issue/deftai/directive/<N>/` (or project-equivalent) may satisfy the body-read requirement offline **only when all** of: (1) usable body (and comments when the body is a stub); (2) **affirmative freshness** — readable cache age or TTL metadata is present **and** within the project's cache TTL (not expired). If age/TTL metadata is missing or unreadable, the entry is **not** body-read complete — re-fetch live when network is available; if offline with missing freshness metadata, do not claim body-level ownership from that cache hit alone. Do not skip body-level ownership solely because network is unavailable if a **complete and affirmatively fresh** cache entry exists
|
|
121
|
+
- ! Verify every issue number cited in the analysis **exists**, is an **issue** (not a PR), and that its **state** matches the claim (open vs closed) — anti-hallucination; fabricated or wrong-state citations are a known failure mode
|
|
122
|
+
- ! If a suggestion duplicates an open issue (body-level ownership): drop it from the proposal and note the existing issue number
|
|
123
|
+
- ! If a suggestion extends or relates to an open issue: flag it as "extends #N" / "related to #N" rather than proposing a standalone new issue
|
|
124
|
+
- ~ Prefer **amend/comment on an owning open issue** over filing a new issue; reserve new issues for verified-untracked findings
|
|
119
125
|
- ~ Scan the open issue list for trends (e.g. a cluster of agent-safety issues, a cluster of pattern/ gaps) — use trends to sharpen framing or prioritization of remaining suggestions
|
|
120
|
-
- ⊗
|
|
126
|
+
- ⊗ Decide ownership or file a "related to #N" claim from **titles only** — body (and stub-comment) reads are required for related/owning claims
|
|
127
|
+
- ⊗ Treat pull requests from the REST issues list as ownership targets without filtering `pull_request`
|
|
128
|
+
- ⊗ Accept a cache hit as body-read complete when the entry lacks body (or required stub comments), lacks readable age/TTL freshness metadata, or is expired/stale — re-fetch live when network is available; without affirmative freshness do not use the cache for ownership verdicts
|
|
129
|
+
- ⊗ Propose a new issue for something already tracked — body-level deduplication is mandatory
|
|
130
|
+
- ⊗ Cite issue numbers without verifying existence and state
|
|
121
131
|
|
|
122
132
|
### Step 6: Present suggestions to the user
|
|
123
133
|
|
|
@@ -163,6 +173,7 @@ If yes, follow the thread. This may include fetching related URLs, evaluating re
|
|
|
163
173
|
- ⊗ Summarizing without reading the full content
|
|
164
174
|
- ⊗ Presenting unrated suggestions — every suggestion needs a confidence level
|
|
165
175
|
- ⊗ Filing a single giant issue for all suggestions — one issue per distinct suggestion or related group
|
|
166
|
-
- ⊗ Proposing a new issue without first checking whether it duplicates an open one
|
|
176
|
+
- ⊗ Proposing a new issue without first checking whether it duplicates an open one (body-level ownership, not titles alone)
|
|
177
|
+
- ⊗ Claiming related/owning issues from titles only, or citing issue numbers without verifying existence and state (#3163)
|
|
167
178
|
- ⊗ Evaluating directive relevance without consulting the Directive Reference section above
|
|
168
179
|
- ⊗ Download-and-execute installers from article or web CTAs during analysis — reject and cite `patterns/install-trust.md` (#2969)
|
|
@@ -258,6 +258,27 @@ All xBRIEFs (including those read from `xbrief/active/` and any new xBRIEFs this
|
|
|
258
258
|
|
|
259
259
|
**Cost model (swarm-heavy path):** moves from roughly `O(commits × full-gate)` toward `O(merges × full-gate) + O(iterations × cheap-proxy)` when workers iterate with affected/static gates and run full `task check` only at PR/merge.
|
|
260
260
|
|
|
261
|
+
### Dual stop — multi-iteration implement and pre-PR loops (#2442)
|
|
262
|
+
|
|
263
|
+
Multi-iteration implement-fix and pre-PR polish loops MUST carry **both** a success stop and a failure/budget stop (`main.md` `## Dual Stop Rule (#2442)`). Single-turn edits and one-shot probes are exempt.
|
|
264
|
+
|
|
265
|
+
**Defaults for this skill (override only with an explicit operator envelope or xBRIEF field):**
|
|
266
|
+
|
|
267
|
+
| Loop class | Success stop | Default failure stop |
|
|
268
|
+
|------------|--------------|----------------------|
|
|
269
|
+
| Implement / quality fix (tests, lint, typecheck, coverage, AC) | Affected/static gates green for the change; AC met | **max 5** fix iterations **or** **3** consecutive identical outcomes (same failing command + same primary error class) with no material code/config change |
|
|
270
|
+
| Pre-PR polish (`deft-directive-pre-pr` Read-Write-Lint-Diff) | Full pass with zero further edits | **max 3** polish passes **or** **2** consecutive no-diff / same-diff outcomes |
|
|
271
|
+
| Full `task check` re-run after a red merge chokepoint | `task check` green | Counts toward the implement/quality fix envelope above (do not open a separate unbounded check-retry loop) |
|
|
272
|
+
|
|
273
|
+
**On failure stop:**
|
|
274
|
+
|
|
275
|
+
- ! Halt the loop. Surface an **operator-visible halt report** with: (1) iterations attempted and which stop fired (max-iter / no-progress / budget), (2) commands and primary failure fingerprints tried, (3) what is still red or missing, (4) the human decision needed (unblock dependency, rescope AC, waive with audit, abandon).
|
|
276
|
+
- ! Prefer a structured `BLOCKED:` terminal (preamble §11 / #2843) when exiting a drive-to:merge-ready or parent-dispatched unit early because the envelope is exhausted.
|
|
277
|
+
- ⊗ Continue "one more fix" after the envelope is exhausted.
|
|
278
|
+
- ⊗ Reset the counter by opening a new commit, rewording the same change, or swapping workers while the same failure class remains.
|
|
279
|
+
|
|
280
|
+
**Enforcement note:** skill defaults are behavioral. Durable delivery/acceptance circuit-breaker: **#3143** `packages/core/src/delivery-attempt/` (`evaluatePreDispatch`, `.deft/delivery-attempts/`). Docs: `docs/delivery-attempt.md`. Route delivery/acceptance automatic retries through that gate; do not invent a parallel ledger in this skill.
|
|
281
|
+
|
|
261
282
|
## Step 3: Build Phase by Phase
|
|
262
283
|
|
|
263
284
|
For each phase:
|
|
@@ -295,6 +316,23 @@ task test:coverage # >=85% or PROJECT-DEFINITION.xbrief.json override
|
|
|
295
316
|
- ⊗ Re-run full install/session ceremony after offline seed when ritual is already complete (#3010) — use `session:ready` for recovery only.
|
|
296
317
|
|
|
297
318
|
|
|
319
|
+
## Operator-log hygiene (lazy-load, #1940)
|
|
320
|
+
|
|
321
|
+
When the story touches **operator-facing** services (dashboards, multi-process
|
|
322
|
+
workers, WARN/ERROR operators triage):
|
|
323
|
+
|
|
324
|
+
- ~ SHOULD load `patterns/operator-log-hygiene.md` and apply the copy-paste
|
|
325
|
+
checklist in `docs/operator-log-hygiene-checklist.md` to story AC or probe
|
|
326
|
+
locked decisions before claiming logging done
|
|
327
|
+
- ⊗ MUST NOT treat this as Product Insights (#2603) or LLM-call telemetry
|
|
328
|
+
(#481) — those are different lanes
|
|
329
|
+
- ⊗ MUST NOT assume core `deft check` enforces a log schema by default —
|
|
330
|
+
consumer-owned shape; optional pack stub under
|
|
331
|
+
`docs/operator-log-hygiene-consumer-pack-stub.md`
|
|
332
|
+
|
|
333
|
+
Discovery keywords: operator log, operator-facing logs, observability checklist
|
|
334
|
+
— also indexed in `REFERENCES.md`.
|
|
335
|
+
|
|
298
336
|
## Coding Standards (Summary)
|
|
299
337
|
|
|
300
338
|
Read full files when you need detail:
|
|
@@ -343,6 +381,7 @@ feat(phase-2): add REST API endpoints with integration tests
|
|
|
343
381
|
- ! Lint/type errors → fix them; ≉ add ignore comments without documented reason
|
|
344
382
|
- ! Scope xBRIEF ambiguous -> ask user; ⊗ guess
|
|
345
383
|
- ! Scope needs changes -> propose, get approval, update the scope xBRIEF first
|
|
384
|
+
- ! Multi-iteration fix loops obey dual-stop defaults above (#2442); on envelope exhaustion halt with an operator-visible report -- do not thrash
|
|
346
385
|
|
|
347
386
|
|
|
348
387
|
## Probe-then-fill remote claims (#3120)
|
|
@@ -388,3 +427,5 @@ feat(phase-2): add REST API endpoints with integration tests
|
|
|
388
427
|
- ⊗ Add a prohibition (`!` or `⊗`) without scanning the same file for conflicting softer-strength rules (`~`, `≉`) that reference the same term
|
|
389
428
|
- ⊗ Invent remote PR/SHA/CI/review claims in handoff evidence without same-turn probe binding — invented-done (#3120)
|
|
390
429
|
- ⊗ Fill remote ship/gate fields from memory when only local work completed; legal partial omits PR fields (#3120)
|
|
430
|
+
- ⊗ Run multi-iteration implement / pre-PR loops without a failure stop (max iterations and/or no-progress) or without an operator-visible halt report when the envelope is exhausted (#2442)
|
|
431
|
+
- ⊗ Silently continue after dual-stop failure halt — escalate; do not thrash (#2442)
|
|
@@ -116,9 +116,7 @@ The agent may suggest the next phase, but the user decides. Phases can be entere
|
|
|
116
116
|
1. ! Pull the ingestion candidate list via `task triage:queue --state=accept` (D11 / #1128). Each row is a cached issue whose latest audit-log decision is `accept` -- the canonical "ready to become a scope xBRIEF" cohort. ! MUST NOT enumerate `xbrief/proposed/` independently of the queue; the folder participates only via the join described in step 2.
|
|
117
117
|
2. ! Join the queue against `xbrief/proposed/` (and the rest of the lifecycle folders) by `references[].uri`: queue rows whose issue is already represented by an existing xBRIEF surface as "already tracked"; queue rows with no matching xBRIEF are "new accept candidates". Items already in `xbrief/proposed/` continue to participate -- they are joined against the cache rather than enumerated separately.
|
|
118
118
|
3. ~ When the join surfaces zero new candidates (every `accept` row already has a xBRIEF), Phase 0b is a clean no-op; chain straight into Phase 0c.
|
|
119
|
-
4. ! For each new candidate, fall through to Phase 1 -- Ingest, which delegates the actual scope-xBRIEF write to `task issue:ingest
|
|
120
|
-
|
|
121
|
-
<!-- TODO(#1136 / D18): when `task scope:promote --from-issue=<N>` ships, refinement Phase 0b consumes it directly instead of chaining `task issue:ingest` + `task scope:promote`. -->
|
|
119
|
+
4. ! For each new candidate, fall through to Phase 1 -- Ingest, which delegates the actual scope-xBRIEF write to `task issue:ingest` (or `task triage:accept`, which already ingests into `proposed/`). After the proposed artifact exists, promote with `task scope:promote -- --from-issue=<N> [--repo OWNER/NAME]` (#1136 / D18), or chain accept+promote via `task triage:accept -- --issue <N> --repo OWNER/NAME --auto-promote` when the operator wants pending/ in one step.
|
|
122
120
|
|
|
123
121
|
⊗ Walk `xbrief/proposed/` directly as the primary ingestion surface -- the cache is the authoritative "what is ready to refine?" surface; the folder is the destination, not the source of truth.
|
|
124
122
|
⊗ Drop items that exist in `xbrief/proposed/` but lack a matching cache row -- those are reconciled later (Phase 3 / origin reconciliation), not silently discarded.
|
|
@@ -190,6 +190,26 @@ Babysit and review-cycle are **not** a second unbounded implementation mandate.
|
|
|
190
190
|
⊗ Expand active story scope past xBRIEF AC mid-babysit without follow-up or consented amend (#2881).
|
|
191
191
|
⊗ Treat confidence-only holds as authorization to invent new subsystems in-tree.
|
|
192
192
|
|
|
193
|
+
|
|
194
|
+
### Dual stop — review fix loops (#2442)
|
|
195
|
+
|
|
196
|
+
Review fix cycles are multi-iteration work and MUST carry dual stop (`main.md` `## Dual Stop Rule (#2442)`). Single-turn re-checks are exempt.
|
|
197
|
+
|
|
198
|
+
**Defaults for this skill (override only with an explicit operator envelope):**
|
|
199
|
+
|
|
200
|
+
| Loop class | Success stop | Default failure stop |
|
|
201
|
+
|------------|--------------|----------------------|
|
|
202
|
+
| Greptile / bot fix batch (Step 3 → re-review) | No P0/P1 on current HEAD; confidence meets `minGreptileConfidence` | **max 3** fix-batch iterations across the whole review ownership (do **not** reset the counter on push when the same primary fingerprint remains) **or** **2** consecutive re-reviews with the same primary P0/P1 fingerprint and no material fix |
|
|
203
|
+
| Confidence-only hold (0 P0/P1, score below floor) | Confidence meets floor, or operator chooses document/accept path | **max 1** optional polish pass, then stop (do not redesign unbounded — see confidence-only holds above) |
|
|
204
|
+
|
|
205
|
+
**On failure stop:**
|
|
206
|
+
|
|
207
|
+
- ! Halt automatic re-fix. Prefer `BLOCKED:` with PR number, HEAD SHA, blocker class (`review_cycle_cap` / `greptile_p0_p1` / `no_progress`), what was tried, and human decision needed (preamble §11 / #2843).
|
|
208
|
+
- ⊗ Continue silent fix rounds after the envelope is exhausted.
|
|
209
|
+
- ⊗ Reset the fix-batch counter solely by re-pushing, empty-committing, or swapping workers when the same primary finding fingerprint remains (poll-wait timer MAY reset for a new HEAD; the dual-stop fix-batch counter MUST NOT).
|
|
210
|
+
|
|
211
|
+
**Enforcement note:** skill defaults are behavioral. Durable delivery/acceptance circuit breaker: **#3143** packages/core/src/delivery-attempt/ (valuatePreDispatch). Docs: docs/delivery-attempt.md.
|
|
212
|
+
|
|
193
213
|
### Step 3: Fix all findings in ONE batch commit
|
|
194
214
|
|
|
195
215
|
! Apply [`coding/review.md`](../../coding/review.md) single-batch, cross-file grep, and local structured-data validation rules. Land **all** in-scope fixes in one commit (or one intentional batch), never per-finding pushes.
|
|
@@ -262,7 +282,7 @@ Remediation:
|
|
|
262
282
|
|
|
263
283
|
! **Official gh-only fallback** (when both `deft`/`directive` and `task deft:<verb>` probes fail for pr:watch / review-monitor):
|
|
264
284
|
|
|
265
|
-
1. Still select Approach 1 when a sub-agent primitive exists (OpenClaw `sessions_spawn`, Cursor `Task`, `spawn_subagent`, `start_agent`) — spawn a review-monitor that runs the gh-only loop; do not block the parent.
|
|
285
|
+
1. Still select Approach 1 when a sub-agent primitive exists (OpenClaw `sessions_spawn`, Cursor `Task`, Claude Code `Agent`, `spawn_subagent`, `start_agent`) — spawn a review-monitor that runs the gh-only loop; do not block the parent.
|
|
266
286
|
2. **Do not call** gate verbs via any surface the probe showed absent — those invocations cannot succeed and must not gate the spawn.
|
|
267
287
|
3. Ownership claim without the tasks: post/update the sticky `<!-- deft:review-owner -->` PR comment via `gh api` (same field shape as the task-written lease) **or** keep ownership in the parent and document `missing-task: review-monitor` in the PR/parent handback. Never invent `.deft/review-monitor.json`.
|
|
268
288
|
4. Poll with adaptive cadence (20-30s / 60s / 90s) using:
|
|
@@ -297,6 +317,94 @@ Remediation:
|
|
|
297
317
|
|
|
298
318
|
⊗ Use `--skip-ci` / merge-with-pending because CI is capacity-stalled — the failover path is the unblock; skip-ci is an incident-only release escape hatch (#2652), not a runner-capacity remedy.
|
|
299
319
|
|
|
320
|
+
### CI weather reason codes + thrash caps (#3167)
|
|
321
|
+
|
|
322
|
+
`pr:watch` / `pr:merge-ready` expose machine-distinguishable `ci_ready_state` values (also `--json`) so agents stop conflating Actions weather with product test failure:
|
|
323
|
+
|
|
324
|
+
| `ci_ready_state` / verdict | Meaning | Agent action |
|
|
325
|
+
|----------------------------|---------|--------------|
|
|
326
|
+
| `ci_never_scheduled` / `CI_NEVER_SCHEDULED` | No CI workflow check-run for HEAD (empty or bots-only: Greptile/SLizard) | Cap re-triggers; then **BLOCKED** — do not multi-hour empty-commit thrash |
|
|
327
|
+
| `runner_capacity_stall` / `RUNNER_CAPACITY_STALL` | Required still `queued`, no runner past budget (#2672) | Wait auto-failover; ⊗ `--skip-ci` |
|
|
328
|
+
| `ci_failures` / `CI_BLOCKED` | Completed `failure` / `timed_out` with product evidence (#2688) | Own like Greptile P0 — fix or escalate |
|
|
329
|
+
| `ci_cancelled_no_failover` / `CI_CANCELLED_NO_FAILOVER` | Primary `cancelled` and no green required sibling (failover skipped/not armed; workflow sibling **#3168**) | Cap re-triggers; then **BLOCKED** |
|
|
330
|
+
| Greptile CLEAN fields / `greptile_pending` | Existing Step 6 / SHA / confidence | Unchanged |
|
|
331
|
+
|
|
332
|
+
! **Thrash caps (MUST):** Under stable `ci_never_scheduled`, `ci_cancelled_no_failover`, or repeated capacity stall after failover wait budget, limit **CI re-trigger attempts** (empty-commit push, close/reopen, rebase-for-enqueue) to **at most 2** total across the ownership span. On the **2nd** failed re-trigger (or immediately when the weather code is stable and Greptile Step 6 is already clean), stop automatic re-push and emit a structured **BLOCKED** handoff.
|
|
333
|
+
|
|
334
|
+
### Platform status probe + outage attribution (#3180)
|
|
335
|
+
|
|
336
|
+
! When `ci_ready_state` is weather-class (`ci_never_scheduled`, `runner_capacity_stall`, `ci_cancelled_no_failover`, `ci_failures`), CI never starts for HEAD, or many PRs share an empty-check pattern: **MUST probe public status pages** before workflow thrash or drive-by edits. Gates surface static URLs in `pr:watch` / `pr:merge-ready` JSON and human output (v1: no network fetch required).
|
|
337
|
+
|
|
338
|
+
1. ! **GitHub Status** (Actions, Webhooks): https://www.githubstatus.com/
|
|
339
|
+
2. ! **Blacksmith Status**: https://status.blacksmith.sh/
|
|
340
|
+
|
|
341
|
+
**Attribution table:**
|
|
342
|
+
|
|
343
|
+
| Observation | `attribution` | Agent action |
|
|
344
|
+
|-------------|---------------|--------------|
|
|
345
|
+
| GH Actions and/or Webhooks major/partial outage | `platform` | Platform incident; ⊗ workflow drive-by edits; ⊗ empty-commit thrash past thrash caps; wait + re-check HEAD runs + local `task check` |
|
|
346
|
+
| Blacksmith red while GH Actions green | `capacity` | Runner-provider incident; failover doctrine (#2672 / #3168) |
|
|
347
|
+
| Both green + still `ci_never_scheduled` on this PR only | `repo_config` | Workflow paths, branch filters, required-check names, Actions disabled / org policy |
|
|
348
|
+
| Unclear / mixed | `unknown` | Cap thrash; BLOCKED with both status URLs; operator decision |
|
|
349
|
+
|
|
350
|
+
! **Anti-thrash during attributed platform outage:** After thrash caps, stop automatic re-push loops. Remediation is wait + re-probe HEAD check-runs, not inventing workflow edits for a global outage.
|
|
351
|
+
|
|
352
|
+
⊗ Merge or `--skip-ci` solely because a status page is red — status is attribution for wait/thrash policy, not a second branch-protection oracle.
|
|
353
|
+
⊗ Blame Blacksmith when GH Actions/Webhooks are the red components and Blacksmith runners are operational.
|
|
354
|
+
⊗ Edit workflows / empty-commit thrash to "fix" a documented global Actions/webhook outage without a status-page probe.
|
|
355
|
+
|
|
356
|
+
Cross-links: #3167 (weather codes), #3168 (failover arms), #2672 (capacity stall), #2688 (Greptile CLEAN + CI holdout).
|
|
357
|
+
|
|
358
|
+
! **BLOCKED handoff template (CI weather):**
|
|
359
|
+
|
|
360
|
+
```text
|
|
361
|
+
BLOCKED: ci_weather
|
|
362
|
+
PR: <N>
|
|
363
|
+
HEAD: <sha>
|
|
364
|
+
REASON: ci_never_scheduled|ci_cancelled_no_failover|runner_capacity_stall
|
|
365
|
+
GREPTILE: CLEAN|P0/P1|pending (Step 6 fields)
|
|
366
|
+
CI: <ci_ready_state from pr:watch --json>
|
|
367
|
+
platform_status_github: https://www.githubstatus.com/
|
|
368
|
+
platform_status_blacksmith: https://status.blacksmith.sh/
|
|
369
|
+
incident_url: <optional status-page incident URL or n/a>
|
|
370
|
+
attribution: platform|capacity|repo_config|unknown
|
|
371
|
+
ATTEMPTS: empty-commit=<0-2> close-reopen=<0-2>
|
|
372
|
+
REMEDIATION: wait for platform recovery | capacity failover (#3168) | repo config fix | human admin-merge playbook below | operator decision
|
|
373
|
+
REDISPATCH_OK: yes|no
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
! Ownership of Greptile CLEAN + CI holdout is still real (#2688) — **ownership ≠ infinite wait**. After thrash caps, hand off; do not burn multi-hour `gh run watch` / empty-commit loops when Greptile is already CLEAN.
|
|
377
|
+
|
|
378
|
+
! **Envelope selection under CI weather (#3153):** Prefer deliberate `stop-at: pr-open` implement + this skill as the partner merge-path babysit when known capacity/outage weather dominates; see swarm Envelope selection SLA and partner merge-path section above. Cross-link only — do not re-spec the tree here.
|
|
379
|
+
|
|
380
|
+
⊗ Multi-hour empty-commit / close-reopen / rebase thrash after thrash caps when `ci_ready_state` is `ci_never_scheduled` or `ci_cancelled_no_failover`.
|
|
381
|
+
⊗ Treat `ci_never_scheduled` as ordinary Greptile latency (`sha_match` / `terminal_check_run` only).
|
|
382
|
+
⊗ Silent `--skip-ci` / admin merge without the outage playbook audit trail below.
|
|
383
|
+
|
|
384
|
+
### SLizard advisory-only for merge-ready wait (#3167)
|
|
385
|
+
|
|
386
|
+
! Required bot for **merge-ready wait** / Step 6 exit ownership is **Greptile**. SLizard (Gemini Verify) is **advisory only**: timeouts, retries, missing check, or flaky SLizard conclusions MUST NOT gate the review-cycle wait loop or authorize unbounded re-push.
|
|
387
|
+
|
|
388
|
+
! `task pr:merge-ready` may still surface SLizard structure when present (#2189); agents MUST NOT idle-poll or thrash solely for SLizard when Greptile Step 6 is clean. Prefer continue / BLOCKED on CI weather / human decision.
|
|
389
|
+
|
|
390
|
+
⊗ Block merge-ready babysit on SLizard alone when Greptile Step 6 all-of is satisfied on HEAD.
|
|
391
|
+
|
|
392
|
+
### Outage admin-merge playbook (opt-in / human, #3167)
|
|
393
|
+
|
|
394
|
+
When GitHub Actions is in a **documented major outage** (or multi-hour `ci_never_scheduled` / `ci_cancelled_no_failover` after thrash caps) and product + Greptile are ready:
|
|
395
|
+
|
|
396
|
+
! Admin / human merge is **opt-in**, never the autonomous agent default. Preconditions:
|
|
397
|
+
|
|
398
|
+
1. ! Greptile Step 6 fail-closed all-of on current HEAD (dogfood conf floor / `minGreptileConfidence`).
|
|
399
|
+
2. ! Evidence of local or prior green `task check` / merge-gate when available.
|
|
400
|
+
3. ! PR comment **audit note** naming the weather code, HEAD SHA, and who authorized override.
|
|
401
|
+
4. ? Optional explicit env/policy for bot merge (`DEFT_ALLOW_BOT_MERGE` / `task policy:allow-bot-merge`) — **opt-in**, never silent default skip-ci.
|
|
402
|
+
|
|
403
|
+
⊗ Autonomous `--skip-ci` / `--admin` merge as the default under ordinary CI weather.
|
|
404
|
+
⊗ Replace branch protection with Greptile-only merge on normal days.
|
|
405
|
+
|
|
406
|
+
Workflow failover arming (Blacksmith cancelled → GH-hosted lane) is sibling issue **#3168** — this skill owns agent thrash caps and reason codes only.
|
|
407
|
+
|
|
300
408
|
### Stall Detection Rubric (#564)
|
|
301
409
|
|
|
302
410
|
! Track per poll: `startedAt` (timestamp of the first observation of the IN_PROGRESS check run for the current commit) and `commit.oid` (head SHA being reviewed). Both fields MUST be re-recorded every time the head SHA changes -- the rubric measures elapsed time on a single commit, not across the whole review cycle.
|
|
@@ -354,25 +462,57 @@ Remediation:
|
|
|
354
462
|
~ **Eval / regression (#3090):** Given PR open + check SUCCESS + open inline P1s + agent text claims driving merge + turn ends with 0 subagents and no lease → **FAIL** (Owner Continuity Gate), not PASS.
|
|
355
463
|
|
|
356
464
|
### Review Monitoring
|
|
357
|
-
! **Background / independent dispatch (#1880 Gap D):** Long-running review-cycle owners and pollers (>~3 min) MUST be dispatched independently / in the background so the parent conversation stays interactive. On Cursor, use the Task tool background path (`run_in_background: true`). This generalizes the Approach-1 sub-agent monitor rule to implementation and fix workers as well — foreground dispatch is reserved for short tasks. The parent receives completion via `DONE` / `BLOCKED` / `FAILED` per `templates/agent-prompt-preamble.md` §11.
|
|
465
|
+
! **Background / independent dispatch (#1880 Gap D):** Long-running review-cycle owners and pollers (>~3 min) MUST be dispatched independently / in the background so the parent conversation stays interactive. On Cursor, use the Task tool background path (`run_in_background: true`) when the current agent is the top-level owner of that primitive (not a nested leaf — see Cursor leaf boundary). On Claude Code, top-level parents/orchestrators use the `Agent` tool with `run_in_background: true` (register primitive `claude-agent`, #3134); implementation leaves follow the Claude Code leaf boundary (blocking `pr:watch` or `stop-at: pr-open` sibling), not nested Agent. This generalizes the Approach-1 sub-agent monitor rule to implementation and fix workers as well — foreground dispatch is reserved for short tasks. The parent receives completion via `DONE` / `BLOCKED` / `FAILED` per `templates/agent-prompt-preamble.md` §11.
|
|
358
466
|
|
|
359
467
|
! **Worker-owns-lifecycle (#1880 Gap C):** When this skill runs as part of an implementation worker scoped `drive-to: merge-ready`, the worker owns the full review/fix loop through merge-ready in its own tool loop — do NOT exit at PR-open expecting the orchestrator to spawn a separate review leaf.
|
|
360
468
|
|
|
361
469
|
! **Swarm monitor must not self-implement (#2843 / Gap C):** When a cohort monitor receives `BLOCKED` or DONE-with-blockers from a `drive-to: merge-ready` implementation leaf, the monitor MUST NOT enter the review/fix loop inline on Tier 1 — background-dispatch ONE continuation leaf scoped `drive-to: merge-ready` on the same worktree. Monitor-inline review-cycle is permitted only on Tier 3 or with explicit operator consent (see `skills/deft-directive-swarm/SKILL.md` Phase 5 completion-notification decision tree).
|
|
362
470
|
|
|
471
|
+
### Partner merge-path when implement stops at PR-open (#3153)
|
|
472
|
+
|
|
473
|
+
! This skill is the **required partner** for the swarm **Envelope selection SLA** (`skills/deft-directive-swarm/references/core-phase-0.md` / Phase 3). When an implement leaf was deliberately scoped **`stop-at: pr-open`** (or a merge-ready leaf failed thin DONE and recovery chose babysit ownership), the parent/monitor MUST **not** leave the open PR without a merge-path owner.
|
|
474
|
+
|
|
475
|
+
! **First-class merge-path ownership (MUST, same turn as PR ground-truth):**
|
|
476
|
+
|
|
477
|
+
1. ! Spawn **or** retain **exactly one** review-cycle owner for the open PR:
|
|
478
|
+
- **Approach 1** review-monitor (`worker_role: review-monitor`) with sticky `<!-- deft:review-owner -->` lease (#3090 / #3044 / dual-invoke `review-monitor:register` when available), **or**
|
|
479
|
+
- A continuation leaf scoped **`drive-to: merge-ready`** on that PR/worktree that owns babysit → merge-ready in its tool loop, **or**
|
|
480
|
+
- Documented **parent-retained** ownership (`review_cycle: in_progress:<pr>#parent-retained`) with an explicit next poll/fix action — never silent hold.
|
|
481
|
+
2. ! Route through **this skill** — ⊗ Cursor global babysit (`#2261`), freestyle main-session poll, or dual parallel monitors (`#3044`).
|
|
482
|
+
3. ! Apply Owner Continuity Gate (#3090) and Single review-monitor lease (#3044) without exception: one sticky lease; force-takeover only when the prior owner is dead.
|
|
483
|
+
4. ! **Post-merge `scope:complete` (#2321 / Gap C):** When the implement leaf stopped at pr-open, it MUST NOT have run `task scope:complete`. After the PR **merges**, the merge-path owner (or swarm Phase 6 `task swarm:finalize-cohort` / `task swarm:complete-cohort` / monitor) MUST run `task scope:complete` or `task scope:cancel`. `task verify:orphan-active` fails closed on stranded active briefs.
|
|
484
|
+
5. ! **Human-merge / CLEAN-before-merge ownership (#3153 / #1193 / #2321):** When `plan.policy.requireHumanMerge` (or missing bot-merge authority) means the review owner reaches Greptile CLEAN / merge-ready but **cannot** squash-merge, lifecycle ownership is **not** complete. Prefer **durable** ownership (not a prose-only promise):
|
|
485
|
+
- **Preferred:** Parent/monitor **retains** ownership (`review_cycle: in_progress:<pr>#parent-retained` or sticky lease held by the long-lived monitor) until human merge lands, then runs `scope:complete` (or Phase 6 `task swarm:finalize-cohort` / `task swarm:complete-cohort`).
|
|
486
|
+
- **Allowed handoff:** Only to a **long-lived** parent/monitor / Phase 6 closer — same turn: (1) re-claim sticky `<!-- deft:review-owner -->` lease for the **recipient** (register/force as needed), (2) structured handback with PR, HEAD, `awaiting-human-merge`, and explicit post-merge `scope:complete` duty, (3) recipient acknowledges with `review_cycle: in_progress:<pr>#…` before the giving agent exits.
|
|
487
|
+
- ! Cohort through-merge: the **swarm monitor** is the default durable post-merge `scope:complete` owner for every `stop-at: pr-open` story (#2321) — do not rely on a review leaf that exits at CLEAN.
|
|
488
|
+
- ! **Post-CLEAN wake path (MUST):** After CLEAN under human-merge, the durable owner MUST keep a **reachable observe path** until the PR is `MERGED` (or closed without merge → `scope:cancel` / operator decision). Concrete options (pick one, same ownership):
|
|
489
|
+
1. **Background poller** (Approach 1 preferred when Tier 1): spawn/retain a review-monitor or short poll loop that probes `gh api repos/<owner>/<repo>/pulls/<N>` for `merged` / `state` on adaptive cadence (or host merge webhook when available), then runs post-merge verification + `scope:complete`.
|
|
490
|
+
2. **Parent-retained yield-with-wake:** parent keeps `review_cycle: in_progress:<pr>#parent-retained` and re-enters on the next operator message / scheduled re-invocation (Approach 2) with an explicit first action of "check merge state → if merged, `scope:complete`".
|
|
491
|
+
3. **Phase 6 cohort closer:** for swarm, record the PR as `awaiting-human-merge` in the monitor checkpoint and **require** the Phase 6 pre-sweep merge re-poll (`skills/deft-directive-swarm/references/core-phase-5-6.md` § Human-merge observe path / Step 1.5) before `task swarm:complete-cohort` / finalize — never skip `scope:complete` solely because Greptile was CLEAN earlier.
|
|
492
|
+
⊗ Keep only a sticky lease with no poller, no parent re-entry plan, and no Phase 6 re-poll checklist — that is ownership-in-name-only and still strands `scope:complete`.
|
|
493
|
+
⊗ Handoff to a short-lived leaf that exits at CLEAN without lease transfer.
|
|
494
|
+
⊗ Emit terminal `DONE` / stand down at CLEAN when merge authority is human-only and no **reachable** durable owner (sticky lease + live parent/monitor/cohort closer **with an observe path above**) remains for post-merge `scope:complete`.
|
|
495
|
+
6. ! **Thin DONE recovery (#2943 / #3153):** A failed `drive-to: merge-ready` leaf that only opened a PR is **not** success. After ground truth, hand merge path to **one** of the owners above — never improvise a second lease or re-dispatch implement + babysit in parallel without releasing the first.
|
|
363
496
|
|
|
497
|
+
! **Cohort through-merge intent is unchanged:** stories still land on master. Envelope selection only assigns **who owns implement vs who owns Greptile/CI/merge** under capacity stall, conf floors, wall-clock budgets, or large multi-gate stories. Happy-path single `drive-to: merge-ready` leaves remain the default and do not use this partner handoff.
|
|
364
498
|
|
|
365
|
-
!
|
|
499
|
+
! **Does not authorize:** lowering `minGreptileConfidence`, `--skip-ci` for capacity stalls, or unbounded redesign on conf-only holds (#2881 / #2672 / #3095).
|
|
366
500
|
|
|
367
|
-
-
|
|
501
|
+
Cross-links: swarm decision tree `skills/deft-directive-swarm/references/core-phase-0.md` § Envelope selection SLA; Phase 3 Gap C `skills/deft-directive-swarm/references/core-phase-3.md`; thin SKILL pointer `skills/deft-directive-swarm/SKILL.md` § Envelope selection SLA.
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
! Select the monitoring approach based on runtime capability detection (the matrix in `skills/deft-directive-swarm/SKILL.md` Phase 3 Step 1, extended per #1342 slices 1-2 for `spawn_subagent` / "grok-build", per #1877 for Cursor as first-class Tier-1 tiers, per #2876 for OpenClaw `sessions_spawn`, and per #3134 for Claude Code `claude-code` / `claude-agent`). Probe the environment (tool set + env vars) to obtain the stable platform descriptor (`grok-build`, `warp-orchestrated`, `warp-manual`, `cursor-composer`, `cursor-cloud-agent`, `claude-code`, `openclaw`, etc.) from the launch adapter / `get_platform_capabilities` and map the descriptor to the appropriate tier + dispatch primitive (`start_agent`, `spawn_subagent`, the Cursor `Task` tool, Claude Code `Agent` / `claude-agent`, or OpenClaw `sessions_spawn`). The descriptor (not hard-coded tool presence) is the single source of truth for both launch and review monitoring.
|
|
506
|
+
|
|
507
|
+
- **Tier 1 (orchestrated sub-agent)** → Approach 1 (spawn review-monitor sub-agent via the primitive matching the descriptor: `start_agent`, `spawn_subagent`, the Cursor `Task` tool with `run_in_background: true`, Claude Code `Agent` with `run_in_background: true` / register `claude-agent`, or OpenClaw `sessions_spawn`)
|
|
368
508
|
- **Tier 2 (no sub-agent primitive, but scheduler/timer/auto-reinvocation)** → Approach 2 (yield-between-polls) — includes OpenClaw `cron` / host scheduler **only when** `sessions_spawn` is unavailable (#2876)
|
|
369
509
|
- **Tier 3 (interactive session, nothing else)** → Approach 3 (blocking sleep loop as last resort)
|
|
370
510
|
|
|
371
|
-
! Detection: use the full runtime capability matrix (swarm Phase 3 + launch adapter from #1342 slice 2). The old single-probe for `start_agent` is superseded; the returned platform descriptor determines both the orchestration path and the MCP surface (see MCP probe below). If the descriptor is `grok-build` (spawn_subagent present, start_agent + WARP_* absent), treat as Tier 1 with the spawn_subagent poller path. If the descriptor is `cursor-composer` / `cursor-cloud-agent` (Cursor `Task` tool present, start_agent + WARP_* + spawn_subagent absent), treat as **Tier 1 with the backgrounded Cursor `Task` poller path** (#1877) — NOT Tier 3. Cursor's `Task` tool is a first-class sub-agent primitive; degrading a Cursor session to the Approach-3 blocking poll is the misclassification #1877 closes. If the descriptor is `openclaw` (`sessions_spawn` present), treat as **Tier 1 with the backgrounded `sessions_spawn` poller path** (#2876) — NOT Approach 2 cron and NOT main-session gh poll.
|
|
511
|
+
! Detection: use the full runtime capability matrix (swarm Phase 3 + launch adapter from #1342 slice 2). The old single-probe for `start_agent` is superseded; the returned platform descriptor determines both the orchestration path and the MCP surface (see MCP probe below). If the descriptor is `grok-build` (spawn_subagent present, start_agent + WARP_* absent), treat as Tier 1 with the spawn_subagent poller path. If the descriptor is `cursor-composer` / `cursor-cloud-agent` (Cursor `Task` tool present, start_agent + WARP_* + spawn_subagent absent), treat as **Tier 1 with the backgrounded Cursor `Task` poller path** (#1877) — NOT Tier 3. Cursor's `Task` tool is a first-class sub-agent primitive; degrading a Cursor session to the Approach-3 blocking poll is the misclassification #1877 closes. If the descriptor is `claude-code` (Claude-unique `Agent` / `CLAUDECODE` / `DEFT_PROBE_CLAUDE_CODE` signals), treat as **Tier 1 with the backgrounded Claude Code `Agent` poller path** (#3134) — NOT Tier 3 and NOT `cursor-composer` (bare `Task` is not a Claude-unique signal). If the descriptor is `openclaw` (`sessions_spawn` present), treat as **Tier 1 with the backgrounded `sessions_spawn` poller path** (#2876) — NOT Approach 2 cron and NOT main-session gh poll.
|
|
372
512
|
|
|
373
513
|
! Swarm agents (whether launched via `start_agent`, `spawn_subagent`, or OpenClaw `sessions_spawn` per the platform descriptor) SHOULD prefer Approach 1 for their own review-monitor sub-agent. Approach 2's yield-between-polls is not self-sustaining for swarm agents (see warning below). Always include the canonical `templates/agent-prompt-preamble.md` (AGENTS.md read mandate, #810 xBRIEF gate, #798 PowerShell UTF-8, pre-PR + review-cycle mandates) when spawning a poller sub-agent.
|
|
374
514
|
|
|
375
|
-
! **Deterministic review-monitor gate (#2655 / #2814 / #2876 / #2893):** When Tier 1 is available **and** a dual-invoke probe succeeds for review-monitor verbs (`deft verify:review-monitor` / `deft review-monitor:register`, or `task deft:verify:review-monitor` / `task deft:review-monitor:register`), run that verify form before yielding, entering Approach 3, or claiming review monitoring started — CLI: `deft verify:review-monitor --pr <N> [--call-site solo]`; task: `task deft:verify:review-monitor -- --pr <N> [--call-site solo]`. After spawning Approach 1, claim the PR-anchored lease with the matching register form (CLI: `deft review-monitor:register --pr <N> --monitor-agent-id <id> --platform-primitive ...`; task: `task deft:review-monitor:register -- --pr <N> --monitor-agent-id <id> --platform-primitive start_agent|spawn_subagent|cursor-task|sessions_spawn|openclaw-sessions-spawn`). Release with the matching release form (CLI: `deft review-monitor:release --pr <N>`; task: `task deft:review-monitor:release -- --pr <N>`) when done. Exit `0` ready / `1` not ready or held-by-other / `2` config. The sole source of truth is the sticky GitHub PR comment (`<!-- deft:review-owner -->`); legacy `.deft/review-monitor.json` is obsolete and ignored. On register conflict, attach to the existing owner or stop — do not parallel-fix.
|
|
515
|
+
! **Deterministic review-monitor gate (#2655 / #2814 / #2876 / #2893):** When Tier 1 is available **and** a dual-invoke probe succeeds for review-monitor verbs (`deft verify:review-monitor` / `deft review-monitor:register`, or `task deft:verify:review-monitor` / `task deft:review-monitor:register`), run that verify form before yielding, entering Approach 3, or claiming review monitoring started — CLI: `deft verify:review-monitor --pr <N> [--call-site solo]`; task: `task deft:verify:review-monitor -- --pr <N> [--call-site solo]`. After spawning Approach 1, claim the PR-anchored lease with the matching register form (CLI: `deft review-monitor:register --pr <N> --monitor-agent-id <id> --platform-primitive ...`; task: `task deft:review-monitor:register -- --pr <N> --monitor-agent-id <id> --platform-primitive start_agent|spawn_subagent|cursor-task|claude-agent|sessions_spawn|openclaw-sessions-spawn`). Release with the matching release form (CLI: `deft review-monitor:release --pr <N>`; task: `task deft:review-monitor:release -- --pr <N>`) when done. Exit `0` ready / `1` not ready or held-by-other / `2` config. The sole source of truth is the sticky GitHub PR comment (`<!-- deft:review-owner -->`); legacy `.deft/review-monitor.json` is obsolete and ignored. On register conflict, attach to the existing owner or stop — do not parallel-fix.
|
|
376
516
|
|
|
377
517
|
! **Missing review-monitor surface carve-out (#2878 / #2893):** When dual-invoke probes fail for `pr:watch` **and** `review-monitor:*` (no `deft` CLI, no `task deft:` include), do **not** invoke those gates and do **not** block Approach 1 on them. Fail-loud once with `missing-task: review-monitor` / `missing-task: pr:watch`, then:
|
|
378
518
|
1. Still spawn Approach 1 with the official gh-only fallback when a sub-agent primitive exists.
|
|
@@ -389,18 +529,20 @@ Remediation:
|
|
|
389
529
|
|
|
390
530
|
! **Cursor leaf boundary (#2797 / #2893):** A Cursor `Task` leaf cannot reliably spawn another Cursor `Task`; nested Task (leaf spawning leaf) is unsupported for an Approach 1 review-monitor. A Cursor `drive-to: merge-ready` leaf MUST either keep ownership in the same agent by blocking on `deft pr:watch <N>` (or `task deft:pr:watch -- <N>` when include-present), or its envelope MUST instead be `stop-at: pr-open` so the orchestrator can spawn and register a sibling review-monitor. A background shell `pr:watch` is not a monitor and MUST NOT be claimed as one.
|
|
391
531
|
|
|
532
|
+
! **Claude Code leaf boundary (#3134 / #2797 analogue):** Nested `Agent` (implementation leaf spawning a second-level review-monitor Agent) is unsupported/unreliable on some Claude Code surfaces. A Claude Code `drive-to: merge-ready` leaf MUST either keep ownership in the same agent by blocking on `deft pr:watch <N>` (or `task deft:pr:watch -- <N>` when include-present), or its envelope MUST instead be `stop-at: pr-open` so the orchestrator can spawn and register a sibling review-monitor with `--platform-primitive claude-agent`. ⊗ Background a nested Agent poller from an implementation leaf and exit claiming monitoring is active. Top-level parents/orchestrators that own the `Agent` primitive MAY still Approach-1 background a review-monitor Agent.
|
|
533
|
+
|
|
392
534
|
**Approach 1 (preferred -- sub-agent orchestration available per platform descriptor):**
|
|
393
535
|
|
|
394
|
-
! **Background dispatch (#1880 / #2876):** Spawn the review-monitor sub-agent via the matching primitive IN THE BACKGROUND (Cursor: Task `run_in_background: true`; Grok Build: `spawn_subagent` with parent yielding; OpenClaw: `sessions_spawn` with parent yielding). The parent MUST remain interactive while the poller runs — never block the parent OpenClaw/Cursor/Grok session for >~3 min of monitor ownership.
|
|
536
|
+
! **Background dispatch (#1880 / #2876 / #3134):** Spawn the review-monitor sub-agent via the matching primitive IN THE BACKGROUND (Cursor: Task `run_in_background: true`; Claude Code: `Agent` `run_in_background: true`; Grok Build: `spawn_subagent` with parent yielding; OpenClaw: `sessions_spawn` with parent yielding). The parent MUST remain interactive while the poller runs — never block the parent OpenClaw/Cursor/Claude Code/Grok session for >~3 min of monitor ownership.
|
|
395
537
|
|
|
396
|
-
! **Heartbeat contract for Cursor pollers (#1877 / #1166 / #2876):** OpenClaw sessions_spawn pollers share this contract. A Cursor `Task` or OpenClaw `sessions_spawn` review-monitor poller whose loop runs > ~3 min MUST honour the sub-agent heartbeat contract (`docs/subagent-heartbeat.md`), same as the `spawn_subagent` path — emit periodic progress so the parent can distinguish a live poller from a hung one.
|
|
538
|
+
! **Heartbeat contract for Cursor pollers (#1877 / #1166 / #2876 / #3134):** Claude Code `Agent` and OpenClaw `sessions_spawn` pollers share this contract. A Cursor `Task`, Claude Code `Agent`, or OpenClaw `sessions_spawn` review-monitor poller whose loop runs > ~3 min MUST honour the sub-agent heartbeat contract (`docs/subagent-heartbeat.md`), same as the `spawn_subagent` path — emit periodic progress so the parent can distinguish a live poller from a hung one.
|
|
397
539
|
|
|
398
540
|
~ **Visible Control UI (OpenClaw / #3044):** When OpenClaw Control UI is the operator control plane, SHOULD spawn the review-monitor with `visible:true` when the tool surface allows so humans can inspect progress without attaching to the parent session; invisible empty settles are higher FC04 residual risk.
|
|
399
541
|
|
|
400
542
|
! When the platform descriptor indicates Tier 1 (sub-agent support), spawn a review-monitor sub-agent using the primitive matching the descriptor:
|
|
401
543
|
|
|
402
|
-
1. ! Launch via the matching primitive: `start_agent` (Warp), `spawn_subagent` (grok-build / TUI / non-Warp), the Cursor `Task` tool with `run_in_background: true` (`cursor-composer` / `cursor-cloud-agent`, #1877), **or OpenClaw `sessions_spawn` (`openclaw`, #2876)** with a prompt that instructs it to poll for Greptile completion. For `spawn_subagent`, Cursor `Task`, and OpenClaw `sessions_spawn` the prompt MUST reference the canonical poller template `templates/swarm-greptile-poller-prompt.md` (with placeholders filled) plus the agent preamble; the working directory / context must be the PR branch (worktree or equivalent for hybrid).
|
|
403
|
-
2. ! The sub-agent polls using the mechanism for its primitive: for `spawn_subagent` use `get_command_or_subagent_output` (adaptive cadence: ~20-30s first check after push, ~60s second, ~90s thereafter; Greptile typically lands in 3-7 min); for `start_agent` the native messaging path; for the Cursor `Task` tool the backgrounded-task completion-notification path; for OpenClaw `sessions_spawn` the host session completion / messaging channel (prefer `task pr:watch` inside the child when available). Front-load the first check to catch fast reviews.
|
|
544
|
+
1. ! Launch via the matching primitive: `start_agent` (Warp), `spawn_subagent` (grok-build / TUI / non-Warp), the Cursor `Task` tool with `run_in_background: true` (`cursor-composer` / `cursor-cloud-agent`, #1877), the Claude Code `Agent` tool with `run_in_background: true` (`claude-code` / register `claude-agent`, #3134), **or OpenClaw `sessions_spawn` (`openclaw`, #2876)** with a prompt that instructs it to poll for Greptile completion. For `spawn_subagent`, Cursor `Task`, Claude Code `Agent`, and OpenClaw `sessions_spawn` the prompt MUST reference the canonical poller template `templates/swarm-greptile-poller-prompt.md` (with placeholders filled) plus the agent preamble; the working directory / context must be the PR branch (worktree or equivalent for hybrid).
|
|
545
|
+
2. ! The sub-agent polls using the mechanism for its primitive: for `spawn_subagent` use `get_command_or_subagent_output` (adaptive cadence: ~20-30s first check after push, ~60s second, ~90s thereafter; Greptile typically lands in 3-7 min); for `start_agent` the native messaging path; for the Cursor `Task` tool the backgrounded-task completion-notification path; for Claude Code `Agent` the backgrounded-agent completion-notification path; for OpenClaw `sessions_spawn` the host session completion / messaging channel (prefer `task pr:watch` inside the child when available). Front-load the first check to catch fast reviews.
|
|
404
546
|
3. ! When the exit condition is met (Greptile review current on the HEAD commit SHA, confidence meets resolved min (policy/dogfood/default; see Step 6 #3095), no P0/P1 remaining), the sub-agent reports completion back to the parent (via `send_message_to_agent`, the spawn_subagent result channel, or the OpenClaw sessions completion channel).
|
|
405
547
|
4. ! The main conversation pane stays fully interactive during monitoring -- the user (or parent monitor) can continue other work.
|
|
406
548
|
5. ! On receiving the completion message / result, the parent re-fetches findings (both gh pr view --comments and the secondary source) and proceeds to Step 5.
|
|
@@ -427,7 +569,7 @@ Remediation:
|
|
|
427
569
|
|
|
428
570
|
! **One sticky lease per PR:** ownership is the single sticky GitHub PR comment `<!-- deft:review-owner -->` (or the dual-invoke `review-monitor:register` form that writes it). Parallel ownership is forbidden.
|
|
429
571
|
|
|
430
|
-
! **Pre-spawn check:** before launching another Approach 1 review-monitor (`sessions_spawn`, `spawn_subagent`, Cursor `Task`, `start_agent`):
|
|
572
|
+
! **Pre-spawn check:** before launching another Approach 1 review-monitor (`sessions_spawn`, `spawn_subagent`, Cursor `Task`, Claude Code `Agent`, `start_agent`):
|
|
431
573
|
|
|
432
574
|
1. ! Read the sticky lease (dual-invoke `verify:review-monitor` when available, else `gh api` issues comments for `<!-- deft:review-owner -->`).
|
|
433
575
|
2. ! List active same-PR / same-`taskName` subagents when the host exposes that surface (OpenClaw `subagents list` or equivalent).
|
|
@@ -635,6 +777,16 @@ task lifecycle:event -- emit plan:approved \
|
|
|
635
777
|
|
|
636
778
|
## Anti-Patterns
|
|
637
779
|
|
|
780
|
+
- ⊗ Multi-hour empty-commit / close-reopen thrash after CI weather thrash caps when `ci_never_scheduled` or `ci_cancelled_no_failover` (#3167)
|
|
781
|
+
- ⊗ Workflow thrash or empty-commit spam during attributed platform outage without status-page probe (#3180)
|
|
782
|
+
- ⊗ Merge or `--skip-ci` solely because a status page is red without check-run evidence (#3180)
|
|
783
|
+
- ⊗ Block merge-ready wait on SLizard alone when Greptile Step 6 is clean (#3167)
|
|
784
|
+
- ⊗ Silent admin / `--skip-ci` merge under Actions outage without audit comment and opt-in authority (#3167)
|
|
785
|
+
- ⊗ Leave a deliberate `stop-at: pr-open` (or thin-DONE recovery) open PR without spawning/retaining one review-cycle babysit owner + lease continuity and post-merge `scope:complete` plan (#3153)
|
|
786
|
+
- ⊗ Stand down at CLEAN under human-merge policy without a durable owner (sticky lease + live parent/monitor/Phase 6 closer) **and** a post-CLEAN observe path (poller / parent wake / Phase 6 re-poll) for post-merge `scope:complete` (#3153 / #1193 / #2321)
|
|
787
|
+
- ⊗ Handoff human-merge cleanup to a short-lived leaf that exits at CLEAN without re-claiming the sticky lease (#3153)
|
|
788
|
+
- ⊗ Retain only a sticky lease after CLEAN with no poller, no parent re-entry, and no Phase 6 merge re-poll — ownership-in-name-only (#3153)
|
|
789
|
+
- ⊗ Dual-lease or freestyle Cursor global babysit for the partner merge-path after implement stops at PR-open (#3153 / #2261 / #3044)
|
|
638
790
|
- ⊗ End owning turn with 0 children, no sticky lease, and no finish after drive-to-merge / babysit / shepherd claim — silent hold (#3090)
|
|
639
791
|
- ⊗ Emit freeform `review_cycle: started` / `pending` / `initiated` or L4 `status: pass` without `done` or verifiable `in_progress:<pr>#…` lease/parent-retained (#3090)
|
|
640
792
|
- ⊗ Treat check-run SUCCESS alone as CLEAN / merge-ready while dual-source P0/P1 remain (#3090)
|
|
@@ -642,6 +794,8 @@ task lifecycle:event -- emit plan:approved \
|
|
|
642
794
|
- ⊗ Route PR shepherding to Cursor global `babysit` on Deft-managed repos when `.deft/core/` is installed -- use this review-cycle skill instead (#2261)
|
|
643
795
|
- ⊗ Route OpenClaw babysit/shepherd/watch to main-session gh poll + cron when `sessions_spawn` is available -- use Approach 1 with `sessions_spawn` (#2876 / #2261)
|
|
644
796
|
- ⊗ Treat OpenClaw `cron` alone as Approach 1 — cron/timer is Approach 2 only if spawn is unavailable (#2876)
|
|
797
|
+
- ⊗ Route Claude Code babysit/shepherd/watch to Approach 3 blocking poll when Claude `Agent` spawn is available — use Approach 1 with backgrounded `Agent` / `claude-agent` (#3134)
|
|
798
|
+
- ⊗ Misclassify Claude Code as `cursor-composer` from bare `Task` alone (#3134)
|
|
645
799
|
- ⊗ Expand active story scope past xBRIEF AC mid-babysit without follow-up issue or consented brief amend (#2881)
|
|
646
800
|
- ⊗ Treat confidence-only holds (0 P0/P1) as a mandate for unbounded redesign (#2881)
|
|
647
801
|
- ⊗ Invent freestyle sleep/poll loops when dual-invoke probes fail for `pr:watch` — use the official gh-only fallback and fail-loud missing-task (#2878 / #2893)
|
|
@@ -675,4 +829,4 @@ task lifecycle:event -- emit plan:approved \
|
|
|
675
829
|
- ⊗ Spawn a second review-monitor while prior owner is running or last settle was empty/unknown without terminal ground truth (#3044)
|
|
676
830
|
- ⊗ Accept empty review-monitor final message missing STATUS/HEAD/CHECKS/MERGE handback (#3044)
|
|
677
831
|
- ⊗ Invent remote PR/SHA/CI/review claims in handoff evidence without same-turn probe binding — invented-done (#3120)
|
|
678
|
-
- ⊗ Fill remote ship/gate fields from memory when only local work completed; legal partial omits PR fields (#3120)
|
|
832
|
+
- ⊗ Fill remote ship/gate fields from memory when only local work completed; legal partial omits PR fields (#3120)
|