@deftai/directive-content 0.94.0 → 0.95.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-sync/SKILL.md +4 -3
- package/QUICK-START.md +1 -1
- package/Taskfile.yml +1 -1
- package/UPGRADING.md +34 -1
- package/commands.md +22 -7
- package/contracts/agent-hook-readiness.md +67 -0
- package/conventions/rule-ownership.json +2 -2
- package/docs/freshness-contract.md +139 -0
- package/package.json +1 -1
- package/packs/skills/skills-pack-0.1.json +9 -7
- package/resilience/continue-here.md +8 -8
- package/skills/deft-directive-build/SKILL.md +18 -0
- package/skills/deft-directive-pre-pr/SKILL.md +18 -0
- package/skills/deft-directive-review-cycle/SKILL.md +18 -0
- package/skills/deft-directive-sync/SKILL.md +181 -26
- package/skills/deft-directive-triage/SKILL.md +3 -3
- package/tasks/triage-classify.yml +1 -1
- package/templates/agent-prompt-preamble.md +19 -0
|
@@ -25,14 +25,14 @@ Sessions end. Work must not be lost. A fresh session must resume from **exactly*
|
|
|
25
25
|
|
|
26
26
|
## Continue Checkpoint Contents
|
|
27
27
|
|
|
28
|
-
Persist to `./vbrief/continue.vbrief.json`
|
|
28
|
+
Persist to `./xbrief/continue.xbrief.json` in xBRIEF format (legacy `./vbrief/continue.vbrief.json` is read-accepted until migrated):
|
|
29
29
|
|
|
30
|
-
- ! **Completed** — what's already done (
|
|
31
|
-
- ! **Remaining** — what's left (
|
|
32
|
-
- ! **Decisions** — choices made during this session (
|
|
30
|
+
- ! **Completed** — what's already done (xBRIEF items with `completed` status)
|
|
31
|
+
- ! **Remaining** — what's left (xBRIEF items with `pending` status)
|
|
32
|
+
- ! **Decisions** — choices made during this session (xBRIEF narratives)
|
|
33
33
|
- ~ **Hazards** — what was tricky, what to watch out for (narrative)
|
|
34
34
|
- ! **Resume point** — the exact first thing to do when resuming (narrative on the next `pending` item)
|
|
35
|
-
- ! **Scope
|
|
35
|
+
- ! **Scope xBRIEF reference** — when scope xBRIEFs exist, MUST include `planRef` to the scope xBRIEF(s) the agent was working on (enables the resuming agent to load the durable scope record)
|
|
36
36
|
|
|
37
37
|
## Resume Protocol
|
|
38
38
|
|
|
@@ -47,8 +47,8 @@ Persist to `./vbrief/continue.vbrief.json` in vBRIEF format:
|
|
|
47
47
|
|
|
48
48
|
- ! Continue checkpoints are **ephemeral** — consumed on resume, not permanent records
|
|
49
49
|
- ~ Durable learnings from the session → persist to [meta/lessons.md](../../meta/lessons.md)
|
|
50
|
-
- ~ Durable state → persist to the task's
|
|
51
|
-
- ! Scope
|
|
50
|
+
- ~ Durable state → persist to the task's xBRIEF plan file or scope xBRIEF(s) in lifecycle folders
|
|
51
|
+
- ! Scope xBRIEFs (`./xbrief/{proposed,pending,active,completed,cancelled}/`; legacy `./vbrief/` read-accepted) are **durable** — they persist across sessions and are shared between agents; do not conflate them with ephemeral continue checkpoints
|
|
52
52
|
- ⊗ Accumulate stale continue checkpoints — clean up after resume
|
|
53
53
|
|
|
54
54
|
---
|
|
@@ -59,4 +59,4 @@ Persist to `./vbrief/continue.vbrief.json` in vBRIEF format:
|
|
|
59
59
|
- ⊗ Re-reading full conversation history instead of the continue checkpoint
|
|
60
60
|
- ⊗ Losing in-flight decisions because they weren't persisted
|
|
61
61
|
- ⊗ Starting over from scratch after an interruption
|
|
62
|
-
- ⊗ Creating `continue-{ULID}.json` — the file is singular: `continue.
|
|
62
|
+
- ⊗ Creating `continue-{ULID}.json` — the file is singular: `continue.xbrief.json`
|
|
@@ -344,6 +344,22 @@ feat(phase-2): add REST API endpoints with integration tests
|
|
|
344
344
|
- ! Scope xBRIEF ambiguous -> ask user; ⊗ guess
|
|
345
345
|
- ! Scope needs changes -> propose, get approval, update the scope xBRIEF first
|
|
346
346
|
|
|
347
|
+
|
|
348
|
+
## Probe-then-fill remote claims (#3120)
|
|
349
|
+
|
|
350
|
+
! Before filling any **remote** handoff field (PR URL, PR number, commit/HEAD SHA, CI green/success, review score) or claiming `status: pass` / ship/gate done, MUST **probe then fill**:
|
|
351
|
+
|
|
352
|
+
1. Run same-turn `git` + forge probes (examples: `git rev-parse HEAD`, `gh api repos/<owner>/<repo>/pulls/<N>`, `task pr:watch -- <N> --one-shot`, checks API).
|
|
353
|
+
2. Copy IDs / URLs / SHAs / scores **only** from that probe JSON/text into the evidence block.
|
|
354
|
+
3. Set `proof_status: bound` and attach short raw probe snippets (`command` + `snippet`) for each remote claim.
|
|
355
|
+
|
|
356
|
+
! Handoff evidence axes: **work** (local) / **ship** (pushed branch or PR) / **gate** (CI/review on HEAD). `proof_status` is `bound` | `unbound` | `n/a-no-remote-claim`.
|
|
357
|
+
! **Legal partial:** local work `done` + ship `not_started` / `blocked` **without** PR/SHA/CI/review fields and `proof_status: n/a-no-remote-claim` (or `status: partial`) is valid — do not invent ship state.
|
|
358
|
+
! **Fail ranking:** **invented-done** (false/unbound remote artifacts under pass) is **stricter** than **empty-done**. Unbound remote claims → invalid evidence (fail), not pass-with-notes.
|
|
359
|
+
! Machine check: `validateHandoffEvidence` in `packages/core/src/handoff-evidence/` (see `templates/agent-prompt-preamble.md` §11).
|
|
360
|
+
⊗ Fill PR / SHA / CI / review fields from recollection, narration, or prior-turn memory.
|
|
361
|
+
⊗ Claim `status: pass` with remote fields when `proof_status` is not `bound` or probes are missing (#3120).
|
|
362
|
+
|
|
347
363
|
## Completion
|
|
348
364
|
|
|
349
365
|
- ! When all phases pass and `task check` is green, complete each implemented story via `task scope:complete -- <active-story-path>` before final PR handoff.
|
|
@@ -370,3 +386,5 @@ feat(phase-2): add REST API endpoints with integration tests
|
|
|
370
386
|
- ⊗ Skip the Change Lifecycle Gate because the user said "proceed" -- broad approval does not satisfy the confirmation gate
|
|
371
387
|
- ⊗ Commit or push directly to the default branch -- always create a feature branch first. Exception: user explicitly instructs a direct commit, or `PROJECT-DEFINITION.xbrief.json` narratives contain `Allow direct commits to master: true`
|
|
372
388
|
- ⊗ Add a prohibition (`!` or `⊗`) without scanning the same file for conflicting softer-strength rules (`~`, `≉`) that reference the same term
|
|
389
|
+
- ⊗ Invent remote PR/SHA/CI/review claims in handoff evidence without same-turn probe binding — invented-done (#3120)
|
|
390
|
+
- ⊗ Fill remote ship/gate fields from memory when only local work completed; legal partial omits PR fields (#3120)
|
|
@@ -162,6 +162,22 @@ git --no-pager diff master
|
|
|
162
162
|
- ! If a full Read-Write-Lint-Diff cycle produced zero changes: exit the loop
|
|
163
163
|
- ~ Track iteration count -- if you exceed 3 iterations, pause and assess whether you are oscillating between competing fixes
|
|
164
164
|
|
|
165
|
+
|
|
166
|
+
## Probe-then-fill remote claims (#3120)
|
|
167
|
+
|
|
168
|
+
! Before filling any **remote** handoff field (PR URL, PR number, commit/HEAD SHA, CI green/success, review score) or claiming `status: pass` / ship/gate done, MUST **probe then fill**:
|
|
169
|
+
|
|
170
|
+
1. Run same-turn `git` + forge probes (examples: `git rev-parse HEAD`, `gh api repos/<owner>/<repo>/pulls/<N>`, `task pr:watch -- <N> --one-shot`, checks API).
|
|
171
|
+
2. Copy IDs / URLs / SHAs / scores **only** from that probe JSON/text into the evidence block.
|
|
172
|
+
3. Set `proof_status: bound` and attach short raw probe snippets (`command` + `snippet`) for each remote claim.
|
|
173
|
+
|
|
174
|
+
! Handoff evidence axes: **work** (local) / **ship** (pushed branch or PR) / **gate** (CI/review on HEAD). `proof_status` is `bound` | `unbound` | `n/a-no-remote-claim`.
|
|
175
|
+
! **Legal partial:** local work `done` + ship `not_started` / `blocked` **without** PR/SHA/CI/review fields and `proof_status: n/a-no-remote-claim` (or `status: partial`) is valid — do not invent ship state.
|
|
176
|
+
! **Fail ranking:** **invented-done** (false/unbound remote artifacts under pass) is **stricter** than **empty-done**. Unbound remote claims → invalid evidence (fail), not pass-with-notes.
|
|
177
|
+
! Machine check: `validateHandoffEvidence` in `packages/core/src/handoff-evidence/` (see `templates/agent-prompt-preamble.md` §11).
|
|
178
|
+
⊗ Fill PR / SHA / CI / review fields from recollection, narration, or prior-turn memory.
|
|
179
|
+
⊗ Claim `status: pass` with remote fields when `proof_status` is not `bound` or probes are missing (#3120).
|
|
180
|
+
|
|
165
181
|
## Exit Condition
|
|
166
182
|
|
|
167
183
|
! Exit when a complete Read-Write-Lint-Diff cycle produces **zero changes** -- no file edits in Write, no lint fixes in Lint, and no scope issues in Diff.
|
|
@@ -179,3 +195,5 @@ After exiting:
|
|
|
179
195
|
- ⊗ Ignore the iteration count -- more than 3 iterations usually indicates oscillating fixes or an unclear spec task
|
|
180
196
|
- ⊗ Add a prohibition (`!` or `⊗`) without scanning the same file for conflicting softer-strength rules (`~`, `≉`) that reference the same term
|
|
181
197
|
- ⊗ Skip `task pr:check-closing-keywords` (#737) before pushing a PR. Intent mode (#3015) also refuses bare/conditional real `Closes #N` without `--allow-close`. The negation-context substring match is the Layer 0 (prevention) gate that prevents the recurring auto-close of umbrella / staying-OPEN issues observed in #697 (closed #642), #401 (closed #642), #700 (closed #233), and #735 (closed #734) -- each incident required manual reopen and downstream cleanup. The lint's three-state exit (0 clean / 1 hits found / 2 config error) MUST be treated as a hard refusal: rewrite the PR body / commit messages until clean, OR pass `--allow-known-false-positives` ONLY for legitimately-quoted occurrences (test fixtures, documentation that discusses the trigger token literally). See `skills/deft-directive-swarm/SKILL.md` Phase 6 Step 1 for the corresponding Layer 3 (recovery) `pr:check-protected-issues` rule (#701)
|
|
198
|
+
- ⊗ Invent remote PR/SHA/CI/review claims in handoff evidence without same-turn probe binding — invented-done (#3120)
|
|
199
|
+
- ⊗ Fill remote ship/gate fields from memory when only local work completed; legal partial omits PR fields (#3120)
|
|
@@ -617,6 +617,22 @@ task lifecycle:event -- emit plan:approved \
|
|
|
617
617
|
3. ~ This step mirrors `skills/deft-directive-swarm/SKILL.md` Phase 6 Step 2 and applies to ALL PR merges, not just swarm runs.
|
|
618
618
|
4. ! For PRs that referenced any umbrella / staying-OPEN issue (`Refs #N`), the INVERSE check applies: any protected issue that auto-closed MUST be reopened with a comment citing #701 and the merged PR. See `skills/deft-directive-swarm/SKILL.md` Phase 6 Step 1 protected-issue reopen sweep and `meta/lessons.md` `## GitHub Closing-Keyword False-Positive Layer 3` for the persistent `closingIssuesReferences` link case (Layer 3, #701).
|
|
619
619
|
|
|
620
|
+
|
|
621
|
+
## Probe-then-fill remote claims (#3120)
|
|
622
|
+
|
|
623
|
+
! Before filling any **remote** handoff field (PR URL, PR number, commit/HEAD SHA, CI green/success, review score) or claiming `status: pass` / ship/gate done, MUST **probe then fill**:
|
|
624
|
+
|
|
625
|
+
1. Run same-turn `git` + forge probes (examples: `git rev-parse HEAD`, `gh api repos/<owner>/<repo>/pulls/<N>`, `task pr:watch -- <N> --one-shot`, checks API).
|
|
626
|
+
2. Copy IDs / URLs / SHAs / scores **only** from that probe JSON/text into the evidence block.
|
|
627
|
+
3. Set `proof_status: bound` and attach short raw probe snippets (`command` + `snippet`) for each remote claim.
|
|
628
|
+
|
|
629
|
+
! Handoff evidence axes: **work** (local) / **ship** (pushed branch or PR) / **gate** (CI/review on HEAD). `proof_status` is `bound` | `unbound` | `n/a-no-remote-claim`.
|
|
630
|
+
! **Legal partial:** local work `done` + ship `not_started` / `blocked` **without** PR/SHA/CI/review fields and `proof_status: n/a-no-remote-claim` (or `status: partial`) is valid — do not invent ship state.
|
|
631
|
+
! **Fail ranking:** **invented-done** (false/unbound remote artifacts under pass) is **stricter** than **empty-done**. Unbound remote claims → invalid evidence (fail), not pass-with-notes.
|
|
632
|
+
! Machine check: `validateHandoffEvidence` in `packages/core/src/handoff-evidence/` (see `templates/agent-prompt-preamble.md` §11).
|
|
633
|
+
⊗ Fill PR / SHA / CI / review fields from recollection, narration, or prior-turn memory.
|
|
634
|
+
⊗ Claim `status: pass` with remote fields when `proof_status` is not `bound` or probes are missing (#3120).
|
|
635
|
+
|
|
620
636
|
## Anti-Patterns
|
|
621
637
|
|
|
622
638
|
- ⊗ End owning turn with 0 children, no sticky lease, and no finish after drive-to-merge / babysit / shepherd claim — silent hold (#3090)
|
|
@@ -658,3 +674,5 @@ task lifecycle:event -- emit plan:approved \
|
|
|
658
674
|
- ⊗ Treat empty/unknown review-monitor settle as DONE/CLEAN/merge-ready without same-turn ground truth (#3044 / FC04 residual)
|
|
659
675
|
- ⊗ Spawn a second review-monitor while prior owner is running or last settle was empty/unknown without terminal ground truth (#3044)
|
|
660
676
|
- ⊗ Accept empty review-monitor final message missing STATUS/HEAD/CHECKS/MERGE handback (#3044)
|
|
677
|
+
- ⊗ 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)
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: deft-directive-sync
|
|
3
3
|
description: >-
|
|
4
|
-
Session-start framework sync
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
Session-start framework sync and upgrade handoff. Refreshes deposit via npm
|
|
5
|
+
+ directive/deft update, validates xBRIEF lifecycle, detects stale origins
|
|
6
|
+
(RFC D12), and finishes SCM release handoff in released | pr-open |
|
|
7
|
+
blocked:<reason> (#1604).
|
|
7
8
|
triggers:
|
|
8
9
|
- good morning
|
|
9
10
|
- update deft
|
|
11
|
+
- update directive
|
|
12
|
+
- upgrade framework
|
|
10
13
|
- update xbrief
|
|
11
14
|
- sync frameworks
|
|
12
15
|
---
|
|
@@ -18,23 +21,34 @@ triggers:
|
|
|
18
21
|
|
|
19
22
|
# Deft Directive Sync
|
|
20
23
|
|
|
21
|
-
Session-start framework sync --
|
|
24
|
+
Session-start framework sync and upgrade handoff -- refresh the framework deposit via npm + `directive update` / `deft update`, validate xBRIEF lifecycle structure, detect stale origins (RFC D12), then finish SCM release handoff in a named terminal state (#1604).
|
|
22
25
|
|
|
23
|
-
> **Canonical bootstrap / update path (#761
|
|
26
|
+
> **Canonical bootstrap / update path (#761 / #1604):** Install and upgrade via npm: `npm i -g @deftai/directive` (install) or `npm i -g @deftai/directive@latest` (upgrade); Node >= 20 is required. Then from the project root run `directive update` (or `deft update`) to refresh `.deft/core/`, optionally `deft migrate` for npm provenance, and `directive doctor` / `deft doctor` / `task doctor` to confirm deposit health. For machines without Node, the frozen legacy Go installer (`deft-install` / platform-specific `install-*` from GitHub Releases) is a no-Node bootstrap bridge (#1912) -- migrate to npm once Node is available. Legacy `run upgrade` / `task upgrade` are metadata-only acknowledgment (they do NOT replace the payload). **Git-submodule / `task framework:doctor` paths are back-compat only** -- Phases 1-2 below are the legacy update flow, de-emphasized in UPGRADING.md / README. Deposit success is not upgrade released; Phase 8 records one terminal state: `released` | `pr-open` | `blocked:<reason>`. See UPGRADING.md and #761 / #1912 / #1604.
|
|
24
27
|
|
|
25
28
|
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
26
29
|
|
|
27
30
|
## Platform Requirements
|
|
28
31
|
|
|
29
|
-
! This skill requires **GitHub** as the SCM platform and the **GitHub CLI (`gh`)** to be installed and authenticated
|
|
32
|
+
! This skill requires **GitHub** as the SCM platform and the **GitHub CLI (`gh`)** to be installed and authenticated for origin freshness (Phase 5) and for the PR path of Phase 8 SCM release handoff. Origin freshness checks fetch issue data via REST-equivalent `gh` surfaces (prefer `gh api repos/<owner>/<repo>/issues/<N>` over GraphQL-heavy forms when under rate pressure; #954).
|
|
30
33
|
|
|
31
34
|
## When to Use
|
|
32
35
|
|
|
33
|
-
- User says "good morning", "update deft", "update xbrief", or "sync frameworks"
|
|
36
|
+
- User says "good morning", "update deft", "update directive", "upgrade framework", "update xbrief", or "sync frameworks"
|
|
34
37
|
- Beginning of a new session where framework updates may be available
|
|
35
|
-
- After a known upstream deft release
|
|
38
|
+
- After a known upstream deft / `@deftai/directive` release
|
|
39
|
+
- After a successful local deposit when the default branch still lacks the framework update
|
|
36
40
|
|
|
41
|
+
## Missing CLI / PATH remediation
|
|
37
42
|
|
|
43
|
+
! When `directive`, `deft`, or the global npm bin is missing from PATH (or `npm i -g @deftai/directive@latest` has not been run), surface actionable install remediation first:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm i -g @deftai/directive@latest
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
(or the pnpm equivalent: `pnpm add -g @deftai/directive@latest`). Then re-run `directive update` / `deft update` and `directive doctor`.
|
|
50
|
+
|
|
51
|
+
⊗ Send the operator to manual GitHub release-asset archaeology or Go installer discovery as the happy path when Node is available -- npm is the primary remediation (#761 / #1604).
|
|
38
52
|
|
|
39
53
|
## Session orientation — unmanaged header (#2065)
|
|
40
54
|
|
|
@@ -65,7 +79,7 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
65
79
|
|
|
66
80
|
### Action on Detection
|
|
67
81
|
|
|
68
|
-
! If pre-cutover state is detected, display the actionable migration message, then **skip Phases
|
|
82
|
+
! If pre-cutover state is detected, display the actionable migration message, then **skip Phases 0-6** and proceed directly to Phase 7 with the Document Model line set to "pre-v0.20 (legacy)". Phase 8 still applies if a local migration/framework change must land on the default branch after the frozen migrator path:
|
|
69
83
|
|
|
70
84
|
> "This project uses the pre-v0.20 document model. Current npm releases no longer ship in-product `task migrate:vbrief` (#2068). Follow UPGRADING.md § Frozen pre-v0.20 document-model migration: pin framework v0.59.0, install Python 3.11+ and uv, run `task migrate:vbrief` once from that payload, then upgrade to current npm."
|
|
71
85
|
|
|
@@ -88,12 +102,77 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
88
102
|
⊗ Skip model state detection during sync -- always report the document model state.
|
|
89
103
|
⊗ Silently ignore pre-cutover artifacts -- the user must be informed with an actionable command to fix the state.
|
|
90
104
|
|
|
91
|
-
## Phase
|
|
105
|
+
## Phase 0 -- Primary upgrade (npm deposit) (#761 / #1604)
|
|
106
|
+
|
|
107
|
+
! Treat npm + `directive update` / `deft update` as the **primary** consumer upgrade path when an upgrade is authorized. Do not lead with submodule update when Node is available.
|
|
108
|
+
|
|
109
|
+
### 0a: When mutation is authorized
|
|
110
|
+
|
|
111
|
+
! **Mutating** engine install / deposit refresh is authorized only when at least one of:
|
|
112
|
+
|
|
113
|
+
1. The operator used an **explicit upgrade** trigger: `update deft`, `update directive`, `upgrade framework`, or equivalent ("upgrade Directive", "run update").
|
|
114
|
+
2. Doctor / payload-staleness already reports the deposit is **behind** and the operator confirmed the upgrade (or autonomous upgrade was pre-approved).
|
|
115
|
+
3. CLI is **missing** from PATH -- then Missing CLI remediation may install the global package so doctor/update can run.
|
|
116
|
+
|
|
117
|
+
! For routine session orientation triggers (`good morning`, `sync frameworks`, plain `update xbrief` without upgrade language):
|
|
118
|
+
|
|
119
|
+
1. ! Run **read-only** checks: CLI present?, `directive doctor` / `deft doctor` / `task doctor` when available, structure validation (Phases 3+).
|
|
120
|
+
2. ! If doctor reports a stale deposit or available upgrade, **report** the recommended command and ask for consent before mutating.
|
|
121
|
+
3. ⊗ Run `npm i -g @deftai/directive@latest` or `directive update` / `deft update` on a routine "good morning" without staleness evidence **and** operator consent (or pre-approved autonomous upgrade).
|
|
122
|
+
|
|
123
|
+
### 0b: Consumer worktree isolation before deposit
|
|
124
|
+
|
|
125
|
+
! Before any mutating deposit that will be handed off in Phase 8:
|
|
126
|
+
|
|
127
|
+
1. ! Run `git status --porcelain` at the **project root** (not only the legacy submodule).
|
|
128
|
+
2. ! If the worktree or index has non-framework product changes (or any unexpected staged paths), **stop** and either:
|
|
129
|
+
- ask the operator to stash / commit product work first, or
|
|
130
|
+
- record `blocked:dirty-worktree` and skip deposit mutation,
|
|
131
|
+
- or, with explicit consent, isolate product changes (stash including index) so the deposit cannot mix with them.
|
|
132
|
+
3. ! After deposit, stage **only** framework-managed paths for the upgrade commit (e.g. `.deft/core/`, managed AGENTS section, hooks, VERSION / marker files). Reconstruct a clean index if needed rather than `git add -A`.
|
|
133
|
+
4. ⊗ Create a framework-only commit or PR from a mixed worktree/index that still carries product feature paths.
|
|
134
|
+
|
|
135
|
+
### 0c: Engine + deposit (when authorized)
|
|
136
|
+
|
|
137
|
+
1. ! Confirm the global CLI is available (`directive --version` or `deft --version`). If missing, run Missing CLI / PATH remediation above, then continue.
|
|
138
|
+
2. ! Upgrade the global engine only when mutation is authorized (0a):
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm i -g @deftai/directive@latest
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
3. ! From the **project root**, after worktree isolation (0b), refresh the deposit:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
directive update
|
|
148
|
+
# or: deft update
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
4. ~ Optionally stamp npm provenance (idempotent): `directive migrate` / `deft migrate`.
|
|
152
|
+
5. ! Verify deposit health:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
directive doctor
|
|
156
|
+
# or: deft doctor / task doctor
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
6. ! Record whether the working tree now has **framework-only** changes under `.deft/core/`, managed AGENTS section, hooks, or related managed files that need SCM release.
|
|
160
|
+
|
|
161
|
+
### 0d: Framework-only change-set discipline
|
|
162
|
+
|
|
163
|
+
! Keep upgrade commits/PRs **framework-only** -- do not mix product feature work into the same commit or PR as the deposit refresh.
|
|
164
|
+
|
|
165
|
+
⊗ Treat a successful deposit alone as `released` -- the default branch must carry the update (or a PR must be open) before the operator goal is complete (#1604).
|
|
166
|
+
⊗ Force a global CLI upgrade or deposit mutation on routine session sync without consent or staleness evidence.
|
|
167
|
+
|
|
168
|
+
## Phase 1 -- Pre-flight (legacy submodule path)
|
|
169
|
+
|
|
170
|
+
! **Legacy / back-compat only.** Run Phases 1-2 only when the consumer still uses a `deft/` git submodule layout and cannot use the npm deposit path. Prefer Phase 0 for all npm-managed installs.
|
|
92
171
|
|
|
93
172
|
! Check that the deft/ submodule working tree is clean before attempting any update.
|
|
94
173
|
|
|
95
174
|
1. ! Run `git -C deft status --porcelain`
|
|
96
|
-
2. ! If output is non-empty (dirty working tree): **stop** and ask user whether to stash (`git -C deft stash`) or abort the sync entirely. Do NOT proceed with a dirty submodule.
|
|
175
|
+
2. ! If output is non-empty (dirty working tree): **stop** and ask user whether to stash (`git -C deft stash`) or abort the sync entirely. Do NOT proceed with a dirty submodule. Record terminal state `blocked:dirty-submodule` if the operator aborts.
|
|
97
176
|
3. ! Record the current DEFT commit for later comparison:
|
|
98
177
|
```
|
|
99
178
|
git -C deft log --oneline -1
|
|
@@ -103,7 +182,9 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
103
182
|
- Clean/dirty status
|
|
104
183
|
- Confirmation that pre-flight passed (or the blocker if dirty)
|
|
105
184
|
|
|
106
|
-
## Phase 2 -- Update DEFT Submodule
|
|
185
|
+
## Phase 2 -- Update DEFT Submodule (legacy / back-compat)
|
|
186
|
+
|
|
187
|
+
! **Legacy / back-compat only** -- not the primary consumer upgrade path (#1604). Submodule update does not replace Phase 0 for npm installs.
|
|
107
188
|
|
|
108
189
|
1. ! Run the submodule update:
|
|
109
190
|
```
|
|
@@ -214,7 +295,7 @@ After structure validation, sync framework-level assets.
|
|
|
214
295
|
|
|
215
296
|
### 6a: Check AGENTS.md freshness
|
|
216
297
|
|
|
217
|
-
~ Compare the project's `AGENTS.md` against the deft template (if a template exists in the updated `deft/` submodule):
|
|
298
|
+
~ Compare the project's `AGENTS.md` against the deft template (if a template exists in the updated deposit / `.deft/core/` or legacy `deft/` submodule):
|
|
218
299
|
|
|
219
300
|
1. ~ Diff the structure (section headings, key rules) rather than expecting byte-identical content
|
|
220
301
|
2. ~ Report any new sections or rules added upstream that are missing locally
|
|
@@ -230,7 +311,7 @@ After structure validation, sync framework-level assets.
|
|
|
230
311
|
|
|
231
312
|
### 6c: List new skills
|
|
232
313
|
|
|
233
|
-
! Compare the `skills/` directory before and after the update:
|
|
314
|
+
! Compare the `skills/` directory (or deposited `.deft/core/` skills) before and after the update:
|
|
234
315
|
|
|
235
316
|
1. ! List any new skill directories added in the update
|
|
236
317
|
2. ~ For each new skill, read its frontmatter `description` field and present a one-liner
|
|
@@ -282,29 +363,103 @@ Doc sprawl is a project-health concern, not just a human-experience one: a lean,
|
|
|
282
363
|
|
|
283
364
|
! Present a consolidated summary to the user covering:
|
|
284
365
|
|
|
285
|
-
1. **
|
|
286
|
-
2. **
|
|
287
|
-
3. **
|
|
288
|
-
4. **
|
|
289
|
-
5. **
|
|
290
|
-
6. **
|
|
291
|
-
7. **
|
|
292
|
-
8. **
|
|
293
|
-
9. **
|
|
294
|
-
10. **
|
|
366
|
+
1. **Upgrade path used**: npm deposit (Phase 0) / legacy submodule (Phases 1-2) / already up to date
|
|
367
|
+
2. **DEFT / deposit version change**: old version or commit -> new (or "already up to date")
|
|
368
|
+
3. **Structure validation**: lifecycle folders status (all present / missing folders listed)
|
|
369
|
+
4. **PROJECT-DEFINITION status**: valid / missing / stale (with freshness details)
|
|
370
|
+
5. **xBRIEF validation results**: pass/fail per file, with details on any failures
|
|
371
|
+
6. **Lifecycle consistency**: all consistent / N mismatches found (with details)
|
|
372
|
+
7. **Origin freshness**: N stale / N externally-closed / N current (with details)
|
|
373
|
+
8. **Document Model**: pre-v0.20 (legacy) / v0.20+ (xBRIEF-centric) OK / v0.20+ with warnings (see Pre-Cutover Detection Guard)
|
|
374
|
+
9. **AGENTS.md status**: current / has upstream changes / needs review
|
|
375
|
+
10. **Codebase MAP status**: current / stale / absent / not configured (advisory)
|
|
376
|
+
11. **New skills**: list any newly added skills with descriptions
|
|
377
|
+
12. **Pending SCM release**: whether framework-only changes still need commit/push/PR/merge (Phase 8)
|
|
295
378
|
|
|
296
|
-
!
|
|
379
|
+
! After a successful deposit (or submodule bump), **do not stop at the local change set**. Proceed to Phase 8 SCM release handoff. If there is nothing to release (already on default branch / no local framework delta), record terminal state `released` when the default branch already carries the current framework update; otherwise name the next release step.
|
|
380
|
+
|
|
381
|
+
? For the legacy submodule path only, if a bump is ready and the operator has not yet approved a commit, ask: "Shall I commit the submodule update and continue SCM release handoff?" -- do NOT auto-commit without approval. Prefer message:
|
|
297
382
|
|
|
298
|
-
? If the user confirms, commit with message:
|
|
299
383
|
```
|
|
300
384
|
chore(deft): update deft submodule to <short-hash>
|
|
301
385
|
```
|
|
302
386
|
|
|
387
|
+
For npm deposit changes, prefer a framework-only commit message such as:
|
|
388
|
+
|
|
389
|
+
```
|
|
390
|
+
chore(deft): refresh framework deposit to <version>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Phase 8 -- SCM release handoff (#1604)
|
|
394
|
+
|
|
395
|
+
! After a successful framework deposit (Phase 0) or legacy submodule bump (Phases 1-2), carry the update through consumer SCM release. Installer/update success is not upgrade released.
|
|
396
|
+
|
|
397
|
+
! Record **exactly one** terminal state when this skill exits after a deposit-related run:
|
|
398
|
+
|
|
399
|
+
| Terminal state | Meaning |
|
|
400
|
+
| --- | --- |
|
|
401
|
+
| `released` | Default branch carries the framework update (merged or committed directly under policy). |
|
|
402
|
+
| `pr-open` | Framework-only branch pushed and PR opened; awaiting review/merge per policy. |
|
|
403
|
+
| `blocked:<reason>` | Explicit blocker (examples: `blocked:dirty-worktree`, `blocked:auth`, `blocked:branch-protection`, `blocked:human-merge-gate`, `blocked:ci`, `blocked:operator-declined`). |
|
|
404
|
+
|
|
405
|
+
### 8a: Policy detection
|
|
406
|
+
|
|
407
|
+
1. ! Read consumer branch policy: `plan.policy.allowDirectCommitsToMaster`, `plan.policy.requireHumanMerge`, and any known branch-protection / default-branch rules (`deft policy:show` when available).
|
|
408
|
+
2. ! Classify the path:
|
|
409
|
+
- **PR path (default when protected or human-merge):** branch protection enabled, or `requireHumanMerge` is true, or direct commits to default branch are disallowed.
|
|
410
|
+
- **Direct-commit path:** `allowDirectCommitsToMaster` (or equivalent) is true **and** human-merge is not required **and** branch protection does not forbid the commit.
|
|
411
|
+
|
|
412
|
+
### 8b: PR-oriented path (branch-protected / human-merge)
|
|
413
|
+
|
|
414
|
+
1. ! With operator consent (or autonomous consent when the operator already approved upgrade handoff), create a **framework-only** branch (e.g. `chore/deft-update-<version>`), commit framework deposit files only, push, and open a PR targeting the default branch.
|
|
415
|
+
2. ! Stop at terminal state **`pr-open`** once the PR URL is available -- unless policy explicitly allows bot merge **and** the operator directed merge.
|
|
416
|
+
3. ⊗ Auto-merge past `requireHumanMerge` / the human merge gate (#1193). Agents may open PRs; they do not merge when policy forbids it.
|
|
417
|
+
4. ⊗ Claim `released` when the PR is only open or only locally committed.
|
|
418
|
+
|
|
419
|
+
### 8c: Direct-commit-enabled path
|
|
420
|
+
|
|
421
|
+
1. ! Present an **explicit** default-branch path with confirmation (do not silently commit to master/main).
|
|
422
|
+
2. ! On confirmation, commit framework-only changes on the default branch (or merge the framework branch) and push so the default branch carries the update.
|
|
423
|
+
3. ! Record terminal state **`released`** only after the default branch ref includes the framework update.
|
|
424
|
+
|
|
425
|
+
### 8d: Stop-after-commit is a failure mode
|
|
426
|
+
|
|
427
|
+
! A local framework-only commit without push/PR/merge **and** without naming the next release step is a **failure mode** of this skill (#1604 historical class).
|
|
428
|
+
|
|
429
|
+
- ! If the workflow must pause after a local commit, name the next step explicitly (push + open PR, or confirm direct-commit + push) and record `blocked:<reason>` or continue until `pr-open` / `released`.
|
|
430
|
+
- ⊗ End the skill at "local framework-only commit done" without a terminal state line.
|
|
431
|
+
- ⊗ Report `released` when only a local commit exists and the default branch does not yet carry the update.
|
|
432
|
+
|
|
433
|
+
### 8e: Terminal state line
|
|
434
|
+
|
|
435
|
+
! End the skill output with a single machine-readable line operators and agents can grep:
|
|
436
|
+
|
|
437
|
+
```text
|
|
438
|
+
upgrade-handoff: released
|
|
439
|
+
upgrade-handoff: pr-open
|
|
440
|
+
upgrade-handoff: blocked:<reason>
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
Include the PR URL when state is `pr-open`, and the merge/default-branch SHA when state is `released`.
|
|
444
|
+
|
|
445
|
+
### 8f: Framework-only path allowlist
|
|
446
|
+
|
|
447
|
+
! When committing for handoff, include only framework deposit artifacts (managed `.deft/core/`, AGENTS managed section, hooks, VERSION/marker files, and other paths the deposit itself refreshed). Exclude product source, tests, and unrelated staged files. If isolation was used in 0b, restore the operator's product stash only **after** the framework commit is complete (or on a separate branch).
|
|
448
|
+
|
|
303
449
|
## Anti-Patterns
|
|
304
450
|
|
|
305
451
|
- ⊗ Auto-commit submodule changes without user approval
|
|
452
|
+
- ⊗ Auto-commit or auto-push framework deposit changes without the Phase 8 policy path and consent rules
|
|
453
|
+
- ⊗ Stop after a local framework-only commit without naming the next release step or recording a terminal state (#1604)
|
|
454
|
+
- ⊗ Claim terminal state `released` when the update is only local or only on an open PR
|
|
455
|
+
- ⊗ Auto-merge when `requireHumanMerge` is true or branch protection forbids bot merge (#1193)
|
|
456
|
+
- ⊗ Treat git submodule update as the primary consumer upgrade path when npm + `directive update` / `deft update` is available
|
|
457
|
+
- ⊗ Send operators to manual GitHub release-asset archaeology when `npm i -g @deftai/directive@latest` is the correct remediation
|
|
306
458
|
- ⊗ Overwrite project-level `./xbrief/*.xbrief.json` files -- those are project data
|
|
307
459
|
- ⊗ Skip the pre-flight dirty check -- a dirty submodule can cause merge conflicts or data loss
|
|
308
460
|
- ⊗ Include a separate fetch of the xBRIEF schema from upstream deftai/xBRIEF -- that is a CI concern (see #128), not a user sync task
|
|
309
461
|
- ⊗ Auto-move xBRIEFs to fix folder/status mismatches -- report only; never auto-fix
|
|
310
462
|
- ⊗ Auto-update xBRIEFs based on origin freshness -- report only; user decides during refinement
|
|
463
|
+
- ⊗ Mix product feature work into a framework-only upgrade commit or PR
|
|
464
|
+
- ⊗ Force `npm i -g @deftai/directive@latest` or deposit mutation on routine session sync without staleness evidence and operator consent
|
|
465
|
+
- ⊗ Run Phase 8 framework-only commit from a mixed product+framework worktree/index without isolation
|
|
@@ -78,7 +78,7 @@ Directive does not guess your mix: **ordered plan** (`task plan-sequence:*`) whe
|
|
|
78
78
|
|
|
79
79
|
! Walk per-item decisions through the canonical `task triage:*` verbs (tasks own audit-log append / schema / `xbrief/proposed/` write).
|
|
80
80
|
|
|
81
|
-
! **Operator brief (same turn as menu) (#2890):** Before every per-item decision menu, present an operator brief in the **same operator-visible message/surface** as the menu, containing at least: issue `#N
|
|
81
|
+
! **Operator brief (same turn as menu) (#2890 / #3116):** Before every per-item decision menu, present an operator brief in the **same operator-visible message/surface** as the menu, containing at least: **URL-first** lead (canonical issue URL as the first line for that item, or `#N title` + URL); labels (or explicit none); **current-state validity** (`still-open` | `partial` | `likely-shipped` | `needs-re-scope`) + one-line evidence (linked closed PR, code path, or "no evidence of fix"); 2–5 line problem/context summary; AC bullets or explicit "thin body / no AC"; agent **lean** + one-line why (Accept / Defer / Reject / Needs-AC / …). ~ Prefer `task triage:show --format=operator <N>` as the brief backbone (URL-first + validity placeholder); agent still owns validity verdict and lean. ⊗ Menu-only or chip-only Phase 3 turns without that brief. ⊗ Brief-only turn followed by a later chip/menu-only turn that does not restate the brief. ⊗ Body-only summary without validity check against current master, closed children, or linked PRs.
|
|
82
82
|
|
|
83
83
|
! **Host structured-question adapter:** On chips / `ask_user` / similar UIs (e.g. OpenClaw `ask_user`), keep the prose brief in chat; structured options are **actions only** (Accept / Defer / Reject / Needs-AC / Mark duplicate / Discuss / Back). Option labels ≉ substitute for the brief.
|
|
84
84
|
|
|
@@ -120,7 +120,7 @@ What would you like to do with this candidate?
|
|
|
120
120
|
|
|
121
121
|
- ⊗ Recommend work without `task triage:queue` (#1149).
|
|
122
122
|
- ⊗ Conclude "nothing to do" from folder scans or live GitHub alone (#2576).
|
|
123
|
-
- ⊗ Stale-cache walk; reimplement audit/`proposed/` writes; treat defer/needs-ac as terminal; edit candidates.jsonl; menu-only Phase 3 without operator brief (#2890).
|
|
123
|
+
- ⊗ Stale-cache walk; reimplement audit/`proposed/` writes; treat defer/needs-ac as terminal; edit candidates.jsonl; menu-only Phase 3 without operator brief (#2890); body-only brief without URL-first or current-state validity (#3116).
|
|
124
124
|
|
|
125
125
|
## EXIT
|
|
126
126
|
|
|
@@ -128,5 +128,5 @@ What would you like to do with this candidate?
|
|
|
128
128
|
|
|
129
129
|
## References
|
|
130
130
|
|
|
131
|
-
- #1119 D6; #1128 D11 (`triage:queue` / `show` / `audit`); #2890 Phase 3 operator brief; #1122 / #1123 / #1127 / #1129 / #1131
|
|
131
|
+
- #1119 D6; #1128 D11 (`triage:queue` / `show` / `audit`); #2890 Phase 3 operator brief; #3116 validity + URL-first; #1122 / #1123 / #1127 / #1129 / #1131
|
|
132
132
|
- Siblings: `deft-directive-refinement`, `deft-directive-swarm`, `deft-directive-sync`
|
|
@@ -22,7 +22,7 @@ vars:
|
|
|
22
22
|
|
|
23
23
|
tasks:
|
|
24
24
|
classify:
|
|
25
|
-
desc: "Inspect / validate
|
|
25
|
+
desc: "Inspect / validate triageAutoClassify + triageLabelMirror; Tier-1 SCM label mirror (#1129 / #1423). -- task triage:classify -- [--list | --validate | --mirror [--apply]]"
|
|
26
26
|
internal: true
|
|
27
27
|
deps: [":engine:_ts-build"]
|
|
28
28
|
dir: '{{.USER_WORKING_DIR}}'
|
|
@@ -547,11 +547,30 @@ Every worker MUST send a final status message before exiting its tool loop, rega
|
|
|
547
547
|
|
|
548
548
|
! **`review_cycle` evidence enum (#3090):** Handoffs, swarm finish messages, and L4 process claims MUST use only `done` | `in_progress:<pr>#<monitor_or_lease_ref>` | `skipped:<reason>` | `n/a`. Freeform `started` / `pending` / `initiated` is forbidden. L4 `status: pass` is illegal unless `review_cycle: done` (Step 6 fail-closed on HEAD) or `review_cycle: in_progress:…` with a verifiable sticky lease / parent-retained ownership. After a drive-to:merge-ready / babysit / shepherd claim, the same turn MUST end in Owner Continuity Gate A/B/C (monitor+lease, parent-retained next dual-source action, or explicit BLOCKED/FAILED finish) — never silent hold. Optional machine gate: `deft verify:l4-owner --pr <N>` / `task verify:l4-owner -- --pr <N>`. Full MUST language: `skills/deft-directive-review-cycle/SKILL.md` Owner Continuity Gate.
|
|
549
549
|
|
|
550
|
+
! **Bound proof for remote artifact claims / invented-done (#3120):** Handoff evidence MUST distinguish at least three axes and a binding state:
|
|
551
|
+
|
|
552
|
+
| Axis / field | Meaning |
|
|
553
|
+
|---|---|
|
|
554
|
+
| **work** | Local changes (edits, tests, commits on the branch) |
|
|
555
|
+
| **ship** | Pushed branch / PR exists on the forge |
|
|
556
|
+
| **gate** | Checks / review verdict on the claimed HEAD |
|
|
557
|
+
| **`proof_status`** | `bound` \| `unbound` \| `n/a-no-remote-claim` |
|
|
558
|
+
|
|
559
|
+
- ! **`proof_status` enum:** `bound` (same-turn probes bind every remote claim) \| `unbound` (remote claims present without probes — illegal under `status: pass`) \| `n/a-no-remote-claim` (no PR URL / PR number / SHA / CI-green / review-score fields filled).
|
|
560
|
+
- ! **`status: pass` is forbidden** when any remote artifact is claimed (PR URL/number, commit/HEAD SHA, CI green/success, review score) unless `proof_status` is `bound` **and** each claim has a same-turn probe (`command` + short raw `snippet` from that command's stdout). Unbound remote claims → **invalid evidence (fail)**, not pass-with-notes.
|
|
561
|
+
- ! **Binding = probe-then-fill (MUST):** run `git` / forge probe first (`git rev-parse HEAD`, `gh api repos/<o>/<r>/pulls/<N>`, `task pr:watch -- <N> --one-shot`, checks API), then **copy** IDs/URLs/SHAs/scores from the probe JSON/text into the evidence block. ⊗ Fill PR/SHA/CI/review fields from recollection, narration, or prior-turn memory.
|
|
562
|
+
- ! **Fail ranking:** **invented-done** (false or unbound remote artifacts under pass) is **stricter** than **empty-done** (pass with no work/ship/gate substance and no remote claims). Empty returns are incomplete; invented complete returns are worse and MUST fail closed.
|
|
563
|
+
- ! **Legal partial:** local work `done` + ship `not_started` / `blocked` **without** PR/SHA/CI/review fields and `proof_status: n/a-no-remote-claim` (or non-pass `status: partial`) is valid — do not invent ship state.
|
|
564
|
+
- Machine check (library): `validateHandoffEvidence` in `@deftai/directive-core` `handoff-evidence` (`packages/core/src/handoff-evidence/`). Skills: build / pre-pr / review-cycle final checklist.
|
|
565
|
+
|
|
550
566
|
! **Parent tool-first after leaf completion (#2943):** When a parent / monitor receives a leaf completion event (`subagent_announce`, parent-push, or host completion notify), its **first response** MUST be a **tool-first** ground-truth batch (`gh` / `git` / worktree or file status) **or** a host **yield** (`sessions_yield` on OpenClaw, or equivalent). ⊗ Multi-sentence progress-only first response with zero tools / yield — the OpenClaw text-repetition hang class (#2943).
|
|
551
567
|
|
|
552
568
|
⊗ Treat thin DONE (no PR URL / merge evidence) as success (#2943).
|
|
553
569
|
⊗ Treat empty/unknown review-monitor settle as DONE without same-turn ground truth, or dual-spawn a second monitor while the first lease is live (#3044).
|
|
554
570
|
⊗ Emit freeform `review_cycle: started` / `pending` / `initiated` or L4 `status: pass` without `done` or verifiable `in_progress:<pr>#…` (#3090).
|
|
571
|
+
⊗ Claim `status: pass` (or equivalent process-green handoff) with PR URL / SHA / CI green / review score filled from memory without same-turn probe binding — **invented-done** (#3120).
|
|
572
|
+
⊗ Set `proof_status: n/a-no-remote-claim` while remote PR/SHA/CI/review fields are non-empty (#3120).
|
|
573
|
+
⊗ Mark ship/gate `done` or fill PR fields when only local work completed — legal partial omits remote fields (#3120).
|
|
555
574
|
|
|
556
575
|
Per-step acks during the run are noise. ONE start message, ONE final message; intermediate messages only on `BLOCKED` / `FAILED`. The final message lets the dispatcher distinguish a clean exit from a silent timeout when the lifecycle event arrives.
|
|
557
576
|
|