@deftai/directive-content 0.98.0 → 0.98.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.
@@ -1,6 +1,6 @@
1
1
  # Approved-scope provenance (`verify:scope-provenance`)
2
2
 
3
- Refs: #3145 · Related: #1310, #2944 human-origin grants, #516 file scope
3
+ Refs: #3145 · #3205 · Related: #1310, #2944 human-origin grants, #516 file scope
4
4
 
5
5
  ## Problem
6
6
 
@@ -27,7 +27,8 @@ Shape:
27
27
  "humanApproval": {
28
28
  "kind": "operator",
29
29
  "actor": "scott",
30
- "mintedAt": "2026-08-06T00:00:00Z"
30
+ "mintedAt": "2026-08-06T00:00:00Z",
31
+ "mintedVia": "scope:record-approved-scope"
31
32
  }
32
33
  }
33
34
  ```
@@ -36,19 +37,77 @@ Shape:
36
37
 
37
38
  | Outcome | Behavior |
38
39
  | --- | --- |
39
- | No expansion | Pass |
40
- | Expansion + renewed human stamp / re-recorded matching digest | Pass |
40
+ | No expansion; base-visible human approval matches current scope | Pass |
41
+ | Expansion + independently renewed human stamp / re-recorded matching digest **already on the merge base** | Pass |
41
42
  | Expansion without renewal | **Fail** — self-authorizing scope |
42
- | Modified active xBRIEF, no digest yet | **Warn** by default; `--enforce` fails closed |
43
+ | Approval created or rewritten in the same change set as the active xBRIEF | **Fail** same-PR self-auth |
44
+ | Agent-stamped or missing human approval with non-empty `file_scope` | **Fail** (or migration warn only for empty scope without digest) |
45
+ | Modified active xBRIEF, empty scope, no digest yet | **Warn** by default; `--enforce` fails closed |
43
46
 
44
- Agent-shaped stamps (`kind: agent`, `actor: agent:…`) never count as renewal.
47
+ Agent-shaped stamps (`kind: agent`, `actor: agent:…`) never count as renewal or first-adoption authority.
48
+
49
+ ### Base-ref authority (#3205)
50
+
51
+ Authority comes from the approval record in the **merge base**, not from whether the active xBRIEF path existed there:
52
+
53
+ 1. Read `<baseRef>:.deft/approved-scope/<plan-id>.json`
54
+ 2. Validate schema, human stamp, plan id, path binding, and digest
55
+ 3. Require the current record to be semantically unchanged from that base record
56
+ 4. Permit `pending/` → `active/` (or later expansion) when the current xBRIEF scope matches that base-approved scope
57
+ 5. Fail closed when the base record is absent, malformed, agent-authored, path/digest mismatched, or created/changed alongside the active xBRIEF
58
+
59
+ ## Operator command: `scope:record-approved-scope`
60
+
61
+ Deposit a human-origin digest (first adoption or renewal):
62
+
63
+ ```bash
64
+ task scope:record-approved-scope -- xbrief/pending/story.xbrief.json --actor scott
65
+ # or after expansion review:
66
+ task scope:record-approved-scope -- xbrief/active/story.xbrief.json --actor scott --kind renewed-approval
67
+ ```
68
+
69
+ Flags:
70
+
71
+ | Flag | Required | Notes |
72
+ | --- | --- | --- |
73
+ | `<xbrief-path>` | yes | pending or active xBRIEF JSON |
74
+ | `--actor` | yes | human operator identity (agent actors refused) |
75
+ | `--kind` | no | default `operator`; also `human`, `renewed-approval`, … |
76
+ | `--project-root` | no | defaults via Taskfile to consumer CWD |
77
+ | `--xbrief-rel-path` | no | override path binding; default maps `pending/` → `active/` |
78
+
79
+ Commit the written `.deft/approved-scope/<plan-id>.json` on the **merge base** (or a prior PR) before the implementation PR activates or expands the scoped xBRIEF.
80
+
81
+ ## First-adoption flow (single consumer upgrade)
82
+
83
+ When the first non-empty `file_scope` story and the 0.97+/0.98 gate land together:
84
+
85
+ 1. Author the pending xBRIEF with the intended `file_scope`
86
+ 2. Run `task scope:record-approved-scope -- <pending-xbrief> --actor <you>`
87
+ 3. **Commit and merge** the approval record (and preferably the pending xBRIEF) first — multi-PR bootstrap
88
+ 4. In a follow-up PR, activate (`pending/` → `active/`) without rewriting the approval
89
+ 5. `task verify:scope-provenance -- --base-ref origin/master --enforce` exits 0
90
+
91
+ Emptying `file_scope` to soft-warn past the gate is **not** the supported migration path; it removes the write fence the gate protects.
92
+
93
+ ## Multi-PR approved expansion
94
+
95
+ 1. PR A: operator reviews expanded scope, runs `scope:record-approved-scope`, merges approval only (or approval + docs)
96
+ 2. PR B: updates the active xBRIEF `file_scope` to exactly that approved set; does **not** rewrite the approval file
97
+ 3. Gate passes under `--enforce` because base approval already authorizes the new scope
45
98
 
46
99
  ## Migration path
47
100
 
48
- 1. Ship gate in warn mode (missing digests do not fail)
49
- 2. Start recording digests on activation / promote
101
+ 1. Ship gate in warn mode (missing digests do not fail for empty scope)
102
+ 2. Start recording digests via `scope:record-approved-scope` on activation / promote
50
103
  3. Enable `--enforce` or project policy when ready
51
104
 
52
105
  ## Remediation
53
106
 
54
- Re-record the approved-scope file after human review of the expanded `file_scope`. Editing the xBRIEF alone does not authorize new implementation paths.
107
+ ```bash
108
+ task scope:record-approved-scope -- <xbrief-path> --actor <you>
109
+ git add .deft/approved-scope/<plan-id>.json
110
+ # merge that commit before (or without) co-changing the active xBRIEF expansion
111
+ ```
112
+
113
+ Editing the xBRIEF alone does not authorize new implementation paths.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive-content",
3
- "version": "0.98.0",
3
+ "version": "0.98.1",
4
4
  "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.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/tasks/scope.yml CHANGED
@@ -156,3 +156,19 @@ tasks:
156
156
  - task: :engine:invoke
157
157
  vars:
158
158
  ENGINE_CMD: 'scope-demote {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"'
159
+
160
+ # First-adoption / renewal of approved-scope digests (#3205).
161
+ # Mint a human-origin .deft/approved-scope/<plan-id>.json so
162
+ # verify:scope-provenance can authorize pending→active and operator-approved
163
+ # expansion without same-PR self-authorization.
164
+ # task scope:record-approved-scope -- xbrief/pending/story.xbrief.json --actor scott
165
+ # task scope:record-approved-scope -- xbrief/active/story.xbrief.json --actor scott --kind renewed-approval
166
+ record-approved-scope:
167
+ desc: "Record human-approved file_scope digest under .deft/approved-scope/<plan-id>.json (#3205). Requires --actor <human>. Refuses agent stamps. Path-binds pending→active. Commit on merge base before activation/expansion PR."
168
+ dir: '{{.USER_WORKING_DIR}}'
169
+ deps:
170
+ - task: :engine:_ts-build
171
+ cmds:
172
+ - task: :engine:invoke
173
+ vars:
174
+ ENGINE_CMD: 'scope:record-approved-scope {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"'