@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,359 +0,0 @@
1
- export const COMPACT_NATURAL_MODE_FIXTURES = [
2
- {
3
- id: 'implementation-summary-ascx-diff',
4
- taskType: 'implementation-summary',
5
- minimumReductionPercent: 35,
6
- baseline: [
7
- 'Sure, I finished the ASCX git diff work. I added the new adapter in lib/cli/ascx/adapters/git-diff.mjs and wired the runtime so that ascx git diff can now summarize supported unified diffs.',
8
- 'The important thing is that it keeps changed files and hunk anchors visible while moving hidden details to the raw tee when truncation happens.',
9
- 'I also ran npm run benchmark:ascx and it passed, so the next thing is to keep the adapter whitelist frozen until a new command has fixtures and continuation checks.',
10
- ].join('\n'),
11
- candidate: [
12
- 'Changed: `lib/cli/ascx/adapters/git-diff.mjs`; runtime now supports `ascx git diff`.',
13
- 'Reason: Diff output compact; changed files, hunk anchors, and raw tee safety stay visible.',
14
- 'Validation: `npm run benchmark:ascx` passed.',
15
- 'Next: Keep adapter whitelist frozen until the next command has fixtures and continuation checks.',
16
- ].join('\n'),
17
- evidenceAtoms: [
18
- { id: 'adapter-path', text: 'lib/cli/ascx/adapters/git-diff.mjs' },
19
- { id: 'command', text: 'ascx git diff' },
20
- { id: 'validation-command', text: 'npm run benchmark:ascx' },
21
- ],
22
- requiredClaims: [
23
- { id: 'diff-output-compact', all: ['Diff output', 'compact'] },
24
- { id: 'hunk-anchors-preserved', all: ['hunk anchors', 'visible'] },
25
- { id: 'raw-tee-safety', all: ['raw tee', 'safety'] },
26
- ],
27
- requiredActions: [
28
- { id: 'freeze-whitelist', all: ['Keep', 'adapter whitelist', 'frozen'] },
29
- ],
30
- calibrationRequirements: [
31
- { id: 'validation-status', all: ['Validation', 'passed'] },
32
- ],
33
- negativeControls: [
34
- {
35
- id: 'drops-validation',
36
- text: [
37
- 'Changed: Added the diff adapter and wired it into ASCX.',
38
- 'Next: Use it for all diff output now.',
39
- ].join('\n'),
40
- },
41
- ],
42
- },
43
- {
44
- id: 'debug-root-cause-session-id',
45
- taskType: 'debug-root-cause',
46
- minimumReductionPercent: 30,
47
- baseline: [
48
- 'The most likely root cause is that the auth callback assumes user is always defined, but in this failing path it is undefined.',
49
- 'The exact error is TypeError: Cannot read properties of undefined (reading "id"), and the stack points at src/auth/callback.ts:42:17.',
50
- 'The fix is to guard user before reading user.id, for example by returning early when user is missing, then rerun npm test -- auth.test.mjs to verify the callback path.',
51
- ].join('\n'),
52
- candidate: [
53
- 'Root Cause: The auth callback reads `user.id` before proving `user` exists.',
54
- 'Evidence: `TypeError: Cannot read properties of undefined (reading "id")` at `src/auth/callback.ts:42:17`.',
55
- 'Fix: Add an early guard before `user.id`.',
56
- 'Next: Run `npm test -- auth.test.mjs`.',
57
- ].join('\n'),
58
- evidenceAtoms: [
59
- { id: 'error-message', text: 'TypeError: Cannot read properties of undefined (reading "id")' },
60
- { id: 'file-line', text: 'src/auth/callback.ts:42:17' },
61
- { id: 'identifier', text: 'user.id' },
62
- { id: 'verify-command', text: 'npm test -- auth.test.mjs' },
63
- ],
64
- requiredClaims: [
65
- { id: 'root-cause', all: ['callback', 'user.id'] },
66
- { id: 'fix-direction', all: ['guard', 'user.id'] },
67
- ],
68
- requiredActions: [
69
- { id: 'run-target-test', text: 'npm test -- auth.test.mjs' },
70
- ],
71
- calibrationRequirements: [
72
- { id: 'evidence-labelled', text: 'Evidence:' },
73
- ],
74
- negativeControls: [
75
- {
76
- id: 'paraphrases-error-and-path',
77
- text: 'Root Cause: The auth code has a missing null check. Fix it and rerun the auth tests.',
78
- },
79
- ],
80
- },
81
- {
82
- id: 'test-failure-order-total',
83
- taskType: 'test-failure',
84
- minimumReductionPercent: 30,
85
- baseline: [
86
- 'The failing test is calculates order total. It expected the order total calculation to return 42, but the actual value was 41.',
87
- 'The exact assertion is AssertionError [ERR_ASSERTION]: 41 !== 42 at tests/order-total.test.mjs:18:10.',
88
- 'The fix direction is to inspect the discount or rounding branch used by calculateTotalPrice and then rerun npm test -- order-total.test.mjs.',
89
- ].join('\n'),
90
- candidate: [
91
- 'Failed: `calculates order total`',
92
- 'Expected/Got: `42` / `41`',
93
- 'At: `tests/order-total.test.mjs:18:10`',
94
- 'Evidence: `AssertionError [ERR_ASSERTION]: 41 !== 42`.',
95
- 'Fix direction: Inspect `calculateTotalPrice` discount/rounding; run `npm test -- order-total.test.mjs`.',
96
- ].join('\n'),
97
- evidenceAtoms: [
98
- { id: 'test-name', text: 'calculates order total' },
99
- { id: 'expected', text: '42' },
100
- { id: 'actual', text: '41' },
101
- { id: 'file-line', text: 'tests/order-total.test.mjs:18:10' },
102
- { id: 'assertion', text: 'AssertionError [ERR_ASSERTION]: 41 !== 42' },
103
- { id: 'identifier', text: 'calculateTotalPrice' },
104
- { id: 'verify-command', text: 'npm test -- order-total.test.mjs' },
105
- ],
106
- requiredClaims: [
107
- { id: 'mismatch-explained', all: ['Expected', 'Got'] },
108
- { id: 'fix-target', text: 'calculateTotalPrice' },
109
- ],
110
- requiredActions: [
111
- { id: 'rerun-test', text: 'npm test -- order-total.test.mjs' },
112
- ],
113
- calibrationRequirements: [
114
- { id: 'evidence-preserved', text: 'Evidence:' },
115
- ],
116
- negativeControls: [
117
- {
118
- id: 'hides-assertion',
119
- text: [
120
- 'Failed: order total test.',
121
- 'Fix direction: Check the total calculation and rerun the test.',
122
- ].join('\n'),
123
- },
124
- ],
125
- },
126
- {
127
- id: 'code-review-auth-guard',
128
- taskType: 'code-review',
129
- minimumReductionPercent: 40,
130
- baseline: [
131
- 'I would flag this as a warning in src/auth/middleware.ts:58 because req.user is read before the middleware verifies that the auth guard actually attached a user.',
132
- 'That means unauthenticated requests can throw a runtime error instead of returning the documented 401 response.',
133
- 'Please add an early 401 return when req.user is missing and add a regression test for that path.',
134
- ].join('\n'),
135
- candidate: '[warn] `src/auth/middleware.ts:58` - `req.user` is read before the guard proves it exists. Return 401 when `req.user` is missing and add a regression test for the unauthenticated path.',
136
- evidenceAtoms: [
137
- { id: 'severity', text: '[warn]' },
138
- { id: 'file-line', text: 'src/auth/middleware.ts:58' },
139
- { id: 'identifier', text: 'req.user' },
140
- { id: 'status-code', text: '401' },
141
- ],
142
- requiredClaims: [
143
- { id: 'concern', all: ['read before', 'exists'] },
144
- { id: 'impact', text: 'unauthenticated' },
145
- ],
146
- requiredActions: [
147
- { id: 'return-401', all: ['Return 401', 'missing'] },
148
- { id: 'add-test', text: 'regression test' },
149
- ],
150
- calibrationRequirements: [
151
- { id: 'severity-visible', text: '[warn]' },
152
- ],
153
- negativeControls: [
154
- {
155
- id: 'assertion-without-evidence',
156
- text: '[warn] Auth middleware is fragile. Please clean it up.',
157
- },
158
- ],
159
- },
160
- {
161
- id: 'refactor-summary-behavior-not-verified',
162
- taskType: 'refactor-summary',
163
- minimumReductionPercent: 35,
164
- baseline: [
165
- 'I refactored src/orders/price.ts by splitting the discount calculation out of calculateOrderTotal into calculateDiscountAmount.',
166
- 'The intended behavior is unchanged, but I did not run tests in this environment, so that claim is not verified yet.',
167
- 'The risk is around rounding for percentage discounts. The next step is to run npm test -- order-total.test.mjs.',
168
- ].join('\n'),
169
- candidate: [
170
- 'Changed: `src/orders/price.ts`: split `calculateOrderTotal` into `calculateDiscountAmount`.',
171
- 'Behavior: intended no, but not verified; tests not run.',
172
- 'Risk: percentage-discount rounding.',
173
- 'Next: `npm test -- order-total.test.mjs`.',
174
- ].join('\n'),
175
- evidenceAtoms: [
176
- { id: 'file-path', text: 'src/orders/price.ts' },
177
- { id: 'old-function', text: 'calculateOrderTotal' },
178
- { id: 'new-function', text: 'calculateDiscountAmount' },
179
- { id: 'validation-gap', text: 'tests not run' },
180
- { id: 'next-command', text: 'npm test -- order-total.test.mjs' },
181
- ],
182
- requiredClaims: [
183
- { id: 'behavior-claim-qualified', all: ['intended no', 'not verified'] },
184
- { id: 'risk-visible', text: 'percentage-discount rounding' },
185
- ],
186
- requiredActions: [
187
- { id: 'run-tests', text: 'npm test -- order-total.test.mjs' },
188
- ],
189
- calibrationRequirements: [
190
- { id: 'not-verified', all: ['not verified', 'tests not run'] },
191
- ],
192
- forbiddenOverconfidence: [
193
- 'behavior is unchanged and verified',
194
- 'fully verified',
195
- ],
196
- negativeControls: [
197
- {
198
- id: 'overstates-verification',
199
- text: 'Changed: Refactored order pricing. Behavior is unchanged and verified. Next: merge it.',
200
- },
201
- ],
202
- },
203
- {
204
- id: 'security-finding-idor',
205
- taskType: 'security-finding',
206
- minimumReductionPercent: 10,
207
- minimumCqs: 0.9,
208
- baseline: [
209
- 'This is a high severity IDOR issue in src/api/users/[id]/route.ts:27. The route loads a user by params.id but does not check whether the authenticated user is allowed to read that record.',
210
- 'The impact is that one authenticated user can read another user profile by changing the id in the URL.',
211
- 'The remediation is to compare params.id with session.user.id or enforce an admin permission before returning the profile, then add an authorization regression test.',
212
- ].join('\n'),
213
- candidate: [
214
- 'Severity: high',
215
- 'Class: IDOR',
216
- 'Location: `src/api/users/[id]/route.ts:27`',
217
- 'Impact: An authenticated user can read another user profile by changing `params.id`',
218
- 'Evidence: The route loads by `params.id` without checking `session.user.id` or admin permission',
219
- 'Remediation: Require owner match or admin permission before returning the profile',
220
- 'Validation: Add an authorization regression test',
221
- ].join('\n'),
222
- evidenceAtoms: [
223
- { id: 'severity', text: 'high' },
224
- { id: 'class', text: 'IDOR' },
225
- { id: 'location', text: 'src/api/users/[id]/route.ts:27' },
226
- { id: 'param', text: 'params.id' },
227
- { id: 'session', text: 'session.user.id' },
228
- { id: 'validation', text: 'authorization regression test' },
229
- ],
230
- requiredClaims: [
231
- { id: 'impact', all: ['authenticated user', 'another user profile'] },
232
- { id: 'remediation', all: ['owner match', 'admin permission'] },
233
- ],
234
- requiredActions: [
235
- { id: 'add-security-test', text: 'authorization regression test' },
236
- ],
237
- calibrationRequirements: [
238
- { id: 'severity-visible', text: 'Severity: high' },
239
- ],
240
- negativeControls: [
241
- {
242
- id: 'compresses-away-impact',
243
- text: 'Security: user route needs a permission check. Fix the auth check.',
244
- },
245
- ],
246
- },
247
- {
248
- id: 'destructive-command-warning',
249
- taskType: 'destructive-command',
250
- minimumReductionPercent: 20,
251
- baseline: [
252
- 'This command is destructive: rm -rf .agent-context/state/token-saver/tee removes all saved raw ASCX tee logs.',
253
- 'It is not reversible unless those files are backed up elsewhere, so only run it after confirming you no longer need raw command evidence for failed or truncated outputs.',
254
- ].join('\n'),
255
- candidate: [
256
- 'WARNING: This deletes all saved ASCX raw tee logs and is not reversible unless backed up.',
257
- 'Command: `rm -rf .agent-context/state/token-saver/tee`',
258
- 'Precondition: Confirm no failed or truncated command evidence is still needed.',
259
- ].join('\n'),
260
- evidenceAtoms: [
261
- { id: 'warning', text: 'WARNING:' },
262
- { id: 'command', text: 'rm -rf .agent-context/state/token-saver/tee' },
263
- { id: 'irreversible', text: 'not reversible' },
264
- { id: 'evidence', text: 'failed or truncated command evidence' },
265
- ],
266
- requiredClaims: [
267
- { id: 'destructive-impact', all: ['deletes', 'raw tee logs'] },
268
- ],
269
- requiredActions: [
270
- { id: 'precondition', regex: 'Precondition:.*confirm' },
271
- ],
272
- calibrationRequirements: [
273
- { id: 'warning-visible', text: 'WARNING:' },
274
- ],
275
- negativeControls: [
276
- {
277
- id: 'drops-warning',
278
- text: 'Run `rm -rf .agent-context/state/token-saver/tee` to clean local output logs.',
279
- },
280
- ],
281
- },
282
- {
283
- id: 'planning-architecture-compact-mode',
284
- taskType: 'planning',
285
- minimumReductionPercent: 20,
286
- baseline: [
287
- 'The decision I recommend is to keep Compact Natural Mode instruction-only first rather than adding a runtime command or a proxy.',
288
- 'The reason is that this mode changes user-facing response shape, not tool output, so the safest first layer is a benchmarked instruction contract.',
289
- 'The main alternative is a second-pass self-compression command, but that adds latency and can delete evidence unless it has a strong preservation gate.',
290
- 'The tradeoff is that instruction-only behavior is less enforceable, so the open question is whether the benchmark should later become a validation command.',
291
- ].join('\n'),
292
- candidate: [
293
- 'Decision: Start Compact Natural Mode as an instruction-only contract.',
294
- 'Rationale: It shapes user-facing replies, not command output; it must be benchmarked before entering `AGENTS.md`.',
295
- 'Alternative: A second-pass compression command can enforce shape, but adds latency and can delete evidence without a preservation gate.',
296
- 'Tradeoff: Lighter, less enforceable.',
297
- 'Open question: Should this become `asc optimize compact benchmark`?',
298
- ].join('\n'),
299
- evidenceAtoms: [
300
- { id: 'decision', text: 'instruction-only contract' },
301
- { id: 'surface', text: 'AGENTS.md' },
302
- { id: 'alternative', text: 'second-pass compression command' },
303
- { id: 'open-question', text: 'asc optimize compact benchmark' },
304
- ],
305
- requiredClaims: [
306
- { id: 'not-command-output', all: ['user-facing replies', 'not command output'] },
307
- { id: 'latency-risk', all: ['latency', 'delete evidence'] },
308
- { id: 'tradeoff', all: ['lighter', 'less enforceable'] },
309
- ],
310
- requiredActions: [
311
- { id: 'benchmark-first', all: ['benchmarked', 'before entering'] },
312
- ],
313
- calibrationRequirements: [
314
- { id: 'open-question-visible', text: 'Open question:' },
315
- ],
316
- negativeControls: [
317
- {
318
- id: 'too-short-to-plan',
319
- text: 'Decision: Add Compact Natural Mode to AGENTS.md now. It is simple and saves tokens.',
320
- },
321
- ],
322
- },
323
- {
324
- id: 'assumption-challenge-framework-version',
325
- taskType: 'assumption-challenge',
326
- minimumReductionPercent: 30,
327
- baseline: [
328
- 'I am assuming this project is on Next.js 15 because package.json lists next at ^15.2.0. If that assumption is wrong, the routing and server-action guidance may not apply.',
329
- 'The next step is to confirm the installed version with npm ls next before changing the route handler behavior.',
330
- ].join('\n'),
331
- candidate: [
332
- 'Assumption: Next.js 15; `package.json` lists `next` as `^15.2.0`.',
333
- 'Consequence if wrong: Route-handler/server-action guidance may not apply.',
334
- 'Next: `npm ls next` before changing route behavior.',
335
- ].join('\n'),
336
- evidenceAtoms: [
337
- { id: 'assumption', text: 'Assumption:' },
338
- { id: 'package-file', text: 'package.json' },
339
- { id: 'version', text: '^15.2.0' },
340
- { id: 'command', text: 'npm ls next' },
341
- ],
342
- requiredClaims: [
343
- { id: 'consequence', all: ['Consequence if wrong', 'may not apply'] },
344
- ],
345
- requiredActions: [
346
- { id: 'verify-version', text: 'npm ls next' },
347
- ],
348
- calibrationRequirements: [
349
- { id: 'assumption-labelled', text: 'Assumption:' },
350
- { id: 'consequence-labelled', text: 'Consequence if wrong:' },
351
- ],
352
- negativeControls: [
353
- {
354
- id: 'assumption-as-fact',
355
- text: 'This project uses Next.js 15. Update the route handler and server actions, then run tests.',
356
- },
357
- ],
358
- },
359
- ];
@@ -1,331 +0,0 @@
1
- import { estimateOutputTokens } from '../../lib/cli/ascx/token-estimate.mjs';
2
-
3
- const DEFAULT_MINIMUM_CQS = 0.8;
4
- const DEFAULT_MINIMUM_REDUCTION_PERCENT = 0;
5
-
6
- const FILLER_PATTERNS = [
7
- /\bsure[,.!]?/iu,
8
- /\bgreat question\b/iu,
9
- /\bi(?:'|’)ll now\b/iu,
10
- /\blet me\b/iu,
11
- /\bi(?:'|’)d be happy to\b/iu,
12
- /\bhope this helps\b/iu,
13
- /\blet me know if\b/iu,
14
- ];
15
-
16
- const REGISTER_FAILURE_PATTERNS = [
17
- /\bwhy use many token\b/iu,
18
- /\boog\b/iu,
19
- /\bcaveman\b/iu,
20
- /\bgrunt\b/iu,
21
- /\bbrain still big\b/iu,
22
- ];
23
-
24
- function normalizeText(value) {
25
- return String(value || '').toLowerCase();
26
- }
27
-
28
- function toRequirementLabel(requirementEntry, fallbackIndex) {
29
- if (typeof requirementEntry === 'string') {
30
- return requirementEntry;
31
- }
32
-
33
- return requirementEntry.id || requirementEntry.text || requirementEntry.regex || `requirement-${fallbackIndex + 1}`;
34
- }
35
-
36
- function matchRequirement(text, requirementEntry) {
37
- const rawText = String(text || '');
38
- const normalized = normalizeText(rawText);
39
-
40
- if (typeof requirementEntry === 'string') {
41
- return normalized.includes(normalizeText(requirementEntry));
42
- }
43
-
44
- if (requirementEntry.text) {
45
- return normalized.includes(normalizeText(requirementEntry.text));
46
- }
47
-
48
- if (Array.isArray(requirementEntry.all)) {
49
- return requirementEntry.all.every((part) => normalized.includes(normalizeText(part)));
50
- }
51
-
52
- if (Array.isArray(requirementEntry.any)) {
53
- return requirementEntry.any.some((part) => normalized.includes(normalizeText(part)));
54
- }
55
-
56
- if (requirementEntry.regex) {
57
- return new RegExp(requirementEntry.regex, 'iu').test(rawText);
58
- }
59
-
60
- return false;
61
- }
62
-
63
- function findMissingRequirements(text, requirementEntries) {
64
- return (requirementEntries || []).filter((requirementEntry, index) => {
65
- return !matchRequirement(text, requirementEntry);
66
- }).map(toRequirementLabel);
67
- }
68
-
69
- function findMatchedPatterns(text, patterns) {
70
- return (patterns || []).filter((patternEntry) => {
71
- if (patternEntry instanceof RegExp) {
72
- return patternEntry.test(text);
73
- }
74
-
75
- return new RegExp(String(patternEntry), 'iu').test(text);
76
- }).map((patternEntry) => String(patternEntry));
77
- }
78
-
79
- function countSentences(text) {
80
- const matches = String(text || '').match(/[^.!?\n]+[.!?]/gu);
81
-
82
- return matches ? matches.length : 0;
83
- }
84
-
85
- function scoreCoverage(totalCount, missingCount) {
86
- if (totalCount === 0) {
87
- return 3;
88
- }
89
-
90
- const coverage = (totalCount - missingCount) / totalCount;
91
-
92
- if (coverage === 1) {
93
- return 3;
94
- }
95
-
96
- if (coverage >= 0.75) {
97
- return 2;
98
- }
99
-
100
- if (coverage >= 0.5) {
101
- return 1;
102
- }
103
-
104
- return 0;
105
- }
106
-
107
- function scoreRegister({ candidateText, fixtureEntry }) {
108
- const matchedGlobalPatterns = findMatchedPatterns(candidateText, REGISTER_FAILURE_PATTERNS);
109
- const matchedFixturePatterns = findMatchedPatterns(candidateText, fixtureEntry.forbiddenRegisterPatterns || []);
110
- const violationCount = matchedGlobalPatterns.length + matchedFixturePatterns.length;
111
-
112
- if (violationCount === 0) {
113
- return {
114
- score: 3,
115
- matchedGlobalPatterns,
116
- matchedFixturePatterns,
117
- };
118
- }
119
-
120
- if (violationCount === 1) {
121
- return {
122
- score: 2,
123
- matchedGlobalPatterns,
124
- matchedFixturePatterns,
125
- };
126
- }
127
-
128
- if (violationCount === 2) {
129
- return {
130
- score: 1,
131
- matchedGlobalPatterns,
132
- matchedFixturePatterns,
133
- };
134
- }
135
-
136
- return {
137
- score: 0,
138
- matchedGlobalPatterns,
139
- matchedFixturePatterns,
140
- };
141
- }
142
-
143
- function scoreRedundancy({
144
- baselineText,
145
- candidateText,
146
- reductionPercent,
147
- fixtureEntry,
148
- }) {
149
- const fillerMatches = findMatchedPatterns(candidateText, FILLER_PATTERNS);
150
- const baselineSentenceCount = countSentences(baselineText);
151
- const candidateSentenceCount = countSentences(candidateText);
152
- const targetReduction = typeof fixtureEntry.redundancyReductionTargetPercent === 'number'
153
- ? fixtureEntry.redundancyReductionTargetPercent
154
- : Math.min(Math.max(fixtureEntry.minimumReductionPercent || 0, 10), 35);
155
- const sentenceRatio = baselineSentenceCount === 0
156
- ? 1
157
- : candidateSentenceCount / baselineSentenceCount;
158
-
159
- if (fillerMatches.length === 0 && reductionPercent >= targetReduction && sentenceRatio <= 1) {
160
- return {
161
- score: 3,
162
- fillerMatches,
163
- baselineSentenceCount,
164
- candidateSentenceCount,
165
- targetReduction,
166
- };
167
- }
168
-
169
- if (fillerMatches.length <= 1 && reductionPercent >= 0 && sentenceRatio <= 1.2) {
170
- return {
171
- score: 2,
172
- fillerMatches,
173
- baselineSentenceCount,
174
- candidateSentenceCount,
175
- targetReduction,
176
- };
177
- }
178
-
179
- if (fillerMatches.length <= 2) {
180
- return {
181
- score: 1,
182
- fillerMatches,
183
- baselineSentenceCount,
184
- candidateSentenceCount,
185
- targetReduction,
186
- };
187
- }
188
-
189
- return {
190
- score: 0,
191
- fillerMatches,
192
- baselineSentenceCount,
193
- candidateSentenceCount,
194
- targetReduction,
195
- };
196
- }
197
-
198
- export function scoreCompactNaturalCandidate(fixtureEntry, candidateText) {
199
- const baselineText = fixtureEntry.baseline || '';
200
- const rawTokens = estimateOutputTokens(baselineText);
201
- const compactTokens = estimateOutputTokens(candidateText);
202
- const reductionPercent = rawTokens === 0
203
- ? 0
204
- : Number((((rawTokens - compactTokens) / rawTokens) * 100).toFixed(2));
205
- const missingEvidenceAtoms = findMissingRequirements(candidateText, fixtureEntry.evidenceAtoms);
206
- const missingRequiredClaims = findMissingRequirements(candidateText, fixtureEntry.requiredClaims);
207
- const missingRequiredActions = findMissingRequirements(candidateText, fixtureEntry.requiredActions);
208
- const missingCalibrationRequirements = findMissingRequirements(candidateText, fixtureEntry.calibrationRequirements);
209
- const forbiddenOverconfidence = findMatchedPatterns(candidateText, fixtureEntry.forbiddenOverconfidence || []);
210
- const register = scoreRegister({ candidateText, fixtureEntry });
211
- const redundancy = scoreRedundancy({
212
- baselineText,
213
- candidateText,
214
- reductionPercent,
215
- fixtureEntry,
216
- });
217
-
218
- const dimensionScores = {
219
- evidencePreservation: scoreCoverage((fixtureEntry.evidenceAtoms || []).length, missingEvidenceAtoms.length),
220
- semanticEquivalence: scoreCoverage((fixtureEntry.requiredClaims || []).length, missingRequiredClaims.length),
221
- actionability: scoreCoverage((fixtureEntry.requiredActions || []).length, missingRequiredActions.length),
222
- calibration: Math.min(
223
- scoreCoverage((fixtureEntry.calibrationRequirements || []).length, missingCalibrationRequirements.length),
224
- forbiddenOverconfidence.length > 0 ? 1 : 3
225
- ),
226
- registerQuality: register.score,
227
- redundancyElimination: redundancy.score,
228
- };
229
- const totalScore = Object.values(dimensionScores).reduce((sum, score) => sum + score, 0);
230
- const compactQualityScore = Number((totalScore / 18).toFixed(4));
231
- const minimumCqs = fixtureEntry.minimumCqs ?? DEFAULT_MINIMUM_CQS;
232
- const minimumReductionPercent = fixtureEntry.minimumReductionPercent ?? DEFAULT_MINIMUM_REDUCTION_PERCENT;
233
- const mandatoryEvidenceFailed = missingEvidenceAtoms.length > 0;
234
- const reductionPassed = reductionPercent >= minimumReductionPercent;
235
- const cqsPassed = compactQualityScore >= minimumCqs;
236
- const passed = !mandatoryEvidenceFailed
237
- && missingRequiredClaims.length === 0
238
- && missingRequiredActions.length === 0
239
- && missingCalibrationRequirements.length === 0
240
- && forbiddenOverconfidence.length === 0
241
- && register.score >= 2
242
- && cqsPassed
243
- && reductionPassed;
244
-
245
- return {
246
- passed,
247
- taskType: fixtureEntry.taskType,
248
- rawTokens,
249
- compactTokens,
250
- reductionPercent,
251
- minimumReductionPercent,
252
- compactQualityScore,
253
- minimumCqs,
254
- dimensionScores,
255
- mandatoryEvidenceFailed,
256
- missingEvidenceAtoms,
257
- missingRequiredClaims,
258
- missingRequiredActions,
259
- missingCalibrationRequirements,
260
- forbiddenOverconfidence,
261
- register,
262
- redundancy,
263
- };
264
- }
265
-
266
- function evaluateNegativeControls(fixtureEntry) {
267
- return (fixtureEntry.negativeControls || []).map((negativeControl) => {
268
- const score = scoreCompactNaturalCandidate(fixtureEntry, negativeControl.text);
269
-
270
- return {
271
- id: negativeControl.id,
272
- escaped: score.passed,
273
- score,
274
- };
275
- });
276
- }
277
-
278
- export function evaluateCompactNaturalFixtures(fixtures) {
279
- const results = fixtures.map((fixtureEntry) => {
280
- const score = scoreCompactNaturalCandidate(fixtureEntry, fixtureEntry.candidate);
281
- const negativeControls = evaluateNegativeControls(fixtureEntry);
282
-
283
- return {
284
- id: fixtureEntry.id,
285
- taskType: fixtureEntry.taskType,
286
- passed: score.passed && negativeControls.every((negativeControl) => !negativeControl.escaped),
287
- score,
288
- negativeControls,
289
- };
290
- });
291
- const failedResults = results.filter((result) => !result.passed);
292
- const negativeControlCount = results.reduce((total, result) => total + result.negativeControls.length, 0);
293
- const negativeControlEscapeCount = results.reduce((total, result) => {
294
- return total + result.negativeControls.filter((negativeControl) => negativeControl.escaped).length;
295
- }, 0);
296
- const rawTokens = results.reduce((total, result) => total + result.score.rawTokens, 0);
297
- const compactTokens = results.reduce((total, result) => total + result.score.compactTokens, 0);
298
- const mandatoryEvidenceFailureCount = results.filter((result) => result.score.mandatoryEvidenceFailed).length;
299
- const registerFailureCount = results.filter((result) => result.score.dimensionScores.registerQuality < 2).length;
300
- const averageCompactQualityScore = results.length === 0
301
- ? 0
302
- : Number((results.reduce((total, result) => total + result.score.compactQualityScore, 0) / results.length).toFixed(4));
303
-
304
- return {
305
- reportName: 'compact-natural-mode-benchmark',
306
- generatedAt: new Date().toISOString(),
307
- fixtureCount: results.length,
308
- passed: failedResults.length === 0 && negativeControlEscapeCount === 0,
309
- passedCount: results.length - failedResults.length,
310
- failedCount: failedResults.length,
311
- negativeControlCount,
312
- negativeControlEscapeCount,
313
- summary: {
314
- rawTokens,
315
- compactTokens,
316
- estimatedTokenReductionPercent: rawTokens === 0
317
- ? 0
318
- : Number((((rawTokens - compactTokens) / rawTokens) * 100).toFixed(2)),
319
- averageCompactQualityScore,
320
- mandatoryEvidenceFailureCount,
321
- registerFailureCount,
322
- semanticFailureCount: results.filter((result) => result.score.missingRequiredClaims.length > 0).length,
323
- actionabilityFailureCount: results.filter((result) => result.score.missingRequiredActions.length > 0).length,
324
- calibrationFailureCount: results.filter((result) => {
325
- return result.score.missingCalibrationRequirements.length > 0
326
- || result.score.forbiddenOverconfidence.length > 0;
327
- }).length,
328
- },
329
- results,
330
- };
331
- }