@deftai/directive-content 0.107.0 → 0.109.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 +4 -3
- package/SKILL.md +9 -10
- package/Taskfile.yml +19 -4
- package/UPGRADING.md +29 -9
- package/coding/build-output.md +4 -3
- package/coding/coding.md +6 -5
- package/coding/security.md +3 -3
- package/coding/testing.md +2 -1
- package/commands.md +35 -15
- package/contracts/deposit-required-paths.json +26 -0
- package/contracts/design-critique.md +180 -16
- package/contracts/deterministic-questions.md +2 -1
- package/contracts/host-lifecycle-duties.md +1 -1
- package/contracts/path-write-fence.md +67 -7
- package/conventions/content-manifest.json +1 -1
- package/conventions/references.md +10 -8
- package/conventions/task-caching.md +2 -1
- package/conventions/vbrief-filenames.md +5 -4
- package/docs/consumer-check-contract.md +35 -0
- package/docs/delivery-attempt.md +4 -1
- package/docs/freshness-contract.md +6 -1
- package/docs/gate-integrity.md +17 -2
- package/docs/getting-started.md +10 -11
- package/docs/hook-runtime-unavailable.md +54 -0
- package/docs/host-surface-assumptions.md +2 -1
- package/docs/orphan-active-verdict-basis.md +199 -0
- package/docs/skill-pin-policy.md +1 -1
- package/events/README.md +12 -13
- package/glossary.md +2 -1
- package/incidents/README.md +2 -1
- package/interfaces/cli.md +2 -1
- package/languages/6502-DASM.md +2 -1
- package/languages/c.md +2 -1
- package/languages/cpp.md +2 -1
- package/languages/csharp.md +2 -1
- package/languages/dart.md +2 -1
- package/languages/delphi.md +2 -1
- package/languages/elixir.md +2 -1
- package/languages/go.md +2 -1
- package/languages/java.md +2 -1
- package/languages/javascript.md +2 -1
- package/languages/julia.md +2 -1
- package/languages/kotlin.md +2 -1
- package/languages/markdown.md +2 -1
- package/languages/mermaid.md +2 -1
- package/languages/officejs.md +2 -1
- package/languages/python.md +2 -1
- package/languages/r.md +2 -1
- package/languages/rust.md +2 -1
- package/languages/sql.md +2 -1
- package/languages/swift.md +2 -1
- package/languages/typescript.md +2 -1
- package/languages/vba.md +2 -1
- package/languages/vhdl.md +2 -1
- package/languages/visual-basic.md +2 -1
- package/languages/zig.md +2 -1
- package/main.md +47 -44
- package/meta/code-field.md +2 -1
- package/meta/morals.md +2 -1
- package/meta/philosophy.md +3 -2
- package/meta/project.md +4 -3
- package/meta/ralph.md +2 -1
- package/meta/security.md +3 -2
- package/meta/versioning.md +2 -1
- package/package.json +3 -3
- package/packs/patterns/patterns-pack-0.1.json +1 -1
- package/packs/rules/rules-pack-0.1.json +6 -6
- package/packs/skills/skills-pack-0.1.json +11 -11
- package/packs/strategies/strategies-pack-0.1.json +5 -5
- package/patterns/executor-layer-credentials.md +1 -1
- package/patterns/multi-agent.md +4 -4
- package/platforms/2600.md +2 -1
- package/platforms/unity.md +2 -1
- package/references/ip-risk.md +14 -19
- package/scm/changelog.md +1 -1
- package/scm/git.md +2 -1
- package/scm/github.md +41 -7
- package/skills/deft-directive-build/SKILL.md +8 -8
- package/skills/deft-directive-cost/SKILL.md +7 -11
- package/skills/deft-directive-design-critique/SKILL.md +8 -1
- package/skills/deft-directive-design-critique/references/motion-shape.md +19 -0
- package/skills/deft-directive-gh-slice/SKILL.md +1 -1
- package/skills/deft-directive-interview/SKILL.md +15 -15
- package/skills/deft-directive-pre-pr/SKILL.md +2 -2
- package/skills/deft-directive-refinement/SKILL.md +3 -3
- package/skills/deft-directive-release/SKILL.md +19 -15
- package/skills/deft-directive-review-cycle/SKILL.md +33 -0
- package/skills/deft-directive-setup/SKILL.md +56 -24
- package/skills/deft-directive-swarm/references/core-ops.md +4 -0
- package/skills/deft-directive-swarm/references/core-phase-1-2.md +1 -1
- package/skills/deft-directive-swarm/references/core-phase-3.md +3 -1
- package/skills/deft-directive-swarm/references/core-phase-4.md +11 -8
- package/skills/deft-directive-swarm/references/host-cursor.md +1 -0
- package/skills/deft-directive-swarm/references/host-grok-build.md +1 -0
- package/skills/deft-directive-sync/SKILL.md +7 -7
- package/stage-pack.mjs +31 -0
- package/strategies/README.md +2 -1
- package/strategies/interview.md +1 -1
- package/strategies/research.md +1 -1
- package/strategies/speckit.md +2 -2
- package/strategies/v0-20-contract.md +2 -2
- package/swarm/swarm.md +2 -1
- package/tasks/engine.yml +2 -0
- package/tasks/occupancy.yml +24 -2
- package/tasks/prd.yml +4 -5
- package/tasks/session.yml +3 -3
- package/tasks/toolchain.yml +2 -2
- package/tasks/vbrief.yml +6 -2
- package/tasks/verify.yml +50 -1
- package/templates/agent-prompt-preamble.md +11 -4
- package/templates/agents-entry.md +8 -3
- package/templates/make-spec.md +1 -1
- package/templates/swarm-greptile-poller-prompt.md +2 -2
- package/tools/package-manager-network.md +2 -1
- package/tools/taskfile-migration.md +2 -1
- package/tools/taskfile.md +2 -1
- package/tools/telemetry.md +2 -1
- package/vbrief/vbrief.md +1 -1
|
@@ -39,6 +39,41 @@ A **partial local** root check aggregate still fails closed — the include must
|
|
|
39
39
|
|
|
40
40
|
Root cause of red `greenfield-python-free-smoke` after #3145: the gate only inspected the root Taskfile, treated include-only greenfield as “no check composition,” and hard-failed (`exit 201` via #3188). That was a **gate false positive** for the intentional deposit shape, not a missing deposit wiring bug.
|
|
41
41
|
|
|
42
|
+
## Merge-chokepoint gate scoping (#3893)
|
|
43
|
+
|
|
44
|
+
Some gates are repo-wide by default and must be **narrowed** when composed on a
|
|
45
|
+
merge chokepoint. `verify:orphan-active` is the first: composed unscoped it
|
|
46
|
+
fails a candidate for lifecycle residue another merge stranded, and N stranded
|
|
47
|
+
briefs make N single-brief lifecycle PRs mutually unmergeable.
|
|
48
|
+
|
|
49
|
+
The contract therefore records a required argument per gate
|
|
50
|
+
(`MERGE_CHOKEPOINT_SCOPED_GATE_ARGS`) and reports a check aggregate that lists
|
|
51
|
+
the gate without it:
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
check:consumer:
|
|
55
|
+
deps:
|
|
56
|
+
- task: verify:orphan-active
|
|
57
|
+
vars:
|
|
58
|
+
CLI_ARGS: "--changed-only"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The check reads the dependency's effective `CLI_ARGS` value, not the raw entry
|
|
62
|
+
text, so the flag appearing in a comment, a sibling variable, or a descriptive
|
|
63
|
+
value does not satisfy it.
|
|
64
|
+
|
|
65
|
+
- **`--framework-source`: fail closed.** This repo owns its own composition, so
|
|
66
|
+
a regression to the unscoped form is a hard failure here.
|
|
67
|
+
- **Consumer deposits: warn.** `deft update` re-deposits the Taskfile; the
|
|
68
|
+
warning names the exact one-line repair in the meantime.
|
|
69
|
+
- **Aggregates that do not list the gate are silent.** Include-only greenfield
|
|
70
|
+
roots and orchestrator-body `check` tasks are unaffected.
|
|
71
|
+
|
|
72
|
+
This is a strengthening, not a relaxation: nothing about the detector, the
|
|
73
|
+
required-gate set, or any exit code is weakened. Repo-wide residue truth still
|
|
74
|
+
runs on the bare verb, at the delivery tip, and on the after-merge
|
|
75
|
+
`verify:orphan-active -- --issue N` DONE gate (#3429).
|
|
76
|
+
|
|
42
77
|
## Repair path
|
|
43
78
|
|
|
44
79
|
1. Restore deposit Taskfiles: `deft update` (includes `tasks/verify.yml` under `.deft/core/`)
|
package/docs/delivery-attempt.md
CHANGED
|
@@ -34,6 +34,8 @@ MUST evaluate this gate before automatic retry or re-dispatch.
|
|
|
34
34
|
| `BLOCK_ELAPSED_BUDGET` | Wall-clock budget exhausted |
|
|
35
35
|
| `BLOCK_TOOL_OR_TOKEN_BUDGET` | Tool-call (or host-token when telemetried) budget exhausted |
|
|
36
36
|
|
|
37
|
+
evaluateInFlight(ledger, input) applies the same elapsed budget to a run that is already queued or running. Pre-dispatch never sees that case: an active attempt is DENY_DUPLICATE_ACTIVE. In-flight elapsed is totalElapsedSeconds plus wall-clock since startedAt. Under budget returns ALLOW_RESUME. Exhausted returns BLOCK_ELAPSED_BUDGET. No second budget store.
|
|
38
|
+
|
|
37
39
|
Once a **block** decision is emitted, automatic re-dispatch MUST stop until a
|
|
38
40
|
declared resume condition is satisfied or an audited operator override is
|
|
39
41
|
recorded. Persist the terminal handoff (`buildTerminalHandoff` /
|
|
@@ -102,7 +104,8 @@ task swarm:pre-dispatch -- --scope-id <story|issue|xbrief-id> --target-id <workt
|
|
|
102
104
|
Default unit key: `scopeId` + `targetId` + `workflowId=drive-to:merge-ready`.
|
|
103
105
|
Actions: `begin` (default), `complete` (`--status succeeded|failed|cancelled|blocked`), `cancel` (takeover step 1).
|
|
104
106
|
Monitors MUST run begin before any peer implement spawn; spawn only on exit 0.
|
|
105
|
-
Takeover: cancel prior attempt, then begin again — never concurrent dual active.
|
|
107
|
+
Takeover after REDISPATCH_OK: cancel prior attempt, then begin again — never concurrent dual active.
|
|
108
|
+
A killed worker stays `queued`/`running` until cancel; REDISPATCH_OK does not lift `DENY_DUPLICATE_ACTIVE` (#3730).
|
|
106
109
|
Implementation: `packages/core/src/swarm/pre-dispatch.ts` + `task swarm:pre-dispatch`.
|
|
107
110
|
|
|
108
111
|
## Skill routing
|
|
@@ -35,10 +35,15 @@ When a mutation `session:start` (cold or re-arm) loads payload surfaces into
|
|
|
35
35
|
runtime context, it binds the live generation:
|
|
36
36
|
|
|
37
37
|
```text
|
|
38
|
-
.deft/session-binds/<
|
|
38
|
+
.deft/session-binds/<sha256-slice>.json # multi-agent isolation (preferred)
|
|
39
39
|
.deft/session-bind.json # default / last-bind convenience
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
The per-session record is named by a 24-hex SHA-256 slice of the session id, so
|
|
43
|
+
a directory listing carries no fragment of the id (#3768). Records written
|
|
44
|
+
before that rename also carried a 32-character id prefix; they are read-accepted
|
|
45
|
+
until the next bind supersedes them.
|
|
46
|
+
|
|
42
47
|
Multi-agent hosts **must** pin session identity so one session cannot certify
|
|
43
48
|
another as current:
|
|
44
49
|
|
package/docs/gate-integrity.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/docs/gate-integrity.md" -->
|
|
1
2
|
# Gate integrity — a failing gate must not be fixed by editing the gate (#3156)
|
|
2
3
|
|
|
3
4
|
General product and process rule for Directive fix loops, refine loops, and quality-gate repair: **when a gate is red, clear red by fixing the work under test — not by mutating the gate.**
|
|
@@ -80,7 +81,7 @@ Field notes and parent framing: issue [#3156](https://github.com/deftai/directiv
|
|
|
80
81
|
## Discoverability
|
|
81
82
|
|
|
82
83
|
- Pre-PR Diff phase checklist: [deft-directive-pre-pr](../skills/deft-directive-pre-pr/SKILL.md) (gate-integrity bullet).
|
|
83
|
-
- Stance / propose-not-apply: [main.md § Self-Improving, Not Self-Editing (#3164)](
|
|
84
|
+
- Stance / propose-not-apply: [main.md § Self-Improving, Not Self-Editing (#3164)](../main.md#self-improving-not-self-editing-3164), [philosophy.md](../meta/philosophy.md).
|
|
84
85
|
- Verification outcomes: [verification.md](../verification/verification.md).
|
|
85
86
|
- Goal/gate rigidity: [goal-gate-determinism.md](../patterns/goal-gate-determinism.md) (#852).
|
|
86
87
|
- Scope self-auth instance: [scope-provenance.md](./scope-provenance.md) (#3145).
|
|
@@ -94,13 +95,27 @@ Full CI automation that blocks “diff touches a gate that just failed” withou
|
|
|
94
95
|
| Topic | Where |
|
|
95
96
|
|-------|--------|
|
|
96
97
|
| Parent epic | [#3179](https://github.com/deftai/directive/issues/3179) |
|
|
97
|
-
| Stance (propose-not-apply) | [#3164](https://github.com/deftai/directive/issues/3164), [main.md](
|
|
98
|
+
| Stance (propose-not-apply) | [#3164](https://github.com/deftai/directive/issues/3164), [main.md](../main.md#self-improving-not-self-editing-3164) |
|
|
98
99
|
| Refine-internal SkillOpt | [#2436](https://github.com/deftai/directive/issues/2436) |
|
|
99
100
|
| Fixed evaluator / agent-loop | [#782](https://github.com/deftai/directive/issues/782) |
|
|
100
101
|
| Verification independence | [#1499](https://github.com/deftai/directive/issues/1499) |
|
|
101
102
|
| Scope self-authorization | [#3145](https://github.com/deftai/directive/issues/3145), [scope-provenance.md](./scope-provenance.md) |
|
|
102
103
|
| Host self-mutate honesty | [#3162](https://github.com/deftai/directive/issues/3162), [host-surface-assumptions.md](./host-surface-assumptions.md) |
|
|
103
104
|
| Safety via formal gates | [#1200](https://github.com/deftai/directive/issues/1200) |
|
|
105
|
+
| Poisoned product-oracle history from a safety refusal | [#3615](https://github.com/deftai/directive/issues/3615), this page § Product-oracle history poisoned by a safety refusal |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Product-oracle history poisoned by a safety refusal (#3615)
|
|
110
|
+
|
|
111
|
+
A safety-refused acceptance command is not a product measurement. `verify:ac` keeps the acceptance gate red, and it does not write `verification.outcome=fail` for an all-refused walk. A mixed walk that still has a refusal does not write a product-oracle pass.
|
|
112
|
+
|
|
113
|
+
Records already written still pair on `session_id` + `check_id`. A correct classifier going forward does not unwrite a `fail` already on disk. Recovery is an operator workaround, not independent re-derivation:
|
|
114
|
+
|
|
115
|
+
1. Start a new Deft session (new `DEFT_SESSION_ID`) so the integrity layer does not pair against the poisoned fail, or
|
|
116
|
+
2. Truncate or delete the run-summary JSONL (default `.deft-run-summary.json`, typically gitignored).
|
|
117
|
+
|
|
118
|
+
⊗ Set `independent_rederivation=true` to clear this class. That flag asserts both sides were rebuilt from scratch. The refused side never executed.
|
|
104
119
|
|
|
105
120
|
---
|
|
106
121
|
|
package/docs/getting-started.md
CHANGED
|
@@ -16,21 +16,18 @@ Before the mechanics below, it helps to see the whole loop. Directive is two con
|
|
|
16
16
|
|
|
17
17
|
## Prerequisites
|
|
18
18
|
|
|
19
|
-
- **Node 20+** and
|
|
19
|
+
- **Node 20+** and the package manager declared by the project (`npm` or `pnpm`) for live consumer gates and the npm distribution channel (see `.nvmrc` in the framework payload). npm is bundled with Node; a pnpm-pinned project enables pnpm through Corepack.
|
|
20
|
+
- **Git** and **GitHub CLI (`gh`)** are also checked by the consumer toolchain gate.
|
|
20
21
|
- **Go 1.22+** only if you use the bootstrap Go installer or build from source.
|
|
21
|
-
- **Python 3.11+**, **uv**,
|
|
22
|
+
- **Python 3.11+**, **uv**, and **task** for the framework-maintainer and session workflows that name them. The consumer toolchain probe itself does not check those tools. Run `directive toolchain:check --consumer --project-root .` after install.
|
|
22
23
|
|
|
23
24
|
---
|
|
24
25
|
|
|
25
26
|
## Installation
|
|
26
27
|
|
|
27
|
-
### npm (
|
|
28
|
+
### npm (canonical)
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<!-- TODO(#1909): flip to npm-canonical and remove this "coming soon" notice when @deftai/directive is published -->
|
|
32
|
-
|
|
33
|
-
Once published, when Node is already available you will install Directive globally:
|
|
30
|
+
With Node already available, install Directive globally from npm:
|
|
34
31
|
|
|
35
32
|
```bash
|
|
36
33
|
npm i -g @deftai/directive
|
|
@@ -38,16 +35,18 @@ directive --version # primary command
|
|
|
38
35
|
deft --version # alias — same binary
|
|
39
36
|
```
|
|
40
37
|
|
|
41
|
-
One-shot without a global install
|
|
38
|
+
One-shot without a global install:
|
|
42
39
|
|
|
43
40
|
```bash
|
|
44
41
|
npx @deftai/directive doctor
|
|
45
42
|
npx @deftai/directive session:start
|
|
46
43
|
```
|
|
47
44
|
|
|
48
|
-
This npm path
|
|
45
|
+
This npm path has been the canonical distribution channel since v0.55.1. A pnpm-managed repository can install the same package with `pnpm add -g @deftai/directive` or project-locally with `pnpm add -D @deftai/directive`.
|
|
46
|
+
|
|
47
|
+
### Go installer (legacy bridge)
|
|
49
48
|
|
|
50
|
-
|
|
49
|
+
The Go installer is a frozen legacy bridge for older installs and source-oriented recovery. New consumer installs should use npm above; see [UPGRADING.md](../UPGRADING.md#one-time-migration-from-the-go-installer-legacy--npm) when migrating an existing Go-installer layout.
|
|
51
50
|
|
|
52
51
|
Download a platform installer from the [Directive release page](https://github.com/deftai/directive/releases) and run it from the project you want to adopt:
|
|
53
52
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Hook runtime unavailable: `deft-hook` is not on PATH
|
|
2
|
+
|
|
3
|
+
On a host that cannot execute `deft-hook`, the Cursor `preToolUse` registration is `failClosed: true`, so **every mutation is denied** — and because the binary never runs, no Directive code is left to say why. The visible symptom is an opaque non-zero exit, typically **127** (command not found).
|
|
4
|
+
|
|
5
|
+
Tracker: [#3785](https://github.com/deftai/directive/issues/3785). Related: [#3736](https://github.com/deftai/directive/issues/3736) (timeout), [#3571](https://github.com/deftai/directive/issues/3571) (unused-host recovery), [#2752](https://github.com/deftai/directive/issues/2752) (per-host toggles).
|
|
6
|
+
|
|
7
|
+
## Who hits this
|
|
8
|
+
|
|
9
|
+
The registration travels via git; the runtime does not. `.cursor/hooks.json` is trackable by design and the `.deft/core/` deposit is born-ignored, so any environment that gets the repo without a Node install of the CLI inherits the fence without the implementation:
|
|
10
|
+
|
|
11
|
+
- cloud agent VMs whose image has no Node and no global install
|
|
12
|
+
- CI runners and containers that never run `npm i -g @deftai/directive`
|
|
13
|
+
- a fresh clone on a new workstation
|
|
14
|
+
|
|
15
|
+
## Recovery is out of band
|
|
16
|
+
|
|
17
|
+
There is no in-session escape. Run this from a shell where Node and the CLI **are** available — your workstation, or the repo before you push it:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
deft policy:disable-host-hooks --host cursor --confirm
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
That sets `plan.policy.hostHooks.cursor = false` in `xbrief/PROJECT-DEFINITION.xbrief.json`, and the next `deft update` strips the Cursor registration. Commit and push; the locked-out environment clears on its next pull or fresh clone.
|
|
24
|
+
|
|
25
|
+
⚠ Capability cost: disabling `hostHooks` for a host removes `deft-hook` pre-execution guardrails for anyone who later opens this repo in that host. The change is tracked and recorded to `meta/policy-changes.log`. Inspect with `deft policy:show --field=hostHooks`; reverse by setting the host back to `true` and running `deft update`.
|
|
26
|
+
|
|
27
|
+
## Preferred fix: make the runtime travel with the registration
|
|
28
|
+
|
|
29
|
+
If Cursor is a host you rely on, restore the runtime rather than removing the fence. Either:
|
|
30
|
+
|
|
31
|
+
- commit a `package.json` dependency on `@deftai/directive` — a published version or another spec a clone can fetch, since a location spec (`file:`, `link:`, `../directive`, an absolute path) resolves only on the machine that wrote it — and run `npm install` in the image or clone, which puts `deft-hook` in `node_modules/.bin`; or
|
|
32
|
+
- add `npm i -g @deftai/directive` to the image build.
|
|
33
|
+
|
|
34
|
+
`deft init` and `deft update` warn when a hook registration travels with the repository — already committed, or merely untracked and not ignored, so the next `git add` carries it — while neither anchor is present. The warning names the affected file and this document.
|
|
35
|
+
|
|
36
|
+
## ⊗ Do not hand-edit `failClosed` in the deposited hook file
|
|
37
|
+
|
|
38
|
+
Setting `failClosed: false` in `.cursor/hooks.json` clears the block exactly once. That file is a managed deposit: the next `deft update` rewrites the entries with `failClosed: true` and **silently re-arms the lockout**, usually long after anyone remembers editing it. Use the policy verb above, which is durable and tracked.
|
|
39
|
+
|
|
40
|
+
## Why the flags do not help
|
|
41
|
+
|
|
42
|
+
| Escape hatch | Why it does not reach this failure |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `.deft-directive-disable` | Evaluated *inside* `deft-hook`. When the binary is missing, nothing reads the flag. |
|
|
45
|
+
| `.no-deft-directive` | Consulted at `session.start` only; it never reaches `preToolUse`. |
|
|
46
|
+
| Host-side "skip hook" | A host concept. Directive has no such bypass. |
|
|
47
|
+
|
|
48
|
+
## Absent, crashed, and timed out are one class
|
|
49
|
+
|
|
50
|
+
The hook exit contract already decouples the exit code from the verdict: exit `0` means a decision was **rendered** — allow *or* deny — so every non-zero exit is by construction a *non-decision*. Absence, a crash, and a host timeout kill are the same state, and all three stay fail-closed.
|
|
51
|
+
|
|
52
|
+
They stay fail-closed because fail-open-on-absence is a bypass primitive, not a lenience: removing the binary is an ordinary shell call, so treating absence as allow would convert a self-inflicted denial into a bypass of the write fence, the intent ceiling, the session ritual, and the occupancy lease ([#3156](https://github.com/deftai/directive/issues/3156)). What these cases need is legibility and an out-of-band escape — this page — not a relaxed fence.
|
|
53
|
+
|
|
54
|
+
For a timeout specifically, retry the gated ritual first when machine load is the likely cause; the Cursor `tool.before` budget is sized for a gated ritual plus live readiness, so a repeated timeout is a real signal rather than noise.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/docs/host-surface-assumptions.md" -->
|
|
1
2
|
# Host-surface assumptions: file gates vs REPL / self-mutating hosts (#3162)
|
|
2
3
|
|
|
3
4
|
Directive control surfaces assume two host behaviors that **some** modern agent hosts break by design.
|
|
@@ -131,7 +132,7 @@ Named hook home for managed-path deny: **Tier-1 host hooks** (`packages/core/src
|
|
|
131
132
|
|
|
132
133
|
| Topic | Where |
|
|
133
134
|
|-------|--------|
|
|
134
|
-
| Self-improving, not self-editing stance | [main.md § Self-Improving, Not Self-Editing (#3164)](
|
|
135
|
+
| Self-improving, not self-editing stance | [main.md § Self-Improving, Not Self-Editing (#3164)](../main.md#self-improving-not-self-editing-3164), [philosophy.md](../meta/philosophy.md) |
|
|
135
136
|
| Gate integrity (do not clear red by editing the gate) | [gate-integrity.md](./gate-integrity.md) (#3156); refine-internal #2436 separate |
|
|
136
137
|
| Skill pin tiers (process pins, not full #830) | [skill-pin-policy.md](./skill-pin-policy.md) |
|
|
137
138
|
| Host lifecycle duty list | [host-lifecycle-duties.md](../contracts/host-lifecycle-duties.md) |
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# `verify:orphan-active`: verdict basis and freshness (#3767)
|
|
2
|
+
|
|
3
|
+
`verify:orphan-active` decides whether an `xbrief/active/` brief with
|
|
4
|
+
`plan.status == running` is really still live work. Until #3767 it answered
|
|
5
|
+
that question from a triage-cache hit returned **unconditionally** — no age
|
|
6
|
+
bound, no re-validation. A cached `open` written twelve hours earlier beat
|
|
7
|
+
reality and suppressed the live read that would have corrected it, so the gate
|
|
8
|
+
exited 0 while scanning the very brief whose issue had already closed.
|
|
9
|
+
|
|
10
|
+
This document records what the gate now does, why, and what it still cannot
|
|
11
|
+
promise.
|
|
12
|
+
|
|
13
|
+
Legend (RFC2119): `!`=MUST, `~`=SHOULD, `⊗`=MUST NOT, `?`=MAY.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Two modes, split by query shape
|
|
18
|
+
|
|
19
|
+
The gate has two callers with different obligations, so it has two mechanisms.
|
|
20
|
+
|
|
21
|
+
| | Scoped `--issue N` | Unscoped aggregate |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| Caller | after-merge DONE proof (#3429 / #3476) | `task check`, pre-commit, pre-push sweep |
|
|
24
|
+
| Mechanism | authoritative per-issue REST read | one complete open-issue inventory |
|
|
25
|
+
| N | 1 | one call regardless of brief count |
|
|
26
|
+
| Unknown state | **fail closed** (exit 1, `unresolved`) | **fail open** (exit 0, reported `unverified`) |
|
|
27
|
+
| Latency budget | 5 s | 15 s |
|
|
28
|
+
|
|
29
|
+
The unknown asymmetry is deliberate and predates this change. Scoped is a proof
|
|
30
|
+
obligation before a worker claims DONE about one named origin. The aggregate
|
|
31
|
+
sweep must not make offline work network-authorized — hard-failing every
|
|
32
|
+
aggregate unknown would break `--skip-gh`, offline runs, and fresh clones.
|
|
33
|
+
|
|
34
|
+
⊗ Do not flatten the two unknown policies into one rule.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## What each run is allowed to look at (#3893)
|
|
39
|
+
|
|
40
|
+
Mode decides *how* a verdict is reached. Scope decides *which briefs* are in
|
|
41
|
+
the question at all.
|
|
42
|
+
|
|
43
|
+
| | Bare / `--issue N` | `--changed-only` |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| Caller | doctor, manual runs, swarm finalize, after-merge DONE proof | `check:framework-source` / `check:consumer` merge chokepoint |
|
|
46
|
+
| Briefs evaluated | every running brief under `active/` | only briefs in the candidate's own diff against `origin/<deliveryBranch>` |
|
|
47
|
+
| On the delivery line | n/a | falls back to the full sweep -- this run *is* the delivery-tip check |
|
|
48
|
+
| Unresolvable git or base ref | n/a | falls back to the full sweep, never to a narrower scan |
|
|
49
|
+
|
|
50
|
+
The merge chokepoint was unscoped until #3893. Measured 2026-08-28: four
|
|
51
|
+
unrelated PRs failed the same two lanes on one stranded brief, one of them
|
|
52
|
+
passed an unchanged re-run once the strandings landed, and two single-brief
|
|
53
|
+
lifecycle PRs could not pass alone because each left the other orphan.
|
|
54
|
+
|
|
55
|
+
The pre-merge run was never preventive for its own candidate either: the gate
|
|
56
|
+
reads REST `merged_at`, and the candidate's linked PR still reads null while
|
|
57
|
+
that candidate's gate runs. The pre-merge signal for closeout residue is
|
|
58
|
+
`verify:pr-closeout-attestable` (#3781), which keys on the PR's structured
|
|
59
|
+
closing references rather than the branch diff.
|
|
60
|
+
|
|
61
|
+
The detector is unchanged. The linked-PR/open-issue signature still fails a
|
|
62
|
+
candidate whose own diff carries it.
|
|
63
|
+
|
|
64
|
+
⊗ Do not read a `--changed-only` pass as repo-wide truth. Every run prints its
|
|
65
|
+
scope; `EvaluateResult.scope` carries the same thing structurally.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## The freshness choice
|
|
70
|
+
|
|
71
|
+
**Age bound plus re-validation, applied per mode.** Both options offered by
|
|
72
|
+
#3767 are used, because each mode needs a different one.
|
|
73
|
+
|
|
74
|
+
- A cache hit is honoured only when it is at most **15 minutes** old
|
|
75
|
+
(`ISSUE_CACHE_MAX_AGE_MS`). Older entries are not evidence.
|
|
76
|
+
- Scoped `--issue N` re-validates first: it takes the authoritative read and
|
|
77
|
+
falls back to the cache only inside the age bound, when the live read is
|
|
78
|
+
unavailable. Unknown after that is `unresolved`.
|
|
79
|
+
- The aggregate sweep resolves from the open-issue inventory when the network
|
|
80
|
+
is allowed, and uses an in-bound cache hit only under `--skip-gh` or when the
|
|
81
|
+
inventory itself is unavailable.
|
|
82
|
+
|
|
83
|
+
15 minutes keeps a warm-cache offline run working while making an overnight
|
|
84
|
+
entry non-authoritative — the measured entry was roughly twelve hours old.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## The aggregate inventory
|
|
89
|
+
|
|
90
|
+
The sweep reuses `restIssueListOpenInventory` (#3752): one
|
|
91
|
+
`gh api --paginate --slurp repos/<owner>/<repo>/issues?state=open&per_page=100`
|
|
92
|
+
subprocess. It excludes pull-request rows and **fails closed** on command
|
|
93
|
+
failure, non-JSON output, a non-array payload, a malformed row, buffer
|
|
94
|
+
exhaustion, and the pagination cap.
|
|
95
|
+
|
|
96
|
+
! The inventory MUST be complete. `probeCacheDrift`'s helper defaults to a
|
|
97
|
+
1,000-item limit; reusing that capped set as a closed-state oracle would
|
|
98
|
+
misclassify open issue 1001+ in a larger repository.
|
|
99
|
+
|
|
100
|
+
Membership in a successful inventory means open. **Absence means "not open"**,
|
|
101
|
+
which is the direction that tells an operator to run `scope:complete` on what
|
|
102
|
+
may be live work — so absence is confirmed by one authoritative per-issue read
|
|
103
|
+
before the gate acts on it. That confirming result is reused for the rest of
|
|
104
|
+
the run when several briefs name the same issue. In the ordinary case
|
|
105
|
+
(everything open) that costs zero extra calls.
|
|
106
|
+
|
|
107
|
+
When the inventory is unavailable the gate reports `unverified` rather than
|
|
108
|
+
inferring closed. Fail-closed here means never manufacturing a false "closed",
|
|
109
|
+
not turning the sweep into a connectivity check.
|
|
110
|
+
|
|
111
|
+
### Why not a live read per brief
|
|
112
|
+
|
|
113
|
+
Per-brief live reads are the mechanism #3752 removed. Measured: the inventory
|
|
114
|
+
is **4.2 s constant**, against **14.2 s** and **76.6 s** for sequential
|
|
115
|
+
per-brief reads at the WIP cap of 20 on two different hosts. Crossover is about
|
|
116
|
+
5 briefs on `gh` and about 1 on `ghx`. `verify:orphan-active` sits in the
|
|
117
|
+
fast-preflight tier, where wall clock rather than REST quota is the constraint.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Reported basis
|
|
122
|
+
|
|
123
|
+
Every run now says how it decided, so a verified pass is distinguishable from
|
|
124
|
+
an unverified one:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
verify:orphan-active: no orphaned active/running xBRIEFs (scanned 3 running briefs in active/).
|
|
128
|
+
Basis: inventory 2, cache 1 (max age 4m).
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
verify:orphan-active: no orphaned active/running xBRIEFs (scanned 1 running brief in active/).
|
|
133
|
+
Basis: unverified 1.
|
|
134
|
+
UNVERIFIED: state could not be established for the references below, so this run is
|
|
135
|
+
not evidence that they are unshipped:
|
|
136
|
+
- #8001 (open-issue inventory unavailable: gh api failed: ...)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`EvaluateResult.basis` carries the same counts structurally
|
|
140
|
+
(`inventory`, `live`, `cache`, `unverified`, `maxCacheAgeMs`, `proxied`,
|
|
141
|
+
`elapsedMs`, `budgetMs`).
|
|
142
|
+
|
|
143
|
+
⊗ Do not cite an exit 0 with `unverified > 0` as evidence that a tree is clean.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## The `ghx` caveat
|
|
148
|
+
|
|
149
|
+
"Live" is itself a cache. `defaultRunGh` resolves through `resolveBinary()`,
|
|
150
|
+
which prefers **`ghx`**, a cached read-only GET proxy whose age nothing in this
|
|
151
|
+
gate can inspect.
|
|
152
|
+
|
|
153
|
+
This gate therefore **pins plain `gh`** for its authoritative reads when `gh` is
|
|
154
|
+
on PATH. When only `ghx` is available the gate still runs, sets
|
|
155
|
+
`basis.proxied`, and prints:
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
Note: reads resolved through `ghx`, a cached GET proxy; freshness is bounded by that
|
|
159
|
+
proxy, which this gate cannot inspect (#3737).
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
⊗ Do not claim the gate detects a closed origin "regardless of cache age" while
|
|
163
|
+
`ghx` is in the path. Whether `resolveBinary` should prefer `ghx` at all is
|
|
164
|
+
[#3737](https://github.com/deftai/directive/issues/3737).
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Latency budgets
|
|
169
|
+
|
|
170
|
+
There were none before #3767, which is why "affordable" was unfalsifiable.
|
|
171
|
+
|
|
172
|
+
| Mode | Budget | Basis |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| Scoped `--issue N` | 5 s | one issue read plus at most one linked-PR read, measured ~0.75 s each |
|
|
175
|
+
| Unscoped aggregate | 15 s | one 4.2 s inventory plus confirming reads for apparent closes |
|
|
176
|
+
|
|
177
|
+
Exceeding a budget prints an advisory line and does **not** change the exit
|
|
178
|
+
code. Budget drift is a signal to re-measure the mechanism, not a new failure
|
|
179
|
+
mode for callers.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Out of scope
|
|
184
|
+
|
|
185
|
+
- The offline crash when neither `gh` nor `ghx` is on PATH
|
|
186
|
+
([#3774](https://github.com/deftai/directive/issues/3774)).
|
|
187
|
+
- Whether `resolveBinary` should prefer `ghx`
|
|
188
|
+
([#3737](https://github.com/deftai/directive/issues/3737)).
|
|
189
|
+
- The `cache_fresh` forge-error fail-open decided on
|
|
190
|
+
[#3738](https://github.com/deftai/directive/issues/3738).
|
|
191
|
+
|
|
192
|
+
## Related
|
|
193
|
+
|
|
194
|
+
- [#3429](https://github.com/deftai/directive/issues/3429) — the gate's contract
|
|
195
|
+
- [#3476](https://github.com/deftai/directive/issues/3476) — `verify:completed-tracked`
|
|
196
|
+
- [#3752](https://github.com/deftai/directive/issues/3752) — the open-inventory mechanism reused here
|
|
197
|
+
- [#3156](https://github.com/deftai/directive/issues/3156) — gate integrity; this was a deliberate gate-definition change
|
|
198
|
+
- [#3893](https://github.com/deftai/directive/issues/3893) — merge-chokepoint scoping; the named check-composition change
|
|
199
|
+
- [#3781](https://github.com/deftai/directive/issues/3781) — `verify:pr-closeout-attestable`, the pre-merge closeout signal
|
package/docs/skill-pin-policy.md
CHANGED
|
@@ -13,7 +13,7 @@ Pins are for **false-negative-sensitive process gates**, not for copying entire
|
|
|
13
13
|
| Tier | Meaning | How the agent discovers it |
|
|
14
14
|
|---|---|---|
|
|
15
15
|
| **always-pin** | Named in AGENTS.md (managed or consumer unmanaged header) as a required `SKILL.md` load when a matching work type starts | Always-loaded AGENTS.md |
|
|
16
|
-
| **on-demand** | Routed via Skills Index triggers
|
|
16
|
+
| **on-demand** | Routed via Skills Index triggers (consumer: `npx deft packs:slice skills list`; maintainer: `REFERENCES.md`) — scan Level-0, read Level-1 on match | Skills Index → `SKILL.md` |
|
|
17
17
|
| **reference-only** | External, rare, or maintainer-only corpora; no standing trigger routing | Explicit doc pointer only |
|
|
18
18
|
|
|
19
19
|
### Criteria for always-pin
|
package/events/README.md
CHANGED
|
@@ -27,11 +27,11 @@ data-file-convention check ([#710](https://github.com/deftai/directive/issues/71
|
|
|
27
27
|
|
|
28
28
|
- **`detection-bound`** — detectable from filesystem state alone (e.g. dirty
|
|
29
29
|
tree, vBRIEF schema invalidity, version drift). Emitted via
|
|
30
|
-
`
|
|
30
|
+
`task lifecycle:event`. Detector lives at the call site documented in
|
|
31
31
|
the entry's `trigger` field.
|
|
32
32
|
- **`behavioral`** — requires runtime instrumentation (paired
|
|
33
33
|
`session:interrupted` / `session:resumed`, `plan:approved`,
|
|
34
|
-
`legacy:detected`). Emitted via `
|
|
34
|
+
`legacy:detected`). Emitted via `task lifecycle:event`, which manages 1:1
|
|
35
35
|
session-pair invariants and a JSONL append-only log at
|
|
36
36
|
`<project_root>/.deft-cache/events.jsonl`.
|
|
37
37
|
|
|
@@ -48,29 +48,28 @@ conforming to `event-record.schema.json`:
|
|
|
48
48
|
}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
`
|
|
51
|
+
`task lifecycle:event -- emit <name> ...` validates against the full
|
|
52
52
|
registry (any registered name is accepted) and is silent by default; when the
|
|
53
53
|
`DEFT_EVENT_LOG` environment variable points to a writable path, each
|
|
54
54
|
emission is appended as a single JSON line.
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
`<project_root>/.deft-cache/events.jsonl` (or a path injected via `
|
|
56
|
+
Behavioral emits validate against the `category="behavioral"` subset of the
|
|
57
|
+
registry, generate a sortable event id for pairing semantics, enforce
|
|
58
|
+
required-payload contracts, and persist to
|
|
59
|
+
`<project_root>/.deft-cache/events.jsonl` (or a path injected via `--log` /
|
|
60
60
|
`DEFT_EVENT_LOG`). The log lives under the already-gitignored `.deft-cache/`
|
|
61
61
|
rather than `.deft/`, because `.deft/` is not blanket-gitignored on hybrid
|
|
62
62
|
installs (`.deft/core/` is gitignored and reconstituted by `directive init`,
|
|
63
|
-
per #1942 / #1465).
|
|
64
|
-
|
|
63
|
+
per #1942 / #1465). Skills emit behavioral events with
|
|
64
|
+
`task lifecycle:event -- emit <name> ...`.
|
|
65
65
|
|
|
66
66
|
## Adding an event
|
|
67
67
|
|
|
68
68
|
1. Append the entry to `registry.json` with the appropriate `category`,
|
|
69
69
|
payload contract, trigger pointer, and consumer pointers (validate via
|
|
70
|
-
`
|
|
71
|
-
2. Add the detection / emission call site in
|
|
72
|
-
|
|
73
|
-
`scripts/_events.py` for behavioral).
|
|
70
|
+
`packages/core/src/lifecycle/events.ts` tests).
|
|
71
|
+
2. Add the detection / emission call site in the TypeScript lifecycle surface
|
|
72
|
+
(use `task lifecycle:event` for both detection-bound and behavioral events).
|
|
74
73
|
3. Reference the event by name from at least one consumer (skill, task,
|
|
75
74
|
script) so the surface stays usable -- the schema requires `consumers`
|
|
76
75
|
to be a non-empty array.
|
package/glossary.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/glossary.md" -->
|
|
1
2
|
# Glossary
|
|
2
3
|
|
|
3
4
|
The authoritative vocabulary for the Deft framework.
|
|
@@ -120,7 +121,7 @@ Canonical vocabulary for the xBRIEF lifecycle. **xBRIEF** / `xbrief/` is the sol
|
|
|
120
121
|
|
|
121
122
|
- **Cross-scope dependency** -- Dependency between two scope xBRIEFs at `plan.metadata.dependencies` (array of dependency IDs). See [vbrief/vbrief.md](./vbrief/vbrief.md).
|
|
122
123
|
|
|
123
|
-
- **Exit Commands** -- The seven deterministic `task scope:*` commands that transition a scope xBRIEF between lifecycle folders: `scope:promote`, `scope:activate`, `scope:complete`, `scope:cancel`, `scope:restore`, `scope:block`, `scope:unblock` (see [tasks/scope.yml](
|
|
124
|
+
- **Exit Commands** -- The seven deterministic `task scope:*` commands that transition a scope xBRIEF between lifecycle folders: `scope:promote`, `scope:activate`, `scope:complete`, `scope:cancel`, `scope:restore`, `scope:block`, `scope:unblock` (see [tasks/scope.yml](tasks/scope.yml)).
|
|
124
125
|
|
|
125
126
|
- **Origin provenance** -- A `references` entry linking a scope xBRIEF to its origin issue / ticket / user-request. Required for ingestion dedup. See [vbrief/vbrief.md](./vbrief/vbrief.md).
|
|
126
127
|
|
package/incidents/README.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/incidents/README.md" -->
|
|
1
2
|
# Incidents Library
|
|
2
3
|
|
|
3
4
|
This directory captures real-world incidents that motivated specific Deft
|
|
@@ -53,7 +54,7 @@ Examples:
|
|
|
53
54
|
- `2026-04-15-some-other-incident.md`
|
|
54
55
|
|
|
55
56
|
Filenames use hyphens, not underscores -- this mirrors the project-wide
|
|
56
|
-
filename convention in [`main.md`](
|
|
57
|
+
filename convention in [`main.md`](../main.md).
|
|
57
58
|
|
|
58
59
|
## When to add an entry
|
|
59
60
|
|
package/interfaces/cli.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/interfaces/cli.md" -->
|
|
1
2
|
# CLI Best Practices
|
|
2
3
|
|
|
3
4
|
Opinionated patterns for command-line interfaces with AI agents.
|
|
@@ -110,4 +111,4 @@ else:
|
|
|
110
111
|
|
|
111
112
|
---
|
|
112
113
|
|
|
113
|
-
**See also**: [python.md](../languages/python.md) | [typescript.md](../languages/typescript.md) | [tui.md](
|
|
114
|
+
**See also**: [python.md](../languages/python.md) | [typescript.md](../languages/typescript.md) | [tui.md](tui.md)
|
package/languages/6502-DASM.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/6502-DASM.md" -->
|
|
1
2
|
# 6502 + DASM Standards
|
|
2
3
|
|
|
3
4
|
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
4
5
|
|
|
5
|
-
**⚠️ See also**: [main.md](
|
|
6
|
+
**⚠️ See also**: [main.md](../main.md) | [PROJECT.md](../../PROJECT.md)
|
|
6
7
|
|
|
7
8
|
## Scope
|
|
8
9
|
- This guide covers:
|
package/languages/c.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/c.md" -->
|
|
1
2
|
# C Standards
|
|
2
3
|
|
|
3
4
|
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
4
5
|
|
|
5
|
-
**⚠️ See also**: [main.md](
|
|
6
|
+
**⚠️ See also**: [main.md](../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
|
|
6
7
|
|
|
7
8
|
**Stack**: C17/C23, CMake 3.25+, clang/GCC; Testing: Unity/cmocka; Analysis: clang-tidy, cppcheck, AddressSanitizer
|
|
8
9
|
|
package/languages/cpp.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/cpp.md" -->
|
|
1
2
|
# C++ Standards
|
|
2
3
|
|
|
3
4
|
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
4
5
|
|
|
5
|
-
**⚠️ See also**: [main.md](
|
|
6
|
+
**⚠️ See also**: [main.md](../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
|
|
6
7
|
|
|
7
8
|
**Stack**: C++20/23, CMake 3.25+, Catch2/GoogleTest, GSL (Guidelines Support Library); CLI: CLI11; TUI: FTXUI; Async: Asio/libcoro
|
|
8
9
|
|
package/languages/csharp.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/csharp.md" -->
|
|
1
2
|
# C# Standards
|
|
2
3
|
|
|
3
4
|
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
4
5
|
|
|
5
|
-
**⚠️ See also**: [main.md](
|
|
6
|
+
**⚠️ See also**: [main.md](../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
|
|
6
7
|
|
|
7
8
|
**Stack**: C# 12+/.NET 8+ (LTS), SDK-style projects; Web: ASP.NET Core/Minimal APIs; Testing: xUnit + NSubstitute + FluentAssertions; Analysis: Roslyn Analyzers, StyleCop.Analyzers
|
|
8
9
|
|
package/languages/dart.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/dart.md" -->
|
|
1
2
|
# Dart Standards
|
|
2
3
|
|
|
3
4
|
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
4
5
|
|
|
5
|
-
**⚠️ See also**: [main.md](
|
|
6
|
+
**⚠️ See also**: [main.md](../main.md) | [PROJECT.md](../../PROJECT.md)
|
|
6
7
|
|
|
7
8
|
**Stack**: Dart 3.x+; Framework: Flutter (mobile/web) or standalone; Testing: `package:test` / `flutter_test`; Lint: `analysis_options.yaml` + custom_lint; Format: `dart format`; Docs: dartdoc
|
|
8
9
|
|
package/languages/delphi.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/delphi.md" -->
|
|
1
2
|
# Delphi / Object Pascal Standards
|
|
2
3
|
|
|
3
4
|
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
4
5
|
|
|
5
|
-
**⚠️ See also**: [main.md](
|
|
6
|
+
**⚠️ See also**: [main.md](../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
|
|
6
7
|
|
|
7
8
|
**Stack**: Delphi 12+/Object Pascal, RAD Studio; GUI: VCL (Windows), FMX (cross-platform); DB: FireDAC; Testing: DUnitX
|
|
8
9
|
|
package/languages/elixir.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/elixir.md" -->
|
|
1
2
|
# Elixir Standards
|
|
2
3
|
|
|
3
4
|
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
4
5
|
|
|
5
|
-
**⚠️ See also**: [main.md](
|
|
6
|
+
**⚠️ See also**: [main.md](../main.md) | [PROJECT.md](../../PROJECT.md)
|
|
6
7
|
|
|
7
8
|
**Stack**: Elixir 1.16+ / OTP 26+; Build: Mix; Testing: ExUnit; Lint: Credo; Format: `mix format`; Docs: ExDoc; Types: Dialyxir
|
|
8
9
|
|