@astrosheep/keiyaku 2.9.10 → 2.9.12
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/README.md +86 -45
- package/build/.tsbuildinfo +1 -1
- package/build/agents/providers/claude-agent-sdk/adapter.js +15 -2
- package/build/cli/commands/contract/bind/meta.js +4 -4
- package/build/cli/commands/metadata.js +3 -2
- package/build/cli/commands/projection/kill/handler.js +4 -5
- package/build/cli/commands/shared.js +1 -1
- package/build/cli/commands/task/catalog.js +2 -0
- package/build/cli/commands/task/compose/handler.js +18 -0
- package/build/cli/commands/task/compose/meta.js +10 -0
- package/build/cli/flags.js +5 -1
- package/build/cli/index.js +11 -6
- package/build/cli/parse-flags.js +21 -21
- package/build/cli/parse-metadata.js +5 -2
- package/build/cli/parse-selectors.js +4 -4
- package/build/cli/parse.js +23 -23
- package/build/cli/projection-address.js +7 -7
- package/build/cli/render/task.js +27 -0
- package/build/cli/types.js +1 -1
- package/build/core/addressing.js +3 -3
- package/build/core/call/context.js +3 -3
- package/build/core/call/prompt.js +1 -1
- package/build/core/contract-view.js +1 -1
- package/build/core/draft.js +51 -22
- package/build/core/projection/generation/model.js +1 -1
- package/build/core/projection/generation/projection-generation-runner.js +13 -3
- package/build/core/projection/generation/transitions.js +10 -0
- package/build/core/projection/projection-history.js +1 -1
- package/build/core/projection/projection-kill.js +5 -4
- package/build/core/projection/projection-runner-lock.js +58 -229
- package/build/core/projection/projection-wait.js +2 -2
- package/build/core/projection/projection-wake.js +2 -0
- package/build/core/repository-ledger/claim-evidence.js +1 -1
- package/build/core/repository-ledger/current-state-store.js +455 -337
- package/build/core/repository-ledger/read-model.js +3 -3
- package/build/core/repository-ledger/write-transaction.js +15 -13
- package/build/core/sqlite-process-lifetime-lock.js +194 -0
- package/build/core/task/compose.js +327 -0
- package/build/core/task/index.js +1 -0
- package/build/core/task/settlement-git.js +69 -26
- package/build/core/task/task-git-store.js +1 -0
- package/build/core/task/task-store-repository.js +1 -0
- package/build/flow-error.js +6 -1
- package/build/generated/version.js +2 -2
- package/package.json +2 -2
- package/skills/keiyaku-akuma/SKILL.md +6 -1
- package/skills/keiyaku-task/SKILL.md +23 -1
- package/skills/keiyaku-workflow/SKILL.md +33 -18
|
@@ -5,6 +5,12 @@ import { runGitProcess } from "../../git/core.js";
|
|
|
5
5
|
import { openGitStreamingBatch } from "../../git/streaming-batch.js";
|
|
6
6
|
import { parseTaskDocument } from "./task.js";
|
|
7
7
|
import { parseTaskCoordinate } from "./coordinate.js";
|
|
8
|
+
function observePublicationEffect(observer, effect) {
|
|
9
|
+
try {
|
|
10
|
+
observer?.(effect);
|
|
11
|
+
}
|
|
12
|
+
catch { /* observation cannot participate in the Git transaction */ }
|
|
13
|
+
}
|
|
8
14
|
async function gitResult(cwd, args, input, env, signal) {
|
|
9
15
|
return await runGitProcess(cwd, args, { input, env, signal });
|
|
10
16
|
}
|
|
@@ -78,9 +84,11 @@ export async function createTaskMutationCommit(input) {
|
|
|
78
84
|
], undefined, env, input.signal);
|
|
79
85
|
}
|
|
80
86
|
const tree = (await git(input.cwd, ["write-tree"], undefined, env, input.signal)).trim();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
if (!input.requireCommit) {
|
|
88
|
+
const parentTree = (await git(input.cwd, ["show", "-s", "--format=%T", input.parent], undefined, undefined, input.signal)).trim();
|
|
89
|
+
if (tree === parentTree)
|
|
90
|
+
return input.parent;
|
|
91
|
+
}
|
|
84
92
|
return (await git(input.cwd, ["commit-tree", tree, "-p", input.parent, "-m", input.subject], undefined, undefined, input.signal)).trim();
|
|
85
93
|
}
|
|
86
94
|
finally {
|
|
@@ -88,15 +96,37 @@ export async function createTaskMutationCommit(input) {
|
|
|
88
96
|
}
|
|
89
97
|
}
|
|
90
98
|
/** Stage only the mutated task paths into the real index; leave unrelated entries alone. */
|
|
91
|
-
|
|
99
|
+
async function reconcileTaskMutationIndexPath(cwd, write, signal) {
|
|
100
|
+
const oid = (await git(cwd, ["hash-object", "-w", "--stdin"], write.text, undefined, signal)).trim();
|
|
101
|
+
await git(cwd, [
|
|
102
|
+
"update-index",
|
|
103
|
+
"--add",
|
|
104
|
+
"--cacheinfo",
|
|
105
|
+
`100644,${oid},${taskMutationPath(write)}`,
|
|
106
|
+
], undefined, undefined, signal);
|
|
107
|
+
}
|
|
108
|
+
export async function reconcileTaskMutationIndex(cwd, writes, signal, reconcilePath = async (input) => {
|
|
109
|
+
await reconcileTaskMutationIndexPath(input.cwd, input.write, input.signal);
|
|
110
|
+
}) {
|
|
92
111
|
for (const write of writes) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
await reconcilePath({ cwd, write, signal });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async function snapshotTaskMutationIndex(cwd, writes, signal) {
|
|
116
|
+
const snapshot = [];
|
|
117
|
+
for (const write of writes) {
|
|
118
|
+
const taskPath = taskMutationPath(write);
|
|
119
|
+
const output = await git(cwd, ["ls-files", "--stage", "-z", "--", taskPath], undefined, undefined, signal);
|
|
120
|
+
snapshot.push({ path: taskPath, entries: output.split("\0").filter(Boolean) });
|
|
121
|
+
}
|
|
122
|
+
return snapshot;
|
|
123
|
+
}
|
|
124
|
+
async function restoreTaskMutationIndex(cwd, snapshot, signal) {
|
|
125
|
+
for (const item of snapshot) {
|
|
126
|
+
await git(cwd, ["update-index", "--force-remove", "--", item.path], undefined, undefined, signal);
|
|
127
|
+
if (item.entries.length > 0) {
|
|
128
|
+
await git(cwd, ["update-index", "-z", "--index-info"], `${item.entries.join("\0")}\0`, undefined, signal);
|
|
129
|
+
}
|
|
100
130
|
}
|
|
101
131
|
}
|
|
102
132
|
/**
|
|
@@ -114,20 +144,33 @@ export async function publishTaskMutationCommit(input, deps = {}) {
|
|
|
114
144
|
parent: branch.head,
|
|
115
145
|
writes: input.writes,
|
|
116
146
|
subject: input.subject,
|
|
147
|
+
requireCommit: input.requireCommit,
|
|
117
148
|
signal: input.signal,
|
|
118
149
|
});
|
|
119
150
|
if (commit === branch.head) {
|
|
120
|
-
|
|
151
|
+
const indexBefore = await snapshotTaskMutationIndex(input.cwd, input.writes, input.signal);
|
|
121
152
|
try {
|
|
122
|
-
await reconcileTaskMutationIndex(input.cwd, input.writes, input.signal);
|
|
123
|
-
input.observeEffect
|
|
153
|
+
await reconcileTaskMutationIndex(input.cwd, input.writes, input.signal, deps.reconcileIndexPath);
|
|
154
|
+
observePublicationEffect(input.observeEffect, { effect: "task-reconciliation", status: "succeeded", commit, detail: "current" });
|
|
155
|
+
observePublicationEffect(input.observeEffect, { effect: "task-index-reconciliation", status: "succeeded", commit });
|
|
156
|
+
return commit;
|
|
124
157
|
}
|
|
125
158
|
catch (error) {
|
|
126
|
-
|
|
159
|
+
try {
|
|
160
|
+
await restoreTaskMutationIndex(input.cwd, indexBefore, input.signal);
|
|
161
|
+
}
|
|
162
|
+
catch (restoreError) {
|
|
163
|
+
observePublicationEffect(input.observeEffect, { effect: "task-index-reconciliation", status: "failed", commit, error: restoreError });
|
|
164
|
+
throw new FlowError("INTERNAL_STATE", "cannot restore task index after reconciliation failure", { cause: restoreError });
|
|
165
|
+
}
|
|
166
|
+
observePublicationEffect(input.observeEffect, { effect: "task-index-reconciliation", status: "failed", commit, error });
|
|
167
|
+
throw error;
|
|
127
168
|
}
|
|
128
|
-
return commit;
|
|
129
169
|
}
|
|
170
|
+
const indexBefore = await snapshotTaskMutationIndex(input.cwd, input.writes, input.signal);
|
|
130
171
|
try {
|
|
172
|
+
await reconcileTaskMutationIndex(input.cwd, input.writes, input.signal, deps.reconcileIndexPath);
|
|
173
|
+
observePublicationEffect(input.observeEffect, { effect: "task-index-reconciliation", status: "succeeded", commit });
|
|
131
174
|
await updateBranch({
|
|
132
175
|
cwd: input.cwd,
|
|
133
176
|
ref: branch.ref,
|
|
@@ -135,22 +178,22 @@ export async function publishTaskMutationCommit(input, deps = {}) {
|
|
|
135
178
|
expected: branch.head,
|
|
136
179
|
signal: input.signal,
|
|
137
180
|
}, deps);
|
|
138
|
-
input.observeEffect
|
|
139
|
-
try {
|
|
140
|
-
await reconcileTaskMutationIndex(input.cwd, input.writes, input.signal);
|
|
141
|
-
input.observeEffect?.({ effect: "task-index-reconciliation", status: "succeeded", commit });
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
// Branch fact remains authoritative; index may be repaired by a later mutation.
|
|
145
|
-
input.observeEffect?.({ effect: "task-index-reconciliation", status: "failed", commit, error });
|
|
146
|
-
}
|
|
181
|
+
observePublicationEffect(input.observeEffect, { effect: "task-reconciliation", status: "succeeded", commit, detail: "published" });
|
|
147
182
|
return commit;
|
|
148
183
|
}
|
|
149
184
|
catch (error) {
|
|
150
185
|
lastError = error;
|
|
186
|
+
try {
|
|
187
|
+
await restoreTaskMutationIndex(input.cwd, indexBefore, input.signal);
|
|
188
|
+
}
|
|
189
|
+
catch (restoreError) {
|
|
190
|
+
observePublicationEffect(input.observeEffect, { effect: "task-index-reconciliation", status: "failed", commit, error: restoreError });
|
|
191
|
+
throw new FlowError("INTERNAL_STATE", "cannot restore task index after publication failure", { cause: restoreError });
|
|
192
|
+
}
|
|
193
|
+
observePublicationEffect(input.observeEffect, { effect: "task-index-reconciliation", status: "failed", commit, error });
|
|
151
194
|
}
|
|
152
195
|
}
|
|
153
|
-
input.observeEffect
|
|
196
|
+
observePublicationEffect(input.observeEffect, { effect: "task-reconciliation", status: "failed", error: lastError });
|
|
154
197
|
throw lastError;
|
|
155
198
|
}
|
|
156
199
|
async function taskTreeEntries(cwd, commit) {
|
|
@@ -75,6 +75,7 @@ function mutationPlan(sources, mutation) {
|
|
|
75
75
|
writes: prepared.writes,
|
|
76
76
|
value: mutation.select(prepared.board),
|
|
77
77
|
...(mutation.subject === undefined ? {} : { subject: mutation.subject }),
|
|
78
|
+
requireCommit: mutation.requireCommit ?? true,
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
81
|
export function taskRepositoryFromStore(store) {
|
package/build/flow-error.js
CHANGED
|
@@ -68,6 +68,11 @@ export function resolveFlowErrorHints(code, context, facts) {
|
|
|
68
68
|
return ["Pass one complete task coordinate from the listed candidates."];
|
|
69
69
|
case "UNKNOWN_COMMAND":
|
|
70
70
|
return ["Run `keiyaku --help` to inspect available commands."];
|
|
71
|
+
case "UNKNOWN_OPTION":
|
|
72
|
+
case "UNKNOWN_ADDRESS":
|
|
73
|
+
case "INVALID_USAGE":
|
|
74
|
+
case "STDIN_EMPTY":
|
|
75
|
+
return [];
|
|
71
76
|
case "EMPTY_PARAM":
|
|
72
77
|
return ["One or more required parameters are empty."];
|
|
73
78
|
case "DIRTY_WORKTREE":
|
|
@@ -95,7 +100,7 @@ export function resolveFlowErrorHints(code, context, facts) {
|
|
|
95
100
|
case "FROM_DRAFT_NOT_FOUND":
|
|
96
101
|
return ["The path in `from_draft` does not exist. `from_draft` must reference an existing file path (absolute or relative to `cwd`)."];
|
|
97
102
|
case "INVALID_KEIYAKU_DRAFT":
|
|
98
|
-
return ["Invalid draft/input. Use a `# <title>` heading with non-empty `## Context`, `## Objective`, `## Design`, `## Scope`, `## Criteria`, and `## Verification` sections (or the equivalent shape in `from_draft`)."];
|
|
103
|
+
return ["Invalid draft/input. Use a `# <title>` heading with non-empty `## Context`, `## Objective`, `## Design & Approach`, `## Scope`, `## Criteria`, and `## Verification` sections (or the equivalent shape in `from_draft`)."];
|
|
99
104
|
case "BIND_TASK_INCOMPLETE":
|
|
100
105
|
return ["Task supplies title/objective defaults; pipe only the missing sections as partial contract Markdown on stdin."];
|
|
101
106
|
case "KEIYAKU_FILE_EXISTS":
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Generated into build output by scripts/build.mjs
|
|
2
|
-
export const VERSION = "2.9.
|
|
3
|
-
export const GIT_HASH = "
|
|
2
|
+
export const VERSION = "2.9.12";
|
|
3
|
+
export const GIT_HASH = "25d9570";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrosheep/keiyaku",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.12",
|
|
4
4
|
"description": "CLI for running iterative keiyaku workflows with Codex subagents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"start": "node build/index.js",
|
|
34
34
|
"test:unit": "node scripts/run-unit-tests.mjs",
|
|
35
35
|
"test:boundaries": "node scripts/check-import-boundaries.mjs",
|
|
36
|
-
"test:integration": "node --import ./tests/support/real-provider-path-sentinel.mjs --import tsx --test tests/integration
|
|
36
|
+
"test:integration": "node --import ./tests/support/real-provider-path-sentinel.mjs --import tsx --test --test-concurrency=4 tests/integration/*.test.ts",
|
|
37
37
|
"pretest:cli-expect": "npm run build",
|
|
38
38
|
"test:cli-expect": "node --import ./tests/support/real-provider-path-sentinel.mjs --test --test-concurrency=8 tests/cli-expect/suite/*.test.mjs",
|
|
39
39
|
"test:real-providers": "KEIYAKU_REAL_PROVIDERS=1 node --import tsx --test --test-concurrency=1 tests/real-provider/matrix.test.ts",
|
|
@@ -52,7 +52,8 @@ keiyaku wait <proj-a> <proj-b> --any # return when the first member fin
|
|
|
52
52
|
keiyaku wait <proj-a> <proj-b> --all # return when every member finishes
|
|
53
53
|
keiyaku tell <proj-id> [--wait DURATION] <BODY|-> # optionally tell, then bounded-join
|
|
54
54
|
keiyaku revive rsp_XXXX "continue..." # new run continuing from a record
|
|
55
|
-
keiyaku kill <proj-id> # stop
|
|
55
|
+
keiyaku kill <proj-id> # request a stop; returns an acceptance receipt
|
|
56
|
+
keiyaku kill <proj-id> --wait 5m # request a stop, then observe the result for 5m
|
|
56
57
|
keiyaku status # forgot an id? it's on the board
|
|
57
58
|
```
|
|
58
59
|
|
|
@@ -74,6 +75,10 @@ Use `keiyaku akuma show NAME` to inspect the resolved source and configuration.
|
|
|
74
75
|
success means the tell and interrupt intent are durable; provider stop and
|
|
75
76
|
successor wake continue asynchronously under the same projection id. Idle or
|
|
76
77
|
terminal state uses ordinary tell plus wake and reports its typed wake error.
|
|
78
|
+
- `kill` returns an acceptance receipt; it does not include the final result.
|
|
79
|
+
Use `kill --wait DURATION` when you need to observe the ordinary final result.
|
|
80
|
+
`DURATION` is required. A timeout ends observation only and does not undo the
|
|
81
|
+
stop request.
|
|
77
82
|
- Body is required for `call`/`tell`. Literal `-` selects stdin; unselected
|
|
78
83
|
piped bytes are ignored and cannot change an argv body.
|
|
79
84
|
- A `--wait`/`--timeout` expiry prints a live snapshot and exits 0 — the run continues; rejoin with `wait` anytime.
|
|
@@ -38,6 +38,28 @@ keiyaku task update k-xxxx --pri 0 # also --title, --body TEXT|-, -
|
|
|
38
38
|
keiyaku task doctor # check board integrity
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
## Atomic reorganization
|
|
42
|
+
|
|
43
|
+
Use `task compose` when the final tree and its complete outgoing relation sets
|
|
44
|
+
need review as one operation. Pass the compact sketch through stdin and check
|
|
45
|
+
it before applying it:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
keiyaku task compose --check - <<'EOF'
|
|
49
|
+
+ Project grouping
|
|
50
|
+
@parser needs=@types
|
|
51
|
+
@renderer relates=
|
|
52
|
+
@release parent=
|
|
53
|
+
EOF
|
|
54
|
+
keiyaku task compose - < composition.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
An indented line assigns its parent. A top-level `@reference` keeps its parent;
|
|
58
|
+
`parent=` explicitly clears it. `needs=`, `supersedes=`, and `relates=` replace
|
|
59
|
+
only their named complete relation sets, and an explicit empty assignment clears
|
|
60
|
+
that set. Omit a relation to preserve it. Use the command help for the current
|
|
61
|
+
sketch grammar and receipt fields; this skill does not redefine task policy.
|
|
62
|
+
|
|
41
63
|
## Dependencies
|
|
42
64
|
|
|
43
65
|
`--needs` stores the forward edge; `blocks` on the other task is derived automatically. Cycles are rejected at write time. Use needs to express "don't start B before A lands" — nothing more.
|
|
@@ -54,7 +76,7 @@ intent, share a coherent write surface, and should settle together; otherwise
|
|
|
54
76
|
keep separate contracts and express order with task `needs` or contract
|
|
55
77
|
`--after`. The first task supplies title/objective defaults; provide a partial
|
|
56
78
|
bind document for every remaining resolved section. Final bind admission always
|
|
57
|
-
requires Title, Context, Objective, Design, Scope, and Criteria; Verification
|
|
79
|
+
requires Title, Context, Objective, Design & Approach, Scope, and Criteria; Verification
|
|
58
80
|
is optional.
|
|
59
81
|
|
|
60
82
|
## Gotcha
|
|
@@ -17,12 +17,33 @@ allowed-tools: Bash(keiyaku *)
|
|
|
17
17
|
`arc`, `renew`, or `petition`.
|
|
18
18
|
- An arc is a coherent chapter of the same delivery. It keeps the contract,
|
|
19
19
|
worktree, branch, and final settlement.
|
|
20
|
-
- `audit`
|
|
20
|
+
- `audit` is the primary integrated review of one pinned candidate; `petition`
|
|
21
|
+
asks to settle that candidate.
|
|
21
22
|
|
|
22
23
|
```text
|
|
23
24
|
bound -> active -> petitioned -> claimed | forfeited
|
|
24
25
|
```
|
|
25
26
|
|
|
27
|
+
## Choosing Scope
|
|
28
|
+
|
|
29
|
+
Scope names the files this contract is currently expected to write. Use exact
|
|
30
|
+
repository-relative paths when known, a one-component wildcard for unknown
|
|
31
|
+
files in one directory, and a recursive wildcard only when the Objective calls
|
|
32
|
+
for changing the whole subtree.
|
|
33
|
+
|
|
34
|
+
## Scope
|
|
35
|
+
~~~
|
|
36
|
+
src/pump.ts
|
|
37
|
+
~~~
|
|
38
|
+
|
|
39
|
+
Scope overlap means contracts may write the same paths; it does not prove their
|
|
40
|
+
changes conflict or forbid parallel work. If intents are independent, proceed
|
|
41
|
+
in parallel and use `--after` to order settlement; use `--exclusive` only when
|
|
42
|
+
concurrent work is unsafe.
|
|
43
|
+
|
|
44
|
+
Amend is cheap. Broad Scope consumes parallel coordination and weakens audit
|
|
45
|
+
signal, so broader patterns need a reason while narrower terms do not.
|
|
46
|
+
|
|
26
47
|
## Bind
|
|
27
48
|
|
|
28
49
|
Bind when one implementation journey is decided: motivating facts, owning
|
|
@@ -30,19 +51,12 @@ modules, inputs and outputs, consequences, failure behavior, invariants,
|
|
|
30
51
|
forbidden expansion, write set, acceptance criteria, and decisive checks.
|
|
31
52
|
Use a task only when planning or dependencies need a durable place.
|
|
32
53
|
|
|
33
|
-
Declare the smallest useful Scope:
|
|
34
|
-
|
|
35
|
-
1. exact paths when known;
|
|
36
|
-
2. a one-component wildcard when names inside one directory are still open;
|
|
37
|
-
3. a recursive wildcard only for a real subtree rewrite, migration, or
|
|
38
|
-
generated output.
|
|
39
|
-
|
|
40
54
|
```bash
|
|
41
55
|
keiyaku bind - < contract.md
|
|
42
56
|
keiyaku bind --task TASK_ID - < contract.md
|
|
43
57
|
```
|
|
44
58
|
|
|
45
|
-
The contract document carries `Title`, `Context`, `Objective`, `Design`,
|
|
59
|
+
The contract document carries `Title`, `Context`, `Objective`, `Design & Approach`,
|
|
46
60
|
`Scope`, `Criteria`, and optional `Verification`. Add newly expected exact paths
|
|
47
61
|
with `amend`; do not pre-authorize a broad tree for convenience.
|
|
48
62
|
|
|
@@ -81,16 +95,14 @@ keiyaku status
|
|
|
81
95
|
- `amend` records a changed intent, invariant, Scope, Criteria, or Verification
|
|
82
96
|
before implementation relies on that change.
|
|
83
97
|
|
|
84
|
-
Scope changes are ordered terms. Use
|
|
85
|
-
`Scope Append` block for an ordered delta:
|
|
98
|
+
Scope changes are ordered terms. Use `--append-scope` for a simple addition or
|
|
99
|
+
one `Scope Append` block for an ordered delta:
|
|
86
100
|
|
|
87
|
-
````markdown
|
|
88
101
|
## Scope Append
|
|
89
|
-
|
|
102
|
+
~~~
|
|
90
103
|
src/new-owner.ts
|
|
91
104
|
!src/retired/**
|
|
92
|
-
|
|
93
|
-
````
|
|
105
|
+
~~~
|
|
94
106
|
|
|
95
107
|
Later `!pattern` terms narrow earlier matches. Do not mix the block with
|
|
96
108
|
`--append-scope` flags.
|
|
@@ -113,9 +125,12 @@ been reviewed again.
|
|
|
113
125
|
|
|
114
126
|
## Settle
|
|
115
127
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
128
|
+
Commit, renew if stale, then run `audit` first. Audit already combines the
|
|
129
|
+
candidate diff, Scope, Criteria, Verification, and delivery context.
|
|
130
|
+
|
|
131
|
+
If the evidence is sufficient, petition. Otherwise, run only the check needed
|
|
132
|
+
for a specific gap. `not configured` is not itself a failure. Audit exit 0 means
|
|
133
|
+
a report was produced, not that the candidate passed.
|
|
119
134
|
|
|
120
135
|
```bash
|
|
121
136
|
keiyaku audit
|