@deftai/directive-content 0.66.2 → 0.68.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.
@@ -1,14 +1,47 @@
1
- # Shared deft CLI resolver for .githooks/* (#2067).
1
+ # Shared deft CLI resolver for .githooks/* (#2067, #2248).
2
2
  # REPO_ROOT must be set before sourcing.
3
+ #
4
+ # Resolution order:
5
+ # 1. DEFT_HOOKS_PREFER_GLOBAL=1 forces the global `deft` (escape hatch, #2248).
6
+ # 2. Framework-source (monorepo) checkout: prefer the freshly-built LOCAL CLI
7
+ # (packages/cli/dist/bin.js) over a possibly-stale global `deft`, so a
8
+ # newly-added-and-wired verb is not unknown to the global and does not
9
+ # block commits/pushes (#2248). Detected via the built local CLI existing
10
+ # under $REPO_ROOT together with a monorepo sentinel (pnpm-workspace.yaml).
11
+ # 3. Consumer install (vendored .deft/core, no local build): resolve the
12
+ # global `deft` exactly as before -- consumers have no local CLI to prefer.
13
+ # 4. Local build present without the monorepo sentinel: fall back to it.
14
+ # 5. Nothing resolvable: fail with an install hint.
3
15
 
4
16
  run_deft() {
17
+ _deft_local="$REPO_ROOT/packages/cli/dist/bin.js"
18
+
19
+ # (1) Escape hatch: force the global even in a monorepo.
20
+ if [ "${DEFT_HOOKS_PREFER_GLOBAL:-}" = "1" ] && command -v deft >/dev/null 2>&1; then
21
+ deft "$@"
22
+ return $?
23
+ fi
24
+
25
+ # (2) Framework-source checkout: the local build is authoritative for verbs.
26
+ if [ -f "$_deft_local" ] && [ -f "$REPO_ROOT/pnpm-workspace.yaml" ]; then
27
+ node "$_deft_local" "$@"
28
+ return $?
29
+ fi
30
+
31
+ # (3) Consumer install: resolve the global `deft` exactly as today.
5
32
  if command -v deft >/dev/null 2>&1; then
6
33
  deft "$@"
7
- elif [ -f "$REPO_ROOT/packages/cli/dist/bin.js" ]; then
8
- node "$REPO_ROOT/packages/cli/dist/bin.js" "$@"
9
- else
10
- echo "deft hooks: 'deft' not found on PATH and no local CLI at packages/cli/dist/bin.js." >&2
11
- echo " Install: npm i -g @deftai/directive" >&2
12
- exit 1
34
+ return $?
35
+ fi
36
+
37
+ # (4) Local build present without the monorepo sentinel.
38
+ if [ -f "$_deft_local" ]; then
39
+ node "$_deft_local" "$@"
40
+ return $?
13
41
  fi
42
+
43
+ # (5) Nothing resolvable.
44
+ echo "deft hooks: 'deft' not found on PATH and no local CLI at packages/cli/dist/bin.js." >&2
45
+ echo " Install: npm i -g @deftai/directive" >&2
46
+ exit 1
14
47
  }
@@ -17,6 +17,8 @@ run_deft verify:branch --project-root "$REPO_ROOT" || exit $?
17
17
 
18
18
  run_deft verify:encoding --staged --project-root "$REPO_ROOT" || exit $?
19
19
 
20
+ run_deft verify:forward-coverage --staged --project-root "$REPO_ROOT" || exit $?
21
+
20
22
  if [ -d "$REPO_ROOT/xbrief" ] || [ -d "$REPO_ROOT/vbrief" ]; then
21
23
  run_deft verify:vbrief-conformance --staged --project-root "$REPO_ROOT" || exit $?
22
24
  fi
package/Taskfile.yml CHANGED
@@ -345,6 +345,7 @@ tasks:
345
345
  - verify:stubs
346
346
  - verify:links
347
347
  - verify:rule-ownership
348
+ - verify:biome-config
348
349
  - verify:content-manifest
349
350
  - verify:contract-drift
350
351
  - verify:cursor-tier1
@@ -352,6 +353,7 @@ tasks:
352
353
  - verify:bridge-drift
353
354
  - verify:branch
354
355
  - verify:encoding
356
+ - verify:forward-coverage
355
357
  - verify:vbrief-conformance
356
358
  - verify:destructive-gh-verbs
357
359
  - verify:scm-boundary
@@ -360,6 +362,7 @@ tasks:
360
362
  - verify:cache-fresh
361
363
  - verify:pack-drift
362
364
  - verify-wip-cap-framework-self-check
365
+ - verify:agents-md-budget
363
366
  - vbrief:validate
364
367
  - codebase:validate-structure
365
368
  - verify:codebase-map-fresh
@@ -458,12 +461,14 @@ tasks:
458
461
  cmds:
459
462
  - task: install:uninstall
460
463
  # User-facing upgrade entrypoint (#1061). Aliases the install:upgrade
461
- # wrapper that delegates to the native deft-ts install-upgrade handler. Cited by the doctor's
462
- # failure prose and docs/install-manifest.md as the canonical
463
- # post-drift repair entrypoint for the AGENTS.md / manifest /
464
- # .deft-version triple.
464
+ # wrapper. As of #2064 the native deft-ts install-upgrade handler is a thin
465
+ # redirect onto `directive update` -- the single canonical upgrade verb that
466
+ # file-swaps the vendored .deft/core payload, rewrites the install manifest,
467
+ # and regenerates .deft-version. Prefer `deft update` directly; this alias is
468
+ # retained for compatibility. Cited by the doctor's failure prose and
469
+ # docs/install-manifest.md as the post-drift repair entrypoint.
465
470
  upgrade:
466
- desc: "Upgrade deft framework -- refresh AGENTS.md + write install manifest + regenerate .deft-version (alias for install:upgrade, #1061)"
471
+ desc: "Upgrade deft framework -- redirects to `deft update` (the canonical verb: refresh payload + AGENTS.md + install manifest + .deft-version; alias for install:upgrade, #1061/#2064)"
467
472
  cmds:
468
473
  - task: install:upgrade
469
474
 
@@ -479,7 +484,7 @@ tasks:
479
484
  # in ``tasks/framework.yml`` now prints a redaction notice pointing
480
485
  # the operator at this surface.
481
486
  doctor:
482
- desc: "Canonical doctor surface (#1272) -- task doctor [-- --session | --fix | --json | --quiet]. Uses vendored bin.js in source checkouts or global deft on npm consumer deposits (#2022 Phase 3)."
487
+ desc: "Canonical doctor surface (#1272) -- task doctor [-- --session | --fix | --json | --quiet | --network]. Uses vendored bin.js in source checkouts or global deft on npm consumer deposits (#2022 Phase 3). --network is required to run the payload-staleness check (git remote, then npm registry fallback); it is offline (skipped) by default and discloses the tool + registry class before contacting either (#2182)."
483
488
  dir: '{{.USER_WORKING_DIR}}'
484
489
  cmds:
485
490
  - task: engine:invoke
package/UPGRADING.md CHANGED
@@ -30,6 +30,8 @@ From v0.55.1 onwards `@deftai/directive` is published on npm. The canonical cons
30
30
 
31
31
  This re-copies the vendored `.deft/core/` payload and refreshes project-root `.githooks/` (#2049).
32
32
 
33
+ > **`deft update` is the single canonical upgrade verb (#2064).** The older `deft install-upgrade` (and its `task upgrade` maintainer alias) now print a one-line notice and delegate to this exact `deft update` path — they no longer have their own semantics. Previously `install-upgrade` only rewrote the marker/manifest without swapping the payload, so on a stale deposit it reported a false "Project already at X. Nothing to do." Use `deft update`; there is nothing `install-upgrade` does that `deft update` does not.
34
+
33
35
  3. **Stamp npm provenance (one-time, idempotent):**
34
36
 
35
37
  ```bash
@@ -56,6 +58,26 @@ deft migrate:xbrief
56
58
 
57
59
  (or `task migrate:xbrief` from a maintainer checkout). The command requires a clean working tree unless you pass `--force`. Legacy `vbrief/` paths and `x-vbrief/` tokens remain **read-accepted** until this migration runs; `deft update` may signpost the same guidance on non-patch upgrades.
58
60
 
61
+ Post-migration behavior check (#2149): on xbrief-only projects (`vbrief/` removed), `task issue:ingest -- <N>` now emits `xbrief/proposed/*.xbrief.json` with `xBRIEFInfo.version` from `xbrief/PROJECT-DEFINITION.xbrief.json` (fallback `0.8`), while legacy `vbrief/` projects keep `.vbrief.json` + `vBRIEFInfo.version: "0.6"` until migrated. `task project:render` / `project-render` also stays on `xbrief/PROJECT-DEFINITION.xbrief.json` and no longer recreates `vbrief/` in migrated trees.
62
+
63
+ ### AGENTS.md: managed vs unmanaged header (#2154)
64
+
65
+ `migrate:xbrief` touches your `AGENTS.md` in two distinct regions:
66
+
67
+ - **Managed section** (between the `<!-- deft:managed-section ... -->` / `<!-- /deft:managed-section -->` markers): regenerated wholesale by `agents:refresh`, so it always reflects the current framework layout. This region is rendered from the framework template — do not hand-edit it.
68
+ - **Unmanaged header/tail** (everything outside those markers — your project-specific `Session orientation`, `Lifecycle` examples, `Local dev` notes): preserved verbatim across upgrades so your consumer notes survive. Because it is preserved, a rename migration would otherwise leave stale `vbrief/` path literals here. `migrate:xbrief` now applies a **bounded, idempotent** rewrite over the unmanaged region only, replacing the known crossover tokens (`vbrief/` → `xbrief/`, `*.vbrief.json` → `*.xbrief.json`, `vbrief:preflight` → `xbrief:preflight`) while leaving freeform prose untouched. It prints a summary of the replacements.
69
+
70
+ If you upgraded before this fix landed and your header still points at `vbrief/`, `deft doctor` now emits an `AGENTS.md header drift:` signpost. Re-run `deft migrate:xbrief` (idempotent) to patch the header, or hand-edit the offending path literals.
71
+
72
+ **Option A (canonical, #2065):** new installs scaffold a **bounded** unmanaged header only — a project one-liner plus a **Session orientation** pointer at the canonical sources below. Do **not** add freeform `Status`, `Next:`, or `Known Issues` blocks; they are retired because the framework preserves the header verbatim while `deft doctor` only checks the managed section (#794, #1308). Session orientation comes from:
73
+
74
+ - `xbrief/PROJECT-DEFINITION.xbrief.json` (project identity)
75
+ - `xbrief/` lifecycle folders (scoped work)
76
+ - `deft triage:queue` / `deft triage:welcome` (ranked queue)
77
+ - GitHub issues (tracked bugs)
78
+
79
+ If your header still carries `Status` / `Known Issues` from an older handoff, replace them with the Session orientation pointer (reference implementation: [deftai/cartograph#75](https://github.com/deftai/cartograph/pull/75)). Ephemeral shell quirks MAY stay under a `Local dev` heading only.
80
+
59
81
  ## Public contract layer — `@deftai/directive-types` (#1799)
60
82
 
61
83
  Downstream TypeScript projects can import the canonical xBRIEF/policy contract instead of hand-mirroring JSON shapes:
@@ -348,6 +370,8 @@ The transition is one-way -- v0.28 has no shim back to the bare-only marker. To
348
370
  <!-- 1061: AGENTS.md drift repair via task upgrade BEGIN -->
349
371
  ## From drifted AGENTS.md -> current install (`task upgrade` repair path, #1061)
350
372
 
373
+ > **Consolidation note (#2064):** `deft install-upgrade` and its `task upgrade` maintainer alias now delegate to the single canonical `deft update` path (see [Canonical upgrade — npm](#canonical-upgrade--npm-v0551)). The legacy `.deft/VERSION` retirement described below (backed up as `.deft/VERSION.premigrate`) is folded into `deft update`, so the drift-repair steps here still apply verbatim — the doctor now names `deft update` as the fix.
374
+
351
375
  - **Applies when:** `task framework:doctor` reports drift on any of the four checks (`quick-start-resolves`, `skill-paths-resolve`, `manifest-agreement`, `install-path-consistency`). Common causes: a canonical-reinstall over a pre-v0.27 AGENTS.md (the #1060 recurrence pattern), a marker-version mismatch where AGENTS.md still carries the v1 / v2 managed-section sentinel after a framework bump, or an install-path-consistency mismatch detected via the new `install_root` manifest field that #1062 added to `<install>/VERSION` (the doctor reads the manifest's `install_root` first, then falls back to the AGENTS.md install-root parse, and FAILs when the resolved directory does not exist on disk).
352
376
  - **Safe to auto-run:** Yes. `task upgrade` is the canonical user-facing entrypoint added in #1061; it wraps `run upgrade` and is idempotent on re-run (a second invocation against a current manifest + AGENTS.md is a no-op). The wrapper: (1) re-pulls the framework version marker by writing / refreshing `.deft-version`; (2) re-writes the canonical install manifest at `<install>/VERSION` (`ref` / `sha` / `tag` / `install_root` / `fetched_at` / `fetched_by`); (3) refreshes AGENTS.md to the current marker version (v3 sentinel with sha / refreshed / session attributes) via `cmd_agents_refresh`. Pre-v0.27 AGENTS.md files (no managed-section markers, or v1 markers) are migrated in place: content above and below the bracketed block is preserved verbatim, only the framework-owned managed section is rewritten.
353
377
  - **Restart required:** Recommended. The agent's current session may still hold stale AGENTS.md / skill references from the pre-upgrade marker. After `task upgrade` completes, start a new agent session so the refreshed prose loads from a clean context.
@@ -0,0 +1,44 @@
1
+ # Authoring agent docs (AGENTS.md) for a project
2
+
3
+ Guidance for structuring the AGENTS.md (and its reference docs) of a project directive creates or maintains. Unlike most style advice, the patterns here are **empirically measured**, not opinion: Augment Code's April 2026 AuggieBench study ran real PRs with and without each pattern and scored the agent's output against the human-reviewed golden PR. Full write-up: [good-agents-md.md](./good-agents-md.md).
4
+
5
+ Legend (RFC2119): `!`=MUST, `~`=SHOULD, `≉`=SHOULD NOT, `⊗`=MUST NOT, `?`=MAY.
6
+
7
+ > The headline finding: a good AGENTS.md gave the agent a quality jump equivalent to a model upgrade; a bad one made output **worse than no AGENTS.md at all**. The same file boosted `best_practices` +25% on a routine bug fix and dropped `completeness` -30% on a complex feature in the same module. Structure is the difference.
8
+
9
+ ## The pattern (what the study measured)
10
+
11
+ | Pattern | Measured effect |
12
+ |---|---|
13
+ | 100–150 line main file + a handful of focused reference files | Top performers; **10–15%** improvement across all metrics in mid-size modules. Gains **reverse** once the main file grows past ~150 lines. |
14
+ | Numbered procedural workflows for multi-step tasks | Missing-wiring PRs **40% → 10%**; correctness **+25%**, completeness **+20%**. |
15
+ | Decision tables for common ambiguities (2–3 reasonable options) | **+25%** best-practices adherence — resolves the choice before the agent writes a line. |
16
+ | 3–10 line snippets from the **real** codebase | Improved reuse and pattern adherence. More than a few, and the agent pattern-matches on the wrong thing. |
17
+ | Paired don't/do rules | Warning-only docs underperform; **15+ unpaired don'ts** measurably cause overexploration. |
18
+ | Module-level files over a root cross-cutting file | Root-level cross-cutting AGENTS.md underperforms module-scoped files. |
19
+
20
+ ## How to structure a project's AGENTS.md
21
+
22
+ 1. ! Keep the always-loaded AGENTS.md to **~100–150 lines**. It is a map (what exists, where to look, the few load-bearing rules), not a manual.
23
+ 2. ! Push detail into **focused reference files** the agent loads on demand, each with a clear "load when…" scope. See the reference-chain contract below.
24
+ 3. ~ Express multi-step tasks (deploy an integration, add a migration, wire a new endpoint) as **numbered workflows**, not prose. Keep branching cases in reference files.
25
+ 4. ~ For each recurring "which of these two approaches?" ambiguity, add a **decision table** that forces the choice up front.
26
+ 5. ~ Include a few **short, real** code snippets (3–10 lines) for the patterns you most want reused. Do not paste large or duplicative examples.
27
+ 6. ! Write rules as **paired don't/do**, not lone warnings — an unpaired "don't" leaves the agent to guess the "do", and a pile of them triggers overexploration.
28
+ 7. ~ Prefer **module-level** agent docs (scoped to the package/app the agent is working in) over one root file that tries to cover everything.
29
+
30
+ ## The reference-chain contract
31
+
32
+ The discovery-rate principle that governs *what to reference* is named in `REFERENCES.md` ("The reference-chain contract", #644) — read it there rather than duplicating it here. In one line: **if a rule must be followed, it must be reachable in the reference chain; orphan docs (<10% discovery) are effectively invisible, and reachable-but-unreferenced docs are still found and still cost context.**
33
+
34
+ ## The overexploration trap (measured failure modes, not style)
35
+
36
+ These are the specific blocks the study measured *hurting* agent quality — treat them as defects, not taste:
37
+
38
+ - ⊗ Do **not** add an "architecture overview" / broad-context section to an always-loaded agent file. On complex tasks it pulls the agent into the reference section to verify its approach against every guideline, producing unnecessary abstractions and incomplete solutions (the measured -30% completeness case).
39
+ - ⊗ Do **not** accumulate 15+ unpaired warnings. Past that threshold the agent over-explores instead of acting.
40
+ - ≉ Avoid stacking dozens of domain-specific gotchas. Domain rules help when specific and enforceable; they stop helping when piled up. Prefer a deterministic gate over prose where one exists (the gate is platform-correct by construction and travels with the repo).
41
+
42
+ ## Relationship to directive's own dogfooding
43
+
44
+ Directive holds its own AGENTS.md to this bar via the `verify:agents-md-budget` ratchet (#645) and the consumer-side advisory signal (`agentsMdAdvisory`, #2155). The doc-sprawl awareness step in the `deft-directive-sync` skill (#647) surfaces reachable-doc-volume drift before it silently degrades agent quality. This doc is the "how to structure it well" companion to those "keep it from bloating" guards.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive-content",
3
- "version": "0.66.2",
3
+ "version": "0.68.0",
4
4
  "description": "Shippable Directive framework content in the consumer .deft/core/ layout (C1 flatten), plus the engine surfaces (.githooks/, Taskfile.yml, tasks/) the deposit wires. Python-free per #2022 Phase 3. Refs #11, #1669, #1967.",
5
5
  "type": "module",
6
6
  "files": [
@@ -548,6 +548,23 @@
548
548
  ],
549
549
  "source": "Issue #696. Observed 2026-04-27: a returning session emitted the alignment confirmation, ran `Test-Path` on USER.md (-> True), declared all config present, and addressed the user by a name injected via a Warp Drive notebook instead of the name in USER.md. USER.md was never read; its `Personal (always wins)` precedence rule was never applied because that rule lives inside the file the agent skipped.",
550
550
  "body": "**Source:** Issue #696. Observed 2026-04-27: a returning session emitted the alignment confirmation, ran `Test-Path` on USER.md (-> True), declared all config present, and addressed the user by a name injected via a Warp Drive notebook instead of the name in USER.md. USER.md was never read; its `Personal (always wins)` precedence rule was never applied because that rule lives inside the file the agent skipped.\n\n**Key insight:** A presence / existence check on USER.md is NOT a content read. An alignment confirmation that can be emitted without reading USER.md leaves a substitution gap: when external context (Warp Drive notebooks, MCP server outputs, prompt-injected preferences) defines the same fields as USER.md, the agent silently adopts the external value. External context sits OUTSIDE deft's precedence hierarchy -- USER.md `Personal (always wins)` must win, but only a real content read can apply that rule.\n\n**Rule:** The alignment confirmation MUST include data drawn from USER.md content -- specifically the addressing-name -- so the read is unfakeable (`Deft Directive active -- AGENTS.md loaded. Addressing you as: {Name}.`). Returning Sessions is promoted from unmarked prose to an enforced `!`/`\u2297` rule with an ordered read list (main.md -> USER.md -> PROJECT-DEFINITION) and an inline external-context precedence rule. A `Test-Path` substitution for a content read is an explicit anti-pattern.\n\n**Canonical encoding (strongest-applicable layer):** the rule body lives in `AGENTS.md` + `templates/agents-entry.md` (`## Returning Sessions` + `### Deft Alignment Confirmation`), propagated to the consumer managed-section via `task agents:refresh` (#1309). Deterministic shape-coverage: `tests/content/test_agents_md.py` (must-marker, Test-Path anti-pattern, name-echo, external-context precedence wording). The behavioral eval that actually catches the substitution failure class (conflicting USER.md vs external-context names) is deferred to its own issue (Fix D); the greet-skill structural cleanup is Fix E.\n\n**Cross-references:** `AGENTS.md` / `templates/agents-entry.md` `## Returning Sessions` + `### Deft Alignment Confirmation` (rule body); `tests/content/test_agents_md.py` (shape coverage); #163 (CLI gate parity, complementary); #258 (Warp Drive inventory, documentation half of the same root cause); #78 (adjacent bootstrap-update offer)."
551
+ },
552
+ {
553
+ "id": "prefiling-master-diff-check-2026-07",
554
+ "title": "Pre-filing master-diff check before proposing to add a file (2026-07)",
555
+ "date": "2026-07",
556
+ "issue_refs": [
557
+ "#1102",
558
+ "#1099",
559
+ "#1100",
560
+ "#1070"
561
+ ],
562
+ "tags": [
563
+ "scm",
564
+ "skills"
565
+ ],
566
+ "source": "Issue #1102. On 2026-05-12 a refinement session (PR #1098) filed #1099 proposing to add .github/dependabot.yml without checking master -- the file already existed (landed via #1070 / v0.29.1). #1099 closed as a stale duplicate the same day; #1100 re-filed as the additive-delta scope.",
567
+ "body": "**Source:** Issue #1102. On 2026-05-12 a refinement session (PR #1098) filed #1099 proposing to add `.github/dependabot.yml` without checking master -- the file already existed (landed via #1070 / v0.29.1). #1099 closed as a stale duplicate the same day; #1100 was re-filed as the additive-delta scope.\n\n**Key insight:** A one-second `git ls-tree origin/master -- <path>` (or `gh api repos/{owner}/{repo}/contents/{path}` without a clone) existence check before filing an add-a-file issue prevents this whole close-and-refile class. If the path already exists, the issue must be scoped to the DELTA vs the on-master state, not the original 'deposit this file' framing.\n\n**Canonical encoding (strongest-applicable layer):** the `!` MUST rule + `\u2297` anti-pattern live in the canonical issue-filing skill `skills/deft-directive-gh-slice/SKILL.md` (Step 5 + Anti-Patterns), cross-referenced from `skills/deft-directive-refinement/SKILL.md` Phase 1. Deterministic shape-coverage: `packages/core/src/content-contracts/skills/gh_slice_prefiling_master_diff.test.ts`.\n\n**Cross-references:** #1070 (`.github/dependabot.yml` originally landed), #1099 (stale-duplicate filing, closed), #1100 (corrected additive-scope refile), PR #1098 (refinement session that surfaced the pattern)."
551
568
  }
552
569
  ]
553
570
  }