@apexops/kernel 0.10.0-next.4 → 0.11.0-next.0

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 (66) hide show
  1. package/README.md +28 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/directory-lock.d.ts +118 -0
  4. package/dist/directory-lock.d.ts.map +1 -0
  5. package/dist/directory-lock.js +587 -0
  6. package/dist/directory-lock.js.map +1 -0
  7. package/dist/files.d.ts +63 -0
  8. package/dist/files.d.ts.map +1 -1
  9. package/dist/files.js +158 -2
  10. package/dist/files.js.map +1 -1
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/object-store.js +2 -2
  16. package/dist/object-store.js.map +1 -1
  17. package/dist/project-store.d.ts +2 -1
  18. package/dist/project-store.d.ts.map +1 -1
  19. package/dist/project-store.js +1 -0
  20. package/dist/project-store.js.map +1 -1
  21. package/dist/repeat-files.d.ts +66 -0
  22. package/dist/repeat-files.d.ts.map +1 -0
  23. package/dist/repeat-files.js +214 -0
  24. package/dist/repeat-files.js.map +1 -0
  25. package/dist/repeat-guard.d.ts +197 -0
  26. package/dist/repeat-guard.d.ts.map +1 -0
  27. package/dist/repeat-guard.js +462 -0
  28. package/dist/repeat-guard.js.map +1 -0
  29. package/dist/review-capture.d.ts +170 -0
  30. package/dist/review-capture.d.ts.map +1 -0
  31. package/dist/review-capture.js +570 -0
  32. package/dist/review-capture.js.map +1 -0
  33. package/dist/run-repository.d.ts +52 -2
  34. package/dist/run-repository.d.ts.map +1 -1
  35. package/dist/run-repository.js +198 -52
  36. package/dist/run-repository.js.map +1 -1
  37. package/dist/tasks.d.ts.map +1 -1
  38. package/dist/tasks.js +24 -2
  39. package/dist/tasks.js.map +1 -1
  40. package/dist/test/files.test.d.ts +2 -0
  41. package/dist/test/files.test.d.ts.map +1 -0
  42. package/dist/test/files.test.js +140 -0
  43. package/dist/test/files.test.js.map +1 -0
  44. package/dist/test/policies.test.js +1 -1
  45. package/dist/test/policies.test.js.map +1 -1
  46. package/dist/test/repeat-guard.test.d.ts +2 -0
  47. package/dist/test/repeat-guard.test.d.ts.map +1 -0
  48. package/dist/test/repeat-guard.test.js +1106 -0
  49. package/dist/test/repeat-guard.test.js.map +1 -0
  50. package/dist/test/review-capture.test.d.ts +2 -0
  51. package/dist/test/review-capture.test.d.ts.map +1 -0
  52. package/dist/test/review-capture.test.js +291 -0
  53. package/dist/test/review-capture.test.js.map +1 -0
  54. package/dist/test/run-repository.test.js +451 -7
  55. package/dist/test/run-repository.test.js.map +1 -1
  56. package/dist/test/workflow.test.js +32 -1
  57. package/dist/test/workflow.test.js.map +1 -1
  58. package/dist/test/writer-transfer.test.js +6 -1
  59. package/dist/test/writer-transfer.test.js.map +1 -1
  60. package/dist/validator-registry.d.ts.map +1 -1
  61. package/dist/validator-registry.js +10 -1
  62. package/dist/validator-registry.js.map +1 -1
  63. package/dist/workflow-validator-ownership.d.ts.map +1 -1
  64. package/dist/workflow-validator-ownership.js +2 -1
  65. package/dist/workflow-validator-ownership.js.map +1 -1
  66. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-capture.d.ts","sourceRoot":"","sources":["../src/review-capture.ts"],"names":[],"mappings":"AAKA,OAAO,EAAkD,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAI1G;;;;;;;;GAQG;AAEH,eAAO,MAAM,qBAAqB,EAAG,wBAAiC,CAAC;AACvE,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AACnD,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AACjD,eAAO,MAAM,YAAY,gBAAgB,CAAC;AAC1C,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,eAAe,qBAAqB,CAAC;AAClD,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAKhD,QAAA,MAAM,UAAU,YAAI,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAU,CAAC;AAC1E,QAAA,MAAM,OAAO,YACX,UAAU,EACV,aAAa,EACb,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,CAChB,CAAC;AACX,QAAA,MAAM,QAAQ,YAAI,MAAM,EAAE,SAAS,EAAE,gBAAgB,CAAU,CAAC;AAIhE,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT,WAAW,GACX,WAAW,GACX,WAAW,GACX,iBAAiB,GACjB,gBAAgB,GAChB,iBAAiB,GACjB,aAAa,GACb,gBAAgB,CAAC;AAErB,2GAA2G;AAC3G,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAEtC,YAAY,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAIxD;CACF;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AACzD,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpD,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,cAAc,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzF,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,WAAW,EAAE,YAAY,CAAC;QAC1B,OAAO,EAAE,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;QACnC,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,cAAc,GAAG,SAAS,GAAG,OAAO,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,0HAA0H;AAC1H,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,qGAAqG;AACrG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAO5D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,kGAAkG;AAClG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOxE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAiCtE;AAED,kFAAkF;AAClF,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA8CnE;AAkBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,eAAe,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CAmFvG;AAED,sHAAsH;AACtH,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAOvE;AAyDD,gHAAgH;AAChH,eAAO,MAAM,2BAA2B,QAAsB,CAAC;AAE/D;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,SAAe,EACnB,GAAG,SAAa,EAChB,QAAQ,SAA8B,EACtC,cAAc,GAAE,WAAW,CAAC,MAAM,CAAa,GAC9C,OAAO,CAAC,MAAM,CAAC,CAajB;AAaD,oHAAoH;AACpH,wBAAsB,gBAAgB,CAAC,IAAI,SAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA0B3E;AAED,KAAK,eAAe,GAAG,IAAI,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC;AAEhE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE;IACL,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,EACD,GAAG,EAAE,MAAM,GACV,qBAAqB,CAgBvB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,gBAAgB,CAAC,GAAG,MAAM,CAE7G;AAED,8GAA8G;AAC9G,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAmBtF;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,KAAK,EAAE,OAAO,CAAC;IACf,gGAAgG;IAChG,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,8BAA8B,oCAAoC,CAAC;AAEhF;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,8BAA8B,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,uHAAuH;AACvH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CAQxF;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,SAAS,iBAAiB,EAAE,EACnC,IAAI,SAAe,GAClB,OAAO,CAAC;IAAE,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAwBnF;AAED,2GAA2G;AAC3G,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAe,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAiBzG;AAID;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBjG;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,gBAAgB,EAAE,MAAM,GAAG,QAAQ,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAclH;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qHAAqH;AACrH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,CAWnF;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,KAAK,EAAE,SAAS,iBAAiB,EAAE,EACnC,GAAG,EAAE,MAAM,GACV,qBAAqB,CAWvB"}
@@ -0,0 +1,570 @@
1
+ import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { link, lstat, mkdir, open, readdir, realpath, rename, rm } from "node:fs/promises";
4
+ import { homedir } from "node:os";
5
+ import { basename, dirname, isAbsolute, join, resolve } from "node:path";
6
+ import { ReviewCaptureV1Schema, registerContractFormats } from "@apexops/contracts";
7
+ import { Value } from "@sinclair/typebox/value";
8
+ import { canonicalJson, sha256Bytes, sha256Text } from "./canonical.js";
9
+ /**
10
+ * Captured rubber-duck reviews (DECISION-031). The kernel issues a review request with a single-use nonce and a prompt;
11
+ * the APEX agent passes the prompt unchanged to the built-in `rubber-duck` agent; the managed `postToolUse` hook saves
12
+ * the prompt and rubber-duck's exact output in a signed capture record outside the workspace. The kernel verifies the
13
+ * record, binds it to the issued prompt and the reviewed artifact, and derives findings only from the captured output.
14
+ *
15
+ * The hook (plugin/hooks/apex-hook.mjs) is dependency-free, so it repeats the record format, canonical JSON, HMAC and
16
+ * location rules below; tools/tests/vnext/plugin-hooks.test.mjs keeps both sides aligned.
17
+ */
18
+ export const REVIEW_CAPTURE_SCHEMA = "apex-review-capture-v1";
19
+ export const REVIEW_REQUEST_HEADER = "APEX-REVIEW";
20
+ export const REVIEW_ANSWER_FENCE = "apex-review";
21
+ export const REVIEW_AGENT = "rubber-duck";
22
+ export const REVIEW_MAX_ATTEMPTS = 2;
23
+ export const REVIEW_HOME_ENV = "APEX_REVIEW_HOME";
24
+ export const REVIEW_MAX_FINDINGS = 50;
25
+ /**
26
+ * Budget for all finding titles and details together, measured as doubly JSON-escaped UTF-8 because an MCP result
27
+ * carries its JSON once as structured content and once as escaped text. nextTask returns every open finding in one
28
+ * result capped at 64 KiB, so the findings must fit there with their IDs and actions.
29
+ */
30
+ export const REVIEW_MAX_FINDINGS_BYTES = 20_480;
31
+ const NONCE_PATTERN = /^[0-9a-f]{32}$/u;
32
+ const SHA256_PATTERN = /^[0-9a-f]{64}$/u;
33
+ const FINDING_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
34
+ const SEVERITIES = ["critical", "high", "medium", "low", "info"];
35
+ const PILLARS = [
36
+ "security",
37
+ "reliability",
38
+ "performance-efficiency",
39
+ "cost-optimization",
40
+ "operational-excellence",
41
+ ];
42
+ const OUTCOMES = ["pass", "finding", "not-applicable"];
43
+ const TASK_TOOLS = new Set(["task", "Task", "Agent"]);
44
+ const MAX_CAPTURE_BYTES = 1024 * 1024;
45
+ /** A capture problem. Every reason fails the review closed; only `missing` leaves the request reusable. */
46
+ export class ReviewCaptureError extends Error {
47
+ reason;
48
+ constructor(reason, message) {
49
+ super(message);
50
+ this.name = "ReviewCaptureError";
51
+ this.reason = reason;
52
+ }
53
+ }
54
+ /**
55
+ * The review home (or a folder in it) is not private to this OS user: another user could replace the capture key or
56
+ * inject captures, so nothing in it can be trusted until its owner and mode are fixed.
57
+ */
58
+ export class ReviewHomeError extends Error {
59
+ constructor(message) {
60
+ super(message);
61
+ this.name = "ReviewHomeError";
62
+ }
63
+ }
64
+ /** A fresh nonce, or one derived from a unique seed (the service's ID source) so deterministic runs stay reproducible. */
65
+ export function createReviewNonce(seed) {
66
+ return seed === undefined ? randomBytes(16).toString("hex") : sha256Text(`apex-review-nonce\0${seed}`).slice(0, 32);
67
+ }
68
+ /** Line endings and trailing whitespace do not change a prompt's identity; every other byte does. */
69
+ export function normalizeReviewPrompt(prompt) {
70
+ return prompt
71
+ .replace(/\r\n?/gu, "\n")
72
+ .split("\n")
73
+ .map((line) => line.replace(/[ \t]+$/u, ""))
74
+ .join("\n")
75
+ .replace(/\n+$/u, "");
76
+ }
77
+ export function reviewPromptSha256(prompt) {
78
+ return sha256Text(normalizeReviewPrompt(prompt));
79
+ }
80
+ /** The nonce from the first non-empty prompt line `APEX-REVIEW: nonce=<32 hex>`, or undefined. */
81
+ export function reviewNonceFromPrompt(prompt) {
82
+ const first = prompt
83
+ .replace(/^\uFEFF/u, "")
84
+ .split(/\r?\n/u)
85
+ .find((line) => line.trim().length > 0);
86
+ const match = /^APEX-REVIEW:\s+nonce=([0-9a-f]{32})\s*$/u.exec(first?.trim() ?? "");
87
+ return match?.[1];
88
+ }
89
+ export function buildReviewPrompt(request) {
90
+ if (!NONCE_PATTERN.test(request.nonce))
91
+ throw new TypeError("Review nonce must be 32 lowercase hex characters");
92
+ if (request.files.filter(({ label }) => label === "subject").length !== 1)
93
+ throw new TypeError("Review prompt needs exactly one subject file");
94
+ for (const file of request.files) {
95
+ if (!isAbsolute(file.path) || /[\r\n]/u.test(file.path))
96
+ throw new TypeError("Review files need absolute paths");
97
+ if (!SHA256_PATTERN.test(file.sha256))
98
+ throw new TypeError("Review file hashes must be SHA-256");
99
+ }
100
+ const shape = request.wellArchitected
101
+ ? '{"findings":[{"id":"F-1","severity":"high","title":"...","detail":"..."}],"criteria":[{"criterionId":"security","outcome":"finding","rationale":"...","findingIds":["F-1"]}]}'
102
+ : '{"findings":[{"id":"F-1","severity":"high","title":"...","detail":"..."}]}';
103
+ return [
104
+ `${REVIEW_REQUEST_HEADER}: nonce=${request.nonce}`,
105
+ "",
106
+ `Review the APEX ${request.subjectKind} artifact for Gate ${request.gate} as an independent critic.`,
107
+ "Only read files. Do not call APEX tools, edit files, run commands or ask the user.",
108
+ "",
109
+ "Read these files with the view tool. Each sha256 is the hash of the file content.",
110
+ ...request.files.map((file) => `- ${file.label} (${file.kind}): ${file.path} sha256=${file.sha256}`),
111
+ "",
112
+ "Follow the instructions file. Reply with exactly one fenced code block whose info string is",
113
+ `${REVIEW_ANSWER_FENCE} and whose content is one JSON object in this shape:`,
114
+ shape,
115
+ `severity is one of ${SEVERITIES.join(", ")}. Use "findings": [] when there are no problems.`,
116
+ `Report at most ${REVIEW_MAX_FINDINGS} findings and keep all titles and details together under ` +
117
+ `${Math.floor(REVIEW_MAX_FINDINGS_BYTES / 2048)} KB; merge related problems.`,
118
+ ...(request.wellArchitected
119
+ ? [
120
+ `Give exactly one criteria entry for each pillar: ${PILLARS.join(", ")}.`,
121
+ `outcome is one of ${OUTCOMES.join(", ")}.`,
122
+ ]
123
+ : []),
124
+ ].join("\n");
125
+ }
126
+ /** Reviewer guidance per subject, carried over from the retired APEX Reviewer. */
127
+ export function buildReviewInstructions(subjectKind) {
128
+ const common = [
129
+ "# APEX rubber-duck review",
130
+ "",
131
+ "Run an adversarial, evidence-linked review of the subject file. Use the input files only as evidence.",
132
+ "Test completeness, contradictions, traceability, evidence freshness, security and governance, reliability and",
133
+ "operations, and cost and scale. Return one finding per real issue with a concise title and a detail that states",
134
+ "the evidence, the impact and a concrete remediation. Do not manufacture findings to fill a quota.",
135
+ "",
136
+ "Missing or unverified performance or scale targets, measurement boundaries or feasibility are validated later.",
137
+ "Report at most one info finding titled `Check later: performance and scale validation` for them, never a higher",
138
+ "severity. Availability and recovery targets, including RTO and RPO, are real findings when missing, contradictory",
139
+ "or infeasible.",
140
+ ];
141
+ const specific = {
142
+ requirements: [
143
+ "",
144
+ "## Requirements",
145
+ "",
146
+ "Missing named owners, latency measurement details, access, ingress and DNS design details, and GDPR lifecycle",
147
+ "planning are advisory when documented as proposed recommendations; do not report blocking findings or owner",
148
+ "assignment requests only because those recommendations are unconfirmed. Concrete contradictions, violated",
149
+ "Azure Policy constraints, required security decisions and missing stage-required evidence remain findings.",
150
+ ],
151
+ architecture: [
152
+ "",
153
+ "## Architecture",
154
+ "",
155
+ "Assume regional and zonal support, quota, deployment feasibility, restore and failover checks are non-issues.",
156
+ "Explicit partial pricing is valid cost documentation. APEX builds the hosting platform: application",
157
+ "functionality such as business workflows, approval paths or application data-lifecycle rules is out of scope.",
158
+ "Check the policy map: each enforcing finding maps to a component with a plausible property and disposition,",
159
+ "`blocked` rows are findings, and every `not-applicable` reason is consistent with the design.",
160
+ "",
161
+ "Return one criteria entry for each Well-Architected pillar. Link `finding` outcomes to finding IDs, explain every",
162
+ "`pass` or `not-applicable` outcome, and use `not-applicable` only where the accepted assessment says so.",
163
+ ],
164
+ plan: [
165
+ "",
166
+ "## Implementation plan",
167
+ "",
168
+ "Check that the implementation intent, IaC binding and environment inputs cover every accepted architecture",
169
+ "component, that dependencies are acyclic and that governance and policy obligations carry into the plan.",
170
+ ],
171
+ };
172
+ return [...common, ...(specific[subjectKind] ?? []), ""].join("\n");
173
+ }
174
+ function isPlainObject(value) {
175
+ return value !== null && typeof value === "object" && !Array.isArray(value);
176
+ }
177
+ function boundedText(value, field, max) {
178
+ if (typeof value !== "string" || value.trim().length === 0 || value.length > max)
179
+ throw new ReviewCaptureError("unparseable", `Review answer ${field} must be text of 1 to ${max} characters`);
180
+ return value.trim();
181
+ }
182
+ function exactKeys(value, allowed, field) {
183
+ const unknown = Object.keys(value).filter((key) => !allowed.includes(key));
184
+ if (unknown.length > 0)
185
+ throw new ReviewCaptureError("unparseable", `Review answer ${field} has unsupported fields: ${unknown.join(", ")}`);
186
+ }
187
+ /**
188
+ * Derives findings from rubber-duck's captured output: exactly one ```apex-review fenced JSON block, checked strictly.
189
+ * Text outside the block is ignored. Findings without an id get F-1, F-2, ... in answer order.
190
+ */
191
+ export function parseReviewAnswer(response, options) {
192
+ const fence = /^[ \t]*(`{3,}|~{3,})[ \t]*apex-review[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*\1[ \t]*$/gmu;
193
+ const blocks = [...response.matchAll(fence)];
194
+ if (blocks.length !== 1)
195
+ throw new ReviewCaptureError("unparseable", `Review answer must contain exactly one ${REVIEW_ANSWER_FENCE} block; found ${blocks.length}`);
196
+ let value;
197
+ try {
198
+ value = JSON.parse(blocks[0][2]);
199
+ }
200
+ catch (error) {
201
+ throw new ReviewCaptureError("unparseable", `Review answer JSON is invalid: ${error.message}`);
202
+ }
203
+ if (!isPlainObject(value))
204
+ throw new ReviewCaptureError("unparseable", "Review answer must be a JSON object");
205
+ exactKeys(value, options.wellArchitected ? ["findings", "criteria"] : ["findings"], "object");
206
+ if (!Array.isArray(value.findings) || value.findings.length > REVIEW_MAX_FINDINGS)
207
+ throw new ReviewCaptureError("unparseable", `Review answer findings must be an array of at most ${REVIEW_MAX_FINDINGS}`);
208
+ const findings = value.findings.map((finding, index) => {
209
+ if (!isPlainObject(finding))
210
+ throw new ReviewCaptureError("unparseable", "Each review finding must be an object");
211
+ exactKeys(finding, ["id", "severity", "title", "detail"], `finding ${index + 1}`);
212
+ const id = finding.id === undefined ? `F-${index + 1}` : finding.id;
213
+ if (typeof id !== "string" || !FINDING_ID_PATTERN.test(id))
214
+ throw new ReviewCaptureError("unparseable", `Review finding ${index + 1} has an invalid id`);
215
+ if (!SEVERITIES.includes(finding.severity))
216
+ throw new ReviewCaptureError("unparseable", `Review finding ${id} severity must be one of ${SEVERITIES.join(", ")}`);
217
+ return {
218
+ id,
219
+ severity: finding.severity,
220
+ title: boundedText(finding.title, `finding ${id} title`, 300),
221
+ detail: boundedText(finding.detail, `finding ${id} detail`, 8_000),
222
+ };
223
+ });
224
+ const findingBytes = findings.reduce((total, { title, detail }) => total + Buffer.byteLength(JSON.stringify(JSON.stringify([title, detail]))), 0);
225
+ if (findingBytes > REVIEW_MAX_FINDINGS_BYTES)
226
+ throw new ReviewCaptureError("unparseable", `Review findings use ${findingBytes} bytes of titles and details; the limit is ${REVIEW_MAX_FINDINGS_BYTES}`);
227
+ const ids = findings.map(({ id }) => id);
228
+ if (new Set(ids).size !== ids.length)
229
+ throw new ReviewCaptureError("unparseable", "Review finding ids must be unique");
230
+ if (!options.wellArchitected)
231
+ return { findings };
232
+ if (!Array.isArray(value.criteria) || value.criteria.length !== PILLARS.length)
233
+ throw new ReviewCaptureError("unparseable", "Review answer criteria must cover the five Well-Architected pillars");
234
+ const criteria = value.criteria.map((criterion) => {
235
+ if (!isPlainObject(criterion))
236
+ throw new ReviewCaptureError("unparseable", "Each criteria entry must be an object");
237
+ exactKeys(criterion, ["criterionId", "outcome", "rationale", "findingIds"], "criteria entry");
238
+ if (!PILLARS.includes(criterion.criterionId))
239
+ throw new ReviewCaptureError("unparseable", `Criteria entry pillar must be one of ${PILLARS.join(", ")}`);
240
+ if (!OUTCOMES.includes(criterion.outcome))
241
+ throw new ReviewCaptureError("unparseable", `Criteria outcome must be one of ${OUTCOMES.join(", ")}`);
242
+ const findingIds = criterion.findingIds ?? [];
243
+ if (!Array.isArray(findingIds) ||
244
+ findingIds.some((id) => typeof id !== "string" || !ids.includes(id)) ||
245
+ new Set(findingIds).size !== findingIds.length)
246
+ throw new ReviewCaptureError("unparseable", `Criteria ${String(criterion.criterionId)} links unknown findings`);
247
+ if (criterion.outcome !== "finding" && findingIds.length > 0)
248
+ throw new ReviewCaptureError("unparseable", `Criteria ${String(criterion.criterionId)} links findings, which only a finding outcome may do`);
249
+ return {
250
+ criterionId: criterion.criterionId,
251
+ outcome: criterion.outcome,
252
+ rationale: boundedText(criterion.rationale, `criteria ${String(criterion.criterionId)} rationale`, 4_000),
253
+ findingIds: findingIds,
254
+ };
255
+ });
256
+ if (new Set(criteria.map(({ criterionId }) => criterionId)).size !== PILLARS.length)
257
+ throw new ReviewCaptureError("unparseable", "Review answer criteria must name each pillar once");
258
+ return { findings, criteria };
259
+ }
260
+ /** Folder shared by the hook and the kernel: `$APEX_REVIEW_HOME`, else `~/.apex/reviews`. Outside every workspace. */
261
+ export function reviewHome(env = process.env) {
262
+ const configured = env[REVIEW_HOME_ENV];
263
+ if (configured !== undefined && configured.length > 0) {
264
+ if (!isAbsolute(configured))
265
+ throw new Error(`${REVIEW_HOME_ENV} must be an absolute path`);
266
+ return resolve(configured);
267
+ }
268
+ return join(homedir(), ".apex", "reviews");
269
+ }
270
+ async function plainDirectory(path, create) {
271
+ const stat = await lstat(path).catch((error) => {
272
+ if (error.code === "ENOENT")
273
+ return undefined;
274
+ throw error;
275
+ });
276
+ if (stat === undefined) {
277
+ if (!create)
278
+ return false;
279
+ await mkdir(path, { recursive: true, mode: 0o700 });
280
+ return plainDirectory(path, false);
281
+ }
282
+ if (stat.isSymbolicLink() || !stat.isDirectory())
283
+ throw new Error(`Review folder is not a plain directory: ${path}`);
284
+ if (process.platform !== "win32" && typeof process.getuid === "function") {
285
+ if (stat.uid !== process.getuid())
286
+ throw new ReviewHomeError(`Review folder is owned by another user: ${path}; it must belong to you`);
287
+ if ((stat.mode & 0o022) !== 0)
288
+ throw new ReviewHomeError(`Review folder is writable by other users: ${path}; run chmod 700 on it`);
289
+ await assertTrustedAncestors(path);
290
+ }
291
+ return true;
292
+ }
293
+ /** An ancestor another user cannot use to rename the review home away: owned by you or root, and not writable by
294
+ * group or others unless it is sticky (as /tmp is). */
295
+ async function assertTrustedFolder(path) {
296
+ const stat = await lstat(path);
297
+ const uid = process.getuid();
298
+ if ((stat.uid !== uid && stat.uid !== 0) || ((stat.mode & 0o022) !== 0 && (stat.mode & 0o1000) === 0))
299
+ throw new ReviewHomeError(`A folder above the review home lets another user replace it: ${path}; ` +
300
+ "set APEX_REVIEW_HOME inside a folder only you (or root) can change");
301
+ }
302
+ /**
303
+ * Rename and delete authority over a folder belongs to its parent, so every real ancestor of the review folder must be
304
+ * trusted, and so must the folder holding each symbolic link in the configured path, which decides where it resolves.
305
+ */
306
+ async function assertTrustedAncestors(path) {
307
+ const real = await realpath(path);
308
+ for (let current = dirname(real);; current = dirname(current)) {
309
+ await assertTrustedFolder(current);
310
+ if (dirname(current) === current)
311
+ break;
312
+ }
313
+ for (let prefix = dirname(resolve(path)); dirname(prefix) !== prefix; prefix = dirname(prefix)) {
314
+ const info = await lstat(prefix);
315
+ if (info.isSymbolicLink()) {
316
+ const holder = await realpath(dirname(prefix));
317
+ for (let current = holder;; current = dirname(current)) {
318
+ await assertTrustedFolder(current);
319
+ if (dirname(current) === current)
320
+ break;
321
+ }
322
+ }
323
+ }
324
+ }
325
+ /** Captures older than this belong to requests that expired (tasks live 24 hours) and can never be ingested. */
326
+ export const REVIEW_CAPTURE_RETENTION_MS = 48 * 60 * 60 * 1000;
327
+ /**
328
+ * Removes captures whose request can no longer be ingested, so abandoned reviews do not keep model output in the
329
+ * shared review home forever: captures older than the retention, and captures whose nonce the caller knows was used
330
+ * (completed, rejected or cancelled) but whose removal failed earlier. Captures for live requests stay. Returns the
331
+ * count removed.
332
+ */
333
+ export async function sweepReviewCaptures(home = reviewHome(), now = Date.now(), maxAgeMs = REVIEW_CAPTURE_RETENTION_MS, consumedNonces = new Set()) {
334
+ const directory = join(home, "captures");
335
+ if (!(await plainDirectory(home, false)) || !(await plainDirectory(directory, false)))
336
+ return 0;
337
+ let removed = 0;
338
+ for (const name of await readdir(directory)) {
339
+ if (!name.endsWith(".json"))
340
+ continue;
341
+ const path = join(directory, name);
342
+ const info = await lstat(path).catch(() => undefined);
343
+ if (info === undefined || !info.isFile())
344
+ continue;
345
+ if (now - info.mtimeMs <= maxAgeMs && !consumedNonces.has(name.slice(0, 32)))
346
+ continue;
347
+ if ((await removeReviewCaptures([{ path, value: undefined }])).length === 0)
348
+ removed += 1;
349
+ }
350
+ return removed;
351
+ }
352
+ async function readRegularFile(path, maxBytes) {
353
+ const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
354
+ try {
355
+ const stat = await handle.stat();
356
+ if (!stat.isFile() || stat.size > maxBytes)
357
+ throw new Error(`Not a bounded regular file: ${path}`);
358
+ return await handle.readFile();
359
+ }
360
+ finally {
361
+ await handle.close();
362
+ }
363
+ }
364
+ /** The per-user HMAC key (32 random bytes, hex) shared with the hook; created with 0600 permissions when absent. */
365
+ export async function reviewCaptureKey(home = reviewHome()) {
366
+ await plainDirectory(home, true);
367
+ const path = join(home, "capture.key");
368
+ // Publish a fully written key through a hard link, which never replaces an existing key: the first writer wins and
369
+ // no reader can see an empty or partial key. The hook uses the same protocol.
370
+ const temporary = join(home, `.${randomBytes(8).toString("hex")}.tmp`);
371
+ const handle = await open(temporary, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY, 0o600);
372
+ try {
373
+ await handle.writeFile(`${randomBytes(32).toString("hex")}\n`);
374
+ }
375
+ finally {
376
+ await handle.close();
377
+ }
378
+ try {
379
+ await link(temporary, path);
380
+ }
381
+ catch (error) {
382
+ if (error.code !== "EEXIST")
383
+ throw error;
384
+ }
385
+ finally {
386
+ await rm(temporary, { force: true });
387
+ }
388
+ const info = await lstat(path);
389
+ if (info.isSymbolicLink() || !info.isFile())
390
+ throw new Error(`Review capture key is not a regular file: ${path}`);
391
+ if (process.platform !== "win32" && (info.mode & 0o077) !== 0)
392
+ throw new Error(`Review capture key permissions must be 0600: ${path}`);
393
+ const text = (await readRegularFile(path, 1024)).toString("utf8").trim();
394
+ if (!/^[0-9a-f]{64}$/u.test(text))
395
+ throw new Error(`Review capture key is malformed: ${path}`);
396
+ return Buffer.from(text, "hex");
397
+ }
398
+ export function reviewCaptureSignature(record, key) {
399
+ return createHmac("sha256", key).update(canonicalJson(record)).digest("hex");
400
+ }
401
+ /** Builds a signed record exactly as the hook does. Used by tests and the hook parity check. */
402
+ export function signReviewCapture(input, key) {
403
+ const nonce = reviewNonceFromPrompt(input.prompt);
404
+ if (nonce === undefined)
405
+ throw new TypeError("Review prompt has no APEX-REVIEW nonce");
406
+ const record = {
407
+ schema: REVIEW_CAPTURE_SCHEMA,
408
+ nonce,
409
+ sessionId: input.sessionId ?? null,
410
+ toolName: input.toolName ?? "task",
411
+ agentType: input.agentType ?? REVIEW_AGENT,
412
+ prompt: input.prompt,
413
+ requestSha256: sha256Text(input.prompt),
414
+ response: input.response,
415
+ responseSha256: sha256Text(input.response),
416
+ capturedAt: input.capturedAt,
417
+ };
418
+ return { ...record, signature: reviewCaptureSignature(record, key) };
419
+ }
420
+ export function reviewCaptureFileName(record) {
421
+ return `${record.nonce}-${record.responseSha256.slice(0, 16)}.json`;
422
+ }
423
+ /** Checks one record's shape, signature, hashes and rubber-duck origin. Does not check the issued request. */
424
+ export function verifyReviewCapture(value, key) {
425
+ registerContractFormats();
426
+ if (!Value.Check(ReviewCaptureV1Schema, value))
427
+ throw new ReviewCaptureError("malformed", "Review capture record is malformed");
428
+ const record = value;
429
+ const { signature, ...unsigned } = record;
430
+ const expected = Buffer.from(reviewCaptureSignature(unsigned, key), "hex");
431
+ if (!timingSafeEqual(expected, Buffer.from(signature, "hex")))
432
+ throw new ReviewCaptureError("signature", "Review capture signature does not verify; the record was edited or forged");
433
+ if (sha256Text(record.prompt) !== record.requestSha256 || sha256Text(record.response) !== record.responseSha256)
434
+ throw new ReviewCaptureError("signature", "Review capture hashes do not match its prompt or response");
435
+ if (!TASK_TOOLS.has(record.toolName) || record.agentType.trim().toLowerCase() !== REVIEW_AGENT)
436
+ throw new ReviewCaptureError("not-rubber-duck", "Review capture is not from a rubber-duck task call");
437
+ if (reviewNonceFromPrompt(record.prompt) !== record.nonce)
438
+ throw new ReviewCaptureError("nonce-mismatch", "Review capture nonce does not match its prompt header");
439
+ return record;
440
+ }
441
+ export const REJECTED_REVIEW_CAPTURE_SCHEMA = "apex.rejected-review-capture.v1";
442
+ /** Wraps capture bytes for the object store, or returns undefined when they are not valid UTF-8 (quarantine those). */
443
+ export function rejectedReviewCapture(bytes) {
444
+ let content;
445
+ try {
446
+ content = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
447
+ }
448
+ catch {
449
+ return undefined;
450
+ }
451
+ return { schema: REJECTED_REVIEW_CAPTURE_SCHEMA, sha256: sha256Bytes(bytes), bytes: bytes.byteLength, content };
452
+ }
453
+ /**
454
+ * Moves captures that could not be archived (oversized, unreadable, not UTF-8 or not regular files) into `quarantine/` in the
455
+ * review home, so the only copy of rejected evidence is kept for inspection rather than deleted.
456
+ */
457
+ export async function quarantineReviewCaptures(files, home = reviewHome()) {
458
+ const result = {
459
+ quarantined: [],
460
+ failed: [],
461
+ };
462
+ if (files.length === 0)
463
+ return result;
464
+ const directory = join(home, "quarantine");
465
+ try {
466
+ await plainDirectory(directory, true);
467
+ }
468
+ catch {
469
+ result.failed.push(...files.map(({ path }) => basename(path)));
470
+ return result;
471
+ }
472
+ for (const { path } of files) {
473
+ const name = basename(path);
474
+ const target = join(directory, `${randomBytes(4).toString("hex")}-${name}`);
475
+ try {
476
+ await rename(path, target);
477
+ result.quarantined.push({ name, path: target });
478
+ }
479
+ catch {
480
+ result.failed.push(name);
481
+ }
482
+ }
483
+ return result;
484
+ }
485
+ /** Reads every capture file for a nonce. Unreadable or non-JSON files are returned as malformed values. */
486
+ export async function loadReviewCaptures(nonce, home = reviewHome()) {
487
+ if (!NONCE_PATTERN.test(nonce))
488
+ throw new TypeError("Review nonce must be 32 lowercase hex characters");
489
+ const directory = join(home, "captures");
490
+ if (!(await plainDirectory(home, false)) || !(await plainDirectory(directory, false)))
491
+ return [];
492
+ const names = (await readdir(directory)).filter((name) => name.startsWith(`${nonce}-`) && name.endsWith(".json"));
493
+ const files = [];
494
+ for (const name of names.sort()) {
495
+ const path = join(directory, name);
496
+ let bytes;
497
+ try {
498
+ bytes = await readRegularFile(path, MAX_CAPTURE_BYTES);
499
+ files.push({ path, value: JSON.parse(bytes.toString("utf8")), bytes });
500
+ }
501
+ catch {
502
+ files.push({ path, value: undefined, ...(bytes === undefined ? {} : { bytes }) });
503
+ }
504
+ }
505
+ return files;
506
+ }
507
+ const TRANSIENT_REMOVE_ERRORS = new Set(["EBUSY", "EPERM", "EACCES", "EMFILE", "ENFILE"]);
508
+ /**
509
+ * Removes ingested, rejected or cancelled captures, retrying transient errors (a scanner or indexer holding the file on
510
+ * Windows). Returns the paths that still could not be removed; `sweepReviewCaptures` removes them on a later call.
511
+ */
512
+ export async function removeReviewCaptures(files) {
513
+ const failed = [];
514
+ for (const { path } of files) {
515
+ for (let attempt = 1;; attempt += 1) {
516
+ try {
517
+ await rm(path, { force: true });
518
+ break;
519
+ }
520
+ catch (error) {
521
+ if (attempt < 5 && TRANSIENT_REMOVE_ERRORS.has(error.code ?? "")) {
522
+ await new Promise((settle) => setTimeout(settle, 25 * attempt));
523
+ continue;
524
+ }
525
+ failed.push(path);
526
+ break;
527
+ }
528
+ }
529
+ }
530
+ return failed;
531
+ }
532
+ /**
533
+ * Rehashes the files a review prompt lists. Rubber-duck reads these files, so a missing, replaced or edited file means
534
+ * its answer may not be about the issued request; that fails closed.
535
+ */
536
+ export async function verifyReviewFiles(files) {
537
+ for (const file of files) {
538
+ let bytes;
539
+ try {
540
+ bytes = await readRegularFile(file.path, 16 * 1024 * 1024);
541
+ }
542
+ catch {
543
+ throw new ReviewCaptureError("inputs-changed", `Review input file is missing or not a regular file: ${file.path}`);
544
+ }
545
+ if (sha256Bytes(bytes) !== file.sha256)
546
+ throw new ReviewCaptureError("inputs-changed", `Review input file changed after the request: ${file.path}`);
547
+ }
548
+ }
549
+ /** Missing and ambiguous checks, which need no key, so an unwritable review home still reports a missing capture. */
550
+ export function assertSingleReviewCapture(files) {
551
+ if (files.length === 0)
552
+ throw new ReviewCaptureError("missing", "No rubber-duck capture exists for this review request; run rubber-duck in sync mode with the exact prompt");
553
+ if (files.length > 1)
554
+ throw new ReviewCaptureError("ambiguous", `${files.length} rubber-duck captures exist for one review request; each request allows exactly one run`);
555
+ }
556
+ /**
557
+ * Selects and verifies the capture for an issued request. Exactly one capture may exist for the nonce, and its prompt
558
+ * must be the issued prompt (line endings and trailing whitespace aside). Two captures mean rubber-duck ran twice for
559
+ * one request, so the agent could pick a favourable answer; that fails closed.
560
+ */
561
+ export function verifyIssuedReviewCapture(request, files, key) {
562
+ assertSingleReviewCapture(files);
563
+ const record = verifyReviewCapture(files[0].value, key);
564
+ if (record.nonce !== request.nonce)
565
+ throw new ReviewCaptureError("nonce-mismatch", "Review capture belongs to a different review request");
566
+ if (reviewPromptSha256(record.prompt) !== request.promptSha256)
567
+ throw new ReviewCaptureError("prompt-mismatch", "Rubber-duck received a prompt that differs from the issued review prompt");
568
+ return record;
569
+ }
570
+ //# sourceMappingURL=review-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-capture.js","sourceRoot":"","sources":["../src/review-capture.ts"],"names":[],"mappings":"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"}