@besales/ops-framework 0.1.23 → 0.1.24

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.24
4
+
5
+ - Raised `standard_plus` Check/Verify context cap so near-cap plans stay in compact mode instead of jumping to slow strict context.
6
+ - Stabilized Check LLM `taskManifest` input by removing volatile `llmInput`, `lastCheckResult`, timestamps and verbose loop history from the prompt payload.
7
+ - Reduced duplicate external Check reruns after `task-manifest.json` refreshes by keeping prompt input stable when plan, memory and risk inputs have not changed.
8
+
3
9
  ## 0.1.23
4
10
 
5
11
  - Added deterministic import/ingestion planning gates for representative real fixtures, raw downstream metadata extraction and explicit duplicate-import behavior.
@@ -12,8 +12,8 @@ export const LLM_CONTEXT_MODES = ['fast', 'standard', 'standard_plus', 'strict']
12
12
  export const LLM_CONTEXT_CAPS = {
13
13
  fast: 8000,
14
14
  standard: 20000,
15
- standard_plus: 26000,
16
- strict: 45000,
15
+ standard_plus: 30000,
16
+ strict: 50000,
17
17
  };
18
18
 
19
19
  const TOKEN_ESTIMATE_CHARS_PER_TOKEN = 1.8;
@@ -225,7 +225,7 @@ export function buildCheckerLlmInputPack({
225
225
  relevantPlaybooks: selectedMode === 'strict'
226
226
  ? renderRelevantPlaybooks(readRelevantPlaybooks(checkContext.riskTriggers || []), { mode: 'strict' })
227
227
  : renderRelevantPlaybooks(readRelevantPlaybooks(checkContext.riskTriggers || []), { mode: 'compact' }),
228
- taskManifest,
228
+ taskManifest: stableTaskManifestForCheck(taskManifest),
229
229
  projectMemory: compactProjectMemory(projectMemory, selectedMode),
230
230
  taskArtifacts: artifacts,
231
231
  outputContract: {
@@ -249,6 +249,61 @@ export function buildCheckerLlmInputPack({
249
249
  return withPackMetadata(input, selectedMode);
250
250
  }
251
251
 
252
+ export function stableTaskManifestForCheck(taskManifest) {
253
+ let parsed = null;
254
+ if (typeof taskManifest === 'string') {
255
+ try {
256
+ parsed = JSON.parse(taskManifest);
257
+ } catch {
258
+ return taskManifest;
259
+ }
260
+ } else if (taskManifest && typeof taskManifest === 'object' && !Array.isArray(taskManifest)) {
261
+ parsed = taskManifest;
262
+ }
263
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
264
+ return taskManifest || '';
265
+ }
266
+
267
+ const stable = {
268
+ schemaVersion: parsed.schemaVersion,
269
+ taskId: parsed.taskId,
270
+ mode: parsed.mode,
271
+ phase: parsed.phase,
272
+ gates: parsed.gates,
273
+ context: {
274
+ planSha: parsed.context?.planSha,
275
+ planFingerprintVersion: parsed.context?.planFingerprintVersion,
276
+ memorySha: parsed.context?.memorySha,
277
+ riskProfile: parsed.context?.riskProfile,
278
+ riskTriggers: parsed.context?.riskTriggers,
279
+ riskWarnings: parsed.context?.riskWarnings,
280
+ checkContextCurrent: parsed.context?.checkContextCurrent,
281
+ },
282
+ requiredEvidenceIssues: parsed.requiredEvidenceIssues,
283
+ qualitySignals: parsed.qualitySignals,
284
+ loopDetector: {
285
+ threshold: parsed.loopDetector?.threshold,
286
+ requiresConsolidatedRemediation: parsed.loopDetector?.requiresConsolidatedRemediation,
287
+ repeatedReasons: parsed.loopDetector?.repeatedReasons,
288
+ },
289
+ consolidatedRemediationAccepted: parsed.consolidatedRemediationAccepted,
290
+ consolidatedRemediationArtifact: parsed.consolidatedRemediationArtifact,
291
+ };
292
+ return JSON.stringify(pruneUndefined(stable), null, 2);
293
+ }
294
+
295
+ function pruneUndefined(value) {
296
+ if (Array.isArray(value)) {
297
+ return value.map(pruneUndefined);
298
+ }
299
+ if (!value || typeof value !== 'object') {
300
+ return value;
301
+ }
302
+ return Object.fromEntries(Object.entries(value)
303
+ .filter(([, item]) => item !== undefined)
304
+ .map(([key, item]) => [key, pruneUndefined(item)]));
305
+ }
306
+
252
307
  export function buildVerifierLlmInputPack({
253
308
  taskDir,
254
309
  taskId,
@@ -112,12 +112,61 @@ describe('llm input pack utilities', () => {
112
112
  });
113
113
 
114
114
  expect(pack.meta.mode).toBe('standard_plus');
115
- expect(pack.meta.capTokens).toBe(26000);
115
+ expect(pack.meta.capTokens).toBe(30000);
116
116
  expect(pack.input.llmInputPolicy.contextInsufficientFallback).toBe('rerun_strict');
117
117
  expect(pack.input.taskArtifacts['plan.md']).toContain('<!-- compacted:plan.md');
118
118
  expect(pack.meta.compactedArtifacts).toContain('plan.md');
119
119
  });
120
120
 
121
+ it('stabilizes checker task manifest by excluding volatile check telemetry', () => {
122
+ const taskDir = createTask();
123
+ const pack = buildCheckerLlmInputPack({
124
+ taskDir,
125
+ taskId: 'TASK-999-token-pack',
126
+ checkerPromptSha: 'sha256:test',
127
+ cacheKey: { test: true },
128
+ checkContext: {
129
+ planSha: 'sha256:plan',
130
+ memorySha: 'sha256:memory',
131
+ riskProfile: 'high',
132
+ riskTriggers: ['source-sync-provider'],
133
+ },
134
+ checkEvidence: '# Evidence\n\nok',
135
+ checkerContextPack: '# Checker Context Pack\n\nok',
136
+ taskManifest: JSON.stringify({
137
+ schemaVersion: 1,
138
+ taskId: 'TASK-999-token-pack',
139
+ mode: 'standard',
140
+ phase: 'check',
141
+ gates: { sourceSyncProvider: { required: true, planComplete: true } },
142
+ context: {
143
+ planSha: 'sha256:plan',
144
+ memorySha: 'sha256:memory',
145
+ riskProfile: 'high',
146
+ riskTriggers: ['source-sync-provider'],
147
+ checkContextCurrent: true,
148
+ },
149
+ llmInput: { check: { updatedAt: 'volatile', attempts: [{ mode: 'strict' }] } },
150
+ lastCheckResult: { verdict: 'ready_for_human_gate', createdAt: 'volatile' },
151
+ timestamps: { updatedAt: 'volatile' },
152
+ loopDetector: {
153
+ threshold: 2,
154
+ requiresConsolidatedRemediation: true,
155
+ repeatedReasons: [{ normalizedReason: 'context_overflow', count: 3 }],
156
+ reasons: { noisy: { normalizedReason: 'verbose history' } },
157
+ },
158
+ }, null, 2),
159
+ projectMemory: [],
160
+ mode: 'standard',
161
+ });
162
+
163
+ expect(pack.input.taskManifest).toContain('"requiresConsolidatedRemediation": true');
164
+ expect(pack.input.taskManifest).not.toContain('lastCheckResult');
165
+ expect(pack.input.taskManifest).not.toContain('llmInput');
166
+ expect(pack.input.taskManifest).not.toContain('timestamps');
167
+ expect(pack.input.taskManifest).not.toContain('verbose history');
168
+ });
169
+
121
170
  it('preserves protected verification sections when compacting long plans', () => {
122
171
  const taskDir = createTask();
123
172
  const longPlan = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@besales/ops-framework",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "ops-agent": "bin/ops-agent.mjs"