@deftai/directive-content 0.108.0 → 0.109.1
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 +18 -3
- package/UPGRADING.md +7 -6
- 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 +21 -16
- package/contracts/deposit-required-paths.json +26 -0
- package/contracts/design-critique.md +96 -1
- package/contracts/deterministic-questions.md +2 -1
- package/contracts/host-lifecycle-duties.md +1 -1
- package/contracts/path-write-fence.md +72 -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 +2 -0
- package/docs/gate-integrity.md +17 -2
- package/docs/hook-root-admission.md +150 -0
- package/docs/host-surface-assumptions.md +4 -1
- package/docs/host-tool-surface-audit.md +163 -0
- package/docs/orphan-active-verdict-basis.md +33 -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 +8 -8
- 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 +10 -6
- package/skills/deft-directive-build/SKILL.md +7 -7
- package/skills/deft-directive-gh-slice/SKILL.md +1 -1
- package/skills/deft-directive-interview/SKILL.md +5 -5
- 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 +9 -9
- package/skills/deft-directive-setup/SKILL.md +3 -2
- 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/vbrief.yml +6 -2
- package/tasks/verify.yml +40 -1
- package/templates/agent-prompt-preamble.md +2 -2
- package/templates/agents-entry.md +2 -2
- 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
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Hook root admission — which tree a gated write is judged against (#3794 / #4013)
|
|
2
|
+
|
|
3
|
+
Every PreToolUse mutation carries **two** roots, and they are not interchangeable:
|
|
4
|
+
|
|
5
|
+
- **payload root** — the project root the host hook payload names.
|
|
6
|
+
- **effective root** — the working tree the write target actually lands in, chosen by
|
|
7
|
+
`admitEffectiveHookRoot` from the target path.
|
|
8
|
+
|
|
9
|
+
Deny messages name both: `payloadRoot=<path> effectiveRoot=<path>`.
|
|
10
|
+
|
|
11
|
+
This page publishes what root admission decides, which gate reads which root, and why the
|
|
12
|
+
no-toplevel case behaves the way it does. It describes shipped behaviour; it changes none of it.
|
|
13
|
+
|
|
14
|
+
## The outcomes of root admission
|
|
15
|
+
|
|
16
|
+
| Target's nearest existing ancestor resolves to | Outcome | Effective root |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| The payload root itself | admit | payload root |
|
|
19
|
+
| Another working tree sharing `--git-common-dir` with the payload root | admit | that worktree |
|
|
20
|
+
| Another Git toplevel, while the payload root is not a Git repository | admit — no containment question exists | payload root |
|
|
21
|
+
| Another Git toplevel whose `--git-common-dir` cannot be read | refuse `unproven-identity` | — (deny) |
|
|
22
|
+
| A proven different repository | refuse `foreign-repository` | — (deny) |
|
|
23
|
+
| **No Git toplevel at all** | **admit** | **payload root** |
|
|
24
|
+
|
|
25
|
+
Set level: `admitMutationTargetSet` admits every member of one mutation (the declared ApplyPatch
|
|
26
|
+
path plus every path in the patch body), short-circuits on the first refused member, and then
|
|
27
|
+
requires **one unique** effective root across the members. Two admitted roots is a
|
|
28
|
+
`worktree-span` refusal, so occupancy and ritual cannot follow only the declared path.
|
|
29
|
+
|
|
30
|
+
The last row is the subject of #4013. It fires for any destination whose nearest existing ancestor
|
|
31
|
+
directory is not inside a Git working tree — a path under the OS temp directory, a file in the home
|
|
32
|
+
directory, a scratch directory outside every checkout.
|
|
33
|
+
|
|
34
|
+
## The no-toplevel case is deliberate
|
|
35
|
+
|
|
36
|
+
**A write target with no Git toplevel is gated against the payload root. That is intended, not a
|
|
37
|
+
gap.** #3794's acceptance text required falling back to the payload root when a target worktree
|
|
38
|
+
could not be admitted, and commit `bcd9d34e` deliberately split the two situations that fallback
|
|
39
|
+
used to hold: a target that resolves to *some other* toplevel whose identity cannot be read now
|
|
40
|
+
fails closed as `unproven-identity`, while a target with *no* toplevel keeps the payload-root
|
|
41
|
+
behaviour. "A question asked and left unanswered" is the rationale for the fail-closed branch. It
|
|
42
|
+
is not the rationale for this one — no containment question was ever posed.
|
|
43
|
+
|
|
44
|
+
Three measured reasons the fallback is not a lease bug (#4013, accepted successor lean
|
|
45
|
+
[5481139589](https://github.com/deftai/directive/issues/4013#issuecomment-5481139589)):
|
|
46
|
+
|
|
47
|
+
1. **The effective root selects more than a lease.** It is the input to occupancy, the session
|
|
48
|
+
ritual, active scope, the story write fence and assist-scratch classification. "No root, no
|
|
49
|
+
gating" would drop all of those for an out-of-tree write, so an unritualed session — or an agent
|
|
50
|
+
acting on an absolute path it read in an issue — could write a home, config or temp file with no
|
|
51
|
+
ritual and no scope basis. It would also buy nothing on active scope, which already exempts
|
|
52
|
+
outside-root writes (#2885).
|
|
53
|
+
2. **Occupancy and ritual are cross-checked, and the allow path re-stamps the lease.** The admitted
|
|
54
|
+
owner is compared against the session the verified ritual is bound to. Relaxing only the
|
|
55
|
+
foreign-lease refusal either leaves the writer blocked by that comparison, or suppresses it and
|
|
56
|
+
lets one session ride another's ceremony. The same path re-stamps `heartbeat_at` immediately
|
|
57
|
+
before an allowed write, so an unrelated out-of-tree write would renew the very lease a
|
|
58
|
+
narrowing meant to decouple.
|
|
59
|
+
3. **A nullable root has no defined behaviour for a multi-target patch.** Target-set admission
|
|
60
|
+
demands one unique root. If an outside member contributed nothing, a patch mixing a
|
|
61
|
+
linked-worktree edit with an injected absolute path could collapse to the linked root and evade
|
|
62
|
+
the `worktree-span` refusal; if absence dominated instead, one outside member would suppress the
|
|
63
|
+
gates for the in-tree edit beside it. Either way an untrusted patch path becomes an
|
|
64
|
+
authority-selection input — the containment risk #3794 closed.
|
|
65
|
+
|
|
66
|
+
The friction is real: a foreign lease holder should not block an unrelated note under the OS temp
|
|
67
|
+
directory. Relieving it costs a change to the authority contract, not a bug fix. See
|
|
68
|
+
[What a narrowing would have to define](#what-a-narrowing-would-have-to-define).
|
|
69
|
+
|
|
70
|
+
## What still runs for a no-toplevel target, gate by gate
|
|
71
|
+
|
|
72
|
+
| Gate | Root it reads | Disposition |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| Occupancy lease | effective root (= payload root here) | **Runs.** A live foreign lease on the payload root denies `occupancy-occupied`; the owner or a granted member is admitted. |
|
|
75
|
+
| Session ritual, gated tier | effective root (= payload root here) | **Runs**, including the occupancy↔ritual owner cross-check and the pre-allow re-check. |
|
|
76
|
+
| Authz / UAT grant scoping | payload root | **Payload-root authoritative**, unchanged by admission. |
|
|
77
|
+
| Authz audit trail | payload root | **Payload-root authoritative.** |
|
|
78
|
+
| Kill-switch (`.deft-directive-disable`) | payload root | **Payload-root authoritative.** A flag beside the target does not disable the gate. |
|
|
79
|
+
| `deny().projectRoot` | payload root | **Payload-root authoritative**, so a deny is reported against the tree the host named. |
|
|
80
|
+
| Mutation intent ceiling (#1193) | neither | **Runs independently** of both roots. |
|
|
81
|
+
| Read-only posture | neither | **Runs.** |
|
|
82
|
+
| Runtime authority / path write fence | project policy from the payload root; story `file_scope` and the path it matches from the effective root | **Runs** when enabled. |
|
|
83
|
+
| Active scope | effective root | **Inspected, deny skipped.** The not-ready deny is skipped by the #2885 outside-root carve-out, measured from the payload root. Spawn tools have no write target and still require scope. |
|
|
84
|
+
| Assist-scratch allowlist | effective root | **No match.** An out-of-tree target is not under `.deft-scratch/` or `temp/` relative to the effective root, so the low-ceremony path does not apply. |
|
|
85
|
+
|
|
86
|
+
Read that table as the answer to "what does the lease actually protect here". The case is not a
|
|
87
|
+
lease question with one disposition; it is a root-selection question with a disposition per gate.
|
|
88
|
+
|
|
89
|
+
## Three surfaces, three behaviours
|
|
90
|
+
|
|
91
|
+
The fallback is a **direct-write** behaviour. It does not generalise across transports.
|
|
92
|
+
|
|
93
|
+
| Surface | Example tool name | Reaches root admission? | Out-of-tree destination |
|
|
94
|
+
| --- | --- | --- | --- |
|
|
95
|
+
| Direct write, bare host name | `Write`, `Edit`, `search_replace`, `ApplyPatch` | **Yes** | Judged against the payload root — the fallback above. |
|
|
96
|
+
| Generic server-prefixed MCP | `tasks__search_replace` | **No** | Routed only through push/merge runtime classification; unrecognized there, so `shell-op-unclassifiable` (fail open). |
|
|
97
|
+
| Recognized Shell file-write | `Set-Content -Path <os-temp>/note.md …` | **No** | `isInRepoShellWritePath` rejects destinations resolving outside the project root, so the #3987 reissue path skips them (fail open). |
|
|
98
|
+
|
|
99
|
+
Catalogued MCP push/merge names (`git_push`, `merge_pull_request`, …) *are* gated — by runtime
|
|
100
|
+
authority scopes, which is a different gate and does not consult root admission either.
|
|
101
|
+
|
|
102
|
+
⊗ Do not state that the payload-root fallback fires "on the direct-write and MCP surfaces". #4013's
|
|
103
|
+
issue body said that and it is wrong for generic MCP. Three surfaces, three behaviours.
|
|
104
|
+
|
|
105
|
+
## Known limitation — relative targets have no declared base (#4023)
|
|
106
|
+
|
|
107
|
+
`existingAncestorDir` resolves the write target with `resolve(targetPath)` and no base argument, so
|
|
108
|
+
a **relative** target is canonicalized against the hook **process** working directory rather than
|
|
109
|
+
the payload root or a host-supplied cwd. The same lexical target can therefore land in different
|
|
110
|
+
rows of the first table depending only on where the hook runs. Symlink and Windows-junction targets
|
|
111
|
+
shift the class the same way: a junction into a linked worktree admits that worktree, a junction
|
|
112
|
+
into a non-repository directory falls back to the payload root.
|
|
113
|
+
|
|
114
|
+
Recorded, not fixed by #4013. Canonicalization changes admission classification, so it needs its own
|
|
115
|
+
arc: **#4023**.
|
|
116
|
+
|
|
117
|
+
## What a narrowing would have to define
|
|
118
|
+
|
|
119
|
+
A narrowing is refused *as filed*, not forever. A viable successor design would:
|
|
120
|
+
|
|
121
|
+
1. Name a target-class lattice: same admitted worktree, same-repository other worktree, foreign
|
|
122
|
+
repository, unproven identity, proven no-toplevel.
|
|
123
|
+
2. State the combining rule for every mixed target set, so `admitMutationTargetSet` still yields one
|
|
124
|
+
answer.
|
|
125
|
+
3. Keep the `foreign-repository`, `unproven-identity` and `worktree-span` refusals ahead of any
|
|
126
|
+
exemption.
|
|
127
|
+
4. State, per gate in the table above, whether the exemption changes that gate — including whether a
|
|
128
|
+
no-toplevel write may refresh any worktree lease, and whose ritual satisfies it.
|
|
129
|
+
5. Canonicalize targets first (#4023).
|
|
130
|
+
|
|
131
|
+
None of that would make #4013's filed premise — that the fallback is a defect — true.
|
|
132
|
+
|
|
133
|
+
## Scope of this guarantee
|
|
134
|
+
|
|
135
|
+
Root admission is **cooperative host-session routing**, the same posture as the occupancy lease it
|
|
136
|
+
selects: hook payloads and local session ids are forgeable by a same-user process. It bounds
|
|
137
|
+
careless cross-tree writes; it is not an authentication boundary against an adversarial agent. See
|
|
138
|
+
[`contracts/path-write-fence.md`](../contracts/path-write-fence.md) for the same limit stated for
|
|
139
|
+
the write fence.
|
|
140
|
+
|
|
141
|
+
## Code
|
|
142
|
+
|
|
143
|
+
| Concern | Where |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| Root admission, single target and target set | `packages/core/src/hooks/dispatcher.ts` — `admitEffectiveHookRoot`, `admitMutationTargetSet` |
|
|
146
|
+
| Which gate reads which root | `packages/core/src/hooks/dispatcher.ts` — `inspectMutationGates` header comment |
|
|
147
|
+
| Nearest existing ancestor, toplevel and common-dir lookups | `packages/core/src/session/git.ts` — `existingAncestorDir`, `worktreePathOrNull`, `gitCommonDir` |
|
|
148
|
+
| Shell write-dest classification and the in-repo predicate | `packages/core/src/hooks/shell-write-targets.ts` — `isInRepoShellWritePath` |
|
|
149
|
+
| Tool-name surfaces | `packages/core/src/hooks/tools.ts` — `isDirectWriteTool`, `isShellTool`, `isMcpTool` |
|
|
150
|
+
| Behaviour lock | `packages/core/src/hooks/dispatcher-effective-root.test.ts` |
|
|
@@ -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.
|
|
@@ -115,6 +116,8 @@ Where the host supports hooks, **deny writes to directive-managed paths** withou
|
|
|
115
116
|
| **Tier-1 host hooks** | PreToolUse / equivalent intercept Write/Edit/Shell that target managed paths (AGENTS managed section, deposit, pin skill paths the host exposes) |
|
|
116
117
|
| **Path write fence** | Project + story `file_scope` evaluation — [`path-write-fence.md`](../contracts/path-write-fence.md) |
|
|
117
118
|
| **Agent hook readiness** | `deft verify:hooks-installed --scope=agent --live` — [`agent-hook-readiness.md`](../contracts/agent-hook-readiness.md) |
|
|
119
|
+
| **Host tool-surface coverage** | Which tool names each host's matcher actually selects, and which are recorded out of scope — [`host-tool-surface-audit.md`](./host-tool-surface-audit.md) (#3987) |
|
|
120
|
+
| **Root admission** | Which working tree a gated write is judged against, gate by gate, and which surfaces consult it — [`hook-root-admission.md`](./hook-root-admission.md) (#3794 / #4013) |
|
|
118
121
|
| **Policy** | `plan.policy.hostHooks.<host>` — inspect with `deft policy:show --field=hostHooks` |
|
|
119
122
|
|
|
120
123
|
! When hooks are available, treat managed-path deny as the enforcement home for constitution bytes — not agent good behavior alone.
|
|
@@ -131,7 +134,7 @@ Named hook home for managed-path deny: **Tier-1 host hooks** (`packages/core/src
|
|
|
131
134
|
|
|
132
135
|
| Topic | Where |
|
|
133
136
|
|-------|--------|
|
|
134
|
-
| Self-improving, not self-editing stance | [main.md § Self-Improving, Not Self-Editing (#3164)](
|
|
137
|
+
| 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
138
|
| Gate integrity (do not clear red by editing the gate) | [gate-integrity.md](./gate-integrity.md) (#3156); refine-internal #2436 separate |
|
|
136
139
|
| Skill pin tiers (process pins, not full #830) | [skill-pin-policy.md](./skill-pin-policy.md) |
|
|
137
140
|
| Host lifecycle duty list | [host-lifecycle-duties.md](../contracts/host-lifecycle-duties.md) |
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Host tool-surface audit (#3987)
|
|
2
|
+
|
|
3
|
+
The PreToolUse write gate only runs on tool names the host's deposited matcher
|
|
4
|
+
selects. A name nobody listed is not a permissive policy — it is a gate that
|
|
5
|
+
never executes. #3987 was exactly that: Grok Build's shell tool
|
|
6
|
+
`run_terminal_command` was in no matcher, so a write the gate refused could be
|
|
7
|
+
reissued through the shell and land unobserved.
|
|
8
|
+
|
|
9
|
+
This file is the recorded answer to acceptance item 2: **for every tool name a
|
|
10
|
+
supported host emits, either the deposited matcher covers it, or there is a
|
|
11
|
+
written reason it stays out of scope.** The machine-readable form is
|
|
12
|
+
`HOST_TOOL_SURFACE_AUDIT` in `packages/core/src/hooks/tools.ts`, and
|
|
13
|
+
`deft verify:hooks-installed --scope=agent` fails closed on any silence in it.
|
|
14
|
+
|
|
15
|
+
Legend (RFC2119): `!`=MUST, `~`=SHOULD, `⊗`=MUST NOT.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Two layers that can disagree
|
|
20
|
+
|
|
21
|
+
| Layer | Form | Where |
|
|
22
|
+
|-------|------|-------|
|
|
23
|
+
| Deposited matcher | literal `a\|b\|c` alternation the host matches against | `.claude/settings.json`, `.grok/hooks/deft.json`, `.cursor/hooks.json`, `.codex/hooks.json` |
|
|
24
|
+
| Runtime classifier | lowercases and strips non-alphanumerics, then set-membership | `isDirectWriteTool` / `isShellTool` / `isSpawnTool` |
|
|
25
|
+
|
|
26
|
+
Both read the same constants, so they normally agree — but a name can be
|
|
27
|
+
present in one and useless in the other. A matcher entry the classifier does not
|
|
28
|
+
recognize invokes the hook and then falls through to `not-direct-write`; a
|
|
29
|
+
classifier entry the deposit omits is never reached at all. The coverage check
|
|
30
|
+
asserts **both** for every catalogued name, so a fix has to say which layer it
|
|
31
|
+
changed.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Grok Build — fully observed
|
|
36
|
+
|
|
37
|
+
Source: this host's published tool list, plus the 5,354-call session census
|
|
38
|
+
recorded on [#3987](https://github.com/deftai/directive/issues/3987).
|
|
39
|
+
|
|
40
|
+
| Tool | Disposition |
|
|
41
|
+
|------|-------------|
|
|
42
|
+
| `write` | covered — direct write |
|
|
43
|
+
| `search_replace` | covered — direct write |
|
|
44
|
+
| `run_terminal_command` | covered — shell (#3990) |
|
|
45
|
+
| `monitor` | covered — shell; it runs an arbitrary background shell command, so omitting it reproduces the #3987 gap one tool over |
|
|
46
|
+
| `spawn_subagent` | covered — spawn |
|
|
47
|
+
| `read_file`, `grep`, `list_dir`, `search_tool`, `web_search`, `web_fetch` | out of scope — read |
|
|
48
|
+
| `todo_write` | out of scope — session-local non-product scratch |
|
|
49
|
+
| `get_command_or_subagent_output`, `wait_commands_or_subagents` | out of scope — poll over already-dispatched work |
|
|
50
|
+
| `kill_command_or_subagent` | out of scope — process control |
|
|
51
|
+
| `scheduler_delete`, `scheduler_list` | out of scope — scheduler control and read; mutate no product path |
|
|
52
|
+
| `enter_plan_mode`, `exit_plan_mode` | out of scope — session posture |
|
|
53
|
+
| `image_gen`, `image_edit`, `image_to_video`, `reference_to_video` | out of scope — generated media lands in session scratch, never a tracked product path |
|
|
54
|
+
| `scheduler_create` | **known gap, not covered** — see below |
|
|
55
|
+
| `use_tool` | **known gap, not covered** — see below |
|
|
56
|
+
|
|
57
|
+
### `scheduler_create` — spawn-class, needs a policy decision
|
|
58
|
+
|
|
59
|
+
It dispatches a background subagent on an interval, which is spawn-class by the
|
|
60
|
+
same reading that puts `spawn_subagent` in the matcher. Covering it routes a
|
|
61
|
+
scheduling primitive through the full spawn stack (session ritual plus an active
|
|
62
|
+
xBRIEF), which denies a shape that works today — a new deny class, not a
|
|
63
|
+
coverage repair. That is a deliberate policy call and belongs in its own change,
|
|
64
|
+
not in a matcher edit.
|
|
65
|
+
|
|
66
|
+
### `use_tool` — mcp-class, needs a classifier change
|
|
67
|
+
|
|
68
|
+
`use_tool` is a proxy: the MCP tool actually invoked is nested in
|
|
69
|
+
`tool_input.tool_name`, and the dispatcher classifies on the outer name only. A
|
|
70
|
+
matcher entry alone would buy a hook invocation and no enforcement, because
|
|
71
|
+
`isMcpTool("use_tool")` is false and `classifyMcpTool` returns null. Reading the
|
|
72
|
+
inner name is a classifier change with its own untrusted-input surface.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Claude, Codex, Cursor — partly or wholly unobserved
|
|
77
|
+
|
|
78
|
+
The deposit asserting a spelling is **not** evidence that the host emits it. All
|
|
79
|
+
four deposits carry the identical shell matcher, which is a matcher-string fact,
|
|
80
|
+
not a coverage fact ([#3987 comment 5471374558](https://github.com/deftai/directive/issues/3987#issuecomment-5471374558) F8).
|
|
81
|
+
|
|
82
|
+
| Host | Established | Unobserved |
|
|
83
|
+
|------|-------------|------------|
|
|
84
|
+
| Claude Code | shell `Bash` | direct-write and spawn spellings |
|
|
85
|
+
| Codex | shell `shell`; `apply_patch` write form (#3614) | everything else |
|
|
86
|
+
| Cursor | nothing | the whole surface |
|
|
87
|
+
|
|
88
|
+
Cursor is the one that matters: nothing in this tree observes which tool names
|
|
89
|
+
it emits on `preToolUse`. The fixture corpus asserts the framework's own
|
|
90
|
+
assumption, and `agent-hooks.test.ts` asserts the deposit contains a string.
|
|
91
|
+
Neither observes the host. Cursor could be a second zero-coverage host by the
|
|
92
|
+
exact mechanism that produced #3987, and the evidence available here would not
|
|
93
|
+
distinguish that from working coverage.
|
|
94
|
+
|
|
95
|
+
! Closing these requires an **observed** PreToolUse payload per host, not a
|
|
96
|
+
re-reading of the deposit.
|
|
97
|
+
|
|
98
|
+
⊗ Fill a host's catalog from the deposit, the matcher constants, or the fixture
|
|
99
|
+
corpus. That makes the check assert its own input and hides the gap it exists
|
|
100
|
+
to find.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## The check
|
|
105
|
+
|
|
106
|
+
`deft verify:hooks-installed --scope=agent` (also run by `deft doctor`) fails
|
|
107
|
+
closed on four silences:
|
|
108
|
+
|
|
109
|
+
| Finding | Meaning |
|
|
110
|
+
|---------|---------|
|
|
111
|
+
| `missing-audit` | a supported host has no entry here at all — the "new host drops out of coverage" case |
|
|
112
|
+
| `uncovered-tool` | a catalogued mutation name is absent from every **deposited** matcher — the "renamed tool" case, read from the file rather than regenerated |
|
|
113
|
+
| `unclassified-tool` | a catalogued name the runtime classifier does not place in the same group |
|
|
114
|
+
| `unexplained-entry` | an out-of-scope entry with no reason, a host claiming full observation while naming no mutation tool, or a non-mutation entry the classifier actually gates |
|
|
115
|
+
|
|
116
|
+
A hand-edited deposit reads as **stale** first, and `deft update` is the remedy
|
|
117
|
+
for that; the coverage message is for gaps a current deposit still leaves.
|
|
118
|
+
|
|
119
|
+
Implementation: `packages/core/src/init-deposit/host-tool-coverage.ts`.
|
|
120
|
+
Catalog: `packages/core/src/hooks/tools.ts`.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Why coverage alone did not close #3987
|
|
125
|
+
|
|
126
|
+
Matcher coverage is necessary and not sufficient — all three seats of the #3987
|
|
127
|
+
panel agreed. Coverage closes the reissue bypass. It does not keep the occupancy
|
|
128
|
+
lease alive, because the lease renews on a **gated write**, and eligibility
|
|
129
|
+
keeps almost all real shell traffic off that path: five recognized write verbs,
|
|
130
|
+
no dest carrying `$` / `*` / `?`, nothing out of root or in OS temp, and any
|
|
131
|
+
compound command refused before the gate. `cd <root>; <command>` is compound,
|
|
132
|
+
and the mandated Windows body-file flow (#2646 / #2744) fails all three
|
|
133
|
+
conditions at once.
|
|
134
|
+
|
|
135
|
+
The renewal half is `restampOwnerLivenessOnHookEvent`
|
|
136
|
+
(`packages/core/src/hooks/owner-liveness.ts`): the hook already resolves the
|
|
137
|
+
owner from the host payload, so a matched tool call renews the lease even when
|
|
138
|
+
it writes nothing. It is bounded to a host-authoritative owner, keeps
|
|
139
|
+
`markWrite` false, and never touches `claimed_at`, so `OCCUPANCY_MAX_LEASE_MS`
|
|
140
|
+
still ends the lease at 12 hours. It renews the tree the mutation gates
|
|
141
|
+
authorized against — a linked worktree under `.deft-scratch/`, not the payload
|
|
142
|
+
root — so a worktree write does not keep the primary checkout's lease alive
|
|
143
|
+
while the tree actually in use expires.
|
|
144
|
+
|
|
145
|
+
! A call with **no write target** proves only the tree the host named.
|
|
146
|
+
`projectRootFromHookPayload` takes that from the payload's own `cwd`-class
|
|
147
|
+
fields, so a session working inside a worktree names the worktree and renews
|
|
148
|
+
it. When the host reports a root that is not the tree the work is in, and no
|
|
149
|
+
write target says otherwise, nothing is renewed. That is deliberate: renewing a
|
|
150
|
+
guessed tree would keep a lease alive for a tree nobody occupies, and reclaiming
|
|
151
|
+
an unused tree is what the TTL is for. `deft occupancy:heartbeat --session-id
|
|
152
|
+
<owner>` remains the explicit path for a long, quiet session.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Cross-links
|
|
157
|
+
|
|
158
|
+
| Topic | Where |
|
|
159
|
+
|-------|-------|
|
|
160
|
+
| Gate integrity (do not clear red by editing the gate) | [`gate-integrity.md`](./gate-integrity.md) |
|
|
161
|
+
| Host honesty limits | [`host-surface-assumptions.md`](./host-surface-assumptions.md) |
|
|
162
|
+
| Agent hook readiness | [`agent-hook-readiness.md`](../contracts/agent-hook-readiness.md) |
|
|
163
|
+
| Occupancy lease and its bounds | `packages/core/src/session/occupancy.ts` |
|
|
@@ -35,6 +35,37 @@ aggregate unknown would break `--skip-gh`, offline runs, and fresh clones.
|
|
|
35
35
|
|
|
36
36
|
---
|
|
37
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
|
+
|
|
38
69
|
## The freshness choice
|
|
39
70
|
|
|
40
71
|
**Age bound plus re-validation, applied per mode.** Both options offered by
|
|
@@ -164,3 +195,5 @@ mode for callers.
|
|
|
164
195
|
- [#3476](https://github.com/deftai/directive/issues/3476) — `verify:completed-tracked`
|
|
165
196
|
- [#3752](https://github.com/deftai/directive/issues/3752) — the open-inventory mechanism reused here
|
|
166
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
|
|
package/languages/go.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/go.md" -->
|
|
1
2
|
# Go 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
|
## Standards
|
|
8
9
|
|
package/languages/java.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/java.md" -->
|
|
1
2
|
# Java 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**: Java 21+ (LTS), Maven/Gradle; Web: Spring Boot 3+; Testing: JUnit 5 + Mockito + AssertJ; Analysis: Checkstyle, SpotBugs, Error Prone
|
|
8
9
|
|
package/languages/javascript.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/javascript.md" -->
|
|
1
2
|
# JavaScript 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**: ES2022+, Node 20+; Build: Vite/esbuild; Testing: Vitest/Jest; Lint: ESLint + Prettier; Web: React/Next.js
|
|
8
9
|
|
package/languages/julia.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/julia.md" -->
|
|
1
2
|
# Julia 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**: Julia 1.10+; Packages: Pkg.jl; Testing: `Test` stdlib + Aqua.jl; Docs: Documenter.jl; Format: JuliaFormatter.jl; Lint: JET.jl / Aqua.jl
|
|
8
9
|
|
package/languages/kotlin.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<!-- deft:deposit-link-rewrite v=1 source="content/languages/kotlin.md" -->
|
|
1
2
|
# Kotlin 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**: Kotlin 2.0+; Build: Gradle (Kotlin DSL); Testing: JUnit 5 + kotest; Lint: detekt; Format: ktfmt/ktlint; Docs: KDoc
|
|
8
9
|
|