@deftai/directive-content 0.116.0 → 0.118.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/SKILL.md +1 -1
- package/Taskfile.yml +5 -0
- package/commands.md +12 -10
- package/contracts/design-critique.md +26 -19
- package/contracts/human-origin-authz.md +1 -1
- package/docs/consumer-check-contract.md +3 -0
- package/docs/gate-integrity.md +25 -2
- package/docs/grok-build-subscription-setup.md +9 -1
- package/docs/host-tool-surface-audit.md +6 -6
- package/docs/orphan-active-verdict-basis.md +11 -1
- package/docs/plan-acceptance.md +53 -0
- package/main.md +1 -1
- package/package.json +1 -1
- package/packs/skills/skills-pack-0.1.json +7 -7
- package/packs/strategies/strategies-pack-0.1.json +2 -2
- package/skills/deft-directive-build/SKILL.md +8 -7
- package/skills/deft-directive-design-critique/SKILL.md +2 -2
- package/skills/deft-directive-pre-pr/SKILL.md +6 -6
- package/skills/deft-directive-refinement/SKILL.md +1 -1
- package/skills/deft-directive-release/SKILL.md +28 -1
- package/skills/deft-directive-setup/SKILL.md +48 -8
- package/skills/deft-directive-swarm/references/core-phase-0.md +2 -0
- package/strategies/emit-hints.md +1 -0
- package/strategies/interview.md +55 -11
- package/tasks/verify.yml +24 -2
- package/templates/agent-prompt-preamble.md +1 -1
- package/templates/agents-entry.md +8 -7
- package/vbrief/schemas/vbrief-core.schema.json +1 -1
package/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- DEFT-PREAMBLE-V1 -->
|
|
2
2
|
<!--
|
|
3
3
|
! Cold-start check: deft runs from the npm-installed engine (`npm i -g @deftai/directive`). If neither `deft` nor `directive` will run on this machine, do not proceed with the instructions below -- recover first (#1933 Option 1, deprecate-by-disuse).
|
|
4
|
-
! To recover:
|
|
4
|
+
! To recover: follow the #4090 ladder before any other instruction in this file or in the consumer AGENTS.md. Already installed? Run `directive doctor` (or `deft doctor`). CLI not on PATH: `npm i -g @deftai/directive@<pin>` (read pin from committed package.json) then re-run doctor. ⊗ never recover by reading an undeposited README block (#2273 / #4430).
|
|
5
5
|
! Respect any "Restart required" directive -- if present, stop and tell the user to start a fresh session after cleanup commands complete. Otherwise continue.
|
|
6
6
|
-->
|
|
7
7
|
---
|
package/Taskfile.yml
CHANGED
|
@@ -445,6 +445,9 @@ tasks:
|
|
|
445
445
|
- task: verify:consumer-check-contract
|
|
446
446
|
vars:
|
|
447
447
|
CLI_ARGS: "--framework-source"
|
|
448
|
+
- task: verify:evaluator-surface
|
|
449
|
+
vars:
|
|
450
|
+
CLI_ARGS: "--base-ref origin/master"
|
|
448
451
|
- verify:telemetry-coverage
|
|
449
452
|
- verify:vbrief-conformance
|
|
450
453
|
- verify:destructive-gh-verbs
|
|
@@ -506,8 +509,10 @@ tasks:
|
|
|
506
509
|
- verify:test-boundary
|
|
507
510
|
- verify:scope-provenance
|
|
508
511
|
- verify:consumer-check-contract
|
|
512
|
+
- verify:evaluator-surface
|
|
509
513
|
- vbrief:validate
|
|
510
514
|
- verify-strategy-output
|
|
515
|
+
- verify:consumer-test-lane
|
|
511
516
|
cmds:
|
|
512
517
|
- echo "Consumer checks passed"
|
|
513
518
|
|
package/commands.md
CHANGED
|
@@ -282,7 +282,8 @@ Current status: the validation, extractor, provider, registry, generated MAP, an
|
|
|
282
282
|
|
|
283
283
|
## Quality And Verification Commands
|
|
284
284
|
|
|
285
|
-
- `
|
|
285
|
+
- `deft check` -- named terminal verb (getting-started / #2893). Include-only consumers then use `task deft:check`. Framework source uses `task check` / `task check:merge`. Do not add a fourth probe (#4379).
|
|
286
|
+
- `task check` -- primary directive repo pre-commit gate (merge chokepoint — #1704). Not deposited at consumer root after `directive init` (#3218).
|
|
286
287
|
- `task check:merge` -- explicit merge-chokepoint alias for `check:framework-source` in the framework source repo (#1704).
|
|
287
288
|
- `task check:framework-source` -- framework-source lane.
|
|
288
289
|
- `task check:consumer` -- consumer-shape lane.
|
|
@@ -292,7 +293,7 @@ Current status: the validation, extractor, provider, registry, generated MAP, an
|
|
|
292
293
|
> **Invariant:** every change MUST pass the full gate at least once before merge.
|
|
293
294
|
|
|
294
295
|
- ! **Iteration lane (agents + humans):** during implementation, use affected/static gates — targeted tests on changed paths, relevant static `verify:*` gates, `task coverage:hotspots` / `task verify:forward-coverage` — not full `task check` on every commit.
|
|
295
|
-
- ! **Merge chokepoint:**
|
|
296
|
+
- ! **Merge chokepoint:** prefer `deft check` before push/PR. If the CLI is missing, use the tree-correct task form (`task deft:check` on include-only consumers; `task check` / `task check:merge` in framework source). These are one gate, not two sequential runs. Do not add a fourth probe (#2893 / #4379). CI in this repo still runs the monolith merge-gate job (`.github/workflows/ci.yml` runs `check:merge`, not cached `deft check`, until `#1713` can invoke internal Taskfile shims).
|
|
296
297
|
- ! **Escape-rate safety:** consume `#1703` Tier-1 telemetry (`helped/crud-metrics.jsonl`) and `task eval:health` (Tier 0) before tightening fast-lane defaults — do not invent a separate metric surface.
|
|
297
298
|
- ~ **In-engine incrementality (#1713):** content-hash cache + runner-delegated affected selection are delivered separately.
|
|
298
299
|
- ~ **Merge queue:** deferred — GitHub merge queue adoption waits until the CI monolith + escape-rate signal are stable; batch merge throughput is the next lever after `#1713` cache lands (#1704 ROI order).
|
|
@@ -310,7 +311,7 @@ Current status: the validation, extractor, provider, registry, generated MAP, an
|
|
|
310
311
|
- `task verify:lifecycle-visible` -- warn when a clone's ignore configuration hides `xbrief/` / `vbrief/` lifecycle roots (#3505). Uses `git check-ignore -v` on the stage dirs, a matching-extension sentinel under each, and bounded probes derived from ignore-rule globs in root, exclude, `core.excludesFile`, and nested lifecycle `.gitignore` files (so `2026-06-*.xbrief.json` / `2025-*.xbrief.json` cannot report clean), plus `git ls-files -v` for skip-worktree / assume-unchanged. Names the matching rule and source file. Warn-first from `session:start` (per-clone, not on `task check`). Selective `.triage-cache/*.jsonl` entries do not trip. Pass `--enforce` to fail closed.
|
|
311
312
|
- `task verify:completed-write-guard` -- fail closed when a newly added `xbrief/completed/` (or `vbrief/completed/`) artifact was not written by `scope:complete` / `scope:fail` (#3679), or when a change set deletes or renames away an `xbrief/active/` brief with no paired stamped destination (#3766). Same name-status parser covers A, R, and D. Terminal moves pass as `R active->completed` or `D active` plus `A completed` when the destination has a runTransition stamp. A `cancelled/` destination pairs only when it carries a `lifecycleWrite` cancel stamp. Delete-plus-add pairing also requires the dest `plan.title` to match the deleted source so a copied stamp cannot authorize an unrelated brief. Lone-D untracking cleanup halts and names `scope:complete` or leaving the brief untracked. Artifacts larger than 1 MiB fail closed before read. Historical corpus is advisory via doctor. Remediation names the leftover land PR after a scope-provenance strip (#3476). `scope:complete` can stamp a brief already in `completed/`. Does not change `verify:completed-tracked`.
|
|
312
313
|
- `task verify:completed-tracked` -- fail closed when closed scoped issues lack a tracked `xbrief/completed/` or `xbrief/cancelled/` artifact on the delivery tip (#3264 / #3476); remediate with `task swarm:finalize-cohort` or a lifecycle PR. `task verify:completed-tracked -- --issue N` is the drive-to DONE form (delivery tip `origin/<deliveryBranch>`, not feature HEAD). Standalone verb (not part of `task check`); use `--tip HEAD` when validating an in-flight land branch. An unresolvable delivery tip fails closed (no silent HEAD fallback) -- fetch the delivery branch or pass an explicit `--tip`. Under `--skip-gh`, a named `--issue` with no cached state fails closed; the unscoped corpus scan keeps the offline allowance. Lifecycle-only lands (completed/cancelled xBRIEFs + optional CHANGELOG) use that verb plus finalize-cohort or the lifecycle PR. ⊗ Full `task check` / the TypeScript suite. ⊗ The drive-to story envelope (pre-pr + review-cycle + suite) for a file-copy land.
|
|
313
|
-
- `task verify:ac` -- product-first acceptance gate (#3284). Runs `plan.acceptance.commands` (or #3267 literal ledger) **verbatim** before done; records AC-source rung (`stated`/`derived`/`project_floor`). Empty commands require `none_stated: true`. Empty resolution is not a green run when the project has no suite floor (`soft_empty` + stamp-acceptance remedy, #3334). Primary name used first in `task check` (fail-fast); `--soft-missing-xbrief` for check composition. Rapid ceremony = AC-only; pressure/degraded makes hygiene advisory. `--capture-only` lists resolved commands without executing. Extends #3267 / #973.
|
|
314
|
+
- `task verify:ac` -- product-first acceptance gate (#3284). Runs `plan.acceptance.commands` (or #3267 literal ledger) **verbatim** before done; records AC-source rung (`stated`/`derived`/`project_floor`). Empty commands require `none_stated: true`. Empty resolution is not a green run when the project has no suite floor (`soft_empty` + stamp-acceptance remedy, #3334). Primary name used first in `task check` (fail-fast); `--soft-missing-xbrief` for check composition. Rapid ceremony = AC-only; pressure/degraded makes hygiene advisory. `--capture-only` lists resolved commands without executing. Extends #3267 / #973. Fields the gate requires (including `ambiguity_attestation` and operator-collected `file_scope`): [`docs/plan-acceptance.md`](docs/plan-acceptance.md) (#4380). A no-oracle walk still passes (#3826); the pass lead keeps the counts (`passed (0 verified, N unverifiable)`).
|
|
314
315
|
- `task verify:literal-ac` -- #3267 mechanism alias for verbatim stated-command run (same flags/cwd); prefer `verify:ac` for product-first done-gate.
|
|
315
316
|
- `task verify:forward-coverage` / `deft verify:forward-coverage` -- fail-closed new-source-file existence (#1310) plus warn-first diff coverage of added/modified branches (#3514). Intersects `coverage/coverage-final.json` with the diff against a 90% per-change branch threshold. That 90% is coverage of new code; the project vitest floor (75) is a collapse detector for the aggregate -- they are not interchangeable. Missing coverage reports skip the diff half (existence still runs). Pass `--enforce` to fail closed on uncovered changed branches; `--staged` for pre-commit.
|
|
316
317
|
- `task coverage:hotspots` / `deft coverage:hotspots` -- read the latest coverage report, compare global metrics to the project's vitest thresholds, fail closed below the branch floor or below configured headroom (default 0.3pp), and list lowest modules plus uncovered branch samples for git-diff paths (`--json` for agents). Complements `deft verify:forward-coverage` (#1310 / #3514) and `--allow-coverage-debt=#N` (#2573); does not replace them.
|
|
@@ -421,10 +422,11 @@ After CLI/deposit upgrade, disk can show the new generation while a long-lived s
|
|
|
421
422
|
- ! **Which tree the lease is read from — root admission (#3794 / #4013):** a gated write is judged against the Git working tree its **target** lands in, not always the tree the host payload names. A target in another worktree sharing `--git-common-dir` is admitted and carries occupancy, ritual and active scope with it; a proven different repository, an unreadable target identity, and a mutation spanning two worktrees are refused. A target with **no Git toplevel at all** (OS temp, a home file, anything outside every checkout) is gated against the payload root — deliberate since #3794, published with its reason and a gate-by-gate disposition in [docs/hook-root-admission.md](./docs/hook-root-admission.md), which also records the three-surface matrix (direct write consults admission; generic server-prefixed MCP and out-of-repo Shell writes do not) and the relative-target canonicalization limitation (#4023).
|
|
422
423
|
- ! **Host owner namespaces (#3611):** canonical owners are `host:<provider>:v1:<base64url(raw-id)>`. Codex uses payload `session_id` for the parent and its subagents. Claude Code uses `session_id`; `agent_id` does not replace the session-family owner. Cursor uses `conversation_id` and requires a simultaneously supplied `session_id` to agree; no Cursor subagent-granularity claim is made until verified. Grok has no verified payload identity, so its owner is the hook process variable `GROK_SESSION_ID` the host publishes (#3873): the hook is a sibling the host spawns, so an agent shell export cannot reach it, and the payload `session_id` is never read. When that variable is absent the host keeps explicit `--session-id` / `DEFT_SESSION_ID` ownership; a malformed one fails closed, as does an ambient `DEFT_SESSION_ID` that contradicts a resolved host owner.
|
|
423
424
|
- ! **Occupancy identity on a host with no session derivation (#3877):** the hook process environment (`GROK_SESSION_ID` on Grok, or `DEFT_SESSION_ID` inherited by the hook) or an explicit `--session-id`. ⊗ a worker-shell `export DEFT_SESSION_ID`. A shell export reaches vitest, CLI verbs, and `scope:complete`; it never reaches `deft-hook`, a sibling process. Nothing in `content/templates` or `content/skills` mentions the variable. Do not invent an envelope mandate.
|
|
424
|
-
- ! **One actor-resolution chain, four terminals (#3954 / #4066):** claim, release, heartbeat and grant/revoke resolve the acting session by the same lookup order — explicit `--session-id`, then `DEFT_SESSION_ID`, then the owner the running host published. **Claim** is host-authoritative when those disagree: inherited `DEFT_SESSION_ID` must not beat the host-published owner (mirrors the write-gate env drop). Release, heartbeat and grant/revoke still report disagreement without reordering, and still refuse to mint. Anonymous release of the occupant recorded in the lease file stays **refused** — possession of that path is not authority to delete a live lease.
|
|
425
|
-
- ! **Where the transport still does not reach (#3873 residue):** the CLI resolves the host owner; the write gate runs in the `deft-hook` sibling process, and on a deployment where the host does not publish `GROK_SESSION_ID` into that sibling the hook presents whatever `DEFT_SESSION_ID` it inherited — possibly another host's session. Nothing in this tree can set that process's environment
|
|
426
|
-
- ! **
|
|
427
|
-
- ! **
|
|
425
|
+
- ! **One actor-resolution chain, four terminals (#3954 / #4066 / #4431):** claim, release, heartbeat and grant/revoke resolve the acting session by the same lookup order — explicit `--session-id`, then `DEFT_SESSION_ID`, then the owner the running host published. **Claim** is host-authoritative when those disagree: inherited `DEFT_SESSION_ID` must not beat the host-published owner (mirrors the write-gate env drop). Claim on a host with a declared identity contract **refuses to mint** a UUID owner (#4431); a print-only companion may name the host-published owner when no hook is registered. `CLAUDE_CODE_SESSION_ID` is not a `host-env` claim source. Recorded `identity_provenance` keys later denial text. Release, heartbeat and grant/revoke still report disagreement without reordering, and still refuse to mint. Anonymous release of the occupant recorded in the lease file stays **refused** — possession of that path is not authority to delete a live lease.
|
|
426
|
+
- ! **Where the transport still does not reach (#3873 residue):** the CLI resolves the host owner; the write gate runs in the `deft-hook` sibling process, and on a deployment where the host does not publish `GROK_SESSION_ID` into that sibling the hook presents whatever `DEFT_SESSION_ID` it inherited — possibly another host's session. Nothing in this tree can set that process's environment. Occupancy identity-conflict and identity-unavailable denials now name `hook --host <flag>` so the next repro can observe the child argv (#4409). Full env/payload capture remains separate work. Recovery meanwhile is the ambient step above: the occupant releases its own lease from its own shell.
|
|
427
|
+
- ! **Child `--host` remainder (#4409):** occupancy owner is produced by argv `--host` plus that host's identity source (`GROK_SESSION_ID` on Grok; payload `session_id` / `conversation_id` on Claude/Codex/Cursor). Inherited `CLAUDE_*` is not an owner producer. ⊗ Honour `DEFT_SESSION_ID` over a derived host owner as a blanket override. Deposit reconstitution in a linked worktree stays on #4443. `session:ready` recovery preserves the presented identity; it does not infer ownership from a previous invocation recorded in occupancy.json.
|
|
428
|
+
- ! **Lifecycle identity transport (#3611 / #4431):** for every host with a resolved owner, PreToolUse rewrites only exact, simple canonical `deft` / `directive` lifecycle commands and source-repo `task <verb> [-- ...]` forms to add the host's `--session-id`. Direct CLI spellings are `session:start`, `session:ready`, `session:end`, `occupancy:steal`, `occupancy:release`, `occupancy:heartbeat`, `occupancy:grant` (#3954, its `--revoke` arm included), and `swarm-launch`; the Task spelling for the last verb is `swarm:launch`. For owner-requiring lifecycle commands, the shell execution directory must be absent or realpath-align exactly with the hook project root. Path-bearing executables (`./deft`, `/path/deft`), path/destination flags (`--project-root`, `--paths`, path-valued `--stories`, `--output`, `--worktree-map`, `--gate-clearances`), `--no-audit`, consumer-repo Task indirection, Task aliases (`task deft:<verb>`), and compound, redirected, quoted, aliased, wrapped, or otherwise ambiguous forms are not auto-rewritten. A supported-host hook rejects a recognized lifecycle form outside the narrow rewrite surface until it carries the explicit matching `--session-id`, including non-inspectable invocations that still name a lifecycle verb (#4431 fail-closed; newline, single `&`, grouped `(cmd)` / `{ cmd; }`, `then`/`do`); an execution-root mismatch on an owner-requiring command always denies. With a matching ID on other excluded forms, the original command remains under normal host permission handling. Manual/integrated-terminal callers must likewise pass one matching `--session-id` (or `DEFT_SESSION_ID`) through the complete lifecycle.
|
|
429
|
+
- ! **Transition, steal, and release (#3611 / #4410):** an existing live UUID lease cannot silently become a host-namespaced owner. A refused party reads worktree isolation, read-only posture, occupant grant, and occupant release — not a steal argv. Occupancy has owner/member/stranger, not human/agent; `--confirm` on steal is a flag, not a human gate. Confirmed steal remains an owner-transition verb for whoever already intends to take a live lease; it is last resort, not isolation, and is not named as recovery in a denial. Bare steal changes only the lease; direct writes remain denied unless ritual state already names the new owner. If they differ, align the same writer ID with `session:start --rearm --session-id=<same-session-id>` when re-arm is eligible, or cold `session:start --session-id=<same-session-id>` otherwise. The occupant drops a live lease with `occupancy:release` or `session:end`; a non-owner cannot clear it. Confirmed steal still prints existing `claimed_at` / `heartbeat_at` / `last_write_at` when available.
|
|
428
430
|
- ! **Lease refresh (#3599):** a gated write by the owner re-stamps `heartbeat_at`, so a session that keeps working keeps its lease, up to the absolute age cap below. The re-stamp is floored at a quarter of the TTL to avoid rewriting the lease per event, and it records `last_write_at` separately — `heartbeat_at` moves on any lease touch, `last_write_at` only on a gated product write, which is what tells a would-be stealer that the occupant is mid-work. When the owner's own lease is inside the staleness window (three quarters of the TTL) and the automatic re-stamp could not run, the write gate says so instead of letting the lease lapse silently; a write that did re-stamp stays quiet, because the warning would name a state that write just cleared. A re-stamp blocked by the lock leaves the lease untouched and the gate re-decides against the file on disk: contention alone keeps the rightful owner writing, while a takeover that completed during the wait denies. Long quiet stretches produce no gated write to ride on, so the owner refreshes explicitly with `deft occupancy:heartbeat` (Task: `task occupancy:heartbeat`). Refresh extends a lease the caller already holds — it never claims a free worktree, never takes a foreign lease, and never mints an owner; an unheld lease exits non-zero. Under a supported host the exact command receives the matching `--session-id` automatically; manual and Grok callers pass `--session-id <id>` or `DEFT_SESSION_ID`.
|
|
429
431
|
- ! **Absolute lease age cap (#3599):** a lease is also dead 12 hours after `claimed_at`, whatever its heartbeat says, and no refresh path may extend that — `claimed_at` survives every re-stamp. Occupancy admits whoever presents the occupant's session id, so refresh alone would let any process holding that string keep a worktree forever and disable the crash-recovery reclaim the TTL exists for. The two dead states call for different responses and read differently: a stale heartbeat means refresh sooner; past the cap the tree is no longer held, so the capped holder's own gated writes are **refused** until it re-claims with `session:start --session-id=<your-session-id>` — allowing them would let the very bearer the cap bounds keep mutating a worktree a peer may claim at any moment. A lease that is both stale and capped reads as capped, because refreshing cannot revive it and the stale wording would send the holder somewhere that does not help. A different session is unaffected: taking over an aged-out tree is the reclaim the cap exists to enable. Twelve hours is sized by the stalled owner, not the busy one: refresh keys on writes, so an agent that finishes overnight and waits for its operator stops refreshing while staying legitimate, and 12 hours spans a 23:00 dispatch to a 09:00 handoff while still bounding reclaim inside a day. Reaching the cap costs one re-claim, never the work. A time cap cannot tell a stalled-but-live owner from a dead one — the only liveness signal on this path is a write; if that bites, the answer is a write-free liveness signal (explicit parked state, or refresh on non-write activity), not a larger number.
|
|
430
432
|
- ! **Lease membership (#3755):** the occupant admits a dispatched child with `deft occupancy:grant --session-id=<owner> --child-session-id=<child> --role <worker-role> [--ttl-minutes N] [--worktree <path>] [--host <id>] [--address <name>] [--join-protocol none|heartbeat-file|parent-message]` (Task: `task occupancy:grant`), and withdraws it with the same command plus `--revoke`. The grant records owner id, child id, worktree, role and expiry, so a write resolves to a session rather than to whoever held the string. Admission splits: **writes** are admitted for the owner **or** a valid unexpired member; **release, steal, heartbeat and cohort close-out stay owner-only**, so a grant never escalates into the lease itself. An expired grant is refused on read, expiry is clamped to the lease's own absolute age cap, a lease carries at most 32 live grants, and a steal or a fresh claim starts with none — grants belong to the lease that issued them. The child id is checked at grant time (#3954): a value under the reserved `host:` prefix must be a well-formed canonical owner, and one that re-prefixes the owner's own host payload under a second provider is refused as the self-grant it is. Both were granted before, and the write gate then admitted them as `member`, so the lease read as membership while admitting nobody. An id outside that prefix is still accepted, because a child on a host with no identity contract presents whatever `DEFT_SESSION_ID` holds. Withdrawal skips the check, so a malformed grant written earlier stays revocable. A member's write re-stamps `heartbeat_at` and `last_write_at` on the same quarter-TTL floor as the owner's: a tree a granted child is actively writing is in use, and letting it lapse would hand the worktree to a peer mid-edit. `claimed_at` is untouched, so the absolute age cap and the grant's own expiry still bound it. The verb is inside the rewrite surface since #3954, so a supported host adds the matching `--session-id`; a `--worktree` rebind stays outside it and must carry the owner explicitly. All of it is cooperative, like the rest of this lease: it names who may write, it does not authenticate them. Ritual state stays single-owner, so a member writes under the occupant's ceremony: the composite hook write gate measures the verified ritual owner against the occupant that issued the grant rather than against the writer, and a revoked or expired member is refused there as well.
|
|
@@ -459,7 +461,7 @@ Cross-link: spawn three postures and deny recoveries live under § Agent-host di
|
|
|
459
461
|
|
|
460
462
|
### Mutable ritual (mutation posture)
|
|
461
463
|
|
|
462
|
-
- ! On **mutation** session start, run `deft session:start` (or `task session:start` in framework source) after loading AGENTS.md. Records quick-tier ritual in `.deft/ritual-state.json`: alignment confirmation, branch-policy disclosure, `deft verify:tools` guidance, default-branch sync warnings, and `deft triage:welcome` one-liner. State is worktree- and HEAD-bound; stale after `plan.policy.sessionRitualStalenessHours` hours (default
|
|
464
|
+
- ! On **mutation** session start, run `deft session:start` (or `task session:start` in framework source) after loading AGENTS.md. Records quick-tier ritual in `.deft/ritual-state.json`: alignment confirmation, branch-policy disclosure, `deft verify:tools` guidance, default-branch sync warnings, and `deft triage:welcome` one-liner. State is worktree- and HEAD-bound; stale after `plan.policy.sessionRitualStalenessHours` hours (default 8). Mutation start also claims the worktree occupancy lease (`.deft/occupancy.json`); see Session routing (#3433).
|
|
463
465
|
- ! **Orientation compression Now (#3286):** mutation cold `session:start` composes `doctor` + #3282 toolchain preflight (and deposit-sha fast-paths for `agents:refresh` / `verify:cache-fresh`) as inline sections with per-section status lines — composition of existing steps, not a new monolith. When the deposit fingerprint (payload + templates + engine) is unchanged, refresh surfaces print one-line `unchanged - sha match` no-ops. Opt-in compact output: `deft session:start --compact` or `DEFT_SESSION_COMPACT=1` (verbose remains the default). #2176 read-only default is unchanged. Dual-path Later (orient) stays open until run-summary telemetry shows ritual+gate share ≥ 25% after Now ships (#2899).
|
|
464
466
|
- ! Cold `session:start` does **not** run the live agent-hook probe. Functional readiness belongs to the gated mutation path so cold ceremony retains the #2990/#2991 latency profile.
|
|
465
467
|
- ! **Hot path latency (#2991):** by default, mutation `session:start` does **not** block ritual-state write on optional network. It skips the npm release-availability probe and triage cache empty-hydrate / self-heal (`ensureTriageCacheHydrated` / `maybeSelfHealCache`). Targets (operator-facing, not CI-hard): warm hot path typically under a few seconds once tools are on PATH; cold path dominated by local `verify:tools` and git, usually well under ~30s when optional network is off. Empty-cache GitHub fetch-all and npm `view` previously accounted for multi-minute hangs in the WWYSYDH pilot — those stay off the critical path unless opted in.
|
|
@@ -469,7 +471,7 @@ Cross-link: spawn three postures and deny recoveries live under § Agent-host di
|
|
|
469
471
|
- ~ **Process-cost events (#2994 / #3508):** on mutation `session:start` completion (cold or re-arm), Directive appends a local `session:start` behavioral event to `.deft-cache/events.jsonl` with `ceremony_tier`, `duration_ms`, `exit_code`, and optional `steps[]` (same labels as `--json`). Mutation `session:start` also prints one operator-visible `ceremony <tier> <ms>` line (hidden under `--compact` / `DEFT_SESSION_COMPACT`). When PreToolUse denies for `ritual-not-ready`, a local `session:ritual-blocked` event records `tool_name`, `code`, and optional `recovery_tier` / `detail`. Always-on best-effort (never blocks ceremony or deny path); not gated on `valueFeedback`; **no remote upload** (Product Insights #2603 is a separate opt-in). Pull the rollup with `task value:show` (composed reader; CLI process time, not agent-turn wall clock). See § Process-cost events below. ⊗ Do not use the printed CLI duration as #3286 Later graduation input.
|
|
470
472
|
- ~ At safe idle points (clean tree, no in-flight story), mutation session start and `deft scope:complete` may also run the staleness tickler: an interactive, consent-based offer to upgrade Directive (`npm i -g @deftai/directive@latest`) and/or migrate xBRIEF (`deft migrate:xbrief`). Escalation tiers, snooze windows, and opt-out live under `plan.policy.stalenessTickler` — inspect with `deft policy:show --field=stalenessTickler`. State persists in `xbrief/.triage-cache/staleness-tickler-state.json`. Skips framework source checkouts, dirty trees, CI/headless (`DEFT_SESSION_RITUAL_SKIP=1`), and typed opt-out. Refs #2488 / #2489.
|
|
471
473
|
- ! Before any code-writing tool call or `start_agent` implementation dispatch, run `deft verify:session-ritual -- --tier=gated`. Gated tier fails closed unless quick-tier state is fresh; lazily records the non-deferrable `agent_hooks` readiness gate plus `deft doctor` and `task verify:cache-fresh` entrypoints. Agent-hook correctness is independent of doctor warnings and throttling. Step 0 of the pre-`start_agent` gate stack.
|
|
472
|
-
- ! **One-shot recovery (#2993 / #3100):** when PreToolUse denies writes for a stale/missing gated ritual, run `deft session:ready` (or `task session:ready`). It composes `session:start` (only when quick-tier is not green) + `verify:session-ritual -- --tier=gated` + `cache fetch-all --force` when `cache_fresh` is the remaining blocker, then re-verifies. Even when gated inspect is already fresh, the fast path forces one live `agent_hooks` check
|
|
474
|
+
- ! **One-shot recovery (#2993 / #3100 / #4399):** when PreToolUse denies writes for a stale/missing gated ritual, run `deft session:ready` (or `task session:ready`). It composes `session:start` (only when quick-tier is not green) + `verify:session-ritual -- --tier=gated` with check-class `cache_fresh` (age + live drift, no `--skip-drift-probe`) + `cache fetch-all --force` when `cache_fresh` is the remaining blocker, then re-verifies. Skip-drift ritual argv is not the ready bar — that is the `task check` / FRAMEWORK_CHECK_GATES evaluate, so stale-by-drift can still fire fetch-all. Even when gated inspect is already fresh, the fast path forces one live `agent_hooks` check and the same check-class `cache_fresh`; it still avoids unnecessary fetch-all when that evaluate is green. Flags: `--json`, `--repo OWNER/NAME`, `--with-network` (forwarded to session:start). Prefer this over juggling the multi-step recovery sequence under hook pressure.
|
|
473
475
|
- ? Postpone with `deft session:start --defer step=reason` (`alignment`, `branch_policy`, `triage_welcome`, `doctor`, `cache_fresh`). `agent_hooks` is non-deferrable.
|
|
474
476
|
- Headless workers / CI MAY set `DEFT_SESSION_RITUAL_SKIP=1`; verifier exits 0 but warns when bypass hides failure.
|
|
475
477
|
- ⊗ Self-report ritual complete without fresh `deft session:start` state; ⊗ bypass `deft verify:session-ritual` before implementation dispatch; ⊗ reorder/skip/merge ritual tiers without operator override.
|
|
@@ -600,7 +602,7 @@ Directive does not guess your mix. Either you name the next units in order (**or
|
|
|
600
602
|
- `task triage:summary`, `task triage:scope`, `task triage:scope-drift`, `task triage:subscribe`, `task triage:unsubscribe`, `task triage:classify`, `task triage:strip-withdrawn-chips`, `task triage:welcome`, and `task triage:smoketest` -- supporting workflow and onboarding commands.
|
|
601
603
|
- `task triage:classify -- --mirror` -- **Withdrawn (#4070).** Dry-run and `--apply` both fail closed with a pointer at #4070. Replacement sieve is #4071. #3579 is transitively withdrawn for the gap. Do not close #1423, #3579, #2611, or #3923. `--list` / `--validate` remain. Strip leftover chips with `task triage:strip-withdrawn-chips` (remaining-set apply, not classify).
|
|
602
604
|
- **Triage write-back pairing (#1423 / ADR-005).** When the author stamps that a lean is mechanism-shaped, write **both**: body-text field `mechanism-shaped: true` (the artifact) **and** mirrored label `design-critique:mechanism-shaped` (what `plan.policy.judgmentGates` matches and lists show). Do not compute the classification. No stamp -> the design-critique gate never fires. Clearance is a separate line on the thread: `design-critique: warranted | not warranted, because ...` -- engine evaluates presence, shape, and authority, never the because-clause content. Advisory/observe; `verify:judgment-gates --enforce` stays opt-in unused; `scope:promote` does not gain `--enforce` in this story.
|
|
603
|
-
- **Design-critique catalog chip (#3642 / #4298).** Parent attach of `ingest-ready` / `in-progress` /
|
|
605
|
+
- **Design-critique catalog chip (#3642 / #4298).** Parent attach of `ingest-ready` / `in-progress` / later-arc `mechanism-shaped` MUST use `task scm:issue:design-critique-chip -- --issue N --chip mechanism-shaped|in-progress|ingest-ready [--repo OWNER/NAME]` (or `deft scm issue design-critique-chip`). Closed catalog remaining-set replace, one write. Auto-stamp chip from `resolveAutoStampCatalogChip` is ingest-ready after the completed-arc record. ⊗ `gh api POST .../labels`. ⊗ additive `scm:issue:edit --add-label`.
|
|
604
606
|
- **Work claim (#4200).** Same-issue busy flag `status:claimed`. `task scm:issue:work-claim -- claim|show|release --issue N [--repo OWNER/NAME]` (`deft scm issue work-claim`). Session-start and `xbrief:preflight` MUST show. Warn is success; not a lock. Claim refuses read-only / no occupancy. Last-write-wins: the board can lie about who. v1 does not detect two-issue path overlap. Catalog in `.github/ISSUE_LABELS.md`; ⊗ invent the name per issue.
|
|
605
607
|
- **Operator discovery for SCM label mirror (#3124).** Withdrawn with classify `--mirror` (#4070). The session/welcome tip does not fire. #3124 discovery and #1423 Wave 1–2 apply are unusable after this lands; those issues stay open.
|
|
606
608
|
|
|
@@ -25,7 +25,7 @@ Boundaries are read off the machinery in this document, not asserted here.
|
|
|
25
25
|
- Rounds accumulate inside one arc. The auto-stamp denominator is scoped to critic posts in this arc and keeps a Stop 4 retry's post, so a retry continues the arc it retries.
|
|
26
26
|
- Same-round siblings share one ceiling and one panel-deposit. A panel is one round, not N arcs.
|
|
27
27
|
- The arc stays open through the operator-gated loop until a verified synthesis is accepted, or until the halt line. Successor leans are moves inside that loop, so revising a lean before bind is not a boundary.
|
|
28
|
-
- A **
|
|
28
|
+
- A **later arc** opens after bind: it re-applies `design-critique:mechanism-shaped`, drops `design-critique:ingest-ready`, and its new lean is not cleared by the older completed-arc record. That is a post-bind target revision.
|
|
29
29
|
|
|
30
30
|
- ! Read `arc` in this document as that unit.
|
|
31
31
|
- ⊗ Read a new ceiling, a new round, or a pre-bind lean revision as a new arc.
|
|
@@ -60,10 +60,10 @@ Record `arc-mode: no-ingest` or `arc-mode: checkout` on the Stop 1 write-back. `
|
|
|
60
60
|
- ! Recognition of `no-ingest` happens before mutation initialization. Refuse github-only when mutation `session:start` has already occurred, unless the lease is released first.
|
|
61
61
|
- ! Posting path that survives a foreign lease: `gh issue comment --body-file -` (stdin). Least-authority envelope: bounded GitHub reads and one comment post.
|
|
62
62
|
- ! Parent fetches, then creates or verifies one dest at origin/<default> tip (`ensureArcDest`). dispatch-sha equals that tip. Against-implementation dest is the fetched PR head SHA, recorded on Stop 1. ⊗ Pin dest to local HEAD.
|
|
63
|
-
- ! N>1 process-only critics share that dest with cwd-without-occupy. They are not swarm Phase 2 and not a #4066 mutating worker. Unique dest-lock stays for implement-class. Skip class is a host-visible Grok stdin marker (`subagent_type` `plan` or `process_only`), not dest-path. That marker is the
|
|
63
|
+
- ! N>1 process-only critics share that dest with cwd-without-occupy. They are not swarm Phase 2 and not a #4066 mutating worker. Unique dest-lock stays for implement-class. Skip class is a host-visible Grok stdin marker (`subagent_type` `plan` or `process_only`), not dest-path. That marker is the process-only skip class, not an implementation-gate bypass: implement-class never sets `process_only`. ⊗ Skip #2885 on destProven. Keep #4066 primary-path deny. ⊗ Pin dest / process_only skip-class rules into `templates/agents-entry.md`.
|
|
64
64
|
- ! Pin reads to `git show <dispatch-sha>:` against the recorded SHA. ⊗ A moving branch ref.
|
|
65
65
|
- ! Direct EXIT names ingest as a later operator verb after the completed-arc record. ⊗ Auto-ingest.
|
|
66
|
-
- ! After
|
|
66
|
+
- ! After an admitted completed-arc record, print ingest (`task issue:ingest`) and do not print next-envelope as the default next. Mid-arc EXIT stays next-envelope. ⊗ Add a land CLI. ⊗ Treat a body PATCH as a later arc. Keep chip `design-critique:ingest-ready` as list state.
|
|
67
67
|
- ! Target-digest / stale-target (#4243) is a different hole. ⊗ Restamp for body alignment.
|
|
68
68
|
- ⊗ Treat `arc-mode:` as ingest clearance or as a permanent ingest denial.
|
|
69
69
|
- ⊗ Record a front-door mode named `ingest`.
|
|
@@ -278,11 +278,16 @@ After this round's same-round siblings are posted, parent posts a successor `**L
|
|
|
278
278
|
- ! The successor lean is the disposition map. Do not post a third map type.
|
|
279
279
|
- ! The first posted map is an ADR-006 arbitration surface. Record a substantiation token when takes introduce load-bearing premises. Non-self-arbitration applies when the same party authored the triage and the proposed takes.
|
|
280
280
|
- ! Bind synthesis and the auto-stamp catalog chip (`design-critique:ingest-ready`) to the latest successor lean, never a superseded write-back.
|
|
281
|
-
- ! When the next-build contract is
|
|
282
|
-
- !
|
|
283
|
-
- !
|
|
281
|
+
- ! When the next-build contract is not this body, stamp a Lean-family line-start `Spec-path:` on that successor lean. Nine spellings: zero to two asterisks counted independently on each side, the same wrapping as `Lean:`. `Spec-path:` is a lean token, not a chip. `resolveAutoStampCatalogChip` remaining-set-replaces `ingest-ready` after the completed-arc record exists. It does not parse lean English and does not map Spec-path to a chip.
|
|
282
|
+
- ! Spec-path token plus a completed-arc record means harvest that closed Bound-remedy heading slice on the cited successor lean. Missing heading or empty list refuses, nothing written. No token stays the #4237 Outcome:ready body-is-normative path. ⊗ Let Spec-path mean both a later arc and a harvest path.
|
|
283
|
+
- ! Bound-remedy harvest is a Lean-family heading token (`## Bound remedy`, same class as `## In plain English`) plus parseListItems on that slice of the cited successor lean only. ⊗ Bind that harvest as reuse extractPlanItems. Empty on that lean refuses. A numbered list without that heading is not enough.
|
|
284
284
|
- ! Point that harvest source at plan.items, literal capture, and derived-clause taskStatement. Overview may keep the GitHub body as historical described content. ⊗ Close with an items-only patch.
|
|
285
|
-
- ⊗ Classify
|
|
285
|
+
- ⊗ Classify the path selector by NLP of the lean.
|
|
286
|
+
|
|
287
|
+
### Legacy alias
|
|
288
|
+
|
|
289
|
+
`Recut:` is a permanent alias for `Spec-path:`, same Lean-family wrapping (zero to two asterisks each side). Ingest on an old-spelling lean is identical: non-empty Bound-remedy list harvests; missing heading or empty list refuses, nothing written; no token stays body-normative. Teach only `Spec-path:` on new leans.
|
|
290
|
+
|
|
286
291
|
- ! Full template (accepted set, residual, supersedes-id, ceiling if retrying) lives only on the successor lean and on a retry disagreement map.
|
|
287
292
|
- ! Walk comments stay slim (model and role lines, Accept X, critic id, heading, decision, and when needed a token plus pointer).
|
|
288
293
|
- ⊗ Edit the ceiling write-back in place.
|
|
@@ -333,6 +338,8 @@ The summary leads both artifacts under one fixed heading token: `## In plain Eng
|
|
|
333
338
|
- ⊗ Address an implementer in the summary. No imperatives, and no instruction to a later worker.
|
|
334
339
|
- ⊗ Mandate a next-step or recommended-action field on either artifact. A closed form (a verb and an issue) was considered and refused: the summary cannot itself be closed-form, because plain language is the point, and a bounded instruction is still an instruction in the parent voice inside the ingest-clearing comment.
|
|
335
340
|
- ⊗ Put ingest-open protocol or the sentence "Ingest may proceed" under this heading. Those crowd out the problem-and-solution reading. Ingest still reads the bound lean and the verified-claims table.
|
|
341
|
+
- ! Summary may say leftover next-build, or no leftover next-build, as a reading.
|
|
342
|
+
- ⊗ Order close. "Should close" is an instruction to a later worker.
|
|
336
343
|
|
|
337
344
|
### Reserved line-starts
|
|
338
345
|
|
|
@@ -398,8 +405,8 @@ Contract stops stay internal. Parent prints these phrases when they apply. They
|
|
|
398
405
|
- ! Do not print **retry differences** until residual headings are named on that map.
|
|
399
406
|
- ! Do not skip the first-lean offer because the draft is all-accept.
|
|
400
407
|
- ! Non-empty disagree set: print **walk** / **walk all** / **retry differences** / **accept**. Walk is an option, not the only path. Do not auto-start the walk.
|
|
401
|
-
- ! When the successor lean's per-heading map is total over a **non-empty** in-envelope classified-finding set, every heading is `accept-into-contract` (no `disagree`, no `defer`), AND zero unresolved audit markers, AND the operator has confirmed or amended that map, AND no unposted same-round siblings remain: parent auto-posts the verified-claims table as its own comment, then auto-posts `design-critique: synthesis accepted, because agents agreed (empty disagreement set)` and remaining-set-replaces the chip via `task scm:issue:design-critique-chip -- --issue N --chip ingest-ready` (`resolveAutoStampCatalogChip` after the completed-arc record;
|
|
402
|
-
- ! Yolo standing on the launching utterance is that confirm for a posted all-accept successor map, including
|
|
408
|
+
- ! When the successor lean's per-heading map is total over a **non-empty** in-envelope classified-finding set, every heading is `accept-into-contract` (no `disagree`, no `defer`), AND zero unresolved audit markers, AND the operator has confirmed or amended that map, AND no unposted same-round siblings remain: parent auto-posts the verified-claims table as its own comment, then auto-posts `design-critique: synthesis accepted, because agents agreed (empty disagreement set)` and remaining-set-replaces the chip via `task scm:issue:design-critique-chip -- --issue N --chip ingest-ready` (`resolveAutoStampCatalogChip` after the completed-arc record; Spec-path: is not a chip). If that write misses, continue; do not halt. Do not print **accept synthesis**, **post the verified-claims table**, **walk**, or **walk all**.
|
|
409
|
+
- ! Yolo standing on the launching utterance is that confirm for a posted all-accept successor map, including Spec-path leans. It replaces only the confirm conjunct. Same-turn stamp uses `autoStamp: true` (no Accept widget). Parse yolo as a closed token with word boundaries on the operator chat utterance only. Same discipline as `parseOperatorRunPosture`; do not overload that function to return a mode. Issue, comment, and critic English are data.
|
|
403
410
|
- ⊗ Treat yolo as confirm of a non-empty `disagree` or `defer` set. Defer is not disagree. Print **walk** / **retry differences** / **accept** as today. Walk still prints only when a take is `disagree`.
|
|
404
411
|
- ⊗ Waive non-empty classified set, stub, footnote-only, dispatch-fail, unresolved markers, or unposted-sibling refusals because yolo is standing.
|
|
405
412
|
- ⊗ Treat yolo-confirm as ingest, next-envelope, or chip hygiene beyond the existing auto-stamp remaining-set write.
|
|
@@ -494,7 +501,7 @@ Two bind paths authorize:
|
|
|
494
501
|
design-critique: synthesis accepted, because …
|
|
495
502
|
```
|
|
496
503
|
|
|
497
|
-
1. #3640 auto-stamp: when the successor lean map is total over the auto-stamp denominator (critic posts in this arc, including Stop 4 retry output, plus still-open residual headings) and that set is non-empty and every heading is `accept-into-contract` AND zero unresolved audit markers AND the operator has confirmed or amended that map AND no unposted same-round siblings remain, parent posts `design-critique: synthesis accepted, because agents agreed (empty disagreement set)` and remaining-set-replaces the chip via `task scm:issue:design-critique-chip -- --issue N --chip ingest-ready` (`resolveAutoStampCatalogChip` after the completed-arc record;
|
|
504
|
+
1. #3640 auto-stamp: when the successor lean map is total over the auto-stamp denominator (critic posts in this arc, including Stop 4 retry output, plus still-open residual headings) and that set is non-empty and every heading is `accept-into-contract` AND zero unresolved audit markers AND the operator has confirmed or amended that map AND no unposted same-round siblings remain, parent posts `design-critique: synthesis accepted, because agents agreed (empty disagreement set)` and remaining-set-replaces the chip via `task scm:issue:design-critique-chip -- --issue N --chip ingest-ready` (`resolveAutoStampCatalogChip` after the completed-arc record; Spec-path: is not a chip). If that write misses, continue; do not halt. Do not print **accept synthesis**. Do not auto-stamp on a partial map, an unconfirmed parent draft, or when any audit marker is unresolved, or while same-round siblings remain unposted. Yolo standing on the launching utterance is the confirm conjunct for that posted all-accept map, including Spec-path leans. It does not satisfy ingest.
|
|
498
505
|
2. Explicit operator **accept synthesis** (or a listed short form), subject to the two non-empty refusals below. Parent may post that line and cite the verb. Then apply the exclusive catalog chip `resolveAutoStampCatalogChip` selects (`design-critique:ingest-ready`) via remaining-set write. If that write misses, continue; do not halt.
|
|
499
506
|
|
|
500
507
|
Closed catalog (last chip wins): `design-critique:mechanism-shaped` (in-flight, gate match), `design-critique:in-progress` (live after first panel-deposit or `role: critic`; not gate-matched), and `design-critique:ingest-ready` (the only bind chip after a complete record). No halt chip. Halt leaves the standing in-flight chip. No clear-to-none. `CHIP_ALIASES` in `packages/core/src/scm/design-critique-chip.ts` is the same three names. Old `design-critique:triage-ready` and `design-critique:recut-needed` fail closed. Unknown `--chip` fails closed.
|
|
@@ -505,14 +512,14 @@ Closed catalog (last chip wins): `design-critique:mechanism-shaped` (in-flight,
|
|
|
505
512
|
- ⊗ `gh api POST .../labels` or additive `scm:issue:edit --add-label` for this facet.
|
|
506
513
|
- ⊗ Intercept mixed `scm issue edit` adds/removes for this facet.
|
|
507
514
|
- ⊗ General-purpose labels CLI.
|
|
508
|
-
- ! After the completed-arc record is present, `triage:accept` / `scope:promote` / `issue:ingest` / build may proceed unless `evaluateCompletedArcRecord` returns `cancelled` or `
|
|
509
|
-
- ! Per-thread body ingest stays the mapper after a set-level bind. Stories the bind wants are
|
|
510
|
-
- !
|
|
511
|
-
- ! A later successor lean after cancel starts a
|
|
512
|
-
- ! A complete record whose latest `target shape:` field is `set-level` is `
|
|
515
|
+
- ! After the completed-arc record is present, `triage:accept` / `scope:promote` / `issue:ingest` / build may proceed unless `evaluateCompletedArcRecord` returns `cancelled` or `set-level-body` (#4057). Any identity may run those verbs. Same-session parent continuation is not required. ⊗ Treat `arc-mode:` as ingest clearance or as a permanent ingest denial. Ingest stays `issue:ingest` after the completed-arc record. Direct EXIT names it as a later operator verb. After an admitted completed-arc record, print ingest and do not print next-envelope as the default next. Mid-arc EXIT stays next-envelope. GitHub Triage on the implementer is not required. They read the accepted verified synthesis (latest successor lean plus the verified-claims table).
|
|
516
|
+
- ! Per-thread body ingest stays the mapper after a set-level bind. Stories the bind wants are rewritten bodies or newly filed issues. Derived AC stays on that body.
|
|
517
|
+
- ! Dominated portfolio members fail closed on `cancelled`. Parent posts `design-critique: cancelled, because ...` on that number. Parent `role: parent` dominate prose is not that record. Critic, quoted, or fenced cancel-shaped prose is not that record. Leftover `mechanism-shaped` without cancel stays `missing-record` and is not this control.
|
|
518
|
+
- ! A later successor lean after cancel starts a later arc. Completing a superseded thread without a later lean would mint the harvest.
|
|
519
|
+
- ! A complete record whose latest `target shape:` field is `set-level` is `set-level-body`. Rewrite the body (and record a non-set-level shape) or file a new issue. Ingest the anchor only is not supported while that field remains set-level.
|
|
513
520
|
- ⊗ Select an author-blind latest successor lean as CurrentShape.
|
|
514
521
|
- ⊗ Put a set-level graph (dominate / split / corpus parsed from comment English) inside ingest.
|
|
515
|
-
- ! Ingest clearance cites the latest successor lean. An older completed-arc record does not clear a later
|
|
522
|
+
- ! Ingest clearance cites the latest successor lean. An older completed-arc record does not clear a later lean. A panel-deposit is in-flight even when the catalog chip missed and no critic has posted.
|
|
516
523
|
- ! The lexical form of that citation, and the requirement that the occurrence be affirmative, are published in `## Citation grammar`. Ingest reads that grammar, not prose intent.
|
|
517
524
|
- ! Keep `plan.policy.judgmentGates` matching only `design-critique:mechanism-shaped`. After `ingest-ready` replaces it, the issue leaves the gate match. Carry not-started vs live on `in-progress`, which is not in the gate match, so Stop 1 clearance scope stays H({mechanism-shaped}).
|
|
518
525
|
- ! Chip is list-visible state, not consent. Do not drop `mechanism-shaped` without the synthesis-accepted line (or the #3640 empty-disagreement path).
|
|
@@ -522,7 +529,7 @@ Closed catalog (last chip wins): `design-critique:mechanism-shaped` (in-flight,
|
|
|
522
529
|
- ! Leftover `design-critique:mechanism-shaped` after a chip apply miss does not block ingest. `judgmentGates` match is advisory/observe.
|
|
523
530
|
- ⊗ Use the halt line for a chip apply miss.
|
|
524
531
|
- ! Write-back `mechanism-shaped: true` is history after replace. The last catalog chip is list-visible state, not current-state authority. Ingest keys off the completed-arc record and cited lean.
|
|
525
|
-
- !
|
|
532
|
+
- ! A later lean applies `design-critique:mechanism-shaped` with the same remaining-set write and drops `ingest-ready`.
|
|
526
533
|
- ~ A live `design-critique:*` count!=1 check is SHOULD, not a new `judgmentGates` match.
|
|
527
534
|
- ⊗ Add `design-critique:ingest-ready` to `judgmentGates` labels.any-of.
|
|
528
535
|
- ⊗ Add `design-critique:recut-needed` to `judgmentGates` labels.any-of.
|
|
@@ -595,8 +602,8 @@ The intake cross-ref scanners (`packages/core/src/intake/markdown-scanners.ts`)
|
|
|
595
602
|
| `unshaped-table-cite` | a typed table claim names a comment on this thread that opens no line with the verified-claims-table heading |
|
|
596
603
|
| `ambiguous-table-cite` | two typed table claims name different tables |
|
|
597
604
|
| `cancelled` | `design-critique: cancelled, because ...` is the latest terminal record; no later successor lean |
|
|
598
|
-
| `
|
|
599
|
-
| `stale-target` | cited successor lean carries `Target-digest:` and the live REST issue body hash does not match; nothing written. Legacy leans with no digest stay admitted.
|
|
605
|
+
| `set-level-body` | completed-arc is present and the latest `target shape:` field is `set-level` |
|
|
606
|
+
| `stale-target` | cited successor lean carries `Target-digest:` and the live REST issue body hash does not match; nothing written. Legacy leans with no digest stay admitted. Spec-path without digest stays on #4237 |
|
|
600
607
|
|
|
601
608
|
- ! Publish a reason in that table before the evaluator returns it. An unpublished reason code is the same gap as an unpublished citation form.
|
|
602
609
|
- ⊗ Merge two states under one reason when their remedies differ. `missing-table-cite` and `unshaped-table-cite` were one reason and one detail until #3942, and the shared detail asserted an absent id in both, so an author whose table was on the thread read a true citation being called false and had no path to the missing heading.
|
|
@@ -57,7 +57,7 @@ While UAT is **active** (and was started with human-origin provenance):
|
|
|
57
57
|
| settings / deploy heuristics | **deny** |
|
|
58
58
|
| Test execution (`vitest`, `pnpm test`, …) | **allow** |
|
|
59
59
|
| Issue filing (`gh issue create`) | **allow** |
|
|
60
|
-
| Evidence / defect capture writes (`xbrief/proposed/**`,
|
|
60
|
+
| Evidence / defect capture writes (`xbrief/proposed/**`, `evidence/**`, `uat-evidence/**`, `incidents/**` at repo root) | **allow** |
|
|
61
61
|
|
|
62
62
|
Approving one named fix cohort **does not** clear the UAT lock or authorize adjacent
|
|
63
63
|
failures or other operations (e.g. edit grant ≠ push).
|
|
@@ -13,6 +13,9 @@ A consumer could omit Directive enforcement gates from its `check` task and CI w
|
|
|
13
13
|
- `verify:test-boundary`
|
|
14
14
|
- `verify:scope-provenance`
|
|
15
15
|
- `verify:consumer-check-contract`
|
|
16
|
+
- `verify:evaluator-surface` (#4386)
|
|
17
|
+
|
|
18
|
+
`verify:consumer-test-lane` is composed on `check:consumer` / `CONSUMER_CHECK_GATES` only. It is not a required framework-source enforcement gate -- the framework suite remains `ts:check-lane`.
|
|
16
19
|
|
|
17
20
|
It fails with a concrete repair path when definitions or explicit check deps omit them. CI workflows that neither invoke the gates nor a composing entrypoint (`task check` / `deft check`) produce **warnings** by default (migration).
|
|
18
21
|
|
package/docs/gate-integrity.md
CHANGED
|
@@ -85,8 +85,8 @@ Field notes and parent framing: issue [#3156](https://github.com/deftai/directiv
|
|
|
85
85
|
- Verification outcomes: [verification.md](../verification/verification.md).
|
|
86
86
|
- Goal/gate rigidity: [goal-gate-determinism.md](../patterns/goal-gate-determinism.md) (#852).
|
|
87
87
|
- Scope self-auth instance: [scope-provenance.md](./scope-provenance.md) (#3145).
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
- Product-oracle history: `packages/core/src/verify-ac/flag.ts` `flagPassAfterFailWithMethodChange` (#3322) -- shipped detector for fail-then-method-change on product oracles.
|
|
89
|
+
- Evaluator-definition diffs: `task verify:evaluator-surface` (#4386) -- declared surface changes fail regardless of prior color unless `xbrief/evaluator-surface-disposition.json` records disclosure.
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
@@ -103,6 +103,8 @@ Full CI automation that blocks “diff touches a gate that just failed” withou
|
|
|
103
103
|
| Host self-mutate honesty | [#3162](https://github.com/deftai/directive/issues/3162), [host-surface-assumptions.md](./host-surface-assumptions.md) |
|
|
104
104
|
| Safety via formal gates | [#1200](https://github.com/deftai/directive/issues/1200) |
|
|
105
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
|
+
| Product-oracle method-change detector | [#3322](https://github.com/deftai/directive/issues/3322), `flagPassAfterFailWithMethodChange` |
|
|
107
|
+
| Evaluator-definition disclosure | [#4386](https://github.com/deftai/directive/issues/4386), `verify:evaluator-surface` |
|
|
106
108
|
|
|
107
109
|
---
|
|
108
110
|
|
|
@@ -125,3 +127,24 @@ Records already written still pair on `session_id` + `check_id`. A correct class
|
|
|
125
127
|
- ⊗ Host hook enforcement for self-mutating hosts (#3162)
|
|
126
128
|
- ⊗ Replacing design-principle docs under #1200 (complementary)
|
|
127
129
|
- ⊗ Shipping full “gate-diff-when-red” CI automation in this story
|
|
130
|
+
- ⊗ A parallel history detector beside #3322
|
|
131
|
+
- ⊗ Treating a commit-body issue/PR URL as reviewed authorization under #3164
|
|
132
|
+
- ⊗ Inventing a universal shipped-library coverage-population default
|
|
133
|
+
- ⊗ Falsifiable oracles for derived acceptance clauses (separate acceptance-design gap)
|
|
134
|
+
|
|
135
|
+
## Evaluator-definition detector (#4386)
|
|
136
|
+
|
|
137
|
+
#3156 shipped the rule and deferred a dedicated detector. That deferral is the gap, not an unnamed hole. #3322 already watches product-oracle pass-after-fail-with-method-change. The missing piece is **unobserved evaluator-definition changes**, not product-oracle history.
|
|
138
|
+
|
|
139
|
+
`verify:evaluator-surface` is the thin first ship:
|
|
140
|
+
|
|
141
|
+
- Declared evaluator-surface diffs (Taskfile.yml, tasks/verify.yml, coverage config, gate-lists, the detector itself) **fail regardless of prior color**.
|
|
142
|
+
- Prior color is unobserved. Do not silently equate unknown with never-red.
|
|
143
|
+
- A committed `xbrief/evaluator-surface-disposition.json` (`schema: deft.evaluator-surface-disposition.v1`, `kind: disclosure`) is the disposition record. It is **disclosure, not reviewed authorization**.
|
|
144
|
+
- A commit-body issue/PR link is disclosure. It does not satisfy this gate and does not claim #3164 protection.
|
|
145
|
+
|
|
146
|
+
`verify:consumer-test-lane` composes the project's **declared** test command (`plan.policy.testCommand` or `package.json` `scripts.test`) into the consumer chokepoint. It does not replace `PRODUCT_FIRST_AC_GATE` (`verify:ac`). When nothing is declared, it skips -- it does not invent `go test ./...`.
|
|
147
|
+
|
|
148
|
+
Keep the [testing.md](../coding/testing.md) coverage-population exclusion (entry points and main functions). Wire project-specific measured populations in the project's runner config. Do not invent a universal shipped-library default.
|
|
149
|
+
|
|
150
|
+
Falsifiable oracles for derived clauses stay a separate acceptance-design gap. Do not implement a parallel history detector.
|
|
@@ -159,12 +159,20 @@ codex exec --ephemeral --skip-git-repo-check --dangerously-bypass-approvals-and-
|
|
|
159
159
|
|
|
160
160
|
On ChatGPT omit `-m gpt-5.6` (HTTP 400). Self-attest the model the CLI ran.
|
|
161
161
|
|
|
162
|
-
**Grok.** Seat remains `spawn_subagent`.
|
|
162
|
+
**Grok.** Seat remains `spawn_subagent`. Native critic is `subagent_type: general-purpose` plus host-visible `process_only` on PreToolUse stdin (`tool_input` / `toolInput`) and dest cwd. That stdin shape is `spawn-process-only-ready`: no dest occupancy, no leftover `file_scope`, at zero, one, or many leftover eligible briefs. Advertised JSON omitting the field is a separate upstream xAI schema ask; pass is the field on stdin. `subagent_type: plan` cannot post (read-only, no Shell) — dispatch-fail, not a hung critic. Do not make plan the critic seat. Implement-class never sets `process_only`.
|
|
163
|
+
|
|
164
|
+
Unmarked dest-cwd general-purpose is never a critic seat. Count selects that class: 2+ leftover eligible briefs on payloadRoot is Deny 1; 0 is #2885; 1 eligible + dest cwd + parent id is spawn-ready implement-class (dest-lock, leftover `file_scope`). Implement-class pin is `DEFT_ACTIVE_SCOPE`, not a critic recovery.
|
|
165
|
+
|
|
166
|
+
`isolation=worktree` without `cwd` is dest-missing. `isolation=worktree` plus `cwd` is invalid-extra-destination, not dest-missing.
|
|
167
|
+
|
|
168
|
+
grok CLI is last-resort after any native outcome that is not skip-class (`spawn-process-only-ready`):
|
|
163
169
|
|
|
164
170
|
```text
|
|
165
171
|
grok --cwd <dest> --prompt-file <path> --permission-mode bypassPermissions --always-approve --output-format plain
|
|
166
172
|
```
|
|
167
173
|
|
|
174
|
+
That CLI is classified launcher-family argv (#4219): dest-present linked dest is process-only skip; dest-absent fails closed (#4066 dest-proven). Native first. Dest still required. Do not skip dest. Do not classify as implement spawn-class.
|
|
175
|
+
|
|
168
176
|
⊗ Dual-launch native + CLI. ⊗ Retarget the contract Grok seat to CLI.
|
|
169
177
|
|
|
170
178
|
Keep process-only plus one `gh issue comment --body-file` post. `claude agents` may report print-mode as `kind: interactive`; do not kill it as a TTY leftover.
|
|
@@ -52,7 +52,7 @@ recorded on [#3987](https://github.com/deftai/directive/issues/3987).
|
|
|
52
52
|
| `enter_plan_mode`, `exit_plan_mode` | out of scope — session posture |
|
|
53
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
54
|
| `scheduler_create` | **known gap, not covered** — see below |
|
|
55
|
-
| `use_tool` |
|
|
55
|
+
| `use_tool` | MCP_HOOK_MATCHER selects the outer name; dest-bearing write-shaped inners unwrap into inspectMutationGates (#3593) |
|
|
56
56
|
|
|
57
57
|
### `scheduler_create` — spawn-class, needs a policy decision
|
|
58
58
|
|
|
@@ -63,13 +63,13 @@ xBRIEF), which denies a shape that works today — a new deny class, not a
|
|
|
63
63
|
coverage repair. That is a deliberate policy call and belongs in its own change,
|
|
64
64
|
not in a matcher edit.
|
|
65
65
|
|
|
66
|
-
### `use_tool` — mcp-class,
|
|
66
|
+
### `use_tool` — mcp-class proxy, classifier unwraps dest-bearing writes (#3593)
|
|
67
67
|
|
|
68
68
|
`use_tool` is a proxy: the MCP tool actually invoked is nested in
|
|
69
|
-
`tool_input.tool_name
|
|
70
|
-
|
|
71
|
-
`
|
|
72
|
-
|
|
69
|
+
`tool_input.tool_name`. `MCP_HOOK_MATCHER` now includes `use_tool` and `CallMcpTool` so the hook runs.
|
|
70
|
+
The dispatcher unwraps the inner name and routes dest-bearing write-shaped
|
|
71
|
+
inners through `inspectMutationGates`. Reads such as `list_issues` stay on the
|
|
72
|
+
runtime-authority fail-open path. Cursor `CallMcpTool` uses the same unwrap.
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
@@ -126,6 +126,7 @@ an unverified one:
|
|
|
126
126
|
```text
|
|
127
127
|
verify:orphan-active: no orphaned active/running xBRIEFs (scanned 3 running briefs in active/).
|
|
128
128
|
Basis: inventory 2, cache 1 (max age 4m).
|
|
129
|
+
Origins: 0 of 3 scanned briefs resolved zero forge origins.
|
|
129
130
|
```
|
|
130
131
|
|
|
131
132
|
```text
|
|
@@ -138,9 +139,18 @@ verify:orphan-active: no orphaned active/running xBRIEFs (scanned 1 running brie
|
|
|
138
139
|
|
|
139
140
|
`EvaluateResult.basis` carries the same counts structurally
|
|
140
141
|
(`inventory`, `live`, `cache`, `unverified`, `maxCacheAgeMs`, `proxied`,
|
|
141
|
-
`elapsedMs`, `budgetMs`).
|
|
142
|
+
`elapsedMs`, `budgetMs`, `scanned`, `noOrigin`).
|
|
142
143
|
|
|
144
|
+
`noOrigin` is how many evaluated briefs resolved zero forge origins
|
|
145
|
+
(`#4426`). Scoped `--issue N` counts `scanned` / `noOrigin` only for
|
|
146
|
+
briefs that name that issue — unrelated and originless briefs stay off
|
|
147
|
+
those counters. It does not change the two unknown policies: the unscoped
|
|
148
|
+
sweep stays fail-open; scoped `--issue N` stays fail-closed.
|
|
149
|
+
|
|
150
|
+
⊗ Do not flatten the two unknown policies into one rule.
|
|
143
151
|
⊗ Do not cite an exit 0 with `unverified > 0` as evidence that a tree is clean.
|
|
152
|
+
⊗ Do not cite an exit 0 with `noOrigin > 0` as evidence that those briefs
|
|
153
|
+
are clean of shipped residue — they were never origin-keyed.
|
|
144
154
|
|
|
145
155
|
---
|
|
146
156
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# `plan.acceptance` fields `verify:ac` requires (#4380)
|
|
2
|
+
|
|
3
|
+
Fields the product AC gate actually reads. Not a schema dump. Derivation
|
|
4
|
+
(`#3323` / `#3360`) owns the stamp. Setup stays silent on this block.
|
|
5
|
+
|
|
6
|
+
Legend (RFC2119): `!`=MUST, `~`=SHOULD, `⊗`=MUST NOT, `?`=MAY.
|
|
7
|
+
|
|
8
|
+
Load when authoring a scope xBRIEF, when `verify:ac` names a missing field, or
|
|
9
|
+
when a pass line shows `0 verified`.
|
|
10
|
+
|
|
11
|
+
## Exclusive writer
|
|
12
|
+
|
|
13
|
+
- ! `#4374` derivation is the exclusive writer of `plan.acceptance`.
|
|
14
|
+
- ⊗ Setup MUST NOT emit `plan.acceptance` (no schema-complete block, no
|
|
15
|
+
hand-authored `clauses[]`). Hand-authored clauses skip derivation, so
|
|
16
|
+
`needsClauseDerivation` is false and missing `ambiguity_attestation` fires.
|
|
17
|
+
- ⊗ Recut `#4374` clause derivation from this issue.
|
|
18
|
+
|
|
19
|
+
## Fields the gate requires
|
|
20
|
+
|
|
21
|
+
| Field | When required | Who writes it |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `commands` + `none_stated` | Empty commands are allowed only with `none_stated: true` | Intake / derivation |
|
|
24
|
+
| `source_rung` | `stated` / `derived` / `project_floor` | Intake / derivation |
|
|
25
|
+
| `ambiguity_attestation` | Required when `clauses[]` is non-empty and no clause has ambiguous readings. Value `none_found` | Derivation (`prepareClauseStamp`). ⊗ A second `none_found` default on the derivation path |
|
|
26
|
+
| `clauses[].artifact_path` | Bound from declared `plan.metadata.swarm.file_scope` when `source_rung === "derived"` (`#4008`) | Promote bind, not setup |
|
|
27
|
+
| `plan.metadata.swarm.file_scope` | Operator-collected declared members for derived-stamp bind | Operator. ⊗ Agent-invented paths. ⊗ Approved-scope digest mint (`#3145` / `#3110` / `#4383`) |
|
|
28
|
+
| `plan.references` / `plan.metadata["x-tracking"].parent_issue` | Forge origin for origin-keyed sweeps | Operator-collected or minted by `task issue:emit`. ⊗ Agent-asserted. Same polarity as `file_scope` (`#4426`) |
|
|
29
|
+
|
|
30
|
+
Missing attestation is **not** "derivation forgot `none_found`". It fires when
|
|
31
|
+
setup or an agent wrote clauses and skipped `#3323` / `#3360`. Provenance is a
|
|
32
|
+
derivation/ingest constraint, not a `verify:ac` config field.
|
|
33
|
+
|
|
34
|
+
## Pass lead vs fail-closed (`#3826`)
|
|
35
|
+
|
|
36
|
+
A clause with no bound artifact is `unverifiable` and non-adjudicable. On
|
|
37
|
+
pre-product `verify:ac` / `task check`, that walk is **not** fail-closed solely
|
|
38
|
+
because it has no oracle yet (`#3826`). `scope:complete` is a different reader.
|
|
39
|
+
|
|
40
|
+
The pass **lead** carries the counts on the first line:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
verify:ac passed (#3284) (0 verified, N unverifiable) [rung=derived]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
A later lean that wants zero-verified to fail closed MUST reverse `#3826` and
|
|
47
|
+
name the reader (`standalone` / `check` / `complete`).
|
|
48
|
+
|
|
49
|
+
## See also
|
|
50
|
+
|
|
51
|
+
- `task verify:ac` in [`../commands.md`](../commands.md)
|
|
52
|
+
- Clause bind: `packages/core/src/verify-ac/clauses.ts` (`bindClausesToDeclaredScope`)
|
|
53
|
+
- Attestation: `packages/core/src/intake/clause-derivation.ts` (`evaluateAmbiguityAttestation`)
|
package/main.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- DEFT-PREAMBLE-V1 -->
|
|
2
2
|
<!-- deft:deposit-link-rewrite v=1 source="main.md" -->
|
|
3
3
|
! Cold-start check: deft runs from the npm-installed engine (`npm i -g @deftai/directive`). If neither `deft` nor `directive` will run on this machine, do not proceed with the instructions below -- recover first (#1933 Option 1, deprecate-by-disuse).
|
|
4
|
-
! To recover:
|
|
4
|
+
! To recover: follow the #4090 ladder before any other instruction in this file or in the consumer AGENTS.md. Already installed? Run `directive doctor` (or `deft doctor`). CLI not on PATH: `npm i -g @deftai/directive@<pin>` (read pin from committed package.json) then re-run doctor. ⊗ never recover by reading an undeposited README block (#2273 / #4430).
|
|
5
5
|
! Respect any "Restart required" directive -- if present, stop and tell the user to start a fresh session after cleanup commands complete. Otherwise continue.
|
|
6
6
|
|
|
7
7
|
# Warp AI Guidelines
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive-content",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.118.0",
|
|
4
4
|
"deftConsumerDeposit": true,
|
|
5
5
|
"description": "Shippable Directive framework content in the consumer .deft/core/ layout (C1 flatten), plus the engine surfaces (.githooks/, Taskfile.yml, tasks/) the deposit wires. Python-free per #2022 Phase 3. Refs #11, #1669, #1967.",
|
|
6
6
|
"license": "MIT",
|