@aperant/framework 0.8.4 → 0.8.7
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/CHANGELOG.md +185 -0
- package/agents/apt-planner.md +34 -3
- package/dist/cli/commands/coverage-check.d.mts.map +1 -1
- package/dist/cli/commands/coverage-check.mjs +74 -7
- package/dist/cli/commands/coverage-check.mjs.map +1 -1
- package/dist/cli/commands/detect-runtime.d.mts.map +1 -1
- package/dist/cli/commands/detect-runtime.mjs +18 -12
- package/dist/cli/commands/detect-runtime.mjs.map +1 -1
- package/dist/cli/coverage-check/user-outcomes.d.mts +84 -0
- package/dist/cli/coverage-check/user-outcomes.d.mts.map +1 -0
- package/dist/cli/coverage-check/user-outcomes.mjs +265 -0
- package/dist/cli/coverage-check/user-outcomes.mjs.map +1 -0
- package/dist/cli/host/detect.mjs +1 -1
- package/dist/cli/host/detect.mjs.map +1 -1
- package/dist/cli/install/install-from-source.mjs +3 -3
- package/dist/cli/install/legacy-paths.d.mts.map +1 -1
- package/dist/cli/install/legacy-paths.mjs +2 -0
- package/dist/cli/install/legacy-paths.mjs.map +1 -1
- package/dist/cli/install/manifest.d.mts +13 -0
- package/dist/cli/install/manifest.d.mts.map +1 -1
- package/dist/cli/install/manifest.mjs +5 -0
- package/dist/cli/install/manifest.mjs.map +1 -1
- package/dist/cli/install/pipeline.d.mts +15 -0
- package/dist/cli/install/pipeline.d.mts.map +1 -1
- package/dist/cli/install/pipeline.mjs +27 -0
- package/dist/cli/install/pipeline.mjs.map +1 -1
- package/dist/cli/install/transforms/codex.d.mts +1 -1
- package/dist/cli/install/transforms/codex.d.mts.map +1 -1
- package/dist/cli/install/transforms/codex.mjs +43 -2
- package/dist/cli/install/transforms/codex.mjs.map +1 -1
- package/dist/cli/install/version-header.d.mts.map +1 -1
- package/dist/cli/install/version-header.mjs +7 -1
- package/dist/cli/install/version-header.mjs.map +1 -1
- package/dist/cli/verify-proof/idl/index.d.mts +1 -1
- package/dist/cli/verify-proof/idl/index.mjs +7 -8
- package/dist/cli/verify-proof/idl/index.mjs.map +1 -1
- package/dist/cli/verify-proof/idl/types.d.ts +5 -4
- package/dist/cli/verify-proof/idl/types.d.ts.map +1 -1
- package/dist/cli/verify-proof/idl/types.js +4 -3
- package/dist/cli/verify-proof/idl/types.js.map +1 -1
- package/dist/cli/verify-proof/resolver.d.mts +63 -1
- package/dist/cli/verify-proof/resolver.d.mts.map +1 -1
- package/dist/cli/verify-proof/resolver.mjs +164 -4
- package/dist/cli/verify-proof/resolver.mjs.map +1 -1
- package/dist/cli/verify-proof/runtime-detect.d.mts +6 -3
- package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -1
- package/dist/cli/verify-proof/runtime-detect.mjs +104 -11
- package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -1
- package/dist/cli/verify-proof/trust.d.mts +1 -1
- package/dist/cli/verify-proof/trust.d.mts.map +1 -1
- package/dist/cli/verify-proof/trust.mjs +1 -1
- package/dist/driver-sdk/conformance.d.ts +41 -0
- package/dist/driver-sdk/conformance.d.ts.map +1 -0
- package/dist/driver-sdk/conformance.js +123 -0
- package/dist/driver-sdk/conformance.js.map +1 -0
- package/dist/driver-sdk/errors.d.ts +75 -0
- package/dist/driver-sdk/errors.d.ts.map +1 -0
- package/dist/driver-sdk/errors.js +80 -0
- package/dist/driver-sdk/errors.js.map +1 -0
- package/dist/driver-sdk/idl.d.ts +221 -0
- package/dist/driver-sdk/idl.d.ts.map +1 -0
- package/dist/driver-sdk/idl.js +140 -0
- package/dist/driver-sdk/idl.js.map +1 -0
- package/dist/driver-sdk/index.d.ts +28 -0
- package/dist/driver-sdk/index.d.ts.map +1 -0
- package/dist/driver-sdk/index.js +28 -0
- package/dist/driver-sdk/index.js.map +1 -0
- package/dist/driver-sdk/manifest.d.ts +93 -0
- package/dist/driver-sdk/manifest.d.ts.map +1 -0
- package/dist/driver-sdk/manifest.js +12 -0
- package/dist/driver-sdk/manifest.js.map +1 -0
- package/dist/driver-sdk/retry.d.ts +33 -0
- package/dist/driver-sdk/retry.d.ts.map +1 -0
- package/dist/driver-sdk/retry.js +50 -0
- package/dist/driver-sdk/retry.js.map +1 -0
- package/dist/plugin/.claude-plugin/plugin.json +2 -1
- package/dist/plugin/agents/apt-planner.md +34 -3
- package/dist/plugin/skills/apt-plan/SKILL.md +50 -0
- package/dist/plugin/skills/apt-pr-review/SKILL.md +1 -1
- package/dist/plugin/skills/apt-research/SKILL.md +526 -0
- package/dist/plugin/skills/apt-research/appendices/budget-loop.md +397 -0
- package/dist/plugin/skills/apt-research/appendices/claim-graph-schema.md +206 -0
- package/dist/plugin/skills/apt-research/appendices/domain-tools.md +236 -0
- package/dist/plugin/skills/apt-spar/SKILL.md +19 -7
- package/dist/plugin/skills/apt-verify-proof/SKILL.md +41 -2
- package/dist/schemas/quick-task.d.ts +17 -17
- package/drivers/.gitkeep +0 -0
- package/drivers/api/README.md +40 -0
- package/drivers/api/driver.mjs +59 -0
- package/drivers/api/manifest.json +26 -0
- package/drivers/browser/README.md +105 -0
- package/drivers/browser/driver.mjs +134 -0
- package/drivers/browser/manifest.json +35 -0
- package/drivers/cli/README.md +44 -0
- package/drivers/cli/driver.mjs +62 -0
- package/drivers/cli/manifest.json +28 -0
- package/drivers/electron/README.md +64 -0
- package/drivers/electron/driver.mjs +87 -0
- package/drivers/electron/manifest.json +37 -0
- package/package.json +7 -3
- package/skills/apt-plan/SKILL.md +50 -0
- package/skills/apt-planner.md +16 -0
- package/skills/apt-pr-review/SKILL.md +1 -1
- package/skills/apt-research/SKILL.md +526 -0
- package/skills/apt-research/appendices/budget-loop.md +397 -0
- package/skills/apt-research/appendices/claim-graph-schema.md +206 -0
- package/skills/apt-research/appendices/domain-tools.md +236 -0
- package/skills/apt-spar/SKILL.md +19 -7
- package/skills/apt-verify-proof/SKILL.md +41 -2
- package/src/cli/commands/coverage-check.mjs +126 -44
- package/src/cli/commands/detect-runtime.mjs +23 -14
- package/src/cli/coverage-check/user-outcomes.mjs +273 -0
- package/src/cli/host/detect.mjs +1 -1
- package/src/cli/install/install-from-source.mjs +3 -3
- package/src/cli/install/legacy-paths.mjs +2 -0
- package/src/cli/install/manifest.mjs +5 -0
- package/src/cli/install/pipeline.mjs +28 -0
- package/src/cli/install/transforms/codex.mjs +51 -2
- package/src/cli/install/version-header.mjs +7 -1
- package/src/cli/verify-proof/idl/index.mjs +7 -8
- package/src/cli/verify-proof/idl/types.ts +5 -4
- package/src/cli/verify-proof/manifest-schema.json +2 -1
- package/src/cli/verify-proof/resolver.mjs +171 -4
- package/src/cli/verify-proof/runtime-detect.mjs +99 -10
- package/src/cli/verify-proof/trust.mjs +1 -1
- package/templates/proof-verification.md +32 -3
- package/workflows/verify-proof.md +78 -9
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* retry.ts — exponential backoff helper with abort signal.
|
|
3
|
+
*
|
|
4
|
+
* Used by driver implementations that want to retry transient transport
|
|
5
|
+
* failures (DriverInvocationError) before giving up. Pure, dependency-free.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Run `fn` with exponential backoff. Returns the result of the first
|
|
9
|
+
* successful call. If every attempt fails (or the signal aborts), throws
|
|
10
|
+
* the last error.
|
|
11
|
+
*/
|
|
12
|
+
export async function retryWithBackoff(fn, opts = {}) {
|
|
13
|
+
const maxAttempts = Math.max(1, opts.max_attempts ?? 3);
|
|
14
|
+
const baseDelay = Math.max(0, opts.base_delay_ms ?? 100);
|
|
15
|
+
const maxDelay = Math.max(0, opts.max_delay_ms ?? 5000);
|
|
16
|
+
const multiplier = opts.multiplier ?? 2;
|
|
17
|
+
const signal = opts.signal;
|
|
18
|
+
const shouldRetry = opts.shouldRetry ?? (() => true);
|
|
19
|
+
let lastErr;
|
|
20
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
21
|
+
if (signal?.aborted) {
|
|
22
|
+
throw signal.reason instanceof Error ? signal.reason : new Error('retryWithBackoff aborted');
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
return await fn();
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
lastErr = err;
|
|
29
|
+
if (attempt >= maxAttempts)
|
|
30
|
+
break;
|
|
31
|
+
if (!shouldRetry(err))
|
|
32
|
+
break;
|
|
33
|
+
const delay = Math.min(maxDelay, baseDelay * multiplier ** (attempt - 1));
|
|
34
|
+
await new Promise((resolve, reject) => {
|
|
35
|
+
const timer = setTimeout(resolve, delay);
|
|
36
|
+
if (signal) {
|
|
37
|
+
const onAbort = () => {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
reject(signal.reason instanceof Error
|
|
40
|
+
? signal.reason
|
|
41
|
+
: new Error('retryWithBackoff aborted'));
|
|
42
|
+
};
|
|
43
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/driver-sdk/retry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,EAAoB,EACpB,OAAqB,EAAE;IAEvB,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,CAAA;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,IAAI,GAAG,CAAC,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,CAAA;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAA;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IAEpD,IAAI,OAAgB,CAAA;IACpB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACzD,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACrB,MAAM,MAAM,CAAC,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;QAC7F,CAAC;QACD,IAAI,CAAC;YACJ,OAAO,MAAM,EAAE,EAAE,CAAA;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,GAAG,GAAG,CAAA;YACb,IAAI,OAAO,IAAI,WAAW;gBAAE,MAAK;YACjC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;gBAAE,MAAK;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,GAAG,UAAU,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAA;YACzE,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;gBACxC,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,OAAO,GAAG,GAAG,EAAE;wBACpB,YAAY,CAAC,KAAK,CAAC,CAAA;wBACnB,MAAM,CACL,MAAM,CAAC,MAAM,YAAY,KAAK;4BAC7B,CAAC,CAAC,MAAM,CAAC,MAAM;4BACf,CAAC,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CACxC,CAAA;oBACF,CAAC,CAAA;oBACD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;gBAC1D,CAAC;YACF,CAAC,CAAC,CAAA;QACH,CAAC;IACF,CAAC;IACD,MAAM,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;AACtE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aperant",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "AI coding framework — composable skills for planning, executing, verifying, and reviewing code with any LLM provider. Works as Claude Code commands, Codex tasks, or programmatically.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mikalsen AI",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"skills/apt-prototype",
|
|
47
47
|
"skills/apt-quick",
|
|
48
48
|
"skills/apt-release-notes",
|
|
49
|
+
"skills/apt-research",
|
|
49
50
|
"skills/apt-resume",
|
|
50
51
|
"skills/apt-review",
|
|
51
52
|
"skills/apt-roadmap",
|
|
@@ -240,6 +240,11 @@ survives the task as a second-consumer document.
|
|
|
240
240
|
|
|
241
241
|
### 4.B. STANDARD / DEEP / COMPLEX — PRD-shaped spec.md
|
|
242
242
|
|
|
243
|
+
**Three orthogonal user-facing sections — keep them distinct.** User
|
|
244
|
+
Stories (motivation prose), User Outcomes (verify-proof input contract),
|
|
245
|
+
and Acceptance Criteria (code-level invariants) serve distinct
|
|
246
|
+
purposes. Do NOT collapse them — STANDARD/DEEP specs carry all three.
|
|
247
|
+
|
|
243
248
|
```markdown
|
|
244
249
|
# Spec: {task title}
|
|
245
250
|
|
|
@@ -257,6 +262,22 @@ survives the task as a second-consumer document.
|
|
|
257
262
|
{One **US-NN (persona).** story per user-value slice. Stories map 1:1
|
|
258
263
|
onto subtasks in implementation_plan.json.}
|
|
259
264
|
|
|
265
|
+
## User Outcomes
|
|
266
|
+
{Verify-proof input contract. One bolded `**Epic:**` headline + N
|
|
267
|
+
atomic outcomes. Authors write the LITERAL string `**ON**` — IDs are
|
|
268
|
+
POSITIONAL and synthesized by the parser (first row becomes O1, second
|
|
269
|
+
O2, ...). Closed surface set: `electron | web | cli | api | electron+web`.
|
|
270
|
+
Optional cross-refs via `*(requires ON N)*`. Refactor-only specs MAY
|
|
271
|
+
use the empty-with-note escape (verbatim string,
|
|
272
|
+
italic underscores + em dash + period required):}
|
|
273
|
+
|
|
274
|
+
`_No user-observable changes — pure refactor._`
|
|
275
|
+
|
|
276
|
+
**Epic:** {one-sentence user-facing capability headline}
|
|
277
|
+
|
|
278
|
+
- **ON** [surface]: {user does X; system shows/does Y}
|
|
279
|
+
- **ON** [surface]: {user does X; system shows/does Y} *(requires ON 1)*
|
|
280
|
+
|
|
260
281
|
## Implementation Decisions
|
|
261
282
|
{Load-bearing principles carried into every subtask. Format:
|
|
262
283
|
"### ID-NN: {title}" + rationale + practical consequence.}
|
|
@@ -279,9 +300,19 @@ reference these IDs via the per-subtask `acceptance_criteria` field.}
|
|
|
279
300
|
```
|
|
280
301
|
|
|
281
302
|
**PRD section ordering is load-bearing.** `apt-tools coverage-check
|
|
282
|
-
validate` greps `## Acceptance Criteria
|
|
283
|
-
greps `## Solution` and `## User Stories`.
|
|
284
|
-
sections breaks downstream tooling and the
|
|
303
|
+
validate` greps `## Acceptance Criteria` AND `## User Outcomes`;
|
|
304
|
+
`apt-tools consistency check` greps `## Solution` and `## User Stories`.
|
|
305
|
+
Renaming or reordering these sections breaks downstream tooling and the
|
|
306
|
+
C15 consistency rules.
|
|
307
|
+
|
|
308
|
+
**`## User Outcomes` synthesis directive.** Outcomes are
|
|
309
|
+
user-observable (a user does X; the system shows/does Y); Acceptance
|
|
310
|
+
Criteria are code-level invariants (a function returns X; a config key
|
|
311
|
+
exists). Do NOT collapse them — they parse through different gates and
|
|
312
|
+
serve different consumers. STANDARD/DEEP specs carry both sections in
|
|
313
|
+
parallel. IDs are POSITIONAL: the parser counts outcome rows in
|
|
314
|
+
document order and synthesizes `O1`, `O2`, ... — authors MUST write
|
|
315
|
+
the literal `**ON**` token, never `**O1**`/`**O2**`.
|
|
285
316
|
|
|
286
317
|
**Do NOT interview the user.** The PRD is synthesized from the task
|
|
287
318
|
description + codebase investigation + AGENTS.md, not from a clarifying
|
|
@@ -161,6 +161,14 @@ and is committable as a second-consumer document. Section ordering is
|
|
|
161
161
|
**load-bearing** — downstream tooling (`apt-tools coverage-check`,
|
|
162
162
|
`apt-tools consistency check`) reads sections by header.
|
|
163
163
|
|
|
164
|
+
**Three orthogonal user-facing sections — keep them distinct.** User
|
|
165
|
+
Stories carry product motivation, User Outcomes carry the
|
|
166
|
+
verify-proof input contract, and Acceptance Criteria carry code-level
|
|
167
|
+
invariants. The three do NOT subsume each other; a STANDARD/DEEP spec
|
|
168
|
+
carries all three. See the `## User Outcomes` block below for the
|
|
169
|
+
verify-proof unit shape (Epic line + atomic outcomes + surface tags
|
|
170
|
+
+ empty-with-note escape).
|
|
171
|
+
|
|
164
172
|
```markdown
|
|
165
173
|
# Spec: {task title}
|
|
166
174
|
|
|
@@ -184,6 +192,29 @@ ships: new files, modified files, new flags, new config, new skills.}
|
|
|
184
192
|
{persona}, when I {trigger}, I want {behavior} so I can {outcome}."
|
|
185
193
|
Stories map 1:1 onto subtasks in implementation_plan.json.}
|
|
186
194
|
|
|
195
|
+
## User Outcomes
|
|
196
|
+
|
|
197
|
+
{The verify-proof input contract. One bolded `**Epic:**` headline + N
|
|
198
|
+
atomic outcomes tagged by surface. Authors write the LITERAL string
|
|
199
|
+
`**ON**` — IDs are POSITIONAL and synthesized by the parser (the first
|
|
200
|
+
outcome row becomes `O1`, the second `O2`, etc.). Closed surface set:
|
|
201
|
+
`electron | web | cli | api | electron+web`. Optional cross-references
|
|
202
|
+
via `*(requires ON N)*` where `N` is the digit of a prior outcome's
|
|
203
|
+
position. For pure-refactor specs with no user-observable changes, the
|
|
204
|
+
body MAY be exactly `_No user-observable changes — pure refactor._`
|
|
205
|
+
(italic underscores required, exact em dash, period mandatory).
|
|
206
|
+
Coverage-check parses this section into a `user_outcomes` payload —
|
|
207
|
+
see the gate table below.}
|
|
208
|
+
|
|
209
|
+
**Epic:** {one-sentence user-facing capability headline}
|
|
210
|
+
|
|
211
|
+
- **ON** [surface]: {user does X; system shows/does Y}
|
|
212
|
+
- **ON** [surface]: {user does X; system shows/does Y} *(requires ON 1)*
|
|
213
|
+
- **ON** [electron+web]: {cross-surface outcome — runs twice, once per surface}
|
|
214
|
+
|
|
215
|
+
(Refactor-only escape:)
|
|
216
|
+
_No user-observable changes — pure refactor._
|
|
217
|
+
|
|
187
218
|
## Implementation Decisions
|
|
188
219
|
|
|
189
220
|
{Load-bearing principles carried forward into every subtask. Format:
|
|
@@ -215,6 +246,25 @@ ID. Subtasks reference these IDs via their per-subtask
|
|
|
215
246
|
plan-coverage-check input.}
|
|
216
247
|
```
|
|
217
248
|
|
|
249
|
+
**`## User Outcomes` is the verify-proof input contract (STANDARD/DEEP
|
|
250
|
+
only — QUICK is hard-exempt per ID-05 / Fast Path Guarantee).** The
|
|
251
|
+
section sits between `## User Stories` (product motivation prose) and
|
|
252
|
+
`## Implementation Decisions` (load-bearing engineering principles).
|
|
253
|
+
Coverage-check (`apt-tools coverage-check validate .`) parses the
|
|
254
|
+
section into a `user_outcomes` payload with this gate behavior:
|
|
255
|
+
|
|
256
|
+
| Header present? | Body shape | Gate result (v0.8.x) | v0.9.0 hard cutover |
|
|
257
|
+
|---|---|---|---|
|
|
258
|
+
| no | — | `warn` (migration deadline emitted) | `block` |
|
|
259
|
+
| yes | `outcomes` (≥1 `**ON**` row) | `pass` | `pass` |
|
|
260
|
+
| yes | exactly `_No user-observable changes — pure refactor._` | `pass` | `pass` |
|
|
261
|
+
| yes | empty (header but nothing under it) | `block` | `block` |
|
|
262
|
+
|
|
263
|
+
Closed surface set: `electron | web | cli | api | electron+web`. The
|
|
264
|
+
`electron+web` tag means the outcome runs on both surfaces during
|
|
265
|
+
verify-proof (split screenshot trees, two test entries in
|
|
266
|
+
`verification.json`).
|
|
267
|
+
|
|
218
268
|
**Constraint — do NOT interview the user.** The PRD is synthesized from
|
|
219
269
|
the task description + codebase investigation + AGENTS.md, not from a
|
|
220
270
|
clarifying interview. If a section truly cannot be filled, write
|
|
@@ -1081,7 +1081,7 @@ For every finding with `validation_status == "confirmed_valid"` AND `severity
|
|
|
1081
1081
|
- `{REVIEWER_EVIDENCE}` — the finding's `evidence` field verbatim.
|
|
1082
1082
|
3. Invoke codex using the shape configured at `.aperant/config.json:router.llm.providers.codex`:
|
|
1083
1083
|
```bash
|
|
1084
|
-
codex exec --
|
|
1084
|
+
codex exec --input-file /tmp/fp-gate-${FINDING_ID}.md
|
|
1085
1085
|
```
|
|
1086
1086
|
Parse the JSON response `{verdict, reasoning, evidence_quote, severity_assessment}`.
|
|
1087
1087
|
4. If `verdict == "falsify"`, set the finding's `validation_status = "dismissed_cross_model_falsification"` and copy the codex response into `fp_gate_result`. If `verdict == "confirm"`, pass through unchanged.
|