@deftai/directive-content 0.55.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/SKILL.md +6 -0
- package/.agents/skills/deft-directive-article-review/SKILL.md +11 -0
- package/.agents/skills/deft-directive-build/SKILL.md +10 -0
- package/.agents/skills/deft-directive-cost/SKILL.md +12 -0
- package/.agents/skills/deft-directive-debug/SKILL.md +13 -0
- package/.agents/skills/deft-directive-gh-arch/SKILL.md +11 -0
- package/.agents/skills/deft-directive-gh-slice/SKILL.md +10 -0
- package/.agents/skills/deft-directive-glossary/SKILL.md +10 -0
- package/.agents/skills/deft-directive-interview/SKILL.md +9 -0
- package/.agents/skills/deft-directive-pre-pr/SKILL.md +9 -0
- package/.agents/skills/deft-directive-refinement/SKILL.md +10 -0
- package/.agents/skills/deft-directive-release/SKILL.md +12 -0
- package/.agents/skills/deft-directive-review-cycle/SKILL.md +10 -0
- package/.agents/skills/deft-directive-setup/SKILL.md +10 -0
- package/.agents/skills/deft-directive-swarm/SKILL.md +10 -0
- package/.agents/skills/deft-directive-sync/SKILL.md +9 -0
- package/.agents/skills/deft-directive-triage/SKILL.md +9 -0
- package/.agents/skills/deft-directive-write-skill/SKILL.md +9 -0
- package/LICENSE.md +22 -0
- package/QUICK-START.md +167 -0
- package/UPGRADING.md +517 -0
- package/coding/build-output.md +28 -0
- package/coding/coding.md +235 -0
- package/coding/debugging.md +110 -0
- package/coding/holzmann.md +96 -0
- package/coding/hygiene.md +127 -0
- package/coding/security.md +158 -0
- package/coding/testing.md +162 -0
- package/coding/toolchain.md +44 -0
- package/commands.md +300 -0
- package/context/context.md +57 -0
- package/context/deterministic-split.md +67 -0
- package/context/examples.md +26 -0
- package/context/fractal-summaries.md +69 -0
- package/context/long-horizon.md +46 -0
- package/context/spec-deltas.md +177 -0
- package/context/tool-design.md +34 -0
- package/context/working-memory.md +62 -0
- package/contracts/boundary-maps.md +65 -0
- package/contracts/deterministic-questions.md +59 -0
- package/contracts/hierarchy.md +77 -0
- package/conventions/content-manifest.json +399 -0
- package/conventions/machine-generated-banner.md +130 -0
- package/conventions/references.md +120 -0
- package/conventions/rule-ownership.json +382 -0
- package/conventions/task-caching.md +43 -0
- package/conventions/vbrief-filenames.md +70 -0
- package/deployments/README.md +37 -0
- package/deployments/agentuity/README.md +138 -0
- package/deployments/agentuity/via-cli.md +380 -0
- package/deployments/agentuity/via-cloud.md +425 -0
- package/deployments/agentuity/via-github-actions.md +664 -0
- package/deployments/agentuity/via-gravity-network.md +606 -0
- package/deployments/agentuity/via-vpc.md +607 -0
- package/deployments/aws/README.md +38 -0
- package/deployments/aws/via-app-runner.md +612 -0
- package/deployments/aws/via-ecs-fargate.md +561 -0
- package/deployments/aws/via-elastic-beanstalk.md +628 -0
- package/deployments/aws/via-lambda.md +649 -0
- package/deployments/azure/README.md +37 -0
- package/deployments/azure/via-aks.md +390 -0
- package/deployments/azure/via-app-service.md +564 -0
- package/deployments/azure/via-container-apps.md +599 -0
- package/deployments/azure/via-functions.md +552 -0
- package/deployments/cloud-gov/README.md +63 -0
- package/deployments/cloud-gov/agents/compliance-docs.md +154 -0
- package/deployments/cloud-gov/agents.md +39 -0
- package/deployments/cloud-gov/cicd.md +64 -0
- package/deployments/cloud-gov/deployment.md +150 -0
- package/deployments/cloud-gov/logging.md +43 -0
- package/deployments/cloud-gov/manifest.md +121 -0
- package/deployments/cloud-gov/overview.md +58 -0
- package/deployments/cloud-gov/security.md +46 -0
- package/deployments/cloud-gov/services.md +72 -0
- package/deployments/cloud-gov/upstream/README.md +18 -0
- package/deployments/cloudflare/README.md +33 -0
- package/deployments/cloudflare/via-dashboard.md +83 -0
- package/deployments/cloudflare/via-git.md +90 -0
- package/deployments/cloudflare/via-github-actions.md +185 -0
- package/deployments/cloudflare/via-terraform.md +157 -0
- package/deployments/cloudflare/via-wrangler.md +165 -0
- package/deployments/fly-io/README.md +37 -0
- package/deployments/fly-io/via-dockerfile.md +648 -0
- package/deployments/fly-io/via-flyctl.md +653 -0
- package/deployments/fly-io/via-github-actions.md +695 -0
- package/deployments/fly-io/via-multi-region.md +598 -0
- package/deployments/google/README.md +34 -0
- package/deployments/google/via-app-engine.md +42 -0
- package/deployments/google/via-cloud-functions.md +23 -0
- package/deployments/google/via-cloud-run.md +330 -0
- package/deployments/google/via-gke.md +23 -0
- package/deployments/netlify/README.md +99 -0
- package/deployments/netlify/via-cli.md +17 -0
- package/deployments/netlify/via-functions.md +19 -0
- package/deployments/netlify/via-git.md +25 -0
- package/deployments/vercel/README.md +90 -0
- package/deployments/vercel/via-api.md +16 -0
- package/deployments/vercel/via-cli.md +17 -0
- package/deployments/vercel/via-git.md +24 -0
- package/docs/BROWNFIELD.md +179 -0
- package/docs/getting-started.md +137 -0
- package/docs/good-agents-md.md +137 -0
- package/events/README.md +89 -0
- package/events/event-record.schema.json +26 -0
- package/events/registry.json +166 -0
- package/events/registry.schema.json +71 -0
- package/glossary.md +145 -0
- package/incidents/README.md +81 -0
- package/incidents/_template.md +38 -0
- package/interfaces/cli.md +104 -0
- package/interfaces/rest.md +212 -0
- package/interfaces/tui.md +242 -0
- package/interfaces/web.md +123 -0
- package/languages/6502-DASM.md +132 -0
- package/languages/c.md +235 -0
- package/languages/commands.md +23 -0
- package/languages/cpp.md +132 -0
- package/languages/csharp.md +259 -0
- package/languages/dart.md +183 -0
- package/languages/delphi.md +218 -0
- package/languages/elixir.md +208 -0
- package/languages/go.md +78 -0
- package/languages/java.md +278 -0
- package/languages/javascript.md +163 -0
- package/languages/julia.md +175 -0
- package/languages/kotlin.md +193 -0
- package/languages/markdown.md +168 -0
- package/languages/mermaid.md +146 -0
- package/languages/officejs.md +392 -0
- package/languages/python.md +209 -0
- package/languages/r.md +163 -0
- package/languages/rust.md +216 -0
- package/languages/sql.md +216 -0
- package/languages/swift.md +153 -0
- package/languages/typescript.md +132 -0
- package/languages/vba.md +279 -0
- package/languages/vhdl.md +180 -0
- package/languages/visual-basic.md +151 -0
- package/languages/zig.md +196 -0
- package/meta/SOUL.md +27 -0
- package/meta/code-field.md +44 -0
- package/meta/morals.md +40 -0
- package/meta/philosophy.md +39 -0
- package/meta/project.md +49 -0
- package/meta/ralph.md +223 -0
- package/meta/security.md +80 -0
- package/meta/versioning.md +326 -0
- package/package.json +22 -0
- package/packs/lessons/lessons-pack-0.1.json +553 -0
- package/packs/patterns/patterns-pack-0.1.json +57 -0
- package/packs/rules/rules-pack-0.1.json +4767 -0
- package/packs/skills/skills-pack-0.1.json +262 -0
- package/packs/strategies/strategies-pack-0.1.json +167 -0
- package/packs/swarm-spec/swarm-spec-pack-0.1.json +17 -0
- package/patterns/executor-layer-credentials.md +227 -0
- package/patterns/llm-app.md +156 -0
- package/patterns/multi-agent.md +278 -0
- package/patterns/prompt-assembly-layer-ordering.md +154 -0
- package/patterns/role-as-overlay.md +179 -0
- package/platforms/2600.md +137 -0
- package/platforms/unity.md +329 -0
- package/references/composer-skill-porting.md +152 -0
- package/references/cost-models.md +163 -0
- package/references/ip-risk.md +246 -0
- package/references/plain-english-ux.md +275 -0
- package/resilience/context-pruning.md +67 -0
- package/resilience/continue-here.md +62 -0
- package/scm/changelog.md +276 -0
- package/scm/git.md +139 -0
- package/scm/github.md +265 -0
- package/secrets/.gitkeep +0 -0
- package/skills/deft-build/SKILL.md +20 -0
- package/skills/deft-directive-article-review/SKILL.md +156 -0
- package/skills/deft-directive-build/SKILL.md +302 -0
- package/skills/deft-directive-cost/SKILL.md +201 -0
- package/skills/deft-directive-debug/SKILL.md +140 -0
- package/skills/deft-directive-decompose/SKILL.md +96 -0
- package/skills/deft-directive-gh-arch/SKILL.md +160 -0
- package/skills/deft-directive-gh-slice/SKILL.md +199 -0
- package/skills/deft-directive-glossary/SKILL.md +118 -0
- package/skills/deft-directive-interview/SKILL.md +528 -0
- package/skills/deft-directive-pre-pr/SKILL.md +131 -0
- package/skills/deft-directive-probe/SKILL.md +127 -0
- package/skills/deft-directive-refinement/SKILL.md +403 -0
- package/skills/deft-directive-release/SKILL.md +266 -0
- package/skills/deft-directive-review-cycle/SKILL.md +401 -0
- package/skills/deft-directive-setup/SKILL.md +717 -0
- package/skills/deft-directive-swarm/SKILL.md +989 -0
- package/skills/deft-directive-sync/SKILL.md +288 -0
- package/skills/deft-directive-triage/SKILL.md +137 -0
- package/skills/deft-directive-write-skill/SKILL.md +169 -0
- package/skills/deft-interview/SKILL.md +16 -0
- package/skills/deft-pre-pr/SKILL.md +16 -0
- package/skills/deft-review-cycle/SKILL.md +16 -0
- package/skills/deft-roadmap-refresh/SKILL.md +16 -0
- package/skills/deft-setup/SKILL.md +20 -0
- package/skills/deft-swarm/SKILL.md +16 -0
- package/skills/deft-sync/SKILL.md +16 -0
- package/strategies/README.md +83 -0
- package/strategies/artifact-guards.md +85 -0
- package/strategies/bdd.md +115 -0
- package/strategies/brownfield.md +7 -0
- package/strategies/discuss.md +129 -0
- package/strategies/emit-hints.md +69 -0
- package/strategies/enterprise.md +193 -0
- package/strategies/interview.md +551 -0
- package/strategies/map.md +179 -0
- package/strategies/probe.md +151 -0
- package/strategies/rapid.md +155 -0
- package/strategies/research.md +155 -0
- package/strategies/roadmap.md +9 -0
- package/strategies/speckit.md +437 -0
- package/strategies/v0-20-contract.md +134 -0
- package/strategies/yolo.md +169 -0
- package/swarm/swarm.md +300 -0
- package/templates/COST-ESTIMATE.md +114 -0
- package/templates/PULL_REQUEST_TEMPLATE.md +35 -0
- package/templates/agent-prompt-preamble.md +409 -0
- package/templates/agents-entry.md +211 -0
- package/templates/agents-entry.placeholders.md +75 -0
- package/templates/embed.go +20 -0
- package/templates/embed_test.go +36 -0
- package/templates/make-spec-example.md +9 -0
- package/templates/make-spec.md +246 -0
- package/templates/project.md.template +52 -0
- package/templates/specification.md +1 -0
- package/templates/swarm-greptile-poller-prompt.md +556 -0
- package/templates/user.md.template +31 -0
- package/tools/RWLDL.md +80 -0
- package/tools/greptile.md +141 -0
- package/tools/installer.md +23 -0
- package/tools/taskfile-migration.md +32 -0
- package/tools/taskfile.md +185 -0
- package/tools/telemetry.md +285 -0
- package/vbrief/schemas/cache-meta.schema.json +137 -0
- package/vbrief/schemas/candidates.schema.json +130 -0
- package/vbrief/schemas/codebase-map.schema.json +213 -0
- package/vbrief/schemas/lessons-pack.schema.json +134 -0
- package/vbrief/schemas/patterns-pack.schema.json +84 -0
- package/vbrief/schemas/rules-pack.schema.json +105 -0
- package/vbrief/schemas/skills-pack.schema.json +94 -0
- package/vbrief/schemas/slices.schema.json +87 -0
- package/vbrief/schemas/strategies-pack.schema.json +89 -0
- package/vbrief/schemas/swarm-spec-pack.schema.json +84 -0
- package/vbrief/schemas/vbrief-core.schema.json +1022 -0
- package/vbrief/vbrief.md +684 -0
- package/verification/integration.md +76 -0
- package/verification/plan-checking.md +85 -0
- package/verification/uat.md +60 -0
- package/verification/verification.md +117 -0
package/UPGRADING.md
ADDED
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
# Upgrading Deft
|
|
2
|
+
|
|
3
|
+
Version-by-version upgrade guide. Newest versions are at the top.
|
|
4
|
+
|
|
5
|
+
> **Agents:** ! If you are reading this because a user updated the framework, have them start a **new agent session** after you finish the upgrade. Your current session may still hold stale AGENTS.md / skill references from the previous version.
|
|
6
|
+
|
|
7
|
+
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Big-jump triage — multi-version upgrades (start here)
|
|
12
|
+
|
|
13
|
+
> **Multi-version jump?** Start here. This guide is ordered newest-first, so a consumer jumping several minor versions otherwise has to read every section to infer which ones apply and in what order. This entry point maps **version-range buckets** to the sections that apply and the **apply-order** to run them in.
|
|
14
|
+
|
|
15
|
+
**How to use this triage:**
|
|
16
|
+
|
|
17
|
+
1. Find the bucket for the version you are upgrading **from** (your current `.deft-version`, or the `tag` field in `<install>/VERSION`).
|
|
18
|
+
2. Apply the listed transitions in **apply-order: oldest applicable first**, working forward to the newest. Because the sections in this file are ordered newest-first, that means working **bottom-up** through the file.
|
|
19
|
+
3. Each bucket is flagged **auto-handled** (the canonical installer / `task doctor` / `task upgrade` does it for you) or **manual** (you run a migration / relocate / cache step yourself).
|
|
20
|
+
|
|
21
|
+
**Version-range buckets (apply-order, oldest applicable first):**
|
|
22
|
+
|
|
23
|
+
- **From pre-v0.20 (very old) — manual.** Run the pre-cutover migration, then refresh AGENTS.md: [From any pre-v0.20 version → v0.20.0](#from-any-pre-v020-version--v0200) and [From pre-#768 AGENTS.md → managed-section AGENTS.md](#from-pre-768-agentsmd--managed-section-agentsmd). Agents: when the project shows BOTH a stale AGENTS.md and pre-cutover artifacts, follow [QUICK-START.md Case G+H](./QUICK-START.md#case-gh--combined-stale-agentsmd--pre-cutover-migration-big-jump-one-session) to complete both in one session instead of two.
|
|
24
|
+
- **From v0.20–v0.24 — auto-handled (opt-in).** Triage v1 is purely additive; nothing breaks if you skip it: [Migration to triage v1](#migration-to-triage-v1).
|
|
25
|
+
- **From v0.25.x — manual (breaking).** The deft-cache on-disk layout changed: [From v0.25.x → v0.26.0](#from-v025x--v0260-deft-cache-unified-layer-breaking).
|
|
26
|
+
- **From v0.26.x — auto-handled (interactive).** Run the triage adoption ritual: [From v0.26.x → v0.27](#from-v026x---v027-triage-adoption-via-task-triagewelcome).
|
|
27
|
+
- **From v0.27.x — mostly auto-handled.** Pick up the install manifest and the `deft/` → `.deft/core/` layout: [From v0.27.x → v0.28](#from-v027x---v028-canonical-install-manifest-at-installversion), [From deft/ → .deft/core/](#from-deft---deftcore), and [From drifted AGENTS.md → current install](#from-drifted-agentsmd---current-install-task-upgrade-repair-path-1061).
|
|
28
|
+
- **From v0.28–v0.36 (and the final hop to current) — auto-handled.** The canonical installer + doctor handoff is the single supported path: [Canonical installer + doctor handoff](#canonical-installer--doctor-handoff-v037--epic-56-1339-1340-1409).
|
|
29
|
+
|
|
30
|
+
**Final step for every bucket.** Finish on the canonical headless upgrade command, then let the doctor confirm you are current:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
deft-install --yes --upgrade --repo-root . --json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Then run `task doctor` (or `run doctor`): it reads `<install>/VERSION`, compares against the remote ref, and tells you whether any further hop is still due. See [Canonical installer + doctor handoff](#canonical-installer--doctor-handoff-v037--epic-56-1339-1340-1409) for the full handoff contract.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Canonical installer + doctor handoff (v0.37+ / Epic-5+6 #1339 #1340, #1409)
|
|
41
|
+
|
|
42
|
+
**The single supported path for humans and agents:**
|
|
43
|
+
|
|
44
|
+
1. Download and run the platform-specific installer binary from GitHub Releases (or the webinstaller).
|
|
45
|
+
2. The installer writes the payload + manifest + AGENTS.md + skills, then **deterministically calls `scripts/doctor.py --session --json`** at the end.
|
|
46
|
+
3. Doctor (now the single owner of all health/install-integrity/staleness logic) reads the `<install>/VERSION` manifest and, when the recorded sha lags the remote ref, emits a **clear recommendation** to run the canonical headless upgrader: `deft-install --yes --upgrade --repo-root . --json`.
|
|
47
|
+
4. On subsequent sessions `task doctor` / `run doctor` (thin shims to the canonical `scripts/doctor.py`) continue to surface the same guidance.
|
|
48
|
+
|
|
49
|
+
### Canonical headless upgrade command (consumers + CI/agents) (#1409)
|
|
50
|
+
|
|
51
|
+
! The canonical, one-command payload refresh for an **existing** install is:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
deft-install --yes --upgrade --repo-root . --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- `--yes` / `--non-interactive` skips all prompts (ideal for CI / agents).
|
|
58
|
+
- `--upgrade` forces the update path even when the framework dir already exists.
|
|
59
|
+
- `--repo-root .` targets the current project (or pass an explicit path).
|
|
60
|
+
- `--json` emits a single machine-readable result object on stdout; **drop `--json` for human-readable output**.
|
|
61
|
+
|
|
62
|
+
Run it from your project root. Unlike the legacy metadata-only verbs, this command actually **replaces the framework payload** in `.deft/core/` AND refreshes the manifest + AGENTS.md, so doctor logic, skills, and scripts all advance to the current snapshot. This is the command the doctor's payload-staleness check now recommends verbatim.
|
|
63
|
+
|
|
64
|
+
**Version-skew note:** consumers on an installer binary that predates the Epic-4/5/6 headless work do not have these flags. Download the latest `deft-install` binary from GitHub Releases first, then run it with `--yes --upgrade --repo-root . --json`.
|
|
65
|
+
|
|
66
|
+
**Legacy paths (back-compat only / de-emphasized):**
|
|
67
|
+
- `task upgrade` / `run upgrade` -- **metadata-only acknowledgment**: refreshes the `.deft-version` marker, the `<install>/VERSION` manifest, and the AGENTS.md managed section, but does NOT replace the framework payload. Use the headless installer command above for a real payload refresh.
|
|
68
|
+
- `task relocate -- --confirm` (and the `task relocate:relocate -- --confirm` form) -- **back-compat only**: moves / reinstalls the framework dir for the rare install-path-consistency relocate, not for routine upgrades.
|
|
69
|
+
- `run install --force` -- back-compat reinstall path superseded by `--yes --upgrade`.
|
|
70
|
+
- `task framework:doctor`, `run doctor` direct old shims, `scripts/framework_doctor.py` (retired #1336)
|
|
71
|
+
- Manual git submodule updates or cloning `deft/` by hand (the installer is the reproducible, manifest-stamped mechanism)
|
|
72
|
+
- Old AGENTS.md thin pointers and upgrade prose that pre-date the unified handoff
|
|
73
|
+
|
|
74
|
+
All documentation (README, AGENTS.md, this file, `deft-directive-sync` skill) now points agents at the headless installer command + doctor handoff as the authoritative flow. Old sections below are retained for migration archaeology only.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Node runtime (#1828 / #1530)
|
|
79
|
+
|
|
80
|
+
After Wave 8, live deft gates run through the TypeScript engine. **Node.js and pnpm are required consumer runtimes** alongside Python (`uv`) — not optional extras for framework contributors only.
|
|
81
|
+
|
|
82
|
+
- Install **Node 20+** (the framework pins `.nvmrc`; currently Node 24).
|
|
83
|
+
- Enable pnpm via Corepack: `corepack enable && corepack prepare pnpm@latest --activate`
|
|
84
|
+
- Verify from your project root: `task toolchain:check` (or `deft toolchain:check`). When Node or pnpm is missing, the check exits non-zero and prints an actionable remediation line instead of failing later with an opaque stack trace.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## From v0.53.0–v0.53.1 → v0.53.2 (vitest no longer discovers vendored framework tests, #1878)
|
|
89
|
+
|
|
90
|
+
- **Applies when:** your project uses **vitest** AND you upgraded to v0.53.0 or v0.53.1, whose deposit vendored the TypeScript engine under `.deft/core/packages/` **including** the framework's own `*.test.ts` / `*.spec.ts` files. Detection: your vitest run discovers ~80+ files under `.deft/core/packages/` via its default include glob (`**/*.{test,spec}.?(c|m)[jt]s?(x)`) and CI fails with `ERR_MODULE_NOT_FOUND` for `@deftai/core` plus framework parity assertion failures. Projects that do not use vitest (or that already exclude `.deft/core/**`) are unaffected.
|
|
91
|
+
- **Safe to auto-run:** Yes. The installer now prunes the vendored `*.test.*` / `*.spec.*` files from the `.deft/core/packages/` deposit on every install and upgrade (and the release archive omits them too), leaving no framework test files for your vitest to discover. The prune touches only the framework's own test SOURCE files; non-test engine sources are left intact. No operator action is required once you are on v0.53.2+.
|
|
92
|
+
- **Restart required:** No -- the prune is a filesystem change to the vendored deposit; the agent's in-memory context does not depend on it.
|
|
93
|
+
- **Commands:**
|
|
94
|
+
- `deft-install --yes --upgrade --repo-root . --json` (refreshes the `.deft/core/` deposit; the prune runs automatically as part of the install)
|
|
95
|
+
- Interim manual workaround **only if you are mid-upgrade on a still-red v0.53.0/v0.53.1 PR**: add `.deft/core/**` to your vitest config's `test.exclude` (and `coverage.exclude`) so vitest skips the vendored payload, then re-run CI:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
// vitest.config.ts
|
|
99
|
+
export default defineConfig({
|
|
100
|
+
test: {
|
|
101
|
+
exclude: ['**/node_modules/**', '.deft/core/**'],
|
|
102
|
+
coverage: { exclude: ['.deft/core/**'] },
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This manual exclude is harmless to keep, but it becomes unnecessary once the installer prune lands in your deposit. Note: the deft-core-guard workflow (#1430) refuses a PR that mixes a `.deft/core/**` change with your own files, so apply the vitest-config exclude in a **separate** PR from the framework deposit.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
<!-- 1046-prb: From v0.27.x -> v0.28 install-manifest transition BEGIN -->
|
|
112
|
+
## From v0.27.x -> v0.28 (canonical install manifest at `<install>/VERSION`)
|
|
113
|
+
|
|
114
|
+
- **Applies when:** any project on deft v0.27.0, v0.27.1, or v0.27.2 that has an existing `./.deft-version` marker but no `<install>/VERSION` YAML provenance manifest at the install root (`./.deft/core/VERSION` for canonical installs, `./deft/VERSION` for legacy state-A installs). Detection: `task framework:doctor` reports the `manifest-agreement` check as FAIL with `missing-manifest`; the upgrade gate emits a one-line advisory (`[deft framework:doctor] 1 check(s) drifted (manifest-agreement). Run \`task framework:doctor\` for the full report. Refs #1046.`) on every CLI invocation. Pre-v0.27 projects skip this section -- they pick up the manifest on first `task upgrade` after landing v0.28.
|
|
115
|
+
- **Safe to auto-run:** Yes. The transition is fully automatic on first `task upgrade` (or `run upgrade`, or `run install --force`) post-v0.28 install. `cmd_upgrade` / `cmd_install` write the canonical YAML manifest at the install root with `fetched_by: run-upgrade` / `run-install`, current framework VERSION as `tag`, resolved git SHA as `sha`, and UTC `fetched_at`. The bare `.deft-version` is regenerated from the manifest's `tag` field (matching the v0.27 single-string format). No operator action required -- the gate advisory is purely informational and never blocks the CLI invocation.
|
|
116
|
+
- **Restart required:** No -- the manifest is structural state on disk; the agent's in-memory context does not depend on it. Future `task framework:doctor` invocations transition the `manifest-agreement` check from FAIL to PASS without a session restart.
|
|
117
|
+
- **Commands:**
|
|
118
|
+
- `task framework:doctor` (read the four-check report; FAIL on the `manifest-agreement` check is the canonical pre-transition state)
|
|
119
|
+
- `task framework:doctor -- --json` (machine-readable form -- the `checks` array carries per-check status; useful for CI assertions)
|
|
120
|
+
- `task upgrade` (writes the canonical manifest + regenerates the derivative; idempotent on re-run -- a second invocation against a current manifest is a no-op)
|
|
121
|
+
- `run install --force <path>` (rewrites the framework dir AND stamps a fresh manifest; the operator-consent path for reinstalls)
|
|
122
|
+
|
|
123
|
+
### What changes for consumers
|
|
124
|
+
|
|
125
|
+
- **Canonical manifest.** `<install>/VERSION` (YAML provenance: `ref`, `sha`, `tag`, `fetched_at`, `fetched_by`) is the canonical source of truth for what the framework believes about itself on disk. See [`docs/install-manifest.md`](../docs/install-manifest.md) for the full field reference and write-rail catalogue.
|
|
126
|
+
- **`.deft-version` is now a derivative.** The bare project-root file is regenerated from the manifest's `tag` field on every install / upgrade. Operators should NOT hand-edit it -- update the manifest and re-run `task upgrade`.
|
|
127
|
+
- **Doctor probe.** `task framework:doctor` adds four checks: `quick-start-resolves`, `skill-paths-resolve`, `manifest-agreement`, `install-path-consistency`. Three-state exit (0 clean / 1 drift / 2 config error). The probe is read-only -- it NEVER mutates state. Mutation belongs to `task upgrade`.
|
|
128
|
+
- **Upgrade-gate advisory.** `_check_upgrade_gate` runs the doctor probe in lazy-import mode after the install-layout prompt and emits a one-line advisory on positive drift. Informational only; never sets `needs_prompt` and never blocks the gate.
|
|
129
|
+
- **Managed-section marker v2 -> v3.** Refreshed AGENTS.md files carry a v3 marker (`<!-- deft:managed-section v3 sha=<framework-sha> refreshed=<iso> session=<id> -->`) with refresh-time provenance. The v2 form is parsed for one release cycle (v0.28 only; v0.29 deprecates v2) and forces a refresh-to-v3 on the next `task upgrade` / `run agents:refresh` invocation. Session-boundary detection: when `DEFT_SESSION_ID` is set AND matches the embedded `session=` token, the gate emits a warn telling the operator to start a new session before re-running the refresh (#1046 finding #6 -- prevents Case G no-op re-entry within the same session).
|
|
130
|
+
|
|
131
|
+
### What `task framework:doctor` does NOT do
|
|
132
|
+
|
|
133
|
+
- ⊗ It does NOT mutate any filesystem state during detection or emission.
|
|
134
|
+
- ⊗ It does NOT block the CLI invocation it fires alongside; the gate stays exit-0 for manifest drift (mirrors the #801 remote-version probe's informational-only contract).
|
|
135
|
+
- ⊗ It does NOT auto-rewrite the manifest -- writing belongs to `task upgrade` / `run install` / `oz-agent-upgrade` / the webinstaller.
|
|
136
|
+
- ⊗ It does NOT call `read_yn` / interactive confirm helpers; the advisory is a one-line warn, not a prompt.
|
|
137
|
+
|
|
138
|
+
### Rollback
|
|
139
|
+
|
|
140
|
+
The transition is one-way -- v0.28 has no shim back to the bare-only marker. To revert to v0.27.x behaviour, pin the framework to a v0.27.x tag and delete `<install>/VERSION`. The bare `.deft-version` survives the rollback and is read by the v0.27 upgrade gate verbatim.
|
|
141
|
+
|
|
142
|
+
### References
|
|
143
|
+
|
|
144
|
+
- [#1046](https://github.com/deftai/directive/issues/1046) -- install / refresh contract umbrella (PR-B AC-3 + AC-4 + AC-5 ship the doctor, manifest, and v3 sentinel respectively).
|
|
145
|
+
- [#992](https://github.com/deftai/directive/issues/992) -- canonical install layout (`.deft/core/`) -- the install root this manifest is anchored to.
|
|
146
|
+
- [#410](https://github.com/deftai/directive/issues/410) -- original upgrade gate + `.deft-version` marker (predecessor surface).
|
|
147
|
+
- [`docs/install-manifest.md`](../docs/install-manifest.md) -- canonical manifest field reference + write-rail catalogue.
|
|
148
|
+
- [`scripts/framework_doctor.py`](../scripts/doctor.py) -- doctor probe source (PR-B AC-3).
|
|
149
|
+
- [`tasks/framework.yml`](../tasks/framework.yml) -- `task framework:doctor` Taskfile fragment.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
<!-- 1046-prb: From v0.27.x -> v0.28 install-manifest transition END -->
|
|
153
|
+
|
|
154
|
+
<!-- 1061: AGENTS.md drift repair via task upgrade BEGIN -->
|
|
155
|
+
## From drifted AGENTS.md -> current install (`task upgrade` repair path, #1061)
|
|
156
|
+
|
|
157
|
+
- **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).
|
|
158
|
+
- **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.
|
|
159
|
+
- **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.
|
|
160
|
+
- **Commands:**
|
|
161
|
+
- `task framework:doctor` -- read the four-check report; identify which checks FAIL and which command the doctor recommends.
|
|
162
|
+
- `task framework:doctor -- --json` -- machine-readable form; per-check `data.suggested_fix` field (added in #1061) carries the named command the doctor recommends for each failure.
|
|
163
|
+
- `task upgrade` -- canonical drift repair (wraps `run upgrade`; rewrites manifest + .deft-version + AGENTS.md managed section). Use this when the framework on disk is correct and AGENTS.md / the manifest is out of date.
|
|
164
|
+
- `.deft/core/run agents:refresh` (Unix) / `.deft\core\run agents:refresh` (Windows) -- AGENTS.md-only refresh; useful when `task upgrade` is not available (e.g. the consumer project has no Taskfile) or when only the managed-section block needs rewriting.
|
|
165
|
+
- `task relocate:relocate -- --confirm` -- use this ONLY when the framework needs to move to a different on-disk path (rare; the doctor's `install-path-consistency` FAIL is the only check that recommends this). The doubled-namespace form (`relocate:relocate`) is the canonical go-task target name because the include namespace `relocate:` and the inner task `relocate:` carry the same key in `tasks/relocate.yml` (no root-level alias exists today, unlike the `install:install` / `install:upgrade` shortcuts wired in `Taskfile.yml`).
|
|
166
|
+
|
|
167
|
+
### AGENTS.md drift symptoms and detection
|
|
168
|
+
|
|
169
|
+
The doctor surfaces AGENTS.md drift across two complementary axes:
|
|
170
|
+
|
|
171
|
+
1. **Mismatched marker version.** When `cmd/deft-install/setup.go::WriteAgentsMD` detects a pre-v0.27 sentinel in the existing AGENTS.md, it skips rewriting the deft entry (treating the legacy sentinel as evidence the entry is already present). On a canonical reinstall over such a file, the AGENTS.md keeps its pre-v0.27 prose while the on-disk framework has migrated to `.deft/core/`. Symptom: `quick-start-resolves` and `skill-paths-resolve` FAIL because the paths AGENTS.md references no longer match the on-disk layout. Repair: `task upgrade` (or `.deft/core/run agents:refresh` if a Taskfile is not available).
|
|
172
|
+
2. **Install-path mismatch via the manifest's `install_root` field (#1062).** The doctor's `install-path-consistency` check reads `<install>/VERSION` for the `install_root` field first; when present, it uses that as the authoritative install-layout source (the field was added in #1062 as the single source of truth for the install-layout contract). When the field is absent (pre-v0.29 manifests), the doctor falls back to parsing the install root out of AGENTS.md and surfaces an INFO note in the check `detail` so operators can see when the legacy parse was taken. FAIL fires when the resolved install root does not exist as a directory on disk -- e.g. AGENTS.md / the manifest claims `.deft/core` but only `deft/` exists. Repair: `task upgrade` to rewrite the manifest + AGENTS.md to match the on-disk framework, OR `task relocate:relocate -- --confirm` to move the framework to the path AGENTS.md / the manifest claims (pick the relocate only when AGENTS.md is the correct source of truth).
|
|
173
|
+
|
|
174
|
+
### What to do if the doctor's failure prose looks wrong
|
|
175
|
+
|
|
176
|
+
The doctor's FAIL `detail` strings name the exact commands the operator should run. If a recommendation looks wrong (the named command does not exist, or the recommendation does not match the failure mode), this is a regression in the failure prose itself -- the prose-regression test at `tests/cli/test_framework_doctor_prose.py` (added in #1061) asserts every command string surfaced in FAIL details either exists as a Taskfile target or matches a documented `run` subcommand. File a new issue against [`deftai/directive`](https://github.com/deftai/directive/issues/new) with:
|
|
177
|
+
|
|
178
|
+
- The full `task framework:doctor -- --json` output (the `checks[].detail` fields carry the prose; the `data.suggested_fix` / `data.suggested_fix_alt` fields carry the structured recommendation).
|
|
179
|
+
- The on-disk state that produced the FAIL (`ls -la .deft/core/`, `cat .deft/core/VERSION` if present, `cat AGENTS.md` -- redact any consumer-private content above / below the managed-section markers first).
|
|
180
|
+
- A reference to the originating issue [#1061](https://github.com/deftai/directive/issues/1061) so the maintainer can chain the regression back to the prose contract.
|
|
181
|
+
|
|
182
|
+
### References
|
|
183
|
+
|
|
184
|
+
- [#1061](https://github.com/deftai/directive/issues/1061) -- doctor failure prose sharpening + `task upgrade` wrapper + this UPGRADING.md section.
|
|
185
|
+
- [#1060](https://github.com/deftai/directive/issues/1060) -- canonical-reinstall-over-pre-v0.27-AGENTS.md root cause that motivates the repair path.
|
|
186
|
+
- [#1062](https://github.com/deftai/directive/issues/1062) -- `install_root` manifest field consumed by the doctor's `install-path-consistency` check.
|
|
187
|
+
- [`scripts/framework_doctor.py`](../scripts/doctor.py) -- doctor probe source (FAIL `detail` strings + `suggested_fix` data field).
|
|
188
|
+
- [`tasks/install.yml`](../tasks/install.yml) -- `task install:upgrade` wrapper definition.
|
|
189
|
+
- [`Taskfile.yml`](../Taskfile.yml) -- root-level `task upgrade` alias for the wrapper.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
<!-- 1061: AGENTS.md drift repair via task upgrade END -->
|
|
193
|
+
|
|
194
|
+
<!-- 992-pr3: From deft/ -> .deft/core/ migration BEGIN -->
|
|
195
|
+
## From deft/ -> .deft/core/
|
|
196
|
+
|
|
197
|
+
- **Applies when:** `.deft/core/run gate` reports a non-A install layout state (`B`, `C`, or `D`) -- equivalently, the new `_check_upgrade_gate` install-layout auto-prompt fires `[deft] install layout state: <X> (<description>). Run .deft/core/run relocate to upgrade. (Y/n)` on every CLI invocation. The four states inspected by the detector are: **A** pure `deft/` (legacy install; AGENTS.md + framework agree at the legacy path -- working today, no action required), **B** pure `.deft/core/` (current installer / webinstaller / sync skill / oz output -- AGENTS.md may still say `deft/` and the contract diverges), **C** hybrid (both `deft/` and `.deft/core/` present -- agents follow whichever they read first), **D** AGENTS.md only (managed-section markers present but no framework directory -- partial install). State A is the only non-firing state in v0.27 -- a future cycle decides whether to deprecate the legacy path. (#992)
|
|
198
|
+
- **Safe to auto-run:** No -- the relocator is wipe-and-reinstall by design and operator consent is required at every gate-prompt invocation. The cmd_gate auto-prompt is purely informational: it asks `(Y/n)` as a visual consent affordance but the gate itself NEVER invokes `task relocate` automatically and NEVER mutates filesystem state. This mirrors the **#884 ghx-install consent gate** precedent (`task setup` prompts before invoking the upstream installer; the only non-interactive paths are explicit `--yes` or env-var opt-out). The relocator's own `task relocate` surface ALSO prompts `[y/N]` on bare invocation; pass `--confirm` to skip the prompt in scripted use, never as a default. The relocator writes a gzip snapshot tarball to `.deft-cache/relocate-snapshot-<UTC-timestamp>.tar.gz` BEFORE any wipe so a botched relocate is recoverable.
|
|
199
|
+
- **Restart required:** Yes -- the marker v1 -> v2 bump (PR1) intentionally fires `agents-md=stale` on every current install on the first `cmd_gate` invocation post-v0.27. After the relocator completes, AGENTS.md is re-rendered with the v2 managed-section markers; chase with a fresh agent session so the refreshed `AGENTS.md` (Implementation Intent Gate, Branch Policy Disclosure, Multi-agent orchestration discipline, etc.) loads from a clean context. Your current session still holds the pre-relocate `AGENTS.md` in memory; restarting closes that drift.
|
|
200
|
+
- **Commands:**
|
|
201
|
+
- `task relocate -- --dry-run` (preview the planned wipe-and-reinstall; never writes; no consent prompt because no mutation)
|
|
202
|
+
- `task relocate` (apply -- prompts `[y/N]` on bare invocation; writes gzip snapshot tarball to `.deft-cache/relocate-snapshot-<UTC-timestamp>.tar.gz` before any wipe; idempotent across states A/B/C/D/F)
|
|
203
|
+
- `task relocate -- --confirm` (apply non-interactively -- scripted-use ONLY; the consent prompt is the default for a reason)
|
|
204
|
+
- `task relocate -- --rollback` (extract the most recent snapshot back into project root if the relocate landed badly)
|
|
205
|
+
- `task relocate -- --force` (override the pre-flight hard-fails for **customized framework dir** [preserved-files list printed] OR **active swarm** [`vbrief/active/*.vbrief.json` with `plan.status == "running"`]; required when either condition is detected)
|
|
206
|
+
- `uv run python scripts/relocate.py --help` (full flag surface reference)
|
|
207
|
+
|
|
208
|
+
### Install-layout state classification
|
|
209
|
+
|
|
210
|
+
The gate-side detector inspects three filesystem facts at the consumer project root: presence of `deft/` (legacy framework dir), presence of `.deft/core/` (canonical framework dir), and presence of managed-section markers in `AGENTS.md`. The four states map onto those facts as follows:
|
|
211
|
+
|
|
212
|
+
- **State A** -- `deft/` present, `.deft/core/` absent. Legacy install. **No prompt fires.** Working today; relocate is OPTIONAL in v0.27. Operators on state A can keep their legacy install indefinitely or relocate proactively.
|
|
213
|
+
- **State B** -- `deft/` absent, `.deft/core/` present. Current installer / webinstaller / sync skill / oz output. **Prompt fires.** AGENTS.md may still reference `deft/` paths (pre-PR1 contract); the relocator re-renders AGENTS.md with the v2 markers and aligns the contract.
|
|
214
|
+
- **State C** -- both `deft/` AND `.deft/core/` present. Hybrid. **Prompt fires.** Agents follow whichever path they read first; the relocator wipes both and reinstalls into `.deft/core/` only (single-namespace contract per the v0.27 DesignChoice).
|
|
215
|
+
- **State D** -- neither directory present, AGENTS.md with managed markers present. Partial install. **Prompt fires.** Typically a cancelled / interrupted install; the relocator does a fresh canonical install into `.deft/core/`.
|
|
216
|
+
|
|
217
|
+
### What the relocator does
|
|
218
|
+
|
|
219
|
+
`task relocate` runs `scripts/relocate.py` (PR2). The implementation is wipe-and-reinstall by design: one idempotent code path across states A/B/C/D/F that enforces the canonical `.deft/core/` namespace contract from #11 (read-only packaged assets), has a trivial test surface (state matrix x relocator -> assert end state), catches stale framework versions for free (state B benefits even though no path move is needed), and aligns with the npm/pip rail packaging semantics that #11 will ship in parallel. Per phase, the relocator:
|
|
220
|
+
|
|
221
|
+
1. **Pre-flight gates** -- hard-fails without `--force` when the framework dir is git-tracked + customized (preserved-files list printed) OR any `vbrief/active/*.vbrief.json` has `plan.status == "running"` (active swarm).
|
|
222
|
+
2. **Snapshot** -- writes a gzip tarball to `.deft-cache/relocate-snapshot-<UTC-timestamp>.tar.gz` covering `deft/` + `.deft/core/` + `AGENTS.md` so the operation is reversible via `task relocate -- --rollback`.
|
|
223
|
+
3. **Wipe** -- removes both `deft/` (if present) and `.deft/core/` (if present) -- the operation is contractually idempotent across source states.
|
|
224
|
+
4. **Reinstall** -- copies the framework source into `.deft/core/`. The bootstrap path (`webinstaller/upgrade.sh` / `upgrade.ps1`, in the separate `webinstaller` repo) fetches a fresh framework copy to a temp dir and runs the relocator FROM that copy, so the in-place framework about to be wiped never executes its own wipe (BOOTSTRAP NEVER SELF-DESTRUCTIVE).
|
|
225
|
+
5. **AGENTS.md re-render** -- bumps the managed-section bytes to the v2 marker contract using the `_wrap_legacy_in_markers` semantics from `run` (#794) so consumer notes outside the bracketed region survive verbatim.
|
|
226
|
+
6. **`.gitignore` update** -- ensures `.deft/core/` is gitignored by default per the #845 / `.deft-cache/` precedent (hidden-namespace contract).
|
|
227
|
+
7. **Advisory grep** -- scans consumer files OUTSIDE `.deft/core/` for legacy framework path references and prints findings (CI workflows, external scripts, dotfiles that hardcode the pre-v0.27 path). See `scripts/_relocate_states.py::advise_external_hardcodes()` for the exact search constant + grep semantics. The relocator NEVER auto-rewrites these -- CI / external tooling that hardcodes the legacy path is out of framework's control; the operator decides whether to update each surface.
|
|
228
|
+
|
|
229
|
+
### Snapshot rollback
|
|
230
|
+
|
|
231
|
+
A botched relocate is reversible:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
task relocate -- --rollback
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The rollback extracts the most recent `.deft-cache/relocate-snapshot-*.tar.gz` back into the project root. Snapshots are timestamped (UTC) so multiple back-to-back relocates each leave their own snapshot; the rollback always picks the most recent. If you need to roll back further, extract the older snapshot manually with `tar -xzf .deft-cache/relocate-snapshot-<timestamp>.tar.gz -C <project_root>`.
|
|
238
|
+
|
|
239
|
+
The rollback restores **byte-equivalent pre-relocate state** for the four tracked paths (`deft/`, `.deft/core/`, `AGENTS.md`, `.gitignore`): captured paths are restored from the tarball; uncaptured tracked paths (relocator-created `.gitignore` when the project had none pre-relocate) are removed so `git status --porcelain` is clean post-rollback. The `.deft-cache/` directory is intentionally outside the byte-equivalent contract because it hosts the snapshot tarball and the relocator's working state -- removing it would break re-rollback against the same snapshot. (F3 #1015)
|
|
240
|
+
|
|
241
|
+
### Manual edits required after relocate (above-marker prose)
|
|
242
|
+
|
|
243
|
+
The relocator preserves consumer-authored prose ABOVE the AGENTS.md managed-section markers verbatim per the [#794](https://github.com/deftai/directive/issues/794) `_wrap_legacy_in_markers` contract -- this is by design so hand-rolled notes survive the migration. As a consequence, **legacy `deft/run` references the consumer wrote into their own AGENTS.md (or other consumer-owned files outside `.deft/core/`) survive the relocate verbatim**. The relocator's advisory grep flags these as fix-manually hits at the end of the run; the operator decides whether to update each surface.
|
|
244
|
+
|
|
245
|
+
The relocator does NOT auto-rewrite consumer-owned files (the canonical reason: external CI workflows, dotfiles, and tooling outside the framework's control may also hardcode the legacy path -- the framework cannot mechanically distinguish a benign reference from a load-bearing one). After the relocate, scan the advisory grep output and update each occurrence by hand:
|
|
246
|
+
|
|
247
|
+
- `AGENTS.md` head/tail (above and below the managed-section markers) -- replace `deft/run` with `.deft/core/run` and `Full guidelines: deft/main.md` with `Full guidelines: .deft/core/main.md`.
|
|
248
|
+
- CI workflow files (`.github/workflows/*.yml`) -- replace any `deft/run <task>` invocations.
|
|
249
|
+
- Project scripts (`scripts/`, `Makefile`, `Taskfile.yml`, dotfiles) that hardcode the legacy path.
|
|
250
|
+
- README / docs / contributor-onboarding prose that points new contributors at `deft/run` for bootstrap.
|
|
251
|
+
|
|
252
|
+
The advisory grep output is the operator's worklist; treat it as a finite todo. Once every flagged occurrence is either updated to `.deft/core/run` or explicitly acknowledged as legacy-friendly redirect-stub content (e.g. the `skills/deft-{sync,setup,...}/SKILL.md` redirect stubs that intentionally retain `deft/run` per [#411](https://github.com/deftai/directive/issues/411)), commit the changes alongside the relocate. (F1 #1015)
|
|
253
|
+
|
|
254
|
+
### What the cmd_gate auto-prompt does NOT do
|
|
255
|
+
|
|
256
|
+
The gate-side prompt is informational only:
|
|
257
|
+
|
|
258
|
+
- ⊗ It does NOT invoke `task relocate` automatically; the operator runs the command on consent.
|
|
259
|
+
- ⊗ It does NOT mutate any filesystem state during detection or emission.
|
|
260
|
+
- ⊗ It does NOT block the CLI invocation it fires alongside; the gate stays exit-0 for layout drift (mirrors the #801 remote-version probe's informational-only contract).
|
|
261
|
+
- ⊗ It does NOT call `read_yn` / interactive confirm helpers; the `(Y/n)` suffix is purely a visual consent affordance.
|
|
262
|
+
|
|
263
|
+
The operator-consent contract is identical to the #884 `task setup` ghx-install consent gate: detection signals that work needs doing; the operator authorizes the work explicitly.
|
|
264
|
+
|
|
265
|
+
### References
|
|
266
|
+
|
|
267
|
+
- [#992](https://github.com/deftai/directive/issues/992) -- adopt `.deft/core/` as canonical install layout (parent issue).
|
|
268
|
+
- [#11](https://github.com/deftai/directive/issues/11) -- origin of the `.deft/core/` layout choice (read-only packaged assets contract).
|
|
269
|
+
- [#768](https://github.com/deftai/directive/issues/768) -- universal upgrade gate + AGENTS.md managed-section markers (PR1 bumps the marker from v1 to v2).
|
|
270
|
+
- [#794](https://github.com/deftai/directive/issues/794) -- pre-#768 AGENTS.md legacy migration (`_wrap_legacy_in_markers` reused by the relocator's AGENTS.md re-render path).
|
|
271
|
+
- [#884](https://github.com/deftai/directive/issues/884) -- `task setup` ghx-install consent gate (operator-consent precedent).
|
|
272
|
+
- [`scripts/relocate.py`](../scripts/relocate.py) -- relocator source (PR2).
|
|
273
|
+
- [`scripts/_relocate_states.py`](../scripts/_relocate_states.py) -- state classifier shared with cmd_gate.
|
|
274
|
+
- [`tasks/relocate.yml`](../tasks/relocate.yml) -- `task relocate` Taskfile fragment.
|
|
275
|
+
- [`tests/cmd_gate/test_state_detection.py`](../tests/cmd_gate/test_state_detection.py) -- gate-side state-detector + auto-prompt regression coverage (PR3).
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
<!-- 992-pr3: From deft/ -> .deft/core/ migration END -->
|
|
279
|
+
|
|
280
|
+
<!-- 1143: From v0.26.x -> v0.27 triage adoption ritual BEGIN -->
|
|
281
|
+
## From v0.26.x -> v0.27 (triage adoption via `task triage:welcome`)
|
|
282
|
+
|
|
283
|
+
- **Applies when:** any project on deft v0.26.0 or later that has not yet run the v0.27 triage adoption ritual. Detection: `vbrief/PROJECT-DEFINITION.vbrief.json` has neither `plan.policy.triageScope` nor `plan.policy.wipCap` set, OR `.deft-cache/github-issue/` is absent / empty. The v0.27 cycle introduced 16+ new `task triage:*` / `task scope:*` verbs (the #1119 governance swarm: D1/#1121, D2/#1122, D5/#1127, D6/#1130, D10/#1129, D11/#1128, D12/#1131, plus the network children N9/#1149 + N3/#1143); without a chained command, operators had to learn each verb individually from the v0.27 release notes.
|
|
284
|
+
- **Safe to auto-run:** Yes (interactive). `task triage:welcome` (#1143 / N3) is the single chained command for the v0.27 cycle's onboarding. The ritual is idempotent and detection-bound -- each phase emits an informational stderr line and skips when its precondition is already satisfied, so a re-run after a partial completion resumes cleanly without redoing work. The two destructive phases (subscription / `wipCap` writes to `PROJECT-DEFINITION`, plus the optional WIP-relief `task scope:demote --batch` invocation) are gated by numbered-menu prompts per [`contracts/deterministic-questions.md`](./contracts/deterministic-questions.md) (`Discuss` and `Back` are the canonical final two options); the relief preview is always shown before any real demote, and the operator must explicitly confirm before the relief runs.
|
|
285
|
+
- **Restart required:** No -- the ritual writes typed flags on `PROJECT-DEFINITION` and runs subprocess hops into existing verbs; no `AGENTS.md` rewrite is involved (N9 / #1149 owns the v0.27 AGENTS.md updates and already landed).
|
|
286
|
+
- **Commands:**
|
|
287
|
+
- `task triage:welcome` -- run the 6-phase ritual (detect prior state, prompt subscription scope, run `task triage:bootstrap`, prompt `wipCap`, offer WIP relief if needed, print `task triage:summary` + pointer to `skills/deft-directive-triage/SKILL.md`).
|
|
288
|
+
- `task triage:welcome -- --no-subprocess` -- test-mode flag that suppresses the bootstrap / scope:demote / triage:summary subprocess hops; never set in production runs.
|
|
289
|
+
|
|
290
|
+
### What the ritual does
|
|
291
|
+
|
|
292
|
+
Six phases, each detection-bound so a partial re-run resumes cleanly:
|
|
293
|
+
|
|
294
|
+
1. **Detect prior state.** Reads `plan.policy.triageScope[]` and `plan.policy.wipCap` from `vbrief/PROJECT-DEFINITION.vbrief.json`; walks `.deft-cache/<source>/<owner>/<repo>/` for cache entries; counts vBRIEFs in `vbrief/pending/ + vbrief/active/`. Pure -- no writes.
|
|
295
|
+
2. **Prompt subscription scope.** Numbered menu over three presets: **Small** (`all-open` -- recommended for repos <200 open issues), **Mid** (curated `labels` rule + `opened-since 60d` -- recommended 200-2000), **Mega** (`explicit-watch` + `referenced-by-vbrief` -- recommended 2000+). Default = Mid. Writes the typed array via the D12 / #1131 surface (`scripts/triage_scope.py::validate_scope_rules` is consulted for schema validation before the write commits). Skipped when already set.
|
|
296
|
+
3. **Run `task triage:bootstrap`.** Subprocess hop into the existing D10 (#1129) / cache (#883) bootstrap. The D10 auto-classify pass runs on by default per its acceptance criteria. Skipped when the cache is already populated.
|
|
297
|
+
4. **Prompt `wipCap`.** Numbered menu (8 small team / 10 default / 15 large team / custom). Default = **10** per umbrella #1119 Current Shape v3 (NOT 12 from older issue-body wording). Writes `plan.policy.wipCap` via the hand-rolled typed-flag writer that mirrors `scripts/policy.py::set_policy`; once D4 (#1124) lands its dedicated `policy_set.py wip-cap` subcommand the writer body becomes a thin delegation. Skipped when already set.
|
|
298
|
+
5. **Offer WIP relief.** When `vbrief/pending/ + vbrief/active/` exceeds the chosen cap, preview the planned `task scope:demote -- --batch --older-than-days 30` (#1121 / D1) invocation: count + name the eligible vBRIEFs, show ineligibles. The relief is opt-in -- the operator must answer `y` to the explicit confirmation prompt (default `[y/N]`) before the real demote runs. Declining leaves the cap over by the existing delta and the ritual proceeds.
|
|
299
|
+
6. **Final summary.** Emits `task triage:summary` (#1122 / D2) and points the operator at `skills/deft-directive-triage/SKILL.md` (#1130 / D6) for the next step.
|
|
300
|
+
|
|
301
|
+
### Audit trail
|
|
302
|
+
|
|
303
|
+
Every policy write (Phase 2 / Phase 4) appends an entry to `meta/policy-changes.log` with `actor=triage-welcome`, the field name, the new value, the previous value, and a `changed=true|false` token. This mirrors the existing `scripts/policy.py::set_policy` audit format so `git grep triage-welcome meta/policy-changes.log` surfaces every ritual run.
|
|
304
|
+
|
|
305
|
+
### References
|
|
306
|
+
|
|
307
|
+
- [#1143](https://github.com/deftai/directive/issues/1143) -- N3: `task triage:welcome` 6-phase onboarding ritual (this section).
|
|
308
|
+
- [#1119](https://github.com/deftai/directive/issues/1119) -- umbrella: triage-eval governance swarm.
|
|
309
|
+
- [#1131](https://github.com/deftai/directive/issues/1131) -- D12: typed `plan.policy.triageScope[]` subscription surface (Phase 2 writes).
|
|
310
|
+
- [#1124](https://github.com/deftai/directive/issues/1124) -- D4: typed `plan.policy.wipCap` (Phase 4 writes; the ritual hand-rolls until D4 ships its writer subcommand).
|
|
311
|
+
- [#1121](https://github.com/deftai/directive/issues/1121) -- D1: `task scope:demote --batch` (Phase 5 relief invocation).
|
|
312
|
+
- [#1122](https://github.com/deftai/directive/issues/1122) -- D2: `task triage:summary` (Phase 6 final-state emission).
|
|
313
|
+
- [#1129](https://github.com/deftai/directive/issues/1129) -- D10: triage auto-classification (consumed inside Phase 3).
|
|
314
|
+
- [#1130](https://github.com/deftai/directive/issues/1130) -- D6: triage skill pointer (Phase 6 forward-pointer).
|
|
315
|
+
- [#1149](https://github.com/deftai/directive/issues/1149) -- N9: `welcome` / `onboard triage` / `triage setup` skill-routing entry in AGENTS.md (already landed).
|
|
316
|
+
- [`contracts/deterministic-questions.md`](./contracts/deterministic-questions.md) -- numbered-menu contract every prompt follows.
|
|
317
|
+
- [`scripts/triage_welcome.py`](../scripts/triage_welcome.py) -- ritual entry point.
|
|
318
|
+
- [`tasks/triage-welcome.yml`](../tasks/triage-welcome.yml) -- `task triage:welcome` Taskfile fragment.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
<!-- 1143: From v0.26.x -> v0.27 triage adoption ritual END -->
|
|
322
|
+
|
|
323
|
+
<!-- 883-story-4: v0.25.x -> v0.26.0 migration BEGIN -->
|
|
324
|
+
## From v0.25.x → v0.26.0 (deft-cache unified layer; breaking)
|
|
325
|
+
|
|
326
|
+
- **Applies when:** any project on deft v0.25.0, v0.25.1, or v0.25.2 that has run `task triage:bootstrap` (i.e. has a populated `.deft-cache/issues/<owner>-<repo>/<N>.{json,md}` flat-sidecar layout). Detection: `Test-Path .deft-cache/issues/` returns `True` AND `Test-Path .deft-cache/github-issue/` returns `False`. Pure-additive opt-out projects (no `.deft-cache/`) skip this section -- they pick up the v0.26.0 surface on first `task triage:bootstrap`.
|
|
327
|
+
- **Safe to auto-run:** No. The on-disk layout changed; the legacy `.deft-cache/issues/` tree is NOT migrated in place. Operators MUST delete the legacy tree and re-populate via `task cache:fetch-all` (one-shot; mirrors the v0.25.x bootstrap-populate timing). The audit log at `vbrief/.eval/candidates.jsonl` is preserved verbatim across the migration -- accept/reject/defer history is untouched.
|
|
328
|
+
- **Restart required:** Yes. The agent's current session still holds stale skill prose pointing at `task triage:cache` / `task triage:show`. After the cache re-populate completes, start a new agent session so the refreshed `skills/deft-directive-refinement/SKILL.md` Phase 0 (rebound onto `cache:*`) loads from a clean context.
|
|
329
|
+
- **Commands:**
|
|
330
|
+
- `Remove-Item -Recurse -Force .deft-cache/issues/` (PowerShell) or `rm -rf .deft-cache/issues/` (bash) -- drop the legacy flat-sidecar layout.
|
|
331
|
+
- `task cache:fetch-all -- --source=github-issue --repo=OWNER/NAME` -- re-populate under the new `.deft-cache/<source>/<key>/{raw.json,content.md,meta.json}` layout (~5 min for a ~200-issue corpus; idempotent on re-run via TTL skip-fresh).
|
|
332
|
+
- `task cache:get -- github-issue <owner>/<repo>/<N>` -- per-issue read replacing the removed `task triage:show <N>` form.
|
|
333
|
+
- `task triage:bootstrap` -- still works; now delegates to `cache:fetch-all` end-to-end.
|
|
334
|
+
|
|
335
|
+
### Surface changes
|
|
336
|
+
|
|
337
|
+
- **`task triage:cache` REMOVED.** Replaced by `task cache:fetch-all --source=github-issue --repo=OWNER/NAME`. The unified surface is the canonical entry point for all cache populates (github-issue today; URL / email / file deferred to v2).
|
|
338
|
+
- **`task triage:show` REMOVED.** Replaced by `task cache:get github-issue <owner>/<repo>/<N>`. Returns the schema-validated `meta.json` envelope plus the path to `content.md` (or a structured stale-with-flag response when `expires_at` has elapsed; pass `--no-stale` to fail closed instead).
|
|
339
|
+
- **On-disk layout changed.** Old: `.deft-cache/issues/<owner>-<repo>/<N>.{json,md}` (flat sidecar). New: `.deft-cache/<source>/<key>/{raw.json,content.md,meta.json}` (per-entry directory; schema-validated meta envelope). `cache:get` validates `meta.json` against `vbrief/schemas/cache-meta.schema.json` on every read so a corrupt or version-incompatible file fails closed.
|
|
340
|
+
- **Audit log UNCHANGED.** `vbrief/.eval/candidates.jsonl` preserves accept / reject / defer / needs-ac / mark-duplicate / reset records across the migration. The Story 3 Tier-2 short-circuit (terminal-decision skip on bulk-* re-runs) operates on the same file.
|
|
341
|
+
- **All other `triage:*` actions UNCHANGED.** `triage:accept` / `triage:reject` / `triage:defer` / `triage:needs-ac` / `triage:mark-duplicate` / `triage:bulk-accept` / `triage:bulk-reject` / `triage:bulk-defer` / `triage:bulk-needs-ac` / `triage:status` / `triage:reset` / `triage:history` / `triage:refresh-active` keep their v0.25.x surface byte-for-byte (13 aliases). The rebind onto `cache:get` is internal. `triage:bootstrap` keeps its v0.25.x command surface but its on-disk output is the new `.deft-cache/<source>/<key>/` per-entry layout (now delegates to `cache:fetch-all`); see the Commands list above.
|
|
342
|
+
|
|
343
|
+
### Rollback
|
|
344
|
+
|
|
345
|
+
The migration is one-way; v0.26.0 ships no shim back to the flat-sidecar layout. To revert to v0.25.2 behaviour, pin `deft/` to the v0.25.2 tag, delete `.deft-cache/`, and re-run `task triage:bootstrap` against the v0.25.2 surface. The audit log at `vbrief/.eval/candidates.jsonl` is forward / backward compatible -- v0.25.x and v0.26.0 read the same JSONL schema.
|
|
346
|
+
|
|
347
|
+
### References
|
|
348
|
+
|
|
349
|
+
- [#883](https://github.com/deftai/directive/issues/883) -- deft-cache unified content cache + quarantine epic (this migration is the v1 cutover).
|
|
350
|
+
- [`vbrief/schemas/cache-meta.schema.json`](./vbrief/schemas/cache-meta.schema.json) -- frozen JSON Schema 2020-12 contract for `meta.json` (validated on read AND write).
|
|
351
|
+
- [`docs/quarantine-spec.md`](../docs/quarantine-spec.md) -- formal spec for the #583 injection-quarantine algorithm consumed by `cache:put`.
|
|
352
|
+
- [`docs/privacy-nfr.md`](../docs/privacy-nfr.md) -- privacy contract for `.deft-cache/` (gitignore default; opt-in commit path; private-repo body treatment).
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
<!-- 883-story-4: v0.25.x -> v0.26.0 migration END -->
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
## Migration to triage v1
|
|
359
|
+
|
|
360
|
+
- **Applies when:** any project on deft v0.24.0 or later that wants to opt in to the pre-ingest triage workflow (#845). Triage v1 is **purely additive** -- existing skills (`deft-directive-refinement`, `deft-directive-swarm`, `deft-directive-build`, etc.) keep working byte-identically when the triage surfaces are absent. Detection: run `task triage:bootstrap` and observe whether `.deft-cache/` exists at the project root. If not, you have not opted in yet.
|
|
361
|
+
- **Safe to auto-run:** Yes. `task triage:bootstrap` is idempotent and reversible -- a second run is a no-op, and the entire opt-in can be undone by deleting `.deft-cache/` and removing the `.deft-cache/` line from `.gitignore`. The bootstrap performs five steps: (1) populate the local issue cache for all open upstream issues; (2) backfill `vbrief/.eval/candidates.jsonl` with `accepted` audit entries for items already in `vbrief/proposed/`, `vbrief/pending/`, or `vbrief/active/` (preserves audit trail; intentionally skips `vbrief/cancelled/` to avoid reanimating rejected items); (3) add `.deft-cache/` to `.gitignore` if absent; (4) install `gitcrawl` if missing (skipped if already on PATH); (5) print a recap of the actions taken.
|
|
362
|
+
- **Restart required:** No. Triage v1 is a new opt-in surface; existing agent sessions continue to work without any awareness of the cache. Future sessions will see the new `task triage:*` targets in `task --list` once the parent `Taskfile.yml` `includes:` block resolves the four fragment files.
|
|
363
|
+
- **Commands:**
|
|
364
|
+
- `task triage:bootstrap` (one-time install, ~5 min for ~200 open issues -- mostly the cache populate step). The `triage:bootstrap` colon-form is wired as a top-level alias by Story 6 and works immediately after this PR merges.
|
|
365
|
+
- The remaining commands ship as **namespaced** targets via the parent Taskfile `includes:` block. Use the `<namespace>:<task>` form against the include key:
|
|
366
|
+
- `task triage-cache:cache` / `task triage-cache:show <N>` (Story 1)
|
|
367
|
+
- `task triage-actions:accept <N>` / `task triage-actions:reject <N> -- --reason <r>` / `task triage-actions:defer <N>` / `task triage-actions:needs-ac <N>` / `task triage-actions:status <N>` / `task triage-actions:history <N>` (Story 3)
|
|
368
|
+
- `task triage-bulk:bulk-accept` / `task triage-bulk:bulk-reject` / `task triage-bulk:refresh-active` etc. with `--label` / `--author` / `--age-days` filters (Story 4)
|
|
369
|
+
- The shorthand `task triage:cache` / `task triage:accept <N>` / etc. forms are intentionally NOT wired in Story 6 because go-task v3 cannot share an `includes:` namespace key across multiple files; consolidating top-level aliases into a single `triage:*` surface is tracked as a follow-up cleanup PR after the four-fragment cascade has fully landed and the inner task names are stable on master. Use the namespaced forms above until that follow-up ships.
|
|
370
|
+
|
|
371
|
+
### What changes for consumers
|
|
372
|
+
|
|
373
|
+
- **Additive nature.** Nothing existing breaks. The refinement skill's Phase 0 (Story 5) auto-skips when the cache is empty, so a consumer who never runs `task triage:bootstrap` sees the same v0.24.0 refinement experience.
|
|
374
|
+
- **Opt-in path is fast.** `task triage:bootstrap` finishes in ~5 minutes for a ~200-issue corpus. Larger corpora scale linearly with `gh issue list` throughput. The bootstrap is interruptible -- a Ctrl-C mid-populate leaves `.deft-cache/` in a partial state that the next run completes idempotently.
|
|
375
|
+
- **Gitignore default.** `.deft-cache/` is gitignored by default. The bootstrap step (3) ensures the line is present. See [docs/privacy-nfr.md](../docs/privacy-nfr.md) for the privacy contract that motivates the default.
|
|
376
|
+
- **Opt-in commit-cache contract.** Consumers who want to commit the cache for shared-cache scenarios MUST manually edit `.gitignore` to comment out the `.deft-cache/` line. Deft tooling will not perform this edit automatically -- the manual step is the deliberate-action gate. See `NFR-2` in [docs/privacy-nfr.md](../docs/privacy-nfr.md).
|
|
377
|
+
- **Quarantine on the cache write path.** Cached issue bodies are passed through `quarantine_body` (Story 1) before being written to `.deft-cache/issues/<owner>-<repo>/<N>.md`. Headings whose text matches imperative tokens (`STEP`, `TASK:`, `IMPORTANT:`, etc.) are wrapped in fenced code blocks with the `quarantined` info string so downstream LLM consumers can treat the enclosed bytes as untrusted user input. See [docs/quarantine-spec.md](../docs/quarantine-spec.md) for the full algorithm + escape-hatch overrides.
|
|
378
|
+
- **Private-repo body content.** Bodies from private repos are stored verbatim on the local filesystem under `.deft-cache/`. The framework never transmits cache contents externally. Operators in regulated environments should review NFR-3, NFR-4, NFR-5 in `docs/privacy-nfr.md`.
|
|
379
|
+
|
|
380
|
+
### Rollback
|
|
381
|
+
|
|
382
|
+
The entire triage v1 opt-in is reversible:
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
rm -rf .deft-cache/
|
|
386
|
+
# remove the `.deft-cache/` line from .gitignore
|
|
387
|
+
rm -rf vbrief/.eval/candidates.jsonl
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
This returns the project to its pre-bootstrap state. Existing scope vBRIEFs in `vbrief/proposed/` / `vbrief/pending/` / `vbrief/active/` are untouched -- the audit log only tracks decisions, not the vBRIEFs themselves.
|
|
391
|
+
|
|
392
|
+
### References
|
|
393
|
+
|
|
394
|
+
- [`docs/quarantine-spec.md`](../docs/quarantine-spec.md) -- formal spec for the #583 injection-quarantine algorithm consumed by Story 1's cache writer.
|
|
395
|
+
- [`docs/privacy-nfr.md`](../docs/privacy-nfr.md) -- privacy contract for `.deft-cache/` (gitignore default, opt-in commit path, private-repo body treatment).
|
|
396
|
+
- [#845](https://github.com/deftai/directive/issues/845) -- pre-ingest triage workflow umbrella.
|
|
397
|
+
- [#583](https://github.com/deftai/directive/issues/583) -- original injection-quarantine specification.
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## From pre-#768 AGENTS.md → managed-section AGENTS.md
|
|
402
|
+
|
|
403
|
+
- **Applies when:** `./AGENTS.md` exists at your project root AND does **not** contain the `<!-- deft:managed-section v1 -->` and `<!-- /deft:managed-section -->` sentinel markers. This is the canonical pre-#768 state -- the file pre-dates the Deft-managed-section contract added in v0.20.0 (#768) -- and is reported as `agents-md=missing` by `.deft/core/run gate`. (Distinct from `agents-md=absent`, which means no `AGENTS.md` exists at all.)
|
|
404
|
+
- **Safe to auto-run:** Yes. `.deft/core/run agents:refresh` performs a **one-time legacy migration**: your existing `AGENTS.md` content is preserved verbatim ABOVE the rendered managed-section block (separated by one blank line). The framework only ever owns the bytes between the two sentinel markers; content outside that bracketed region is never modified. Run `.deft/core/run agents:refresh --dry-run` first to preview the planned change, or `.deft/core/run agents:refresh --check` to interrogate the current state without writing.
|
|
405
|
+
- **Restart required:** Yes -- after the managed section is appended, the agent's current session still holds the pre-#768 `AGENTS.md` in context. Start a new agent session so the refreshed `AGENTS.md` (Implementation Intent Gate, Branch Policy Disclosure, Pre-Cutover Check, etc.) is loaded from a clean context.
|
|
406
|
+
- **Commands:**
|
|
407
|
+
- `python .deft/core/run agents:refresh --dry-run` (preview; never writes)
|
|
408
|
+
- `python .deft/core/run agents:refresh` (apply -- one-time append for state=`missing`, byte-replace for state=`stale`, no-op for state=`current`, fresh write for state=`absent`)
|
|
409
|
+
- `python .deft/core/run upgrade` (records the framework version in `vbrief/.deft-version` AND chains into `agents:refresh` -- equivalent end state to running both above)
|
|
410
|
+
|
|
411
|
+
### What `agents:refresh` does on a pre-#768 file
|
|
412
|
+
|
|
413
|
+
The gate (`.deft/core/run gate`) classifies every project's `AGENTS.md` into one of four states; pre-#768 files land in `missing`:
|
|
414
|
+
|
|
415
|
+
- `current` -- markers present and bracketed bytes match the rendered template. No-op.
|
|
416
|
+
- `stale` -- markers present but bracketed bytes have drifted from the rendered template. Byte-replace the bracketed region in place.
|
|
417
|
+
- `missing` -- file exists but no markers (pre-#768 legacy file). **One-time append** of the rendered managed section, preserving existing content verbatim above the markers.
|
|
418
|
+
- `absent` -- file does not exist. Create from the rendered template.
|
|
419
|
+
|
|
420
|
+
### Long-term contract: sentinel-only rewrite
|
|
421
|
+
|
|
422
|
+
After the one-time legacy migration, every subsequent `.deft/core/run agents:refresh` against the same project follows a **sentinel-only-rewrite** contract: the framework reads only the bytes between `<!-- deft:managed-section v1 -->` and `<!-- /deft:managed-section -->`, replaces them in place when the rendered template drifts (`stale` state), and never touches content above or below those markers. Hand-authored notes, custom rules, project-specific gates, and any text that lived in your `AGENTS.md` before the one-time append survive every future framework upgrade verbatim.
|
|
423
|
+
|
|
424
|
+
The contract is byte-stable by construction:
|
|
425
|
+
|
|
426
|
+
- `agents:refresh --check` exits 0 only when the bracketed bytes match the rendered template byte-for-byte; this is the regression guard against silent drift.
|
|
427
|
+
- The bracketed region is the SOLE byte sequence the framework owns. Edits inside the markers are not preserved across upgrades; edit the consumer-section above or below the markers instead.
|
|
428
|
+
- The migration is idempotent: re-running `.deft/core/run agents:refresh` against an already-migrated file is a no-op.
|
|
429
|
+
|
|
430
|
+
### References
|
|
431
|
+
|
|
432
|
+
- [`templates/agents-entry.md`](./templates/agents-entry.md) -- the canonical rendered managed-section template; this is the source of the bytes that `.deft/core/run agents:refresh` writes between the sentinel markers.
|
|
433
|
+
- [`QUICK-START.md`](./QUICK-START.md) Case G -- agent-prescriptive coverage of the same scenario for agents that read `QUICK-START.md` (rather than invoking `.deft/core/run agents:refresh` directly).
|
|
434
|
+
- [#768](https://github.com/deftai/directive/issues/768) -- the universal upgrade gate that introduced the managed-section markers and the `agents:refresh` reference implementation.
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## From any pre-v0.20 version → v0.20.0
|
|
439
|
+
|
|
440
|
+
- **Applies when:** `.deft/core/run gate` reports `precutover=SPECIFICATION.md,PROJECT.md` (or any subset thereof) AND/OR `agents-md=missing`. The presence of legacy `SPECIFICATION.md` / `PROJECT.md` without the `<!-- deft:deprecated-redirect -->` sentinel is the canonical pre-cutover signal.
|
|
441
|
+
- **Safe to auto-run:** No -- `task migrate:vbrief` rewrites `SPECIFICATION.md` and `PROJECT.md` into deprecation-redirect stubs and creates lifecycle folders; the operator must review the dry-run output and acknowledge the rewrite. `--dry-run` is recommended on any non-trivial project before the live run.
|
|
442
|
+
- **Restart required:** Yes -- the agent's current session still holds stale rules from the previous `AGENTS.md`. After cleanup commands complete, stop the session and start a fresh one so the rewritten `AGENTS.md` and v0.20 skills are loaded from a clean context.
|
|
443
|
+
- **Commands:**
|
|
444
|
+
- `task migrate:vbrief --dry-run` (preview)
|
|
445
|
+
- `task migrate:vbrief` (apply)
|
|
446
|
+
- `.deft/core/run upgrade` (writes `vbrief/.deft-version` AND now refreshes the AGENTS.md managed section in one step per #768)
|
|
447
|
+
- `.deft/core/run agents:refresh` (idempotent; runs implicitly via `.deft/core/run upgrade` -- only invoke directly if you skipped that step)
|
|
448
|
+
- `task roadmap:render` / `task project:render` / `task prd:render -- --force` (regenerate exports)
|
|
449
|
+
- `task check` (verify)
|
|
450
|
+
|
|
451
|
+
### Remote probe (#801)
|
|
452
|
+
|
|
453
|
+
- **Applies when:** the periodic remote-version probe (added in this section's source release) prints a `⚠ Upstream directive v<N> is available (you are on v<M>)` warn line below the existing recorded-vs-current banner, OR `task framework:check-updates` exits non-zero (status `BEHIND`).
|
|
454
|
+
- **Safe to auto-run:** Yes for the probe itself (read-only `git ls-remote --tags --refs <upstream>`, never mutates project state, throttled 24h per tag, opt-out via `DEFT_NO_NETWORK=1`). The remediation -- pulling the upstream submodule -- is NOT auto-run; the operator decides when to update.
|
|
455
|
+
- **Restart required:** No for the probe. Once you actually update the framework (refresh the `./deft` submodule), the standard "start a new agent session" rule from the recorded-vs-current upgrade flow applies.
|
|
456
|
+
- **Commands:**
|
|
457
|
+
- `task framework:check-updates` (synchronous probe, exit 1 on BEHIND; pass `-- --force` to bypass the 24h throttle and `-- --json` for machine-parseable output)
|
|
458
|
+
- `git submodule update --remote --merge deft && git add deft && git commit -m "chore(deft): bump submodule"` (canonical update path -- mirrors `skills/deft-directive-sync/SKILL.md` Phase 2)
|
|
459
|
+
- `.deft/core/run upgrade` (after the bump, to record the new framework version in `vbrief/.deft-version` and refresh the AGENTS.md managed section)
|
|
460
|
+
- `DEFT_NO_NETWORK=1 task <anything>` (CI / air-gapped opt-out: probe short-circuits before any subprocess call)
|
|
461
|
+
|
|
462
|
+
**What changed:** Deft moved from a flat document model (`SPECIFICATION.md`, `PROJECT.md`, `ROADMAP.md` as authoritative) to a **vBRIEF-centric model** with lifecycle folders. All skills were renamed from `deft-*` to `deft-directive-*`.
|
|
463
|
+
|
|
464
|
+
### One-paragraph summary
|
|
465
|
+
|
|
466
|
+
After you update `deft/` to v0.20.0, `vbrief/*.vbrief.json` files are the source of truth; the familiar `PRD.md`, `SPECIFICATION.md`, and `ROADMAP.md` are **rendered views** generated by `task *:render`. Scope vBRIEFs live in lifecycle folders (`proposed/`, `pending/`, `active/`, `completed/`, `cancelled/`). Every legacy skill path (`skills/deft-sync/`, `skills/deft-setup/`, …) now contains a small redirect stub pointing at `deft/QUICK-START.md`, which rewrites your stale `AGENTS.md` and runs migration. The deft framework itself detects the state and tells your agent what to do.
|
|
467
|
+
|
|
468
|
+
### Upgrade steps
|
|
469
|
+
|
|
470
|
+
1. **Update the framework.** Pick whichever matches how you installed deft:
|
|
471
|
+
- **Submodule:** `cd deft && git fetch && git checkout v0.20.0 && cd ..` then `git add deft && git commit -m "chore(deft): bump to v0.20.0"`.
|
|
472
|
+
- **Installer binary:** run the new installer against your existing project directory; it updates the clone and appends any new skill thin pointers idempotently.
|
|
473
|
+
- **Direct clone:** `cd deft && git pull --rebase && git checkout v0.20.0`.
|
|
474
|
+
2. **Have your agent read `deft/QUICK-START.md` and follow it.** Example prompt: *"Read `deft/QUICK-START.md` and follow it."* QUICK-START detects your project state and refreshes `AGENTS.md` idempotently; if it needs to rewrite the Deft-managed section or run migration, it tells you and instructs your next step.
|
|
475
|
+
3. **Run migration** (if QUICK-START asks for it): `task migrate:vbrief`. See [docs/BROWNFIELD.md](./docs/BROWNFIELD.md) for a detailed walkthrough of what migration does and how to preserve existing content.
|
|
476
|
+
4. **Regenerate rendered exports.** v0.20.0's `task migrate:vbrief` does not yet auto-invoke the renderers at the end (tracked: [#630](https://github.com/deftai/directive/issues/630), slated for v0.21). Run them manually once after migration so `ROADMAP.md` and any pre-existing `PRD.md` reflect the migrated `vbrief/` source of truth:
|
|
477
|
+
```bash
|
|
478
|
+
task roadmap:render
|
|
479
|
+
task project:render # refresh PROJECT-DEFINITION items registry
|
|
480
|
+
task prd:render -- --force # only if you previously maintained a PRD.md
|
|
481
|
+
# task spec:render # optional; re-emits SPECIFICATION.md from narratives
|
|
482
|
+
```
|
|
483
|
+
The `deft-directive-pre-pr` skill auto-renders `PRD.md` / `SPECIFICATION.md` at Phase 3b on every PR, so you only need to run these explicitly once post-migration. `ROADMAP.md` is not covered by Phase 3b auto-render.
|
|
484
|
+
5. **Record the framework version** so the CLI upgrade gate stops warning on every invocation: `.deft/core/run upgrade` writes `vbrief/.deft-version`.
|
|
485
|
+
6. **Start a new agent session.** Your current session still holds stale rules from the previous `AGENTS.md`. Close the tab / session and open a new one; the agent will read the refreshed `AGENTS.md` and v0.20 skills on its own.
|
|
486
|
+
7. **Verify.** Run `task check` -- the full pre-commit pipeline (fmt + lint + typecheck + tests + vbrief validation + link check) must be green. If `task vbrief:validate` warns about `SPECIFICATION.md` or `PROJECT.md`, the deprecation redirect stubs were not written correctly; re-run `task migrate:vbrief` or patch the stubs to include the `<!-- deft:deprecated-redirect -->` line on the first line.
|
|
487
|
+
|
|
488
|
+
### Upgrade safety
|
|
489
|
+
|
|
490
|
+
~ When running `task migrate:vbrief` against a non-trivial project for the first time, test it on a fork or a clean working copy before applying it to your primary checkout. The migration is designed to be idempotent and preserves existing narratives, but real-world repos vary -- exercising the migration once against a disposable copy lets you review the redirect stubs, lifecycle folder contents, and `task check` output before accepting the changes.
|
|
491
|
+
|
|
492
|
+
### What to expect
|
|
493
|
+
|
|
494
|
+
- Your `SPECIFICATION.md` and `PROJECT.md` are replaced with short redirect stubs containing `<!-- deft:deprecated-redirect -->` on the first line. Existing content is migrated into `vbrief/specification.vbrief.json` narratives + `vbrief/pending/` scope vBRIEFs + `vbrief/PROJECT-DEFINITION.vbrief.json` narratives. `ROADMAP.md` remains an **actively rendered view** (not a deprecation redirect) -- it is backed up to `ROADMAP.premigrate.md` and is regenerated by `task roadmap:render` from the migrated scope vBRIEFs in `vbrief/pending/` and `vbrief/completed/`.
|
|
495
|
+
- `.md` files continue to exist as **rendered views**, generated on demand via `task spec:render`, `task prd:render`, `task roadmap:render`. ⊗ Edit them directly — your changes are overwritten on the next render; edit the underlying `.vbrief.json` instead.
|
|
496
|
+
- Skills live under new `deft-directive-*` directory names. Legacy `skills/deft-*/SKILL.md` files contain small redirect stubs that point agents at `deft/QUICK-START.md`; they exist for one release cycle so v0.19 `AGENTS.md` files that still reference old paths keep working until you re-run QUICK-START.
|
|
497
|
+
- The CLI (`.deft/core/run`) now has a **non-fatal upgrade gate** (issue #410). After updating, the gate warns once per invocation until you run `.deft/core/run upgrade` or `task migrate:vbrief`. Interactive sessions get a `Continue anyway? [y/N]` prompt; non-interactive sessions (CI, cloud agents) warn and continue.
|
|
498
|
+
- **New `task issue:ingest`** (#454) -- materialise GitHub issues as scope vBRIEFs in `vbrief/proposed/` (single-issue mode `task issue:ingest -- <N>` or bulk `task issue:ingest -- --all [--label L] [--status S] [--dry-run]`). Deduplicates against existing origin-provenance references so the `task reconcile:issues` unlinked section stops growing monotonically post-GA.
|
|
499
|
+
|
|
500
|
+
### Troubleshooting
|
|
501
|
+
|
|
502
|
+
- **Agent says it can't find `deft/skills/deft-sync/SKILL.md`:** that is a stale v0.19 `AGENTS.md` path. Tell your agent: *"Read `deft/QUICK-START.md` and follow it."* If the dummy redirect stub is read, it also points at QUICK-START.md.
|
|
503
|
+
- **`task check` fails on `task vbrief:validate`:** typical causes are filename convention (must be `YYYY-MM-DD-<lowercase-slug>.vbrief.json`), folder/status mismatch (use `task scope:activate|complete|cancel|restore|block|unblock` to move files), or missing `overview` / `tech stack` narrative keys on `PROJECT-DEFINITION.vbrief.json`.
|
|
504
|
+
- **CLI keeps warning about version drift:** run `.deft/core/run upgrade` to record the current framework version in `vbrief/.deft-version`.
|
|
505
|
+
- **"My existing `AGENTS.md` additions got wiped":** QUICK-START refreshes only the Deft-managed section (bounded by the `deft/main.md` sentinel region). If you saw content outside that region change, please file an issue with `discovered-during-402` so we can tighten the detection.
|
|
506
|
+
|
|
507
|
+
### References
|
|
508
|
+
|
|
509
|
+
- [docs/BROWNFIELD.md](./docs/BROWNFIELD.md) — detailed brownfield adoption / migration walkthrough.
|
|
510
|
+
- [QUICK-START.md](./QUICK-START.md) — agent-facing bootstrap + upgrade detection.
|
|
511
|
+
- [vbrief/vbrief.md](./vbrief/vbrief.md) — canonical vBRIEF file taxonomy.
|
|
512
|
+
- [glossary.md](./glossary.md) — canonical v0.20 vocabulary (Scope vBRIEF, lifecycle folder, canonical narrative keys, rendered export, source of truth, ...).
|
|
513
|
+
- [CHANGELOG.md](../CHANGELOG.md) — full v0.20.0 change list.
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
Future upgrade sections will be prepended here as new releases ship. Each section starts with `## From <prev> → <new>` and follows the same shape: summary, steps, expectations, troubleshooting, references.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
|
|
2
|
+
<!-- Purpose: rendered coding rules -->
|
|
3
|
+
<!-- Source of truth: packs/rules/rules-pack-0.1.json -->
|
|
4
|
+
<!-- Regenerate with: task packs:render -->
|
|
5
|
+
<!-- Edit the source, not this file. Slice instead of loading every coding doc: task packs:slice rules by-tier --tier <TIER> (or by-domain, list) -->
|
|
6
|
+
|
|
7
|
+
# Build Output Validation
|
|
8
|
+
|
|
9
|
+
Rules for validating build output artifacts after custom build scripts run.
|
|
10
|
+
|
|
11
|
+
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
12
|
+
|
|
13
|
+
**⚠️ See also**:
|
|
14
|
+
- [coding.md](../coding/coding.md) — Build Automation section
|
|
15
|
+
- [testing.md](../coding/testing.md) — Build Output Tests section
|
|
16
|
+
|
|
17
|
+
## Artifact Verification
|
|
18
|
+
|
|
19
|
+
- ! After running a custom build script, verify expected output files exist and are non-empty
|
|
20
|
+
- ! When a build script copies/transforms non-compiled assets (manifests, configs, extension metadata), verify those files are present and structurally valid in the output directory
|
|
21
|
+
- ! A build that exits 0 but produces stale or incomplete artifacts is a silent failure — treat it as a build failure (#105)
|
|
22
|
+
- ~ Verify required keys/fields are present in structured output files (JSON manifests, config files, etc.)
|
|
23
|
+
- ⊗ Assume a zero-exit-code build produced correct output without checking
|
|
24
|
+
|
|
25
|
+
## Smoke Tests
|
|
26
|
+
|
|
27
|
+
- ~ Build scripts that produce `dist/` artifacts have a smoke test verifying expected output files exist and contain expected content
|
|
28
|
+
- ~ See [testing.md](../coding/testing.md#build-output-tests) for test type guidance and examples
|