@deftai/directive-content 0.61.2 → 0.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QUICK-START.md +12 -15
- package/Taskfile.yml +6 -25
- package/UPGRADING.md +42 -12
- package/docs/BROWNFIELD.md +7 -3
- package/package.json +1 -1
- package/packs/skills/skills-pack-0.1.json +5 -5
- package/skills/deft-directive-build/SKILL.md +3 -3
- package/skills/deft-directive-refinement/SKILL.md +2 -0
- package/skills/deft-directive-setup/SKILL.md +17 -48
- package/skills/deft-directive-sync/SKILL.md +4 -4
- package/skills/deft-directive-triage/SKILL.md +2 -0
- package/tasks/core.yml +9 -123
- package/tasks/framework.yml +15 -19
- package/tasks/migrate.yml +5 -62
- package/tasks/ts.yml +2 -293
- package/tasks/umbrella.yml +30 -0
- package/templates/agent-prompt-preamble.md +14 -0
- package/templates/agents-entry.md +10 -1
- package/tasks/ci.yml +0 -57
|
@@ -76,11 +76,11 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
76
76
|
|
|
77
77
|
! If pre-cutover or strategy-nonconformant state is detected, **stop immediately** and display an actionable message that cites the exact validator:
|
|
78
78
|
|
|
79
|
-
> "This project was generated with pre-v0.20 or non-conformant strategy output. Run the deterministic validator and follow its remediation: `task verify-strategy-output` (works in source and after `deft` package install) or `python .deft/core/scripts/validate_strategy_output.py --project-root
|
|
79
|
+
> "This project was generated with pre-v0.20 or non-conformant strategy output. Run the deterministic validator and follow its remediation: `task verify-strategy-output` (works in source and after `deft` package install) or `python .deft/core/scripts/validate_strategy_output.py --project-root .`. For document-model migration, follow UPGRADING.md § Frozen pre-v0.20 document-model migration (#2068): pin v0.59.0, then run `task migrate:vbrief` from that payload. Otherwise `task project:render` / strategy re-run as indicated."
|
|
80
80
|
|
|
81
81
|
! Include specific details about what was detected (the validator output is authoritative):
|
|
82
82
|
|
|
83
|
-
- Legacy specification.vbrief.json or missing lifecycle folders: "
|
|
83
|
+
- Legacy specification.vbrief.json or missing lifecycle folders: "Follow the frozen v0.59.0 migrator path (#2068) or run `task migrate:preflight` for current-release guidance"
|
|
84
84
|
- Non-date-prefixed vBRIEFs: "Re-run the emitting strategy after the v0.20 migrations (#1166 s1+s2+...) or manually rename files to `YYYY-MM-DD-<slug>.vbrief.json` and `task scope:promote`"
|
|
85
85
|
- Missing `PROJECT-DEFINITION.vbrief.json`: "Run `task project:render` to generate the project definition"
|
|
86
86
|
- `SPECIFICATION.md` / `PROJECT.md` without sentinel: the classic pre-cutover messages
|
|
@@ -88,7 +88,7 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
88
88
|
|
|
89
89
|
! After the validator reports clean, re-run this guard before continuing.
|
|
90
90
|
|
|
91
|
-
⊗ Proceed with build when pre-cutover or strategy-nonconformant artifacts are detected -- always redirect to migration first (or run the validator) and surface the exact remediation.
|
|
91
|
+
⊗ Proceed with build when pre-cutover or strategy-nonconformant artifacts are detected -- always redirect to the frozen migration path first (or run the validator) and surface the exact remediation.
|
|
92
92
|
⊗ Silently ignore these artifacts or guess at fixes -- the validator (wired into `task check` and this guard) is the deterministic gate.
|
|
93
93
|
|
|
94
94
|
## USER.md Gate
|
|
@@ -317,6 +317,8 @@ The task scans every vBRIEF with a GitHub-backed reference (whether the referenc
|
|
|
317
317
|
|
|
318
318
|
! When the refinement session files a new umbrella issue (or surfaces one whose current-shape comment is missing), file the umbrella then file its `## Current shape (as of pass-N)` comment per `## Umbrella current-shape convention` in `AGENTS.md` (#1152) -- the edit-in-place comment is the canonical surface every subsequent design pass updates.
|
|
319
319
|
|
|
320
|
+
! Before reporting an umbrella or epic's current status to the operator (what is done, what blocks, wave order), fetch `repos/<owner>/<repo>/issues/<N>/comments` via REST, read the `## Current shape (as of pass-N)` comment and any linked context/`LockedDecisions` vBRIEF — never conclude status from the issue body alone (claim-cites-state-surface, #2066).
|
|
321
|
+
|
|
320
322
|
~ Issue-label hygiene for any umbrella or child issue this skill files: before creating issues, inspect the target repo's existing labels with `gh label list` or the labels API; choose one or more suitable existing labels when practical, or explicitly note that no label was applied. This is a recommendation, not a gate -- do not block issue creation solely because no label fits, and do not invent ad hoc labels outside the repo's existing label set.
|
|
321
323
|
|
|
322
324
|
! When a refinement pass produces a slicing event (rare but possible -- e.g. a design pass on an existing umbrella files N additional Wave-N child issues), record the cohort in `vbrief/.eval/slices.jsonl` via `scripts/slice_record.py::write_slice(...)` with `actor="skill:refinement"` immediately after the children are filed (#1132 / D13). Same call shape as `skills/deft-directive-gh-slice/SKILL.md` Step 6. The cohort record is what makes `task triage:audit --orphans` able to detect Wave-2+ children whose umbrella closes prematurely; without it the production-side drift this surface guards against re-fires. Skip when the pass produced no new child cohort (e.g. a pure re-prioritization).
|
|
@@ -12,12 +12,6 @@ description: >-
|
|
|
12
12
|
<!-- Regenerate with: task packs:render -->
|
|
13
13
|
<!-- Edit the source, not this file. Slice instead of loading every SKILL.md: task packs:slice skills by-trigger --trigger <kw> (or list) -->
|
|
14
14
|
|
|
15
|
-
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
|
|
16
|
-
<!-- Purpose: rendered skill -->
|
|
17
|
-
<!-- Source of truth: packs/skills/skills-pack-0.1.json -->
|
|
18
|
-
<!-- Regenerate with: task packs:render -->
|
|
19
|
-
<!-- Edit the source, not this file. Slice instead of loading every SKILL.md: task packs:slice skills by-trigger --trigger <kw> (or list) -->
|
|
20
|
-
|
|
21
15
|
# Deft Directive Setup
|
|
22
16
|
|
|
23
17
|
Agent-driven alternative to `.deft/core/run bootstrap && .deft/core/run project && .deft/core/run spec`.
|
|
@@ -44,45 +38,24 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
44
38
|
|
|
45
39
|
### Action on Detection
|
|
46
40
|
|
|
47
|
-
! If pre-cutover state is detected, **stop immediately** and display an actionable message:
|
|
41
|
+
! If pre-cutover state is detected, **stop immediately** and display an actionable message pointing at the frozen-release migration path (#2068):
|
|
48
42
|
|
|
49
|
-
> "This project uses the pre-v0.20 document model.
|
|
43
|
+
> "This project uses the pre-v0.20 document model. Current npm releases no longer ship in-product `task migrate:vbrief`. Follow UPGRADING.md § Frozen pre-v0.20 document-model migration: pin framework v0.59.0 (frozen Go installer or git tag), install Python 3.11+ and uv, run `task migrate:vbrief` once from that payload, then upgrade to current npm."
|
|
50
44
|
|
|
51
45
|
! Include specific details about what was detected:
|
|
52
46
|
|
|
53
|
-
- Missing lifecycle folders: "
|
|
54
|
-
- `SPECIFICATION.md` with real content: "SPECIFICATION.md contains non-redirect content
|
|
55
|
-
- `PROJECT.md` with real content: "PROJECT.md contains non-redirect content
|
|
56
|
-
- Missing `PROJECT-DEFINITION.vbrief.json`: "Run `task project:render`
|
|
57
|
-
|
|
58
|
-
### Environment Preflight (before asking to run migration)
|
|
47
|
+
- Missing lifecycle folders: "Create lifecycle folders via the frozen-release migrator on v0.59.0, or manually add `vbrief/{proposed,pending,active,completed,cancelled}/` after migrating narratives"
|
|
48
|
+
- `SPECIFICATION.md` with real content: "SPECIFICATION.md contains non-redirect content — migrate on pinned v0.59.0 before upgrading to current npm"
|
|
49
|
+
- `PROJECT.md` with real content: "PROJECT.md contains non-redirect content — migrate on pinned v0.59.0 before upgrading to current npm"
|
|
50
|
+
- Missing `PROJECT-DEFINITION.vbrief.json`: "Run `task project:render` after document-model migration completes"
|
|
59
51
|
|
|
60
|
-
|
|
52
|
+
### Preflight (optional diagnostic)
|
|
61
53
|
|
|
62
|
-
Run
|
|
54
|
+
~ Run `task migrate:preflight` to confirm pre-cutover state and print the frozen-release guidance. It does **not** run migration.
|
|
63
55
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- If present: the primary command works from the project root -- canonical invocation is `task migrate:vbrief`.
|
|
68
|
-
- If absent: the consumer `Taskfile.yml` does not include `deft/Taskfile.yml`. Fall back to the explicit-taskfile invocation `task -t ./deft/Taskfile.yml migrate:vbrief` and tell the user: "`task migrate:vbrief` is not resolvable from the project root. I will use the fallback invocation `task -t ./deft/Taskfile.yml migrate:vbrief`, which reads the task directly from the framework Taskfile. To make the primary command work in future, add an include for `deft/Taskfile.yml` to your project `Taskfile.yml` — see `deft/main.md` § Publishing deft tasks in your project root."
|
|
69
|
-
3. **`uv` on PATH** -- the migrator runs `uv run python scripts/migrate_vbrief.py`. Check `uv --version` (or equivalent): if it fails, point the user at the uv install docs (`https://docs.astral.sh/uv/`) and stop; migration cannot run without `uv`.
|
|
70
|
-
4. **Migration script present** -- check `deft/scripts/migrate_vbrief.py` exists on disk. If absent, the `deft/` checkout is incomplete or came from a pre-v0.20 framework version; point the user at `deft/QUICK-START.md` (framework refresh guidance) and stop.
|
|
71
|
-
|
|
72
|
-
! Report each preflight check's result to the user (e.g. "✓ task migrate:vbrief resolvable", "✗ uv not on PATH — install from https://docs.astral.sh/uv/") BEFORE prompting for yes/no approval. If any check fails, do NOT offer to run migration until it is resolved.
|
|
73
|
-
|
|
74
|
-
⊗ Skip preflight and immediately ask "Would you like me to run `task migrate:vbrief` now?" -- preflight catches preventable errors (unresolvable task, missing `uv`, missing script) before the user commits to running migration.
|
|
75
|
-
⊗ Propose an install-step mutation that writes `migrate:vbrief` content into the consumer Taskfile. The supported publish mechanism is the `includes: deft: deft/Taskfile.yml` pattern documented in `deft/main.md` § Publishing deft tasks in your project root; inline Taskfile mutation is explicitly out of scope (per #506 D6).
|
|
76
|
-
|
|
77
|
-
### Prompt and Run
|
|
78
|
-
|
|
79
|
-
! After preflight results are reported (and all checks pass), ask the user: "Would you like me to run `task migrate:vbrief` now?"
|
|
80
|
-
- If yes: run the migration command (use the fallback invocation `task -t ./deft/Taskfile.yml migrate:vbrief` if the preflight resolvability check found the primary task unresolvable). Then re-run the pre-cutover detection guard to verify clean state before proceeding.
|
|
81
|
-
- If no: stop and let the user handle migration manually.
|
|
82
|
-
|
|
83
|
-
⊗ Proceed with setup phases when pre-cutover artifacts are detected -- always redirect to migration first.
|
|
84
|
-
⊗ Silently ignore pre-cutover artifacts -- the user must be informed with an actionable command to fix the state.
|
|
85
|
-
⊗ Display the migration diagnostic without offering to run it -- always ask the user if they want the agent to handle it (after preflight has passed).
|
|
56
|
+
⊗ Offer to run `task migrate:vbrief` from the current npm deposit — the migrator is not bundled on current releases (#2068).
|
|
57
|
+
⊗ Proceed with setup phases when pre-cutover artifacts are detected — always redirect to the frozen migration path first.
|
|
58
|
+
⊗ Silently ignore pre-cutover artifacts — the user must be informed with an actionable command to fix the state.
|
|
86
59
|
|
|
87
60
|
### Greenfield Projects (No Migration Needed)
|
|
88
61
|
|
|
@@ -96,19 +69,15 @@ Run these four checks, in order:
|
|
|
96
69
|
|
|
97
70
|
~ This is already handled by Phase 2 Output Path (creates `./vbrief/` and lifecycle subfolders) and Phase 3 Output (creates scope vBRIEFs in lifecycle folders). The guard ensures migrating projects are redirected before reaching these phases.
|
|
98
71
|
|
|
99
|
-
### Migration safety flags
|
|
100
|
-
|
|
101
|
-
`task migrate:vbrief` is destructive by default (it replaces `SPECIFICATION.md` and `PROJECT.md` with redirect stubs and rewrites `vbrief/`), but it carries four always-on / on-demand safety affordances so operators can preview, recover, and undo (#497, #506 D7). Agents offering to run migration MUST mention these and pick the right one for the operator's situation.
|
|
72
|
+
### Migration safety flags (frozen v0.59.0 release only)
|
|
102
73
|
|
|
103
|
-
|
|
104
|
-
- ! **`task migrate:vbrief -- --dry-run` (preview)**: prints the complete migration plan (every proposed backup, lifecycle folder, narrative ingestion, scope vBRIEF, and deprecation-redirect replacement) prefixed `DRYRUN` without writing any file. Exits 0 on success. Use this before running migration for the first time on an unfamiliar project.
|
|
105
|
-
- ! **Dirty-tree guard (always-on)**: if `git status --porcelain` is non-empty the migrator refuses to run and points the operator at `--force`. Keeps migration output separable from in-progress edits. Bypass with `task migrate:vbrief -- --force` only after confirming the operator has accepted the risk.
|
|
106
|
-
- ! **`task migrate:vbrief -- --rollback`**: restores every pre-cutover input from its `.premigrate.*` backup and removes the scope vBRIEFs and migration-report files a prior run created. Reads `vbrief/migration/safety-manifest.json` (written by the migrator). Refuses if any redirect stub has been edited since migration -- re-run with `--force` to overwrite those edits on purpose, or commit them before rolling back. Prompts for a yes/no confirmation unless `--force` is passed.
|
|
74
|
+
When guiding an operator through migration on the pinned release, mention the migrator safety affordances (#497, #506 D7):
|
|
107
75
|
|
|
108
|
-
|
|
76
|
+
- **`task migrate:vbrief -- --dry-run` (preview)** on v0.59.0
|
|
77
|
+
- **Dirty-tree guard** — migrator refuses when the working tree is dirty unless `--force`
|
|
78
|
+
- **`task migrate:vbrief -- --rollback`** on v0.59.0 to restore `.premigrate.*` backups
|
|
109
79
|
|
|
110
|
-
⊗ Offer
|
|
111
|
-
⊗ Suggest `git reset --hard` or manual file deletion as a recovery path when `--rollback` would do the right thing more safely.
|
|
80
|
+
⊗ Offer in-product migration from a current npm deposit — use the frozen path (#2068).
|
|
112
81
|
|
|
113
82
|
## Deterministic Questions Contract
|
|
114
83
|
|
|
@@ -58,11 +58,11 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
58
58
|
|
|
59
59
|
! If pre-cutover state is detected, display the actionable migration message, then **skip Phases 1-6** and proceed directly to Phase 7 with the Document Model line set to "pre-v0.20 (legacy)":
|
|
60
60
|
|
|
61
|
-
> "This project uses the pre-v0.20 document model.
|
|
61
|
+
> "This project uses the pre-v0.20 document model. Current npm releases no longer ship in-product `task migrate:vbrief` (#2068). Follow UPGRADING.md § Frozen pre-v0.20 document-model migration: pin framework v0.59.0, install Python 3.11+ and uv, run `task migrate:vbrief` once from that payload, then upgrade to current npm."
|
|
62
62
|
|
|
63
63
|
! Include specific details about what was detected:
|
|
64
64
|
|
|
65
|
-
- Missing lifecycle folders: "
|
|
65
|
+
- Missing lifecycle folders: "Create lifecycle folders via the frozen v0.59.0 migrator (#2068), or manually add `vbrief/{proposed,pending,active,completed,cancelled}/` after migrating narratives"
|
|
66
66
|
- `SPECIFICATION.md` with real content: "SPECIFICATION.md contains non-redirect content -- this file is deprecated; use scope vBRIEFs in `vbrief/` instead"
|
|
67
67
|
- `PROJECT.md` with real content: "PROJECT.md contains non-redirect content -- this file is deprecated; use `PROJECT-DEFINITION.vbrief.json` instead"
|
|
68
68
|
- Missing `PROJECT-DEFINITION.vbrief.json`: "Run `task project:render` to generate the project definition"
|
|
@@ -72,7 +72,7 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
72
72
|
|
|
73
73
|
! Include a **Document Model** line in the Phase 7 summary:
|
|
74
74
|
|
|
75
|
-
- Pre-cutover detected: "**Document Model**: pre-v0.20 (legacy) --
|
|
75
|
+
- Pre-cutover detected: "**Document Model**: pre-v0.20 (legacy) -- follow UPGRADING.md § Frozen pre-v0.20 document-model migration (#2068)"
|
|
76
76
|
- Post-cutover (lifecycle folders present, no stale artifacts): "**Document Model**: v0.20+ (vBRIEF-centric) -- OK"
|
|
77
77
|
- Post-cutover with tampered placeholders: "**Document Model**: v0.20+ with warnings -- SPECIFICATION.md or PROJECT.md contains non-redirect content"
|
|
78
78
|
|
|
@@ -122,7 +122,7 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
|
|
|
122
122
|
- `cancelled/`
|
|
123
123
|
2. ! Report any missing folders with a clear warning:
|
|
124
124
|
- "WARNING: vbrief/{folder}/ does not exist -- lifecycle structure is incomplete"
|
|
125
|
-
3. ~ If folders are missing, suggest
|
|
125
|
+
3. ~ If folders are missing, suggest `task migrate:preflight` and the frozen v0.59.0 migrator path (#2068), or creating them manually after migration
|
|
126
126
|
|
|
127
127
|
### 3b: PROJECT-DEFINITION.vbrief.json Validation
|
|
128
128
|
|
|
@@ -102,6 +102,8 @@ What would you like to do with this candidate?
|
|
|
102
102
|
4. ~ When the audit surfaces a stale acceptance (`accept` decision whose issue is no longer referenced by any `vbrief/active/`), surface it to the operator -- the typical fix is a fresh ingest via `task issue:ingest -- <N>` or a `task triage:reset <N>` if the acceptance was in error.
|
|
103
103
|
5. ⊗ Skip the Phase 4 audit -- silent exit leaves the operator without a record of what landed in `vbrief/proposed/` this session, which is the typical recurrence vector for "what did I just accept?" confusion.
|
|
104
104
|
|
|
105
|
+
! Before reporting an umbrella or epic's current status during triage (what is done, what blocks, wave order), fetch `repos/<owner>/<repo>/issues/<N>/comments` via REST, read the `## Current shape (as of pass-N)` comment and any linked context/`LockedDecisions` vBRIEF — never conclude status from the issue body alone (claim-cites-state-surface, #2066 / AGENTS.md #1152).
|
|
106
|
+
|
|
105
107
|
## Reversibility
|
|
106
108
|
|
|
107
109
|
! To undo a decision, run `task triage:reset <N>`. This writes a `reset` audit entry referencing the prior decision id; history is **never** deleted. `task triage:reset` is the canonical Layer 5 reversibility verb (resolves the V3 audit from 2026-05-13). After a reset, the candidate re-enters the untriaged group on the next `task triage:queue` render so it can be re-walked through Phase 3.
|
package/tasks/core.yml
CHANGED
|
@@ -1,136 +1,22 @@
|
|
|
1
1
|
version: '3'
|
|
2
2
|
|
|
3
|
-
# Maintainer-only
|
|
4
|
-
#
|
|
5
|
-
# pytest, ruff, black, and mypy run here via `uv run` for framework-source-repo
|
|
6
|
-
# pre-commit checks. This fragment is included from the root Taskfile with
|
|
7
|
-
# `internal: true` so `core:*` tasks are NOT listed or callable from the CLI on
|
|
8
|
-
# consumer installs — only `task check:framework-source` wires them as deps.
|
|
9
|
-
#
|
|
10
|
-
# Consumer `task check` dispatches to `check:consumer` (TS / deft verbs only).
|
|
11
|
-
# Do NOT add these tasks to the consumer check aggregate.
|
|
3
|
+
# Maintainer-only packaging lane (#1860). Build/clean dispatch the native
|
|
4
|
+
# TypeScript build-dist helper; Python/uv paths removed.
|
|
12
5
|
|
|
13
6
|
vars:
|
|
14
7
|
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
15
8
|
|
|
16
9
|
tasks:
|
|
17
|
-
validate:
|
|
18
|
-
desc: Validate all markdown files
|
|
19
|
-
env:
|
|
20
|
-
PYTHONUTF8: "1"
|
|
21
|
-
cmds:
|
|
22
|
-
- cmd: >-
|
|
23
|
-
uv --project "{{.DEFT_ROOT}}" run python -c "from pathlib import Path;
|
|
24
|
-
files=[f for f in sorted(Path('.').rglob('*.md')) if '.git' not in f.parts and 'backup' not in f.parts];
|
|
25
|
-
[print(f'\u2713 {f}') for f in files];
|
|
26
|
-
print(f'\u2713 All {len(files)} markdown files validated')"
|
|
27
|
-
|
|
28
|
-
test:
|
|
29
|
-
desc: Run test suite
|
|
30
|
-
cmds:
|
|
31
|
-
# #1474: tolerate a missing tests/ directory. The installer (#1482)
|
|
32
|
-
# prunes the vendored .deft/core/tests/ from the consumer deposit, so in
|
|
33
|
-
# a vendored consumer `task deft:check` -> framework check -> core:test
|
|
34
|
-
# would otherwise run `pytest tests/` against a now-absent directory and
|
|
35
|
-
# exit with a path error instead of 0 (blocking #1474 acceptance a1).
|
|
36
|
-
# A cross-platform pathlib guard (no bare shell conditional, per the
|
|
37
|
-
# AGENTS.md Windows rules) skips the run with a clear notice when tests/
|
|
38
|
-
# is absent; the framework's own repo (tests/ present) still runs the
|
|
39
|
-
# full suite unchanged. The check targets the same CWD-relative `tests`
|
|
40
|
-
# path pytest would run against, so it is correct regardless of CWD.
|
|
41
|
-
- cmd: >-
|
|
42
|
-
uv --project "{{.DEFT_ROOT}}" run python -c "import sys, subprocess;
|
|
43
|
-
from pathlib import Path;
|
|
44
|
-
_exists = Path('tests').exists();
|
|
45
|
-
print('no tests/ (vendored consumer) -- skipping') if not _exists else None;
|
|
46
|
-
sys.exit(subprocess.run([sys.executable, '-m', 'pytest', 'tests']).returncode if _exists else 0)"
|
|
47
|
-
|
|
48
|
-
test:coverage:
|
|
49
|
-
desc: Run tests with coverage (fails if < 85%)
|
|
50
|
-
cmds:
|
|
51
|
-
- uv --project "{{.DEFT_ROOT}}" run pytest tests/ --cov --cov-report=html
|
|
52
|
-
|
|
53
|
-
fmt:
|
|
54
|
-
desc: Format Python code
|
|
55
|
-
cmds:
|
|
56
|
-
- uv --project "{{.DEFT_ROOT}}" run ruff format .
|
|
57
|
-
- uv --project "{{.DEFT_ROOT}}" run black .
|
|
58
|
-
|
|
59
|
-
lint:
|
|
60
|
-
desc: Lint and type-check Python code
|
|
61
|
-
cmds:
|
|
62
|
-
- uv --project "{{.DEFT_ROOT}}" run ruff check .
|
|
63
|
-
# #1475: bring the local type-check gate to parity with CI. The CI
|
|
64
|
-
# Python job (.github/workflows/ci.yml) runs `mypy tests/`, but this
|
|
65
|
-
# local gate previously checked only run.py -- so a type error under
|
|
66
|
-
# tests/ shipped green locally (task check -> core:lint) and reddened
|
|
67
|
-
# master after merge. The tests/ tree is now part of the gate; run.py
|
|
68
|
-
# is retained for its pre-existing local-only coverage. Both surfaces
|
|
69
|
-
# share the [tool.mypy] config in pyproject.toml, including the
|
|
70
|
-
# tests.* override that relaxes disallow_untyped_defs while still
|
|
71
|
-
# failing on real type mismatches under tests/.
|
|
72
|
-
#
|
|
73
|
-
# #1474: the same vendored-consumer guard core:test uses. The installer
|
|
74
|
-
# (#1482) prunes the vendored .deft/core/tests/, and `task deft:check`
|
|
75
|
-
# runs core:lint too, so an unconditional `mypy run.py tests/` would
|
|
76
|
-
# fail on the now-absent tests/ path. The cross-platform pathlib guard
|
|
77
|
-
# (no bare shell conditional, per the AGENTS.md Windows rules) appends
|
|
78
|
-
# tests/ to the mypy target list only when it exists; run.py (always in
|
|
79
|
-
# the payload) stays checked either way.
|
|
80
|
-
- cmd: >-
|
|
81
|
-
uv --project "{{.DEFT_ROOT}}" run python -c "import sys, subprocess;
|
|
82
|
-
from pathlib import Path;
|
|
83
|
-
targets = ['run.py'] + (['tests'] if Path('tests').exists() else []);
|
|
84
|
-
sys.exit(subprocess.run([sys.executable, '-m', 'mypy', *targets]).returncode)"
|
|
85
|
-
|
|
86
|
-
|
|
87
10
|
build:
|
|
88
|
-
desc: Package framework for distribution (cross-platform via
|
|
89
|
-
|
|
90
|
-
|
|
11
|
+
desc: Package framework for distribution (cross-platform via TypeScript build-dist, #736 / #1860)
|
|
12
|
+
deps:
|
|
13
|
+
- task: :ts:build
|
|
91
14
|
cmds:
|
|
92
|
-
|
|
93
|
-
# stdlib tarfile / zipfile with a canonical exclude list and
|
|
94
|
-
# auto-selects tar.gz on Linux/macOS, zip on Windows. The previous
|
|
95
|
-
# platform-split shape had the Windows branch missing the exclude
|
|
96
|
-
# list, ingesting .git history and the prior dist/ artifact.
|
|
97
|
-
# Regression-guarded by tests/content/test_taskfile_zip_parity.py.
|
|
98
|
-
- uv --project "{{.DEFT_ROOT}}" run python "{{.DEFT_ROOT}}/scripts/build_dist.py" --version "{{.VERSION}}"
|
|
15
|
+
- node "{{.DEFT_ROOT}}/packages/core/dist/release/build-dist-runner.js" "{{.VERSION}}" "{{.DEFT_ROOT}}"
|
|
99
16
|
|
|
100
17
|
clean:
|
|
101
|
-
desc: Clean generated artifacts (cross-platform
|
|
102
|
-
env:
|
|
103
|
-
PYTHONUTF8: "1"
|
|
104
|
-
cmds:
|
|
105
|
-
# Single cross-platform dispatch (#736) -- mirrors the build target's
|
|
106
|
-
# simplification. Python's pathlib + shutil.rmtree handles the dist/
|
|
107
|
-
# directory removal identically on POSIX and Windows, replacing the
|
|
108
|
-
# prior rm -rf / Remove-Item duplication.
|
|
109
|
-
#
|
|
110
|
-
# The dist/ path is anchored at {{.DEFT_ROOT}} so `task clean` works
|
|
111
|
-
# the same way regardless of the operator's current working directory.
|
|
112
|
-
# The previous shape relied on `pathlib.Path('dist')` resolving against
|
|
113
|
-
# the inherited CWD, which silently no-ops when the operator runs
|
|
114
|
-
# `task -t tasks/core.yml clean` from a subdirectory (Greptile P2 on
|
|
115
|
-
# PR #773).
|
|
116
|
-
- cmd: >-
|
|
117
|
-
uv --project "{{.DEFT_ROOT}}" run python -c "import shutil, pathlib;
|
|
118
|
-
d = pathlib.Path(r'{{.DEFT_ROOT}}') / 'dist';
|
|
119
|
-
shutil.rmtree(d) if d.exists() else None;
|
|
120
|
-
print(f'Cleaned {d}')"
|
|
121
|
-
|
|
122
|
-
stats:
|
|
123
|
-
desc: Show framework statistics
|
|
18
|
+
desc: Clean generated dist/ artifacts (cross-platform, #736 / #1860)
|
|
124
19
|
cmds:
|
|
125
20
|
- cmd: >-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
sep='='*42;
|
|
129
|
-
dirs=[('Core files','core'),('Languages','languages'),('Interfaces','interfaces'),('Tools','tools'),('Templates','templates')];
|
|
130
|
-
counts=[(n,len(list(Path(d).glob('*.md')))) for n,d in dirs];
|
|
131
|
-
total=len([f for f in Path('.').rglob('*.md') if '.git' not in str(f) and 'backup' not in str(f)]);
|
|
132
|
-
print(f'Deft Framework v{v} Statistics:');
|
|
133
|
-
print(sep);
|
|
134
|
-
[print(f'{n}: {c}') for n,c in counts];
|
|
135
|
-
print(f'Total files: {total}');
|
|
136
|
-
print(sep)"
|
|
21
|
+
node -e "const fs=require('node:fs');const path=require('node:path');const d=path.join(process.argv[1],'dist');if(fs.existsSync(d))fs.rmSync(d,{recursive:true,force:true});console.log('Cleaned '+d);"
|
|
22
|
+
"{{.DEFT_ROOT}}"
|
package/tasks/framework.yml
CHANGED
|
@@ -23,30 +23,26 @@ tasks:
|
|
|
23
23
|
desc: "Read-only remote-version probe (#801) -- task framework:check-updates [-- --force | --json]. Honors DEFT_NO_NETWORK=1 and DEFT_REMOTE_PROBE_TIMEOUT (default 5s)."
|
|
24
24
|
dir: '{{.USER_WORKING_DIR}}'
|
|
25
25
|
env:
|
|
26
|
-
PYTHONUTF8: "1"
|
|
27
26
|
# When the operator passes `--force`, the task wrapper sets
|
|
28
27
|
# DEFT_FORCE_REMOTE_PROBE=1 so the gate-integration helper bypasses
|
|
29
|
-
# the 24h throttle. The
|
|
30
|
-
#
|
|
31
|
-
#
|
|
28
|
+
# the 24h throttle. The deft-ts CLI surface is idempotent (does not
|
|
29
|
+
# write to the throttle file), so this env var only affects callers
|
|
30
|
+
# that probe through the upgrade gate.
|
|
32
31
|
DEFT_FORCE_REMOTE_PROBE: '{{if (mustRegexMatch "(^|\\s)--force(\\s|$)" .CLI_ARGS)}}1{{else}}{{.DEFT_FORCE_REMOTE_PROBE | default ""}}{{end}}'
|
|
33
32
|
cmds:
|
|
34
|
-
# Strip our own `--force` from the args we pass through
|
|
35
|
-
#
|
|
36
|
-
#
|
|
33
|
+
# Strip our own `--force` from the args we pass through so it does not
|
|
34
|
+
# surface as an unknown flag in the JSON / text output. Other supported
|
|
35
|
+
# flags (e.g. `--json`) flow through unchanged.
|
|
37
36
|
#
|
|
38
|
-
# #
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- >-
|
|
48
|
-
uv --project "{{.DEFT_ROOT}}" run python "{{.DEFT_ROOT}}/run" check-updates
|
|
49
|
-
{{regexReplaceAll "(^|\\s)--force(\\s|$)" .CLI_ARGS " "}}
|
|
37
|
+
# #2069: consumer path dispatches through the native deft-ts handler
|
|
38
|
+
# via engine:invoke (vendored bin.js in source checkouts, global deft
|
|
39
|
+
# on npm consumer deposits — #2022 Phase 3).
|
|
40
|
+
- task: :engine:invoke
|
|
41
|
+
vars:
|
|
42
|
+
ENGINE_CMD: >-
|
|
43
|
+
framework:check-updates --project-root "{{.USER_WORKING_DIR}}"
|
|
44
|
+
--deft-root "{{.DEFT_ROOT}}"
|
|
45
|
+
{{regexReplaceAll "(^|\\s)--force(\\s|$)" .CLI_ARGS " "}}
|
|
50
46
|
|
|
51
47
|
doctor:
|
|
52
48
|
# #1272: the legacy ``task framework:doctor`` surface is REDACTED.
|
package/tasks/migrate.yml
CHANGED
|
@@ -10,75 +10,18 @@ tasks:
|
|
|
10
10
|
_ts-build:
|
|
11
11
|
internal: true
|
|
12
12
|
desc: "Build @deftai/cli dist/ before TS-backed gates run (#1828 s2)."
|
|
13
|
-
# Match scope.yml _ensure-ts: run from USER_WORKING_DIR with pnpm --dir so
|
|
14
|
-
# Windows consumer invocations via `-t <abs Taskfile>` do not double-prefix
|
|
15
|
-
# DEFT_ROOT under go-task's dir: handling (#566 / Windows CI regression).
|
|
16
13
|
dir: '{{.USER_WORKING_DIR}}'
|
|
17
14
|
cmds:
|
|
18
15
|
- pnpm --dir "{{.DEFT_ROOT}}" run build
|
|
19
16
|
|
|
20
17
|
preflight:
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
# (uv on PATH, v0.20+ layout, document model, git working tree) before
|
|
27
|
-
# any destructive mutation runs. Three-state exit (0 ready / 1 not-ready / 2 config
|
|
28
|
-
# error) mirrors `scripts/preflight_branch.py` (#747).
|
|
29
|
-
#
|
|
30
|
-
# Consumer path dispatches through the native deft-ts handler (#2022 Phase 2);
|
|
31
|
-
# the legacy Python script remains for maintainer parity only.
|
|
32
|
-
#
|
|
33
|
-
# NO `sources:` / `generates:` per `conventions/task-caching.md`: the
|
|
34
|
-
# script forwards user-facing CLI flags (`--project-root`, `--deft-root`,
|
|
35
|
-
# `--quiet`) via `{{.CLI_ARGS}}` and a cached cmds skip would silently
|
|
36
|
-
# swallow them.
|
|
37
|
-
desc: "Verify environment readiness for `task migrate:vbrief` (uv on PATH, v0.20+ layout, document model, git tree). Three-state exit (#793)."
|
|
18
|
+
# Pre-v0.20 document-model probe (#793, #2068 cutoff). Detects legacy
|
|
19
|
+
# SPECIFICATION.md / PROJECT.md or missing lifecycle folders and points
|
|
20
|
+
# operators at the frozen-release migration path in UPGRADING.md. Does NOT
|
|
21
|
+
# run the in-product migrator (retired from current npm deposits).
|
|
22
|
+
desc: "Detect pre-v0.20 document model and report the frozen-release migration path (#2068). Three-state exit (#793)."
|
|
38
23
|
dir: '{{.USER_WORKING_DIR}}'
|
|
39
24
|
deps:
|
|
40
25
|
- _ts-build
|
|
41
26
|
cmds:
|
|
42
27
|
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" migrate-preflight --project-root "{{.USER_WORKING_DIR}}" --deft-root "{{.DEFT_ROOT}}" {{.CLI_ARGS}}
|
|
43
|
-
|
|
44
|
-
vbrief:
|
|
45
|
-
desc: >
|
|
46
|
-
Migrate existing project files to vBRIEF-centric folder structure (RFC #309).
|
|
47
|
-
Pass safety flags after --, e.g. `task migrate:vbrief -- --dry-run`,
|
|
48
|
-
`task migrate:vbrief -- --force`, `task migrate:vbrief -- --rollback` (#497, #506 D7).
|
|
49
|
-
Pass `task migrate:vbrief -- --strict` to fail the run on any SPEC/ROADMAP
|
|
50
|
-
reconciliation conflict (#496, #506).
|
|
51
|
-
Self-invokes `task migrate:preflight` first (#793) so a non-zero preflight
|
|
52
|
-
exit aborts the run before any destructive mutation; pre-existing CLI
|
|
53
|
-
flags continue to dispatch to `scripts/migrate_vbrief.py` unchanged.
|
|
54
|
-
Emits framework events on guard trip: `dirty-tree:detected` (#497-3
|
|
55
|
-
dirty-tree guard) and `pre-cutover:detected` (when
|
|
56
|
-
run::_check_upgrade_gate is consulted by the CLI flow). See
|
|
57
|
-
events/registry.json for the payload contracts and `DEFT_EVENT_LOG` for
|
|
58
|
-
opt-in JSON-line capture (#635).
|
|
59
|
-
#2013 HOLDOUT: `migrate:vbrief` remains the sole consumer-path Python
|
|
60
|
-
entrypoint until the spec-authority umbrella resolves the
|
|
61
|
-
`migrate_vbrief.py` port-vs-cutoff decision (#2022 Phase 2).
|
|
62
|
-
deps:
|
|
63
|
-
# #793: gate destructive migration on the environment preflight. A
|
|
64
|
-
# non-zero exit from the preflight task aborts this task before any
|
|
65
|
-
# `cmds:` line runs. Operator-supplied `{{.CLI_ARGS}}` (e.g.
|
|
66
|
-
# `--dry-run`, `--force`, `--rollback`, `--strict`) belong to the
|
|
67
|
-
# migrator and are NOT valid migrate:preflight flags. go-task
|
|
68
|
-
# forwards parent CLI_ARGS into dependency tasks by default, so we
|
|
69
|
-
# explicitly clear CLI_ARGS here; otherwise `task migrate:vbrief --
|
|
70
|
-
# --dry-run` reaches the preflight argparse surface as
|
|
71
|
-
# `migrate:preflight -- --dry-run` and exits 2 (`unrecognized
|
|
72
|
-
# arguments: --dry-run`) before the migrator runs. This bug was
|
|
73
|
-
# caught by the Windows task-dispatch regression job on PR #860.
|
|
74
|
-
- task: preflight
|
|
75
|
-
vars:
|
|
76
|
-
CLI_ARGS: ""
|
|
77
|
-
dir: '{{.USER_WORKING_DIR}}'
|
|
78
|
-
env:
|
|
79
|
-
PYTHONUTF8: "1"
|
|
80
|
-
cmds:
|
|
81
|
-
# #2013 holdout: migrate_vbrief.py stays on the consumer path until the
|
|
82
|
-
# spec-authority umbrella closes the port-vs-cutoff decision (#2022).
|
|
83
|
-
# Preflight is TS-native; the migrator body remains Python for now.
|
|
84
|
-
- uv --project "{{.DEFT_ROOT}}" run python "{{.DEFT_ROOT}}/scripts/migrate_vbrief.py" "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|