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,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
const crypto = require("node:crypto");
|
|
6
|
+
|
|
7
|
+
const CONTRACT = "avorelo.feedbackSignal.v1";
|
|
8
|
+
const SCHEMA_VERSION = 1;
|
|
9
|
+
|
|
10
|
+
const FEEDBACK_DIR_REL = ".claude/cco/feedback";
|
|
11
|
+
|
|
12
|
+
const VALID_SOURCES = Object.freeze([
|
|
13
|
+
"dogfood",
|
|
14
|
+
"manual_customer",
|
|
15
|
+
"support_note",
|
|
16
|
+
"session_review",
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
const VALID_FRICTION_TYPES = Object.freeze([
|
|
20
|
+
"missing_evidence",
|
|
21
|
+
"noisy_output",
|
|
22
|
+
"manual_fallback_required",
|
|
23
|
+
"generic_next_action",
|
|
24
|
+
"verification_missing",
|
|
25
|
+
"proof_missing",
|
|
26
|
+
"unavailable_worker",
|
|
27
|
+
"context_too_large",
|
|
28
|
+
"unknown_asset_repeated",
|
|
29
|
+
"high_risk_blocked_without_continuation",
|
|
30
|
+
"value_claim_not_evidence_backed",
|
|
31
|
+
"activation_friction",
|
|
32
|
+
"support_explainability_gap",
|
|
33
|
+
"other",
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
const VALID_SEVERITIES = Object.freeze(["low", "medium", "high", "critical"]);
|
|
37
|
+
|
|
38
|
+
// Patterns that must not appear in feedback payloads
|
|
39
|
+
const FORBIDDEN_PATTERNS = [
|
|
40
|
+
/\bpassword\b/i,
|
|
41
|
+
/\bsecret\b/i,
|
|
42
|
+
/\bapi[_-]?key\b/i,
|
|
43
|
+
/\btoken\b.*[:=]\s*[A-Za-z0-9+/=]{20,}/i,
|
|
44
|
+
/\bPRIVATE\s+KEY\b/,
|
|
45
|
+
/sk-[A-Za-z0-9]{20,}/,
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
function redactString(val) {
|
|
49
|
+
if (typeof val !== "string") return val;
|
|
50
|
+
let result = val;
|
|
51
|
+
for (const pattern of FORBIDDEN_PATTERNS) {
|
|
52
|
+
result = result.replace(pattern, "[REDACTED]");
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function redactPayload(obj) {
|
|
58
|
+
if (typeof obj === "string") return redactString(obj);
|
|
59
|
+
if (Array.isArray(obj)) return obj.map(redactPayload);
|
|
60
|
+
if (obj && typeof obj === "object") {
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
63
|
+
out[k] = redactPayload(v);
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
return obj;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function validateFeedbackSignal(signal) {
|
|
71
|
+
const errors = [];
|
|
72
|
+
|
|
73
|
+
if (!signal || typeof signal !== "object") {
|
|
74
|
+
return { valid: false, errors: ["Signal must be an object."] };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!VALID_SOURCES.includes(signal.source)) {
|
|
78
|
+
errors.push(`source must be one of: ${VALID_SOURCES.join(", ")}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!signal.summary || typeof signal.summary !== "string" || signal.summary.trim().length === 0) {
|
|
82
|
+
errors.push("summary is required and must be a non-empty string.");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (signal.frictionType && !VALID_FRICTION_TYPES.includes(signal.frictionType)) {
|
|
86
|
+
errors.push(`frictionType must be one of: ${VALID_FRICTION_TYPES.join(", ")}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (signal.severity && !VALID_SEVERITIES.includes(signal.severity)) {
|
|
90
|
+
errors.push(`severity must be one of: ${VALID_SEVERITIES.join(", ")}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Reject any forbidden patterns in summary or desiredBehavior
|
|
94
|
+
for (const field of ["summary", "desiredBehavior"]) {
|
|
95
|
+
if (typeof signal[field] === "string") {
|
|
96
|
+
for (const pattern of FORBIDDEN_PATTERNS) {
|
|
97
|
+
if (pattern.test(signal[field])) {
|
|
98
|
+
errors.push(`${field} contains forbidden/sensitive content.`);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return { valid: errors.length === 0, errors };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function normalizeFeedbackSignal(raw) {
|
|
109
|
+
const signal = {
|
|
110
|
+
contract: CONTRACT,
|
|
111
|
+
schemaVersion: SCHEMA_VERSION,
|
|
112
|
+
signalId: raw.signalId || `feedback-${crypto.randomBytes(6).toString("hex")}`,
|
|
113
|
+
source: raw.source,
|
|
114
|
+
persona: raw.persona || null,
|
|
115
|
+
runId: raw.runId || null,
|
|
116
|
+
frictionType: raw.frictionType || "other",
|
|
117
|
+
severity: raw.severity || "medium",
|
|
118
|
+
summary: redactString(raw.summary || ""),
|
|
119
|
+
desiredBehavior: redactString(raw.desiredBehavior || null),
|
|
120
|
+
evidencePath: raw.evidencePath || null,
|
|
121
|
+
createdAt: raw.createdAt || new Date().toISOString(),
|
|
122
|
+
redacted: true,
|
|
123
|
+
};
|
|
124
|
+
return signal;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function writeFeedbackSignal(cwd, raw) {
|
|
128
|
+
const validation = validateFeedbackSignal(raw);
|
|
129
|
+
if (!validation.valid) {
|
|
130
|
+
throw new Error(`Invalid feedback signal: ${validation.errors.join("; ")}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const signal = normalizeFeedbackSignal(raw);
|
|
134
|
+
const dir = path.join(cwd, FEEDBACK_DIR_REL);
|
|
135
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
136
|
+
|
|
137
|
+
const filename = `${signal.signalId}.json`;
|
|
138
|
+
const filePath = path.join(dir, filename);
|
|
139
|
+
fs.writeFileSync(filePath, JSON.stringify(signal, null, 2), "utf8");
|
|
140
|
+
|
|
141
|
+
return { filePath, signal };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function readFeedbackSignals(cwd) {
|
|
145
|
+
const dir = path.join(cwd, FEEDBACK_DIR_REL);
|
|
146
|
+
if (!fs.existsSync(dir)) return [];
|
|
147
|
+
|
|
148
|
+
const signals = [];
|
|
149
|
+
let files;
|
|
150
|
+
try {
|
|
151
|
+
files = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
|
|
152
|
+
} catch {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (const f of files) {
|
|
157
|
+
try {
|
|
158
|
+
const raw = JSON.parse(fs.readFileSync(path.join(dir, f), "utf8"));
|
|
159
|
+
if (raw.contract === CONTRACT) {
|
|
160
|
+
signals.push(raw);
|
|
161
|
+
}
|
|
162
|
+
} catch {
|
|
163
|
+
// skip corrupted
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return signals;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function summarizeFeedbackSignals(cwd) {
|
|
171
|
+
const signals = readFeedbackSignals(cwd);
|
|
172
|
+
if (signals.length === 0) {
|
|
173
|
+
return { total: 0, byFrictionType: {}, bySeverity: {}, topSummaries: [] };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const byFrictionType = {};
|
|
177
|
+
const bySeverity = {};
|
|
178
|
+
for (const s of signals) {
|
|
179
|
+
const ft = s.frictionType || "other";
|
|
180
|
+
byFrictionType[ft] = (byFrictionType[ft] || 0) + 1;
|
|
181
|
+
const sev = s.severity || "medium";
|
|
182
|
+
bySeverity[sev] = (bySeverity[sev] || 0) + 1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
total: signals.length,
|
|
187
|
+
byFrictionType,
|
|
188
|
+
bySeverity,
|
|
189
|
+
topSummaries: signals.slice(-5).map((s) => s.summary),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
module.exports = {
|
|
194
|
+
CONTRACT,
|
|
195
|
+
SCHEMA_VERSION,
|
|
196
|
+
FEEDBACK_DIR_REL,
|
|
197
|
+
VALID_SOURCES,
|
|
198
|
+
VALID_FRICTION_TYPES,
|
|
199
|
+
VALID_SEVERITIES,
|
|
200
|
+
validateFeedbackSignal,
|
|
201
|
+
normalizeFeedbackSignal,
|
|
202
|
+
writeFeedbackSignal,
|
|
203
|
+
readFeedbackSignals,
|
|
204
|
+
summarizeFeedbackSignals,
|
|
205
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// File integrity validation
|
|
2
|
+
// Ensures "completed" states actually have required files
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Expected files for a "completed" onboarding state
|
|
9
|
+
*/
|
|
10
|
+
const EXPECTED_ONBOARDING_FILES = [
|
|
11
|
+
'.claude/cco/config.json',
|
|
12
|
+
'.claude/cco/state/onboarding.json',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Validates that required files exist when onboarding state claims completion
|
|
17
|
+
* If files are missing, returns validation errors for repair
|
|
18
|
+
*/
|
|
19
|
+
function validateOnboardingFileIntegrity(cwd) {
|
|
20
|
+
const missing = [];
|
|
21
|
+
const onboardingPath = path.join(cwd, '.claude/cco/state/onboarding.json');
|
|
22
|
+
|
|
23
|
+
// Check onboarding state exists
|
|
24
|
+
if (!fs.existsSync(onboardingPath)) {
|
|
25
|
+
return {
|
|
26
|
+
isValid: false,
|
|
27
|
+
reason: 'no-state',
|
|
28
|
+
missing: [onboardingPath],
|
|
29
|
+
recommendedAction: 'Run initial setup'
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Check if state says "completed"
|
|
34
|
+
try {
|
|
35
|
+
const state = JSON.parse(fs.readFileSync(onboardingPath, 'utf8'));
|
|
36
|
+
if (state.status === 'completed') {
|
|
37
|
+
// Verify expected files exist
|
|
38
|
+
for (const file of EXPECTED_ONBOARDING_FILES) {
|
|
39
|
+
const fullPath = path.join(cwd, file);
|
|
40
|
+
if (!fs.existsSync(fullPath)) {
|
|
41
|
+
missing.push(file);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (missing.length > 0) {
|
|
46
|
+
return {
|
|
47
|
+
isValid: false,
|
|
48
|
+
reason: 'missing-files',
|
|
49
|
+
missing: missing,
|
|
50
|
+
recommendedAction: 'Restore missing onboarding files or re-run initialization'
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch (err) {
|
|
55
|
+
return {
|
|
56
|
+
isValid: false,
|
|
57
|
+
reason: 'corrupt-state',
|
|
58
|
+
error: err.message
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { isValid: true };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = {
|
|
66
|
+
validateOnboardingFileIntegrity,
|
|
67
|
+
EXPECTED_ONBOARDING_FILES
|
|
68
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const {
|
|
6
|
+
readProjectConfig,
|
|
7
|
+
ensureProjectConfig,
|
|
8
|
+
writeProjectConfig,
|
|
9
|
+
readTeamPolicy,
|
|
10
|
+
ensureTeamPolicy,
|
|
11
|
+
getEffectiveConfig,
|
|
12
|
+
} = require("./config");
|
|
13
|
+
|
|
14
|
+
function readStdinJson() {
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
let data = "";
|
|
17
|
+
process.stdin.setEncoding("utf8");
|
|
18
|
+
process.stdin.on("data", (chunk) => (data += chunk));
|
|
19
|
+
process.stdin.on("end", () => {
|
|
20
|
+
try {
|
|
21
|
+
resolve(JSON.parse(data || "{}"));
|
|
22
|
+
} catch {
|
|
23
|
+
resolve({});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function ensureDir(p) {
|
|
30
|
+
fs.mkdirSync(p, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function ensureCcoDirs(cwd) {
|
|
34
|
+
// Essential directories for local-first operation (7 dirs for core functionality)
|
|
35
|
+
ensureDir(path.join(cwd, ".claude", "cco", "reports"));
|
|
36
|
+
ensureDir(path.join(cwd, ".claude", "cco", "metrics"));
|
|
37
|
+
ensureDir(path.join(cwd, ".claude", "cco", "state"));
|
|
38
|
+
ensureDir(path.join(cwd, ".claude", "cco", "security"));
|
|
39
|
+
ensureDir(path.join(cwd, ".claude", "cco", "events"));
|
|
40
|
+
ensureDir(path.join(cwd, ".claude", "cco", "memory"));
|
|
41
|
+
ensureDir(path.join(cwd, ".claude", "cco", "orchestration"));
|
|
42
|
+
ensureDir(path.join(cwd, ".claude", "cco", "orchestration", "runs"));
|
|
43
|
+
ensureDir(path.join(cwd, ".claude", "cco", "orchestration", "handoffs"));
|
|
44
|
+
ensureDir(path.join(cwd, ".claude", "cco", "orchestration", "host-contracts"));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function safeWriteText(cwd, relPath, content) {
|
|
48
|
+
const abs = path.join(cwd, relPath);
|
|
49
|
+
ensureDir(path.dirname(abs));
|
|
50
|
+
fs.writeFileSync(abs, content, "utf8");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function safeWriteJson(cwd, relPath, obj) {
|
|
54
|
+
safeWriteText(cwd, relPath, JSON.stringify(obj, null, 2));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function safeReadJson(cwd, relPath, fallback = null) {
|
|
58
|
+
const abs = path.join(cwd, relPath);
|
|
59
|
+
try {
|
|
60
|
+
return JSON.parse(fs.readFileSync(abs, "utf8").replace(/^\uFEFF/, ""));
|
|
61
|
+
} catch {
|
|
62
|
+
return fallback;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function nowIso() {
|
|
67
|
+
return new Date().toISOString();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function latestArtifactMeta(cwd, dirRel, nameContains) {
|
|
71
|
+
const dir = path.join(cwd, dirRel);
|
|
72
|
+
try {
|
|
73
|
+
const files = fs
|
|
74
|
+
.readdirSync(dir)
|
|
75
|
+
.filter((f) => f.endsWith(".json") && (!nameContains || f.includes(nameContains)));
|
|
76
|
+
if (!files.length) return null;
|
|
77
|
+
const latest = files
|
|
78
|
+
.map((name) => ({ name, mtimeMs: fs.statSync(path.join(dir, name)).mtimeMs }))
|
|
79
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs)[0];
|
|
80
|
+
return {
|
|
81
|
+
relPath: path.posix.join(dirRel.replace(/\\/g, "/"), latest.name.replace(/\\/g, "/")),
|
|
82
|
+
mtimeMs: latest.mtimeMs,
|
|
83
|
+
};
|
|
84
|
+
} catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function latestSecurityScanMeta(cwd) {
|
|
90
|
+
return latestArtifactMeta(cwd, ".claude/cco/security", null);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function latestTrustAuditMeta(cwd) {
|
|
94
|
+
return latestArtifactMeta(cwd, ".claude/cco/security", "trust-audit-");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function latestMemoryProfileMeta(cwd) {
|
|
98
|
+
return latestArtifactMeta(cwd, ".claude/cco/memory", "profile");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function latestIntelSignalsMeta(cwd) {
|
|
102
|
+
return latestArtifactMeta(cwd, ".claude/cco/intel/signals", null);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function latestOutcomeEventsMeta(cwd) {
|
|
106
|
+
return latestArtifactMeta(cwd, ".claude/cco/events", "outcome-events");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
readStdinJson,
|
|
111
|
+
ensureCcoDirs,
|
|
112
|
+
safeWriteJson,
|
|
113
|
+
safeWriteText,
|
|
114
|
+
safeReadJson,
|
|
115
|
+
readProjectConfig,
|
|
116
|
+
ensureProjectConfig,
|
|
117
|
+
writeProjectConfig,
|
|
118
|
+
readTeamPolicy,
|
|
119
|
+
ensureTeamPolicy,
|
|
120
|
+
getEffectiveConfig,
|
|
121
|
+
nowIso,
|
|
122
|
+
latestSecurityScanMeta,
|
|
123
|
+
latestTrustAuditMeta,
|
|
124
|
+
latestMemoryProfileMeta,
|
|
125
|
+
latestIntelSignalsMeta,
|
|
126
|
+
latestOutcomeEventsMeta,
|
|
127
|
+
};
|