@deftai/directive-content 0.96.0 → 0.98.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/.agents/skills/deft-directive-portfolio-priority/SKILL.md +11 -0
- package/Taskfile.yml +6 -0
- package/UPGRADING.md +9 -6
- package/commands.md +17 -2
- package/contracts/test-boundary.md +18 -0
- package/docs/consumer-check-contract.md +64 -0
- package/docs/deft-directive-disable.md +6 -0
- package/docs/delivery-attempt.md +173 -0
- package/docs/openclaw-agent-host.md +36 -1
- 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 +46 -0
- package/meta/philosophy.md +10 -0
- package/package.json +1 -1
- package/packs/patterns/patterns-pack-0.1.json +10 -0
- package/packs/skills/skills-pack-0.1.json +22 -5
- package/patterns/operator-log-hygiene.md +130 -0
- package/scm/github.md +26 -0
- package/skills/deft-directive-article-review/SKILL.md +17 -6
- package/skills/deft-directive-build/SKILL.md +41 -0
- package/skills/deft-directive-portfolio-priority/SKILL.md +144 -0
- package/skills/deft-directive-release/SKILL.md +22 -5
- package/skills/deft-directive-review-cycle/SKILL.md +150 -0
- package/skills/deft-directive-swarm/SKILL.md +14 -0
- package/skills/deft-directive-swarm/references/core-ops.md +14 -2
- package/skills/deft-directive-swarm/references/core-phase-0.md +34 -1
- package/skills/deft-directive-swarm/references/core-phase-3.md +6 -0
- package/skills/deft-directive-swarm/references/core-phase-4.md +21 -2
- package/skills/deft-directive-swarm/references/core-phase-5-6.md +17 -0
- package/skills/deft-directive-swarm/references/host-openclaw.md +4 -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 +8 -0
- package/templates/agents-entry.md +10 -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
|
@@ -399,6 +399,32 @@ Following a v1.0.0 release, commits:
|
|
|
399
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)
|
|
400
400
|
- ! Agents seeing `runner_capacity_stall` / `RUNNER_CAPACITY_STALL` MUST wait for auto-failover — ⊗ `--skip-ci` as a capacity remedy
|
|
401
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
|
+
|
|
402
428
|
**Security**:
|
|
403
429
|
- ! Use GitHub Secrets for CI/CD credentials
|
|
404
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)
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deft-directive-portfolio-priority
|
|
3
|
+
description: >-
|
|
4
|
+
Pre-promotion portfolio prioritization: cluster competing open RFCs/issues
|
|
5
|
+
from the local github-issue cache, emit a propose-not-apply priority brief
|
|
6
|
+
(conflict matrix, shortlist, park), with epistemic citation gates, then hand
|
|
7
|
+
off for operator dispose. Use when the operator asks for portfolio priority,
|
|
8
|
+
a priority brief, competing RFCs, or to cluster open issues. Do NOT trigger
|
|
9
|
+
on single-item "what's next?" ranking (deft-directive-triage / triage:queue)
|
|
10
|
+
or post-promotion capacity prioritization (#1419/#1511).
|
|
11
|
+
triggers:
|
|
12
|
+
- portfolio priority
|
|
13
|
+
- priority brief
|
|
14
|
+
- competing RFCs
|
|
15
|
+
- cluster open issues
|
|
16
|
+
- pre-promotion portfolio
|
|
17
|
+
- portfolio prioritization
|
|
18
|
+
- rank this backlog slice
|
|
19
|
+
metadata:
|
|
20
|
+
clawdbot:
|
|
21
|
+
requires:
|
|
22
|
+
bins: ["gh"]
|
|
23
|
+
---
|
|
24
|
+
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
|
|
25
|
+
<!-- Purpose: rendered skill -->
|
|
26
|
+
<!-- Source of truth: packs/skills/skills-pack-0.1.json -->
|
|
27
|
+
<!-- Regenerate with: task packs:render -->
|
|
28
|
+
<!-- Edit the source, not this file. Slice instead of loading every SKILL.md: task packs:slice skills by-trigger --trigger <kw> (or list) -->
|
|
29
|
+
|
|
30
|
+
# Deft Directive Portfolio Priority
|
|
31
|
+
|
|
32
|
+
Pre-promotion **portfolio prioritization pass**: cluster competing RFCs/issues from the local github-issue cache, name conflicts/supersession, emit a **propose-not-apply** priority brief (shortlist + park), then hand off for operator dispose. Parent process + dogfood: **#3198**. Worked example: **#3200** / [`docs/analysis/2026-08-07-portfolio-priority-brief-patterns-pilot.md`](../../../docs/analysis/2026-08-07-portfolio-priority-brief-patterns-pilot.md).
|
|
33
|
+
|
|
34
|
+
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
35
|
+
|
|
36
|
+
## When to Use
|
|
37
|
+
|
|
38
|
+
- Maintainer wants a **portfolio priority** brief across competing open issues / RFCs
|
|
39
|
+
- Operator says: portfolio priority, priority brief, competing RFCs, cluster open issues, pre-promotion portfolio, rank this backlog slice
|
|
40
|
+
- After a large classify / label-mirror partition when humans still need a shortlist (B-side; not the ranker)
|
|
41
|
+
- ⊗ Do NOT use for single-issue "what's next?" ranking — that is `deft-directive-triage` + `task triage:queue`
|
|
42
|
+
- ⊗ Do NOT use for post-promotion capacity buckets — that is #1419 / #1511
|
|
43
|
+
- ⊗ Do NOT use for review-handoff briefs — that is #1590
|
|
44
|
+
|
|
45
|
+
## Stance (hard)
|
|
46
|
+
|
|
47
|
+
- ! **Propose-not-apply** (#3179): the brief proposes; the operator disposes
|
|
48
|
+
- ⊗ SCM label writes, mirror `--apply`, or re-enrich apply from this skill
|
|
49
|
+
- ⊗ `task triage:accept` / reject / defer / needs-ac / mark-duplicate / bulk-*
|
|
50
|
+
- ⊗ Scope lifecycle (`scope:promote` / `activate` / `complete` / `cancel`) from this skill
|
|
51
|
+
- ⊗ Treat the brief as a decision record — dispose into #1396 / plan-sequence / operator comment
|
|
52
|
+
|
|
53
|
+
## Inputs
|
|
54
|
+
|
|
55
|
+
- ! Local `.deft-cache/github-issue/` (bodies available)
|
|
56
|
+
- ! Classify partition via `task triage:classify -- --mirror` (or cached JSON digest) as **FILTER only**
|
|
57
|
+
- ~ Optional theme slice: label family, title prefix, author, epic parent
|
|
58
|
+
|
|
59
|
+
## Phases
|
|
60
|
+
|
|
61
|
+
### Phase 0 — Cache freshness
|
|
62
|
+
|
|
63
|
+
1. ! Run `task verify:cache-fresh`. Exit 0 → proceed. Exit 1 → refresh (`task cache:fetch-all -- --source=github-issue --repo OWNER/NAME`) or **disclose stale** and continue only with operator consent. Exit 2 → `task triage:bootstrap` first.
|
|
64
|
+
2. ~ When zero cache entries, bootstrap/fetch before clustering (#2575).
|
|
65
|
+
3. ⊗ Cluster against a silent stale cache without disclosing staleness.
|
|
66
|
+
|
|
67
|
+
### Phase 1 — Classify as FILTER only
|
|
68
|
+
|
|
69
|
+
1. ! Run `task triage:classify -- --mirror` (dry-run; optional `--json`) to partition dispositions (`no_match` / escalate / defer / already planned).
|
|
70
|
+
2. ! Use classify outcomes only to **filter** the portfolio slice (e.g. deep-dive candidates from `no_match`; keep escalate on an interrupt queue).
|
|
71
|
+
3. ⊗ Use classify disposition chips as the **ranker** or final shortlist order.
|
|
72
|
+
4. ⊗ Pass `--apply` or `--re-enrich` with intent to write labels from this skill.
|
|
73
|
+
|
|
74
|
+
### Phase 2 — Theme / slice selection
|
|
75
|
+
|
|
76
|
+
1. ! Name an **explicit slice** (label family, title theme, author, or epic). Unattended full-backlog ranking is out of scope.
|
|
77
|
+
2. ! Record scope counts: open in slice, classify partitions inside the slice, exclusions.
|
|
78
|
+
3. ~ Prefer one coherent theme per brief (pilot: patterns + `no_match`).
|
|
79
|
+
|
|
80
|
+
### Phase 3 — Cluster + conflict matrix + shortlist + park
|
|
81
|
+
|
|
82
|
+
1. ! Group candidates into **families** (title/theme/body overlap, shared parent epic, layered pack).
|
|
83
|
+
2. ! Build a **conflict / supersession matrix** per family: overlapping roots, pack-vs-atom, research-vs-product.
|
|
84
|
+
3. ! Emit an ordered **shortlist** (deep dive / promote candidates) and a **park list** with park reasons.
|
|
85
|
+
4. ! Separate **interrupt / non-portfolio** rows (escalate, hold, already dispositioned) so they are not ranked against park list.
|
|
86
|
+
5. ⊗ Claim "#X supersedes #Y" from titles alone — see Phase 4 epistemic gates.
|
|
87
|
+
|
|
88
|
+
### Phase 4 — Epistemic gates (MUST)
|
|
89
|
+
|
|
90
|
+
Before citing any `#N` in the brief:
|
|
91
|
+
|
|
92
|
+
1. ! **Verify existence + state** for every cited issue via live `gh api repos/OWNER/NAME/issues/N` (REST) **or** a proven-fresh cache entry whose state matches the claim.
|
|
93
|
+
2. ! **Read the body** of every issue used for shortlist, park-as-superseded, pack membership, or "decided" claims.
|
|
94
|
+
3. ! When claiming decided / superseded / closed-by-comment, also **read comments** (REST `issues/N/comments`).
|
|
95
|
+
4. ! State **open/closed accurately**; never invent issue numbers.
|
|
96
|
+
5. ⊗ **Title-only supersession** or ownership claims.
|
|
97
|
+
6. ⊗ Cite PRs as issues without filtering `pull_request` on mixed issue lists.
|
|
98
|
+
|
|
99
|
+
### Phase 5 — Emit priority brief
|
|
100
|
+
|
|
101
|
+
! Write markdown matching the pilot section shape (fill with this run's slice):
|
|
102
|
+
|
|
103
|
+
1. **Header** — process issue (#3198 or project equivalent), parent tracker if any, generated timestamp, stance (propose-not-apply), epistemic method
|
|
104
|
+
2. **Dispose path** — not a decision record; points at #1396 / plan-sequence / operator comment
|
|
105
|
+
3. **Scope of this pass** — counts table (slice filters + partition sizes)
|
|
106
|
+
4. **Interrupt / non-portfolio** — escalate/hold/already planned (do not rank here)
|
|
107
|
+
5. **Conflict / family matrix** — families with verified state + body claims + recommendation
|
|
108
|
+
6. **Shortlist** — ordered P1/P2/… with why
|
|
109
|
+
7. **Park list** — classes, examples, park reasons
|
|
110
|
+
8. **Epistemic limits** — what was cache-only, what needs follow-up probe
|
|
111
|
+
9. **Operator dispose checklist** — accept/edit shortlist, accept park, record dispose, optional plan-sequence; do not treat as mirror apply
|
|
112
|
+
|
|
113
|
+
~ Prefer writing under `docs/analysis/YYYY-MM-DD-portfolio-priority-brief-<slice>.md` for durable dogfood; chat-only is allowed if the operator declines a file.
|
|
114
|
+
|
|
115
|
+
~ Link the worked example: #3200 and `docs/analysis/2026-08-07-portfolio-priority-brief-patterns-pilot.md` (may live on the pilot PR until merged).
|
|
116
|
+
|
|
117
|
+
### Phase 6 — Dispose checklist (hand off)
|
|
118
|
+
|
|
119
|
+
1. ! Present the dispose checklist to the operator (accept/edit shortlist + park; record dispose; optional plan-sequence for P1).
|
|
120
|
+
2. ! Point dispose targets: **#1396**-shaped decision log (or interim issue comment), and/or `task plan-sequence:set`.
|
|
121
|
+
3. ⊗ Auto-promote shortlist into plan-sequence without explicit operator dispose.
|
|
122
|
+
4. ⊗ Exit treating the brief alone as durable prioritization memory (#2741 class).
|
|
123
|
+
|
|
124
|
+
## Anti-Patterns
|
|
125
|
+
|
|
126
|
+
- ⊗ SCM label writes / mirror apply / re-enrich apply from this skill
|
|
127
|
+
- ⊗ `triage:accept` or any triage decision verb from this skill
|
|
128
|
+
- ⊗ Scope lifecycle mutations from this skill
|
|
129
|
+
- ⊗ Title-only supersession or unverified `#N` citations
|
|
130
|
+
- ⊗ Full open-backlog unattended ranking without an explicit slice
|
|
131
|
+
- ⊗ Replacing `triage:queue` for buildable work selection
|
|
132
|
+
- ⊗ Treating the brief as the decision record without dispose
|
|
133
|
+
|
|
134
|
+
## EXIT
|
|
135
|
+
|
|
136
|
+
! Confirm: `deft-directive-portfolio-priority complete -- exiting skill.`
|
|
137
|
+
~ Chain: operator dispose (#1396 / plan-sequence) · `deft-directive-triage` for single-item queue work · `deft-directive-refinement` after accept on a different path · do **not** chain into mirror apply.
|
|
138
|
+
⊗ Silent exit.
|
|
139
|
+
|
|
140
|
+
## References
|
|
141
|
+
|
|
142
|
+
- #3198 process + dogfood · #3201 this skill · #3200 / patterns pilot brief
|
|
143
|
+
- #1396 decision log · #3179 propose-not-apply · #1423 / #3197 classify filter only
|
|
144
|
+
- Siblings: `deft-directive-triage`, `deft-directive-refinement` — not #1419/#1511 post-promotion
|
|
@@ -114,12 +114,24 @@ The release pipeline's Step 9/10/11 git mutations carry the bypass in subprocess
|
|
|
114
114
|
|
|
115
115
|
See [`docs/RELEASING.md`](../../../docs/RELEASING.md) § Fixable check failure during release for the operator runbook and the existing `--allow-skip-ci=#N` incident contract.
|
|
116
116
|
|
|
117
|
-
### Step 5 branch-coverage threshold — open-issue ledger hatch (#2866)
|
|
117
|
+
### Step 5 branch-coverage threshold — open-issue ledger hatch (#2866 / #3187)
|
|
118
118
|
|
|
119
|
-
! When **`task release` Step 5** fails on Vitest coverage below the 85% goal, apply this hatch **only** when **branches** is the **sole** metric below 85% (hairline branch miss — lines, functions, and statements all ≥ 85%). Confirm via the Step 5 failure output or `task coverage:hotspots` before hatching. If **any other metric** is also below 85%, or the failure is a hang / failing test / non-coverage defect, STOP — use § Fixable check failure — file-and-merge before resume (#2859) instead.
|
|
119
|
+
! When **`task release` Step 5** fails on Vitest coverage below the 85% goal, apply this hatch **only** when **branches** is the **sole** metric below 85% (hairline branch miss — lines, functions, and statements all ≥ 85%). Confirm via the Step 5 failure output, `coverage/coverage-final.json`, or `task coverage:hotspots` before hatching. If **any other metric** is also below 85%, or the failure is a hang / failing test / non-coverage defect, STOP — use § Fixable check failure — file-and-merge before resume (#2859) instead.
|
|
120
120
|
|
|
121
121
|
**Runtime disclosure (#2573):** `--allow-coverage-debt=#N` sets vitest coverage thresholds to zero for the release Step 5 run (`vitest.config.ts`). The hatch is justified only for branch-only hairlines; the filed debt issue MUST require restoring **all four metrics** (lines, functions, branches, statements) to ≥ 85% before close.
|
|
122
122
|
|
|
123
|
+
**Auto-hatch in `task release` Step 5 (#3187):** the pipeline classifies a non-zero Step 5 as `REAL_FAILURE` | `BRANCH_HAIRLINE` | `OTHER_COVERAGE` | `UNKNOWN` after **one** suite run.
|
|
124
|
+
|
|
125
|
+
1. `REAL_FAILURE` | `OTHER_COVERAGE` | `UNKNOWN` → **fail closed** (no auto-issue). Route product defects via #2859.
|
|
126
|
+
2. `BRANCH_HAIRLINE` + **any open** coverage-debt ledger entry → **fail closed** ("restore coverage; close `#N` first") — consecutive soft-pass ban (#2866).
|
|
127
|
+
3. `BRANCH_HAIRLINE` + **empty** open debt ledger → **auto-file** `#N` with markers `coverage-debt` and `--allow-coverage-debt`, measured metrics, cut version, and acceptance (all four metrics ≥ 85%); mark Step 5 `PASS_WITH_DEBT(#N)`; **continue the cut without re-running vitest**. Loud stderr banner + cite `#N` in CHANGELOG / release notes.
|
|
128
|
+
|
|
129
|
+
! **File before continue** — never soft-pass without a durable issue number.
|
|
130
|
+
|
|
131
|
+
? Operators MAY still pass `--allow-coverage-debt=#N` manually (PowerShell-safe: `--allow-coverage-debt=N` or `--allow-coverage-debt="#N"` — #2621) when re-running after a pre-filed debt issue.
|
|
132
|
+
|
|
133
|
+
**SHA suite stamp (#3187, coordinates with #3188 check ordering):** after suite **green** or `PASS_WITH_DEBT`, write a local SHA-bound stamp under `.deft/release-suite-stamp.json` (gitignored). Re-entry at the **same clean HEAD** skips the suite; dirty tree or different HEAD invalidates the stamp. ⊗ CI never trusts the stamp (GHA has no committed stamp; `CI`/`GITHUB_ACTIONS` force miss).
|
|
134
|
+
|
|
123
135
|
**Open-issue ledger (release-scoped only):**
|
|
124
136
|
|
|
125
137
|
1. Check for an **open coverage-debt tracking issue** (unpaid hatch from a prior cut) — union all three probes and dedupe by issue number:
|
|
@@ -128,15 +140,18 @@ See [`docs/RELEASING.md`](../../../docs/RELEASING.md) § Fixable check failure d
|
|
|
128
140
|
gh issue list --repo <owner>/<repo> --state open --search "coverage-debt in:title,body" --limit 20
|
|
129
141
|
gh issue list --repo <owner>/<repo> --state open --search "allow-coverage-debt in:body" --limit 20
|
|
130
142
|
```
|
|
131
|
-
- **CHANGELOG citation scan** (legacy hatch issues filed before markers were mandatory): parse `CHANGELOG.md` `[Unreleased]` plus the last three `## [version]` sections for `--allow-coverage-debt=#N` / `allow-coverage-debt=#N` citations; for each `#N`,
|
|
132
|
-
2. If **no open coverage-debt issue exists** →
|
|
143
|
+
- **CHANGELOG citation scan** (legacy hatch issues filed before markers were mandatory): parse `CHANGELOG.md` `[Unreleased]` plus the last three `## [version]` sections for `--allow-coverage-debt=#N` / `allow-coverage-debt=#N` citations; for each `#N`, probe issue state via REST — `OPEN` (or unknown) counts as unpaid debt even when title/body lack the new markers (#2866).
|
|
144
|
+
2. If **no open coverage-debt issue exists** → auto-hatch files `#N` (or operator files manually) with title prefix `coverage-debt:` and body containing both markers. The open `#N` remains WIP until coverage is restored and the issue is closed.
|
|
133
145
|
3. If an **open coverage-debt issue from a prior hatch still exists** → ⊗ soft-pass again; restore real coverage (all four metrics ≥ 85%) and close the debt issue before the cut proceeds.
|
|
134
146
|
|
|
147
|
+
**Framework-release-first (#3187):** auto-hatch applies to framework `task release` Step 5 (e.g. deftai/directive). Consumer expansion of auto-hatch is blocked on project `plan.policy.coverageDebt` (#3189) — refuse when `status=unset` or `mode=off`. Do not auto-file debt on the framework repo from consumer trees; consumer ledger is always the consumer repo.
|
|
148
|
+
|
|
135
149
|
⊗ Auto-pass on a near-miss band without `#N` (#2573).
|
|
136
150
|
⊗ Silent soft-pass with no tracked issue.
|
|
137
151
|
⊗ File a debt issue without `coverage-debt` / `allow-coverage-debt` markers in title or body — the ledger query will miss it and permit a consecutive soft-pass (#2866).
|
|
138
152
|
⊗ Use this carve-out when lines, functions, or statements are also below 85%, or for hangs, failing tests, or non-coverage Step 5 failures — those stay under #2859 file-and-merge.
|
|
139
153
|
⊗ Treat file-debt-then-hatch as the default for ordinary PR / `task check` work outside a release cut — this hatch is release-scoped only.
|
|
154
|
+
⊗ Trust a laptop suite stamp in CI or after HEAD/tree drift (#3187).
|
|
140
155
|
|
|
141
156
|
See [`docs/RELEASING.md`](../../../docs/RELEASING.md) § Coverage debt hatch during release.
|
|
142
157
|
|
|
@@ -373,4 +388,6 @@ Where `<one-line guidance>` is one of:
|
|
|
373
388
|
- ⊗ Manually rewrite the Phase 8 Slack `*Summary*:` line to deviate from the CHANGELOG `[<version>]` blockquote -- the canonical narrative is authored ONCE at Phase 1 via `--summary` and propagates verbatim across all three audiences (CHANGELOG / GitHub release body / Slack). Per-audience hand-edits create documentation drift that the deterministic `--summary` flow is designed to prevent. If the operator wants Slack-specific tone, fold it into the canonical Phase 1 wording before passing `--summary`, OR amend the CHANGELOG blockquote BEFORE Phase 8 so all three surfaces stay aligned
|
|
374
389
|
- ⊗ Export `DEFT_ALLOW_DEFAULT_BRANCH_COMMIT=1` for the entire release session or wrap `task release` / `task ci:local` in it (#1553) -- the env var is process-wide and leaks into nested tests and temporary repos, producing false preflight failures. Prefer `task policy:allow-direct-commits -- --confirm` and restore with `task policy:enforce-branches` after the cut (closeout commit+push may use a **scoped** env prefix on those three git commands only — see Branch-Protection Policy Guard, #2623)
|
|
375
390
|
- ⊗ Pass `--allow-coverage-debt=#N` unquoted on Windows PowerShell (#2621) -- `#` starts a comment and silently drops the issue number. Use `--allow-coverage-debt=N` or `--allow-coverage-debt="#N"`
|
|
376
|
-
- ⊗ Soft-pass coverage debt while an **open** coverage-debt issue from a prior hatch still exists (#2866 / #2573) -- restore real branch coverage >= 85% and close the debt issue before reusing `--allow-coverage-debt
|
|
391
|
+
- ⊗ Soft-pass coverage debt while an **open** coverage-debt issue from a prior hatch still exists (#2866 / #2573 / #3187) -- restore real branch coverage >= 85% and close the debt issue before reusing `--allow-coverage-debt` or expecting auto-hatch; the ledger is open GitHub issues, not prior CHANGELOG citations (#2618 superseded by open-issue ledger)
|
|
392
|
+
- ⊗ Re-run the full Step 5 suite after a legal branch-only hairline when auto-hatch already filed `#N` and continued (`PASS_WITH_DEBT`) — that is the ceremony tax #3187 removes
|
|
393
|
+
- ⊗ Trust `.deft/release-suite-stamp.json` in CI or after HEAD/tree drift (#3187)
|