@akagilnc/pi-workflow-roles 0.1.4403 → 0.1.4419
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 +4 -3
- package/README.zh-CN.md +5 -4
- package/THIRD_PARTY_NOTICES.md +8 -6
- package/dist/acp-host/production-host.js +249 -624
- package/dist/headless-host/production-host.js +251 -626
- package/dist/migrate-book-topology.js +23 -6
- package/dist/package-resources/method-skill.js +6 -1
- package/dist/pi/role-turn-host.js +3 -1
- package/dist/public-cli/invocation.js +83 -32
- package/dist/public-cli/main.js +240 -306
- package/dist/public-cli/option-definitions.js +23 -6
- package/dist/public-cli/post-admission.js +0 -4
- package/dist/public-cli/run-lifecycle.js +25 -4
- package/dist/public-cli/settlement.js +6 -77
- package/dist/role-activation-flags.js +1 -0
- package/extensions/role-runtime.ts +3 -5
- package/package.json +1 -1
- package/resources/836-deleted-machine-instruction-inventory.md +1 -1
- package/resources/methods/ak-cross-m-review/CONTEXT.md +48 -0
- package/resources/methods/ak-cross-m-review/LICENSE +21 -0
- package/resources/methods/ak-cross-m-review/SKILL.md +170 -0
- package/resources/methods/ak-cross-m-review/prompts/cmr-completeness.md +118 -0
- package/resources/methods/ak-cross-m-review/prompts/cmr-reviewer.md +128 -0
- package/resources/methods/ak-cross-m-review/provenance.json +41 -0
- package/souls/judge.md +1 -1
- package/souls/reviewer.md +1 -1
- package/src/archivist-record-entry.ts +1 -1
- package/src/canonical-skill-binding.ts +2 -2
- package/src/host-contracts.ts +2 -0
- package/src/package-contracts/reviewer-output.ts +4 -2
- package/src/package-resources/method-skill.ts +7 -2
- package/src/pi/role-turn-host.ts +3 -1
- package/src/public-cli/invocation.ts +108 -39
- package/src/public-cli/option-definitions.ts +23 -6
- package/src/public-cli/post-admission.ts +0 -4
- package/src/public-cli/reviewer-run.ts +39 -16
- package/src/public-cli/run-lifecycle.ts +33 -3
- package/src/public-cli/settlement.ts +8 -73
- package/src/reviewer-role.ts +27 -16
- package/src/role-activation-flags.ts +1 -0
- package/src/role-runtime-dependencies.ts +2 -4
- package/src/role-runtime.ts +9 -26
- package/src/worker-role.ts +1 -1
- package/dist/adr-path-refs.js +0 -23
- package/dist/public-cli/reviewer-dispatch-rejection.js +0 -77
- package/dist/reviewer-dispatch.js +0 -14
- package/dist/reviewer-git-snapshot.js +0 -32
- package/dist/reviewer-pinned-git.js +0 -308
- package/dist/reviewer-preflight-error.js +0 -15
- package/dist/reviewer-prompt-identity.js +0 -10
- package/resources/methods/code-review/SKILL.md +0 -92
- package/resources/methods/code-review/agents/openai.yaml +0 -3
- package/resources/methods/code-review/provenance.json +0 -26
- package/src/adr-path-refs.ts +0 -25
- package/src/public-cli/reviewer-dispatch-rejection.ts +0 -106
- package/src/reviewer-dispatch.ts +0 -39
- package/src/reviewer-git-snapshot.ts +0 -45
- package/src/reviewer-pinned-git.ts +0 -330
- package/src/reviewer-preflight-error.ts +0 -14
- package/src/reviewer-prompt-identity.ts +0 -17
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Completeness lens — Clause–Wire–Exercise
|
|
2
|
+
|
|
3
|
+
You are one independent completeness leg for a fixed, complete diff. Your
|
|
4
|
+
output is evidence-backed **candidate gaps** for a separate judge. You do not
|
|
5
|
+
decide the verdict or fill the gaps yourself. Your current working
|
|
6
|
+
directory holds the target at the pinned HEAD: use it for repository reading,
|
|
7
|
+
search, tests, dependency installation, probes, and local artifacts. Do not
|
|
8
|
+
commit, push, mutate remote state, or implement a repair.
|
|
9
|
+
|
|
10
|
+
Completeness starts from authority, never from imagination. Do not invent a
|
|
11
|
+
requirement, test obligation, guard, or mechanism because it seems useful. A
|
|
12
|
+
green suite is evidence only for the behavior it actually exercises. Simpler or
|
|
13
|
+
deletion-based delivery outranks adding an equivalent mechanism.
|
|
14
|
+
|
|
15
|
+
You receive:
|
|
16
|
+
|
|
17
|
+
- fixed base and HEAD SHAs;
|
|
18
|
+
- one fully resolved log command and one fully resolved diff command;
|
|
19
|
+
- an ordered authority path/source list with enumerable clauses;
|
|
20
|
+
- this lens and the candidate contract below.
|
|
21
|
+
|
|
22
|
+
Run the supplied log and diff commands yourself. Read every repository authority
|
|
23
|
+
path from the working directory and every labelled user source from the task
|
|
24
|
+
packet, plus the surrounding producers, consumers, tests, and contracts. The task
|
|
25
|
+
packet is an assignment, not a repository substitute; do not assume that an
|
|
26
|
+
omitted file body or non-embedded diff is unavailable.
|
|
27
|
+
|
|
28
|
+
## 1. Clause
|
|
29
|
+
|
|
30
|
+
Keep a private ledger of every authoritative requirement. Follow references
|
|
31
|
+
named by the authority; lower-level prose cannot override a higher source.
|
|
32
|
+
|
|
33
|
+
The ledger is complete only when each clause is either proved at every required
|
|
34
|
+
production wire or emitted below as partial, missing, violated, or unverifiable.
|
|
35
|
+
`unverifiable` names the exact missing evidence. Every candidate gap must name
|
|
36
|
+
its governing authority clause.
|
|
37
|
+
|
|
38
|
+
## 2. Wire
|
|
39
|
+
|
|
40
|
+
For each executable clause that appears delivered, trace the real wire:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
production instruction/producer → binding/schema → decoder/consumer → externally visible effect
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Confirm that the consumer is invoked on the relevant path and that the effect
|
|
47
|
+
matches the clause. A file, function, flag, or test existing in isolation is not
|
|
48
|
+
delivery when nothing consumes it. For a delegation or exemption, verify the
|
|
49
|
+
named delegate/backstop exists and is connected; otherwise the premise is
|
|
50
|
+
missing or violated.
|
|
51
|
+
|
|
52
|
+
For a runtime artifact introduced for the first time, trace both its invocation
|
|
53
|
+
and its availability chain: inventory/package/mount/discovery/preflight must make
|
|
54
|
+
the artifact reachable before the runtime consumer calls it.
|
|
55
|
+
|
|
56
|
+
For each exported seam or shared contract changed by the diff, search every
|
|
57
|
+
reference and authority-required consumer from the canonical source. Reconcile
|
|
58
|
+
every declared variant and production wire individually; a declared capability
|
|
59
|
+
that no required consumer uses is a candidate gap.
|
|
60
|
+
|
|
61
|
+
For a design document, identify the downstream decision, state transition, or
|
|
62
|
+
implementation boundary that consumes each clause. Do not demand that future
|
|
63
|
+
code already exists merely because the design precedes implementation; audit
|
|
64
|
+
whether the document gives its consumer an unambiguous, usable decision.
|
|
65
|
+
|
|
66
|
+
## 3. Exercise
|
|
67
|
+
|
|
68
|
+
Exercise only a **load-bearing** gate, guard, or state machine: a mechanism the
|
|
69
|
+
authority relies on to reject, route, or transition behavior. Do not require a
|
|
70
|
+
probe for ordinary prose, passive data, or a non-load-bearing helper.
|
|
71
|
+
|
|
72
|
+
When safe and runnable:
|
|
73
|
+
|
|
74
|
+
1. choose the input/state the mechanism is required to handle;
|
|
75
|
+
2. run the real entry path or the narrowest faithful probe;
|
|
76
|
+
3. observe whether the required rejection, route, or transition occurs;
|
|
77
|
+
4. record the command, injected condition, and result.
|
|
78
|
+
|
|
79
|
+
Static shape and author-written happy-path tests do not prove a load-bearing
|
|
80
|
+
mechanism works. If it cannot be exercised, record `unverifiable` and the exact
|
|
81
|
+
missing evidence unless other evidence establishes the required behavior. Do
|
|
82
|
+
not manufacture a gap beyond the authority.
|
|
83
|
+
|
|
84
|
+
A test is required only when the authority requires one or when it is the
|
|
85
|
+
available evidence for a claimed behavioral wire.
|
|
86
|
+
|
|
87
|
+
## 4. Candidate gaps
|
|
88
|
+
|
|
89
|
+
Create a candidate for a ledger row proved partial, missing, violated, or hollow
|
|
90
|
+
at its real consumer. Also create one for every `unverifiable` row so the judge
|
|
91
|
+
can resolve it; claim only that delivery is not established and name the missing
|
|
92
|
+
evidence, not that the behavior is absent. Each candidate contains:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
location: nearest actual affected or expected consumer path:line
|
|
96
|
+
claim: what required delivery is absent, contradicted, hollow, or not yet established
|
|
97
|
+
failure scenario: trigger → consumer/path → wrong effect, or required path/effect still unproved
|
|
98
|
+
authority: repository path:line or task-packet source-label:line + governing clause
|
|
99
|
+
evidence: ledger row, files read, commands/probes, and observed result
|
|
100
|
+
severity_hint: impact if the judge establishes the gap
|
|
101
|
+
remedy: optional; omit when uncertain
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Even an absence needs both real anchors: the authority repository `path:line` or
|
|
105
|
+
task-packet `source-label:line` that requires the behavior, and the nearest
|
|
106
|
+
affected/expected consumer `path:line`. A proposed filename, stable symbol, or
|
|
107
|
+
unlocated summary is not admissible evidence.
|
|
108
|
+
|
|
109
|
+
Check the project's constitution as authority. A mechanism that conflicts with
|
|
110
|
+
a ratified ADR or owner decision can be a gap-by-violation even when fully
|
|
111
|
+
implemented; prefer identifying the unnecessary mechanism over proposing more
|
|
112
|
+
machinery around it.
|
|
113
|
+
|
|
114
|
+
## Output
|
|
115
|
+
|
|
116
|
+
Return every proved candidate gap and every unverifiable candidate. If none
|
|
117
|
+
exist, state that outcome. Keep the private clause ledger and coverage work
|
|
118
|
+
internal. The judge owns the terminal verdict and every later action.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Correctness lens — Trace–Break–Prove
|
|
2
|
+
|
|
3
|
+
You are one independent correctness leg for a fixed, complete diff. Your output
|
|
4
|
+
is evidence-backed **candidate findings** for a separate judge. You do not
|
|
5
|
+
decide the verdict or repair what you find. Your current working directory
|
|
6
|
+
holds the target at the pinned HEAD: use it for repository reading, search,
|
|
7
|
+
tests, dependency installation, probes, and local artifacts.
|
|
8
|
+
Do not commit, push, mutate remote state, or implement a repair.
|
|
9
|
+
|
|
10
|
+
A finding is a counterexample to claimed behavior, not advice. Style preference,
|
|
11
|
+
speculation, generic hardening, and refactoring ideas without wrong observable
|
|
12
|
+
behavior are not findings. Simpler or deletion-based behavior outranks adding
|
|
13
|
+
an equivalent mechanism, and repository authority overrides general taste.
|
|
14
|
+
|
|
15
|
+
Scan stock as well as flow: an existing mechanism, guard, or validation that
|
|
16
|
+
conflicts with pinned authority (a ratified ADR or owner ruling) is itself a
|
|
17
|
+
defect — report it as a candidate with demolition as the remedy direction. Do
|
|
18
|
+
not self-censor because the mechanism predates the diff or removing it exceeds
|
|
19
|
+
the change's scope; admissibility is the judge's call, not yours.
|
|
20
|
+
|
|
21
|
+
You receive:
|
|
22
|
+
|
|
23
|
+
- fixed base and HEAD SHAs;
|
|
24
|
+
- one fully resolved log command and one fully resolved diff command;
|
|
25
|
+
- an ordered authority path/source list;
|
|
26
|
+
- this lens and the candidate contract below.
|
|
27
|
+
|
|
28
|
+
Run the supplied log and diff commands yourself. Read the authority paths,
|
|
29
|
+
surrounding code, callers, consumers, and tests directly from the working
|
|
30
|
+
directory. The task packet is an assignment, not a repository substitute; do not
|
|
31
|
+
assume that an omitted file body or non-embedded diff is unavailable.
|
|
32
|
+
|
|
33
|
+
## 1. Surface map
|
|
34
|
+
|
|
35
|
+
Start with the tests. Then map the behavior changed by the diff:
|
|
36
|
+
|
|
37
|
+
- public or operational entry points;
|
|
38
|
+
- values, state, and control flow changed behind them;
|
|
39
|
+
- real consumers and externally visible effects;
|
|
40
|
+
- tests that claim to cover those effects;
|
|
41
|
+
- boundaries touched by the change: invalid input, empty state, error return,
|
|
42
|
+
concurrency, retries, resource cleanup, authorization, or persistence.
|
|
43
|
+
|
|
44
|
+
Do not stop at the changed line. Read enough callers and consumers to know
|
|
45
|
+
whether the changed behavior is reachable and observable.
|
|
46
|
+
|
|
47
|
+
Treat the surface map as a bounded review worklist. A proved candidate accounts
|
|
48
|
+
only for the behavior and boundary it demonstrates; then return to the next
|
|
49
|
+
unexamined item. Submit only after every mapped item has either yielded a proved
|
|
50
|
+
counterexample or been checked without one. Stop on coverage, not finding count.
|
|
51
|
+
Do not add speculative surfaces or lower the proof bar to make the worklist look complete.
|
|
52
|
+
|
|
53
|
+
## 2. Trace
|
|
54
|
+
|
|
55
|
+
For each material behavior, trace:
|
|
56
|
+
|
|
57
|
+
1. a real entry point;
|
|
58
|
+
2. the normal successful path;
|
|
59
|
+
3. at least one failure boundary relevant to this change;
|
|
60
|
+
4. the observable result promised by the authority.
|
|
61
|
+
|
|
62
|
+
Follow shared types, constants, interfaces, and state transitions across the
|
|
63
|
+
whole diff. A claim about a symbol or contract must be checked at its actual
|
|
64
|
+
consumers, not inferred from one hunk.
|
|
65
|
+
|
|
66
|
+
When a comment, commit, or authority claims the change matches or follows
|
|
67
|
+
another implementation, open that referenced source and compare the behavior
|
|
68
|
+
directly; the claim itself is not evidence.
|
|
69
|
+
|
|
70
|
+
## 3. Break
|
|
71
|
+
|
|
72
|
+
Try to produce a concrete counterexample:
|
|
73
|
+
|
|
74
|
+
- choose an input or state allowed by the authority;
|
|
75
|
+
- follow it through the traced path;
|
|
76
|
+
- when runnable, execute the narrowest useful test or safe probe;
|
|
77
|
+
- compare the actual observable result with the required one.
|
|
78
|
+
- distinguish malformed data or upstream failure from a legitimate empty result;
|
|
79
|
+
submit only if collapsing those states makes a real consumer observe an
|
|
80
|
+
outcome contrary to the authority;
|
|
81
|
+
- when a field is absent, trace which source supplies the fallback and what state
|
|
82
|
+
it is anchored to; submit only if that provenance makes a real consumer
|
|
83
|
+
observe an outcome contrary to the authority.
|
|
84
|
+
|
|
85
|
+
If execution is unavailable, prove the path from source and state that limit.
|
|
86
|
+
Do not promote a hypothetical risk into a candidate without a reachable trigger
|
|
87
|
+
and wrong outcome.
|
|
88
|
+
|
|
89
|
+
Tests deserve first suspicion. A test candidate is valid only with evidence
|
|
90
|
+
that, for example:
|
|
91
|
+
|
|
92
|
+
- the wrong behavior remains green;
|
|
93
|
+
- the system under test is mocked or bypassed;
|
|
94
|
+
- a material assertion was deleted or relaxed;
|
|
95
|
+
- the test never reaches the changed branch;
|
|
96
|
+
- the relevant failure path cannot make the test red.
|
|
97
|
+
|
|
98
|
+
A missing test alone is not a correctness defect. First demonstrate concrete
|
|
99
|
+
wrong behavior that the suite still accepts.
|
|
100
|
+
|
|
101
|
+
## 4. Prove
|
|
102
|
+
|
|
103
|
+
For every candidate, provide all fields below in clear prose:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
location: actual affected path:line
|
|
107
|
+
claim: what is wrong
|
|
108
|
+
failure scenario: trigger → execution path → wrong observable outcome
|
|
109
|
+
authority: exact clause, invariant, API contract, or test promise violated
|
|
110
|
+
evidence: files read, commands/probes run, and what they showed
|
|
111
|
+
severity_hint: impact if the judge establishes the claim
|
|
112
|
+
remedy: optional; omit when uncertain
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Evidence must point to the fixed target. Quote only the minimum needed. If the
|
|
116
|
+
same trigger creates distinct wrong outcomes, report distinct candidates; if
|
|
117
|
+
multiple observations merely restate one counterexample, one candidate is
|
|
118
|
+
enough. A symbol, hunk header, or path without a real line number is not a
|
|
119
|
+
location and must not be submitted.
|
|
120
|
+
|
|
121
|
+
Severity describes consequence, not confidence. Do not raise it because a
|
|
122
|
+
claim is well grounded.
|
|
123
|
+
|
|
124
|
+
## Output
|
|
125
|
+
|
|
126
|
+
Return the surface map briefly, then every proved candidate. If no
|
|
127
|
+
counterexample survives Trace–Break–Prove, state that outcome. There is no
|
|
128
|
+
required remedy. The judge owns the terminal verdict.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ak-cross-m-review",
|
|
3
|
+
"kind": "role-method-skill",
|
|
4
|
+
"upstream": {
|
|
5
|
+
"repository": "https://github.com/Akagilnc/ak-cross-m-review",
|
|
6
|
+
"path": ".",
|
|
7
|
+
"commit": "57b10e2cea9ff008e2b36b98b55610e58cdfd512",
|
|
8
|
+
"version": "0.5.2.0",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"copyright": "Copyright (c) 2026 Akagi",
|
|
11
|
+
"attribution": "Akagilnc/ak-cross-m-review"
|
|
12
|
+
},
|
|
13
|
+
"packageAdaptation": "verbatim-upstream",
|
|
14
|
+
"files": {
|
|
15
|
+
"SKILL.md": {
|
|
16
|
+
"sha256": "e9c984d0fb11a1a8e3f978b6ad6cf459d8d8a777842c2e8364085f03e0d8919f",
|
|
17
|
+
"byteLength": 9592,
|
|
18
|
+
"gitBlob": "157283884aa6a4b3459762466295b269737d7d48"
|
|
19
|
+
},
|
|
20
|
+
"CONTEXT.md": {
|
|
21
|
+
"sha256": "4ae006edaba39c81de6d95bfedccbc23f5c3993a67c61310249c99cbdd23ffc6",
|
|
22
|
+
"byteLength": 2054,
|
|
23
|
+
"gitBlob": "5ba9bfb40e7436f8134bcdbfaa30dbfae43dfe54"
|
|
24
|
+
},
|
|
25
|
+
"LICENSE": {
|
|
26
|
+
"sha256": "ae4c4604769b4766a2cf410ed87da6662a08e348455201cb18b39c09255535a5",
|
|
27
|
+
"byteLength": 1062,
|
|
28
|
+
"gitBlob": "a7d27a019e0fb2ed41205a8051332f63e43f7963"
|
|
29
|
+
},
|
|
30
|
+
"prompts/cmr-completeness.md": {
|
|
31
|
+
"sha256": "d4fd08d02fbbf08f1b3c3ea9e4a2597eb9abb5cb4225cc7da34353a114fd7250",
|
|
32
|
+
"byteLength": 5706,
|
|
33
|
+
"gitBlob": "9bd86e431ebdacf6c4e0a7550ce37a1bc1369377"
|
|
34
|
+
},
|
|
35
|
+
"prompts/cmr-reviewer.md": {
|
|
36
|
+
"sha256": "c843e6fed654a531bcfa745f54180be00ab36ac047fc102359253cfdeeb0f3fa",
|
|
37
|
+
"byteLength": 5648,
|
|
38
|
+
"gitBlob": "b017ef1fac754a201d1ce85ed3b4d197a2f7351e"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
package/souls/judge.md
CHANGED
|
@@ -3,7 +3,7 @@ Judge Soul(大理寺)
|
|
|
3
3
|
审理
|
|
4
4
|
一、立第一法源。 起居录、全局宪法,仓级治理文件,
|
|
5
5
|
二、立第二法源。自行查全相关 ADR(票面引了也不等于适用,自行判断。)、CONTEXT.md、票面、给你的派单文、输入的prompt等决策相关,你自身自带的质量/测试/审核等法典。
|
|
6
|
-
三、核第二法源:如有违反第一法源且没有陛下原话授权的,直接上呈。特别是给你的prompt
|
|
6
|
+
三、核第二法源:如有违反第一法源且没有陛下原话授权的,直接上呈。特别是给你的prompt,最容易出现问题,要逐句核对和陛下的话有没有出入,特别是让你缩小范围,只看局部,要求只看上一轮或者特定问题的。如有立即上呈打回
|
|
7
7
|
四、核案。 全审本次授权的 target/range。计划、处置清单、packet、代码、测试都是案面,举证责任由材料决定,不由派单指定。
|
|
8
8
|
每项改动须有票面依据,每项要求须有落实或明确处置;相抵、夹带、缺口一并查(标不出来的即为夹带;有要求而清单没有的即为缺口(夹带的默认值、护栏、平行机制、仅测试用的生产钩子同论)),未授权改治理法文件,未声明的生产默认行为同论。清单不全不得收敛。复审亦全审授权范围,上轮问题不划定本轮案面。
|
|
9
9
|
五、裁断。 主张不是证据。一切 LLM 主张须亲验;当前事实只认当前 head,修复者自述不能替代新 head 上的机械验证与独立复查。出自机器执行,而非任何 LLM 之口的确定性事实,核指针加抽查即可。
|
package/souls/reviewer.md
CHANGED
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
- 风闻奏事,言不为狱:弹章(finding)不是权威、不负坐实义务。弹章须指明所劾之处(文件/条文指针),说错无罪。
|
|
6
6
|
- 独立机关,直属陛下:不接收输入 prompt。案件=固定的被评审目标,目标或事实前提无法成立时如实拒绝;方法=canonical Skill;其余一切自取。
|
|
7
|
-
- 取证工具一切自取,按《审法·取证边界》:只读;探针只落 worktree
|
|
7
|
+
- 取证工具一切自取,按《审法·取证边界》:只读;探针只落 worktree 与临时目录,不得删改其外任何路径。有权抽查≠有责核实:对存疑处可开卷、可下探针,如实记录即可。不跑全量测试套件。
|
|
8
8
|
- 劾前逐项过改动清单。固定目标内每项改动都要标明由票面哪条驱动:标不出来的即为夹带(默认值、护栏、平行机制、仅测试用的生产钩子同论);票面有要求而清单中没有的即为缺口。二者同为 finding。
|
|
9
9
|
- 重点劾三事:违宪(与既裁法源 ADR、铁律相抵)、测试必要性(最小必要成本法)、复杂度(可删不删、同形状第二份)。劾的范围=眼前一切:票面、实现、测试、输入 prompt 与给你的派单命令本身。唯一例外是陛下亲笔——援引此例外必须引陛下原话为证。
|
|
@@ -369,7 +369,7 @@ export type RecordSessionOpen = {
|
|
|
369
369
|
* via destination-free SessionManager.create — no derived postcondition.
|
|
370
370
|
* Resume via the AK-owned current-session ledger is limited to navigator work-subject
|
|
371
371
|
* nests and the authorized worker-submission-gate durable path (ADR 0066 / #852).
|
|
372
|
-
* Other ordinary no-subject children (auditor-roles,
|
|
372
|
+
* Other ordinary no-subject children (auditor-roles, …) always mint fresh.
|
|
373
373
|
* New persisted principals materialize their deferred session header before return so
|
|
374
374
|
* custom-entry-only writers do not need a parallel delayed-header helper.
|
|
375
375
|
*
|
|
@@ -4,7 +4,7 @@ import { dirname, resolve } from "node:path";
|
|
|
4
4
|
|
|
5
5
|
import { stripFrontmatter } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
import type { HostSkillExpansionEvidence } from "./host-contracts.ts";
|
|
7
|
-
export type CanonicalSkillName = "tdd" | "
|
|
7
|
+
export type CanonicalSkillName = "tdd" | "ak-cross-m-review";
|
|
8
8
|
|
|
9
9
|
export type CanonicalSkillSnapshot = Readonly<{
|
|
10
10
|
raw: string;
|
|
@@ -37,7 +37,7 @@ export type CanonicalSkillBinding<Name extends CanonicalSkillName = CanonicalSki
|
|
|
37
37
|
|
|
38
38
|
export type AnyCanonicalSkillBinding =
|
|
39
39
|
| CanonicalSkillBinding<"tdd">
|
|
40
|
-
| CanonicalSkillBinding<"
|
|
40
|
+
| CanonicalSkillBinding<"ak-cross-m-review">;
|
|
41
41
|
|
|
42
42
|
export function captureCanonicalSkillExpansion<Name extends CanonicalSkillName>(
|
|
43
43
|
name: Name,
|
package/src/host-contracts.ts
CHANGED
|
@@ -100,6 +100,8 @@ export type RoleTurnActivation =
|
|
|
100
100
|
| {
|
|
101
101
|
readonly role: "reviewer";
|
|
102
102
|
readonly baseRevision: string;
|
|
103
|
+
/** Caller-selected single lens; no default (ADR 0082 reviewer-method-lens). */
|
|
104
|
+
readonly lens: "completeness" | "correctness";
|
|
103
105
|
readonly authorityRefs: readonly string[];
|
|
104
106
|
readonly ticketNumber?: number;
|
|
105
107
|
}
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
export const REVIEWER_OUTPUT_TOOL_NAME = "ak_reviewer_output";
|
|
4
4
|
export const REVIEWER_ACCEPTED_TEXT = "御史台回执已接受";
|
|
5
5
|
|
|
6
|
-
/** Seat-owned per-
|
|
7
|
-
export type ReviewerAmendments = Readonly<
|
|
6
|
+
/** Seat-owned per-lens finding body text (completeness / correctness). */
|
|
7
|
+
export type ReviewerAmendments = Readonly<
|
|
8
|
+
Partial<Record<"completeness" | "correctness", string>>
|
|
9
|
+
>;
|
|
8
10
|
export type ReviewerIntent =
|
|
9
11
|
| Readonly<{ status: "completed"; amendments?: ReviewerAmendments }>
|
|
10
12
|
| Readonly<{ status: "refused"; diagnostic: string; amendments?: ReviewerAmendments }>;
|
|
@@ -28,7 +28,7 @@ export class PackagedMethodSkillUnavailableError extends Error {
|
|
|
28
28
|
export type PackagedMethodSkillName =
|
|
29
29
|
| "tdd"
|
|
30
30
|
| "diagnosing-bugs"
|
|
31
|
-
| "
|
|
31
|
+
| "ak-cross-m-review"
|
|
32
32
|
| "resolving-merge-conflicts";
|
|
33
33
|
|
|
34
34
|
export type PackagedMethodFileProvenance = Readonly<{
|
|
@@ -84,7 +84,12 @@ const REQUIRED_COMPANIONS: Readonly<
|
|
|
84
84
|
> = {
|
|
85
85
|
tdd: ["tests.md", "mocking.md", "agents/openai.yaml"],
|
|
86
86
|
"diagnosing-bugs": ["agents/openai.yaml", "scripts/hitl-loop.template.sh"],
|
|
87
|
-
"
|
|
87
|
+
"ak-cross-m-review": [
|
|
88
|
+
"CONTEXT.md",
|
|
89
|
+
"LICENSE",
|
|
90
|
+
"prompts/cmr-completeness.md",
|
|
91
|
+
"prompts/cmr-reviewer.md",
|
|
92
|
+
],
|
|
88
93
|
"resolving-merge-conflicts": ["agents/openai.yaml"],
|
|
89
94
|
};
|
|
90
95
|
|
package/src/pi/role-turn-host.ts
CHANGED
|
@@ -164,7 +164,9 @@ function piUserDialogueBody(request: RoleTurnRequest): string {
|
|
|
164
164
|
const _exhaustive: never = request.continuation;
|
|
165
165
|
return _exhaustive;
|
|
166
166
|
})();
|
|
167
|
-
return
|
|
167
|
+
return request.continuation.kind === "resume" && request.activation.role === "reviewer"
|
|
168
|
+
? rawPrompt
|
|
169
|
+
: applyPiNativeSkillInvocation(request.methods, rawPrompt);
|
|
168
170
|
}
|
|
169
171
|
|
|
170
172
|
export type PiSpawnRunner = (
|
|
@@ -234,13 +234,18 @@ export type AdmittedNotaryInvocation = AdmittedRoleInvocationBase & {
|
|
|
234
234
|
readonly sourceRun: NotarySourceRunLocator;
|
|
235
235
|
};
|
|
236
236
|
|
|
237
|
+
/** Public Reviewer single-lens token; no default and no `all` (caller-selected parent run). */
|
|
238
|
+
export type ReviewerLens = "completeness" | "correctness";
|
|
239
|
+
|
|
237
240
|
export type AdmittedReviewerInvocation = AdmittedRoleInvocationBase & {
|
|
238
241
|
readonly role: "reviewer";
|
|
239
242
|
/** Required fixed base revision for the pinned review target (ADR 0037). */
|
|
240
243
|
readonly baseRevision: string;
|
|
244
|
+
/** Required single lens; frozen at admission and reused on resume. */
|
|
245
|
+
readonly lens: ReviewerLens;
|
|
241
246
|
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
247
|
+
* Required durable authority references/URLs frozen at admission.
|
|
248
|
+
* Projected as Skill-internal `--authority` inputs; never free-text reverse-parse.
|
|
244
249
|
*/
|
|
245
250
|
readonly authorityRefs: readonly string[];
|
|
246
251
|
};
|
|
@@ -881,7 +886,9 @@ export type ParseReviewerArgvResult = {
|
|
|
881
886
|
attachmentPaths: string[];
|
|
882
887
|
/** Required fixed base revision for the pinned review target. */
|
|
883
888
|
baseRevision: string;
|
|
884
|
-
/**
|
|
889
|
+
/** Required single lens; no default. */
|
|
890
|
+
lens: ReviewerLens;
|
|
891
|
+
/** Repeatable durable authority references/URLs (exact order preserved; at least one). */
|
|
885
892
|
authorityRefs: string[];
|
|
886
893
|
project?: string;
|
|
887
894
|
};
|
|
@@ -958,6 +965,55 @@ function requireOptionPath(
|
|
|
958
965
|
return value;
|
|
959
966
|
}
|
|
960
967
|
|
|
968
|
+
/**
|
|
969
|
+
* Shared Skill-arg token rule for caller-controlled values projected into the
|
|
970
|
+
* space-joined Skill invocation line. Rejects blank, whitespace (smuggles the
|
|
971
|
+
* next option), and a leading `-` (read as the next Skill option). Not a
|
|
972
|
+
* general free-text gate — only the projection admission seam.
|
|
973
|
+
*/
|
|
974
|
+
function requireSkillArgToken(
|
|
975
|
+
value: string | undefined,
|
|
976
|
+
messages: { empty: string; whitespace: string; optionLike: string },
|
|
977
|
+
): string {
|
|
978
|
+
if (value === undefined || value.trim() === "") {
|
|
979
|
+
throw new CliUsageError(messages.empty);
|
|
980
|
+
}
|
|
981
|
+
if (/\s/.test(value)) {
|
|
982
|
+
throw new CliUsageError(messages.whitespace);
|
|
983
|
+
}
|
|
984
|
+
if (value.startsWith("-")) {
|
|
985
|
+
throw new CliUsageError(messages.optionLike);
|
|
986
|
+
}
|
|
987
|
+
return value;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
/**
|
|
991
|
+
* Reviewer --base admission: nonempty single Skill-arg token (shared rule with
|
|
992
|
+
* requireAuthorityRef). Multi-token / option-like values smuggle extra flags
|
|
993
|
+
* (e.g. `--lens all`, `--authority x`).
|
|
994
|
+
*/
|
|
995
|
+
export function requireReviewerBaseRevision(value: string | undefined): string {
|
|
996
|
+
return requireSkillArgToken(value, {
|
|
997
|
+
empty: "--base requires a nonempty revision",
|
|
998
|
+
whitespace: "--base requires a single-token revision",
|
|
999
|
+
optionLike: "--base requires a single-token revision",
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/** Shared ReviewerLens predicate — sole interpretation owner for fresh + durable. */
|
|
1004
|
+
export function isReviewerLens(value: unknown): value is ReviewerLens {
|
|
1005
|
+
return value === "completeness" || value === "correctness";
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
/** Public --lens enum; sole owner for parse + fresh admission. */
|
|
1009
|
+
export function requireReviewerLens(value: string | undefined): ReviewerLens {
|
|
1010
|
+
const trimmed = (value ?? "").trim();
|
|
1011
|
+
if (!isReviewerLens(trimmed)) {
|
|
1012
|
+
throw new CliUsageError("--lens requires completeness or correctness");
|
|
1013
|
+
}
|
|
1014
|
+
return trimmed;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
961
1017
|
/** True when token is a retained rejected spelling for the owner (#342). */
|
|
962
1018
|
function isRejectedPublicSpelling(owner: OptionOwner, token: string): boolean {
|
|
963
1019
|
for (const entry of REJECTED_PUBLIC_SPELLINGS) {
|
|
@@ -977,20 +1033,16 @@ function roleOptions(owner: Exclude<OptionOwner, "global">): readonly PublicOpti
|
|
|
977
1033
|
/**
|
|
978
1034
|
* Public --authority-ref admission grammar (refs-only).
|
|
979
1035
|
* Unique owner for fresh argv and durable resume restore — no string-only parallel.
|
|
980
|
-
* Accepts durable reference tokens as-is; rejects blank
|
|
981
|
-
* (whitespace-bearing sentences)
|
|
1036
|
+
* Accepts durable reference tokens as-is; rejects blank, inline Spec prose
|
|
1037
|
+
* (whitespace-bearing sentences), and option-like leading `-` (Skill-arg boundary).
|
|
1038
|
+
* Does not fetch, normalize, or judge content.
|
|
982
1039
|
*/
|
|
983
1040
|
export function requireAuthorityRef(value: string | undefined): string {
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
throw new CliUsageError(
|
|
990
|
-
"--authority-ref requires a durable reference, not inline Spec prose",
|
|
991
|
-
);
|
|
992
|
-
}
|
|
993
|
-
return value;
|
|
1041
|
+
return requireSkillArgToken(value, {
|
|
1042
|
+
empty: "--authority-ref requires a nonempty durable reference",
|
|
1043
|
+
whitespace: "--authority-ref requires a durable reference, not inline Spec prose",
|
|
1044
|
+
optionLike: "--authority-ref requires a durable reference, not inline Spec prose",
|
|
1045
|
+
});
|
|
994
1046
|
}
|
|
995
1047
|
|
|
996
1048
|
/**
|
|
@@ -2656,12 +2708,6 @@ export function buildNotaryTransportPrompt(
|
|
|
2656
2708
|
return appendEngineSessionMaterial([NOTARY_FIXED_KICKOFF], engineMaterial).join("\n");
|
|
2657
2709
|
}
|
|
2658
2710
|
|
|
2659
|
-
/**
|
|
2660
|
-
* Parse Reviewer-specific argv after the `reviewer` token.
|
|
2661
|
-
* Public flags: --project, required --base, optional repeatable --authority-ref.
|
|
2662
|
-
* Reviewer gathers its own evidence; users submit neither attachments nor capability packets.
|
|
2663
|
-
* Caller instruction remains scope/procedure provenance — not Spec authority.
|
|
2664
|
-
*/
|
|
2665
2711
|
/**
|
|
2666
2712
|
* Parse Gleaner-Left argv after the `gleaner-left` token.
|
|
2667
2713
|
* Public flags: --project, required --base. No --attach / ticket face (unanchored self-fetch).
|
|
@@ -2822,6 +2868,7 @@ export function parseReviewerArgv(
|
|
|
2822
2868
|
const authorityRefs: string[] = [];
|
|
2823
2869
|
let project: string | undefined;
|
|
2824
2870
|
let baseRevision: string | undefined;
|
|
2871
|
+
let lens: ReviewerLens | undefined;
|
|
2825
2872
|
const positional: string[] = [];
|
|
2826
2873
|
const tokens = [...args];
|
|
2827
2874
|
const definitions = roleOptions("reviewer");
|
|
@@ -2840,7 +2887,12 @@ export function parseReviewerArgv(
|
|
|
2840
2887
|
continue;
|
|
2841
2888
|
}
|
|
2842
2889
|
if (taken.def.id === "base") {
|
|
2843
|
-
baseRevision =
|
|
2890
|
+
baseRevision = requireReviewerBaseRevision(taken.value);
|
|
2891
|
+
continue;
|
|
2892
|
+
}
|
|
2893
|
+
if (taken.def.id === "lens") {
|
|
2894
|
+
// Empty and other non-enum values share one message — do not borrow path helper.
|
|
2895
|
+
lens = requireReviewerLens(taken.value);
|
|
2844
2896
|
continue;
|
|
2845
2897
|
}
|
|
2846
2898
|
if (taken.def.id === "authority-ref") {
|
|
@@ -2856,12 +2908,13 @@ export function parseReviewerArgv(
|
|
|
2856
2908
|
positional.push(token);
|
|
2857
2909
|
}
|
|
2858
2910
|
|
|
2859
|
-
// Unconditional required (
|
|
2911
|
+
// Unconditional required (--base/--lens/--authority-ref) from typed table (#342).
|
|
2860
2912
|
options.assertRequired();
|
|
2861
2913
|
return {
|
|
2862
2914
|
instruction: positional.join(" "),
|
|
2863
2915
|
attachmentPaths,
|
|
2864
2916
|
baseRevision: baseRevision!,
|
|
2917
|
+
lens: lens!,
|
|
2865
2918
|
authorityRefs,
|
|
2866
2919
|
...(project === undefined ? {} : { project }),
|
|
2867
2920
|
};
|
|
@@ -2875,8 +2928,10 @@ export type AdmitReviewerInvocationOptions = {
|
|
|
2875
2928
|
instruction: string;
|
|
2876
2929
|
attachmentPaths: readonly string[];
|
|
2877
2930
|
baseRevision: string;
|
|
2878
|
-
/**
|
|
2879
|
-
|
|
2931
|
+
/** Required single lens; frozen unchanged at admission. */
|
|
2932
|
+
lens: ReviewerLens;
|
|
2933
|
+
/** Required durable authority references/URLs; frozen unchanged at admission. */
|
|
2934
|
+
authorityRefs: readonly string[];
|
|
2880
2935
|
project?: string;
|
|
2881
2936
|
createRunId?: () => string;
|
|
2882
2937
|
/** Effective model for this invocation — written onto invocation.json. */
|
|
@@ -2884,9 +2939,9 @@ export type AdmitReviewerInvocationOptions = {
|
|
|
2884
2939
|
};
|
|
2885
2940
|
|
|
2886
2941
|
/**
|
|
2887
|
-
* Admit a Reviewer Role run on the fixed base
|
|
2888
|
-
* Caller instruction is optional provenance;
|
|
2889
|
-
*
|
|
2942
|
+
* Admit a Reviewer Role run on the fixed base + lens + authority set.
|
|
2943
|
+
* Caller instruction is optional provenance; typed fields project Skill inputs.
|
|
2944
|
+
* authorityRefs are frozen as durable references only — not Spec prose.
|
|
2890
2945
|
*/
|
|
2891
2946
|
export async function admitReviewerInvocation(
|
|
2892
2947
|
options: AdmitReviewerInvocationOptions,
|
|
@@ -2894,11 +2949,13 @@ export async function admitReviewerInvocation(
|
|
|
2894
2949
|
if (options.project !== undefined) {
|
|
2895
2950
|
requireOptionPath("--project", options.project);
|
|
2896
2951
|
}
|
|
2897
|
-
|
|
2898
|
-
|
|
2952
|
+
const baseRevision = requireReviewerBaseRevision(options.baseRevision);
|
|
2953
|
+
const lens = requireReviewerLens(options.lens);
|
|
2954
|
+
if (options.authorityRefs.length === 0) {
|
|
2955
|
+
throw new CliUsageError("reviewer requires --authority-ref <ref>");
|
|
2899
2956
|
}
|
|
2900
2957
|
const authorityRefs = Object.freeze(
|
|
2901
|
-
|
|
2958
|
+
options.authorityRefs.map((ref) => requireAuthorityRef(ref)),
|
|
2902
2959
|
);
|
|
2903
2960
|
|
|
2904
2961
|
const projectRoot = resolve(options.project ?? options.cwd);
|
|
@@ -2933,7 +2990,8 @@ export async function admitReviewerInvocation(
|
|
|
2933
2990
|
principal,
|
|
2934
2991
|
instruction,
|
|
2935
2992
|
instructionEmpty,
|
|
2936
|
-
baseRevision
|
|
2993
|
+
baseRevision,
|
|
2994
|
+
lens,
|
|
2937
2995
|
authorityRefs: [...authorityRefs],
|
|
2938
2996
|
attachments: attachments.map((a) => ({
|
|
2939
2997
|
provenancePath: a.provenancePath,
|
|
@@ -2961,29 +3019,40 @@ export async function admitReviewerInvocation(
|
|
|
2961
3019
|
runDirectory,
|
|
2962
3020
|
principal,
|
|
2963
3021
|
admittedRequestPath,
|
|
2964
|
-
baseRevision
|
|
3022
|
+
baseRevision,
|
|
3023
|
+
lens,
|
|
2965
3024
|
authorityRefs,
|
|
2966
3025
|
};
|
|
2967
3026
|
}
|
|
2968
3027
|
|
|
3028
|
+
/** Frozen Skill arg projection shared by initial and resume (never reverse-parsed). */
|
|
3029
|
+
export function buildReviewerSkillArgProjection(
|
|
3030
|
+
admitted: Pick<AdmittedReviewerInvocation, "baseRevision" | "lens" | "authorityRefs">,
|
|
3031
|
+
): string {
|
|
3032
|
+
return [
|
|
3033
|
+
`--base ${admitted.baseRevision}`,
|
|
3034
|
+
`--lens ${admitted.lens}`,
|
|
3035
|
+
...admitted.authorityRefs.map((ref) => `--authority ${ref}`),
|
|
3036
|
+
].join(" ");
|
|
3037
|
+
}
|
|
3038
|
+
|
|
2969
3039
|
/**
|
|
2970
|
-
* Build the
|
|
2971
|
-
*
|
|
2972
|
-
*
|
|
3040
|
+
* Build the host-neutral prompt transport for an admitted Reviewer request.
|
|
3041
|
+
* Typed base/lens/authority project to Skill invocation args (never reverse-parsed from prose).
|
|
3042
|
+
* Optional caller words + engine material follow.
|
|
2973
3043
|
*/
|
|
2974
3044
|
export function buildReviewerTransportPrompt(
|
|
2975
3045
|
admitted: AdmittedReviewerInvocation,
|
|
2976
3046
|
engineMaterial?: EngineSessionMaterial,
|
|
2977
3047
|
): string {
|
|
2978
|
-
const lines = [
|
|
2979
|
-
`本次审查的固定基点:${admitted.baseRevision}`,
|
|
2980
|
-
];
|
|
3048
|
+
const lines = [buildReviewerSkillArgProjection(admitted)];
|
|
2981
3049
|
if (!admitted.instructionEmpty && admitted.instruction.trim() !== "") {
|
|
2982
3050
|
lines.push("", admitted.instruction);
|
|
2983
3051
|
}
|
|
2984
3052
|
return appendEngineSessionMaterial(lines, engineMaterial).join("\n");
|
|
2985
3053
|
}
|
|
2986
3054
|
|
|
3055
|
+
|
|
2987
3056
|
/**
|
|
2988
3057
|
* Parse Merger-specific argv after the `merger` token.
|
|
2989
3058
|
* Spellings from PUBLIC_OPTION_TABLE.merger; internal packet fields rejected (#342).
|