0sec-cli 0.15.0 → 0.18.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 (209) hide show
  1. package/0sec.js +327 -0
  2. package/README.md +68 -48
  3. package/attacks/data-exfiltration/pii-leakage.yaml +27 -0
  4. package/attacks/encoding-bypass/base64-encoding.yaml +24 -0
  5. package/attacks/jailbreak/dan-roleplay.yaml +27 -0
  6. package/attacks/jailbreak/hypothetical-scenario.yaml +25 -0
  7. package/attacks/jailbreak/multilingual-bypass.yaml +22 -0
  8. package/attacks/output-manipulation/harmful-content.yaml +25 -0
  9. package/attacks/prompt-injection/context-manipulation.yaml +32 -0
  10. package/attacks/prompt-injection/direct-injection.yaml +28 -0
  11. package/attacks/prompt-injection/indirect-injection.yaml +33 -0
  12. package/attacks/system-prompt-extraction/direct-ask.yaml +30 -0
  13. package/attacks/system-prompt-extraction/markdown-exfil.yaml +26 -0
  14. package/attacks/tool-misuse/ssrf-via-tools.yaml +27 -0
  15. package/chunks/adapt-loop-SMH6V4PD.js +18 -0
  16. package/chunks/adgraph-JLGA6RYI.js +54 -0
  17. package/chunks/agent/skills/frameworks/entra-id.yaml +63 -0
  18. package/chunks/agent/skills/frameworks/graphql-introspection.yaml +116 -0
  19. package/chunks/agent/skills/frameworks/nextjs.yaml +82 -0
  20. package/chunks/agent/skills/frameworks/python-web.yaml +85 -0
  21. package/chunks/agent/skills/frameworks/supabase.yaml +83 -0
  22. package/chunks/agent/skills/frameworks/wordpress-deep.yaml +122 -0
  23. package/chunks/agent/skills/techniques/ad-attack-paths.yaml +57 -0
  24. package/chunks/agent/skills/techniques/advisory-disclosure.yaml +59 -0
  25. package/chunks/agent/skills/techniques/assumption-mining.yaml +53 -0
  26. package/chunks/agent/skills/techniques/blind-exploitation.yaml +143 -0
  27. package/chunks/agent/skills/techniques/crypto-misuse.yaml +88 -0
  28. package/chunks/agent/skills/techniques/cve-poc-adaptation.yaml +82 -0
  29. package/chunks/agent/skills/techniques/entra-attack-paths.yaml +55 -0
  30. package/chunks/agent/skills/techniques/http-conformance-diff.yaml +48 -0
  31. package/chunks/agent/skills/techniques/jwt-attacks.yaml +137 -0
  32. package/chunks/agent/skills/techniques/kernel-weaponization.yaml +53 -0
  33. package/chunks/agent/skills/techniques/llm-excessive-agency.yaml +55 -0
  34. package/chunks/agent/skills/techniques/llm-insecure-output-handling.yaml +56 -0
  35. package/chunks/agent/skills/techniques/llm-prompt-injection.yaml +54 -0
  36. package/chunks/agent/skills/techniques/llm-prompt-layer-write.yaml +68 -0
  37. package/chunks/agent/skills/techniques/llm-rag-poisoning.yaml +57 -0
  38. package/chunks/agent/skills/techniques/llm-safety-eval.yaml +51 -0
  39. package/chunks/agent/skills/techniques/npm-ecosystem.yaml +51 -0
  40. package/chunks/agent/skills/techniques/poc-verification.yaml +55 -0
  41. package/chunks/agent/skills/techniques/race-condition.yaml +122 -0
  42. package/chunks/agent/skills/techniques/scoped-fix.yaml +49 -0
  43. package/chunks/agent/skills/techniques/seedless-depth-review.yaml +59 -0
  44. package/chunks/agent/skills/techniques/spec-differential.yaml +48 -0
  45. package/chunks/agent/skills/techniques/variant-hunting.yaml +55 -0
  46. package/chunks/agent/skills/vulnerabilities/cardano-eutxo-validators.yaml +72 -0
  47. package/chunks/agent/skills/vulnerabilities/command-injection.yaml +99 -0
  48. package/chunks/agent/skills/vulnerabilities/deserialization-chains.yaml +106 -0
  49. package/chunks/agent/skills/vulnerabilities/native-memory-safety.yaml +93 -0
  50. package/chunks/agent/skills/vulnerabilities/path-traversal.yaml +78 -0
  51. package/chunks/agent/skills/vulnerabilities/prototype-pollution.yaml +132 -0
  52. package/chunks/agent/skills/vulnerabilities/request-smuggling.yaml +129 -0
  53. package/chunks/agent/skills/vulnerabilities/sqli-advanced.yaml +102 -0
  54. package/chunks/agent/skills/vulnerabilities/ssrf-bypass.yaml +84 -0
  55. package/chunks/agent/skills/vulnerabilities/ssti-exploitation.yaml +112 -0
  56. package/chunks/agent/skills/vulnerabilities/structural-sqli.yaml +91 -0
  57. package/chunks/appsec-catalog-CBWHGTEL.js +24 -0
  58. package/chunks/artifact-scraper-HQ7HLP6V.js +34 -0
  59. package/chunks/assumption-mining-5SNIVVDN.js +79 -0
  60. package/chunks/chunk-242TMK6G.js +110 -0
  61. package/chunks/chunk-2JCCA2JL.js +381 -0
  62. package/chunks/chunk-2RMLOJVB.js +47 -0
  63. package/chunks/chunk-3KPWWJCI.js +1422 -0
  64. package/chunks/chunk-3MOLBTLS.js +953 -0
  65. package/chunks/chunk-53G27VPS.js +136 -0
  66. package/chunks/chunk-57ZENEX2.js +169 -0
  67. package/chunks/chunk-5G3ZXFBW.js +182 -0
  68. package/chunks/chunk-5JI7L7KV.js +74240 -0
  69. package/chunks/chunk-6L26OBWI.js +1094 -0
  70. package/chunks/chunk-6LKRLK2R.js +542 -0
  71. package/chunks/chunk-72CISA2D.js +2597 -0
  72. package/chunks/chunk-7DQEV5QI.js +287 -0
  73. package/chunks/chunk-AD7WXDH6.js +3250 -0
  74. package/chunks/chunk-ADOLI6DT.js +102 -0
  75. package/chunks/chunk-AHTBZC3E.js +596 -0
  76. package/chunks/chunk-ASUR522M.js +518 -0
  77. package/chunks/chunk-ATATQACO.js +471 -0
  78. package/chunks/chunk-BATRQBOR.js +1732 -0
  79. package/chunks/chunk-BFR2CDV5.js +5735 -0
  80. package/chunks/chunk-BFRB6HB2.js +235 -0
  81. package/chunks/chunk-BKZFDZ23.js +361 -0
  82. package/chunks/chunk-BVAZO4WA.js +193 -0
  83. package/chunks/chunk-BZNEY2ZS.js +33225 -0
  84. package/chunks/chunk-C2WXWFBB.js +1070 -0
  85. package/chunks/chunk-CMKXP5RR.js +917 -0
  86. package/chunks/chunk-DW5UWPFY.js +275 -0
  87. package/chunks/chunk-F3WBKITT.js +687 -0
  88. package/chunks/chunk-GMT2AZKM.js +2439 -0
  89. package/chunks/chunk-H2FFLZNK.js +3 -0
  90. package/chunks/chunk-IOL7D5YV.js +515 -0
  91. package/chunks/chunk-IR537GON.js +49 -0
  92. package/chunks/chunk-JQHOLLTD.js +3729 -0
  93. package/chunks/chunk-KLTNTE2Z.js +121 -0
  94. package/chunks/chunk-LP3HHYQU.js +245 -0
  95. package/chunks/chunk-MYVT64FN.js +16 -0
  96. package/chunks/chunk-N7BOUYEV.js +852 -0
  97. package/chunks/chunk-OEFNRYI2.js +150 -0
  98. package/chunks/chunk-P6WKNFWX.js +1968 -0
  99. package/chunks/chunk-QI233I24.js +333 -0
  100. package/chunks/chunk-RJWOYEOG.js +271 -0
  101. package/chunks/chunk-RRMJC3ZE.js +105 -0
  102. package/chunks/chunk-RWONANDA.js +973 -0
  103. package/chunks/chunk-SAFFWQW4.js +5921 -0
  104. package/chunks/chunk-SF4KZ4O3.js +502 -0
  105. package/chunks/chunk-SVJEDVYK.js +808 -0
  106. package/chunks/chunk-TSK2AG6J.js +5108 -0
  107. package/chunks/chunk-U5FLXGHT.js +2010 -0
  108. package/chunks/chunk-UCYRA73C.js +662 -0
  109. package/chunks/chunk-UR4ELX2Y.js +4784 -0
  110. package/chunks/chunk-VQG4FT5D.js +685 -0
  111. package/chunks/chunk-WEBMRWEG.js +9337 -0
  112. package/chunks/chunk-WU6AFRAZ.js +1167 -0
  113. package/chunks/chunk-WVTBZEQO.js +1531 -0
  114. package/chunks/chunk-WXQ6BJ6A.js +596 -0
  115. package/chunks/chunk-XM5NLHYU.js +600 -0
  116. package/chunks/chunk-YLMN3N25.js +4054 -0
  117. package/chunks/chunk-YYRBQVFE.js +2572 -0
  118. package/chunks/chunk-Z5FA2XOX.js +2798 -0
  119. package/chunks/commands-TBC2F5CE.js +16999 -0
  120. package/chunks/corpus-v1.json +403 -0
  121. package/chunks/cost-ledger-NU63MYZM.js +13 -0
  122. package/chunks/data/appsec-archetypes.json +102 -0
  123. package/chunks/data/chromium-archetypes.json +204 -0
  124. package/chunks/data/freebsd-archetypes.json +171 -0
  125. package/chunks/data/kernel-archetypes.json +611 -0
  126. package/chunks/db-KFWOAUUB.js +16 -0
  127. package/chunks/disclose-EKTWSCGW.js +132 -0
  128. package/chunks/dist-4MAW5X6L.js +74 -0
  129. package/chunks/dist-4YICS2J2.js +2776 -0
  130. package/chunks/dist-FMGSR3DW.js +159 -0
  131. package/chunks/eval-runner-7ZF472KV.js +27 -0
  132. package/chunks/example-manifest.json +95 -0
  133. package/chunks/exploit-agent-45YQOHPJ.js +98 -0
  134. package/chunks/exploit-autoclimb-UZGEMGYT.js +81 -0
  135. package/chunks/exploit-climb-SG23KB2G.js +358 -0
  136. package/chunks/fix-IG7LYXH3.js +12 -0
  137. package/chunks/github-issues-MJ6OYOOU.js +157 -0
  138. package/chunks/harness-7ODOLOWU.js +22 -0
  139. package/chunks/http-conformance-DU66MZIU.js +11 -0
  140. package/chunks/http-sender-GWH2IYEA.js +10 -0
  141. package/chunks/hunt-scan-MMKUOETU.js +38 -0
  142. package/chunks/identity-6ZAIIWOR.js +191 -0
  143. package/chunks/kernel-primitive-7U6CWHXD.js +44 -0
  144. package/chunks/kernel-vm-runner-3JAU4O6J.js +62 -0
  145. package/chunks/memsafety-scan-J7SECV5W.js +16 -0
  146. package/chunks/native-loop-RJCJPOUS.js +54 -0
  147. package/chunks/npm-detectors-KB5Y5ZFX.js +69 -0
  148. package/chunks/npm-dynamic-discovery-AHROOZDB.js +13 -0
  149. package/chunks/orchestrate-OC2VZN2X.js +62 -0
  150. package/chunks/pipeline-BZK5BLJR.js +14 -0
  151. package/chunks/pre-recon-cve-66EB6G4M.js +351 -0
  152. package/chunks/prepare-MYY743TK.js +13 -0
  153. package/chunks/process-LQRCS5OY.js +13 -0
  154. package/chunks/replay-runner-45G3VU7X.js +39 -0
  155. package/chunks/run-D56MPDKY.js +32716 -0
  156. package/chunks/runtime-G7YWIO3B.js +43 -0
  157. package/chunks/runtime-J7PLXZNM.js +12 -0
  158. package/chunks/scan-stream-FHI2FYZE.js +96 -0
  159. package/chunks/scope-BI7BF4ZY.js +18 -0
  160. package/chunks/session-store-GZ4A4KYT.js +28 -0
  161. package/chunks/source-files-PWRQR6LY.js +12 -0
  162. package/chunks/specdrift-WCLH6TTQ.js +19 -0
  163. package/chunks/variant-candidates-YERCYMPD.js +13 -0
  164. package/chunks/web-recon-prepass-JJGPEOLE.js +1148 -0
  165. package/dashboard/assets/0sec-icon-66SreztZ.gif +0 -0
  166. package/dashboard/assets/bot-yILPnRgD.js +1 -0
  167. package/dashboard/assets/chevron-down-BeDJ-Vka.js +1 -0
  168. package/dashboard/assets/circle-alert-BEnMBMT-.js +1 -0
  169. package/dashboard/assets/client-DRYsuOGl.js +9 -0
  170. package/dashboard/assets/copy-Bi5vzoF9.js +1 -0
  171. package/dashboard/assets/desktop-CXTQonNm.js +32 -0
  172. package/dashboard/assets/desktop-NOekk4QS.css +1 -0
  173. package/dashboard/assets/dist-CmX-h7a4.js +1 -0
  174. package/dashboard/assets/dist-DAwYQmf_.js +45 -0
  175. package/dashboard/assets/findings-page-CACW9nw2.js +5 -0
  176. package/dashboard/assets/format-PoISqsES.js +1 -0
  177. package/dashboard/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  178. package/dashboard/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  179. package/dashboard/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  180. package/dashboard/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  181. package/dashboard/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  182. package/dashboard/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
  183. package/dashboard/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
  184. package/dashboard/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
  185. package/dashboard/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
  186. package/dashboard/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  187. package/dashboard/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  188. package/dashboard/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
  189. package/dashboard/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
  190. package/dashboard/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
  191. package/dashboard/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
  192. package/dashboard/assets/jsx-runtime-C7oxC63R.js +1 -0
  193. package/dashboard/assets/live-page-DrgQqQK5.js +1 -0
  194. package/dashboard/assets/meta-tile-CcskIV_o.js +1 -0
  195. package/dashboard/assets/operations-BKE8T-vY.css +2 -0
  196. package/dashboard/assets/operations-D8nUP5_m.js +4 -0
  197. package/dashboard/assets/operations-app-CQQhG54n.js +2 -0
  198. package/dashboard/assets/overview-page-DTGS8dPo.js +1 -0
  199. package/dashboard/assets/page-header-MFVvEtZW.js +1 -0
  200. package/dashboard/assets/play-Dwo-9xt6.js +1 -0
  201. package/dashboard/assets/scans-page-ChVtq8Us.js +1 -0
  202. package/dashboard/assets/search-CiooTLck.js +1 -0
  203. package/dashboard/assets/siren-CCBwTSuk.js +1 -0
  204. package/dashboard/assets/table-BYS-nIVA.js +1 -0
  205. package/dashboard/assets/tabs-DivxbhQy.js +1 -0
  206. package/dashboard/desktop.html +21 -0
  207. package/dashboard/index.html +15 -0
  208. package/package.json +30 -18
  209. package/bin/0sec.cjs +0 -361
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __0secCreateRequire } from "node:module";
3
+ const require = __0secCreateRequire(import.meta.url);
@@ -0,0 +1,515 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __0secCreateRequire } from "node:module";
3
+ const require = __0secCreateRequire(import.meta.url);
4
+ import {
5
+ external_exports
6
+ } from "./chunk-YLMN3N25.js";
7
+
8
+ // packages/core/dist/protocol/http-conformance.js
9
+ import { randomUUID } from "node:crypto";
10
+
11
+ // packages/core/dist/protocol/conformance-gen.js
12
+ var REQUIREMENT_LEVELS = [
13
+ "MUST",
14
+ "MUST NOT",
15
+ "SHOULD",
16
+ "SHOULD NOT",
17
+ "MAY"
18
+ ];
19
+ var HTTP_SURFACES = ["method", "header", "status"];
20
+ var httpExerciseSchema = external_exports.object({
21
+ method: external_exports.string().min(1),
22
+ path: external_exports.string().optional(),
23
+ headers: external_exports.record(external_exports.string()).optional(),
24
+ body: external_exports.string().optional()
25
+ }).strict();
26
+ var conformanceRuleSchema = external_exports.object({
27
+ id: external_exports.string().min(1),
28
+ specCitation: external_exports.string().min(1),
29
+ level: external_exports.enum(REQUIREMENT_LEVELS),
30
+ surface: external_exports.enum(HTTP_SURFACES),
31
+ mandate: external_exports.string().min(1),
32
+ exercise: httpExerciseSchema
33
+ }).strict();
34
+ var predictionSchema = external_exports.object({
35
+ surface: external_exports.enum(HTTP_SURFACES),
36
+ expectedStatusIn: external_exports.array(external_exports.number().int()).optional(),
37
+ forbiddenStatusIn: external_exports.array(external_exports.number().int()).optional(),
38
+ requiredHeader: external_exports.string().optional(),
39
+ forbiddenHeader: external_exports.string().optional(),
40
+ whenStatusIn: external_exports.array(external_exports.number().int()).optional(),
41
+ unlessStatusIn: external_exports.array(external_exports.number().int()).optional()
42
+ }).strict().refine((p) => p.expectedStatusIn && p.expectedStatusIn.length > 0 || p.forbiddenStatusIn && p.forbiddenStatusIn.length > 0 || Boolean(p.requiredHeader) || Boolean(p.forbiddenHeader), { message: "predictedObservable carries no matcher (status set or header)" }).refine((p) => {
43
+ if (!p.expectedStatusIn || !p.forbiddenStatusIn)
44
+ return true;
45
+ const forbidden = new Set(p.forbiddenStatusIn);
46
+ return !p.expectedStatusIn.some((s) => forbidden.has(s));
47
+ }, {
48
+ message: "predictedObservable has overlapping expectedStatusIn and forbiddenStatusIn (a status cannot be both conformant and a violation)"
49
+ });
50
+ var divergenceHypothesisSchema = external_exports.object({
51
+ ruleId: external_exports.string().min(1),
52
+ specCitation: external_exports.string().min(1),
53
+ level: external_exports.enum(REQUIREMENT_LEVELS),
54
+ implLocation: external_exports.string().min(1),
55
+ rationale: external_exports.string().min(1),
56
+ predictedObservable: predictionSchema,
57
+ exercise: httpExerciseSchema,
58
+ confidence: external_exports.number().min(0).max(1)
59
+ }).strict();
60
+ var conformanceModelSchema = external_exports.object({
61
+ rules: external_exports.array(conformanceRuleSchema).min(1),
62
+ hypotheses: external_exports.array(divergenceHypothesisSchema)
63
+ }).strict().superRefine((model, ctx) => {
64
+ const ruleIds = new Set(model.rules.map((r) => r.id));
65
+ model.hypotheses.forEach((h, i) => {
66
+ if (!ruleIds.has(h.ruleId)) {
67
+ ctx.addIssue({
68
+ code: external_exports.ZodIssueCode.custom,
69
+ path: ["hypotheses", i, "ruleId"],
70
+ message: `hypothesis references unknown ruleId \`${h.ruleId}\``
71
+ });
72
+ }
73
+ });
74
+ });
75
+ function structurallyValidateConformanceModel(candidate) {
76
+ const parsed = conformanceModelSchema.safeParse(candidate);
77
+ if (parsed.success) {
78
+ return { valid: true, model: parsed.data, errors: [] };
79
+ }
80
+ const errors = parsed.error.issues.map((issue) => ({
81
+ path: issue.path.join("."),
82
+ message: issue.message
83
+ }));
84
+ return { valid: false, errors };
85
+ }
86
+ var SYSTEM_PROMPT = [
87
+ "You are a protocol-conformance analyst. Given (a) an authoritative protocol",
88
+ "specification excerpt and (b) a slice of an implementation's source, you",
89
+ "extract the spec's testable requirements and hypothesize where the",
90
+ "implementation diverges from them.",
91
+ "",
92
+ "Rules:",
93
+ "- Output ONLY a single ```json fenced block \u2014 no prose outside it.",
94
+ "- The JSON has exactly two top-level keys: `rules` and `hypotheses`.",
95
+ "- A rule is { id, specCitation, level, surface, mandate, exercise }.",
96
+ " - `level` is one of MUST, MUST NOT, SHOULD, SHOULD NOT, MAY (RFC 2119).",
97
+ " - `surface` is one of method, header, status (Tier-1 is HTTP/text only).",
98
+ " - `exercise` is the HTTP request that exercises the rule:",
99
+ " { method, path?, headers?, body? }.",
100
+ "- A hypothesis is { ruleId, specCitation, level, implLocation, rationale,",
101
+ " predictedObservable, exercise, confidence }.",
102
+ " - `ruleId` MUST reference one of the rules you emitted.",
103
+ " - `predictedObservable` is the deterministic, machine-checkable shape a",
104
+ " CONFORMANT response must have: { surface, expectedStatusIn?,",
105
+ " forbiddenStatusIn?, requiredHeader?, forbiddenHeader?, whenStatusIn?,",
106
+ " unlessStatusIn? }. It MUST carry at least one matcher. Use",
107
+ " `forbiddenStatusIn` for codes that CONCRETELY prove a violation (e.g. a",
108
+ " 2xx to a method the spec says MUST be rejected). `expectedStatusIn` and",
109
+ " `forbiddenStatusIn` MUST NOT share any code.",
110
+ " - For a HEADER rule, the requirement is almost always CONDITIONAL on the",
111
+ " status (e.g. `Location` is required only on a 201/3xx; `Content-Range` is",
112
+ " forbidden except on 206). Carry `whenStatusIn` (rule applies only on these",
113
+ " statuses) so an unrelated response (e.g. a 500) is not mistaken for a",
114
+ " conformant 201 missing its header. Use `unlessStatusIn` for the inverse.",
115
+ " - `confidence` is your prior plausibility (0\u20131) that the impl diverges. It",
116
+ " is NOT a verdict \u2014 a deterministic oracle decides confirmed/refuted.",
117
+ "- Prefer MUST/MUST NOT rules: only those can be confirmed by the oracle.",
118
+ " SHOULD-level divergences are advisory and cannot be confirmed, so do not",
119
+ " over-invest hypotheses in them."
120
+ ].join("\n");
121
+ function buildInitialPrompt(model, implExcerpt, focusHint) {
122
+ const hint = focusHint ? `
123
+ Focus: ${focusHint}
124
+ ` : "";
125
+ return [
126
+ `# Protocol: ${model.name} (${model.version}, ${model.specRef})`,
127
+ hint,
128
+ "Extract the testable conformance requirements from the specification",
129
+ "excerpt below, then hypothesize where the implementation source diverges",
130
+ "from them. Emit a single ```json fenced block with `rules` and",
131
+ "`hypotheses`.",
132
+ "",
133
+ "## Specification excerpt",
134
+ "```",
135
+ model.specExcerpt ?? "",
136
+ "```",
137
+ "",
138
+ "## Implementation source excerpt",
139
+ "```",
140
+ implExcerpt,
141
+ "```"
142
+ ].join("\n");
143
+ }
144
+ function buildRepairPrompt(rawCandidate, errors) {
145
+ const errorList = errors.map((e) => e.path ? `- ${e.path}: ${e.message}` : `- ${e.message}`).join("\n");
146
+ return [
147
+ "The JSON you produced failed structural validation.",
148
+ "Fix ONLY the reported problems and re-emit the COMPLETE corrected JSON",
149
+ "inside a single ```json fenced block. Do not add commentary.",
150
+ "",
151
+ "## Your output",
152
+ "```",
153
+ rawCandidate,
154
+ "```",
155
+ "",
156
+ "## Validation errors",
157
+ errorList
158
+ ].join("\n");
159
+ }
160
+ function extractJsonBlock(response) {
161
+ const fenced = response.match(/```(?:json)?\s*\n([\s\S]*?)```/i) ?? response.match(/```\s*\n([\s\S]*?)```/);
162
+ return (fenced ? fenced[1] : response).trim();
163
+ }
164
+ function responseText(content) {
165
+ return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
166
+ }
167
+ function parseCandidate(raw) {
168
+ try {
169
+ return { ok: true, value: JSON.parse(raw) };
170
+ } catch (err) {
171
+ return {
172
+ ok: false,
173
+ error: `not valid JSON: ${err instanceof Error ? err.message : String(err)}`
174
+ };
175
+ }
176
+ }
177
+ async function generateConformanceModel(model, implExcerpt, llm, opts = {}) {
178
+ const maxIterations = Math.max(1, opts.maxIterations ?? 4);
179
+ const validate = opts.validator ?? structurallyValidateConformanceModel;
180
+ let prompt = buildInitialPrompt(model, implExcerpt, opts.focusHint);
181
+ let rawCandidate = "";
182
+ let errors = [];
183
+ for (let iteration = 1; iteration <= maxIterations; iteration++) {
184
+ const message = {
185
+ role: "user",
186
+ content: [{ type: "text", text: prompt }]
187
+ };
188
+ const result = await llm.executeNative(SYSTEM_PROMPT, [message], []);
189
+ rawCandidate = extractJsonBlock(responseText(result.content));
190
+ const parsed = parseCandidate(rawCandidate);
191
+ if (!parsed.ok) {
192
+ errors = [{ path: "", message: parsed.error }];
193
+ prompt = buildRepairPrompt(rawCandidate, errors);
194
+ continue;
195
+ }
196
+ const verdict = await validate(parsed.value);
197
+ if (verdict.valid && verdict.model) {
198
+ return {
199
+ ok: true,
200
+ model: verdict.model,
201
+ rawCandidate,
202
+ iterations: iteration,
203
+ errors: []
204
+ };
205
+ }
206
+ errors = verdict.errors;
207
+ prompt = buildRepairPrompt(rawCandidate, errors);
208
+ }
209
+ return { ok: false, rawCandidate, iterations: maxIterations, errors };
210
+ }
211
+
212
+ // packages/core/dist/protocol/oracle-http.js
213
+ var CONFIRMABLE_LEVELS = /* @__PURE__ */ new Set(["MUST", "MUST NOT"]);
214
+ function inSet(value, set) {
215
+ return Boolean(set && set.includes(value));
216
+ }
217
+ function setsOverlap(a, b) {
218
+ if (!a || !b)
219
+ return false;
220
+ const bset = new Set(b);
221
+ return a.some((x) => bset.has(x));
222
+ }
223
+ function ruleApplies(prediction, status) {
224
+ if (prediction.whenStatusIn && prediction.whenStatusIn.length > 0) {
225
+ if (!prediction.whenStatusIn.includes(status))
226
+ return false;
227
+ }
228
+ if (prediction.unlessStatusIn && prediction.unlessStatusIn.includes(status)) {
229
+ return false;
230
+ }
231
+ return true;
232
+ }
233
+ function lowerHeaders(headers) {
234
+ const out = {};
235
+ if (!headers)
236
+ return out;
237
+ for (const [k, v] of Object.entries(headers))
238
+ out[k.toLowerCase()] = v;
239
+ return out;
240
+ }
241
+ function judgeHttpDivergence(hypothesis, observed) {
242
+ const base = {
243
+ ruleId: hypothesis.ruleId
244
+ };
245
+ const prediction = hypothesis.predictedObservable;
246
+ if (observed.error !== void 0) {
247
+ return {
248
+ ...base,
249
+ status: "inconclusive",
250
+ confidence: hypothesis.confidence,
251
+ evidence: `no response observed (transport error: ${observed.error}); cannot judge conformance`
252
+ };
253
+ }
254
+ const confirmable = CONFIRMABLE_LEVELS.has(hypothesis.level);
255
+ const headers = lowerHeaders(observed.headers);
256
+ if (setsOverlap(prediction.expectedStatusIn, prediction.forbiddenStatusIn)) {
257
+ return {
258
+ ...base,
259
+ status: "inconclusive",
260
+ confidence: hypothesis.confidence,
261
+ evidence: `contradictory prediction: status set [${prediction.expectedStatusIn?.join(", ")}] is marked both conformant and forbidden; cannot confirm a violation`
262
+ };
263
+ }
264
+ if (prediction.surface === "method" || prediction.surface === "status") {
265
+ if (inSet(observed.status, prediction.forbiddenStatusIn)) {
266
+ if (!confirmable) {
267
+ return {
268
+ ...base,
269
+ status: "inconclusive",
270
+ confidence: hypothesis.confidence,
271
+ evidence: `observed status ${observed.status} is in the forbidden set [${prediction.forbiddenStatusIn?.join(", ")}], but the rule is ${hypothesis.level}-level (advisory) \u2014 not a confirmable violation`
272
+ };
273
+ }
274
+ return {
275
+ ...base,
276
+ status: "confirmed",
277
+ confidence: 1,
278
+ evidence: `${hypothesis.level} violation: observed status ${observed.status}, which the spec forbids for this input (forbidden set [${prediction.forbiddenStatusIn?.join(", ")}]). Rule ${hypothesis.specCitation}.`
279
+ };
280
+ }
281
+ if (inSet(observed.status, prediction.expectedStatusIn)) {
282
+ return {
283
+ ...base,
284
+ status: "refuted",
285
+ confidence: 0,
286
+ evidence: `observed status ${observed.status} matches the conformant set [${prediction.expectedStatusIn?.join(", ")}] \u2014 no divergence`
287
+ };
288
+ }
289
+ return {
290
+ ...base,
291
+ status: "inconclusive",
292
+ confidence: hypothesis.confidence,
293
+ evidence: `observed status ${observed.status} is neither in the conformant set [${prediction.expectedStatusIn?.join(", ") ?? ""}] nor a declared forbidden status [${prediction.forbiddenStatusIn?.join(", ") ?? ""}]; insufficient evidence to confirm a violation`
294
+ };
295
+ }
296
+ if (prediction.surface === "header") {
297
+ if (!ruleApplies(prediction, observed.status)) {
298
+ return {
299
+ ...base,
300
+ status: "inconclusive",
301
+ confidence: hypothesis.confidence,
302
+ evidence: `header rule does not apply to status ${observed.status} (guard: whenStatusIn=[${prediction.whenStatusIn?.join(", ") ?? ""}], unlessStatusIn=[${prediction.unlessStatusIn?.join(", ") ?? ""}]); header presence/absence proves nothing here`
303
+ };
304
+ }
305
+ if (prediction.forbiddenHeader) {
306
+ const name = prediction.forbiddenHeader.toLowerCase();
307
+ const present = name in headers;
308
+ if (present) {
309
+ if (!confirmable) {
310
+ return {
311
+ ...base,
312
+ status: "inconclusive",
313
+ confidence: hypothesis.confidence,
314
+ evidence: `forbidden header \`${prediction.forbiddenHeader}\` present, but the rule is ${hypothesis.level}-level (advisory) \u2014 not confirmable`
315
+ };
316
+ }
317
+ return {
318
+ ...base,
319
+ status: "confirmed",
320
+ confidence: 1,
321
+ evidence: `${hypothesis.level} violation: response carries header \`${prediction.forbiddenHeader}\`, which the spec forbids. Rule ${hypothesis.specCitation}.`
322
+ };
323
+ }
324
+ return {
325
+ ...base,
326
+ status: "refuted",
327
+ confidence: 0,
328
+ evidence: `forbidden header \`${prediction.forbiddenHeader}\` absent \u2014 no divergence`
329
+ };
330
+ }
331
+ if (prediction.requiredHeader) {
332
+ const name = prediction.requiredHeader.toLowerCase();
333
+ const present = name in headers;
334
+ if (!present) {
335
+ if (!confirmable) {
336
+ return {
337
+ ...base,
338
+ status: "inconclusive",
339
+ confidence: hypothesis.confidence,
340
+ evidence: `required header \`${prediction.requiredHeader}\` missing, but the rule is ${hypothesis.level}-level (advisory) \u2014 not confirmable`
341
+ };
342
+ }
343
+ return {
344
+ ...base,
345
+ status: "confirmed",
346
+ confidence: 1,
347
+ evidence: `${hypothesis.level} violation: response is missing required header \`${prediction.requiredHeader}\`. Rule ${hypothesis.specCitation}.`
348
+ };
349
+ }
350
+ return {
351
+ ...base,
352
+ status: "refuted",
353
+ confidence: 0,
354
+ evidence: `required header \`${prediction.requiredHeader}\` present \u2014 no divergence`
355
+ };
356
+ }
357
+ }
358
+ return {
359
+ ...base,
360
+ status: "inconclusive",
361
+ confidence: hypothesis.confidence,
362
+ evidence: "predictedObservable carried no matcher applicable to its surface"
363
+ };
364
+ }
365
+
366
+ // packages/core/dist/protocol/http-conformance.js
367
+ var DEFAULT_MAX_EXERCISES = 8;
368
+ function exerciseUrl(targetUrl, exercise) {
369
+ const path = exercise.path ?? "/";
370
+ const base = targetUrl.replace(/\/+$/, "");
371
+ const suffix = path.startsWith("/") ? path : `/${path}`;
372
+ return `${base}${suffix}`;
373
+ }
374
+ function toObserved(result) {
375
+ if (!result.success || !result.output || typeof result.output.status !== "number") {
376
+ return { status: 0, error: result.error ?? "http_request did not return a status" };
377
+ }
378
+ const headers = {};
379
+ if (result.output.headers) {
380
+ for (const [k, v] of Object.entries(result.output.headers))
381
+ headers[k] = v;
382
+ }
383
+ return { status: result.output.status, headers };
384
+ }
385
+ function confirmedDivergenceToFinding(protocolModel, attempt) {
386
+ const { hypothesis, observed, verdict } = attempt;
387
+ return {
388
+ id: randomUUID(),
389
+ templateId: `protocol-conformance-${protocolModel.name}-${hypothesis.ruleId}`,
390
+ title: `${protocolModel.name} conformance divergence: ${hypothesis.ruleId} (${hypothesis.specCitation})`,
391
+ description: [
392
+ `Implementation diverges from ${protocolModel.name} (${protocolModel.specRef}).`,
393
+ `Rule ${hypothesis.specCitation} (${hypothesis.level}): ${hypothesis.rationale}`,
394
+ `Predicted at ${hypothesis.implLocation}.`,
395
+ `Confirmed by sending ${hypothesis.exercise.method} ${hypothesis.exercise.path ?? "/"}`,
396
+ `and observing status ${observed.status}.`
397
+ ].join(" "),
398
+ severity: "medium",
399
+ category: "missing-validation",
400
+ status: "confirmed",
401
+ evidence: {
402
+ request: `${hypothesis.exercise.method} ${hypothesis.exercise.path ?? "/"}`,
403
+ response: `status=${observed.status}`,
404
+ analysis: [
405
+ "Source: protocol-conformance (Tier-1 HTTP)",
406
+ `Protocol: ${protocolModel.name} ${protocolModel.version} (${protocolModel.specRef})`,
407
+ `Rule: ${hypothesis.specCitation} [${hypothesis.level}]`,
408
+ "Hypothesis: false",
409
+ `Oracle: confirmed`,
410
+ `Evidence: ${verdict.evidence}`
411
+ ].join("\n")
412
+ },
413
+ fingerprint: `protoconf:${protocolModel.name}:${hypothesis.ruleId}`,
414
+ triageStatus: "new",
415
+ // Same promotion contract as kernel-verify: confirmed ⇒ confidence 1.0.
416
+ confidence: verdict.confidence,
417
+ timestamp: Date.now()
418
+ };
419
+ }
420
+ function reconcileHypothesisWithRule(hypothesis, rule) {
421
+ if (hypothesis.predictedObservable.surface !== rule.surface) {
422
+ return null;
423
+ }
424
+ return {
425
+ ...hypothesis,
426
+ // Authoritative fields come from the RULE, not the hypothesis's copies.
427
+ level: rule.level,
428
+ specCitation: rule.specCitation,
429
+ exercise: rule.exercise,
430
+ predictedObservable: {
431
+ ...hypothesis.predictedObservable,
432
+ surface: rule.surface
433
+ }
434
+ };
435
+ }
436
+ async function runHttpConformanceCheck(specExcerpt, implExcerpt, targetUrl, llm, send, protocol, opts = {}) {
437
+ const protocolModel = {
438
+ name: protocol.name,
439
+ version: protocol.version,
440
+ specRef: protocol.specRef,
441
+ specExcerpt
442
+ };
443
+ const gen = await generateConformanceModel(protocolModel, implExcerpt, llm, opts.gen);
444
+ if (!gen.ok || !gen.model) {
445
+ return {
446
+ ok: false,
447
+ findings: [],
448
+ attempts: [],
449
+ genIterations: gen.iterations,
450
+ reason: `conformance-gen failed after ${gen.iterations} iteration(s): ${gen.errors.map((e) => e.path ? `${e.path}: ${e.message}` : e.message).join("; ")}`
451
+ };
452
+ }
453
+ const cap = Math.max(0, opts.maxExercises ?? DEFAULT_MAX_EXERCISES);
454
+ const rawHypotheses = gen.model.hypotheses.slice(0, cap);
455
+ const rulesById = new Map(gen.model.rules.map((r) => [r.id, r]));
456
+ const attempts = [];
457
+ const findings = [];
458
+ for (const rawHypothesis of rawHypotheses) {
459
+ const rule = rulesById.get(rawHypothesis.ruleId);
460
+ const hypothesis = rule ? reconcileHypothesisWithRule(rawHypothesis, rule) : null;
461
+ if (!hypothesis) {
462
+ const observed2 = {
463
+ status: 0,
464
+ error: rule ? `hypothesis surface "${rawHypothesis.predictedObservable.surface}" disagrees with rule "${rule.id}" surface "${rule.surface}"; not exercised (cannot confirm on drifted hypothesis)` : `hypothesis references unknown rule "${rawHypothesis.ruleId}"; not exercised`
465
+ };
466
+ attempts.push({
467
+ hypothesis: rawHypothesis,
468
+ observed: observed2,
469
+ verdict: {
470
+ ruleId: rawHypothesis.ruleId,
471
+ status: "inconclusive",
472
+ confidence: rawHypothesis.confidence,
473
+ evidence: observed2.error ?? "drifted hypothesis; not exercised"
474
+ }
475
+ });
476
+ continue;
477
+ }
478
+ const url = exerciseUrl(targetUrl, hypothesis.exercise);
479
+ let observed;
480
+ try {
481
+ const sendArgs = {
482
+ url,
483
+ method: hypothesis.exercise.method,
484
+ ...hypothesis.exercise.headers ? { headers: hypothesis.exercise.headers } : {},
485
+ ...hypothesis.exercise.body !== void 0 ? { body: hypothesis.exercise.body } : {}
486
+ };
487
+ const result = await send(sendArgs);
488
+ observed = toObserved(result);
489
+ } catch (err) {
490
+ observed = {
491
+ status: 0,
492
+ error: err instanceof Error ? err.message : String(err)
493
+ };
494
+ }
495
+ const verdict = judgeHttpDivergence(hypothesis, observed);
496
+ const attempt = { hypothesis, observed, verdict };
497
+ attempts.push(attempt);
498
+ if (verdict.status === "confirmed") {
499
+ findings.push(confirmedDivergenceToFinding(protocolModel, attempt));
500
+ }
501
+ }
502
+ return {
503
+ ok: true,
504
+ findings,
505
+ attempts,
506
+ genIterations: gen.iterations
507
+ };
508
+ }
509
+
510
+ export {
511
+ structurallyValidateConformanceModel,
512
+ generateConformanceModel,
513
+ judgeHttpDivergence,
514
+ runHttpConformanceCheck
515
+ };
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __0secCreateRequire } from "node:module";
3
+ const require = __0secCreateRequire(import.meta.url);
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12
+ }) : x)(function(x) {
13
+ if (typeof require !== "undefined") return require.apply(this, arguments);
14
+ throw Error('Dynamic require of "' + x + '" is not supported');
15
+ });
16
+ var __commonJS = (cb, mod) => function __require2() {
17
+ try {
18
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
+ } catch (e) {
20
+ throw mod = 0, e;
21
+ }
22
+ };
23
+ var __export = (target, all) => {
24
+ for (var name in all)
25
+ __defProp(target, name, { get: all[name], enumerable: true });
26
+ };
27
+ var __copyProps = (to, from, except, desc) => {
28
+ if (from && typeof from === "object" || typeof from === "function") {
29
+ for (let key of __getOwnPropNames(from))
30
+ if (!__hasOwnProp.call(to, key) && key !== except)
31
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
32
+ }
33
+ return to;
34
+ };
35
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
36
+ // If the importer is in node compatibility mode or this is not an ESM
37
+ // file that has been converted to a CommonJS file using a Babel-
38
+ // compatible transform (i.e. "__esModule" has not been set), then set
39
+ // "default" to the CommonJS "module.exports" for node compatibility.
40
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
41
+ mod
42
+ ));
43
+
44
+ export {
45
+ __require,
46
+ __commonJS,
47
+ __export,
48
+ __toESM
49
+ };