avorelo 0.1.0 → 0.2.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.
- package/LICENSE +23 -16
- package/README.md +91 -51
- package/bin/avorelo.mjs +7 -0
- package/dist/avorelo.mjs +14337 -0
- package/package.json +106 -120
- package/bin/avorelo +0 -9
- package/scripts/README.md +0 -40
- package/scripts/cco-dashboard.js +0 -252
- package/scripts/cco-status.js +0 -430
- package/scripts/lib/activation/account-state.js +0 -37
- package/scripts/lib/activation/activation-runner.js +0 -546
- package/scripts/lib/activation/activation-self-healing.js +0 -480
- package/scripts/lib/activation/activation-state.js +0 -83
- package/scripts/lib/activation/activation-summary.js +0 -191
- package/scripts/lib/activation/adapters/claude-code.js +0 -77
- package/scripts/lib/activation/adapters/codex-cli.js +0 -52
- package/scripts/lib/activation/adapters/cursor.js +0 -37
- package/scripts/lib/activation/adapters/github-agent.js +0 -39
- package/scripts/lib/activation/adapters/terminal.js +0 -42
- package/scripts/lib/activation/adapters/vscode.js +0 -39
- package/scripts/lib/activation/adapters/windsurf.js +0 -37
- package/scripts/lib/activation/ai-surface-detector.js +0 -151
- package/scripts/lib/activation/connect-account.js +0 -145
- package/scripts/lib/activation/detect-environment.js +0 -75
- package/scripts/lib/activation/detect-hosts.js +0 -62
- package/scripts/lib/activation/format-activation-output.js +0 -109
- package/scripts/lib/activation/next-action.js +0 -43
- package/scripts/lib/activation/repair-engine.js +0 -219
- package/scripts/lib/activation-distribution-readiness.js +0 -507
- package/scripts/lib/adapter-conformance.js +0 -176
- package/scripts/lib/adapter-readiness.js +0 -417
- package/scripts/lib/adapter-safety-boundaries.js +0 -335
- package/scripts/lib/adapter-technical-readiness-gate.js +0 -205
- package/scripts/lib/agent-access-governance.js +0 -455
- package/scripts/lib/agent-enforcement.js +0 -765
- package/scripts/lib/agent-policy-profile.js +0 -210
- package/scripts/lib/agent-security/action-evaluator.js +0 -507
- package/scripts/lib/agent-security/adapter-registry.js +0 -98
- package/scripts/lib/agent-security/auto-policy.js +0 -139
- package/scripts/lib/agent-security/bounded-scan.js +0 -93
- package/scripts/lib/agent-security/enforcement-adapter.js +0 -174
- package/scripts/lib/agent-security/enforcement-engine.js +0 -1129
- package/scripts/lib/agent-security/file-write-adapter.js +0 -183
- package/scripts/lib/agent-security/file-write-rules.js +0 -178
- package/scripts/lib/agent-security/index.js +0 -3342
- package/scripts/lib/agent-security/instruction-risk.js +0 -181
- package/scripts/lib/agent-security/mcp-action-adapter.js +0 -185
- package/scripts/lib/agent-security/mcp-action-rules.js +0 -184
- package/scripts/lib/agent-security/package-action-adapter.js +0 -175
- package/scripts/lib/agent-security/package-action-rules.js +0 -233
- package/scripts/lib/agent-security/performance.js +0 -148
- package/scripts/lib/agent-security/permission-minimizer.js +0 -403
- package/scripts/lib/agent-security/scan-cache.js +0 -74
- package/scripts/lib/agent-security/source-trust.js +0 -146
- package/scripts/lib/ai-install-prompt.js +0 -288
- package/scripts/lib/ai-workspace-hygiene.js +0 -1499
- package/scripts/lib/alpha-activation.js +0 -520
- package/scripts/lib/alpha-feedback.js +0 -263
- package/scripts/lib/alpha-readiness-gate.js +0 -332
- package/scripts/lib/anti-gaming.js +0 -169
- package/scripts/lib/artifact-health.js +0 -431
- package/scripts/lib/attribution.js +0 -180
- package/scripts/lib/audit.js +0 -289
- package/scripts/lib/avorelo-skill-registry.js +0 -810
- package/scripts/lib/batch-jobs.js +0 -71
- package/scripts/lib/brain-pack.js +0 -578
- package/scripts/lib/brand-boundary.js +0 -424
- package/scripts/lib/brand.js +0 -74
- package/scripts/lib/browser-capability.js +0 -1048
- package/scripts/lib/browser-proof-preflight.js +0 -321
- package/scripts/lib/cache-readiness.js +0 -187
- package/scripts/lib/canonical-reentry.js +0 -162
- package/scripts/lib/capability-packs.js +0 -314
- package/scripts/lib/capability-recommender.js +0 -512
- package/scripts/lib/capability-registry.js +0 -1059
- package/scripts/lib/carry-forward-surfacing.js +0 -194
- package/scripts/lib/ccusage-adapter.js +0 -188
- package/scripts/lib/company-loop.js +0 -1149
- package/scripts/lib/config.js +0 -637
- package/scripts/lib/context-acquisition-plan.js +0 -287
- package/scripts/lib/context-budget-guard.js +0 -170
- package/scripts/lib/context-budget-scanner.js +0 -257
- package/scripts/lib/context-optimizer.js +0 -715
- package/scripts/lib/context-reduction-plan.js +0 -178
- package/scripts/lib/context-safety.js +0 -88
- package/scripts/lib/context-savings-engine.js +0 -158
- package/scripts/lib/cost-evidence.js +0 -254
- package/scripts/lib/cross-host-install-plan.js +0 -308
- package/scripts/lib/cross-host-install-readiness.js +0 -237
- package/scripts/lib/cross-host-value-flow.js +0 -268
- package/scripts/lib/dashboard.js +0 -900
- package/scripts/lib/design-partner-feedback.js +0 -346
- package/scripts/lib/entitlements.js +0 -100
- package/scripts/lib/execution-packet.js +0 -559
- package/scripts/lib/experimentation-events.js +0 -547
- package/scripts/lib/external-capability-compliance.js +0 -107
- package/scripts/lib/external-user-simulation.js +0 -166
- package/scripts/lib/failure-recovery-readiness.js +0 -81
- package/scripts/lib/failure-recovery.js +0 -419
- package/scripts/lib/feedback-intelligence.js +0 -537
- package/scripts/lib/feedback-signals.js +0 -205
- package/scripts/lib/file-integrity.js +0 -68
- package/scripts/lib/fsx.js +0 -127
- package/scripts/lib/full-readiness-gate.js +0 -451
- package/scripts/lib/guidance-builder.js +0 -174
- package/scripts/lib/hook-apply.js +0 -1019
- package/scripts/lib/hook-baseline.js +0 -310
- package/scripts/lib/hook-config-preview.js +0 -275
- package/scripts/lib/hook-contracts.js +0 -290
- package/scripts/lib/hook-safety-boundary-readiness.js +0 -80
- package/scripts/lib/host-capability-matrix.js +0 -351
- package/scripts/lib/host-support-context.js +0 -254
- package/scripts/lib/http-hook-action.js +0 -538
- package/scripts/lib/install-ai-readiness.js +0 -84
- package/scripts/lib/install-intake-risk.js +0 -1037
- package/scripts/lib/install-journey-intelligence.js +0 -329
- package/scripts/lib/intervention-guidance.js +0 -57
- package/scripts/lib/known-limitations.js +0 -115
- package/scripts/lib/l8-path-truth.js +0 -146
- package/scripts/lib/launch-hardening-gate.js +0 -436
- package/scripts/lib/launch-readiness.js +0 -628
- package/scripts/lib/learning-memory.js +0 -686
- package/scripts/lib/lifecycle-hooks.js +0 -802
- package/scripts/lib/local-package-smoke.js +0 -423
- package/scripts/lib/local-pricing.js +0 -299
- package/scripts/lib/mcp-enforcement.js +0 -311
- package/scripts/lib/mcp-least-privilege-policy.js +0 -303
- package/scripts/lib/mcp-tool-inventory.js +0 -388
- package/scripts/lib/mcp-tool-risk.js +0 -0
- package/scripts/lib/memory.js +0 -335
- package/scripts/lib/metrics.js +0 -699
- package/scripts/lib/micro-proof.js +0 -133
- package/scripts/lib/next-run-context.js +0 -436
- package/scripts/lib/operating-value.js +0 -1648
- package/scripts/lib/optimization-v3.js +0 -122
- package/scripts/lib/orchestration/adapters/_shared.js +0 -49
- package/scripts/lib/orchestration/adapters/aider.js +0 -18
- package/scripts/lib/orchestration/adapters/claude-code.js +0 -35
- package/scripts/lib/orchestration/adapters/codex.js +0 -35
- package/scripts/lib/orchestration/adapters/gemini-cli.js +0 -18
- package/scripts/lib/orchestration/adapters/git.js +0 -25
- package/scripts/lib/orchestration/adapters/index.js +0 -31
- package/scripts/lib/orchestration/adapters/lm-studio.js +0 -18
- package/scripts/lib/orchestration/adapters/ollama.js +0 -18
- package/scripts/lib/orchestration/adapters/opencode.js +0 -18
- package/scripts/lib/orchestration/adapters/openrouter.js +0 -18
- package/scripts/lib/orchestration/adapters/test-runner.js +0 -25
- package/scripts/lib/orchestration/cli.js +0 -438
- package/scripts/lib/orchestration/execution-manager.js +0 -279
- package/scripts/lib/orchestration/handoff.js +0 -314
- package/scripts/lib/orchestration/index.js +0 -456
- package/scripts/lib/orchestration/inventory.js +0 -47
- package/scripts/lib/orchestration/model-discovery.js +0 -498
- package/scripts/lib/orchestration/model-profiler.js +0 -170
- package/scripts/lib/orchestration/model-profiles.js +0 -252
- package/scripts/lib/orchestration/model-refresh-policy.js +0 -72
- package/scripts/lib/orchestration/proof-writer.js +0 -349
- package/scripts/lib/orchestration/provider-discovery/aider.js +0 -49
- package/scripts/lib/orchestration/provider-discovery/claude-code.js +0 -56
- package/scripts/lib/orchestration/provider-discovery/codex.js +0 -49
- package/scripts/lib/orchestration/provider-discovery/common.js +0 -186
- package/scripts/lib/orchestration/provider-discovery/gemini.js +0 -106
- package/scripts/lib/orchestration/provider-discovery/lm-studio.js +0 -118
- package/scripts/lib/orchestration/provider-discovery/models-dev.js +0 -12
- package/scripts/lib/orchestration/provider-discovery/ollama.js +0 -100
- package/scripts/lib/orchestration/provider-discovery/opencode.js +0 -47
- package/scripts/lib/orchestration/provider-discovery/openrouter.js +0 -44
- package/scripts/lib/orchestration/risk-classifier.js +0 -130
- package/scripts/lib/orchestration/routing-policy.js +0 -486
- package/scripts/lib/orchestration/settings.js +0 -112
- package/scripts/lib/orchestration/state.js +0 -165
- package/scripts/lib/orchestration/verification-manager.js +0 -138
- package/scripts/lib/output-profiles.js +0 -146
- package/scripts/lib/package-content-audit.js +0 -368
- package/scripts/lib/package-runtime.js +0 -278
- package/scripts/lib/plan-surface.js +0 -53
- package/scripts/lib/plans.js +0 -2318
- package/scripts/lib/policy-provider.js +0 -27
- package/scripts/lib/prelaunch-activation-readiness.js +0 -409
- package/scripts/lib/prelaunch-evidence-store.js +0 -816
- package/scripts/lib/prelaunch-intelligence.js +0 -869
- package/scripts/lib/pricing-experiment.js +0 -118
- package/scripts/lib/pro-moment-events.js +0 -77
- package/scripts/lib/pro-moment-state.js +0 -227
- package/scripts/lib/pro-moments.js +0 -1216
- package/scripts/lib/product-learning-events.js +0 -629
- package/scripts/lib/project-profile.js +0 -555
- package/scripts/lib/prompt-compiler.js +0 -280
- package/scripts/lib/prompt-lint.js +0 -32
- package/scripts/lib/prompt-suggestions.js +0 -52
- package/scripts/lib/proof-canonical.js +0 -398
- package/scripts/lib/proof-drilldown.js +0 -383
- package/scripts/lib/proof-events.js +0 -342
- package/scripts/lib/proof-history.js +0 -243
- package/scripts/lib/proof-metrics.js +0 -296
- package/scripts/lib/proof-outcome-evidence.js +0 -134
- package/scripts/lib/proof-receipt.js +0 -335
- package/scripts/lib/proof-record.js +0 -461
- package/scripts/lib/public-activation-distribution-gate.js +0 -258
- package/scripts/lib/public-cli.js +0 -3891
- package/scripts/lib/public-distribution-truth.js +0 -211
- package/scripts/lib/public-install-claim-checker.js +0 -294
- package/scripts/lib/publish-provenance-readiness.js +0 -283
- package/scripts/lib/readiness-delta.js +0 -218
- package/scripts/lib/readiness-evidence-closure.js +0 -196
- package/scripts/lib/reentry-memory-capture.js +0 -241
- package/scripts/lib/reentry-memory-retrieval.js +0 -302
- package/scripts/lib/reentry-memory-status.js +0 -146
- package/scripts/lib/reentry-memory-store.js +0 -178
- package/scripts/lib/reentry-state.js +0 -66
- package/scripts/lib/release-candidate-bundle.js +0 -166
- package/scripts/lib/remediation.js +0 -81
- package/scripts/lib/repo-map.js +0 -391
- package/scripts/lib/run-improvements-lifecycle.js +0 -330
- package/scripts/lib/run-improvements.js +0 -789
- package/scripts/lib/runtime-decision-policy.js +0 -387
- package/scripts/lib/safe-path-engine.js +0 -705
- package/scripts/lib/safe-run-controller.js +0 -887
- package/scripts/lib/score.js +0 -262
- package/scripts/lib/seamless-enforcement.js +0 -329
- package/scripts/lib/seamless-outcome.js +0 -689
- package/scripts/lib/seamless-reality-gate.js +0 -5043
- package/scripts/lib/security-risk-classifier.js +0 -511
- package/scripts/lib/security-scan.js +0 -384
- package/scripts/lib/session-context-optimizer.js +0 -1211
- package/scripts/lib/session-timing.js +0 -315
- package/scripts/lib/skill-hygiene.js +0 -805
- package/scripts/lib/skill-packs.js +0 -161
- package/scripts/lib/skills-operating-layer.js +0 -580
- package/scripts/lib/smart-work-routing.js +0 -768
- package/scripts/lib/source-catalog.js +0 -700
- package/scripts/lib/status-value-summary.js +0 -32
- package/scripts/lib/support-bundle.js +0 -578
- package/scripts/lib/task-continuation.js +0 -440
- package/scripts/lib/test-helpers.js +0 -15
- package/scripts/lib/tier.js +0 -38
- package/scripts/lib/token-context-quality-gate.js +0 -370
- package/scripts/lib/token-cost-capture.js +0 -187
- package/scripts/lib/token-cost-intelligence.js +0 -358
- package/scripts/lib/token-efficiency-evidence.js +0 -213
- package/scripts/lib/token-evidence.js +0 -699
- package/scripts/lib/tokenish.js +0 -17
- package/scripts/lib/tool-output-sandbox.js +0 -304
- package/scripts/lib/trust-audit.js +0 -136
- package/scripts/lib/unified-events.js +0 -396
- package/scripts/lib/upgrade-interruption-recovery.js +0 -407
- package/scripts/lib/usage-ledger.js +0 -201
- package/scripts/lib/value-ledger.js +0 -130
- package/scripts/lib/value-proof-calibration.js +0 -531
- package/scripts/lib/visual-qa.js +0 -231
- package/scripts/lib/voice-alpha.js +0 -29
- package/scripts/lib/work-aware-orchestration.js +0 -976
- package/scripts/lib/work-control-receipts.js +0 -577
- package/scripts/lib/work-ledger.js +0 -1123
- package/scripts/lib/work-panel-preview.js +0 -352
- package/scripts/lib/workflow-discipline.js +0 -280
- package/scripts/lib/workflow-signals.js +0 -419
- package/scripts/lib/workspace-map.js +0 -281
- package/scripts/lib/workspace-registry.js +0 -1367
- package/scripts/lib/workspace-resolver.js +0 -480
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Inline Micro-Proof System (Surface 1).
|
|
5
|
-
*
|
|
6
|
-
* Shows small, calm, contextual proof moments inside the workflow
|
|
7
|
-
* only when a material value event actually happened.
|
|
8
|
-
*
|
|
9
|
-
* Rules:
|
|
10
|
-
* - Must not be modal
|
|
11
|
-
* - Must not spam the user
|
|
12
|
-
* - Must deduplicate repeated proof types per session
|
|
13
|
-
* - Must show at most top 1-2 meaningful proofs at a moment
|
|
14
|
-
* - Must map directly to real telemetry/proof data
|
|
15
|
-
* - Must use calm factual copy
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
const fs = require("fs");
|
|
19
|
-
const path = require("path");
|
|
20
|
-
const { REASON_CODE_PROOF_MAP } = require("./proof-events");
|
|
21
|
-
|
|
22
|
-
const MAX_PROOFS_PER_HOOK = 2;
|
|
23
|
-
const MAX_PROOFS_PER_TYPE_PER_SESSION = 3;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Load the micro-proof dedup state for a session.
|
|
27
|
-
*/
|
|
28
|
-
function loadMicroProofState(cwd, sessionId) {
|
|
29
|
-
const p = path.join(cwd, ".claude", "cco", "state", `micro-proof-${sessionId}.json`);
|
|
30
|
-
try {
|
|
31
|
-
return JSON.parse(fs.readFileSync(p, "utf8"));
|
|
32
|
-
} catch {
|
|
33
|
-
return { shown: {} };
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Save the micro-proof dedup state for a session.
|
|
39
|
-
*/
|
|
40
|
-
function saveMicroProofState(cwd, sessionId, state) {
|
|
41
|
-
const p = path.join(cwd, ".claude", "cco", "state", `micro-proof-${sessionId}.json`);
|
|
42
|
-
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
43
|
-
fs.writeFileSync(p, JSON.stringify(state, null, 2), "utf8");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Select proof-worthy micro-proofs from a set of reason codes.
|
|
48
|
-
*
|
|
49
|
-
* Returns up to MAX_PROOFS_PER_HOOK calm one-liners, deduplicated
|
|
50
|
-
* against what was already shown in this session.
|
|
51
|
-
*
|
|
52
|
-
* @param {string[]} reasonCodes - reason codes from the current hook metric
|
|
53
|
-
* @param {string} cwd - workspace root
|
|
54
|
-
* @param {string} sessionId - session identifier
|
|
55
|
-
* @param {object} options - { proofEnabled?: boolean }
|
|
56
|
-
* @returns {{ proofs: string[], updated: boolean }}
|
|
57
|
-
*/
|
|
58
|
-
function selectMicroProofs(reasonCodes, cwd, sessionId, options = {}) {
|
|
59
|
-
if (options.proofEnabled === false) {
|
|
60
|
-
return { proofs: [], updated: false };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const state = loadMicroProofState(cwd, sessionId);
|
|
64
|
-
const candidates = [];
|
|
65
|
-
|
|
66
|
-
for (const code of reasonCodes || []) {
|
|
67
|
-
const mapping = REASON_CODE_PROOF_MAP[code];
|
|
68
|
-
if (!mapping || !mapping.proofWorthy || !mapping.calmCopy) continue;
|
|
69
|
-
|
|
70
|
-
// Dedup: skip if this proof type has been shown too many times
|
|
71
|
-
const shown = state.shown[code] || 0;
|
|
72
|
-
if (shown >= MAX_PROOFS_PER_TYPE_PER_SESSION) continue;
|
|
73
|
-
|
|
74
|
-
candidates.push({
|
|
75
|
-
code,
|
|
76
|
-
copy: mapping.calmCopy,
|
|
77
|
-
dimension: mapping.dimension,
|
|
78
|
-
family: mapping.family,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (candidates.length === 0) {
|
|
83
|
-
return { proofs: [], updated: false };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Prioritize by dimension diversity: show one from each dimension if possible
|
|
87
|
-
const selected = [];
|
|
88
|
-
const seenDimensions = new Set();
|
|
89
|
-
|
|
90
|
-
for (const c of candidates) {
|
|
91
|
-
if (selected.length >= MAX_PROOFS_PER_HOOK) break;
|
|
92
|
-
if (!seenDimensions.has(c.dimension)) {
|
|
93
|
-
selected.push(c);
|
|
94
|
-
seenDimensions.add(c.dimension);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Fill remaining slots if we haven't hit the cap
|
|
99
|
-
for (const c of candidates) {
|
|
100
|
-
if (selected.length >= MAX_PROOFS_PER_HOOK) break;
|
|
101
|
-
if (!selected.includes(c)) {
|
|
102
|
-
selected.push(c);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Update dedup state
|
|
107
|
-
for (const s of selected) {
|
|
108
|
-
state.shown[s.code] = (state.shown[s.code] || 0) + 1;
|
|
109
|
-
}
|
|
110
|
-
saveMicroProofState(cwd, sessionId, state);
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
proofs: selected.map((s) => s.copy),
|
|
114
|
-
updated: true,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Format micro-proofs as additional context for hook output.
|
|
120
|
-
* Returns a single string to be injected via outAdditional, or null if no proofs.
|
|
121
|
-
*/
|
|
122
|
-
function formatMicroProofContext(proofs) {
|
|
123
|
-
if (!proofs || proofs.length === 0) return null;
|
|
124
|
-
return proofs.join(" ");
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
module.exports = {
|
|
128
|
-
selectMicroProofs,
|
|
129
|
-
formatMicroProofContext,
|
|
130
|
-
loadMicroProofState,
|
|
131
|
-
MAX_PROOFS_PER_HOOK,
|
|
132
|
-
MAX_PROOFS_PER_TYPE_PER_SESSION,
|
|
133
|
-
};
|
|
@@ -1,436 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
// Next-Run Context — auto-injection of evidence-backed learning into the next AI coding run.
|
|
4
|
-
// Builds a compact, bounded artifact from prepared run improvements and learning summary.
|
|
5
|
-
// No cloud calls, no LLM, no daemon. Deterministic, local-first, honest.
|
|
6
|
-
//
|
|
7
|
-
// Artifact path: .claude/cco/state/next-run-context.json
|
|
8
|
-
// Schema: avorelo.nextRunContext.v1
|
|
9
|
-
//
|
|
10
|
-
// Lifecycle:
|
|
11
|
-
// not_available — run improvements not prepared
|
|
12
|
-
// prepared — artifact built, waiting for session to consume
|
|
13
|
-
// injected — session-start hook read and embedded it
|
|
14
|
-
// applied — artifact written and pointed to by lifecycle receipt
|
|
15
|
-
// expired — TTL exceeded
|
|
16
|
-
// stale — source fingerprint no longer matches run improvements
|
|
17
|
-
// insufficient_evidence — no actionable defaults to inject
|
|
18
|
-
// skipped — injection explicitly skipped
|
|
19
|
-
// error — unexpected error
|
|
20
|
-
|
|
21
|
-
const fs = require("fs");
|
|
22
|
-
const path = require("path");
|
|
23
|
-
|
|
24
|
-
const NEXT_RUN_CONTEXT_REL = ".claude/cco/state/next-run-context.json";
|
|
25
|
-
const SCHEMA_VERSION = "avorelo.nextRunContext.v1";
|
|
26
|
-
|
|
27
|
-
// 4-hour TTL: this is a "current-handoff" artifact, shorter than run-improvements (24h)
|
|
28
|
-
const TTL_MS = 4 * 60 * 60 * 1000;
|
|
29
|
-
|
|
30
|
-
const NEXT_RUN_STATUSES = [
|
|
31
|
-
"not_available",
|
|
32
|
-
"prepared",
|
|
33
|
-
"injected",
|
|
34
|
-
"applied",
|
|
35
|
-
"expired",
|
|
36
|
-
"stale",
|
|
37
|
-
"insufficient_evidence",
|
|
38
|
-
"skipped",
|
|
39
|
-
"error",
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
function nowIso() {
|
|
43
|
-
return new Date().toISOString();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function expiresAtFromNow(fromIso) {
|
|
47
|
-
const base = fromIso ? new Date(fromIso) : new Date();
|
|
48
|
-
return new Date(base.getTime() + TTL_MS).toISOString();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function isExpired(artifact) {
|
|
52
|
-
if (!artifact || !artifact.expiresAt) return true;
|
|
53
|
-
return Date.now() > new Date(artifact.expiresAt).getTime();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function isStale(artifact, runImprovementsArtifact) {
|
|
57
|
-
if (!artifact || !runImprovementsArtifact) return false;
|
|
58
|
-
return artifact.sourceRunFingerprint !== runImprovementsArtifact.sourceRunFingerprint;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// ── Bounded payload selection ─────────────────────────────────────────────────
|
|
62
|
-
|
|
63
|
-
// Top 1–3 defaults from run improvements (evidence-backed only)
|
|
64
|
-
function selectBoundedDefaults(runImprovements) {
|
|
65
|
-
if (!runImprovements || !Array.isArray(runImprovements.nextRunDefaults)) return [];
|
|
66
|
-
return runImprovements.nextRunDefaults.slice(0, 3);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Top 1–3 active decisions from learning summary
|
|
70
|
-
function selectActiveDecisions(learningSummary) {
|
|
71
|
-
if (!learningSummary || !Array.isArray(learningSummary.topSignals)) return [];
|
|
72
|
-
return learningSummary.topSignals
|
|
73
|
-
.filter((s) => s.type === "decision")
|
|
74
|
-
.slice(0, 3)
|
|
75
|
-
.map((s) => ({
|
|
76
|
-
summary: s.summary,
|
|
77
|
-
confidence: s.confidence,
|
|
78
|
-
reasonCodes: s.reasonCodes || [],
|
|
79
|
-
}));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Top 1–3 active risks from learning summary
|
|
83
|
-
function selectActiveRisks(learningSummary) {
|
|
84
|
-
if (!learningSummary || !Array.isArray(learningSummary.topRisks)) return [];
|
|
85
|
-
return learningSummary.topRisks
|
|
86
|
-
.filter((r) => r.status === "active")
|
|
87
|
-
.slice(0, 3)
|
|
88
|
-
.map((r) => ({
|
|
89
|
-
title: r.title,
|
|
90
|
-
severity: r.severity,
|
|
91
|
-
mitigation: r.mitigation,
|
|
92
|
-
reasonCodes: r.reasonCodes || [],
|
|
93
|
-
}));
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Evidence-backed capability recommendation
|
|
97
|
-
function selectCapabilityRecommendation(learningSummary) {
|
|
98
|
-
if (!learningSummary || !learningSummary.capabilityRecommendation) return null;
|
|
99
|
-
const rec = learningSummary.capabilityRecommendation;
|
|
100
|
-
if (!rec.id) return null;
|
|
101
|
-
return {
|
|
102
|
-
id: rec.id,
|
|
103
|
-
whenToUse: rec.whenToUse || null,
|
|
104
|
-
whenNotToUse: rec.whenNotToUse || null,
|
|
105
|
-
evidenceBacked: Boolean(rec.evidenceRefs && rec.evidenceRefs.length > 0),
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Build the human-readable context blocks for session injection
|
|
110
|
-
function buildContextBlocks(appliedDefaults, activeDecisions, activeRisks, capabilityRec) {
|
|
111
|
-
const blocks = [];
|
|
112
|
-
|
|
113
|
-
if (appliedDefaults.length > 0) {
|
|
114
|
-
const lines = appliedDefaults.map((d) => `- ${d.text}`).join("\n");
|
|
115
|
-
blocks.push({
|
|
116
|
-
type: "next_run_defaults",
|
|
117
|
-
heading: "Next-run defaults (evidence-backed):",
|
|
118
|
-
text: lines,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (activeDecisions.length > 0) {
|
|
123
|
-
const lines = activeDecisions.map((d) => `- ${d.summary}`).join("\n");
|
|
124
|
-
blocks.push({
|
|
125
|
-
type: "active_decisions",
|
|
126
|
-
heading: "Active decisions for this run:",
|
|
127
|
-
text: lines,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (activeRisks.length > 0) {
|
|
132
|
-
const lines = activeRisks.map((r) => `- [${r.severity}] ${r.title}: ${r.mitigation}`).join("\n");
|
|
133
|
-
blocks.push({
|
|
134
|
-
type: "active_risks",
|
|
135
|
-
heading: "Active risks to carry forward:",
|
|
136
|
-
text: lines,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (capabilityRec && capabilityRec.evidenceBacked) {
|
|
141
|
-
blocks.push({
|
|
142
|
-
type: "capability_recommendation",
|
|
143
|
-
heading: "Capability recommendation:",
|
|
144
|
-
text: `Use: ${capabilityRec.id}. ${capabilityRec.whenToUse || ""}`,
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return blocks;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Produce a compact human-readable text block suitable for session injection
|
|
152
|
-
function buildCompactContextText(artifact) {
|
|
153
|
-
if (!artifact || !Array.isArray(artifact.contextBlocks) || artifact.contextBlocks.length === 0) {
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const lines = ["Next-run context from Avorelo:"];
|
|
158
|
-
for (const block of artifact.contextBlocks) {
|
|
159
|
-
for (const line of block.text.split("\n")) {
|
|
160
|
-
lines.push(` ${line}`);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (artifact.limitations && artifact.limitations.length > 0) {
|
|
164
|
-
lines.push(` Limitations: ${artifact.limitations[0]}`);
|
|
165
|
-
}
|
|
166
|
-
return lines.join("\n");
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// ── Core builder ──────────────────────────────────────────────────────────────
|
|
170
|
-
|
|
171
|
-
function buildNextRunContext(cwd) {
|
|
172
|
-
const generatedAt = nowIso();
|
|
173
|
-
|
|
174
|
-
// Load run improvements
|
|
175
|
-
let runImprovements = null;
|
|
176
|
-
try {
|
|
177
|
-
const { loadRunImprovements } = require("./run-improvements");
|
|
178
|
-
runImprovements = loadRunImprovements(cwd);
|
|
179
|
-
} catch {}
|
|
180
|
-
|
|
181
|
-
if (!runImprovements || runImprovements.status === "not_available" || runImprovements.status === "expired") {
|
|
182
|
-
return {
|
|
183
|
-
schemaVersion: SCHEMA_VERSION,
|
|
184
|
-
generatedAt,
|
|
185
|
-
expiresAt: expiresAtFromNow(generatedAt),
|
|
186
|
-
sourceRunFingerprint: runImprovements?.sourceRunFingerprint || "none",
|
|
187
|
-
sourceArtifacts: {
|
|
188
|
-
runImprovementsRef: null,
|
|
189
|
-
learningSummaryRef: null,
|
|
190
|
-
},
|
|
191
|
-
appliedDefaults: [],
|
|
192
|
-
contextBlocks: [],
|
|
193
|
-
reasonCodes: ["NO_RUN_IMPROVEMENTS"],
|
|
194
|
-
redactionStatus: "redacted",
|
|
195
|
-
limitations: ["No prepared run improvements found. Run `avorelo run-improvements --generate` first."],
|
|
196
|
-
status: "not_available",
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Load learning summary (optional)
|
|
201
|
-
let learningSummary = null;
|
|
202
|
-
try {
|
|
203
|
-
const { loadLearningSummary } = require("./learning-memory");
|
|
204
|
-
learningSummary = loadLearningSummary(cwd);
|
|
205
|
-
} catch {}
|
|
206
|
-
|
|
207
|
-
const fingerprint = runImprovements.sourceRunFingerprint;
|
|
208
|
-
const appliedDefaults = selectBoundedDefaults(runImprovements);
|
|
209
|
-
const activeDecisions = selectActiveDecisions(learningSummary);
|
|
210
|
-
const activeRisks = selectActiveRisks(learningSummary);
|
|
211
|
-
const capabilityRec = selectCapabilityRecommendation(learningSummary);
|
|
212
|
-
|
|
213
|
-
if (appliedDefaults.length === 0 && activeDecisions.length === 0) {
|
|
214
|
-
return {
|
|
215
|
-
schemaVersion: SCHEMA_VERSION,
|
|
216
|
-
generatedAt,
|
|
217
|
-
expiresAt: expiresAtFromNow(generatedAt),
|
|
218
|
-
sourceRunFingerprint: fingerprint,
|
|
219
|
-
sourceArtifacts: {
|
|
220
|
-
runImprovementsRef: ".claude/cco/state/run-improvements.json",
|
|
221
|
-
learningSummaryRef: learningSummary ? ".claude/cco/state/learning-summary.json" : null,
|
|
222
|
-
},
|
|
223
|
-
appliedDefaults: [],
|
|
224
|
-
contextBlocks: [],
|
|
225
|
-
reasonCodes: ["INSUFFICIENT_DEFAULTS"],
|
|
226
|
-
redactionStatus: "redacted",
|
|
227
|
-
limitations: [
|
|
228
|
-
"No actionable defaults or decisions found to inject.",
|
|
229
|
-
"Run `avorelo learning --generate` to refresh learning artifacts.",
|
|
230
|
-
],
|
|
231
|
-
status: "insufficient_evidence",
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const contextBlocks = buildContextBlocks(appliedDefaults, activeDecisions, activeRisks, capabilityRec);
|
|
236
|
-
const reasonCodes = [
|
|
237
|
-
...new Set([
|
|
238
|
-
...(runImprovements.reasonCodes || []),
|
|
239
|
-
...(learningSummary ? ["LEARNING_SUMMARY_INCLUDED"] : []),
|
|
240
|
-
]),
|
|
241
|
-
];
|
|
242
|
-
|
|
243
|
-
const limitations = [
|
|
244
|
-
"Defaults are bounded to top 3 from evidence — full register is not included.",
|
|
245
|
-
"Decisions are active-only — stale/superseded items are excluded.",
|
|
246
|
-
"Run improvements lifecycle: applied only when this artifact is written and receipt exists.",
|
|
247
|
-
...(runImprovements.limitations || []).slice(0, 2),
|
|
248
|
-
];
|
|
249
|
-
|
|
250
|
-
// Never include raw transcripts, secrets, env dumps, or absolute local paths
|
|
251
|
-
return {
|
|
252
|
-
schemaVersion: SCHEMA_VERSION,
|
|
253
|
-
generatedAt,
|
|
254
|
-
expiresAt: expiresAtFromNow(generatedAt),
|
|
255
|
-
sourceRunFingerprint: fingerprint,
|
|
256
|
-
sourceArtifacts: {
|
|
257
|
-
runImprovementsRef: ".claude/cco/state/run-improvements.json",
|
|
258
|
-
learningSummaryRef: learningSummary ? ".claude/cco/state/learning-summary.json" : null,
|
|
259
|
-
},
|
|
260
|
-
appliedDefaults,
|
|
261
|
-
activeDecisionCount: activeDecisions.length,
|
|
262
|
-
activeRiskCount: activeRisks.length,
|
|
263
|
-
capabilityRecommendation: capabilityRec,
|
|
264
|
-
contextBlocks,
|
|
265
|
-
reasonCodes,
|
|
266
|
-
redactionStatus: "redacted",
|
|
267
|
-
limitations,
|
|
268
|
-
status: "prepared",
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// ── Write / load ──────────────────────────────────────────────────────────────
|
|
273
|
-
|
|
274
|
-
function generateNextRunContextArtifact(cwd, options = {}) {
|
|
275
|
-
const artifact = buildNextRunContext(cwd);
|
|
276
|
-
|
|
277
|
-
// Idempotency: same fingerprint + prepared/applied + not expired → skip rewrite
|
|
278
|
-
const existing = loadNextRunContext(cwd);
|
|
279
|
-
if (
|
|
280
|
-
existing &&
|
|
281
|
-
!isExpired(existing) &&
|
|
282
|
-
existing.sourceRunFingerprint === artifact.sourceRunFingerprint &&
|
|
283
|
-
(existing.status === "prepared" || existing.status === "applied" || existing.status === "injected") &&
|
|
284
|
-
!options.force
|
|
285
|
-
) {
|
|
286
|
-
return { artifact: existing, written: false, reason: "same_fingerprint_not_expired" };
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const absPath = path.join(cwd, NEXT_RUN_CONTEXT_REL);
|
|
290
|
-
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
|
291
|
-
fs.writeFileSync(absPath, JSON.stringify(artifact, null, 2), "utf8");
|
|
292
|
-
|
|
293
|
-
_emitAuditEvent(cwd, artifact, "next_run_context.prepared");
|
|
294
|
-
|
|
295
|
-
return { artifact, written: true, reason: "generated" };
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
function loadNextRunContext(cwd) {
|
|
299
|
-
try {
|
|
300
|
-
const absPath = path.join(cwd, NEXT_RUN_CONTEXT_REL);
|
|
301
|
-
const raw = JSON.parse(fs.readFileSync(absPath, "utf8"));
|
|
302
|
-
if (raw.schemaVersion !== SCHEMA_VERSION) return null;
|
|
303
|
-
if (isExpired(raw)) {
|
|
304
|
-
raw.status = "expired";
|
|
305
|
-
}
|
|
306
|
-
return raw;
|
|
307
|
-
} catch {
|
|
308
|
-
return null;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// Update the artifact's status in-place (used by session-start injection)
|
|
313
|
-
function updateNextRunContextStatus(cwd, newStatus, options = {}) {
|
|
314
|
-
try {
|
|
315
|
-
const absPath = path.join(cwd, NEXT_RUN_CONTEXT_REL);
|
|
316
|
-
if (!fs.existsSync(absPath)) return false;
|
|
317
|
-
const stored = JSON.parse(fs.readFileSync(absPath, "utf8"));
|
|
318
|
-
if (stored.schemaVersion !== SCHEMA_VERSION) return false;
|
|
319
|
-
stored.status = newStatus;
|
|
320
|
-
if (options.injectedAt) stored.injectedAt = options.injectedAt;
|
|
321
|
-
fs.writeFileSync(absPath, JSON.stringify(stored, null, 2), "utf8");
|
|
322
|
-
return true;
|
|
323
|
-
} catch {
|
|
324
|
-
return false;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// ── Audit events ──────────────────────────────────────────────────────────────
|
|
329
|
-
|
|
330
|
-
function _emitAuditEvent(cwd, artifact, eventName) {
|
|
331
|
-
try {
|
|
332
|
-
const eventsPath = path.join(cwd, ".claude/cco/events/outcome-events.jsonl");
|
|
333
|
-
fs.mkdirSync(path.dirname(eventsPath), { recursive: true });
|
|
334
|
-
const safeEventName = eventName.replace(/\./g, "_");
|
|
335
|
-
const event = JSON.stringify({
|
|
336
|
-
event_id: `nrc_${safeEventName}_${artifact.sourceRunFingerprint}`,
|
|
337
|
-
session_id: "avorelo-next-run-context",
|
|
338
|
-
timestamp: nowIso(),
|
|
339
|
-
category: "next_run_context",
|
|
340
|
-
event_name: safeEventName,
|
|
341
|
-
reason_code: "NEXT_RUN_CONTEXT_LIFECYCLE",
|
|
342
|
-
confidence_score: 1.0,
|
|
343
|
-
platform: "avorelo",
|
|
344
|
-
metadata: {
|
|
345
|
-
schemaVersion: artifact.schemaVersion,
|
|
346
|
-
status: artifact.status,
|
|
347
|
-
defaultsCount: (artifact.appliedDefaults || []).length,
|
|
348
|
-
decisionsCount: artifact.activeDecisionCount || 0,
|
|
349
|
-
risksCount: artifact.activeRiskCount || 0,
|
|
350
|
-
capabilityCount: artifact.capabilityRecommendation ? 1 : 0,
|
|
351
|
-
sourceRunFingerprint: artifact.sourceRunFingerprint,
|
|
352
|
-
surface: artifact.injectedSurface || null,
|
|
353
|
-
redactionStatus: artifact.redactionStatus || "redacted",
|
|
354
|
-
reasonCodes: (artifact.reasonCodes || []).slice(0, 5),
|
|
355
|
-
},
|
|
356
|
-
});
|
|
357
|
-
fs.appendFileSync(eventsPath, event + "\n", "utf8");
|
|
358
|
-
} catch {}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
function emitNextRunContextEvent(cwd, artifact, eventName) {
|
|
362
|
-
_emitAuditEvent(cwd, artifact, eventName);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// ── Status/dashboard surface ──────────────────────────────────────────────────
|
|
366
|
-
|
|
367
|
-
function buildNextRunContextSurface(cwd) {
|
|
368
|
-
const artifact = loadNextRunContext(cwd);
|
|
369
|
-
if (!artifact || artifact.status === "not_available") {
|
|
370
|
-
return {
|
|
371
|
-
showInStatus: false,
|
|
372
|
-
statusLine: null,
|
|
373
|
-
artifact: null,
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const statusText = {
|
|
378
|
-
prepared: "prepared",
|
|
379
|
-
injected: "injected",
|
|
380
|
-
applied: "applied",
|
|
381
|
-
expired: "expired",
|
|
382
|
-
stale: "stale",
|
|
383
|
-
insufficient_evidence: "no actionable context",
|
|
384
|
-
skipped: "skipped",
|
|
385
|
-
error: "error",
|
|
386
|
-
}[artifact.status] || artifact.status;
|
|
387
|
-
|
|
388
|
-
const defaultsCount = (artifact.appliedDefaults || []).length;
|
|
389
|
-
const expiresIn = artifact.expiresAt
|
|
390
|
-
? Math.max(0, Math.round((new Date(artifact.expiresAt).getTime() - Date.now()) / 60000))
|
|
391
|
-
: null;
|
|
392
|
-
|
|
393
|
-
const expiryNote = expiresIn !== null && artifact.status !== "expired"
|
|
394
|
-
? ` · expires in ${expiresIn}m`
|
|
395
|
-
: "";
|
|
396
|
-
|
|
397
|
-
const statusLine =
|
|
398
|
-
artifact.status === "expired"
|
|
399
|
-
? "Next-run context: expired — run `avorelo run-improvements --apply` to refresh"
|
|
400
|
-
: artifact.status === "insufficient_evidence"
|
|
401
|
-
? "Next-run context: no actionable context"
|
|
402
|
-
: `Next-run context: ${statusText} · ${defaultsCount} default(s)${expiryNote}`;
|
|
403
|
-
|
|
404
|
-
return {
|
|
405
|
-
showInStatus: true,
|
|
406
|
-
statusLine,
|
|
407
|
-
artifact,
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
function formatNextRunContextText(cwd) {
|
|
412
|
-
const artifact = loadNextRunContext(cwd);
|
|
413
|
-
if (!artifact) return null;
|
|
414
|
-
if (artifact.status === "not_available" || artifact.status === "expired") return null;
|
|
415
|
-
return buildCompactContextText(artifact);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
module.exports = {
|
|
419
|
-
SCHEMA_VERSION,
|
|
420
|
-
NEXT_RUN_CONTEXT_REL,
|
|
421
|
-
NEXT_RUN_STATUSES,
|
|
422
|
-
TTL_MS,
|
|
423
|
-
buildNextRunContext,
|
|
424
|
-
generateNextRunContextArtifact,
|
|
425
|
-
loadNextRunContext,
|
|
426
|
-
updateNextRunContextStatus,
|
|
427
|
-
buildNextRunContextSurface,
|
|
428
|
-
buildCompactContextText,
|
|
429
|
-
formatNextRunContextText,
|
|
430
|
-
emitNextRunContextEvent,
|
|
431
|
-
isExpired,
|
|
432
|
-
isStale,
|
|
433
|
-
selectBoundedDefaults,
|
|
434
|
-
selectActiveDecisions,
|
|
435
|
-
selectActiveRisks,
|
|
436
|
-
};
|