@ryuenn3123/agentic-senior-core 4.3.15 → 5.1.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 (198) hide show
  1. package/.agents/plugins/marketplace.json +21 -0
  2. package/.agents/rules/agentic-senior-core.md +126 -0
  3. package/.claude-plugin/marketplace.json +17 -0
  4. package/.claude-plugin/plugin.json +17 -0
  5. package/.clinerules/agentic-senior-core.md +94 -0
  6. package/.codex-plugin/plugin.json +24 -0
  7. package/.cursor/rules/agentic-senior-core.mdc +99 -0
  8. package/.devin-plugin/plugin.json +13 -0
  9. package/.github/copilot-instructions.md +94 -0
  10. package/.github/plugin/marketplace.json +20 -0
  11. package/.github/plugin/plugin.json +16 -0
  12. package/.kiro/steering/agentic-senior-core.md +94 -0
  13. package/.openclaw/skills/asc/SKILL.md +23 -0
  14. package/.openclaw/skills/asc-audit/SKILL.md +28 -0
  15. package/.openclaw/skills/asc-review/SKILL.md +54 -0
  16. package/.opencode/plugins/agentic-senior-core.mjs +31 -0
  17. package/.windsurf/rules/agentic-senior-core.md +94 -0
  18. package/AGENTS.md +126 -179
  19. package/CONTRIBUTING.md +93 -63
  20. package/README.md +160 -111
  21. package/__init__.py +61 -0
  22. package/bin/agentic-senior-core.js +41 -43
  23. package/commands/asc-audit.md +1 -0
  24. package/commands/asc-audit.toml +2 -0
  25. package/commands/asc-help.md +9 -0
  26. package/commands/asc-help.toml +2 -0
  27. package/commands/asc-refactor.md +1 -0
  28. package/commands/asc-refactor.toml +2 -0
  29. package/commands/asc-review.md +1 -0
  30. package/commands/asc-review.toml +2 -0
  31. package/gemini-extension.json +10 -0
  32. package/hooks/copilot-hooks.json +21 -0
  33. package/hooks/hooks.json +31 -0
  34. package/hooks/session-start.js +36 -0
  35. package/hooks/subagent-start.js +38 -0
  36. package/lib/cli/commands/adapter.mjs +109 -0
  37. package/lib/cli/commands/clean.mjs +63 -0
  38. package/lib/cli/commands/status.mjs +94 -0
  39. package/package.json +43 -67
  40. package/plugin.yaml +16 -0
  41. package/scripts/uninstall.js +38 -0
  42. package/skills/asc/SKILL.md +16 -0
  43. package/skills/asc-audit/SKILL.md +28 -0
  44. package/skills/asc-refactor/SKILL.md +35 -0
  45. package/skills/asc-review/SKILL.md +54 -0
  46. package/.agent-context/policies/llm-judge-threshold.json +0 -29
  47. package/.agent-context/prompts/bootstrap-design.md +0 -63
  48. package/.agent-context/prompts/compact-natural-mode.md +0 -100
  49. package/.agent-context/prompts/init-project.md +0 -60
  50. package/.agent-context/prompts/refactor.md +0 -38
  51. package/.agent-context/prompts/review-code.md +0 -31
  52. package/.agent-context/review-checklists/architecture-review.md +0 -57
  53. package/.agent-context/review-checklists/pr-checklist.md +0 -136
  54. package/.agent-context/rules/api-docs.md +0 -24
  55. package/.agent-context/rules/api-versioning.md +0 -16
  56. package/.agent-context/rules/architecture.md +0 -33
  57. package/.agent-context/rules/background-jobs.md +0 -17
  58. package/.agent-context/rules/config-and-flags.md +0 -16
  59. package/.agent-context/rules/database-design.md +0 -18
  60. package/.agent-context/rules/docker-runtime.md +0 -17
  61. package/.agent-context/rules/error-handling.md +0 -16
  62. package/.agent-context/rules/event-driven.md +0 -16
  63. package/.agent-context/rules/frontend-architecture.md +0 -54
  64. package/.agent-context/rules/microservices.md +0 -16
  65. package/.agent-context/rules/migrations.md +0 -16
  66. package/.agent-context/rules/observability.md +0 -16
  67. package/.agent-context/rules/performance.md +0 -16
  68. package/.agent-context/rules/realtime.md +0 -16
  69. package/.agent-context/rules/resilience.md +0 -18
  70. package/.agent-context/rules/security.md +0 -18
  71. package/.agent-context/rules/testing.md +0 -16
  72. package/.agent-context/state/README.md +0 -25
  73. package/.agent-context/state/architecture-map.md +0 -40
  74. package/.agent-context/state/benchmark-comparison-schema.json +0 -181
  75. package/.agent-context/state/benchmark-reproducibility.json +0 -87
  76. package/.agent-context/state/benchmark-thresholds.json +0 -10
  77. package/.agent-context/state/benchmark-writer-judge-config.json +0 -58
  78. package/.agent-context/state/dependency-map.md +0 -41
  79. package/.agent-context/state/memory-adapter-contract.json +0 -52
  80. package/.agent-context/state/memory-schema-v1.json +0 -88
  81. package/GEMINI.md +0 -1
  82. package/benchmarks/README.md +0 -60
  83. package/benchmarks/compact-natural-mode/fixtures.mjs +0 -359
  84. package/benchmarks/compact-natural-mode/scorer.mjs +0 -331
  85. package/benchmarks/runtime-token-saver/fixtures.mjs +0 -836
  86. package/lib/cli/adaptive-context/catalog.mjs +0 -390
  87. package/lib/cli/adaptive-context/file-signals.mjs +0 -100
  88. package/lib/cli/adaptive-context/implications.mjs +0 -44
  89. package/lib/cli/adaptive-context.mjs +0 -365
  90. package/lib/cli/audits/typography-palette-anti-repeat/color-utils.mjs +0 -156
  91. package/lib/cli/audits/typography-palette-anti-repeat/file-scanner.mjs +0 -103
  92. package/lib/cli/audits/typography-palette-anti-repeat/typography-utils.mjs +0 -70
  93. package/lib/cli/audits/typography-palette-anti-repeat-audit.mjs +0 -239
  94. package/lib/cli/backup.mjs +0 -210
  95. package/lib/cli/commands/audit-design-anti-repeat.mjs +0 -39
  96. package/lib/cli/commands/context.mjs +0 -140
  97. package/lib/cli/commands/init/project-context.mjs +0 -60
  98. package/lib/cli/commands/init/runtime-environment.mjs +0 -59
  99. package/lib/cli/commands/init/setup-decisions.mjs +0 -83
  100. package/lib/cli/commands/init.mjs +0 -654
  101. package/lib/cli/commands/launch.mjs +0 -76
  102. package/lib/cli/commands/optimize.mjs +0 -284
  103. package/lib/cli/commands/rollback.mjs +0 -64
  104. package/lib/cli/commands/upgrade/token-optimization-state.mjs +0 -51
  105. package/lib/cli/commands/upgrade.mjs +0 -451
  106. package/lib/cli/compiler.mjs +0 -570
  107. package/lib/cli/constants.mjs +0 -136
  108. package/lib/cli/detector/constants.mjs +0 -135
  109. package/lib/cli/detector/design-evidence/collector.mjs +0 -256
  110. package/lib/cli/detector/design-evidence/constants.mjs +0 -39
  111. package/lib/cli/detector/design-evidence/file-traversal.mjs +0 -83
  112. package/lib/cli/detector/design-evidence/structured-attribute-evidence.mjs +0 -117
  113. package/lib/cli/detector/design-evidence/summary.mjs +0 -109
  114. package/lib/cli/detector/design-evidence/utility-helpers.mjs +0 -122
  115. package/lib/cli/detector/design-evidence.mjs +0 -25
  116. package/lib/cli/detector/stack-detection.mjs +0 -243
  117. package/lib/cli/detector/ui-signals.mjs +0 -150
  118. package/lib/cli/detector/workspace-scan.mjs +0 -177
  119. package/lib/cli/detector.mjs +0 -23
  120. package/lib/cli/init-detection-flow.mjs +0 -48
  121. package/lib/cli/init-options.mjs +0 -237
  122. package/lib/cli/init-selection.mjs +0 -29
  123. package/lib/cli/memory-continuity.mjs +0 -537
  124. package/lib/cli/preflight.mjs +0 -76
  125. package/lib/cli/project-scaffolder/constants.mjs +0 -69
  126. package/lib/cli/project-scaffolder/discovery.mjs +0 -272
  127. package/lib/cli/project-scaffolder/prompt-builders.mjs +0 -171
  128. package/lib/cli/project-scaffolder/storage.mjs +0 -144
  129. package/lib/cli/project-scaffolder/ui-scope-detection.mjs +0 -36
  130. package/lib/cli/project-scaffolder.mjs +0 -29
  131. package/lib/cli/rollback.mjs +0 -66
  132. package/lib/cli/token-optimization.mjs +0 -486
  133. package/lib/cli/utils/filesystem.mjs +0 -81
  134. package/lib/cli/utils/managed-surface.mjs +0 -280
  135. package/lib/cli/utils/prompting.mjs +0 -44
  136. package/lib/cli/utils.mjs +0 -479
  137. package/mcp.json +0 -134
  138. package/scripts/adaptive-context/fixtures.mjs +0 -183
  139. package/scripts/adaptive-context-benchmark.mjs +0 -9
  140. package/scripts/ascx-runtime-token-saver-benchmark.mjs +0 -9
  141. package/scripts/audit-cache-layer-contract.mjs +0 -263
  142. package/scripts/audit-caching-scope-hygiene.mjs +0 -268
  143. package/scripts/audit-file-size.mjs +0 -219
  144. package/scripts/audit-reflection-citations.mjs +0 -163
  145. package/scripts/audit-release-bundle.mjs +0 -170
  146. package/scripts/audit-rule-id-uniqueness.mjs +0 -313
  147. package/scripts/audit-typography-palette-anti-repeat.mjs +0 -120
  148. package/scripts/benchmark-evidence-bundle.mjs +0 -645
  149. package/scripts/benchmark-gate.mjs +0 -121
  150. package/scripts/benchmark-intelligence.mjs +0 -33
  151. package/scripts/benchmark-writer-judge-matrix.mjs +0 -379
  152. package/scripts/build-release-benchmark-bundle.mjs +0 -202
  153. package/scripts/bump-version.mjs +0 -103
  154. package/scripts/clean-local-artifacts.mjs +0 -78
  155. package/scripts/compact-natural-mode-benchmark.mjs +0 -9
  156. package/scripts/context-triggered-audit.mjs +0 -391
  157. package/scripts/detection-benchmark.mjs +0 -127
  158. package/scripts/docs-quality-drift-report.mjs +0 -358
  159. package/scripts/documentation-boundary-audit.mjs +0 -305
  160. package/scripts/explain-on-demand-audit.mjs +0 -427
  161. package/scripts/forbidden-content-check.mjs +0 -123
  162. package/scripts/frontend-usability-audit.mjs +0 -243
  163. package/scripts/generate-sbom.mjs +0 -61
  164. package/scripts/governance-weekly-report.mjs +0 -466
  165. package/scripts/llm-judge/checklist-loader.mjs +0 -45
  166. package/scripts/llm-judge/constants.mjs +0 -66
  167. package/scripts/llm-judge/diff-collection.mjs +0 -74
  168. package/scripts/llm-judge/prompting.mjs +0 -78
  169. package/scripts/llm-judge/providers.mjs +0 -111
  170. package/scripts/llm-judge/verdict.mjs +0 -134
  171. package/scripts/llm-judge.mjs +0 -200
  172. package/scripts/memory-continuity-benchmark.mjs +0 -322
  173. package/scripts/quality-trend-report.mjs +0 -289
  174. package/scripts/release-gate/audit-checks.mjs +0 -441
  175. package/scripts/release-gate/constants.mjs +0 -53
  176. package/scripts/release-gate/runtime.mjs +0 -63
  177. package/scripts/release-gate/static-checks.mjs +0 -182
  178. package/scripts/release-gate.mjs +0 -42
  179. package/scripts/rules-guardian-audit.mjs +0 -580
  180. package/scripts/single-source-lazy-loading-audit.mjs +0 -449
  181. package/scripts/sync-thin-adapters.mjs +0 -72
  182. package/scripts/token-optimization-benchmark.mjs +0 -252
  183. package/scripts/ui-design-judge/constants.mjs +0 -13
  184. package/scripts/ui-design-judge/design-execution-summary.mjs +0 -81
  185. package/scripts/ui-design-judge/git-input.mjs +0 -134
  186. package/scripts/ui-design-judge/prompting.mjs +0 -52
  187. package/scripts/ui-design-judge/providers.mjs +0 -102
  188. package/scripts/ui-design-judge/reporting.mjs +0 -183
  189. package/scripts/ui-design-judge/rubric-calibration.mjs +0 -214
  190. package/scripts/ui-design-judge/rubric-goldset.json +0 -188
  191. package/scripts/ui-design-judge.mjs +0 -319
  192. package/scripts/ui-rubric-calibration.mjs +0 -35
  193. package/scripts/validate/config.mjs +0 -519
  194. package/scripts/validate/coverage-checks.mjs +0 -446
  195. package/scripts/validate/file-structure.mjs +0 -162
  196. package/scripts/validate/markdown-content.mjs +0 -109
  197. package/scripts/validate/project-metadata.mjs +0 -166
  198. package/scripts/validate.mjs +0 -338
@@ -1,183 +0,0 @@
1
- export const ADAPTIVE_CONTEXT_FIXTURES = [
2
- {
3
- id: 'auth-flow-review',
4
- requestText: 'Review this login auth flow. Check JWT session handling, API response errors, and what tests should cover.',
5
- requiredLabels: ['SEC', 'API', 'ERR', 'TEST'],
6
- allowedLabels: ['SEC', 'API', 'ERR', 'TEST'],
7
- },
8
- {
9
- id: 'real-auth-refactor',
10
- requestText: 'Tolong refactor auth flow ini, jangan ubah behavior, cek security dan test juga.',
11
- requiredLabels: ['SEC', 'ARCH', 'TEST'],
12
- allowedLabels: ['SEC', 'ARCH', 'TEST', 'ERR', 'API'],
13
- },
14
- {
15
- id: 'runtime-hardening',
16
- requestText: 'Make adaptive context runtime stable. Fix missed implicit cases before moving to ASCX.',
17
- requiredLabels: ['ARCH', 'TEST', 'ERR'],
18
- allowedLabels: ['ARCH', 'TEST', 'ERR'],
19
- },
20
- {
21
- id: 'natural-migration-broke',
22
- requestText: 'Something broke after I pushed the migration yesterday.',
23
- requiredLabels: ['MIG', 'ERR'],
24
- allowedLabels: ['MIG', 'ERR'],
25
- },
26
- {
27
- id: 'natural-frontend-mobile-overlap',
28
- requestText: 'This page flickers on mobile and the text overlaps.',
29
- requiredLabels: ['FE'],
30
- allowedLabels: ['FE'],
31
- },
32
- {
33
- id: 'indonesian-access-leak',
34
- requestText: 'Audit pembayaran ini, takut kebuka akses user lain.',
35
- requiredLabels: ['SEC'],
36
- allowedLabels: ['SEC'],
37
- },
38
- {
39
- id: 'indonesian-readable-service',
40
- requestText: 'Rapihin service ini biar namingnya enak dibaca.',
41
- requiredLabels: ['ARCH'],
42
- allowedLabels: ['ARCH'],
43
- },
44
- {
45
- id: 'natural-cron-silent',
46
- requestText: 'My cron stops silently, need logs and retry.',
47
- requiredLabels: ['JOB', 'ERR', 'OBS', 'RES'],
48
- allowedLabels: ['JOB', 'ERR', 'OBS', 'RES'],
49
- },
50
- {
51
- id: 'auth-middleware-duplicate',
52
- requestText: 'Remove duplicate code in auth middleware.',
53
- requiredLabels: ['SEC', 'ARCH'],
54
- allowedLabels: ['SEC', 'ARCH'],
55
- },
56
- {
57
- id: 'indonesian-slow-query',
58
- requestText: 'Bisa cek kenapa checkout lemot banget pas query order.',
59
- requiredLabels: ['DATA', 'PERF'],
60
- allowedLabels: ['DATA', 'PERF'],
61
- },
62
- {
63
- id: 'config-exposing-key',
64
- requestText: 'Update env var for staging without exposing key.',
65
- requiredLabels: ['CFG', 'SEC'],
66
- allowedLabels: ['CFG', 'SEC'],
67
- },
68
- {
69
- id: 'token-budget-context-hardening',
70
- requestText: 'Tighten adaptive context token budget and benchmark reporting for real request corpus.',
71
- requiredLabels: ['ARCH', 'TEST'],
72
- allowedLabels: ['ARCH', 'TEST'],
73
- },
74
- {
75
- id: 'tenant-access-leak-indonesian',
76
- requestText: 'Pas login, user bisa lihat data tenant sebelah.',
77
- requiredLabels: ['SEC'],
78
- allowedLabels: ['SEC'],
79
- },
80
- {
81
- id: 'invoice-worker-no-log',
82
- requestText: 'Abis deploy, worker invoice ga jalan tapi ga ada error di log.',
83
- requiredLabels: ['JOB', 'ERR', 'OBS'],
84
- allowedLabels: ['JOB', 'ERR', 'OBS'],
85
- },
86
- {
87
- id: 'checkout-helper-naming',
88
- requestText: 'Rapihin nama variabel di checkout helper, jangan bikin abstraction baru.',
89
- requiredLabels: ['ARCH'],
90
- allowedLabels: ['ARCH'],
91
- },
92
- {
93
- id: 'mobile-button-cut-off',
94
- requestText: 'Button checkout kepotong di layar kecil.',
95
- requiredLabels: ['FE'],
96
- allowedLabels: ['FE'],
97
- },
98
- {
99
- id: 'production-migration-rollback',
100
- requestText: 'Migration order sukses locally tapi production rollback.',
101
- requiredLabels: ['MIG', 'ERR'],
102
- allowedLabels: ['MIG', 'ERR'],
103
- },
104
- {
105
- id: 'cancel-order-idempotent-endpoint',
106
- requestText: 'Buat endpoint cancel order idempotent dan documented.',
107
- requiredLabels: ['API'],
108
- allowedLabels: ['API'],
109
- },
110
- {
111
- id: 'production-env-secret-error',
112
- requestText: 'Env production salah kebaca, jangan tampilin secret di error.',
113
- requiredLabels: ['CFG', 'SEC', 'ERR'],
114
- allowedLabels: ['CFG', 'SEC', 'ERR'],
115
- },
116
- {
117
- id: 'websocket-reconnect-timeout',
118
- requestText: 'WebSocket reconnect sering timeout, perlu fallback.',
119
- requiredLabels: ['RT', 'RES'],
120
- allowedLabels: ['RT', 'RES'],
121
- },
122
- {
123
- id: 'invoice-query-timeout-nplusone',
124
- requestText: 'Query invoice timeout dan N+1.',
125
- requiredLabels: ['DATA', 'PERF', 'RES'],
126
- allowedLabels: ['DATA', 'PERF', 'RES'],
127
- },
128
-
129
- {
130
- id: 'frontend-redesign',
131
- requestText: 'Redesign this frontend screen from zero with responsive layout, motion, and UI design docs.',
132
- requiredLabels: ['FE'],
133
- allowedLabels: ['FE'],
134
- },
135
- {
136
- id: 'database-migration-failure',
137
- requestText: 'The database migration fails during rollback after a schema change. Check query impact and validation coverage.',
138
- requiredLabels: ['DATA', 'MIG', 'ERR', 'TEST'],
139
- allowedLabels: ['DATA', 'MIG', 'ERR', 'TEST'],
140
- },
141
- {
142
- id: 'docker-env-setup',
143
- requestText: 'Set up Docker Compose with env config and validation so the container can run locally.',
144
- requiredLabels: ['DOCK', 'CFG', 'TEST'],
145
- allowedLabels: ['DOCK', 'CFG', 'TEST'],
146
- },
147
- {
148
- id: 'worker-retry-observability',
149
- requestText: 'Fix the queue worker retry flow. It publishes events, needs fallback behavior, and should log trace data.',
150
- requiredLabels: ['JOB', 'EVT', 'RES', 'OBS', 'ERR'],
151
- allowedLabels: ['JOB', 'EVT', 'RES', 'OBS', 'ERR'],
152
- },
153
- {
154
- id: 'service-refactor-clean-code',
155
- requestText: 'Refactor this service module. Clean up helper names, avoid over-engineering, and keep tests readable.',
156
- requiredLabels: ['ARCH', 'TEST'],
157
- allowedLabels: ['ARCH', 'TEST'],
158
- },
159
- {
160
- id: 'versioned-api-endpoint',
161
- requestText: 'Design a versioned API endpoint contract with safe request validation, error responses, and backward compatibility.',
162
- requiredLabels: ['API', 'VER', 'ERR', 'SEC', 'TEST'],
163
- allowedLabels: ['API', 'VER', 'ERR', 'SEC', 'TEST'],
164
- },
165
- {
166
- id: 'slow-query-performance',
167
- requestText: 'The SQL query is slow and may be an N+1 issue. Add observability and a performance test.',
168
- requiredLabels: ['PERF', 'DATA', 'OBS', 'TEST'],
169
- allowedLabels: ['PERF', 'DATA', 'OBS', 'TEST'],
170
- },
171
- {
172
- id: 'config-secret-feature-flag',
173
- requestText: 'Add a feature flag from env config without leaking secrets in errors.',
174
- requiredLabels: ['CFG', 'SEC', 'ERR'],
175
- allowedLabels: ['CFG', 'SEC', 'ERR'],
176
- },
177
- {
178
- id: 'realtime-stream-contract',
179
- requestText: 'Plan a realtime WebSocket stream API with timeout recovery and monitoring.',
180
- requiredLabels: ['RT', 'API', 'RES', 'OBS'],
181
- allowedLabels: ['RT', 'API', 'RES', 'OBS'],
182
- },
183
- ];
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { evaluateAdaptiveContextFixtures } from '../lib/cli/adaptive-context.mjs';
4
- import { ADAPTIVE_CONTEXT_FIXTURES } from './adaptive-context/fixtures.mjs';
5
-
6
- const report = evaluateAdaptiveContextFixtures(ADAPTIVE_CONTEXT_FIXTURES);
7
-
8
- console.log(JSON.stringify(report, null, 2));
9
- process.exit(report.passed ? 0 : 1);
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { evaluateAscxFixtures } from '../lib/cli/ascx/fixture-evaluator.mjs';
4
- import { ASCX_RUNTIME_TOKEN_SAVER_FIXTURES } from '../benchmarks/runtime-token-saver/fixtures.mjs';
5
-
6
- const report = await evaluateAscxFixtures(ASCX_RUNTIME_TOKEN_SAVER_FIXTURES);
7
-
8
- console.log(JSON.stringify(report, null, 2));
9
- process.exit(report.passed ? 0 : 1);
@@ -1,263 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * audit-cache-layer-contract.mjs
4
- *
5
- * Phase 2 cache-layer integrity gate. Validates provider cache metadata,
6
- * fixture segmentation, and the emitted cache simulation JSON without calling
7
- * provider APIs.
8
- *
9
- * Boundary: this audit covers the TECHNICAL contract (provider matrix,
10
- * layer definitions, fixture segmentation, simulation result JSON shape).
11
- * For public-prose hygiene around caching saving figures see
12
- * audit-caching-scope-hygiene.mjs.
13
- */
14
-
15
- import { existsSync, readFileSync } from 'node:fs';
16
- import { dirname, join, resolve } from 'node:path';
17
- import { fileURLToPath } from 'node:url';
18
-
19
- import {
20
- CACHE_LAYER_DEFINITIONS,
21
- CACHE_LAYER_IDS,
22
- validateCacheLayerContract,
23
- } from '../benchmarks/token-usage/lib/cache-layer-contract.mjs';
24
- import {
25
- CACHE_MATRIX_VERIFIED_AT,
26
- PROVIDER_CACHE_MATRIX,
27
- listProviderCacheEntries,
28
- } from '../benchmarks/token-usage/lib/provider-cache-matrix.mjs';
29
- import {
30
- buildCacheLayeredScenarioPrompts,
31
- loadFixtures,
32
- } from '../benchmarks/token-usage/runners/_shared.mjs';
33
-
34
- const SCRIPT_FILE_PATH = fileURLToPath(import.meta.url);
35
- const REPOSITORY_ROOT = resolve(dirname(SCRIPT_FILE_PATH), '..');
36
- const DEFAULT_RESULT_PATH = join(REPOSITORY_ROOT, 'benchmarks', 'results', 'cache-phase-2-2026-05-16.json');
37
- const ARGS = new Set(process.argv.slice(2));
38
- const JSON_ONLY = ARGS.has('--json');
39
-
40
- const REQUIRED_PROVIDER_KEYS = [
41
- 'provider',
42
- 'sourceUrl',
43
- 'sourceType',
44
- 'verifiedAt',
45
- 'cacheMode',
46
- 'minimumCacheableTokens',
47
- 'costModel',
48
- ];
49
-
50
- function addViolation(violations, kind, detail, context = {}) {
51
- violations.push({ kind, detail, ...context });
52
- }
53
-
54
- function validateProviderMatrix(violations) {
55
- for (const entry of listProviderCacheEntries()) {
56
- for (const key of REQUIRED_PROVIDER_KEYS) {
57
- if (!(key in entry)) {
58
- addViolation(violations, 'provider-metadata.missing-key', `${entry.provider} missing ${key}`, { provider: entry.provider });
59
- }
60
- }
61
-
62
- if (entry.sourceType === 'official-docs') {
63
- if (typeof entry.sourceUrl !== 'string' || !entry.sourceUrl.startsWith('https://')) {
64
- addViolation(violations, 'provider-metadata.invalid-source-url', `${entry.provider} official sourceUrl must be https`, { provider: entry.provider });
65
- }
66
- if (entry.verifiedAt !== CACHE_MATRIX_VERIFIED_AT) {
67
- addViolation(violations, 'provider-metadata.invalid-verified-at', `${entry.provider} verifiedAt must be ${CACHE_MATRIX_VERIFIED_AT}`, { provider: entry.provider });
68
- }
69
- }
70
-
71
- if (entry.provider === 'anthropic') {
72
- const ttlOptions = entry.costModel?.ttlOptions;
73
- if (ttlOptions?.['5m']?.writeMultiplier !== 1.25 || ttlOptions?.['5m']?.readMultiplier !== 0.1) {
74
- addViolation(violations, 'provider-metadata.anthropic-5m-multiplier', 'Anthropic 5m cache multipliers drifted');
75
- }
76
- if (ttlOptions?.['1h']?.writeMultiplier !== 2.0 || ttlOptions?.['1h']?.readMultiplier !== 0.1) {
77
- addViolation(violations, 'provider-metadata.anthropic-1h-multiplier', 'Anthropic 1h cache multipliers drifted');
78
- }
79
- }
80
-
81
- if (['openai', 'gemini'].includes(entry.provider) && entry.costModel?.accurate !== false) {
82
- addViolation(violations, 'provider-metadata.fake-universal-pricing', `${entry.provider} must not claim universal accurate pricing`, { provider: entry.provider });
83
- }
84
- }
85
- }
86
-
87
- function validateLayerDefinitions(violations) {
88
- const definitionIds = Object.keys(CACHE_LAYER_DEFINITIONS);
89
- const uniqueDefinitionIds = new Set(definitionIds);
90
- if (definitionIds.length !== uniqueDefinitionIds.size) {
91
- addViolation(violations, 'layer-definition.duplicate-id', 'Cache layer definition IDs must be unique');
92
- }
93
-
94
- const expectedIds = [
95
- CACHE_LAYER_IDS.STATIC_PREFIX,
96
- CACHE_LAYER_IDS.SEMI_STATIC_CONTEXT,
97
- CACHE_LAYER_IDS.DYNAMIC_SUFFIX,
98
- ];
99
- if (JSON.stringify(definitionIds) !== JSON.stringify(expectedIds)) {
100
- addViolation(violations, 'layer-definition.unexpected-order', `Expected ${expectedIds.join(', ')}, got ${definitionIds.join(', ')}`);
101
- }
102
- }
103
-
104
- function validateFixtureSegmentation(violations) {
105
- const fixtures = loadFixtures();
106
- let auditedScenarioCount = 0;
107
- for (const fixture of fixtures) {
108
- const layered = buildCacheLayeredScenarioPrompts(fixture);
109
- const scenarios = [
110
- { name: 'always_included', contract: layered.alwaysIncluded },
111
- { name: 'with_loaded_rules', contract: layered.withLoadedRules },
112
- ];
113
-
114
- for (const scenario of scenarios) {
115
- auditedScenarioCount += 1;
116
- try {
117
- validateCacheLayerContract(scenario.contract);
118
- } catch (error) {
119
- addViolation(violations, 'fixture-segmentation.invalid-contract', error.message, {
120
- fixture_id: fixture.id,
121
- scenario: scenario.name,
122
- });
123
- }
124
-
125
- const layerIds = scenario.contract.layers.map((layer) => layer.id);
126
- if (new Set(layerIds).size !== layerIds.length) {
127
- addViolation(violations, 'fixture-segmentation.duplicate-layer-id', 'Fixture contract contains duplicate layer IDs', {
128
- fixture_id: fixture.id,
129
- scenario: scenario.name,
130
- });
131
- }
132
-
133
- for (const layer of [
134
- scenario.contract.layer_1_static_prefix,
135
- scenario.contract.layer_2_semi_static_context,
136
- ]) {
137
- if (layer.content.includes(fixture.user_message)) {
138
- addViolation(violations, 'fixture-segmentation.dynamic-leak', `Fixture user message leaked into ${layer.id}`, {
139
- fixture_id: fixture.id,
140
- scenario: scenario.name,
141
- });
142
- }
143
- }
144
-
145
- if (scenario.contract.layer_3_dynamic_suffix.content.trim().length === 0) {
146
- addViolation(violations, 'fixture-segmentation.missing-dynamic-layer', 'Layer 3 dynamic suffix is empty', {
147
- fixture_id: fixture.id,
148
- scenario: scenario.name,
149
- });
150
- }
151
- }
152
- }
153
- return { fixtureCount: fixtures.length, auditedScenarioCount };
154
- }
155
-
156
- function validateSimulationResultJson(violations, resultPath = DEFAULT_RESULT_PATH) {
157
- if (!existsSync(resultPath)) {
158
- addViolation(violations, 'result-json.missing', `Missing cache simulation result: ${resultPath}`);
159
- return { resultPath, resultCount: 0 };
160
- }
161
-
162
- const parsed = JSON.parse(readFileSync(resultPath, 'utf8'));
163
- if (parsed.report_version !== '2.0.0') {
164
- addViolation(violations, 'result-json.schema-version', `Unexpected report_version ${parsed.report_version}`);
165
- }
166
- if (!Array.isArray(parsed.results) || parsed.results.length === 0) {
167
- addViolation(violations, 'result-json.results-empty', 'results must be a non-empty array');
168
- return { resultPath, resultCount: 0 };
169
- }
170
-
171
- const expectedResultCount = parsed.fixture_count * parsed.provider_count * parsed.scenario_count;
172
- if (parsed.results.length !== expectedResultCount) {
173
- addViolation(violations, 'result-json.result-count', `Expected ${expectedResultCount} rows, got ${parsed.results.length}`);
174
- }
175
-
176
- for (const result of parsed.results) {
177
- if (!result.token_counts || !result.economic_projection) {
178
- addViolation(violations, 'result-json.missing-separation', 'Result must separate token_counts and economic_projection', {
179
- fixture_id: result.fixture_id,
180
- provider: result.provider,
181
- scenario: result.scenario,
182
- });
183
- continue;
184
- }
185
- if (typeof result.token_counts.layer_3_dynamic_suffix !== 'number' || result.token_counts.layer_3_dynamic_suffix <= 0) {
186
- addViolation(violations, 'result-json.missing-layer-3-tokens', 'Layer 3 token count must be present and positive', {
187
- fixture_id: result.fixture_id,
188
- provider: result.provider,
189
- scenario: result.scenario,
190
- });
191
- }
192
- if (result.economic_projection.accurate === true && (!result.source?.sourceUrl || !result.source?.verifiedAt)) {
193
- addViolation(violations, 'result-json.accurate-without-source', 'Accurate projection requires official source metadata', {
194
- fixture_id: result.fixture_id,
195
- provider: result.provider,
196
- scenario: result.scenario,
197
- });
198
- }
199
- if (['openai', 'gemini'].includes(result.provider) && result.economic_projection.first_request_effective_tokens !== null) {
200
- addViolation(violations, 'result-json.fake-openai-gemini-savings', `${result.provider} must not emit exact savings without pricing metadata`, {
201
- fixture_id: result.fixture_id,
202
- scenario: result.scenario,
203
- });
204
- }
205
- }
206
-
207
- return { resultPath, resultCount: parsed.results.length };
208
- }
209
-
210
- export function runCacheLayerContractAudit({ resultPath = DEFAULT_RESULT_PATH } = {}) {
211
- const violations = [];
212
- validateProviderMatrix(violations);
213
- validateLayerDefinitions(violations);
214
- const segmentationStats = validateFixtureSegmentation(violations);
215
- const resultStats = validateSimulationResultJson(violations, resultPath);
216
-
217
- return {
218
- auditName: 'audit-cache-layer-contract',
219
- reportVersion: '1.0.0',
220
- generatedAt: new Date().toISOString(),
221
- providerCount: Object.keys(PROVIDER_CACHE_MATRIX).length,
222
- ...segmentationStats,
223
- ...resultStats,
224
- violationCount: violations.length,
225
- violations,
226
- passed: violations.length === 0,
227
- };
228
- }
229
-
230
- function main() {
231
- const report = runCacheLayerContractAudit();
232
-
233
- if (JSON_ONLY) {
234
- process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
235
- process.exit(report.passed ? 0 : 1);
236
- }
237
-
238
- console.log('===============================================');
239
- console.log(' audit:cache-layer-contract');
240
- console.log('===============================================');
241
- console.log(` Providers: ${report.providerCount}`);
242
- console.log(` Fixtures: ${report.fixtureCount}`);
243
- console.log(` Layered scenarios: ${report.auditedScenarioCount}`);
244
- console.log(` Result rows: ${report.resultCount}`);
245
- console.log('');
246
-
247
- if (report.passed) {
248
- console.log(' Cache layer contract audit clean.');
249
- process.stderr.write(`AUDIT_CACHE_LAYER_REPORT: ${JSON.stringify({ passed: true, providerCount: report.providerCount, resultCount: report.resultCount })}\n`);
250
- process.exit(0);
251
- }
252
-
253
- console.log(' Violations:');
254
- for (const violation of report.violations) {
255
- console.log(` [${violation.kind}] ${violation.detail}`);
256
- }
257
- process.stderr.write(`AUDIT_CACHE_LAYER_REPORT: ${JSON.stringify({ passed: false, violationCount: report.violationCount })}\n`);
258
- process.exit(1);
259
- }
260
-
261
- if (import.meta.url === `file://${process.argv[1].replace(/\\/g, '/')}` || process.argv[1].endsWith('audit-cache-layer-contract.mjs')) {
262
- main();
263
- }