Skip to content

deftai/directive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,385 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚡ Cold-start bootstrap (read this first)

New clone, or deft / directive won't run? Directive runs from an npm-installed engine — there is no committed shell shim, so you (agent or human) are the interpreter. Work the global-first ladder below top-down and stop at the first rung that yields a working directive. The version to install is always the one pinned in the project's committed package.json.

  1. Already installed? Run directive doctor (or the deft alias). If it runs, you're bootstrapped — skip the rest and follow its Next command:.
  2. Local engine. If .deft/.cli/<platform> holds an intact engine at or above the package.json pin, use it.
  3. Global install (canonical). npm i -g @deftai/directive (Node ≥ 20), then re-run directive doctor. Using pnpm? pnpm add -g @deftai/directive (same package, same registry) — make sure PNPM_HOME is on your PATH (pnpm setup if not).
  4. Sandbox install. If the global npm prefix isn't writable (sandboxed environment), install into the project instead: npm install --prefix .deft/.cli/<platform> @deftai/directive@<pinned>. (This internal .deft/.cli/ layout is always npm-shaped, regardless of your project's package manager.)
  5. Offline. If the npm registry is unreachable, install from a staged tarball / vendored payload. If none exists, stage one — recovery cannot proceed without a payload.

This block is always committed (never gitignored) and does not depend on the .deft/core/ payload being present, so it is reachable on a fresh clone even when the vendored framework is missing. Once directive runs, continue with the guidance below and in AGENTS.md.

Deft

One-shot, anti-slop

A layered framework for AI-assisted development with consistent standards and workflows.

📝 Notation Legend

Deft uses compact RFC 2119-based notation for requirements. You will see these markers throughout main.md, language standards, skills, and the docs below:

  • ! = MUST (required, mandatory)
  • ~ = SHOULD (recommended, strong preference)
  • = SHOULD NOT (discouraged, avoid unless justified)
  • = MUST NOT (forbidden, never do this)

TL;DR

Deft is a layered set of standards files plus deterministic task tooling that makes AI-assisted coding significantly more effective. Instead of repeating the same instructions in every AI session, you define your preferences once — from general coding style to project-specific rules — and AI agents follow them. The result: higher-quality code, reproducible workflows, and AI that gets better over time by learning from your patterns.

Key benefits: No more "AI forgot my preferences", no more inconsistent code style across AI sessions, no more re-explaining your stack every time.

Don't have preferences yet? Deft ships with professional-grade defaults for Python, Go, TypeScript, C++, and common workflows. Use it out of the box and customize later.

Context-efficient: Deft keeps AI context windows lean through the Notation Legend above and lazy-loading — agents only read the files relevant to the current task, not everything at once.

📍 Roadmap: See ROADMAP.md for the development timeline, open issues, and planned work.

Deft & Directive (naming)

Deft is the company; Directive is the product. In docs and on npm, Deft names the organization and the on-disk footprint (.deft/, @deftai/* scope, deft.md). Directive names the framework you install and run — the published npm package is @deftai/directive, and the primary CLI command is directive (deft is retained as an alias). Existing deft-install / deft wording in older paths refers to the same product during the staged transition to the npm-first channel (#423, #11).

🚀 Getting Started

Directive is driven by three commandsinit, update, and doctor. You never have to choose between a half-dozen setup verbs; pick the single command that matches your situation:

Your situation Run this one command What it does
New, empty project directory directive init Scaffolds a fresh Directive deposit (.deft/core/, the AGENTS.md managed section, the xbrief/ layout, and a committed package.json pin).
Existing codebase (app code, no Directive yet) directive init Installs Directive support beside your code without disturbing it, then points you at brownfield spec extraction.
Existing Directive project (already initialized) directive update Refreshes the vendored payload and self-heals the engine. (init detects this state and delegates to update with a disclosure line — it never re-scaffolds an existing install.)
Not sure, or something looks broken directive doctor Read-only diagnosis that prints exactly one recommended next step.
Legacy / pre-v0.20 layout directive init (or directive doctor) Classifies the layout and routes you to the specific migration path (see UPGRADING.md).

directive init is the universal entrypoint: run it from a project directory and it classifies that directory and dispatches to exactly one of the paths above, always printing a state summary plus one recommended next action. directive doctor is the safe "where am I?" probe, and directive update is the refresh path — the same three-command model the CLI's own directive help screen leads with.

1. Install and initialize

Install the engine globally with npm (Node ≥ 20 required):

npm i -g @deftai/directive

Using pnpm? pnpm resolves the same package from the same npm registry — no extra registry or configuration is required:

pnpm add -g @deftai/directive

Make sure pnpm's global bin directory is on your PATH (run pnpm setup once to configure PNPM_HOME). If you prefer not to install globally, a project-local pnpm add -D @deftai/directive plus pnpm exec directive <verb> works too. Deft detects your package manager (via DEFT_PACKAGE_MANAGER, the packageManager field, a pnpm-lock.yaml, or npm_config_user_agent) and prints install/upgrade hints in the matching form.

Then cd into your project and run the universal entrypoint:

directive init      # classify this directory and set up (or route) accordingly
directive doctor    # confirm the install and print your one next step

directive (the deft alias also works) runs any verb; npx @deftai/directive <verb> (npm) or pnpm dlx @deftai/directive <verb> (pnpm) runs one without a global install.

Where your project lands (honest scope): the global install above is location-independent, but directive init acts on the current working directory — it inspects that directory and dispatches, so cd into the folder you want the project to live in first (create it if it doesn't exist yet). init does not reach outside the directory you run it in. When an engine is already installed, Directive reconciles it against your committed package.json pin: a matched engine (same version as the pin) proceeds; a mismatched engine (ahead of or behind the pin) prints the exact npm i -g / directive update step to take rather than silently running against the wrong version.

What gets tracked vs ignored: init and update add Directive's local-only artifacts to your .gitignore — the reconstitutable deposit .deft/core/, the per-platform engine cache .deft/.cli/, session/ritual state such as .deft/ritual-state.json, and the .deft-cache/ content cache. Your committed package.json pin is never ignored: it is the anchor that lets directive init / directive update reconstitute .deft/core/ on a fresh clone, so it stays tracked in version control.

Node runtime (required): Live deft gates run through the TypeScript engine. Install Node 20+ (see .nvmrc in the framework payload) and pnpm (corepack enable && corepack prepare pnpm@latest --activate). Run task toolchain:check to confirm Node, pnpm, Python (uv), git, and gh are on PATH. See UPGRADING.md § Node runtime for details.

🔄 Upgrading an existing Directive project? The ordinary path is directive update from your project root (after npm i -g @deftai/directive@latest, or pnpm add -g @deftai/directive@latest on pnpm). See UPGRADING.md for the canonical steps and the advanced/big-jump detail. Agents: ! Read UPGRADING.md on the first session after a framework update.

📦 Brownfield adoption: Adding Deft to an existing project with pre-v0.20 SPECIFICATION.md / PROJECT.md? See docs/BROWNFIELD.md and UPGRADING.md § Frozen pre-v0.20 document-model migration (#2068).

📢 Cloned manually (no installer)? Tell your agent: Read deft/QUICK-START.md and follow it. It creates your project's AGENTS.md and starts the setup flow automatically.

Legacy and offline install (Go installer, #1912)

Node is always required to run Deft. Its live gates run through the TypeScript engine, so there is no Node-free way to actually use the framework — the Go installer only deposits files on disk. On a machine without Node, install Node 20+ first (via nvm, your OS package manager, or nodejs.org), then run the npm i -g @deftai/directive command above.

The Go installer is a legacy bridge, not the first-start installer — npm is canonical (above). Reach for it only when npm isn't an option: an offline / air-gapped deposit, or migrating an existing old on-disk layout (git-clone / submodule / legacy deft/-prefixed install) to the canonical .deft/core/ layout so the npm path can take over. The final Go installer release will be frozen as the permanent stage-1 bridge (#1912).

⬇️ Legacy binaries — from the latest GitHub Release:

Windows:

  • Download install-windows-amd64.exe (or install-windows-arm64.exe for Surface / Copilot+ PCs)
  • Run it — Windows SmartScreen may warn about an unrecognised publisher; click "More info" then "Run anyway"

macOS:

  • Download install-macos-universal (works on all Macs — Intel and Apple Silicon)
  • Make it executable and run:
    chmod +x install-macos-universal && ./install-macos-universal
  • If macOS Gatekeeper blocks the file: right-click then Open, or remove the quarantine attribute:
    xattr -d com.apple.quarantine install-macos-universal

Linux:

  • Download install-linux-amd64 (or install-linux-arm64 for Raspberry Pi / ARM cloud)
  • Make it executable and run:
    chmod +x install-linux-amd64 && ./install-linux-amd64

The legacy Go installer deposits a tarball payload into .deft/core/ on disk. For normal installs, use npm (npm i -g @deftai/directive) and then directive init in your project — init resolves the locally installed @deftai/directive-content package and copies it into gitignored .deft/core/, renders AGENTS.md, scaffolds the xbrief/ layout, and creates your user config directory.

Agent / headless install

Asked to "install Deft into this directory" — for example by an AI agent or a CI job? Use npm:

npm i -g @deftai/directive

Node 20+ is required to run Deft (see the note above). For offline / air-gapped deposits or migrating a legacy on-disk layout, the Go-installer binaries remain available from GitHub Releases (see the Legacy and offline install section above) — Node is still required to run the framework afterward.

Building from source (developers only): requires Go 1.22+

go run ./cmd/deft-install/

Framework maintainers working in a clone of deftai/directive should use the maintainer installer mode when bootstrapping tools from a published binary:

deft-install --yes --upgrade --maintainer --repo-root /path/to/directive --json

This mode checks maintainer tooling without projecting consumer-managed files such as AGENTS.md, .gitignore, .gitattributes, guard workflows, or consumer vbrief/ scaffolding into the framework repository. See CONTRIBUTING.md for maintainer setup details.

2. Set Up Your Preferences

Deft offers two setup paths that produce the same output (USER.md + vbrief/PROJECT-DEFINITION.vbrief.json + scope vBRIEFs) but adapt to different users:

  • Agent-driven (recommended for most users) — Tell your agent read AGENTS.md and follow it, or run directive bootstrap to deposit the framework and hand off to the setup skill.
  • CLI launcher (for terminal operators) — directive bootstrap deposits .deft/core/ when absent and routes into the agent-driven setup flow (Phases 1–3). Use --project or --strategy <name> to jump to a later phase; --reconfigure / --force control re-entry when artifacts already exist.

User config location:

  • Unix / macOS: ~/.config/deft/USER.md
  • Windows: %APPDATA%\deft\USER.md
  • Override: set DEFT_USER_PATH environment variable

3. Generate a Scope vBRIEF

directive bootstrap walks the full setup chain (user preferences → project definition → scope vBRIEF interview). Jump to a later phase when re-entering:

directive bootstrap --strategy interview   # Phase 3 — scope vBRIEF interview
directive bootstrap --project              # Phase 2 — project configuration only

The interview writes a scope vBRIEF to vbrief/proposed/. vbrief/*.vbrief.json files are the source of truth; .md files (PRD.md, SPECIFICATION.md, ROADMAP.md) are rendered views generated on demand via task *:render. Direct edits to the rendered .md files are overwritten on the next render — edit the underlying .vbrief.json instead.

Other commands:

directive doctor               # Check install integrity and dependencies
directive agents:refresh       # Refresh AGENTS.md managed section

Legacy note: Other .deft/core/run verbs (validate, reset, upgrade) remain available during the Python-purge transition; prefer directive <verb> where a native handler exists.

4. Build With AI

Ask your AI to build the product/project from your scope vBRIEFs and away you go:

Read vbrief/PROJECT-DEFINITION.vbrief.json and the scope vBRIEFs in
vbrief/active/ (or vbrief/pending/ if none are active yet) and implement
the project following deft/main.md standards.

5. Backlog triage (working an existing backlog)

Already have a populated backlog — an existing project, a brownfield migration, or an upstream issue tracker that has been accumulating? Trigger the refinement workflow's pre-ingest Phase 0 action menu with words like "triage", "work the cache", or "pre-ingest". The agent walks each cached candidate through the menu (accept | reject | defer | needs-ac | mark-duplicate) and only accepted items land in vbrief/proposed/ — rejected and deferred items are recorded in the audit log without polluting the backlog.

First populate is scoped via flags so the upstream rate limit does not bite:

task triage:bootstrap -- --limit 50 --state open

Why scoped flags? An unbounded populate against a real-sized backlog can drain the shared GitHub GraphQL bucket (see #976); the --limit / --state / --batch-size / --delay-ms surface keeps the populate inside the REST budget with batched delays. The cache (task cache:fetch-all) is REST-backed and reproducible across re-runs — no live gh issue view per decision.

Full walkthrough — including the three-tier model (cache → audit log → accepted backlog), the action menu, and how to re-enter triage on subsequent passes — lives in docs/getting-started.md § Working an existing backlog. The verb-to-outcome reference for every task triage:* and task cache:* command is in commands.md.

6. Feature slicing (breaking a plan into parallel-grabbable issues)

When a spec, PRD, or plan is ready to hand off — especially to multiple agents or collaborators working in parallel — slice it into tracer-bullet vertical slices. Trigger the workflow with words like "slice this into tickets" or "break this into GitHub issues" (the deft-directive-gh-slice skill).

  • Vertical, not horizontal — each slice cuts a narrow but complete path through every layer (schema → API → UI → tests) so it is independently demoable. "Implement all the data models" is a horizontal slice and an anti-pattern.
  • AFK vs HITL — each slice is tagged AFK (mergeable with no human interaction — preferred) or HITL (needs a decision/review first), and declares what blocks it so issues are filed in dependency order.
  • Durable cohorts — when a plan slices into an umbrella + child issues, the cohort is recorded in vbrief/.eval/slices.jsonl (tracked in git, with per-child wave numbers). This lets task triage:audit --orphans | --slice-stalled | --slice-coverage detect children stranded when an umbrella closes early, stalled siblings, and per-umbrella completion. Hand-filed cohorts are backfilled with task slice:record-existing; list recorded cohorts with task slice:list.

Slices become GitHub issues, which triage into vBRIEFs, which flow through the proposed/ → pending/ → active/ → completed/ lifecycle and can be allocated to parallel agents (the deft-directive-swarm skill). Architectural refactors follow the same slicing path via deft-directive-gh-arch.

🪜 Layered Architecture (at a glance)

Deft separates how the AI behaves (the rule ladder) from what to build (project requirements). Both are summarised here; the full diagram and rationale live in docs/ARCHITECTURE.md.

Rule Hierarchy

Rules cascade with precedence (highest first). This is the how-the-AI-behaves ladder:

  1. USER.md (highest) — your personal overrides (~/.config/deft/USER.md on Unix/macOS, %APPDATA%\deft\USER.md on Windows)
  2. vbrief/PROJECT-DEFINITION.vbrief.json — project-specific rules and identity gestalt
  3. Language files (languages/python.md, languages/go.md, ...) — language standards
  4. Tool files (tools/taskfile.md, ...) — tool guidelines
  5. main.md (lowest) — general AI behavior

Note: project requirements (vbrief/specification.vbrief.json + scope vBRIEFs in vbrief/{proposed,pending,active,completed,cancelled}/) describe what to build and are deliberately kept on a separate ladder from the rule cascade above. ROADMAP.md is the rendered backlog view of those requirements.

🌲 Branch policy

Deft enforces a feature-branch policy by default (#746, #747): direct commits to master/main are blocked and PRs whose head_ref equals base_ref are refused at the CI gate. The policy is governed by a typed flag on vbrief/PROJECT-DEFINITION.vbrief.json:

{
  "plan": {
    "policy": { "allowDirectCommitsToMaster": false }
  }
}

Three enforcement surfaces back the rule:

  1. Git hooks.githooks/pre-commit and .githooks/pre-push invoke scripts/preflight_branch.py. Activate them with task setup (idempotent git config core.hooksPath .githooks); verify with task verify:hooks-installed.
  2. Pre-commit gatetask verify:branch is wired into the task check aggregate so any local pre-commit pass flags a default-branch commit before it lands.
  3. CI.github/workflows/branch-gate.yml refuses PRs whose head_ref equals base_ref (catches master->master PRs that the local hooks cannot see).

Reconfigure via deterministic tasks (audited to meta/policy-changes.log):

  • task policy:show — display the resolved policy and its source.
  • task policy:enforce-branches — set allowDirectCommitsToMaster=false.
  • task policy:allow-direct-commits -- --confirm — set the typed flag to true after the capability-cost disclosure (branch-protection turns OFF). The deft-directive-setup interview Phase 2 Step 9 elicits the same choice with the same disclosure.

Emergency bypass: set DEFT_ALLOW_DEFAULT_BRANCH_COMMIT=1 for the current shell. The legacy Allow direct commits to master: narrative key is recognised at read time with a deprecation warning and is migrated to the typed surface on the next task policy:* write.

See glossary.md (Branch-protection policy / Policy audit log entries) for the canonical vocabulary and skills/deft-directive-setup/SKILL.md Phase 2 Step 9 for the interview disclosure copy.

🔒 Security

Security posture, audit cadence, and vulnerability-reporting flow live in docs/security.md. The 2026-05-12 supply-chain hygiene cohort (#1069) recorded the inaugural baseline; future quarterly + event-driven audits append new sections rather than rewrite history. To report a vulnerability, file a private advisory at https://github.com/deftai/directive/security/advisories/new.

⚙️ Platform Requirements

GitHub is the primary supported SCM platform. Skills that interact with issues and PRs (deft-directive-sync, deft-directive-swarm, deft-directive-review-cycle, deft-directive-refinement, deft-directive-release, deft-directive-gh-slice, deft-directive-gh-arch) require the GitHub CLI (gh) to be installed and authenticated. Core framework features (setup, build, rendering, validation) work independently of any SCM platform.

ghx (recommended proxy): When gh is on PATH, Deft automatically prefers ghx — a read-only cache proxy for gh — if it is installed. ghx speeds up repeated GitHub API reads and helps multi-agent swarms stay under rate limits. Install it with consent via directive setup:ghx (or task setup:ghx); task setup nudges you when gh is present but ghx is missing. Consumer projects only require gh; ghx is optional but supported.

The migration script (task migrate:vbrief) defaults origin provenance to x-vbrief/github-issue type. Non-GitHub users should manually adjust references[].type in generated vBRIEFs after migration.

📦 Content packs

Deft ships versioned content packs — structured JSON projections of the framework's own corpus (lessons, skills, rules, strategies, patterns, the swarm spec). They let an agent pull just the slice it needs into context instead of reading a whole .md file, and they keep the rendered .md files drift-checked against a single canonical source.

task packs:slice -- --list-packs          # discover packs (name, version, one-line description)
task packs:slice lessons -- --list        # list the named slices a pack exposes
task packs:slice lessons by-tag -- --tag testing   # load just that slice (add --json for structured output)

Slices are addressed by a stable, versioned slice name (e.g. recent, by-tag, by-trigger, by-tier) — never a JSONPath — and read the canonical pack source directly, so a slice never drifts from what an agent sees. New packs and slices appear automatically in --list-packs / --list with no rewiring. See strategies/README.md and the pack sources under packs/ for details.

📚 Learn More

  • docs/ARCHITECTURE.md — Current Taskfile-first architecture, rule authority, vBRIEF state, installer layout, and codeStructure projection boundary
  • docs/CONCEPTS.md — Current operating concepts: vBRIEF source of truth, deterministic gates, cache-backed triage, lifecycle folders, and projections
  • docs/FILES.md — Current directory tree, task includes, skills, vBRIEF state, and consumer artifact locations
  • docs/RELEASING.md — Release & smoke-test workflow
  • docs/BROWNFIELD.md — Brownfield adoption (pre-v0.20 → vBRIEF migration)
  • docs/security.md — Security posture, audit baseline, cadence, vulnerability-reporting flow
  • main.md — Comprehensive AI guidelines (general behavior layer)
  • commands.md — Taskfile-first command lifecycle with compatibility run surfaces
  • glossary.md — Canonical v0.20 vocabulary

🎓 Philosophy

Deft embodies:

  • Correctness over convenience — Optimize for long-term quality
  • Standards over flexibility — Consistent patterns across projects
  • Evolution over perfection — Continuously improve through learning
  • Clarity over cleverness — Direct, explicit, maintainable code

Next Steps: Read main.md for comprehensive AI guidelines, then run npm i -g @deftai/directive (Node ≥ 20) to get started.


Copyright © 2025-2026 Jonathan "visionik" Taylor — https://deft.md Licensed under the MIT License

About

Best practices and guidelines for AI agents in software development

Resources

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors