* Increment trust counters in harness.json for contextual appropriateness. * Tracks sessions completed and campaigns completed this session. * Non-critical -- wrapped in try/catch.
()
| 277 | |
| 278 | process.stdout.write( |
| 279 | `[session] $${cost.toFixed(2)}${source} | ${durationMinutes} min | $${rate}/min${msgs}${agents}${campaign}\n` |
| 280 | ); |
| 281 | } |
| 282 | } catch { /* summary is non-critical */ } |
| 283 | } catch { /* non-critical -- never block session end */ } |
| 284 | } |
| 285 | |
| 286 | /** |
| 287 | * Increment trust counters in harness.json for contextual appropriateness. |
| 288 | * Tracks sessions completed and campaigns completed this session. |
| 289 | * Non-critical -- wrapped in try/catch. |
| 290 | */ |
| 291 | function reconcileV2TrustCounters(trust) { |
| 292 | const reconciled = { ...trust }; |
| 293 | const legacyCounters = { |
| 294 | sessionsCompleted: 'sessions_completed', |
| 295 | campaignsCompleted: 'campaigns_completed', |
| 296 | fleetCleanMerges: 'fleet_clean_merges', |
| 297 | improveLoopsAccepted: 'improve_loops_accepted', |
| 298 | daemonRuns: 'daemon_runs', |
| 299 | }; |
| 300 | |
| 301 | for (const [canonicalKey, legacyKey] of Object.entries(legacyCounters)) { |
| 302 | if (!Number.isInteger(trust[legacyKey]) || trust[legacyKey] < 0) continue; |
| 303 | const canonicalValue = Number.isInteger(trust[canonicalKey]) && trust[canonicalKey] >= 0 |
| 304 | ? trust[canonicalKey] |
| 305 | : 0; |
| 306 | // Earlier v2 hooks wrote new activity to snake_case aliases. Add that |
| 307 | // activity before normalization removes the aliases. |
| 308 | reconciled[canonicalKey] = canonicalValue + trust[legacyKey]; |
| 309 | } |
| 310 | |
| 311 | return normalizeTrust(reconciled); |
| 312 | } |
| 313 | |
| 314 | function incrementTrustCounters() { |
| 315 | try { |
| 316 | const configPath = path.join(PROJECT_ROOT, '.claude', 'harness.json'); |
| 317 | if (!fs.existsSync(configPath)) return; // trust isn't tracked without config |
| 318 | |
| 319 | const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); |
| 320 | const isV2 = config.schemaVersion === 2; |
| 321 | const counterKeys = isV2 |
| 322 | ? { |
| 323 | sessions: 'sessionsCompleted', |
| 324 | campaigns: 'campaignsCompleted', |
| 325 | fleetMerges: 'fleetCleanMerges', |
| 326 | improveLoops: 'improveLoopsAccepted', |
| 327 | daemonRuns: 'daemonRuns', |
| 328 | } |
| 329 | : { |
| 330 | sessions: 'sessions_completed', |
| 331 | campaigns: 'campaigns_completed', |
| 332 | fleetMerges: 'fleet_clean_merges', |
| 333 | improveLoops: 'improve_loops_accepted', |
| 334 | daemonRuns: 'daemon_runs', |
| 335 | }; |
| 336 |