@aperant/framework 0.8.0 → 0.8.4

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 (271) hide show
  1. package/CHANGELOG.md +311 -1
  2. package/README.md +12 -0
  3. package/agents/apt-planner.md +5 -4
  4. package/dist/cli/commands/adr.mjs +1 -1
  5. package/dist/cli/commands/audit-branch-current.d.mts +25 -0
  6. package/dist/cli/commands/audit-branch-current.d.mts.map +1 -0
  7. package/dist/cli/commands/audit-branch-current.mjs +252 -0
  8. package/dist/cli/commands/audit-branch-current.mjs.map +1 -0
  9. package/dist/cli/commands/audit.d.mts.map +1 -1
  10. package/dist/cli/commands/audit.mjs +13 -2
  11. package/dist/cli/commands/audit.mjs.map +1 -1
  12. package/dist/cli/commands/check-version.d.mts.map +1 -1
  13. package/dist/cli/commands/check-version.mjs +19 -1
  14. package/dist/cli/commands/check-version.mjs.map +1 -1
  15. package/dist/cli/commands/context.mjs +3 -3
  16. package/dist/cli/commands/context.mjs.map +1 -1
  17. package/dist/cli/commands/detect-runtime.d.mts +6 -0
  18. package/dist/cli/commands/detect-runtime.d.mts.map +1 -0
  19. package/dist/cli/commands/detect-runtime.mjs +136 -0
  20. package/dist/cli/commands/detect-runtime.mjs.map +1 -0
  21. package/dist/cli/commands/driver-doctor.d.mts +29 -0
  22. package/dist/cli/commands/driver-doctor.d.mts.map +1 -0
  23. package/dist/cli/commands/driver-doctor.mjs +291 -0
  24. package/dist/cli/commands/driver-doctor.mjs.map +1 -0
  25. package/dist/cli/commands/gate.mjs +14 -0
  26. package/dist/cli/commands/gate.mjs.map +1 -1
  27. package/dist/cli/commands/init.d.mts.map +1 -1
  28. package/dist/cli/commands/init.mjs +76 -33
  29. package/dist/cli/commands/init.mjs.map +1 -1
  30. package/dist/cli/commands/install-from-source.d.mts +2 -0
  31. package/dist/cli/commands/install-from-source.d.mts.map +1 -0
  32. package/dist/cli/commands/install-from-source.mjs +2 -0
  33. package/dist/cli/commands/install-from-source.mjs.map +1 -0
  34. package/dist/cli/commands/modes.mjs +1 -1
  35. package/dist/cli/commands/route.d.mts.map +1 -1
  36. package/dist/cli/commands/route.mjs +38 -1
  37. package/dist/cli/commands/route.mjs.map +1 -1
  38. package/dist/cli/commands/triage.mjs +1 -1
  39. package/dist/cli/config/load.d.mts.map +1 -1
  40. package/dist/cli/config/load.mjs +9 -3
  41. package/dist/cli/config/load.mjs.map +1 -1
  42. package/dist/cli/coordination/auto-emit-artifact-ready.mjs +1 -1
  43. package/dist/cli/coordination/event-schema.d.mts.map +1 -1
  44. package/dist/cli/coordination/event-schema.mjs +18 -0
  45. package/dist/cli/coordination/event-schema.mjs.map +1 -1
  46. package/dist/cli/design/frontmatter-schema.d.mts +4 -4
  47. package/dist/cli/dispatch.d.mts.map +1 -1
  48. package/dist/cli/dispatch.mjs +18 -1
  49. package/dist/cli/dispatch.mjs.map +1 -1
  50. package/dist/cli/gate/context.d.mts +1 -0
  51. package/dist/cli/gate/context.d.mts.map +1 -1
  52. package/dist/cli/gate/context.mjs +14 -1
  53. package/dist/cli/gate/context.mjs.map +1 -1
  54. package/dist/cli/gate/gates/consistency-check.d.mts +1 -0
  55. package/dist/cli/gate/gates/consistency-check.d.mts.map +1 -1
  56. package/dist/cli/gate/gates/consistency-check.mjs +1 -0
  57. package/dist/cli/gate/gates/consistency-check.mjs.map +1 -1
  58. package/dist/cli/gate/gates/review-clean.d.mts +1 -0
  59. package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
  60. package/dist/cli/gate/gates/review-clean.mjs +1 -0
  61. package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
  62. package/dist/cli/gate/gates/verify-approved.d.mts +1 -0
  63. package/dist/cli/gate/gates/verify-approved.d.mts.map +1 -1
  64. package/dist/cli/gate/gates/verify-approved.mjs +1 -0
  65. package/dist/cli/gate/gates/verify-approved.mjs.map +1 -1
  66. package/dist/cli/gate/registry.d.mts.map +1 -1
  67. package/dist/cli/gate/registry.mjs +9 -1
  68. package/dist/cli/gate/registry.mjs.map +1 -1
  69. package/dist/cli/install/cli-to-install-root.d.mts.map +1 -1
  70. package/dist/cli/install/cli-to-install-root.mjs +0 -2
  71. package/dist/cli/install/cli-to-install-root.mjs.map +1 -1
  72. package/dist/cli/install/find-workspace-framework-version.d.mts +16 -0
  73. package/dist/cli/install/find-workspace-framework-version.d.mts.map +1 -0
  74. package/dist/cli/install/find-workspace-framework-version.mjs +85 -0
  75. package/dist/cli/install/find-workspace-framework-version.mjs.map +1 -0
  76. package/dist/cli/install/install-from-source.d.mts +10 -0
  77. package/dist/cli/install/install-from-source.d.mts.map +1 -0
  78. package/dist/cli/install/install-from-source.mjs +271 -0
  79. package/dist/cli/install/install-from-source.mjs.map +1 -0
  80. package/dist/cli/install/install-kernel.d.mts.map +1 -1
  81. package/dist/cli/install/install-kernel.mjs +24 -0
  82. package/dist/cli/install/install-kernel.mjs.map +1 -1
  83. package/dist/cli/install/legacy-paths.d.mts +33 -11
  84. package/dist/cli/install/legacy-paths.d.mts.map +1 -1
  85. package/dist/cli/install/legacy-paths.mjs +161 -39
  86. package/dist/cli/install/legacy-paths.mjs.map +1 -1
  87. package/dist/cli/install/runtime-detect.d.mts +2 -6
  88. package/dist/cli/install/runtime-detect.d.mts.map +1 -1
  89. package/dist/cli/install/runtime-detect.mjs +9 -4
  90. package/dist/cli/install/runtime-detect.mjs.map +1 -1
  91. package/dist/cli/install/runtime-migrate.d.mts +34 -14
  92. package/dist/cli/install/runtime-migrate.d.mts.map +1 -1
  93. package/dist/cli/install/runtime-migrate.mjs +63 -30
  94. package/dist/cli/install/runtime-migrate.mjs.map +1 -1
  95. package/dist/cli/install/transforms/codex.d.mts.map +1 -1
  96. package/dist/cli/install/transforms/codex.mjs +28 -17
  97. package/dist/cli/install/transforms/codex.mjs.map +1 -1
  98. package/dist/cli/install/transforms/pi.d.mts +6 -0
  99. package/dist/cli/install/transforms/pi.d.mts.map +1 -0
  100. package/dist/cli/install/transforms/pi.mjs +37 -0
  101. package/dist/cli/install/transforms/pi.mjs.map +1 -0
  102. package/dist/cli/personas/sidecar.d.mts +1 -1
  103. package/dist/cli/roadmap/lifecycle.d.mts +1 -1
  104. package/dist/cli/roadmap/rollup.d.mts +2 -2
  105. package/dist/cli/skill-author/contract.mjs +2 -2
  106. package/dist/cli/skill-author/contract.mjs.map +1 -1
  107. package/dist/cli/verify-proof/audit.d.mts +34 -0
  108. package/dist/cli/verify-proof/audit.d.mts.map +1 -0
  109. package/dist/cli/verify-proof/audit.mjs +53 -0
  110. package/dist/cli/verify-proof/audit.mjs.map +1 -0
  111. package/dist/cli/verify-proof/exec.d.mts +20 -0
  112. package/dist/cli/verify-proof/exec.d.mts.map +1 -0
  113. package/dist/cli/verify-proof/exec.mjs +74 -0
  114. package/dist/cli/verify-proof/exec.mjs.map +1 -0
  115. package/dist/cli/verify-proof/idl/index.d.mts +2 -0
  116. package/dist/cli/verify-proof/idl/index.d.mts.map +1 -0
  117. package/dist/cli/verify-proof/idl/index.mjs +14 -0
  118. package/dist/cli/verify-proof/idl/index.mjs.map +1 -0
  119. package/dist/cli/verify-proof/idl/types.d.ts +9 -0
  120. package/dist/cli/verify-proof/idl/types.d.ts.map +1 -0
  121. package/dist/cli/verify-proof/idl/types.js +9 -0
  122. package/dist/cli/verify-proof/idl/types.js.map +1 -0
  123. package/dist/cli/verify-proof/manifest-validator.d.mts +19 -0
  124. package/dist/cli/verify-proof/manifest-validator.d.mts.map +1 -0
  125. package/dist/cli/verify-proof/manifest-validator.mjs +182 -0
  126. package/dist/cli/verify-proof/manifest-validator.mjs.map +1 -0
  127. package/dist/cli/verify-proof/resolver.d.mts +43 -0
  128. package/dist/cli/verify-proof/resolver.d.mts.map +1 -0
  129. package/dist/cli/verify-proof/resolver.mjs +160 -0
  130. package/dist/cli/verify-proof/resolver.mjs.map +1 -0
  131. package/dist/cli/verify-proof/runtime-detect.d.mts +27 -0
  132. package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -0
  133. package/dist/cli/verify-proof/runtime-detect.mjs +116 -0
  134. package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -0
  135. package/dist/cli/verify-proof/trust.d.mts +70 -0
  136. package/dist/cli/verify-proof/trust.d.mts.map +1 -0
  137. package/dist/cli/verify-proof/trust.mjs +174 -0
  138. package/dist/cli/verify-proof/trust.mjs.map +1 -0
  139. package/dist/plugin/.claude-plugin/plugin.json +4 -1
  140. package/dist/plugin/agents/apt-executor.md +12 -0
  141. package/dist/plugin/agents/apt-planner.md +5 -4
  142. package/dist/plugin/agents/apt-team-docs-narrator.md +11 -0
  143. package/dist/plugin/skills/apt/SKILL.md +78 -8
  144. package/dist/plugin/skills/apt-caveman/SKILL.md +64 -0
  145. package/dist/plugin/skills/apt-debug/SKILL.md +36 -4
  146. package/dist/plugin/skills/apt-debug/appendices/diagnose-discipline.md +2 -11
  147. package/dist/plugin/skills/apt-discuss/SKILL.md +4 -4
  148. package/dist/plugin/skills/apt-discuss/appendices/grill-discipline.md +2 -11
  149. package/dist/plugin/skills/apt-discuss/appendices/zoom-out-helper.md +0 -8
  150. package/dist/plugin/skills/apt-execute/SKILL.md +40 -4
  151. package/dist/plugin/skills/apt-execute/appendices/tdd-mode.md +2 -10
  152. package/dist/plugin/skills/apt-fan-out/SKILL.md +159 -0
  153. package/dist/plugin/skills/apt-handoff/SKILL.md +228 -0
  154. package/dist/plugin/skills/apt-improve/DEEPENING.md +0 -8
  155. package/dist/plugin/skills/apt-improve/INTERFACE-DESIGN.md +0 -8
  156. package/dist/plugin/skills/apt-improve/LANGUAGE.md +0 -8
  157. package/dist/plugin/skills/apt-improve/SKILL.md +4 -4
  158. package/dist/plugin/skills/apt-plan/SKILL.md +23 -5
  159. package/dist/plugin/skills/apt-plan/adapters/conductor.md +1 -1
  160. package/dist/plugin/skills/apt-pr-review/SKILL.md +8 -1
  161. package/dist/plugin/skills/apt-prototype/LOGIC.md +0 -8
  162. package/dist/plugin/skills/apt-prototype/SKILL.md +4 -4
  163. package/dist/plugin/skills/apt-prototype/UI.md +0 -8
  164. package/dist/plugin/skills/apt-quick/SKILL.md +31 -1
  165. package/dist/plugin/skills/apt-resume/SKILL.md +54 -31
  166. package/dist/plugin/skills/apt-review/SKILL.md +4 -0
  167. package/dist/plugin/skills/apt-run/SKILL.md +134 -21
  168. package/dist/plugin/skills/apt-setup/SKILL.md +97 -8
  169. package/dist/plugin/skills/apt-ship/SKILL.md +165 -9
  170. package/dist/plugin/skills/apt-spar/SKILL.md +77 -25
  171. package/dist/plugin/skills/apt-triage/AGENT-BRIEF.md +0 -8
  172. package/dist/plugin/skills/apt-triage/OUT-OF-SCOPE.md +0 -7
  173. package/dist/plugin/skills/apt-triage/SKILL.md +2 -2
  174. package/dist/plugin/skills/apt-update/SKILL.md +74 -17
  175. package/dist/plugin/skills/apt-verify/SKILL.md +11 -0
  176. package/dist/plugin/skills/apt-verify-proof/SKILL.md +48 -1
  177. package/dist/plugin/skills/apt-watch-ci/SKILL.md +2 -2
  178. package/dist/plugin/skills/apt-zoom-out/SKILL.md +3 -3
  179. package/dist/schemas/quick-task.d.ts +17 -17
  180. package/dist/schemas/quick-task.d.ts.map +1 -1
  181. package/dist/schemas/quick-task.js +2 -2
  182. package/dist/schemas/quick-task.js.map +1 -1
  183. package/dist/types/config.d.ts +33 -0
  184. package/dist/types/config.d.ts.map +1 -1
  185. package/dist/types/state.d.ts +1 -1
  186. package/dist/types/state.d.ts.map +1 -1
  187. package/dist/types/task-record.d.ts +1 -1
  188. package/dist/types/task-record.d.ts.map +1 -1
  189. package/package.json +134 -133
  190. package/prompts/planner.md +1 -1
  191. package/prompts/spec_writer.md +1 -1
  192. package/skills/apt/SKILL.md +78 -8
  193. package/skills/apt-caveman/SKILL.md +64 -0
  194. package/skills/apt-debug/SKILL.md +36 -4
  195. package/skills/apt-debug/appendices/diagnose-discipline.md +2 -11
  196. package/skills/apt-discuss/SKILL.md +4 -4
  197. package/skills/apt-discuss/appendices/grill-discipline.md +2 -11
  198. package/skills/apt-discuss/appendices/zoom-out-helper.md +0 -8
  199. package/skills/apt-execute/SKILL.md +27 -4
  200. package/skills/apt-execute/appendices/tdd-mode.md +2 -10
  201. package/skills/apt-fan-out/SKILL.md +36 -1
  202. package/skills/apt-handoff/SKILL.md +228 -0
  203. package/skills/apt-improve/DEEPENING.md +0 -8
  204. package/skills/apt-improve/INTERFACE-DESIGN.md +0 -8
  205. package/skills/apt-improve/LANGUAGE.md +0 -8
  206. package/skills/apt-improve/SKILL.md +4 -4
  207. package/skills/apt-plan/SKILL.md +23 -5
  208. package/skills/apt-plan/adapters/conductor.md +1 -1
  209. package/skills/apt-planner.md +1 -1
  210. package/skills/apt-prototype/LOGIC.md +0 -8
  211. package/skills/apt-prototype/SKILL.md +4 -4
  212. package/skills/apt-prototype/UI.md +0 -8
  213. package/skills/apt-quick/SKILL.md +31 -1
  214. package/skills/apt-resume/SKILL.md +54 -31
  215. package/skills/apt-run/SKILL.md +114 -16
  216. package/skills/apt-setup/SKILL.md +97 -8
  217. package/skills/apt-ship/SKILL.md +165 -9
  218. package/skills/apt-spar/SKILL.md +65 -16
  219. package/skills/apt-triage/AGENT-BRIEF.md +0 -8
  220. package/skills/apt-triage/OUT-OF-SCOPE.md +0 -7
  221. package/skills/apt-triage/SKILL.md +2 -2
  222. package/skills/apt-update/SKILL.md +74 -17
  223. package/skills/apt-verify-proof/SKILL.md +48 -1
  224. package/skills/apt-zoom-out/SKILL.md +3 -3
  225. package/src/cli/commands/adr.mjs +1 -1
  226. package/src/cli/commands/audit-branch-current.mjs +250 -0
  227. package/src/cli/commands/audit.mjs +13 -2
  228. package/src/cli/commands/check-version.mjs +20 -1
  229. package/src/cli/commands/context.mjs +3 -3
  230. package/src/cli/commands/detect-runtime.mjs +134 -0
  231. package/src/cli/commands/driver-doctor.mjs +294 -0
  232. package/src/cli/commands/gate.mjs +15 -0
  233. package/src/cli/commands/init.mjs +75 -33
  234. package/src/cli/commands/install-from-source.mjs +1 -0
  235. package/src/cli/commands/modes.mjs +1 -1
  236. package/src/cli/commands/route.mjs +42 -1
  237. package/src/cli/commands/triage.mjs +1 -1
  238. package/src/cli/config/load.mjs +9 -3
  239. package/src/cli/coordination/auto-emit-artifact-ready.mjs +1 -1
  240. package/src/cli/coordination/event-schema.mjs +19 -0
  241. package/src/cli/dispatch.mjs +17 -1
  242. package/src/cli/gate/context.mjs +20 -1
  243. package/src/cli/gate/gates/consistency-check.mjs +1 -0
  244. package/src/cli/gate/gates/review-clean.mjs +1 -0
  245. package/src/cli/gate/gates/verify-approved.mjs +1 -0
  246. package/src/cli/gate/registry.mjs +11 -1
  247. package/src/cli/install/cli-to-install-root.mjs +0 -2
  248. package/src/cli/install/find-workspace-framework-version.mjs +88 -0
  249. package/src/cli/install/install-from-source.mjs +276 -0
  250. package/src/cli/install/install-kernel.mjs +24 -0
  251. package/src/cli/install/legacy-paths.mjs +162 -39
  252. package/src/cli/install/runtime-detect.mjs +9 -4
  253. package/src/cli/install/runtime-migrate.mjs +63 -30
  254. package/src/cli/install/transforms/codex.mjs +26 -17
  255. package/src/cli/install/transforms/pi.mjs +37 -0
  256. package/src/cli/skill-author/contract.mjs +2 -2
  257. package/src/cli/verify-proof/.gitkeep +0 -0
  258. package/src/cli/verify-proof/audit.mjs +55 -0
  259. package/src/cli/verify-proof/exec.mjs +74 -0
  260. package/src/cli/verify-proof/idl/index.mjs +24 -0
  261. package/src/cli/verify-proof/idl/types.ts +41 -0
  262. package/src/cli/verify-proof/manifest-schema.json +211 -0
  263. package/src/cli/verify-proof/manifest-validator.mjs +184 -0
  264. package/src/cli/verify-proof/resolver.mjs +163 -0
  265. package/src/cli/verify-proof/runtime-detect.mjs +122 -0
  266. package/src/cli/verify-proof/trust.mjs +187 -0
  267. package/templates/adr-format.md +0 -8
  268. package/templates/aperant-claude-md-appendix.md +1 -1
  269. package/templates/context-format.md +1 -9
  270. package/templates/proof-verification.md +19 -5
  271. package/workflows/verify-proof.md +56 -14
@@ -11,18 +11,28 @@
11
11
  * pre-manifest install still surfaces as "installed" rather than
12
12
  * "missing-skills".
13
13
  *
14
- * Derivation: the codex `framework_files` list was extracted from
15
- * `git show 1a8dd8a8 --stat` (the original "make Codex a first-class
16
- * skill install surface" commit) every `.agents/skills/…` path the
17
- * installer once wrote, including the `.apt-version` stamp and the
18
- * apt-pr-review / apt-discuss / apt-verify-proof sub-files. When the
19
- * codex installer was retargeted to `.codex/`, that entire tree became
20
- * orphaned on upgrading projects.
14
+ * Codex evolution: v0.7/v0.8 retargeted the codex transform to write
15
+ * markdown skills under `.codex/agents/` + `.codex/commands/` (with the
16
+ * apt-file-manifest.json next to them). Codex CLI 0.132.0 does not
17
+ * discover skills at either path its documented surface is
18
+ * `.agents/skills/<folder>/SKILL.md` (per
19
+ * https://developers.openai.com/codex/skills). The v0.8.2 fix inverts
20
+ * this registry: the dead `.codex/` markdown tree becomes the legacy
21
+ * target so `runLegacyCleanup` GCs it on the next `apt-tools init`.
21
22
  *
22
23
  * Schema:
23
24
  * { [runtimeId]: {
24
25
  * install_root: relative path the runtime once wrote into,
25
- * version_file: relative path of the legacy `.apt-version` stamp,
26
+ * version_file: relative path of the legacy `.apt-version` stamp
27
+ * (or a path known to never exist, when no version
28
+ * stamp was ever written for the legacy topology),
29
+ * honor_manifest: when true (default), a present apt-file-manifest.json
30
+ * at install_root signals a managed install and the
31
+ * cleanup no-ops (`reason: 'managed'`). When false,
32
+ * the legacy root is known-dead so the manifest is
33
+ * removed alongside framework files (used for surfaces
34
+ * like the v0.7/v0.8 codex misdirect that will never
35
+ * again be a managed install root).
26
36
  * framework_files: array of relative paths the installer once owned
27
37
  * (under install_root).
28
38
  * } }
@@ -30,40 +40,153 @@
30
40
  * Frozen via Object.freeze so callers cannot mutate the shared registry.
31
41
  */
32
42
 
33
- /** @type {Record<string, { install_root: string, version_file: string, framework_files: ReadonlyArray<string> }>} */
43
+ /**
44
+ * @typedef {Object} LegacyInstallPath
45
+ * @property {string} install_root
46
+ * @property {string} version_file
47
+ * @property {boolean} [honor_manifest] default true; false for known-dead surfaces
48
+ * @property {ReadonlyArray<string>} framework_files
49
+ */
50
+
51
+ /** @type {Record<string, LegacyInstallPath>} */
34
52
  export const LEGACY_INSTALL_PATHS = Object.freeze({
35
53
  codex: Object.freeze({
36
- install_root: '.agents/skills',
37
- version_file: '.agents/skills/.apt-version',
54
+ // The v0.7/v0.8 misdirect lived under `.codex/agents/` + `.codex/commands/`
55
+ // (with the orphan apt-file-manifest.json at `.codex/apt-file-manifest.json`).
56
+ // Codex CLI 0.132.0 does not consume any of those paths — see header.
57
+ install_root: '.codex',
58
+ // No `.apt-version` was ever written under `.codex/`; point at a path
59
+ // that doesn't exist so `existsSync` returns false in
60
+ // skill-installs.mjs:67-68 (legacy version_file fallback). The bare
61
+ // apt-file-manifest.json (handled by framework_files) is enough to
62
+ // signal the legacy install.
63
+ version_file: '.codex/.apt-version',
64
+ // Known-dead surface: this `.codex/` topology will never again be
65
+ // a managed Aperant install root, so a manifest sitting here is
66
+ // always stale. Skip the no-op-on-manifest safety and remove the
67
+ // manifest alongside framework_files. Default-true elsewhere
68
+ // preserves the safety for legacy roots that could legitimately
69
+ // re-host a managed install.
70
+ honor_manifest: false,
71
+ // Enumerated from BOTH canonical sources (drift-checked at test time
72
+ // by legacy-cleanup-codex.test.ts):
73
+ // - For each `packages/framework/skills/apt-*/` directory: the v0.7/v0.8
74
+ // transform emitted BOTH `agents/<dir>.md` AND `commands/<dir>.md`.
75
+ // - For each top-level `packages/framework/skills/apt-*.md` file
76
+ // (fileType=agent in the pipeline): the transform emitted
77
+ // `agents/<basename>.md`.
78
+ // - For each `packages/framework/agents/apt-*.md` file: the transform
79
+ // emitted `agents/<basename>.md` (last-write-wins de-dupe applied
80
+ // by the pipeline for overlapping outputs).
81
+ // - Plus the orphan apt-file-manifest.json the install pipeline
82
+ // stamps at install_root.
83
+ // TODO: follow-up — derive this programmatically per spec ID-06 so
84
+ // new apt-* skills auto-extend the legacy set without an edit here.
38
85
  framework_files: Object.freeze([
39
- '.apt-version',
40
- 'apt/SKILL.md',
41
- 'apt-debug/SKILL.md',
42
- 'apt-discuss/SKILL.md',
43
- 'apt-discuss/examples/rationalization-example.md',
44
- 'apt-docs/SKILL.md',
45
- 'apt-execute/SKILL.md',
46
- 'apt-pause/SKILL.md',
47
- 'apt-plan/SKILL.md',
48
- 'apt-pr-review/SCHEMA.md',
49
- 'apt-pr-review/SKILL.md',
50
- 'apt-pr-review/prompts/fp-gate-codex.md',
51
- 'apt-pr-review/templates/external-comment.md',
52
- 'apt-quick/SKILL.md',
53
- 'apt-resume/SKILL.md',
54
- 'apt-review/SKILL.md',
55
- 'apt-roadmap/SKILL.md',
56
- 'apt-roundtable/SKILL.md',
57
- 'apt-run/SKILL.md',
58
- 'apt-scan/SKILL.md',
59
- 'apt-setup/SKILL.md',
60
- 'apt-ship/SKILL.md',
61
- 'apt-stress-test/SKILL.md',
62
- 'apt-verify/SKILL.md',
63
- 'apt-verify-proof/SKILL.md',
64
- 'apt-verify-proof/references/multi-model-setup.md',
65
- 'apt-verify-proof/references/multi-model-verification.md',
66
- 'apt-verify-proof/references/proof-capture.md',
86
+ 'apt-file-manifest.json',
87
+ // agents/<dir>.md — one per skill directory (39 dirs)
88
+ 'agents/apt.md',
89
+ 'agents/apt-author-skill.md',
90
+ 'agents/apt-bootstrap.md',
91
+ 'agents/apt-caveman.md',
92
+ 'agents/apt-classify.md',
93
+ 'agents/apt-close-task.md',
94
+ 'agents/apt-create-docs.md',
95
+ 'agents/apt-debug.md',
96
+ 'agents/apt-design.md',
97
+ 'agents/apt-diagram.md',
98
+ 'agents/apt-discuss.md',
99
+ 'agents/apt-docs.md',
100
+ 'agents/apt-execute.md',
101
+ 'agents/apt-fan-out.md',
102
+ 'agents/apt-handoff.md',
103
+ 'agents/apt-improve.md',
104
+ 'agents/apt-mockup.md',
105
+ 'agents/apt-pause.md',
106
+ 'agents/apt-personas.md',
107
+ 'agents/apt-plan.md',
108
+ 'agents/apt-pr-review.md',
109
+ 'agents/apt-prototype.md',
110
+ 'agents/apt-quick.md',
111
+ 'agents/apt-release-notes.md',
112
+ 'agents/apt-resume.md',
113
+ 'agents/apt-review.md',
114
+ 'agents/apt-roadmap.md',
115
+ 'agents/apt-roundtable.md',
116
+ 'agents/apt-run.md',
117
+ 'agents/apt-scan.md',
118
+ 'agents/apt-setup.md',
119
+ 'agents/apt-ship.md',
120
+ 'agents/apt-spar.md',
121
+ 'agents/apt-stress-test.md',
122
+ 'agents/apt-terminal.md',
123
+ 'agents/apt-triage.md',
124
+ 'agents/apt-update.md',
125
+ 'agents/apt-verify.md',
126
+ 'agents/apt-verify-proof.md',
127
+ 'agents/apt-watch-ci.md',
128
+ 'agents/apt-zoom-out.md',
129
+ // commands/<dir>.md — one per skill directory (mirrors agents/)
130
+ 'commands/apt.md',
131
+ 'commands/apt-author-skill.md',
132
+ 'commands/apt-bootstrap.md',
133
+ 'commands/apt-caveman.md',
134
+ 'commands/apt-classify.md',
135
+ 'commands/apt-close-task.md',
136
+ 'commands/apt-create-docs.md',
137
+ 'commands/apt-debug.md',
138
+ 'commands/apt-design.md',
139
+ 'commands/apt-diagram.md',
140
+ 'commands/apt-discuss.md',
141
+ 'commands/apt-docs.md',
142
+ 'commands/apt-execute.md',
143
+ 'commands/apt-fan-out.md',
144
+ 'commands/apt-handoff.md',
145
+ 'commands/apt-improve.md',
146
+ 'commands/apt-mockup.md',
147
+ 'commands/apt-pause.md',
148
+ 'commands/apt-personas.md',
149
+ 'commands/apt-plan.md',
150
+ 'commands/apt-pr-review.md',
151
+ 'commands/apt-prototype.md',
152
+ 'commands/apt-quick.md',
153
+ 'commands/apt-release-notes.md',
154
+ 'commands/apt-resume.md',
155
+ 'commands/apt-review.md',
156
+ 'commands/apt-roadmap.md',
157
+ 'commands/apt-roundtable.md',
158
+ 'commands/apt-run.md',
159
+ 'commands/apt-scan.md',
160
+ 'commands/apt-setup.md',
161
+ 'commands/apt-ship.md',
162
+ 'commands/apt-spar.md',
163
+ 'commands/apt-stress-test.md',
164
+ 'commands/apt-terminal.md',
165
+ 'commands/apt-triage.md',
166
+ 'commands/apt-update.md',
167
+ 'commands/apt-verify.md',
168
+ 'commands/apt-verify-proof.md',
169
+ 'commands/apt-watch-ci.md',
170
+ 'commands/apt-zoom-out.md',
171
+ // agents/<basename>.md — packages/framework/agents/apt-*.md (17 files)
172
+ // (overlap with skills/apt-*.md top-level — same outputPath, de-dupe)
173
+ 'agents/apt-docs-author.md',
174
+ 'agents/apt-executor.md',
175
+ 'agents/apt-improver.md',
176
+ 'agents/apt-planner.md',
177
+ 'agents/apt-pr-review-codebase-fit.md',
178
+ 'agents/apt-pr-review-fixer.md',
179
+ 'agents/apt-pr-review-logic.md',
180
+ 'agents/apt-pr-review-performance.md',
181
+ 'agents/apt-pr-review-quality.md',
182
+ 'agents/apt-pr-review-security.md',
183
+ 'agents/apt-pr-review-self-reviewer.md',
184
+ 'agents/apt-pr-review-test-integrity.md',
185
+ 'agents/apt-pr-review-validator.md',
186
+ 'agents/apt-researcher.md',
187
+ 'agents/apt-reviewer.md',
188
+ 'agents/apt-team-docs-narrator.md',
189
+ 'agents/apt-verifier.md',
67
190
  ]),
68
191
  }),
69
192
  })
@@ -30,9 +30,7 @@ import { MANIFEST_FILENAME } from './manifest.mjs'
30
30
  * @property {string|null} cliId The `cli` string `detectHost()` returns
31
31
  * when this runtime's CLI is at the prompt.
32
32
  * `null` when the runtime has no install
33
- * target mapped to a host CLI (e.g. `pi`,
34
- * which has a detectable host but no apt
35
- * install root of its own).
33
+ * target mapped to a host CLI.
36
34
  * @property {string} [displayLabel] Optional user-facing label (e.g. "Kilo Code").
37
35
  * When unset, callers fall back to the
38
36
  * capitalized form of `id`. Use for runtimes
@@ -52,7 +50,7 @@ export const RUNTIMES = Object.freeze([
52
50
  {
53
51
  id: 'codex',
54
52
  flag: '--codex',
55
- installRoot: '.codex',
53
+ installRoot: '.agents',
56
54
  markers: ['.codex/config.toml'],
57
55
  cliId: 'codex',
58
56
  },
@@ -77,6 +75,13 @@ export const RUNTIMES = Object.freeze([
77
75
  markers: ['.opencode/config.json'],
78
76
  cliId: 'opencode',
79
77
  },
78
+ {
79
+ id: 'pi',
80
+ flag: '--pi',
81
+ installRoot: '.pi',
82
+ markers: ['.pi/settings.json', '.pi/skills', '.pi/prompts'],
83
+ cliId: 'pi',
84
+ },
80
85
  {
81
86
  id: 'kilo',
82
87
  flag: '--kilo',
@@ -2,15 +2,14 @@
2
2
  * install/runtime-migrate.mjs — at-install cleanup of legacy install
3
3
  * trees the framework no longer owns (FRAMEWORK-BUG-021).
4
4
  *
5
- * Codex was originally installed into `.agents/skills/` (commit 1a8dd8a8)
6
- * and later moved to `.codex/`. Projects that upgraded across that move
7
- * end up with a stale `.agents/skills/` tree that:
8
- *
9
- * - keeps `.apt-version` on disk the legacy fallback in
10
- * `readSkillInstallState` reports a stale codex install.
11
- * - shows up in `health-check` as `stale-skills`.
12
- * - leaves dozens of orphaned SKILL.md files the runtime no longer
13
- * reads.
5
+ * Codex shuffled install roots twice:
6
+ * - Pre-0.7: installed at `.agents/skills/` (commit 1a8dd8a8).
7
+ * - v0.7/v0.8: moved to `.codex/agents/` + `.codex/commands/` a
8
+ * misdirect, since Codex CLI 0.132.0 doesn't discover skills there.
9
+ * - v0.8.2 (this fix): moved back to `.agents/skills/<folder>/SKILL.md`
10
+ * (Codex's documented surface). The v0.7/v0.8 `.codex/` markdown
11
+ * tree is now the legacy target — `LEGACY_INSTALL_PATHS.codex` was
12
+ * re-pointed accordingly.
14
13
  *
15
14
  * `runLegacyCleanup` runs once per `apt-tools init` when codex is in the
16
15
  * requested runtime set. It is conservative by default:
@@ -20,8 +19,11 @@
20
19
  * preserved. If anything beyond the known framework set remains,
21
20
  * `retained[]` lists those paths.
22
21
  * - A present-and-current `apt-file-manifest.json` is treated as the
23
- * authoritative "this is a managed install, leave it alone" signal:
24
- * the function no-ops with `reason: 'managed'`.
22
+ * authoritative "this is a managed install, leave it alone" signal
23
+ * — but ONLY when the legacy entry has `honor_manifest: true` (the
24
+ * default). When `honor_manifest: false` (the current codex entry,
25
+ * because `.codex/` is known-dead), the manifest is removed alongside
26
+ * framework files.
25
27
  * - The caller can suppress cleanup entirely via `--keep-legacy` at the
26
28
  * init.mjs site; the function itself is dumb about flags.
27
29
  */
@@ -33,7 +35,8 @@ import { MANIFEST_FILENAME } from './manifest.mjs'
33
35
 
34
36
  /**
35
37
  * @typedef {Object} LegacyCodexDetection
36
- * @property {boolean} present True when `.agents/skills/` exists.
38
+ * @property {boolean} present True when the legacy install_root
39
+ * (currently `.codex/`) exists.
37
40
  * @property {string[]} frameworkFiles Subset of `framework_files` that
38
41
  * actually exist on disk (relative
39
42
  * to install_root).
@@ -46,9 +49,15 @@ import { MANIFEST_FILENAME } from './manifest.mjs'
46
49
  * stamp is present.
47
50
  * @property {boolean} hasManifest Whether an
48
51
  * `apt-file-manifest.json` is
49
- * present at install_root (signals
50
- * a managed install — cleanup
51
- * should no-op).
52
+ * present at install_root. When the
53
+ * legacy entry has
54
+ * `honor_manifest: true` (default)
55
+ * this signals a managed install
56
+ * and cleanup no-ops; when
57
+ * `honor_manifest: false` the
58
+ * manifest is treated as orphan
59
+ * and removed alongside framework
60
+ * files.
52
61
  */
53
62
 
54
63
  const LEGACY = LEGACY_INSTALL_PATHS.codex
@@ -93,7 +102,9 @@ function walkRelative(dir) {
93
102
  }
94
103
 
95
104
  /**
96
- * Probe the codex legacy install tree at `<targetDir>/.agents/skills/`.
105
+ * Probe the codex legacy install tree at `<targetDir>/<LEGACY.install_root>`
106
+ * (currently `.codex/` after the v0.8.2 registry inversion — the v0.7/v0.8
107
+ * misdirect topology).
97
108
  *
98
109
  * @param {string} targetDir
99
110
  * @returns {LegacyCodexDetection}
@@ -142,25 +153,36 @@ function rmEmptyDir(dir) {
142
153
  }
143
154
 
144
155
  /**
145
- * Clean up the legacy `.agents/skills/` tree if it looks orphaned.
156
+ * Clean up the legacy install tree at `<targetDir>/<LEGACY.install_root>`
157
+ * if it looks orphaned. Post v0.8.2 the codex legacy root is `.codex/`
158
+ * with framework files at `agents/<file>.md` + `commands/<file>.md` +
159
+ * `apt-file-manifest.json`.
146
160
  *
147
161
  * Branches:
148
162
  * 1. `present: false` OR `frameworkFiles.length === 0` → no-op,
149
163
  * `{ ran: false, reason: 'no-legacy' }`.
150
- * 2. `hasManifest: true` managed install, no-op,
151
- * `{ ran: false, reason: 'managed' }`.
164
+ * 2. `hasManifest: true` AND `LEGACY.honor_manifest !== false`
165
+ * (default true) managed install, no-op,
166
+ * `{ ran: false, reason: 'managed' }`. When `honor_manifest: false`
167
+ * (known-dead surface like the v0.7/v0.8 codex misdirect) the
168
+ * manifest is treated as orphan and removed alongside framework
169
+ * files.
152
170
  * 3. Otherwise: per-file `unlinkSync` each framework-owned file;
153
- * `rmdirSync` any now-empty `apt-*` subdirectory; sweep
154
- * `.agents/skills/` only if it is empty; sweep `.agents/` only if
155
- * its `skills/` got removed and `.agents/` is empty.
171
+ * `rmdirSync` any subdirectory left empty after the unlinks (e.g.
172
+ * `.codex/agents/`, `.codex/commands/`); sweep the install_root
173
+ * itself only if it is fully empty after the per-file pass; sweep
174
+ * the install_root's parent only if it too became empty (relevant
175
+ * for legacy topologies two levels deep, e.g. the pre-0.7
176
+ * `.agents/skills/` codex layout).
156
177
  *
157
178
  * Returns `{ ran: true, removed, retained, rmdirs }` on the cleanup
158
179
  * branch:
159
180
  * - `removed` — relative paths under `install_root` that were unlinked.
160
181
  * - `retained` — relative paths under `install_root` that were NOT
161
- * removed (user-added skills / files not in the legacy set).
162
- * - `rmdirs` — absolute paths of directories that were removed
163
- * (apt-* subdirs, the install_root itself, .agents/), in removal order.
182
+ * removed (user-added skills / files not in the legacy set, e.g.
183
+ * `.codex/config.toml`).
184
+ * - `rmdirs` — absolute paths of directories that were removed,
185
+ * in removal order.
164
186
  *
165
187
  * Atomicity: per-file unlink is non-atomic. A partial-failure scenario
166
188
  * (process killed mid-loop) is tolerable — the next `init` run will
@@ -178,7 +200,14 @@ export function runLegacyCleanup({ targetDir, dryRun = false }) {
178
200
  if (!detection.present || detection.frameworkFiles.length === 0) {
179
201
  return { ran: false, reason: 'no-legacy' }
180
202
  }
181
- if (detection.hasManifest) {
203
+ // `honor_manifest: false` means the legacy install_root is a known-dead
204
+ // surface (the v0.7/v0.8 codex misdirect). A manifest sitting there is
205
+ // by definition stale — fall through and remove it alongside framework
206
+ // files. `honor_manifest: true` (default) preserves the managed-install
207
+ // safety for legacy roots that could legitimately re-host a managed
208
+ // install.
209
+ const honorManifest = LEGACY.honor_manifest !== false
210
+ if (detection.hasManifest && honorManifest) {
182
211
  return { ran: false, reason: 'managed' }
183
212
  }
184
213
 
@@ -233,12 +262,16 @@ export function runLegacyCleanup({ targetDir, dryRun = false }) {
233
262
  if (rmEmptyDir(abs)) rmdirs.push(abs)
234
263
  }
235
264
 
236
- // Sweep `.agents/skills/` only if fully empty after the per-file
237
- // pass — preserves any user-added skill dirs.
265
+ // Sweep the legacy install_root only if fully empty after the per-file
266
+ // pass — preserves any user-added content under it (e.g. `.codex/config.toml`
267
+ // when LEGACY.install_root is `.codex/`).
238
268
  if (rmEmptyDir(installRoot)) {
239
269
  rmdirs.push(installRoot)
240
- // Sweep `.agents/` only if it became empty too (i.e. no other
241
- // `.agents/<sibling>` content the user keeps there).
270
+ // Sweep the install_root's parent only if it became empty too
271
+ // (relevant for legacy topologies whose install_root sits two
272
+ // levels deep, e.g. the pre-0.7 `.agents/skills/` codex layout).
273
+ // No-op when install_root is a top-level dir like `.codex/` —
274
+ // rmEmptyDir refuses to remove a non-empty project root.
242
275
  const agentsRoot = dirname(installRoot)
243
276
  if (rmEmptyDir(agentsRoot)) rmdirs.push(agentsRoot)
244
277
  }
@@ -2,13 +2,18 @@
2
2
  * install/transforms/codex.mjs — Codex transform.
3
3
  *
4
4
  * Codex quirks:
5
- * - frontmatter strips `tools` and `color` (Codex validates strictly and
6
- * rejects unknown/style-only keys).
5
+ * - frontmatter is whitelisted to `KEEP = {name, description}` (Codex
6
+ * validates strictly against its `allowed_properties` set and rejects
7
+ * unknown keys; the whitelist is drift-proof against new framework
8
+ * frontmatter keys).
7
9
  * - body is wrapped in <codex_agent_role>…</codex_agent_role>.
8
10
  * - slash-command refs `/apt:foo` rewritten to `/apt-foo` (Codex command
9
11
  * names disallow `:`).
10
- * - output: .codex/agents/<name>.md AND .codex/commands/<name>.md (some
11
- * skills register both as agent + invocable command).
12
+ * - output: skills/<folder>/SKILL.md (the documented Codex discovery
13
+ * surface per https://developers.openai.com/codex/skills resolved
14
+ * against installRoot `.agents` to land at `.agents/skills/<folder>/SKILL.md`).
15
+ * Markdown agents are NOT a Codex surface (custom-agents are TOML
16
+ * under `.codex/agents/`); only skills are emitted.
12
17
  */
13
18
 
14
19
  import { basename, dirname } from 'node:path'
@@ -16,11 +21,16 @@ import {
16
21
  parseFrontmatter,
17
22
  rewriteCommandRefs,
18
23
  serializeFrontmatter,
19
- stripFields,
20
24
  substituteVersion,
21
25
  } from './_shared.mjs'
22
26
 
23
- const STRIP = ['tools', 'color']
27
+ // Codex's `allowed_properties` set (see
28
+ // ~/.codex/skills/.system/skill-creator/scripts/quick_validate.py:40):
29
+ // {"name", "description", "license", "allowed-tools", "metadata"}.
30
+ // We use the minimum viable whitelist {name, description} so adding new
31
+ // framework frontmatter keys (a routine occurrence) doesn't break Codex
32
+ // validation — only the 2 keys Codex actually consumes are emitted.
33
+ const KEEP = ['name', 'description']
24
34
 
25
35
  /**
26
36
  * @param {import('../pipeline.mjs').TransformInput} input
@@ -31,7 +41,10 @@ export function transform({ canonicalContent, canonicalRelPath, version, fileTyp
31
41
  const parsed = parseFrontmatter(subbed)
32
42
  let payload
33
43
  if (parsed.hasFrontmatter && parsed.fm) {
34
- stripFields(parsed.fm, STRIP)
44
+ // Whitelist filter: drop every frontmatter key NOT in KEEP.
45
+ for (const k of Object.keys(parsed.fm)) {
46
+ if (!KEEP.includes(k)) delete parsed.fm[k]
47
+ }
35
48
  const wrappedBody = `<codex_agent_role>\n${parsed.body}\n</codex_agent_role>\n`
36
49
  payload = serializeFrontmatter({ ...parsed, body: wrappedBody })
37
50
  } else {
@@ -41,16 +54,12 @@ export function transform({ canonicalContent, canonicalRelPath, version, fileTyp
41
54
 
42
55
  if (fileType === 'skill') {
43
56
  const folder = basename(dirname(canonicalRelPath))
44
- // Skills emit BOTH an agent definition (for invocation context) and a
45
- // command (so the user can type `/apt-foo` directly in Codex).
46
- return [
47
- { outputPath: `agents/${folder}.md`, content: payload },
48
- { outputPath: `commands/${folder}.md`, content: payload },
49
- ]
50
- }
51
- if (fileType === 'agent') {
52
- const file = basename(canonicalRelPath, '.md')
53
- return [{ outputPath: `agents/${file}.md`, content: payload }]
57
+ // Codex's documented skill discovery surface is `.agents/skills/<folder>/SKILL.md`
58
+ // (one folder per skill, canonical SKILL.md filename).
59
+ return [{ outputPath: `skills/${folder}/SKILL.md`, content: payload }]
54
60
  }
61
+ // Markdown agents are not a Codex surface. Codex custom-agents are TOML
62
+ // under `.codex/agents/`; emitting markdown there would just create
63
+ // another dead surface. Drop the agent branch entirely.
55
64
  return []
56
65
  }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * install/transforms/pi.mjs — Pi coding agent transform.
3
+ *
4
+ * Pi uses prompt templates under `.pi/prompts/` for slash commands and
5
+ * root-level skills under `.pi/skills/`. Unlike Codex, Pi supports
6
+ * colon-form prompt names, so `/apt:foo` references are preserved.
7
+ */
8
+
9
+ import { basename, dirname } from 'node:path'
10
+ import { substituteVersion } from './_shared.mjs'
11
+
12
+ function promptNameForSkill(folder) {
13
+ if (folder === 'apt') return 'apt'
14
+ if (folder.startsWith('apt-')) return `apt:${folder.slice('apt-'.length)}`
15
+ return folder
16
+ }
17
+
18
+ /**
19
+ * @param {import('../pipeline.mjs').TransformInput} input
20
+ * @returns {import('../pipeline.mjs').TransformOutput[]}
21
+ */
22
+ export function transform({ canonicalContent, canonicalRelPath, version, fileType }) {
23
+ const content = substituteVersion(canonicalContent, version)
24
+ if (fileType === 'skill') {
25
+ const folder = basename(dirname(canonicalRelPath))
26
+ const promptName = promptNameForSkill(folder)
27
+ return [
28
+ { outputPath: `skills/${folder}/SKILL.md`, content },
29
+ { outputPath: `prompts/${promptName}.md`, content },
30
+ ]
31
+ }
32
+ if (fileType === 'agent') {
33
+ const file = basename(canonicalRelPath)
34
+ return [{ outputPath: `skills/${file}`, content }]
35
+ }
36
+ return []
37
+ }
@@ -164,9 +164,9 @@ export const SkillFrontmatterSchema = z
164
164
  // don't immediately break skills that carry them.
165
165
  triggers: z.array(z.string()).optional(),
166
166
  color: z.string().optional(),
167
- // Pocock adoption ST-13 (AC12): optional `produces:` field enumerates
167
+ // ST-13 (AC12): optional `produces:` field enumerates
168
168
  // the content-formats a skill emits (e.g. "PRD-shaped spec.md",
169
- // "vertical-slice subtasks", "Pocock-format CONTEXT.md term-block").
169
+ // "vertical-slice subtasks", "Aperant CONTEXT.md term-block").
170
170
  // Consumed by `apt-tools modes list` to surface what each skill ships.
171
171
  // Additive and backward-compatible — skills without the field default
172
172
  // to [] in modes list output.
File without changes
@@ -0,0 +1,55 @@
1
+ /**
2
+ * audit.mjs — append-only JSONL audit log for driver invocations.
3
+ *
4
+ * ID-05: one file per day at .aperant/events/{YYYY-MM-DD}.jsonl.
5
+ * One line per driver invocation:
6
+ * {ts, driver_id, version, manifest_sha256, trust_tier, sandbox_profile,
7
+ * decision: "allow|deny|requires_approval",
8
+ * result: "success|fail|skip"}
9
+ *
10
+ * Append-only — no rewrites. Each appendDriverEvent() opens the file in
11
+ * 'a' mode and writes a single line; concurrent agents may interleave
12
+ * lines but no line is ever overwritten.
13
+ */
14
+
15
+ import { appendFileSync, mkdirSync } from 'node:fs'
16
+ import { dirname, join, resolve } from 'node:path'
17
+
18
+ /**
19
+ * Compute today's events filename relative to projectDir.
20
+ * @param {string} projectDir
21
+ * @param {Date} [now]
22
+ * @returns {string}
23
+ */
24
+ export function dailyEventsPath(projectDir, now = new Date()) {
25
+ const yyyy = now.getUTCFullYear()
26
+ const mm = String(now.getUTCMonth() + 1).padStart(2, '0')
27
+ const dd = String(now.getUTCDate()).padStart(2, '0')
28
+ return join(resolve(projectDir), '.aperant/events', `${yyyy}-${mm}-${dd}.jsonl`)
29
+ }
30
+
31
+ /**
32
+ * Append a driver-invocation audit line.
33
+ *
34
+ * @param {string} projectDir
35
+ * @param {Object} entry
36
+ * @param {string} entry.driver_id
37
+ * @param {string} entry.version
38
+ * @param {string} entry.manifest_sha256
39
+ * @param {string} entry.trust_tier
40
+ * @param {string} entry.sandbox_profile
41
+ * @param {'allow' | 'deny' | 'requires_approval'} entry.decision
42
+ * @param {'success' | 'fail' | 'skip'} entry.result
43
+ * @param {string} [entry.verb] — IDL verb invoked (optional metadata)
44
+ * @param {string} [entry.reason] — decision-rationale string (optional)
45
+ */
46
+ export function appendDriverEvent(projectDir, entry) {
47
+ const path = dailyEventsPath(projectDir)
48
+ mkdirSync(dirname(path), { recursive: true })
49
+ const line = JSON.stringify({
50
+ ts: new Date().toISOString(),
51
+ kind: 'driver_invocation',
52
+ ...entry,
53
+ })
54
+ appendFileSync(path, line + '\n', 'utf-8')
55
+ }