@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.
Files changed (127) hide show
  1. package/CHANGELOG.md +185 -0
  2. package/agents/apt-planner.md +34 -3
  3. package/dist/cli/commands/coverage-check.d.mts.map +1 -1
  4. package/dist/cli/commands/coverage-check.mjs +74 -7
  5. package/dist/cli/commands/coverage-check.mjs.map +1 -1
  6. package/dist/cli/commands/detect-runtime.d.mts.map +1 -1
  7. package/dist/cli/commands/detect-runtime.mjs +18 -12
  8. package/dist/cli/commands/detect-runtime.mjs.map +1 -1
  9. package/dist/cli/coverage-check/user-outcomes.d.mts +84 -0
  10. package/dist/cli/coverage-check/user-outcomes.d.mts.map +1 -0
  11. package/dist/cli/coverage-check/user-outcomes.mjs +265 -0
  12. package/dist/cli/coverage-check/user-outcomes.mjs.map +1 -0
  13. package/dist/cli/host/detect.mjs +1 -1
  14. package/dist/cli/host/detect.mjs.map +1 -1
  15. package/dist/cli/install/install-from-source.mjs +3 -3
  16. package/dist/cli/install/legacy-paths.d.mts.map +1 -1
  17. package/dist/cli/install/legacy-paths.mjs +2 -0
  18. package/dist/cli/install/legacy-paths.mjs.map +1 -1
  19. package/dist/cli/install/manifest.d.mts +13 -0
  20. package/dist/cli/install/manifest.d.mts.map +1 -1
  21. package/dist/cli/install/manifest.mjs +5 -0
  22. package/dist/cli/install/manifest.mjs.map +1 -1
  23. package/dist/cli/install/pipeline.d.mts +15 -0
  24. package/dist/cli/install/pipeline.d.mts.map +1 -1
  25. package/dist/cli/install/pipeline.mjs +27 -0
  26. package/dist/cli/install/pipeline.mjs.map +1 -1
  27. package/dist/cli/install/transforms/codex.d.mts +1 -1
  28. package/dist/cli/install/transforms/codex.d.mts.map +1 -1
  29. package/dist/cli/install/transforms/codex.mjs +43 -2
  30. package/dist/cli/install/transforms/codex.mjs.map +1 -1
  31. package/dist/cli/install/version-header.d.mts.map +1 -1
  32. package/dist/cli/install/version-header.mjs +7 -1
  33. package/dist/cli/install/version-header.mjs.map +1 -1
  34. package/dist/cli/verify-proof/idl/index.d.mts +1 -1
  35. package/dist/cli/verify-proof/idl/index.mjs +7 -8
  36. package/dist/cli/verify-proof/idl/index.mjs.map +1 -1
  37. package/dist/cli/verify-proof/idl/types.d.ts +5 -4
  38. package/dist/cli/verify-proof/idl/types.d.ts.map +1 -1
  39. package/dist/cli/verify-proof/idl/types.js +4 -3
  40. package/dist/cli/verify-proof/idl/types.js.map +1 -1
  41. package/dist/cli/verify-proof/resolver.d.mts +63 -1
  42. package/dist/cli/verify-proof/resolver.d.mts.map +1 -1
  43. package/dist/cli/verify-proof/resolver.mjs +164 -4
  44. package/dist/cli/verify-proof/resolver.mjs.map +1 -1
  45. package/dist/cli/verify-proof/runtime-detect.d.mts +6 -3
  46. package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -1
  47. package/dist/cli/verify-proof/runtime-detect.mjs +104 -11
  48. package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -1
  49. package/dist/cli/verify-proof/trust.d.mts +1 -1
  50. package/dist/cli/verify-proof/trust.d.mts.map +1 -1
  51. package/dist/cli/verify-proof/trust.mjs +1 -1
  52. package/dist/driver-sdk/conformance.d.ts +41 -0
  53. package/dist/driver-sdk/conformance.d.ts.map +1 -0
  54. package/dist/driver-sdk/conformance.js +123 -0
  55. package/dist/driver-sdk/conformance.js.map +1 -0
  56. package/dist/driver-sdk/errors.d.ts +75 -0
  57. package/dist/driver-sdk/errors.d.ts.map +1 -0
  58. package/dist/driver-sdk/errors.js +80 -0
  59. package/dist/driver-sdk/errors.js.map +1 -0
  60. package/dist/driver-sdk/idl.d.ts +221 -0
  61. package/dist/driver-sdk/idl.d.ts.map +1 -0
  62. package/dist/driver-sdk/idl.js +140 -0
  63. package/dist/driver-sdk/idl.js.map +1 -0
  64. package/dist/driver-sdk/index.d.ts +28 -0
  65. package/dist/driver-sdk/index.d.ts.map +1 -0
  66. package/dist/driver-sdk/index.js +28 -0
  67. package/dist/driver-sdk/index.js.map +1 -0
  68. package/dist/driver-sdk/manifest.d.ts +93 -0
  69. package/dist/driver-sdk/manifest.d.ts.map +1 -0
  70. package/dist/driver-sdk/manifest.js +12 -0
  71. package/dist/driver-sdk/manifest.js.map +1 -0
  72. package/dist/driver-sdk/retry.d.ts +33 -0
  73. package/dist/driver-sdk/retry.d.ts.map +1 -0
  74. package/dist/driver-sdk/retry.js +50 -0
  75. package/dist/driver-sdk/retry.js.map +1 -0
  76. package/dist/plugin/.claude-plugin/plugin.json +2 -1
  77. package/dist/plugin/agents/apt-planner.md +34 -3
  78. package/dist/plugin/skills/apt-plan/SKILL.md +50 -0
  79. package/dist/plugin/skills/apt-pr-review/SKILL.md +1 -1
  80. package/dist/plugin/skills/apt-research/SKILL.md +526 -0
  81. package/dist/plugin/skills/apt-research/appendices/budget-loop.md +397 -0
  82. package/dist/plugin/skills/apt-research/appendices/claim-graph-schema.md +206 -0
  83. package/dist/plugin/skills/apt-research/appendices/domain-tools.md +236 -0
  84. package/dist/plugin/skills/apt-spar/SKILL.md +19 -7
  85. package/dist/plugin/skills/apt-verify-proof/SKILL.md +41 -2
  86. package/dist/schemas/quick-task.d.ts +17 -17
  87. package/drivers/.gitkeep +0 -0
  88. package/drivers/api/README.md +40 -0
  89. package/drivers/api/driver.mjs +59 -0
  90. package/drivers/api/manifest.json +26 -0
  91. package/drivers/browser/README.md +105 -0
  92. package/drivers/browser/driver.mjs +134 -0
  93. package/drivers/browser/manifest.json +35 -0
  94. package/drivers/cli/README.md +44 -0
  95. package/drivers/cli/driver.mjs +62 -0
  96. package/drivers/cli/manifest.json +28 -0
  97. package/drivers/electron/README.md +64 -0
  98. package/drivers/electron/driver.mjs +87 -0
  99. package/drivers/electron/manifest.json +37 -0
  100. package/package.json +7 -3
  101. package/skills/apt-plan/SKILL.md +50 -0
  102. package/skills/apt-planner.md +16 -0
  103. package/skills/apt-pr-review/SKILL.md +1 -1
  104. package/skills/apt-research/SKILL.md +526 -0
  105. package/skills/apt-research/appendices/budget-loop.md +397 -0
  106. package/skills/apt-research/appendices/claim-graph-schema.md +206 -0
  107. package/skills/apt-research/appendices/domain-tools.md +236 -0
  108. package/skills/apt-spar/SKILL.md +19 -7
  109. package/skills/apt-verify-proof/SKILL.md +41 -2
  110. package/src/cli/commands/coverage-check.mjs +126 -44
  111. package/src/cli/commands/detect-runtime.mjs +23 -14
  112. package/src/cli/coverage-check/user-outcomes.mjs +273 -0
  113. package/src/cli/host/detect.mjs +1 -1
  114. package/src/cli/install/install-from-source.mjs +3 -3
  115. package/src/cli/install/legacy-paths.mjs +2 -0
  116. package/src/cli/install/manifest.mjs +5 -0
  117. package/src/cli/install/pipeline.mjs +28 -0
  118. package/src/cli/install/transforms/codex.mjs +51 -2
  119. package/src/cli/install/version-header.mjs +7 -1
  120. package/src/cli/verify-proof/idl/index.mjs +7 -8
  121. package/src/cli/verify-proof/idl/types.ts +5 -4
  122. package/src/cli/verify-proof/manifest-schema.json +2 -1
  123. package/src/cli/verify-proof/resolver.mjs +171 -4
  124. package/src/cli/verify-proof/runtime-detect.mjs +99 -10
  125. package/src/cli/verify-proof/trust.mjs +1 -1
  126. package/templates/proof-verification.md +32 -3
  127. 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.4",
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`; `apt-tools consistency check`
283
- greps `## Solution` and `## User Stories`. Renaming or reordering these
284
- sections breaks downstream tooling and the C15 consistency rules.
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 --model gpt-5.3-codex --input-file /tmp/fp-gate-${FINDING_ID}.md
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.