avorelo 0.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.
- package/LICENSE +21 -0
- package/README.md +56 -0
- package/bin/avorelo +9 -0
- package/package.json +135 -0
- package/scripts/README.md +40 -0
- package/scripts/cco-dashboard.js +252 -0
- package/scripts/cco-status.js +430 -0
- package/scripts/lib/activation/account-state.js +37 -0
- package/scripts/lib/activation/activation-runner.js +546 -0
- package/scripts/lib/activation/activation-self-healing.js +480 -0
- package/scripts/lib/activation/activation-state.js +83 -0
- package/scripts/lib/activation/activation-summary.js +191 -0
- package/scripts/lib/activation/adapters/claude-code.js +77 -0
- package/scripts/lib/activation/adapters/codex-cli.js +52 -0
- package/scripts/lib/activation/adapters/cursor.js +37 -0
- package/scripts/lib/activation/adapters/github-agent.js +39 -0
- package/scripts/lib/activation/adapters/terminal.js +42 -0
- package/scripts/lib/activation/adapters/vscode.js +39 -0
- package/scripts/lib/activation/adapters/windsurf.js +37 -0
- package/scripts/lib/activation/ai-surface-detector.js +151 -0
- package/scripts/lib/activation/connect-account.js +145 -0
- package/scripts/lib/activation/detect-environment.js +75 -0
- package/scripts/lib/activation/detect-hosts.js +62 -0
- package/scripts/lib/activation/format-activation-output.js +109 -0
- package/scripts/lib/activation/next-action.js +43 -0
- package/scripts/lib/activation/repair-engine.js +219 -0
- package/scripts/lib/activation-distribution-readiness.js +507 -0
- package/scripts/lib/adapter-conformance.js +176 -0
- package/scripts/lib/adapter-readiness.js +417 -0
- package/scripts/lib/adapter-safety-boundaries.js +335 -0
- package/scripts/lib/adapter-technical-readiness-gate.js +205 -0
- package/scripts/lib/agent-access-governance.js +455 -0
- package/scripts/lib/agent-enforcement.js +765 -0
- package/scripts/lib/agent-policy-profile.js +210 -0
- package/scripts/lib/agent-security/action-evaluator.js +507 -0
- package/scripts/lib/agent-security/adapter-registry.js +98 -0
- package/scripts/lib/agent-security/auto-policy.js +139 -0
- package/scripts/lib/agent-security/bounded-scan.js +93 -0
- package/scripts/lib/agent-security/enforcement-adapter.js +174 -0
- package/scripts/lib/agent-security/enforcement-engine.js +1129 -0
- package/scripts/lib/agent-security/file-write-adapter.js +183 -0
- package/scripts/lib/agent-security/file-write-rules.js +178 -0
- package/scripts/lib/agent-security/index.js +3342 -0
- package/scripts/lib/agent-security/instruction-risk.js +181 -0
- package/scripts/lib/agent-security/mcp-action-adapter.js +185 -0
- package/scripts/lib/agent-security/mcp-action-rules.js +184 -0
- package/scripts/lib/agent-security/package-action-adapter.js +175 -0
- package/scripts/lib/agent-security/package-action-rules.js +233 -0
- package/scripts/lib/agent-security/performance.js +148 -0
- package/scripts/lib/agent-security/permission-minimizer.js +403 -0
- package/scripts/lib/agent-security/scan-cache.js +74 -0
- package/scripts/lib/agent-security/source-trust.js +146 -0
- package/scripts/lib/ai-install-prompt.js +288 -0
- package/scripts/lib/ai-workspace-hygiene.js +1499 -0
- package/scripts/lib/alpha-activation.js +520 -0
- package/scripts/lib/alpha-feedback.js +263 -0
- package/scripts/lib/alpha-readiness-gate.js +332 -0
- package/scripts/lib/anti-gaming.js +169 -0
- package/scripts/lib/artifact-health.js +431 -0
- package/scripts/lib/attribution.js +180 -0
- package/scripts/lib/audit.js +289 -0
- package/scripts/lib/avorelo-skill-registry.js +810 -0
- package/scripts/lib/batch-jobs.js +71 -0
- package/scripts/lib/brain-pack.js +578 -0
- package/scripts/lib/brand-boundary.js +424 -0
- package/scripts/lib/brand.js +74 -0
- package/scripts/lib/browser-capability.js +1048 -0
- package/scripts/lib/browser-proof-preflight.js +321 -0
- package/scripts/lib/cache-readiness.js +187 -0
- package/scripts/lib/canonical-reentry.js +162 -0
- package/scripts/lib/capability-packs.js +314 -0
- package/scripts/lib/capability-recommender.js +512 -0
- package/scripts/lib/capability-registry.js +1059 -0
- package/scripts/lib/carry-forward-surfacing.js +194 -0
- package/scripts/lib/ccusage-adapter.js +188 -0
- package/scripts/lib/company-loop.js +1149 -0
- package/scripts/lib/config.js +637 -0
- package/scripts/lib/context-acquisition-plan.js +287 -0
- package/scripts/lib/context-budget-guard.js +170 -0
- package/scripts/lib/context-budget-scanner.js +257 -0
- package/scripts/lib/context-optimizer.js +715 -0
- package/scripts/lib/context-reduction-plan.js +178 -0
- package/scripts/lib/context-safety.js +88 -0
- package/scripts/lib/context-savings-engine.js +158 -0
- package/scripts/lib/cost-evidence.js +254 -0
- package/scripts/lib/cross-host-install-plan.js +308 -0
- package/scripts/lib/cross-host-install-readiness.js +237 -0
- package/scripts/lib/cross-host-value-flow.js +268 -0
- package/scripts/lib/dashboard.js +900 -0
- package/scripts/lib/design-partner-feedback.js +346 -0
- package/scripts/lib/entitlements.js +100 -0
- package/scripts/lib/execution-packet.js +559 -0
- package/scripts/lib/experimentation-events.js +547 -0
- package/scripts/lib/external-capability-compliance.js +107 -0
- package/scripts/lib/external-user-simulation.js +166 -0
- package/scripts/lib/failure-recovery-readiness.js +81 -0
- package/scripts/lib/failure-recovery.js +419 -0
- package/scripts/lib/feedback-intelligence.js +537 -0
- package/scripts/lib/feedback-signals.js +205 -0
- package/scripts/lib/file-integrity.js +68 -0
- package/scripts/lib/fsx.js +127 -0
- package/scripts/lib/full-readiness-gate.js +451 -0
- package/scripts/lib/guidance-builder.js +174 -0
- package/scripts/lib/hook-apply.js +1019 -0
- package/scripts/lib/hook-baseline.js +310 -0
- package/scripts/lib/hook-config-preview.js +275 -0
- package/scripts/lib/hook-contracts.js +290 -0
- package/scripts/lib/hook-safety-boundary-readiness.js +80 -0
- package/scripts/lib/host-capability-matrix.js +351 -0
- package/scripts/lib/host-support-context.js +254 -0
- package/scripts/lib/http-hook-action.js +538 -0
- package/scripts/lib/install-ai-readiness.js +84 -0
- package/scripts/lib/install-intake-risk.js +1037 -0
- package/scripts/lib/install-journey-intelligence.js +329 -0
- package/scripts/lib/intervention-guidance.js +57 -0
- package/scripts/lib/known-limitations.js +115 -0
- package/scripts/lib/l8-path-truth.js +146 -0
- package/scripts/lib/launch-hardening-gate.js +436 -0
- package/scripts/lib/launch-readiness.js +628 -0
- package/scripts/lib/learning-memory.js +686 -0
- package/scripts/lib/lifecycle-hooks.js +802 -0
- package/scripts/lib/local-package-smoke.js +423 -0
- package/scripts/lib/local-pricing.js +299 -0
- package/scripts/lib/mcp-enforcement.js +311 -0
- package/scripts/lib/mcp-least-privilege-policy.js +303 -0
- package/scripts/lib/mcp-tool-inventory.js +388 -0
- package/scripts/lib/mcp-tool-risk.js +0 -0
- package/scripts/lib/memory.js +335 -0
- package/scripts/lib/metrics.js +699 -0
- package/scripts/lib/micro-proof.js +133 -0
- package/scripts/lib/next-run-context.js +436 -0
- package/scripts/lib/operating-value.js +1648 -0
- package/scripts/lib/optimization-v3.js +122 -0
- package/scripts/lib/orchestration/adapters/_shared.js +49 -0
- package/scripts/lib/orchestration/adapters/aider.js +18 -0
- package/scripts/lib/orchestration/adapters/claude-code.js +35 -0
- package/scripts/lib/orchestration/adapters/codex.js +35 -0
- package/scripts/lib/orchestration/adapters/gemini-cli.js +18 -0
- package/scripts/lib/orchestration/adapters/git.js +25 -0
- package/scripts/lib/orchestration/adapters/index.js +31 -0
- package/scripts/lib/orchestration/adapters/lm-studio.js +18 -0
- package/scripts/lib/orchestration/adapters/ollama.js +18 -0
- package/scripts/lib/orchestration/adapters/opencode.js +18 -0
- package/scripts/lib/orchestration/adapters/openrouter.js +18 -0
- package/scripts/lib/orchestration/adapters/test-runner.js +25 -0
- package/scripts/lib/orchestration/cli.js +438 -0
- package/scripts/lib/orchestration/execution-manager.js +279 -0
- package/scripts/lib/orchestration/handoff.js +314 -0
- package/scripts/lib/orchestration/index.js +456 -0
- package/scripts/lib/orchestration/inventory.js +47 -0
- package/scripts/lib/orchestration/model-discovery.js +498 -0
- package/scripts/lib/orchestration/model-profiler.js +170 -0
- package/scripts/lib/orchestration/model-profiles.js +252 -0
- package/scripts/lib/orchestration/model-refresh-policy.js +72 -0
- package/scripts/lib/orchestration/proof-writer.js +349 -0
- package/scripts/lib/orchestration/provider-discovery/aider.js +49 -0
- package/scripts/lib/orchestration/provider-discovery/claude-code.js +56 -0
- package/scripts/lib/orchestration/provider-discovery/codex.js +49 -0
- package/scripts/lib/orchestration/provider-discovery/common.js +186 -0
- package/scripts/lib/orchestration/provider-discovery/gemini.js +106 -0
- package/scripts/lib/orchestration/provider-discovery/lm-studio.js +118 -0
- package/scripts/lib/orchestration/provider-discovery/models-dev.js +12 -0
- package/scripts/lib/orchestration/provider-discovery/ollama.js +100 -0
- package/scripts/lib/orchestration/provider-discovery/opencode.js +47 -0
- package/scripts/lib/orchestration/provider-discovery/openrouter.js +44 -0
- package/scripts/lib/orchestration/risk-classifier.js +130 -0
- package/scripts/lib/orchestration/routing-policy.js +486 -0
- package/scripts/lib/orchestration/settings.js +112 -0
- package/scripts/lib/orchestration/state.js +165 -0
- package/scripts/lib/orchestration/verification-manager.js +138 -0
- package/scripts/lib/output-profiles.js +146 -0
- package/scripts/lib/package-content-audit.js +368 -0
- package/scripts/lib/package-runtime.js +278 -0
- package/scripts/lib/plan-surface.js +53 -0
- package/scripts/lib/plans.js +2318 -0
- package/scripts/lib/policy-provider.js +27 -0
- package/scripts/lib/prelaunch-activation-readiness.js +409 -0
- package/scripts/lib/prelaunch-evidence-store.js +816 -0
- package/scripts/lib/prelaunch-intelligence.js +869 -0
- package/scripts/lib/pricing-experiment.js +118 -0
- package/scripts/lib/pro-moment-events.js +77 -0
- package/scripts/lib/pro-moment-state.js +227 -0
- package/scripts/lib/pro-moments.js +1216 -0
- package/scripts/lib/product-learning-events.js +629 -0
- package/scripts/lib/project-profile.js +555 -0
- package/scripts/lib/prompt-compiler.js +280 -0
- package/scripts/lib/prompt-lint.js +32 -0
- package/scripts/lib/prompt-suggestions.js +52 -0
- package/scripts/lib/proof-canonical.js +398 -0
- package/scripts/lib/proof-drilldown.js +383 -0
- package/scripts/lib/proof-events.js +342 -0
- package/scripts/lib/proof-history.js +243 -0
- package/scripts/lib/proof-metrics.js +296 -0
- package/scripts/lib/proof-outcome-evidence.js +134 -0
- package/scripts/lib/proof-receipt.js +335 -0
- package/scripts/lib/proof-record.js +461 -0
- package/scripts/lib/public-activation-distribution-gate.js +258 -0
- package/scripts/lib/public-cli.js +3891 -0
- package/scripts/lib/public-distribution-truth.js +211 -0
- package/scripts/lib/public-install-claim-checker.js +294 -0
- package/scripts/lib/publish-provenance-readiness.js +283 -0
- package/scripts/lib/readiness-delta.js +218 -0
- package/scripts/lib/readiness-evidence-closure.js +196 -0
- package/scripts/lib/reentry-memory-capture.js +241 -0
- package/scripts/lib/reentry-memory-retrieval.js +302 -0
- package/scripts/lib/reentry-memory-status.js +146 -0
- package/scripts/lib/reentry-memory-store.js +178 -0
- package/scripts/lib/reentry-state.js +66 -0
- package/scripts/lib/release-candidate-bundle.js +166 -0
- package/scripts/lib/remediation.js +81 -0
- package/scripts/lib/repo-map.js +391 -0
- package/scripts/lib/run-improvements-lifecycle.js +330 -0
- package/scripts/lib/run-improvements.js +789 -0
- package/scripts/lib/runtime-decision-policy.js +387 -0
- package/scripts/lib/safe-path-engine.js +705 -0
- package/scripts/lib/safe-run-controller.js +887 -0
- package/scripts/lib/score.js +262 -0
- package/scripts/lib/seamless-enforcement.js +329 -0
- package/scripts/lib/seamless-outcome.js +689 -0
- package/scripts/lib/seamless-reality-gate.js +5043 -0
- package/scripts/lib/security-risk-classifier.js +511 -0
- package/scripts/lib/security-scan.js +384 -0
- package/scripts/lib/session-context-optimizer.js +1211 -0
- package/scripts/lib/session-timing.js +315 -0
- package/scripts/lib/skill-hygiene.js +805 -0
- package/scripts/lib/skill-packs.js +161 -0
- package/scripts/lib/skills-operating-layer.js +580 -0
- package/scripts/lib/smart-work-routing.js +768 -0
- package/scripts/lib/source-catalog.js +700 -0
- package/scripts/lib/status-value-summary.js +32 -0
- package/scripts/lib/support-bundle.js +578 -0
- package/scripts/lib/task-continuation.js +440 -0
- package/scripts/lib/test-helpers.js +15 -0
- package/scripts/lib/tier.js +38 -0
- package/scripts/lib/token-context-quality-gate.js +370 -0
- package/scripts/lib/token-cost-capture.js +187 -0
- package/scripts/lib/token-cost-intelligence.js +358 -0
- package/scripts/lib/token-efficiency-evidence.js +213 -0
- package/scripts/lib/token-evidence.js +699 -0
- package/scripts/lib/tokenish.js +17 -0
- package/scripts/lib/tool-output-sandbox.js +304 -0
- package/scripts/lib/trust-audit.js +136 -0
- package/scripts/lib/unified-events.js +396 -0
- package/scripts/lib/upgrade-interruption-recovery.js +407 -0
- package/scripts/lib/usage-ledger.js +201 -0
- package/scripts/lib/value-ledger.js +130 -0
- package/scripts/lib/value-proof-calibration.js +531 -0
- package/scripts/lib/visual-qa.js +231 -0
- package/scripts/lib/voice-alpha.js +29 -0
- package/scripts/lib/work-aware-orchestration.js +976 -0
- package/scripts/lib/work-control-receipts.js +577 -0
- package/scripts/lib/work-ledger.js +1123 -0
- package/scripts/lib/work-panel-preview.js +352 -0
- package/scripts/lib/workflow-discipline.js +280 -0
- package/scripts/lib/workflow-signals.js +419 -0
- package/scripts/lib/workspace-map.js +281 -0
- package/scripts/lib/workspace-registry.js +1367 -0
- package/scripts/lib/workspace-resolver.js +480 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// ── Readiness Evidence Closure ────────────────────────────────────────────────
|
|
4
|
+
// Contract: avorelo.readinessEvidenceClosure.v1
|
|
5
|
+
// Attempts safe, local, non-destructive actions to collect missing evidence.
|
|
6
|
+
// Does NOT apply hooks, modify MCP config, run destructive commands, or fake data.
|
|
7
|
+
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
const { nowIso } = require("./fsx");
|
|
11
|
+
const { appendProductLearningEvent } = require("./product-learning-events");
|
|
12
|
+
|
|
13
|
+
const CONTRACT = "avorelo.readinessEvidenceClosure.v1";
|
|
14
|
+
const SCHEMA_VERSION = 1;
|
|
15
|
+
const CLOSURE_DIR_REL = ".claude/cco/orchestration/full-readiness";
|
|
16
|
+
const ARTIFACT_REL = CLOSURE_DIR_REL + "/latest-evidence-closure.json";
|
|
17
|
+
|
|
18
|
+
function safeReadJson(absPath) {
|
|
19
|
+
try {
|
|
20
|
+
if (!fs.existsSync(absPath)) return null;
|
|
21
|
+
return JSON.parse(fs.readFileSync(absPath, "utf8").replace(/^/, ""));
|
|
22
|
+
} catch { return null; }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var EVIDENCE_CHECKS = [
|
|
26
|
+
{ id: "install_ai_receipt", description: "AI install prompt receipt", artifactPath: ".claude/cco/orchestration/ai-install/latest-prompt.json", recoverCommand: "node bin/avorelo install-ai --json", safeToAutoRun: false, required: true },
|
|
27
|
+
{ id: "prelaunch_readiness_receipt", description: "Prelaunch activation readiness receipt", artifactPath: ".claude/cco/orchestration/prelaunch-readiness/latest-activation-readiness.json", recoverCommand: "node bin/avorelo prelaunch-readiness --json", safeToAutoRun: false, required: true },
|
|
28
|
+
{ id: "launch_hardening_receipt", description: "Launch hardening gate receipt", artifactPath: ".claude/cco/orchestration/launch-hardening/latest-gate.json", recoverCommand: "node bin/avorelo launch-hardening --json", safeToAutoRun: false, required: true },
|
|
29
|
+
{ id: "token_efficiency_receipt", description: "Token efficiency evidence receipt", artifactPath: ".claude/cco/orchestration/token-efficiency/latest-evidence.json", recoverCommand: "node bin/avorelo token-efficiency --json", safeToAutoRun: false, required: false },
|
|
30
|
+
{ id: "mcp_doctor_receipt", description: "MCP governance receipt", artifactPath: ".claude/cco/orchestration/mcp-tool-governance/latest-policy.json", recoverCommand: "node bin/avorelo mcp doctor --json", safeToAutoRun: false, required: true },
|
|
31
|
+
{ id: "support_bundle_receipt", description: "Support bundle (redacted)", artifactPath: ".claude/cco/support/latest-support-bundle.json", recoverCommand: "node bin/avorelo support-bundle --json", safeToAutoRun: false, required: true },
|
|
32
|
+
{ id: "proof_outcome_receipt", description: "Proof / value summary readiness evidence", artifactPath: ".claude/cco/orchestration/seamless-outcome/latest-proof-outcome-evidence.json", recoverCommand: "node bin/avorelo proof (after completing a real task)", safeToAutoRun: false, required: true },
|
|
33
|
+
{ id: "prelaunch_intelligence_receipt", description: "Prelaunch intelligence", artifactPath: ".claude/cco/orchestration/prelaunch-intelligence/latest-intelligence.json", recoverCommand: "node bin/avorelo prelaunch-intelligence --json", safeToAutoRun: false, required: true },
|
|
34
|
+
{ id: "feedback_intelligence_receipt", description: "Feedback intelligence", artifactPath: ".claude/cco/orchestration/prelaunch-intelligence/latest-feedback-intelligence.json", recoverCommand: "node bin/avorelo feedback intake-pack --json", safeToAutoRun: false, required: true },
|
|
35
|
+
{ id: "design_partner_feedback_receipt", description: "Design partner feedback summary", artifactPath: ".claude/cco/feedback/design-partner/latest-summary.json", recoverCommand: "node bin/avorelo feedback summary --json", safeToAutoRun: false, required: false },
|
|
36
|
+
{ id: "readiness_delta_receipt", description: "Readiness delta (score movement)", artifactPath: ".claude/cco/orchestration/readiness-delta/latest-readiness-delta.json", recoverCommand: "node bin/avorelo readiness-delta --json", safeToAutoRun: false, required: false },
|
|
37
|
+
{ id: "token_cost_intelligence_receipt", description: "Token/cost intelligence", artifactPath: ".claude/cco/orchestration/prelaunch-intelligence/latest-token-cost-intelligence.json", recoverCommand: "node bin/avorelo token-cost --json", safeToAutoRun: false, required: true },
|
|
38
|
+
{ id: "token_cost_capture_receipt", description: "Real usage token/cost capture", artifactPath: ".claude/cco/evidence/token-cost/latest-capture.json", recoverCommand: "node bin/avorelo token-cost capture --json", safeToAutoRun: false, required: false },
|
|
39
|
+
{ id: "token_cost_summary_receipt", description: "Token/cost evidence summary", artifactPath: ".claude/cco/evidence/token-cost/summary.json", recoverCommand: "node bin/avorelo token-cost summary --json", safeToAutoRun: false, required: true },
|
|
40
|
+
{ id: "company_loop_receipt", description: "Company loop recommendation", artifactPath: ".claude/cco/orchestration/company-loop/latest-report.json", recoverCommand: "node bin/avorelo company-loop --json", safeToAutoRun: false, required: false },
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
var SAFETY_BOUNDARIES = ["hooks apply --yes", "mcp config patch", "deploy", "publish", "prod", "rm -rf", "destructive", "fake feedback", "fake token cost", "exact savings without source"];
|
|
44
|
+
|
|
45
|
+
function buildEvidenceClosurePlan(cwd, options) {
|
|
46
|
+
options = options || {};
|
|
47
|
+
return EVIDENCE_CHECKS.map(function(check) {
|
|
48
|
+
var exists = fs.existsSync(path.join(cwd, check.artifactPath));
|
|
49
|
+
var artifact = exists ? safeReadJson(path.join(cwd, check.artifactPath)) : null;
|
|
50
|
+
var sufficient = exists;
|
|
51
|
+
if (check.id === "feedback_intelligence_receipt") {
|
|
52
|
+
sufficient = exists && artifact && artifact.qualifiedFeedbackItemsCount > 0;
|
|
53
|
+
} else if (check.id === "token_cost_intelligence_receipt") {
|
|
54
|
+
sufficient = exists && artifact && artifact.realUsageSamplesCount > 0;
|
|
55
|
+
} else if (check.id === "token_cost_capture_receipt") {
|
|
56
|
+
sufficient = exists && artifact && artifact.realUsageSamplesCount > 0;
|
|
57
|
+
} else if (check.id === "token_cost_summary_receipt") {
|
|
58
|
+
sufficient = exists && artifact && artifact.realUsageSamplesCount > 0;
|
|
59
|
+
} else if (check.id === "prelaunch_intelligence_receipt") {
|
|
60
|
+
sufficient = exists && artifact && artifact.status !== "insufficient_data" && (artifact.missingEvidence || []).length === 0;
|
|
61
|
+
} else if (check.id === "proof_outcome_receipt") {
|
|
62
|
+
sufficient = exists && artifact && artifact.latestProofAvailable === true && artifact.realTaskProofCount > 0;
|
|
63
|
+
} else if (check.id === "launch_hardening_receipt") {
|
|
64
|
+
sufficient = exists && artifact && artifact.status !== "fail";
|
|
65
|
+
}
|
|
66
|
+
return Object.assign({}, check, {
|
|
67
|
+
evidencePresent: exists,
|
|
68
|
+
sufficient: sufficient,
|
|
69
|
+
artifactStatus: artifact && artifact.status || (exists ? "present" : "missing"),
|
|
70
|
+
action: exists ? "read" : "missing",
|
|
71
|
+
artifact: artifact,
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function executeSafeEvidenceClosure(cwd, plan, options) {
|
|
77
|
+
options = options || {};
|
|
78
|
+
var actionsAttempted = [], evidenceGenerated = [], evidenceStillMissing = [], skippedActions = [], gaps = [];
|
|
79
|
+
plan.forEach(function(item) {
|
|
80
|
+
if (item.evidencePresent) {
|
|
81
|
+
actionsAttempted.push({ id: item.id, action: "read", result: "present" });
|
|
82
|
+
evidenceGenerated.push({
|
|
83
|
+
id: item.id,
|
|
84
|
+
description: item.description,
|
|
85
|
+
artifactPath: item.artifactPath,
|
|
86
|
+
status: item.artifactStatus,
|
|
87
|
+
sufficient: item.sufficient,
|
|
88
|
+
required: item.required,
|
|
89
|
+
});
|
|
90
|
+
if (!item.sufficient) {
|
|
91
|
+
var recoverCommand = (item.artifact && item.artifact.safeNextActions && item.artifact.safeNextActions[0]) || item.recoverCommand;
|
|
92
|
+
gaps.push({
|
|
93
|
+
id: item.id,
|
|
94
|
+
description: item.description,
|
|
95
|
+
recoverCommand: recoverCommand,
|
|
96
|
+
required: item.required,
|
|
97
|
+
reason: "artifact_present_but_insufficient",
|
|
98
|
+
canAutoRun: false,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
skippedActions.push({ id: item.id, reason: "requires_user_run", recoverCommand: item.recoverCommand });
|
|
103
|
+
evidenceStillMissing.push({ id: item.id, description: item.description, recoverCommand: item.recoverCommand, required: item.required, canAutoRun: false });
|
|
104
|
+
gaps.push({
|
|
105
|
+
id: item.id,
|
|
106
|
+
description: item.description,
|
|
107
|
+
recoverCommand: item.recoverCommand,
|
|
108
|
+
required: item.required,
|
|
109
|
+
reason: "artifact_missing",
|
|
110
|
+
canAutoRun: false,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
return { actionsAttempted: actionsAttempted, evidenceGenerated: evidenceGenerated, evidenceStillMissing: evidenceStillMissing, skippedActions: skippedActions, safetyBoundaries: SAFETY_BOUNDARIES, gaps: gaps };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function runReadinessEvidenceClosure(cwd, options) {
|
|
118
|
+
options = options || {};
|
|
119
|
+
var plan = buildEvidenceClosurePlan(cwd, options);
|
|
120
|
+
var result = executeSafeEvidenceClosure(cwd, plan, options);
|
|
121
|
+
var totalItems = plan.length;
|
|
122
|
+
var presentCount = result.evidenceGenerated.filter(function(item) { return item.sufficient; }).length;
|
|
123
|
+
var missingCount = result.gaps.length;
|
|
124
|
+
var requiredEvidence = plan.filter(function(item) { return item.required; }).map(function(item) { return item.id; });
|
|
125
|
+
var optionalEvidence = plan.filter(function(item) { return !item.required; }).map(function(item) { return item.id; });
|
|
126
|
+
var status = missingCount === 0 ? "completed" : presentCount > 0 ? "partial" : "blocked";
|
|
127
|
+
var safeNextActions = [];
|
|
128
|
+
result.gaps.forEach(function(gap) {
|
|
129
|
+
if (gap.recoverCommand && safeNextActions.indexOf(gap.recoverCommand) === -1) safeNextActions.push(gap.recoverCommand);
|
|
130
|
+
});
|
|
131
|
+
var nextAction = safeNextActions[0] || "All evidence collected. Run: node bin/avorelo full-readiness --json";
|
|
132
|
+
var closure = {
|
|
133
|
+
contract: CONTRACT,
|
|
134
|
+
schemaVersion: SCHEMA_VERSION,
|
|
135
|
+
createdAt: nowIso(),
|
|
136
|
+
status: status,
|
|
137
|
+
totalChecked: totalItems,
|
|
138
|
+
evidencePresentCount: presentCount,
|
|
139
|
+
evidenceMissingCount: missingCount,
|
|
140
|
+
actionsAttempted: result.actionsAttempted,
|
|
141
|
+
evidenceGenerated: result.evidenceGenerated,
|
|
142
|
+
evidenceStillMissing: result.evidenceStillMissing,
|
|
143
|
+
skippedActions: result.skippedActions,
|
|
144
|
+
gaps: result.gaps,
|
|
145
|
+
requiredEvidence: requiredEvidence,
|
|
146
|
+
optionalEvidence: optionalEvidence,
|
|
147
|
+
evidenceItems: plan.map(function(item) {
|
|
148
|
+
return {
|
|
149
|
+
id: item.id,
|
|
150
|
+
description: item.description,
|
|
151
|
+
artifactPath: item.artifactPath,
|
|
152
|
+
evidencePresent: item.evidencePresent,
|
|
153
|
+
sufficient: item.sufficient,
|
|
154
|
+
required: item.required,
|
|
155
|
+
status: item.artifactStatus,
|
|
156
|
+
canAutoRun: false,
|
|
157
|
+
};
|
|
158
|
+
}),
|
|
159
|
+
safeNextActions: safeNextActions,
|
|
160
|
+
safetyBoundaries: result.safetyBoundaries,
|
|
161
|
+
nextAction: nextAction,
|
|
162
|
+
canAutoRun: false,
|
|
163
|
+
redacted: true,
|
|
164
|
+
};
|
|
165
|
+
try { appendProductLearningEvent(cwd, { eventName: "readiness_evidence_closure_run", category: "full_readiness", status: status, evidencePresentCount: presentCount, evidenceMissingCount: missingCount }); } catch (e) {}
|
|
166
|
+
return closure;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function writeEvidenceClosure(cwd, closure) {
|
|
170
|
+
var dir = path.join(cwd, CLOSURE_DIR_REL);
|
|
171
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
172
|
+
fs.writeFileSync(path.join(cwd, ARTIFACT_REL), JSON.stringify(closure, null, 2));
|
|
173
|
+
return closure;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function buildEvidenceClosureSurface(cwd, options) {
|
|
177
|
+
options = options || {};
|
|
178
|
+
var closure = safeReadJson(path.join(cwd, ARTIFACT_REL));
|
|
179
|
+
if (!closure) return { status: "not_available", evidencePresentCount: 0, evidenceMissingCount: 0 };
|
|
180
|
+
return { status: closure.status, evidencePresentCount: closure.evidencePresentCount, evidenceMissingCount: closure.evidenceMissingCount, nextAction: closure.nextAction, gaps: closure.gaps || [] };
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function formatEvidenceClosureText(closure, options) {
|
|
184
|
+
options = options || {};
|
|
185
|
+
var lines = [];
|
|
186
|
+
lines.push("Evidence closure: " + closure.status);
|
|
187
|
+
lines.push("Evidence: " + closure.evidencePresentCount + "/" + closure.totalChecked + " present");
|
|
188
|
+
if ((closure.gaps || []).length > 0) {
|
|
189
|
+
lines.push(""); lines.push("Missing evidence:");
|
|
190
|
+
closure.gaps.forEach(function(m) { lines.push(" - " + m.description); lines.push(" Run: " + m.recoverCommand); });
|
|
191
|
+
}
|
|
192
|
+
lines.push(""); lines.push("Next: " + closure.nextAction);
|
|
193
|
+
return lines.join("\n");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
module.exports = { CONTRACT, SCHEMA_VERSION, ARTIFACT_REL, runReadinessEvidenceClosure, buildEvidenceClosurePlan, executeSafeEvidenceClosure, writeEvidenceClosure, buildEvidenceClosureSurface, formatEvidenceClosureText };
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { ReentryMemoryStore } = require("./reentry-memory-store");
|
|
4
|
+
|
|
5
|
+
// Patterns for sensitive content detection
|
|
6
|
+
const SENSITIVE_PATTERNS = [
|
|
7
|
+
/sk-[a-zA-Z0-9._\-]{10,}/, // Anthropic/OpenAI API keys
|
|
8
|
+
/Bearer\s+[a-zA-Z0-9._\-]{20,}/i, // Bearer tokens
|
|
9
|
+
/AKIA[A-Z0-9]{16}/, // AWS access keys
|
|
10
|
+
/private[_\s]?key/i, // Private key references
|
|
11
|
+
/-----BEGIN [A-Z ]+KEY-----/, // PEM keys
|
|
12
|
+
/password\s*=\s*\S+/i, // password= assignments
|
|
13
|
+
/secret\s*=\s*\S+/i, // secret= assignments
|
|
14
|
+
/token\s*=\s*['"][a-zA-Z0-9._\-]{20,}['"]/i, // token= with value
|
|
15
|
+
/Authorization:\s*[^\n]{20,}/i, // Auth headers
|
|
16
|
+
/\.env\s+\S+\s*=\s*\S{10,}/, // .env style assignments
|
|
17
|
+
/GITHUB_TOKEN[^a-zA-Z0-9]/, // GitHub tokens
|
|
18
|
+
/ghp_[a-zA-Z0-9]{36,}/, // GitHub PATs
|
|
19
|
+
/ghs_[a-zA-Z0-9]{36,}/, // GitHub secrets
|
|
20
|
+
/sk_live_[a-zA-Z0-9]{20,}/, // Stripe live keys
|
|
21
|
+
/sk_test_[a-zA-Z0-9]{20,}/, // Stripe test keys
|
|
22
|
+
/eyJ[a-zA-Z0-9_\-]{8,}\.eyJ[a-zA-Z0-9_\-]{8,}\.[a-zA-Z0-9_\-]{8,}/, // JWTs
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const REDACTION_PLACEHOLDER = "[REDACTED]";
|
|
26
|
+
const MAX_RAW_OUTPUT_BYTES = 4 * 1024; // 4KB max for raw output in evidence
|
|
27
|
+
|
|
28
|
+
function detectSensitive(text) {
|
|
29
|
+
if (!text || typeof text !== "string") return false;
|
|
30
|
+
return SENSITIVE_PATTERNS.some((re) => re.test(text));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function redactSensitive(text) {
|
|
34
|
+
if (!text || typeof text !== "string") return text;
|
|
35
|
+
let result = text;
|
|
36
|
+
for (const re of SENSITIVE_PATTERNS) {
|
|
37
|
+
result = result.replace(new RegExp(re.source, re.flags + (re.flags.includes("g") ? "" : "g")), REDACTION_PLACEHOLDER);
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function truncateLargeOutput(text, maxBytes = MAX_RAW_OUTPUT_BYTES) {
|
|
43
|
+
if (!text) return "";
|
|
44
|
+
const bytes = Buffer.byteLength(String(text), "utf8");
|
|
45
|
+
if (bytes <= maxBytes) return text;
|
|
46
|
+
const truncated = String(text).slice(0, maxBytes);
|
|
47
|
+
return truncated + `\n...(truncated, original ${bytes} bytes)`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function isInternalProtocolPayload(text) {
|
|
51
|
+
if (!text || typeof text !== "string") return false;
|
|
52
|
+
// Skip task-notification-like system payloads
|
|
53
|
+
const lower = text.toLowerCase();
|
|
54
|
+
return (
|
|
55
|
+
lower.includes("<task-notification>") ||
|
|
56
|
+
lower.includes("<system-reminder>") ||
|
|
57
|
+
lower.includes("<local-command-caveat>") ||
|
|
58
|
+
lower.includes("<<autonomous-loop")
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function captureMemoryItem(store, partial, opts = {}) {
|
|
63
|
+
const { captureSensitive = false } = opts;
|
|
64
|
+
|
|
65
|
+
// Skip internal protocol payloads
|
|
66
|
+
const combined = [partial.title, partial.summary, partial.evidence].join(" ");
|
|
67
|
+
if (isInternalProtocolPayload(combined)) return null;
|
|
68
|
+
|
|
69
|
+
// Sensitive detection
|
|
70
|
+
const isSensitive = detectSensitive(combined);
|
|
71
|
+
if (isSensitive && !captureSensitive) {
|
|
72
|
+
// Store a redacted version, flagged as sensitive and not auto-injectable
|
|
73
|
+
partial = {
|
|
74
|
+
...partial,
|
|
75
|
+
summary: redactSensitive(partial.summary || ""),
|
|
76
|
+
evidence: redactSensitive(partial.evidence || ""),
|
|
77
|
+
sensitive: true,
|
|
78
|
+
safeForAutoInject: false,
|
|
79
|
+
};
|
|
80
|
+
} else if (isSensitive && captureSensitive) {
|
|
81
|
+
partial = {
|
|
82
|
+
...partial,
|
|
83
|
+
sensitive: true,
|
|
84
|
+
safeForAutoInject: false,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Deduplication: skip if same session already has this title+type
|
|
89
|
+
if (partial.sessionId && store.hasDuplicate(partial.sessionId, partial.title, partial.type)) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Truncate large evidence
|
|
94
|
+
if (partial.evidence) {
|
|
95
|
+
partial = { ...partial, evidence: truncateLargeOutput(partial.evidence) };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return store.append(partial);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function captureFromFailure(store, params, opts = {}) {
|
|
102
|
+
const {
|
|
103
|
+
sessionId,
|
|
104
|
+
toolName,
|
|
105
|
+
errorText,
|
|
106
|
+
relatedFiles = [],
|
|
107
|
+
relatedCommands = [],
|
|
108
|
+
repoRoot,
|
|
109
|
+
} = params;
|
|
110
|
+
|
|
111
|
+
if (!errorText || !errorText.trim()) return null;
|
|
112
|
+
|
|
113
|
+
const truncated = truncateLargeOutput(errorText, 800);
|
|
114
|
+
const title = `Tool failure: ${toolName || "unknown"} — ${truncated.slice(0, 80).replace(/\n/g, " ")}`;
|
|
115
|
+
|
|
116
|
+
return captureMemoryItem(store, {
|
|
117
|
+
sessionId,
|
|
118
|
+
type: "failure",
|
|
119
|
+
title,
|
|
120
|
+
summary: `${toolName || "unknown"} failed during session.`,
|
|
121
|
+
evidence: truncated,
|
|
122
|
+
relatedFiles,
|
|
123
|
+
relatedCommands: relatedCommands.length ? relatedCommands : (toolName ? [toolName] : []),
|
|
124
|
+
confidence: "medium",
|
|
125
|
+
riskLevel: "medium",
|
|
126
|
+
staleStatus: "fresh",
|
|
127
|
+
safeForAutoInject: false,
|
|
128
|
+
tags: ["tool-failure", toolName].filter(Boolean),
|
|
129
|
+
repoRoot,
|
|
130
|
+
}, opts);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function captureFromFileChange(store, params, opts = {}) {
|
|
134
|
+
const {
|
|
135
|
+
sessionId,
|
|
136
|
+
filePath,
|
|
137
|
+
toolName,
|
|
138
|
+
summary,
|
|
139
|
+
repoRoot,
|
|
140
|
+
} = params;
|
|
141
|
+
|
|
142
|
+
if (!filePath) return null;
|
|
143
|
+
|
|
144
|
+
const title = `File updated: ${filePath}`;
|
|
145
|
+
|
|
146
|
+
return captureMemoryItem(store, {
|
|
147
|
+
sessionId,
|
|
148
|
+
type: "file_change",
|
|
149
|
+
title,
|
|
150
|
+
summary: summary || `${toolName || "Write"} updated ${filePath}.`,
|
|
151
|
+
evidence: `file=${filePath} tool=${toolName || "Write"}`,
|
|
152
|
+
relatedFiles: [filePath],
|
|
153
|
+
relatedCommands: toolName ? [toolName] : [],
|
|
154
|
+
confidence: "high",
|
|
155
|
+
riskLevel: "low",
|
|
156
|
+
staleStatus: "fresh",
|
|
157
|
+
safeForAutoInject: true,
|
|
158
|
+
tags: ["file-change"],
|
|
159
|
+
repoRoot,
|
|
160
|
+
}, opts);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function captureFromValidation(store, params, opts = {}) {
|
|
164
|
+
const {
|
|
165
|
+
sessionId,
|
|
166
|
+
title,
|
|
167
|
+
summary,
|
|
168
|
+
evidence,
|
|
169
|
+
passed,
|
|
170
|
+
relatedFiles = [],
|
|
171
|
+
relatedCommands = [],
|
|
172
|
+
repoRoot,
|
|
173
|
+
} = params;
|
|
174
|
+
|
|
175
|
+
return captureMemoryItem(store, {
|
|
176
|
+
sessionId,
|
|
177
|
+
type: "validation",
|
|
178
|
+
title: title || (passed ? "Validation passed" : "Validation failed"),
|
|
179
|
+
summary: summary || (passed ? "Validation succeeded." : "Validation failed."),
|
|
180
|
+
evidence: evidence || "",
|
|
181
|
+
relatedFiles,
|
|
182
|
+
relatedCommands,
|
|
183
|
+
confidence: passed ? "high" : "medium",
|
|
184
|
+
riskLevel: passed ? "low" : "medium",
|
|
185
|
+
staleStatus: "fresh",
|
|
186
|
+
safeForAutoInject: passed,
|
|
187
|
+
tags: [passed ? "validation-pass" : "validation-fail"],
|
|
188
|
+
repoRoot,
|
|
189
|
+
}, opts);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function captureFromSessionEnd(store, params, opts = {}) {
|
|
193
|
+
const {
|
|
194
|
+
sessionId,
|
|
195
|
+
nextAction,
|
|
196
|
+
whereAmINow,
|
|
197
|
+
whatHappened,
|
|
198
|
+
relatedFiles = [],
|
|
199
|
+
repoRoot,
|
|
200
|
+
} = params;
|
|
201
|
+
|
|
202
|
+
if (!nextAction && !whereAmINow) return null;
|
|
203
|
+
|
|
204
|
+
const title = nextAction
|
|
205
|
+
? `Next action: ${String(nextAction).slice(0, 120)}`
|
|
206
|
+
: `Session ended: ${String(whereAmINow || "unknown state").slice(0, 100)}`;
|
|
207
|
+
|
|
208
|
+
const summary = [
|
|
209
|
+
whereAmINow ? `State: ${whereAmINow}` : null,
|
|
210
|
+
whatHappened ? `What happened: ${whatHappened}` : null,
|
|
211
|
+
nextAction ? `Next: ${nextAction}` : null,
|
|
212
|
+
].filter(Boolean).join(". ");
|
|
213
|
+
|
|
214
|
+
return captureMemoryItem(store, {
|
|
215
|
+
sessionId,
|
|
216
|
+
type: "next_action",
|
|
217
|
+
title,
|
|
218
|
+
summary,
|
|
219
|
+
evidence: `session=${sessionId}`,
|
|
220
|
+
relatedFiles,
|
|
221
|
+
relatedCommands: [],
|
|
222
|
+
confidence: "medium",
|
|
223
|
+
riskLevel: "low",
|
|
224
|
+
staleStatus: "fresh",
|
|
225
|
+
safeForAutoInject: false,
|
|
226
|
+
tags: ["session-end", "reentry"],
|
|
227
|
+
repoRoot,
|
|
228
|
+
}, opts);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
module.exports = {
|
|
232
|
+
detectSensitive,
|
|
233
|
+
redactSensitive,
|
|
234
|
+
truncateLargeOutput,
|
|
235
|
+
isInternalProtocolPayload,
|
|
236
|
+
captureMemoryItem,
|
|
237
|
+
captureFromFailure,
|
|
238
|
+
captureFromFileChange,
|
|
239
|
+
captureFromValidation,
|
|
240
|
+
captureFromSessionEnd,
|
|
241
|
+
};
|