@opacedev/astro-ai-content-checker 0.3.1

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 (185) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/LICENSE +9 -0
  3. package/README.md +236 -0
  4. package/SBOM.cdx.json +172 -0
  5. package/SECURITY.md +9 -0
  6. package/THIRD_PARTY_NOTICES.md +36 -0
  7. package/dist/build-report-html.d.ts +3 -0
  8. package/dist/highlight.js +155 -0
  9. package/dist/index.d.ts +6 -0
  10. package/dist/index.js +43 -0
  11. package/dist/options.d.ts +21 -0
  12. package/dist/options.js +6 -0
  13. package/dist/receipt.d.ts +15 -0
  14. package/dist/receipt.js +100 -0
  15. package/dist/report.d.ts +55 -0
  16. package/dist/report.js +12 -0
  17. package/dist/sections.js +181 -0
  18. package/dist/share.d.ts +47 -0
  19. package/dist/share.js +72 -0
  20. package/dist/shared-EX54KI6H.js +1503 -0
  21. package/dist/shared-MMXWTX2U.js +43 -0
  22. package/dist/toolbar.js +13478 -0
  23. package/node_modules/@opacedev/ai-content-checker-browser/LICENSE +21 -0
  24. package/node_modules/@opacedev/ai-content-checker-browser/README.md +145 -0
  25. package/node_modules/@opacedev/ai-content-checker-browser/dist/dom/visible-text.d.ts +14 -0
  26. package/node_modules/@opacedev/ai-content-checker-browser/dist/dom/visible-text.js +47 -0
  27. package/node_modules/@opacedev/ai-content-checker-browser/dist/index.d.ts +3 -0
  28. package/node_modules/@opacedev/ai-content-checker-browser/dist/index.js +99 -0
  29. package/node_modules/@opacedev/ai-content-checker-browser/dist/worker/client.d.ts +12 -0
  30. package/node_modules/@opacedev/ai-content-checker-browser/dist/worker/client.js +17 -0
  31. package/node_modules/@opacedev/ai-content-checker-browser/dist/worker/entry.d.ts +1 -0
  32. package/node_modules/@opacedev/ai-content-checker-browser/dist/worker/entry.js +3984 -0
  33. package/node_modules/@opacedev/ai-content-checker-browser/dist/worker/protocol.d.ts +30 -0
  34. package/node_modules/@opacedev/ai-content-checker-browser/dist/worker/protocol.js +1 -0
  35. package/node_modules/@opacedev/ai-content-checker-browser/package.json +60 -0
  36. package/node_modules/@opacedev/ai-content-checker-contracts/LICENSE +21 -0
  37. package/node_modules/@opacedev/ai-content-checker-contracts/README.md +93 -0
  38. package/node_modules/@opacedev/ai-content-checker-contracts/dist/index.d.ts +58 -0
  39. package/node_modules/@opacedev/ai-content-checker-contracts/dist/index.js +17 -0
  40. package/node_modules/@opacedev/ai-content-checker-contracts/package.json +57 -0
  41. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/analysis-request.schema.d.ts +44 -0
  42. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/analysis-result.schema.d.ts +122 -0
  43. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/candidate.schema.d.ts +81 -0
  44. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/capabilities.schema.d.ts +24 -0
  45. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/checker-result.schema.d.ts +342 -0
  46. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/common.schema.d.ts +10 -0
  47. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/envelope.schema.d.ts +14 -0
  48. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/gate-result.schema.d.ts +19 -0
  49. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/integrity-receipt.schema.d.ts +122 -0
  50. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/job.schema.d.ts +188 -0
  51. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/method-result.schema.d.ts +39 -0
  52. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/pattern-finding.schema.d.ts +26 -0
  53. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/protected-span.schema.d.ts +35 -0
  54. package/node_modules/@opacedev/ai-content-checker-contracts/src/generated/rewrite-request.schema.d.ts +65 -0
  55. package/node_modules/@opacedev/ai-content-checker-contracts/src/index.ts +63 -0
  56. package/node_modules/@opacedev/ai-content-checker-contracts/src/semantic-validation.mjs +32 -0
  57. package/node_modules/@opacedev/ai-content-checker-core/LICENSE +21 -0
  58. package/node_modules/@opacedev/ai-content-checker-core/README.md +186 -0
  59. package/node_modules/@opacedev/ai-content-checker-core/dist/bundle.js +4744 -0
  60. package/node_modules/@opacedev/ai-content-checker-core/dist/capabilities.d.ts +16 -0
  61. package/node_modules/@opacedev/ai-content-checker-core/dist/capabilities.js +7 -0
  62. package/node_modules/@opacedev/ai-content-checker-core/dist/diff/diff.d.ts +17 -0
  63. package/node_modules/@opacedev/ai-content-checker-core/dist/diff/diff.js +76 -0
  64. package/node_modules/@opacedev/ai-content-checker-core/dist/fixes/preview.d.ts +27 -0
  65. package/node_modules/@opacedev/ai-content-checker-core/dist/fixes/preview.js +47 -0
  66. package/node_modules/@opacedev/ai-content-checker-core/dist/gates/policy.d.ts +14 -0
  67. package/node_modules/@opacedev/ai-content-checker-core/dist/gates/policy.js +16 -0
  68. package/node_modules/@opacedev/ai-content-checker-core/dist/index.d.ts +15 -0
  69. package/node_modules/@opacedev/ai-content-checker-core/dist/index.js +15 -0
  70. package/node_modules/@opacedev/ai-content-checker-core/dist/inspect.d.ts +8 -0
  71. package/node_modules/@opacedev/ai-content-checker-core/dist/inspect.js +84 -0
  72. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-gb-v1.d.ts +12 -0
  73. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-gb-v1.js +68 -0
  74. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v2-data.d.ts +73 -0
  75. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v2-data.js +499 -0
  76. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v2.d.ts +76 -0
  77. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v2.js +1067 -0
  78. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v3-data.d.ts +165 -0
  79. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v3-data.js +614 -0
  80. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v3.d.ts +19 -0
  81. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v3.js +542 -0
  82. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v4-corpus.d.ts +40 -0
  83. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v4-corpus.js +40 -0
  84. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v4-data.d.ts +138 -0
  85. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v4-data.js +200 -0
  86. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v4.d.ts +71 -0
  87. package/node_modules/@opacedev/ai-content-checker-core/dist/patterns/en-signals-v4.js +388 -0
  88. package/node_modules/@opacedev/ai-content-checker-core/dist/protected/extract.d.ts +17 -0
  89. package/node_modules/@opacedev/ai-content-checker-core/dist/protected/extract.js +75 -0
  90. package/node_modules/@opacedev/ai-content-checker-core/dist/protected/validate.d.ts +3 -0
  91. package/node_modules/@opacedev/ai-content-checker-core/dist/protected/validate.js +17 -0
  92. package/node_modules/@opacedev/ai-content-checker-core/dist/provenance/c2pa-text.d.ts +55 -0
  93. package/node_modules/@opacedev/ai-content-checker-core/dist/provenance/c2pa-text.js +86 -0
  94. package/node_modules/@opacedev/ai-content-checker-core/dist/receipts/build.d.ts +48 -0
  95. package/node_modules/@opacedev/ai-content-checker-core/dist/receipts/build.js +61 -0
  96. package/node_modules/@opacedev/ai-content-checker-core/dist/report/checker-result.d.ts +241 -0
  97. package/node_modules/@opacedev/ai-content-checker-core/dist/report/checker-result.js +419 -0
  98. package/node_modules/@opacedev/ai-content-checker-core/dist/source/offsets.d.ts +34 -0
  99. package/node_modules/@opacedev/ai-content-checker-core/dist/source/offsets.js +51 -0
  100. package/node_modules/@opacedev/ai-content-checker-core/dist/source/utf8.d.ts +3 -0
  101. package/node_modules/@opacedev/ai-content-checker-core/dist/source/utf8.js +58 -0
  102. package/node_modules/@opacedev/ai-content-checker-core/dist/source/visible-text.d.ts +12 -0
  103. package/node_modules/@opacedev/ai-content-checker-core/dist/source/visible-text.js +30 -0
  104. package/node_modules/@opacedev/ai-content-checker-core/dist/unicode/data.d.ts +22 -0
  105. package/node_modules/@opacedev/ai-content-checker-core/dist/unicode/data.js +137 -0
  106. package/node_modules/@opacedev/ai-content-checker-core/dist/unicode/inspect.d.ts +16 -0
  107. package/node_modules/@opacedev/ai-content-checker-core/dist/unicode/inspect.js +84 -0
  108. package/node_modules/@opacedev/ai-content-checker-core/dist/verdict/combine.d.ts +162 -0
  109. package/node_modules/@opacedev/ai-content-checker-core/dist/verdict/combine.js +501 -0
  110. package/node_modules/@opacedev/ai-content-checker-core/package.json +62 -0
  111. package/node_modules/canonicalize/LICENSE +201 -0
  112. package/node_modules/canonicalize/README.md +65 -0
  113. package/node_modules/canonicalize/bin/canonicalize.js +17 -0
  114. package/node_modules/canonicalize/lib/canonicalize.d.ts +2 -0
  115. package/node_modules/canonicalize/lib/canonicalize.js +74 -0
  116. package/node_modules/canonicalize/package.json +64 -0
  117. package/node_modules/entities/LICENSE +11 -0
  118. package/node_modules/entities/lib/decode.d.ts +211 -0
  119. package/node_modules/entities/lib/decode.d.ts.map +1 -0
  120. package/node_modules/entities/lib/decode.js +536 -0
  121. package/node_modules/entities/lib/decode.js.map +1 -0
  122. package/node_modules/entities/lib/decode_codepoint.d.ts +19 -0
  123. package/node_modules/entities/lib/decode_codepoint.d.ts.map +1 -0
  124. package/node_modules/entities/lib/decode_codepoint.js +76 -0
  125. package/node_modules/entities/lib/decode_codepoint.js.map +1 -0
  126. package/node_modules/entities/lib/encode.d.ts +22 -0
  127. package/node_modules/entities/lib/encode.d.ts.map +1 -0
  128. package/node_modules/entities/lib/encode.js +77 -0
  129. package/node_modules/entities/lib/encode.js.map +1 -0
  130. package/node_modules/entities/lib/escape.d.ts +43 -0
  131. package/node_modules/entities/lib/escape.d.ts.map +1 -0
  132. package/node_modules/entities/lib/escape.js +122 -0
  133. package/node_modules/entities/lib/escape.js.map +1 -0
  134. package/node_modules/entities/lib/esm/decode.d.ts +211 -0
  135. package/node_modules/entities/lib/esm/decode.d.ts.map +1 -0
  136. package/node_modules/entities/lib/esm/decode.js +496 -0
  137. package/node_modules/entities/lib/esm/decode.js.map +1 -0
  138. package/node_modules/entities/lib/esm/decode_codepoint.d.ts +19 -0
  139. package/node_modules/entities/lib/esm/decode_codepoint.d.ts.map +1 -0
  140. package/node_modules/entities/lib/esm/decode_codepoint.js +71 -0
  141. package/node_modules/entities/lib/esm/decode_codepoint.js.map +1 -0
  142. package/node_modules/entities/lib/esm/encode.d.ts +22 -0
  143. package/node_modules/entities/lib/esm/encode.d.ts.map +1 -0
  144. package/node_modules/entities/lib/esm/encode.js +69 -0
  145. package/node_modules/entities/lib/esm/encode.js.map +1 -0
  146. package/node_modules/entities/lib/esm/escape.d.ts +43 -0
  147. package/node_modules/entities/lib/esm/escape.d.ts.map +1 -0
  148. package/node_modules/entities/lib/esm/escape.js +116 -0
  149. package/node_modules/entities/lib/esm/escape.js.map +1 -0
  150. package/node_modules/entities/lib/esm/generated/decode-data-html.d.ts +3 -0
  151. package/node_modules/entities/lib/esm/generated/decode-data-html.d.ts.map +1 -0
  152. package/node_modules/entities/lib/esm/generated/decode-data-html.js +7 -0
  153. package/node_modules/entities/lib/esm/generated/decode-data-html.js.map +1 -0
  154. package/node_modules/entities/lib/esm/generated/decode-data-xml.d.ts +3 -0
  155. package/node_modules/entities/lib/esm/generated/decode-data-xml.d.ts.map +1 -0
  156. package/node_modules/entities/lib/esm/generated/decode-data-xml.js +7 -0
  157. package/node_modules/entities/lib/esm/generated/decode-data-xml.js.map +1 -0
  158. package/node_modules/entities/lib/esm/generated/encode-html.d.ts +8 -0
  159. package/node_modules/entities/lib/esm/generated/encode-html.d.ts.map +1 -0
  160. package/node_modules/entities/lib/esm/generated/encode-html.js +10 -0
  161. package/node_modules/entities/lib/esm/generated/encode-html.js.map +1 -0
  162. package/node_modules/entities/lib/esm/index.d.ts +96 -0
  163. package/node_modules/entities/lib/esm/index.d.ts.map +1 -0
  164. package/node_modules/entities/lib/esm/index.js +99 -0
  165. package/node_modules/entities/lib/esm/index.js.map +1 -0
  166. package/node_modules/entities/lib/esm/package.json +1 -0
  167. package/node_modules/entities/lib/generated/decode-data-html.d.ts +3 -0
  168. package/node_modules/entities/lib/generated/decode-data-html.d.ts.map +1 -0
  169. package/node_modules/entities/lib/generated/decode-data-html.js +9 -0
  170. package/node_modules/entities/lib/generated/decode-data-html.js.map +1 -0
  171. package/node_modules/entities/lib/generated/decode-data-xml.d.ts +3 -0
  172. package/node_modules/entities/lib/generated/decode-data-xml.d.ts.map +1 -0
  173. package/node_modules/entities/lib/generated/decode-data-xml.js +9 -0
  174. package/node_modules/entities/lib/generated/decode-data-xml.js.map +1 -0
  175. package/node_modules/entities/lib/generated/encode-html.d.ts +8 -0
  176. package/node_modules/entities/lib/generated/encode-html.d.ts.map +1 -0
  177. package/node_modules/entities/lib/generated/encode-html.js +12 -0
  178. package/node_modules/entities/lib/generated/encode-html.js.map +1 -0
  179. package/node_modules/entities/lib/index.d.ts +96 -0
  180. package/node_modules/entities/lib/index.d.ts.map +1 -0
  181. package/node_modules/entities/lib/index.js +126 -0
  182. package/node_modules/entities/lib/index.js.map +1 -0
  183. package/node_modules/entities/package.json +90 -0
  184. package/node_modules/entities/readme.md +122 -0
  185. package/package.json +91 -0
@@ -0,0 +1,39 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * This file was automatically generated by json-schema-to-typescript.
4
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
+ * and run json-schema-to-typescript to regenerate this file.
6
+ */
7
+
8
+ export type HttpsSchemasOpaceAgencyContentIntegrityV1MethodResultSchemaJson = {
9
+ [k: string]: unknown;
10
+ } & {
11
+ id: string;
12
+ category: "detector" | "watermark" | "provenance" | "unicode" | "pattern" | "fidelity";
13
+ provider_or_method: string;
14
+ version: string;
15
+ status: "pass" | "attention" | "fail" | "inconclusive" | "unsupported" | "not_configured" | "not_run" | "error";
16
+ availability?: "available" | "restricted" | "not_available";
17
+ native_outcome?: string;
18
+ score: number | null;
19
+ score_scale?: {
20
+ [k: string]: unknown;
21
+ } | null;
22
+ threshold: {
23
+ [k: string]: unknown;
24
+ } | null;
25
+ segments: {
26
+ [k: string]: unknown;
27
+ }[];
28
+ evidence: {
29
+ [k: string]: unknown;
30
+ }[];
31
+ /**
32
+ * @minItems 1
33
+ */
34
+ limitations: [string, ...string[]];
35
+ started_at: string;
36
+ completed_at: string;
37
+ privacy_route: "browser" | "wordpress_local" | "local_service" | "hub_provider" | "commercial_byok";
38
+ [k: string]: unknown;
39
+ };
@@ -0,0 +1,26 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * This file was automatically generated by json-schema-to-typescript.
4
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
+ * and run json-schema-to-typescript to regenerate this file.
6
+ */
7
+
8
+ export interface HttpsSchemasOpaceAgencyContentIntegrityV1PatternFindingSchemaJson {
9
+ rule_id: string;
10
+ rule_version: string;
11
+ severity: "note" | "low" | "medium" | "high";
12
+ message: string;
13
+ suggestion?: string;
14
+ span: {
15
+ start_utf16: number;
16
+ end_utf16: number;
17
+ start_codepoint: number;
18
+ end_codepoint: number;
19
+ [k: string]: unknown;
20
+ };
21
+ matched_text_hash: string;
22
+ evidence: {
23
+ [k: string]: unknown;
24
+ };
25
+ [k: string]: unknown;
26
+ }
@@ -0,0 +1,35 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * This file was automatically generated by json-schema-to-typescript.
4
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
+ * and run json-schema-to-typescript to regenerate this file.
6
+ */
7
+
8
+ export interface HttpsSchemasOpaceAgencyContentIntegrityV1ProtectedSpanSchemaJson {
9
+ id: string;
10
+ kind:
11
+ | "name"
12
+ | "organisation"
13
+ | "number"
14
+ | "date"
15
+ | "time"
16
+ | "currency"
17
+ | "unit"
18
+ | "url"
19
+ | "email"
20
+ | "quote"
21
+ | "citation"
22
+ | "code"
23
+ | "user_selected";
24
+ text: string;
25
+ start_utf16: number;
26
+ end_utf16: number;
27
+ start_codepoint: number;
28
+ end_codepoint: number;
29
+ normalised_value?: unknown;
30
+ policy: "exact" | "equivalent_format" | "must_remain_supported" | "user_review";
31
+ source: "deterministic" | "ner" | "citation_parser" | "user";
32
+ confidence?: number | null;
33
+ content_hash: string;
34
+ [k: string]: unknown;
35
+ }
@@ -0,0 +1,65 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * This file was automatically generated by json-schema-to-typescript.
4
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
+ * and run json-schema-to-typescript to regenerate this file.
6
+ */
7
+
8
+ export interface HttpsSchemasOpaceAgencyContentIntegrityV1RewriteRequestSchemaJson {
9
+ schema_version: "1.0";
10
+ contract_version: string;
11
+ request_id: string;
12
+ created_at: string;
13
+ source: Source;
14
+ protected_spans: HttpsSchemasOpaceAgencyContentIntegrityV1ProtectedSpanSchemaJson[];
15
+ candidate_count: number;
16
+ /**
17
+ * @minItems 1
18
+ */
19
+ allowed_routes: [
20
+ "browser" | "wordpress_local" | "local_service" | "hub_provider" | "commercial_byok",
21
+ ...("browser" | "wordpress_local" | "local_service" | "hub_provider" | "commercial_byok")[]
22
+ ];
23
+ checks: string[];
24
+ gate_policy: "strict" | "manual_review";
25
+ style_brief?: string;
26
+ [k: string]: unknown;
27
+ }
28
+ export interface Source {
29
+ content: string;
30
+ content_type: "plain_text" | "html" | "markdown";
31
+ language: string;
32
+ title?: string;
33
+ source_uri?: string;
34
+ content_hash?: string;
35
+ normalised_hash?: string;
36
+ [k: string]: unknown;
37
+ }
38
+ export interface HttpsSchemasOpaceAgencyContentIntegrityV1ProtectedSpanSchemaJson {
39
+ id: string;
40
+ kind:
41
+ | "name"
42
+ | "organisation"
43
+ | "number"
44
+ | "date"
45
+ | "time"
46
+ | "currency"
47
+ | "unit"
48
+ | "url"
49
+ | "email"
50
+ | "quote"
51
+ | "citation"
52
+ | "code"
53
+ | "user_selected";
54
+ text: string;
55
+ start_utf16: number;
56
+ end_utf16: number;
57
+ start_codepoint: number;
58
+ end_codepoint: number;
59
+ normalised_value?: unknown;
60
+ policy: "exact" | "equivalent_format" | "must_remain_supported" | "user_review";
61
+ source: "deterministic" | "ner" | "citation_parser" | "user";
62
+ confidence?: number | null;
63
+ content_hash: string;
64
+ [k: string]: unknown;
65
+ }
@@ -0,0 +1,63 @@
1
+ export const SCHEMA_VERSION = "1.0" as const;
2
+ export const CONTRACT_VERSION = "1.0.0" as const;
3
+ export const WORDPRESS_REST_NAMESPACE = "oaci/v1" as const;
4
+ export const WORDPRESS_ADMIN_PAGE = "admin.php?page=oaci-lab" as const;
5
+ export const LOCAL_ENGINE_ORIGIN = "http://127.0.0.1:8741" as const;
6
+ export const PUBLIC_API_IDENTITY = "Opace\\ContentIntegrity\\Integration\\PublicApi::instance()" as const;
7
+ export const READY_HOOK = "oaci_ready" as const;
8
+ export const PHP_PUBLIC_API_METHODS = ["version", "is_compatible", "capabilities", "register_source_adapter", "create_session", "get_session", "approve", "get_approved_output", "mark_applied", "get_receipt", "asset_handles"] as const;
9
+ export const JS_MOUNT_CONTRACT = {
10
+ global: "OpaceContentIntegrity",
11
+ apiVersion: "1.0",
12
+ requiredOptions: ["surface", "sourceRef", "sourceHash", "getContent", "onApproved", "onClose"],
13
+ returns: ["destroy", "refresh", "getState"],
14
+ events: ["oaci:statechange", "oaci:approved", "oaci:error"]
15
+ } as const;
16
+
17
+ export const METHOD_STATUSES = ["pass", "attention", "fail", "inconclusive", "unsupported", "not_configured", "not_run", "error"] as const;
18
+ export type MethodStatus = (typeof METHOD_STATUSES)[number];
19
+
20
+ export const PRIVACY_ROUTES = ["browser", "wordpress_local", "local_service", "hub_provider", "commercial_byok"] as const;
21
+ export type PrivacyRoute = (typeof PRIVACY_ROUTES)[number];
22
+
23
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1EnvelopeSchemaJson as ContractEnvelope } from "./generated/envelope.schema.js";
24
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1MethodResultSchemaJson as MethodResult } from "./generated/method-result.schema.js";
25
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1AnalysisRequestSchemaJson as AnalysisRequest } from "./generated/analysis-request.schema.js";
26
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1AnalysisResultSchemaJson as AnalysisResult } from "./generated/analysis-result.schema.js";
27
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1ProtectedSpanSchemaJson as ProtectedSpan } from "./generated/protected-span.schema.js";
28
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1PatternFindingSchemaJson as PatternFinding } from "./generated/pattern-finding.schema.js";
29
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1GateResultSchemaJson as GateResult } from "./generated/gate-result.schema.js";
30
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1CandidateSchemaJson as Candidate } from "./generated/candidate.schema.js";
31
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1RewriteRequestSchemaJson as RewriteRequest } from "./generated/rewrite-request.schema.js";
32
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1JobSchemaJson as Job } from "./generated/job.schema.js";
33
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1CapabilitiesSchemaJson as Capabilities } from "./generated/capabilities.schema.js";
34
+ export type { HttpsSchemasOpaceAgencyContentIntegrityV1IntegrityReceiptSchemaJson as IntegrityReceipt } from "./generated/integrity-receipt.schema.js";
35
+ export type { OpaceAIContentIntegrityCheckerResult as CheckerResult } from "./generated/checker-result.schema.js";
36
+
37
+ export interface AnthropicUnsupportedMethodResultV1 {
38
+ id: "watermark.anthropic";
39
+ category: "watermark";
40
+ provider_or_method: string;
41
+ version: "unavailable-2026-08-26";
42
+ status: "unsupported";
43
+ availability: "not_available";
44
+ native_outcome?: "not_available";
45
+ score: null;
46
+ threshold: null;
47
+ segments: Record<string, unknown>[];
48
+ evidence: Record<string, unknown>[];
49
+ limitations: [string, ...string[]];
50
+ started_at: string;
51
+ completed_at: string;
52
+ privacy_route: PrivacyRoute;
53
+ [key: string]: unknown;
54
+ }
55
+
56
+ export interface JsMountOptionsV1 {
57
+ surface: string;
58
+ sourceRef: string;
59
+ sourceHash: string;
60
+ getContent(): string | Promise<string>;
61
+ onApproved(payload: unknown): void;
62
+ onClose(): void;
63
+ }
@@ -0,0 +1,32 @@
1
+ const HASH_PATTERN = /^sha256:[a-f0-9]{64}$/;
2
+
3
+ function result(valid, errors = []) {
4
+ return { valid, errors };
5
+ }
6
+
7
+ export function validateProtectedSpan(span) {
8
+ const errors = [];
9
+ if (span.end_utf16 <= span.start_utf16) errors.push("utf16_range_empty_or_reversed");
10
+ if (span.end_codepoint <= span.start_codepoint) errors.push("codepoint_range_empty_or_reversed");
11
+ if (typeof span.text === "string") {
12
+ if (span.end_utf16 - span.start_utf16 !== span.text.length) errors.push("utf16_length_mismatch");
13
+ if (span.end_codepoint - span.start_codepoint !== [...span.text].length) errors.push("codepoint_length_mismatch");
14
+ }
15
+ if (!HASH_PATTERN.test(span.content_hash ?? "")) errors.push("source_hash_invalid");
16
+ return result(errors.length === 0, errors);
17
+ }
18
+
19
+ export function validatePatternFinding(finding) {
20
+ const errors = [];
21
+ const span = finding.span ?? {};
22
+ if (span.end_utf16 <= span.start_utf16) errors.push("utf16_range_empty_or_reversed");
23
+ if (span.end_codepoint <= span.start_codepoint) errors.push("codepoint_range_empty_or_reversed");
24
+ if (!HASH_PATTERN.test(finding.matched_text_hash ?? "")) errors.push("matched_text_hash_invalid");
25
+ return result(errors.length === 0, errors);
26
+ }
27
+
28
+ export function validateContractSemantics(schemaName, value) {
29
+ if (schemaName === "protected-span.schema.json") return validateProtectedSpan(value);
30
+ if (schemaName === "pattern-finding.schema.json") return validatePatternFinding(value);
31
+ return result(true);
32
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Opace Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,186 @@
1
+ # @opacedev/ai-content-checker-core
2
+
3
+ ![Free Opace AI Content Checker, Detector and Watermark Tools](https://raw.githubusercontent.com/OpaceDigitalAgency/opace-ai-content-checker-detector/main/docs/assets/opace-ai-content-checker-detector-hero-v3.png)
4
+
5
+ Deterministic, offline content-integrity engine: invisible-Unicode and homoglyph forensics, named writing-signal rules with an editorial score, protected spans, safe-fix previews, diffs, gates and RFC 8785 hash-only receipts. This is the single analysis implementation used by every Opace surface (web checker, WordPress plugin, Chrome extension, Astro integration, CLI).
6
+
7
+ - Consumes `@opacedev/ai-content-checker-contracts` contract `1.0.0`
8
+ - Browser/SSR-safe ESM, transport-free by design: no network call, telemetry or postinstall download
9
+ - Unicode carriers: 38 rules over 415 code points, with context exemptions for emoji, cursive/Indic scripts and French typography (`unicode:2026.08.2`)
10
+ - Homoglyphs: 60 Cyrillic/Greek confusables with a mixed-script gate
11
+ - Writing signals: 113 weighted categories (116 named rules, including 7 rhythm and cadence stylometrics and 3 chat-export formatting rules, measured, not calibrated to a clean sheet: on 1,200 human long-form documents these rules flag 24.8% of them, and any claim that they produce no false positives is withdrawn — see the measured rates below) at `en-signals:2026.08.6`, with a raise-only evidence-based escalation policy recorded in an explanatory `escalation` result field. 95 of the 116 fire on real documents: one is recorded inactive and twenty dormant, with the measured per-rule inventory in `tests/battery/rule-liveness.json`
12
+ - Protected spans: 12 kinds including name, organisation and citation
13
+ - `watermark.anthropic` remains visibly `unsupported` until an official interface exists; the browser checker runs a separate live known-key scan (`@opace/watermark-lab`) rather than presenting that boundary as a check
14
+ - Licence: MIT for the Opace-authored package
15
+
16
+ A pass applies only to its named disclosed check and does not prove authorship or detector clearance. The full capability inventory is in the repository's [capability register](../../docs/CAPABILITIES.md); every test total and evaluation behind it is indexed in the [evidence index](../../docs/EVIDENCE-INDEX.md).
17
+
18
+ > Release state: a 0.1.0 npm candidate is prepared locally but is not published. The install command below applies only after owner-approved publication.
19
+
20
+ ## Install
21
+
22
+ ```sh
23
+ npm install @opacedev/ai-content-checker-core
24
+ ```
25
+
26
+ Targets ESM on modern browsers and Node.js 20 or newer.
27
+
28
+ ## API
29
+
30
+ ```js
31
+ import {
32
+ inspect, // full analysis over an AnalysisRequest
33
+ computeEditorialSignals, // 0-100 writing-signal score for plain text
34
+ inspectSignalsV2, // raw signal findings
35
+ inspectUnicode, // carrier/homoglyph findings for a string
36
+ extractProtectedSpans, // 12 protected-span kinds
37
+ previewSafeFixes, diff, validateCandidate,
38
+ buildReceipt, verifyReceipt,
39
+ presentCycle5Result, composeCheckerAxes,
40
+ buildContentFreeSharePayload, assertCheckerResultInvariants,
41
+ listMethods, registerPatternPack,
42
+ projectVisibleText, prefixedSha256, sha256Hex, utf8Bytes,
43
+ UNICODE_RULES_VERSION, EN_SIGNALS_PATTERN_VERSION,
44
+ } from "@opacedev/ai-content-checker-core";
45
+ ```
46
+
47
+ The checker-result helpers are presentation/contract logic, not a bundled detector. They freeze the
48
+ Cycle-5 identity and five `signal-*` level ids, format all scores once per run, preserve the three
49
+ independent axes and reject model/route/section/export contradictions. A full-checker adapter supplies
50
+ the measured model result; without one, `notAssessedAiPattern()` is the only honest AI axis.
51
+
52
+ ### Full inspection
53
+
54
+ `inspect(request)` takes a contract `AnalysisRequest` and returns a frozen `AnalysisResult` with per-method statuses, evidence, limitations and hashes. Verified example (output from the built package):
55
+
56
+ ```js
57
+ const result = await inspect({
58
+ schema_version: "1.0",
59
+ contract_version: "1.0.0",
60
+ request_id: "req_readme_demo",
61
+ created_at: new Date().toISOString(),
62
+ source: { content: "In today's rapidly evolving landscape, Opace quoted £1,250.​",
63
+ content_type: "plain_text", language: "en-GB" },
64
+ checks: ["unicode.invisible", "style.patterns", "watermark.anthropic"],
65
+ privacy: { allowed_routes: ["browser"], save_receipt: false, retain_content: false }
66
+ });
67
+
68
+ result.summary;
69
+ // { pass: 0, attention: 2, fail: 0, inconclusive: 0, unsupported: 1, not_configured: 0, not_run: 0, error: 0 }
70
+ result.methods.map(m => [m.id, m.status]);
71
+ // [["unicode.invisible","attention"], ["style.patterns","attention"], ["watermark.anthropic","unsupported"]]
72
+ result.protected_spans.map(s => s.kind);
73
+ // ["currency", "number"]
74
+ ```
75
+
76
+ The zero-width space hidden in the sample content is what turns `unicode.invisible` to `attention`. Statuses come from the fixed vocabulary `pass | attention | fail | inconclusive | unsupported | not_configured | not_run | error`; unrun checks are never collapsed into a pass, and a zero-finding pattern run carries a scope note stating it is not evidence of human authorship.
77
+
78
+ ### Editorial signals score
79
+
80
+ ```js
81
+ const signals = computeEditorialSignals(draftText);
82
+ // { score: 23, classification: "mixed_signals", probabilities, confidence: "low",
83
+ // categoriesHit, findingCount, wordCount, version: "en-signals:2026.08.6",
84
+ // status: "scored", escalation: null, description }
85
+ ```
86
+
87
+ Classification is trinary (`human_like` / `mixed_signals` / `ai_like`), false-negative-biased by design, and probability-consistent: the label is always the argmax of the published probabilities. The evidence-based escalation policy (artefact floor, citation co-occurrence, artefact-plus-score, formatting floor, formatting cluster, furniture gate, finding breadth) can only raise a classification and, when it does, `escalation` names the policy and reason. Never present the score as authorship detection: clean, well-prompted AI prose scores low on any rule tier, which is why the result vocabulary says "no strong AI-style signals" rather than "human".
88
+
89
+ Measured on the fresh 5,558-document long-form corpus (`services/local-engine/research/longform-corpus/`), this rules tier detects **45.1%** of AI writing and wrongly flags **24.8%** of human writing. It flags roughly one human document in four, which is why it is editorial suggestion only and contributes nothing to any AI verdict. The older provider-eval aggregate is superseded and must not be quoted: its human side was 169 documents, 76% of them encyclopaedic and question-and-answer text, so its rate described that corpus and not published prose. See `docs/CAPABILITIES.md` §7.2 and §7.3.
90
+
91
+ ### Unicode findings
92
+
93
+ ```js
94
+ inspectUnicode("claim​ed");
95
+ // [{ code_point: "U+200B", severity: "medium", fix: "remove", span: {...},
96
+ // matched_text_hash: "sha256:...", limitations: [...] }]
97
+ ```
98
+
99
+ ## Test and integration boundary
100
+
101
+ ```sh
102
+ npm ci
103
+ npm test
104
+ npm run pack:check
105
+ ```
106
+
107
+ Use the typed exports rather than copying algorithms into a consumer; browser, Astro, CLI and extension adapters must produce the same stable fields for the same projected input, and the repository's cross-surface battery enforces this. Consumers remain responsible for explicit user consent before inspecting content and for keeping content out of logs and receipts.
108
+
109
+ ## Attribution
110
+
111
+ This engine was built on existing open-source work by deliberate choice, so the projects it
112
+ stands on are named here rather than only in a licence file.
113
+
114
+ - [avoid-ai-writing](https://github.com/conorbronsdon/avoid-ai-writing) — MIT, Conor Bronsdon and contributors. 46 of the 51 v2 writing-pattern rule categories, the stylometric methods, the weights and the classifier logic, adapted to TypeScript, plus Cyrillic and Greek lookalike map data. One upstream bug was fixed in the port.
115
+ - [watermarks-remover](https://github.com/guillaumemeyer/watermarks-remover) — MIT, Guillaume Meyer. The invisible-character and space-substitute carrier tables and the explicit-carrier inspection model. Table data only; no upstream code is distributed.
116
+ - [Unicode Consortium character data](https://www.unicode.org/Public/UCD/latest/) — Unicode licence. The 415-code-point carrier inventory across 38 rules and the 60-entry confusable set.
117
+ - [antislop-sampler](https://github.com/sam-paech/antislop-sampler) — Apache-2.0, Sam Paech. Fiction phrase and over-represented name data behind the `fiction-slop-phrase` and `fiction-promptonym` rules.
118
+ - [slop-forensics](https://github.com/sam-paech/slop-forensics) — MIT, Sam Paech. Per-model observations corroborating the fiction-lane rules.
119
+ - [SLOP_Detector](https://github.com/SicariusSicariiStuff/SLOP_Detector) — Apache-2.0, SicariusSicariiStuff. The graded penalty-class weighting approach.
120
+ - [slop-gate](https://github.com/hwajongpark/slop-gate) — MIT, hwajongpark. Promotional-register and buzz-phrase pattern data.
121
+ - [anti-ai-writing](https://github.com/avectats7/anti-ai-writing) — MIT, avectats7. Buzz-phrase and weak-verb observation data.
122
+ - [anti-slop](https://github.com/kjmagnan1s/anti-slop) — MIT, kjmagnan1s. Faux-insight phrase data and the protect-list and context-profile design.
123
+ - [claude-slop-detector](https://github.com/aplaceforallmystuff/claude-slop-detector) — MIT, aplaceforallmystuff. Staccato-fragment and tripled-negation observations.
124
+ - [Wikipedia, *Signs of AI writing*](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing) — CC BY-SA 4.0. Editorial guidance independently re-expressed with no verbatim excerpts, credited as the licence requires.
125
+ - [Project Gutenberg](https://www.gutenberg.org) public-domain texts, all published before 1929 — the embedded human-prose reference corpus behind the rhythm and register signals.
126
+ - [canonicalize](https://github.com/cyberphone/json-canonicalization) — Apache-2.0. RFC 8785 canonicalisation.
127
+ - Published academic findings by Liang et al. (ICML 2024), Kobak et al. (*Science Advances* 2025), Juzek & Ward (COLING 2025), Reinhart et al. (PNAS 2025), Geng & Trotta (2024) and Pew Research (2026), used as rule thresholds and lexicon facts.
128
+
129
+ Several well-known detector repositories were cloned and read during the research phase and are
130
+ credited as exactly that — read, not used. Nothing in this package derives from `fast-detect-gpt`,
131
+ `Binoculars`, `RADAR`, `DIPPER`, `ai-detector-bench`, `BIRA`, `SIRA` or `MarkLLM`.
132
+
133
+ Full records, with versions, snapshot commits and file-level destinations:
134
+ [THIRD_PARTY_NOTICES.md](https://github.com/OpaceDigitalAgency/opace-ai-content-checker-detector/blob/main/THIRD_PARTY_NOTICES.md) ·
135
+ [DEPENDENCY-LEDGER.md](https://github.com/OpaceDigitalAgency/opace-ai-content-checker-detector/blob/main/docs/legal/DEPENDENCY-LEDGER.md).
136
+
137
+ ## Troubleshooting and links
138
+
139
+ - **A check reports `unsupported`:** preserve that result. Do not replace it with a different method or a pass.
140
+ - **Browser and server output differ:** confirm both adapters supplied the same projected UTF-8 text and use the same contract/core versions (`UNICODE_RULES_VERSION`, `EN_SIGNALS_PATTERN_VERSION` are exported for exactly this).
141
+ - **A safe fix changes protected content:** reject the candidate and inspect the protected-span gate before applying any text.
142
+
143
+ Report security concerns through the repository [security policy](https://github.com/OpaceDigitalAgency/opace-ai-content-checker-detector/blob/main/SECURITY.md). For non-sensitive help, use [Opace AI Content Checker & Detector support](https://opace.agency/get-in-touch/). Changes follow the repository [contribution guide](../../CONTRIBUTING.md) and [changelog](../../CHANGELOG.md).
144
+
145
+ [Opace AI Content Checker & Detector](https://opace.agency/tools/ai/content-verification-integrity/) · [Browser checker](https://opace.agency/tools/ai/content-verification-integrity/checker/) · [Capability register](../../docs/CAPABILITIES.md) · [Opace](https://opace.agency/) · [Opace Digital Agency on GitHub](https://github.com/OpaceDigitalAgency) · [Related contracts package](../contracts/README.md)
146
+
147
+ ## Where this is weakest, measured
148
+
149
+ This package ships the deterministic character forensics and editorial writing rules. It does
150
+ **not** contain the trained model that produces an AI reading; Cycle 5 runs only in the web
151
+ checker. The model results are disclosed here so package users can distinguish the two systems.
152
+
153
+ **The writing rules are editorial feedback, not detection.** On 922 machine and 1,200 held-out
154
+ human long-form documents, they detect 45.1% of machine writing while flagging **24.8% of human
155
+ writing** — one human document in four. `computeEditorialSignals` returns a writing score, never
156
+ an authorship reading, and must not be presented as one.
157
+
158
+ The deployed Cycle 5 model (`tier3-cycle5-v1`, margin rule
159
+ `max(m1, m2+0.34) >= 3.571`) was measured separately through both live runtimes on the full
160
+ 5,558-document long-form evaluation corpus. That corpus is not wholly independent: 654/922 AI
161
+ documents are independent of every Cycle 2 split and 268 are not; 11/4,636 human documents
162
+ overlap. The separate topic-matched held-out slice is the independent evasion measurement.
163
+
164
+ | Cycle 5 measurement | result | denominator and runtime |
165
+ |---|---:|---|
166
+ | AI documents flagged | **97.8%** | 902/922, EU server fp32 |
167
+ | human documents wrongly flagged | **0.99%** | 46/4,636, EU server fp32 |
168
+ | AI documents flagged | **97.6%** | 900/922, browser int8 |
169
+ | human documents wrongly flagged | **1.57%** | 73/4,636, browser int8 |
170
+ | topic-matched held-out AI flagged | **86.9%** | 153/176, server evaluation route |
171
+ | structured human partners wrongly flagged | **0.2%** | 1/418, server evaluation route |
172
+ | human fiction wrongly flagged | **3.1% / 3.5%** | 7/227 server / 8/227 browser |
173
+ | held-out 100-word AI flagged | **76.8%** | 43/56, server evaluation route |
174
+ | heavy AI edits of human originals flagged | **28.5%** | 39/137, server evaluation view |
175
+ | academic human documents wrongly flagged | **0.8%** | 15/1,992, server evaluation view |
176
+
177
+ The 100-word cell is small, fiction remains higher-risk than the overall human set, and treating
178
+ heavy AI edits as machine-assisted is a product boundary rather than proof of authorship. Do not
179
+ use a result for an academic misconduct decision about one student.
180
+
181
+ *Historical, not current:* Cycle 2 (`tier3-cycle2-v1`, live 28 August – 1 September 2026) produced
182
+ the earlier 883/922 server, 889/922 browser, 45/4,636 server-human and 90/4,636 browser-human
183
+ figures. Its fiction and length rows are retired and must not be mixed with Cycle 5.
184
+
185
+ Complete list with sources: [Honest limitations](https://github.com/OpaceDigitalAgency/opace-ai-content-checker-detector#honest-limitations).
186
+ The same figures plotted, with the 50% acceptance floor drawn in: [result charts](https://github.com/OpaceDigitalAgency/opace-ai-content-checker-detector#what-it-measures-and-where-it-fails).