@open-agent-toolkit/cli 0.3.7 → 0.3.8
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/configuration.md +15 -1
- package/assets/docs/cli-utilities/workflow-gates.md +37 -0
- package/assets/docs/provider-sync/commands.md +6 -0
- package/assets/docs/provider-sync/providers.md +20 -0
- package/assets/docs/provider-sync/scope-and-surface.md +2 -0
- package/assets/docs/reference/cli-reference.md +2 -1
- package/assets/docs/workflows/projects/evidence-layers.md +5 -1
- package/assets/docs/workflows/projects/retro.md +7 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-agent-instructions-analyze/SKILL.md +1 -1
- package/assets/skills/oat-agent-instructions-analyze/scripts/resolve-providers.sh +17 -6
- package/assets/skills/oat-dispatch-subagents/SKILL.md +1 -1
- package/assets/skills/oat-dispatch-subagents/references/managed-claude-example.json +387 -0
- package/assets/skills/oat-dispatch-subagents/references/record-schema.md +75 -0
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +24 -22
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-retro/SKILL.md +70 -6
- package/assets/skills/oat-project-review-provide/SKILL.md +3 -1
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +3 -1
- package/dist/agents/canonical/resolve.d.ts +6 -4
- package/dist/agents/canonical/resolve.d.ts.map +1 -1
- package/dist/agents/canonical/resolve.js +6 -4
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +51 -2
- package/dist/commands/gate/review-verdict.d.ts +22 -0
- package/dist/commands/gate/review-verdict.d.ts.map +1 -1
- package/dist/commands/gate/review-verdict.js +111 -0
- package/dist/commands/project/dispatch/canonical-role.d.ts +33 -0
- package/dist/commands/project/dispatch/canonical-role.d.ts.map +1 -0
- package/dist/commands/project/dispatch/canonical-role.js +114 -0
- package/dist/commands/project/dispatch/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch/index.js +3 -1
- package/dist/commands/project/dispatch/record.d.ts.map +1 -1
- package/dist/commands/project/dispatch/record.js +146 -4
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +28 -21
- package/dist/commands/tools/shared/sync-evidence.d.ts.map +1 -1
- package/dist/commands/tools/shared/sync-evidence.js +32 -5
- package/dist/config/oat-config.d.ts +8 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +116 -1
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +31 -3
- package/dist/providers/claude/dispatch-envelope.d.ts +53 -0
- package/dist/providers/claude/dispatch-envelope.d.ts.map +1 -1
- package/dist/providers/claude/dispatch-envelope.js +324 -48
- package/dist/providers/claude/rule-transform.js +1 -1
- package/dist/providers/copilot/rule-transform.js +1 -1
- package/dist/providers/cursor/rule-transform.js +1 -1
- package/dist/providers/identity/absolute-paths.d.ts +13 -0
- package/dist/providers/identity/absolute-paths.d.ts.map +1 -1
- package/dist/providers/identity/absolute-paths.js +27 -14
- package/dist/providers/identity/generic-dispatch-record.d.ts +212 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts.map +1 -1
- package/dist/providers/identity/generic-dispatch-record.js +78 -19
- package/dist/providers/identity/oat-dispatch-record.d.ts +5 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -1
- package/dist/providers/identity/oat-dispatch-record.js +11 -2
- package/dist/providers/shared/registry.d.ts +6 -0
- package/dist/providers/shared/registry.d.ts.map +1 -1
- package/dist/providers/shared/registry.js +30 -0
- package/dist/rules/canonical/parse.d.ts.map +1 -1
- package/dist/rules/canonical/parse.js +38 -3
- package/package.json +2 -2
|
@@ -274,7 +274,7 @@ remains immutable baseline evidence for the original p01-t01 verification.
|
|
|
274
274
|
| `oat-dispatch-subagents/references/provider-claude.md` | `fbe3a21e9533 -> NG` |
|
|
275
275
|
| `oat-dispatch-subagents/references/provider-codex.md` | `95b0f82018c7 -> NG` |
|
|
276
276
|
| `oat-dispatch-subagents/references/provider-cursor.md` | `f781555295a9 -> NG`; `55ccfef14fd6 -> NG` |
|
|
277
|
-
| `oat-dispatch-subagents/references/record-schema.md` | `78f8069274a8 -> NG`; `1c9a84c4d1e0 -> NG`; `2a63da6e3a96 -> NG`; `30762d53b043 -> NG`
|
|
277
|
+
| `oat-dispatch-subagents/references/record-schema.md` | `78f8069274a8 -> NG`; `1c9a84c4d1e0 -> NG`; `2a63da6e3a96 -> NG`; `30762d53b043 -> NG`; `66bc2f0d4fda -> NG` |
|
|
278
278
|
| `oat-project-dispatch-subagents/SKILL.md` | `eca03ad1ca12 -> PDISPATCH-01`; `59fbcdc79cea -> PDISPATCH-01` |
|
|
279
279
|
| `oat-project-plan/SKILL.md` | `f99e44b39932 -> PLAN-12`; `7e6a9854504b -> NG` |
|
|
280
280
|
| `oat-project-complete/SKILL.md` | `0177956707aa -> NG`; `8305b5bb65ef -> NG`; `3c0b26f0ff1c -> NG`; `8cc1fa5aab1e -> COMPLETE-01`; `4c209fbb4716 -> COMPLETE-01`; `02e4175e1171 -> COMPLETE-01`; `d698d4f98e76 -> COMPLETE-01`; `9f86a7218d93 -> COMPLETE-01`; `024713698d9a -> COMPLETE-01`; `c327995053fa -> COMPLETE-01`; `61f81d4ec7c1 -> COMPLETE-01`; `14fb2e56809f -> COMPLETE-01`; `7d4ff668744d -> COMPLETE-01`; `502a6c141784 -> COMPLETE-01`; `fb7e2db356af -> COMPLETE-01`; `f73f8476360a -> NG`; `1e15f420039f -> NG`; `cc234032ddd7 -> NG`; `1dd54687229b -> NG`; `fc05c8303cd2 -> NG`; `24be721d635e -> NG` |
|
|
@@ -5,7 +5,7 @@ disable-model-invocation: false
|
|
|
5
5
|
user-invocable: true
|
|
6
6
|
allowed-tools: Read, Write, Bash(git:*), Bash(jq:*), Bash(pnpm:*), Bash(oat config:*), Bash(oat decision:*), Bash(oat project log:*), Bash(oat project push:*), Bash(oat project scope:*), Bash(oat tools:*), Glob, Grep, AskUserQuestion
|
|
7
7
|
metadata:
|
|
8
|
-
version: 1.0.
|
|
8
|
+
version: 1.0.7
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Project Retrospective
|
|
@@ -53,8 +53,9 @@ OAT ▸ PROJECT RETRO
|
|
|
53
53
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
Use `[1/
|
|
57
|
-
|
|
56
|
+
Use `[1/7] Resolving project and mode…` through `[7/7] Walking through
|
|
57
|
+
register items…`, with `[6/7] Formatting and committing…` before the final
|
|
58
|
+
walkthrough. Name evidence inventory, synthesis, disposition, and project-log
|
|
58
59
|
steps as they begin.
|
|
59
60
|
|
|
60
61
|
## Artifact Hygiene
|
|
@@ -165,7 +166,9 @@ provenance.
|
|
|
165
166
|
|
|
166
167
|
### Step 4: Resolve Post-Generation Consent
|
|
167
168
|
|
|
168
|
-
Read effective `workflow.retro.apply
|
|
169
|
+
Read effective `workflow.retro.apply`, `workflow.retro.filing.repo`, and
|
|
170
|
+
`workflow.retro.filing.upstream` configuration. Read each filing leaf key on its
|
|
171
|
+
own; the filing namespace has no single readable value.
|
|
169
172
|
|
|
170
173
|
**Interactive run:**
|
|
171
174
|
|
|
@@ -173,16 +176,19 @@ Read effective `workflow.retro.apply` and `workflow.retro.filing` configuration.
|
|
|
173
176
|
2. Ask whether to apply eligible RP apply-items now.
|
|
174
177
|
3. If unfiled UP or RP file-items exist, offer the `oat-project-retro-file`
|
|
175
178
|
skill.
|
|
179
|
+
4. Close the run with the Step 7 walkthrough, whatever the user answered.
|
|
176
180
|
|
|
177
181
|
**Non-interactive run:**
|
|
178
182
|
|
|
179
183
|
- Apply only when `workflow.retro.apply` is `auto`.
|
|
180
184
|
- `ask` or absent means propose-only.
|
|
181
|
-
- Chain to `oat-project-retro-file` only when
|
|
182
|
-
`workflow.retro.filing`
|
|
185
|
+
- Chain to `oat-project-retro-file` only when `workflow.retro.filing.repo` or
|
|
186
|
+
`workflow.retro.filing.upstream` is explicitly configured; chaining means
|
|
183
187
|
loading the current `oat-project-retro-file/SKILL.md` and following it, or
|
|
184
188
|
dispatching a child that carries it.
|
|
185
189
|
- Without filing config, file nothing and report that proposals remain.
|
|
190
|
+
- Close the run with the Step 7 walkthrough even though no one answered a
|
|
191
|
+
prompt.
|
|
186
192
|
|
|
187
193
|
All applications follow the apply procedure. Filing remains owned by
|
|
188
194
|
`oat-project-retro-file`; generate/apply mode does not file tracker items.
|
|
@@ -298,6 +304,61 @@ Commit the artifact, project-log append, and any approved apply outputs. Use
|
|
|
298
304
|
one reviewed batch when items are tightly coupled; otherwise use one commit per
|
|
299
305
|
item as described in the apply procedure. Never stage unrelated changes.
|
|
300
306
|
|
|
307
|
+
### Step 7: Final Report Walkthrough
|
|
308
|
+
|
|
309
|
+
After the artifact passes Step 6 validation, end the final response with a
|
|
310
|
+
walkthrough of every `RP-*` and `UP-*` item so the user can decide what to apply
|
|
311
|
+
or file without opening the retro. Link the artifact by its repo-relative path
|
|
312
|
+
instead of reproducing it; the walkthrough explains items, it does not copy
|
|
313
|
+
their bodies.
|
|
314
|
+
|
|
315
|
+
For each item, state:
|
|
316
|
+
|
|
317
|
+
- its ID and a short title;
|
|
318
|
+
- a plain-language summary of what it proposes;
|
|
319
|
+
- why it matters for future runs;
|
|
320
|
+
- its current disposition and destination, read from the register fields after
|
|
321
|
+
every action in this run; and
|
|
322
|
+
- the next available action, or that none remains.
|
|
323
|
+
|
|
324
|
+
Group items in this order: apply items (RP `Disposition: apply`), repository
|
|
325
|
+
filing items (RP `Disposition: file`), and upstream filing items (UP). Give an
|
|
326
|
+
empty group a one-line "none" note rather than dropping it.
|
|
327
|
+
|
|
328
|
+
The walkthrough is required in interactive and non-interactive runs alike, and
|
|
329
|
+
whether apply or filing was performed, declined, deferred, skipped, automatic,
|
|
330
|
+
or unanswered. When both registers are empty, give an explicit no-items summary
|
|
331
|
+
such as "No repo improvements or upstream feedback items were proposed."
|
|
332
|
+
|
|
333
|
+
Worked example:
|
|
334
|
+
|
|
335
|
+
```markdown
|
|
336
|
+
Retro: `.oat/projects/shared/example/references/project-retro.md`
|
|
337
|
+
|
|
338
|
+
**Apply items**
|
|
339
|
+
|
|
340
|
+
- **RP-01 — Isolate HOME in template tests.** Summary: run template-resolving
|
|
341
|
+
tests with a temporary HOME. Why it matters: they read the maintainer's user
|
|
342
|
+
templates and fail locally while passing in CI. Disposition: apply; Status:
|
|
343
|
+
applied; Applied-ref: `abc1234`. Next action: none.
|
|
344
|
+
|
|
345
|
+
**Repository filing items**
|
|
346
|
+
|
|
347
|
+
- **RP-02 — Document the cache-replay trap.** Summary: warn that a green turbo
|
|
348
|
+
run can be a cache replay. Why it matters: two sessions reported replays as
|
|
349
|
+
real passes. Disposition: file; Status: proposed; Destination: — because
|
|
350
|
+
filing was deferred, and `workflow.retro.filing.repo` routes it to the
|
|
351
|
+
backlog. Next action: run retro filing to create the backlog item.
|
|
352
|
+
|
|
353
|
+
**Upstream filing items**
|
|
354
|
+
|
|
355
|
+
- **UP-01 — Name the file in rule parse errors.** Summary: include the rule path
|
|
356
|
+
in canonical parse failures. Why it matters: the error named no file, so
|
|
357
|
+
diagnosis needed a full scan. Status: proposed; Destination: — because
|
|
358
|
+
`workflow.retro.filing.upstream` is unset. Next action: set that key or file
|
|
359
|
+
it interactively.
|
|
360
|
+
```
|
|
361
|
+
|
|
301
362
|
## Success Criteria
|
|
302
363
|
|
|
303
364
|
- The resolved mode matches explicit user/config intent.
|
|
@@ -311,3 +372,6 @@ item as described in the apply procedure. Never stage unrelated changes.
|
|
|
311
372
|
- No promotion is applied or item filed without interactive approval or
|
|
312
373
|
explicit non-interactive configuration.
|
|
313
374
|
- The project log and commit preserve the outcome without unrelated changes.
|
|
375
|
+
- The final response walks through every `RP-*` and `UP-*` item, grouped into
|
|
376
|
+
apply, repository filing, and upstream filing items, or gives an explicit
|
|
377
|
+
no-items summary, and links the artifact instead of reproducing it.
|
|
@@ -5,7 +5,7 @@ disable-model-invocation: false
|
|
|
5
5
|
user-invocable: true
|
|
6
6
|
allowed-tools: Read, Glob, Grep, Write, Edit, Bash(git:*), Bash(oat:*), Bash(pnpm:*), Bash(mkdir:*), Bash(date:*), Bash(realpath:*), Bash(awk:*), AskUserQuestion
|
|
7
7
|
metadata:
|
|
8
|
-
version: 1.5.
|
|
8
|
+
version: 1.5.11
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Request Review
|
|
@@ -1034,6 +1034,8 @@ When `oat gate review` invokes this skill, it includes gate-originated context i
|
|
|
1034
1034
|
|
|
1035
1035
|
The gate prompt also supplies exact values for `oat_gate_run_id`, `oat_gate_target`, `oat_gate_runtime`, `oat_invocation_model`, `oat_invocation_reasoning_effort`, and `oat_invocation_source`. Copy all six values verbatim for gate-originated artifacts. These fields record OAT's configured invocation; do not derive them from `baseCommand`, the target id, model self-identification, or surrounding dispatch prose. Optional observed/self-reported identity is separate and non-authoritative.
|
|
1036
1036
|
|
|
1037
|
+
For gate-originated artifacts (`oat_review_invocation: gate`), write the Step 6.0 resolver stamp on a line labeled `**Dispatch audit (policy view):**`, with the stamp in one backtick pair so the literal `Dispatch:` token stays readable, for example ``**Dispatch audit (policy view):** `Dispatch: scope=p01 action=review role=reviewer …` ``. The resolver stamp records the project reviewer policy, and the six gate frontmatter fields record the gate's actual invocation; the label keeps both accurate. `oat gate review` checks every other reviewer audit stamp anywhere outside `## Findings`, the severity sections, and fenced code (for example in the metadata block, `## Dispatch Audit`, or `## Review Scope`), including a backtick-wrapped stamp followed only by punctuation or one parenthetical, against the frontmatter: its `target` must equal `oat_gate_target`, and its `effort_axis` must equal `selected:<oat_invocation_reasoning_effort>` when that effort is concrete. A disagreeing stamp fails the gate with `gate_dispatch_audit_mismatched`. Manual and auto reviews keep their audit line unlabeled.
|
|
1038
|
+
|
|
1037
1039
|
For all other invocations (user-triggered, fresh session), use `manual`.
|
|
1038
1040
|
|
|
1039
1041
|
Gate parsing contract:
|
|
@@ -5,7 +5,7 @@ disable-model-invocation: true
|
|
|
5
5
|
user-invocable: true
|
|
6
6
|
allowed-tools: Read, Write, Bash, Glob, Grep, Task, AskUserQuestion
|
|
7
7
|
metadata:
|
|
8
|
-
version: 1.1.
|
|
8
|
+
version: 1.1.8
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Remote Review Provide (Project-Scoped GitHub PR)
|
|
@@ -408,6 +408,8 @@ oat_gate_target: <exact configured gate target; omit for lifecycle>
|
|
|
408
408
|
|
|
409
409
|
`oat_project` carries the resolved project path so machine A's `oat-project-review-receive-remote` routes findings into the right project's plan tasks. Preserve the current invocation lineage in the GitHub marker: omit `oat_gate_target` for lifecycle reviews and include the exact target for gate reviews. Verdict: `REQUEST_CHANGES` when any critical or high finding exists; `COMMENT` otherwise (including a clean, zero-findings review — never auto-`APPROVE`).
|
|
410
410
|
|
|
411
|
+
For gate reviews (`oat_review_invocation: gate`), write the resolver stamp in the posted review's dispatch audit metadata on a line labeled `**Dispatch audit (policy view):**`, with the stamp in one backtick pair so the literal `Dispatch:` token stays readable. The resolver stamp records the project reviewer policy, while `oat_gate_target` names the gate's actual invocation; the label keeps both accurate. Any other reviewer audit stamp outside `## Findings`, the severity sections, and fenced code must name `oat_gate_target` as its `target` and carry `effort_axis=selected:<effort>` for a concrete gate effort, because `oat gate review` rejects a disagreeing unlabeled stamp with `gate_dispatch_audit_mismatched`. Lifecycle reviews keep their audit line unlabeled.
|
|
412
|
+
|
|
411
413
|
### Step 8: Post the Review + Clean Up
|
|
412
414
|
|
|
413
415
|
Probe `agent-reviews` for a posting flow with a non-mutating check (`npx agent-reviews --help`), cached for the run:
|
|
@@ -36,10 +36,12 @@ export interface ResolveCanonicalRoleInput {
|
|
|
36
36
|
projectCanonicalRoot: string;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* `
|
|
42
|
-
*
|
|
39
|
+
* Resolve canonical role identity before a native launch. Its production
|
|
40
|
+
* caller is `oat project dispatch canonical-role`
|
|
41
|
+
* (`commands/project/dispatch/canonical-role.ts`), which prints the evidence
|
|
42
|
+
* as a `canonical-role-resolution` event for `oat project dispatch record` to
|
|
43
|
+
* validate, so skill-side callers never hand-assemble redacted paths or a
|
|
44
|
+
* content digest.
|
|
43
45
|
*/
|
|
44
46
|
export declare function resolveCanonicalRole(input: ResolveCanonicalRoleInput): CanonicalRoleEvidence;
|
|
45
47
|
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/agents/canonical/resolve.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAC9D,MAAM,MAAM,uBAAuB,GAC/B,kBAAkB,GAClB,yBAAyB,CAAC;AAC9B,MAAM,MAAM,6BAA6B,GACrC,SAAS,GACT,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,cAAc,GACd,cAAc,CAAC;AAEnB,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,6BAA6B,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,UAAU,EAAE,uBAAuB,CAAC;IACpC,aAAa,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CACrC,CAAC;AAEN,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAgLD
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/agents/canonical/resolve.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAC9D,MAAM,MAAM,uBAAuB,GAC/B,kBAAkB,GAClB,yBAAyB,CAAC;AAC9B,MAAM,MAAM,6BAA6B,GACrC,SAAS,GACT,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,cAAc,GACd,cAAc,CAAC;AAEnB,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,6BAA6B,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,UAAU,EAAE,uBAAuB,CAAC;IACpC,aAAa,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CACrC,CAAC;AAEN,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAgLD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,yBAAyB,GAC/B,qBAAqB,CA0DvB"}
|
|
@@ -138,10 +138,12 @@ function resolveRoleIdentity(resolved, candidate, input, candidateMisses) {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* `
|
|
144
|
-
*
|
|
141
|
+
* Resolve canonical role identity before a native launch. Its production
|
|
142
|
+
* caller is `oat project dispatch canonical-role`
|
|
143
|
+
* (`commands/project/dispatch/canonical-role.ts`), which prints the evidence
|
|
144
|
+
* as a `canonical-role-resolution` event for `oat project dispatch record` to
|
|
145
|
+
* validate, so skill-side callers never hand-assemble redacted paths or a
|
|
146
|
+
* content digest.
|
|
145
147
|
*/
|
|
146
148
|
export function resolveCanonicalRole(input) {
|
|
147
149
|
const loadedRoot = resolve(input.skillDir, '..', '..');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,gBAAgB,EAKhB,KAAK,qBAAqB,EAE3B,MAAM,8BAA8B,CAAC;AAYtC,OAAO,EAWL,KAAK,UAAU,EAIf,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAExB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ import { normalizeToPosixPath, resolveProjectRoot, validateRealPathWithinScope,
|
|
|
16
16
|
import { buildDispatchReport, } from '../../providers/identity/dispatch-report.js';
|
|
17
17
|
import { classifyModelFamily, } from '../../providers/identity/family.js';
|
|
18
18
|
import { resolveIdentityConfidence, } from '../../providers/identity/provenance.js';
|
|
19
|
-
import { parseDispatchStamps } from '../../providers/identity/stamp.js';
|
|
19
|
+
import { parseDispatchStamps, } from '../../providers/identity/stamp.js';
|
|
20
20
|
import { Command } from 'commander';
|
|
21
21
|
import YAML from 'yaml';
|
|
22
22
|
import { createGateActivityProbe, } from './activity-probes.js';
|
|
@@ -84,7 +84,7 @@ const VALID_IDENTITY_PROVENANCES = [
|
|
|
84
84
|
'unknown',
|
|
85
85
|
];
|
|
86
86
|
const REVIEW_GATE_CONTEXT_NOTE = [
|
|
87
|
-
|
|
87
|
+
"This review is gate-originated. If you run `oat-project-review-provide`, set `oat_review_invocation: gate` in the review artifact. Write a canonical review artifact with `### Critical`, `### High`, `### Medium`, and `### Low` headings in that order, using `None` for empty sections. Gate-originated reviews write the resolver dispatch stamp on a line labeled `**Dispatch audit (policy view):**`, with the stamp in one backtick pair, because an unlabeled audit stamp must name this gate's target and effort.",
|
|
88
88
|
'Complete the review, artifact write, and required bookkeeping inline or through a synchronously awaited child before this headless process exits. Do not start background tasks, monitors, or waiters that outlive this turn.',
|
|
89
89
|
"Artifact hygiene contract: Before finishing or committing, format every file you created or edited. Use the concrete write/fix formatting command supplied by the governing plan, task, or brief. If none is usable, discover the repository's documented write/fix command from applicable `AGENTS.md`/`CLAUDE.md` instructions and relevant package manifests; do not infer or hardcode a formatter. Prefer a file-scoped invocation when supported, and avoid rewriting unrelated files. If no command is discoverable, warn once with `no format command discovered in repo instructions; skipping`, then continue.",
|
|
90
90
|
].join('\n\n');
|
|
@@ -281,6 +281,29 @@ function gateInvocationPromptContext(invocation) {
|
|
|
281
281
|
frontmatter,
|
|
282
282
|
].join('\n');
|
|
283
283
|
}
|
|
284
|
+
const NON_CONCRETE_REASONING_EFFORTS = new Set([
|
|
285
|
+
'unknown',
|
|
286
|
+
'provider-default',
|
|
287
|
+
'not-applicable',
|
|
288
|
+
]);
|
|
289
|
+
/**
|
|
290
|
+
* Unlabeled reviewer audit stamps that disagree with the gate frontmatter.
|
|
291
|
+
*
|
|
292
|
+
* The frontmatter (`oat_gate_target`, `oat_invocation_*`) is the authority for
|
|
293
|
+
* the gate's actual invocation. A stamp labeled as the reviewer policy view is
|
|
294
|
+
* exempt; any other audit stamp must name the gate target and, when the gate
|
|
295
|
+
* recorded a concrete reasoning effort, carry `effort_axis=selected:<effort>`.
|
|
296
|
+
*/
|
|
297
|
+
function disagreeingDispatchAuditStamps(verdict) {
|
|
298
|
+
const unlabeled = verdict.dispatchAudit?.unlabeled ?? [];
|
|
299
|
+
const target = verdict.gateInvocation?.targetId ?? null;
|
|
300
|
+
const effort = verdict.gateInvocation?.reasoningEffort ?? null;
|
|
301
|
+
const expectedEffortAxis = effort && !NON_CONCRETE_REASONING_EFFORTS.has(effort)
|
|
302
|
+
? `selected:${effort}`
|
|
303
|
+
: null;
|
|
304
|
+
return unlabeled.filter((stamp) => stamp.target !== target ||
|
|
305
|
+
(expectedEffortAxis !== null && stamp.effortAxis !== expectedEffortAxis));
|
|
306
|
+
}
|
|
284
307
|
function corroborateGateInvocation(expected, actual, targetCorroboration) {
|
|
285
308
|
const invocationFields = [
|
|
286
309
|
['targetId', expected.targetId, actual?.targetId],
|
|
@@ -2422,6 +2445,32 @@ async function disposeValidatedReviewArtifact(snapshot, identity, dependencies,
|
|
|
2422
2445
|
},
|
|
2423
2446
|
};
|
|
2424
2447
|
}
|
|
2448
|
+
const disagreeingAudit = disagreeingDispatchAuditStamps(verdict);
|
|
2449
|
+
if (disagreeingAudit.length > 0) {
|
|
2450
|
+
const lines = disagreeingAudit.map((stamp) => stamp.lineNumber).join(', ');
|
|
2451
|
+
const effort = verdict.gateInvocation?.reasoningEffort ?? 'unknown';
|
|
2452
|
+
return {
|
|
2453
|
+
eligible: false,
|
|
2454
|
+
status: 'artifact_validation_failed',
|
|
2455
|
+
cause: 'gate_dispatch_audit_mismatched',
|
|
2456
|
+
verdict,
|
|
2457
|
+
writeEnvelope: (context) => {
|
|
2458
|
+
writeReviewGateArtifactValidationFailure(context, {
|
|
2459
|
+
runId: identity.runId,
|
|
2460
|
+
target: identity.target,
|
|
2461
|
+
project: identity.project,
|
|
2462
|
+
projectResolutionSource: identity.projectResolutionSource,
|
|
2463
|
+
artifactPath: snapshot.path,
|
|
2464
|
+
generatedAt: snapshot.generatedAt,
|
|
2465
|
+
message: `Review artifact dispatch audit line (line ${lines}) does not agree with the gate invocation frontmatter (oat_gate_target: ${verdict.gateInvocation?.targetId ?? 'unknown'}, oat_invocation_reasoning_effort: ${effort}). An unlabeled audit stamp must describe the gate invocation; label the reviewer policy stamp \`**Dispatch audit (policy view):**\`. Artifacts written by an older installed review skill need \`oat tools update\`.`,
|
|
2466
|
+
recovery: `Label the reviewer policy stamp in ${snapshot.path} as \`**Dispatch audit (policy view):**\`, or correct the stamp to the gate target and effort, then rerun the gate. If an older installed oat-project-review-provide wrote the unlabeled line, refresh installed skills with \`oat tools update\` and rerun the gate.`,
|
|
2467
|
+
gateInvocation: identity.gateInvocation,
|
|
2468
|
+
dispatchReport: identity.dispatchReport,
|
|
2469
|
+
corroboration,
|
|
2470
|
+
});
|
|
2471
|
+
},
|
|
2472
|
+
};
|
|
2473
|
+
}
|
|
2425
2474
|
hooks.onStep?.('verdict-disposition');
|
|
2426
2475
|
return {
|
|
2427
2476
|
eligible: true,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DispatchStamp } from '../../providers/identity/stamp.js';
|
|
1
2
|
export interface ReviewGateVerdict {
|
|
2
3
|
artifactPath: string;
|
|
3
4
|
reviewType: 'code' | 'artifact' | 'unknown';
|
|
@@ -5,6 +6,8 @@ export interface ReviewGateVerdict {
|
|
|
5
6
|
invocation: string | null;
|
|
6
7
|
project: string | null;
|
|
7
8
|
gateInvocation?: ReviewArtifactGateInvocation;
|
|
9
|
+
/** Present only when the artifact carries at least one audit line. */
|
|
10
|
+
dispatchAudit?: ReviewDispatchAudit;
|
|
8
11
|
counts: {
|
|
9
12
|
critical: number;
|
|
10
13
|
high: number;
|
|
@@ -25,6 +28,15 @@ export interface ReviewArtifactGateInvocation {
|
|
|
25
28
|
reasoningEffort: string | null;
|
|
26
29
|
source: string | null;
|
|
27
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Reviewer dispatch stamps found on audit lines. `policyView` holds stamps
|
|
33
|
+
* whose label names the project reviewer policy view; every other audit stamp
|
|
34
|
+
* is `unlabeled` and must agree with the gate invocation frontmatter.
|
|
35
|
+
*/
|
|
36
|
+
export interface ReviewDispatchAudit {
|
|
37
|
+
unlabeled: DispatchStamp[];
|
|
38
|
+
policyView: DispatchStamp[];
|
|
39
|
+
}
|
|
28
40
|
export type Severity = keyof ReviewGateVerdict['counts'];
|
|
29
41
|
export interface ReviewGateArtifactSnapshot {
|
|
30
42
|
readonly content: string;
|
|
@@ -35,5 +47,15 @@ export interface ParseReviewGateVerdictOptions {
|
|
|
35
47
|
artifactSnapshot?: ReviewGateArtifactSnapshot;
|
|
36
48
|
}
|
|
37
49
|
export declare function severityDisplayName(severity: Severity): string;
|
|
50
|
+
/**
|
|
51
|
+
* Reviewer dispatch audit lines from every part of the artifact body except
|
|
52
|
+
* finding sections: `## Findings` (with its subsections) and any
|
|
53
|
+
* `### Critical`, `### High`, `### Medium`, or `### Low` section. Reviewers
|
|
54
|
+
* have placed audit stamps in the pre-heading metadata block and in sections
|
|
55
|
+
* such as `## Dispatch Audit`, `## Review Dispatch Audit`, `## Review Scope`,
|
|
56
|
+
* and `## Dispatch Evidence`, so recognition is by line shape, not section
|
|
57
|
+
* name. Fenced code blocks and prose that merely quotes a stamp are ignored.
|
|
58
|
+
*/
|
|
59
|
+
export declare function extractDispatchAudit(content: string): ReviewDispatchAudit;
|
|
38
60
|
export declare function parseReviewGateVerdict(artifactPath: string, options?: ParseReviewGateVerdictOptions): Promise<ReviewGateVerdict>;
|
|
39
61
|
//# sourceMappingURL=review-verdict.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-verdict.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/review-verdict.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-verdict.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/review-verdict.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,CAAC,EAAE,4BAA4B,CAAC;IAC9C,sEAAsE;IACtE,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE;QACd,kBAAkB,EAAE,QAAQ,EAAE,CAAC;QAC/B,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;AAEzD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,6BAA6B;IAC5C,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;CAC/C;AA8OD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE9D;AAwJD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAkCzE;AAwbD,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAkG5B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { getFrontmatterBlock } from '../shared/frontmatter.js';
|
|
4
|
+
import { parseDispatchStamps, } from '../../providers/identity/stamp.js';
|
|
4
5
|
import YAML from 'yaml';
|
|
5
6
|
const SEVERITIES = ['critical', 'high', 'medium', 'low'];
|
|
6
7
|
const FRONTMATTER_COUNT_KEYS = {
|
|
@@ -214,6 +215,113 @@ function linesOutsideFences(content) {
|
|
|
214
215
|
}
|
|
215
216
|
return outsideFenceLines;
|
|
216
217
|
}
|
|
218
|
+
const TOP_SECTION_HEADING = /^##\s+\S/;
|
|
219
|
+
const FINDINGS_SECTION_HEADING = /^##\s+Findings\b/i;
|
|
220
|
+
const SEVERITY_SECTION_HEADING = /^#{3,6}\s+(?:Critical|High|Medium|Low)\s*#*\s*$/i;
|
|
221
|
+
const LIST_MARKER = /^(?:[-*+]|\d+[.)])\s+/;
|
|
222
|
+
const DISPATCH_TOKEN = /(^|[\s`])Dispatch:/;
|
|
223
|
+
const POLICY_VIEW_LABEL = /policy\s+view/i;
|
|
224
|
+
/** After a closing backtick: nothing, punctuation, or one parenthetical. */
|
|
225
|
+
const ALLOWED_TRAILING_TEXT = /^\s*(?:[.,;:!?]+|\([^()`]*\))?\s*$/;
|
|
226
|
+
function frontmatterEnd(content) {
|
|
227
|
+
const match = content.match(/^---\n[\s\S]*?\n---(?:\n|$)/);
|
|
228
|
+
return match ? match[0].length : 0;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Classifies one line as a reviewer dispatch audit line.
|
|
232
|
+
*
|
|
233
|
+
* Shape: an optional list marker, an optional bold or plain label ending in
|
|
234
|
+
* `:` (the label may itself hold backtick spans), and a `Dispatch:` stamp that
|
|
235
|
+
* is either bare to the end of the line or wrapped in one backtick pair, which
|
|
236
|
+
* may be followed only by punctuation or a single parenthetical. A wrapped
|
|
237
|
+
* stamp followed by other prose is a quotation, not an audit line. The stamp
|
|
238
|
+
* must parse as a reviewer stamp (`action=review role=reviewer`).
|
|
239
|
+
*/
|
|
240
|
+
function classifyAuditLine(text, lineNumber) {
|
|
241
|
+
const remainder = text.trim().replace(LIST_MARKER, '');
|
|
242
|
+
const token = DISPATCH_TOKEN.exec(remainder);
|
|
243
|
+
if (!token) {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
let label = remainder.slice(0, token.index + (token[1] ?? '').length);
|
|
247
|
+
let stamp = remainder.slice(token.index + (token[1] ?? '').length);
|
|
248
|
+
const wrapped = label.endsWith('`');
|
|
249
|
+
if (wrapped) {
|
|
250
|
+
label = label.slice(0, -1);
|
|
251
|
+
const closing = stamp.indexOf('`');
|
|
252
|
+
if (closing === -1) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
// Only punctuation or one parenthetical may follow the closing backtick;
|
|
256
|
+
// longer prose means the line quotes a stamp rather than records one.
|
|
257
|
+
if (!ALLOWED_TRAILING_TEXT.test(stamp.slice(closing + 1))) {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
stamp = stamp.slice(0, closing);
|
|
261
|
+
}
|
|
262
|
+
else if (stamp.includes('`')) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
const trimmedLabel = label.trim();
|
|
266
|
+
if (trimmedLabel && !/:(?:\*{1,2}|_{1,2})?$/.test(trimmedLabel)) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
const parsed = parseDispatchStamps(stamp);
|
|
270
|
+
const first = parsed[0];
|
|
271
|
+
if (parsed.length !== 1 ||
|
|
272
|
+
!first ||
|
|
273
|
+
first.legacy ||
|
|
274
|
+
first.action !== 'review' ||
|
|
275
|
+
first.role !== 'reviewer') {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
stamp: { ...first, line: text, lineNumber },
|
|
280
|
+
policyView: POLICY_VIEW_LABEL.test(trimmedLabel),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Reviewer dispatch audit lines from every part of the artifact body except
|
|
285
|
+
* finding sections: `## Findings` (with its subsections) and any
|
|
286
|
+
* `### Critical`, `### High`, `### Medium`, or `### Low` section. Reviewers
|
|
287
|
+
* have placed audit stamps in the pre-heading metadata block and in sections
|
|
288
|
+
* such as `## Dispatch Audit`, `## Review Dispatch Audit`, `## Review Scope`,
|
|
289
|
+
* and `## Dispatch Evidence`, so recognition is by line shape, not section
|
|
290
|
+
* name. Fenced code blocks and prose that merely quotes a stamp are ignored.
|
|
291
|
+
*/
|
|
292
|
+
export function extractDispatchAudit(content) {
|
|
293
|
+
const bodyStart = frontmatterEnd(content);
|
|
294
|
+
const audit = { unlabeled: [], policyView: [] };
|
|
295
|
+
let inFindingSection = false;
|
|
296
|
+
for (const line of linesOutsideFences(content)) {
|
|
297
|
+
if (line.start < bodyStart) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (TOP_SECTION_HEADING.test(line.text)) {
|
|
301
|
+
inFindingSection = FINDINGS_SECTION_HEADING.test(line.text);
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (SEVERITY_SECTION_HEADING.test(line.text)) {
|
|
305
|
+
inFindingSection = true;
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
if (inFindingSection) {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const lineNumber = content.slice(0, line.start).split('\n').length;
|
|
312
|
+
const classified = classifyAuditLine(line.text, lineNumber);
|
|
313
|
+
if (!classified) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (classified.policyView) {
|
|
317
|
+
audit.policyView.push(classified.stamp);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
audit.unlabeled.push(classified.stamp);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return audit;
|
|
324
|
+
}
|
|
217
325
|
function findFindingsSection(content) {
|
|
218
326
|
const lines = linesOutsideFences(content);
|
|
219
327
|
const findingsHeading = lines.find((line) => /^##\s+Findings\s*#*\s*$/i.test(line.text));
|
|
@@ -544,6 +652,8 @@ export async function parseReviewGateVerdict(artifactPath, options = {}) {
|
|
|
544
652
|
throw new Error(`Review artifact at ${artifactPath} does not contain recognizable review findings or explicit verdict counts.`);
|
|
545
653
|
}
|
|
546
654
|
const gateInvocation = readGateInvocation(frontmatter);
|
|
655
|
+
const dispatchAudit = extractDispatchAudit(content);
|
|
656
|
+
const hasDispatchAudit = dispatchAudit.unlabeled.length > 0 || dispatchAudit.policyView.length > 0;
|
|
547
657
|
if (options.artifactSnapshot) {
|
|
548
658
|
await assertArtifactContentCurrent(artifactPath, options.artifactSnapshot.content);
|
|
549
659
|
}
|
|
@@ -554,6 +664,7 @@ export async function parseReviewGateVerdict(artifactPath, options = {}) {
|
|
|
554
664
|
invocation: stringOrNull(frontmatter['oat_review_invocation']),
|
|
555
665
|
project: stringOrNull(frontmatter['oat_project']),
|
|
556
666
|
...(gateInvocation ? { gateInvocation } : {}),
|
|
667
|
+
...(hasDispatchAudit ? { dispatchAudit } : {}),
|
|
557
668
|
counts,
|
|
558
669
|
blocking: hasBlockingFindings(counts),
|
|
559
670
|
...(insertedSeverities.length > 0
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type CanonicalRoleEvidence } from '../../../agents/canonical/index.js';
|
|
2
|
+
import type { CommandContext, GlobalOptions } from '../../../app/command-context.js';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
/** The pack that ships the canonical OAT dispatch roles. */
|
|
5
|
+
export declare const CANONICAL_ROLE_DEPENDENCY = "workflows";
|
|
6
|
+
export interface CanonicalRoleCommandDependencies {
|
|
7
|
+
buildCommandContext: (options: GlobalOptions) => CommandContext;
|
|
8
|
+
resolveProjectRoot: (cwd: string) => Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
export interface CanonicalRoleResolutionEvent {
|
|
11
|
+
kind: 'canonical-role-resolution';
|
|
12
|
+
requestId: string;
|
|
13
|
+
source: 'canonical-role-resolver';
|
|
14
|
+
evidence: CanonicalRoleEvidence;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Produce `canonical-role-resolution` evidence from the resolver itself, so a
|
|
18
|
+
* caller never hand-assembles redacted paths or a content digest. Read-only:
|
|
19
|
+
* it inspects the loaded, user, and project `.agents` roots and writes
|
|
20
|
+
* nothing. The emitted event is checked against the recorder's own event
|
|
21
|
+
* schema before it is printed, so `oat project dispatch record` accepts it
|
|
22
|
+
* unchanged.
|
|
23
|
+
*/
|
|
24
|
+
export declare function produceCanonicalRoleEvent(input: {
|
|
25
|
+
role: string;
|
|
26
|
+
requestId: string;
|
|
27
|
+
skillDir: string;
|
|
28
|
+
cwd: string;
|
|
29
|
+
home: string;
|
|
30
|
+
repoRoot: string;
|
|
31
|
+
}): Promise<CanonicalRoleResolutionEvent>;
|
|
32
|
+
export declare function createCanonicalRoleCommand(dependencies: CanonicalRoleCommandDependencies): Command;
|
|
33
|
+
//# sourceMappingURL=canonical-role.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-role.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch/canonical-role.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,4DAA4D;AAC5D,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAKrD,MAAM,WAAW,gCAAgC;IAC/C,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;AAQD,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,2BAA2B,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,yBAAyB,CAAC;IAClC,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAeD;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAiCxC;AAwDD,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,gCAAgC,GAC7C,OAAO,CAyBT"}
|