avorelo 0.3.5 → 0.3.6

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.
Files changed (3) hide show
  1. package/README.md +77 -77
  2. package/dist/avorelo.mjs +1450 -24
  3. package/package.json +4 -3
package/dist/avorelo.mjs CHANGED
@@ -2562,6 +2562,7 @@ function buildCapabilityRouteDecision(input) {
2562
2562
  const proposalHints = unique(input.proposalHints ?? []);
2563
2563
  const allowedLegacyFeatures = input.allowedLegacyFeatures ?? [];
2564
2564
  pushCapability(selected, expectedEvidence, reasonCodes, "context-check", "CONTEXT_CHECK_REUSED", ["context_check_result"]);
2565
+ pushCapability(selected, expectedEvidence, reasonCodes, "context-control", "CONTEXT_CONTROL_ACTIVE", ["context_control_summary"]);
2565
2566
  pushCapability(selected, expectedEvidence, reasonCodes, "tool-governance", "TOOL_GOVERNANCE_REUSED", ["tool_routing_projection"]);
2566
2567
  pushCapability(selected, expectedEvidence, reasonCodes, "receipt-trace", "KERNEL_RECEIPTS_REUSED", ["kernel_receipt_ref"]);
2567
2568
  pushCapability(selected, expectedEvidence, reasonCodes, "model-routing", "MODEL_ROUTING_SUBORDINATE", ["model_routing_projection"]);
@@ -2752,7 +2753,8 @@ var init_work_controls = __esm({
2752
2753
  "loop-control",
2753
2754
  "drift-guard",
2754
2755
  "company-loop",
2755
- "founder-cockpit"
2756
+ "founder-cockpit",
2757
+ "context-control"
2756
2758
  ];
2757
2759
  CAPABILITY_TO_LEGACY_FEATURE = {
2758
2760
  "production-confidence": "visual-proof",
@@ -8120,7 +8122,7 @@ function runFullActivation(targetDir) {
8120
8122
  const dashboardPath = join27(targetDir, ".avorelo", "dashboard", "index.html");
8121
8123
  const localDashboard = { available: existsSync30(dashboardPath), path: existsSync30(dashboardPath) ? dashboardPath : void 0 };
8122
8124
  const blockers = repairsBlocked.length;
8123
- const activationStatus = blockers > 0 ? "blocked" : "active_with_holds";
8125
+ const activationStatus = blockers > 0 ? "blocked" : "active";
8124
8126
  const existingState = readActivationState(targetDir);
8125
8127
  const workspaceId = existingState?.workspaceId || makeWorkspaceId(targetDir);
8126
8128
  const state = {
@@ -8845,7 +8847,7 @@ import { join as join40 } from "node:path";
8845
8847
 
8846
8848
  // src/avorelo/capabilities/runtime-flow/index.ts
8847
8849
  init_entitlement_resolver();
8848
- import { createHash as createHash12 } from "node:crypto";
8850
+ import { createHash as createHash13 } from "node:crypto";
8849
8851
  import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, appendFileSync as appendFileSync9, readFileSync as readFileSync23, existsSync as existsSync39 } from "node:fs";
8850
8852
  import { join as join39 } from "node:path";
8851
8853
 
@@ -11473,6 +11475,1281 @@ function buildSummary(status, sourceCount, findingCount) {
11473
11475
  return `Checked ${sourceCount} instruction source(s). ${findingCount} finding(s) detected.`;
11474
11476
  }
11475
11477
 
11478
+ // src/avorelo/kernel/context-control/classify.ts
11479
+ var SECRET_PATTERNS2 = [
11480
+ /(?:api[_-]?key|apikey)\s*[:=]\s*\S+/i,
11481
+ /(?:secret|token|password|passwd|pwd)\s*[:=]\s*\S+/i,
11482
+ /(?:aws|gcp|azure)[_-](?:access|secret|key)\s*[:=]/i,
11483
+ /-----BEGIN (?:RSA |EC )?PRIVATE KEY-----/,
11484
+ /(?:sk-|pk-|rk-)[a-zA-Z0-9]{20,}/,
11485
+ /ghp_[a-zA-Z0-9]{36}/,
11486
+ /glpat-[a-zA-Z0-9_-]{20,}/,
11487
+ /xox[bpsa]-[a-zA-Z0-9-]+/
11488
+ ];
11489
+ var FORBIDDEN_PATTERNS = [
11490
+ /PRIVATE[_ ]KEY/,
11491
+ /\.env\b/,
11492
+ /credentials\.json/,
11493
+ /id_rsa/,
11494
+ /-----BEGIN (?:RSA |EC )?PRIVATE KEY-----/
11495
+ ];
11496
+ function classifyContentType(content, label) {
11497
+ const lower = label.toLowerCase();
11498
+ const trimmed = content.slice(0, 2e3);
11499
+ if (lower.includes("log") || lower.includes("output")) {
11500
+ if (/^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}/.test(trimmed)) return "log";
11501
+ if (/\b(?:ERROR|WARN|INFO|DEBUG|FATAL)\b/.test(trimmed)) return "log";
11502
+ if (/(?:exit code|exited with|status:)\s*\d/i.test(trimmed)) return "log";
11503
+ }
11504
+ if (lower.includes("test")) {
11505
+ if (/(?:PASS|FAIL|✓|✗|passed|failed)\s/i.test(trimmed)) return "test_output";
11506
+ if (/(?:tests?|specs?|suites?)\s+\d+/i.test(trimmed)) return "test_output";
11507
+ }
11508
+ if (lower.includes("diff") || lower.includes("patch")) return "diff";
11509
+ if (lower.includes("tree") || lower.includes("directory")) return "file_tree";
11510
+ if (lower.includes("conversation") || lower.includes("history") || lower.includes("session")) return "conversation_history";
11511
+ if (lower.includes("receipt") || lower.includes("proof") || lower.includes("evidence")) return "receipt_proof_evidence";
11512
+ if (lower.includes("doc") || lower.includes("readme") || lower.includes("markdown")) return "documentation";
11513
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
11514
+ try {
11515
+ JSON.parse(content);
11516
+ return "json_tool_output";
11517
+ } catch {
11518
+ }
11519
+ }
11520
+ if (/^diff --git/.test(trimmed) || /^@@\s/.test(trimmed)) return "diff";
11521
+ if (/^[├└│─\s]+/.test(trimmed) || /^\s*[a-z_-]+\/$/m.test(trimmed)) return "file_tree";
11522
+ if (/\b(?:function|class|const|let|var|import|export|def |async )\b/.test(trimmed)) return "source_like";
11523
+ return "unknown";
11524
+ }
11525
+ function classifySensitivity(content) {
11526
+ for (const pattern of FORBIDDEN_PATTERNS) {
11527
+ if (pattern.test(content)) return "forbidden";
11528
+ }
11529
+ for (const pattern of SECRET_PATTERNS2) {
11530
+ if (pattern.test(content)) return "secret_like";
11531
+ }
11532
+ if (/\b(?:internal|private|confidential)\b/i.test(content.slice(0, 500))) return "internal";
11533
+ return "public";
11534
+ }
11535
+ function classifyPersistence(sensitivity) {
11536
+ switch (sensitivity) {
11537
+ case "forbidden":
11538
+ return { safeForModel: false, safeForPersistence: false, safeForCloudSync: false, localOnly: true, forbidden: true };
11539
+ case "secret_like":
11540
+ return { safeForModel: false, safeForPersistence: false, safeForCloudSync: false, localOnly: true, forbidden: false };
11541
+ case "local_only":
11542
+ return { safeForModel: true, safeForPersistence: true, safeForCloudSync: false, localOnly: true, forbidden: false };
11543
+ case "internal":
11544
+ return { safeForModel: true, safeForPersistence: true, safeForCloudSync: false, localOnly: false, forbidden: false };
11545
+ case "public":
11546
+ return { safeForModel: true, safeForPersistence: true, safeForCloudSync: true, localOnly: false, forbidden: false };
11547
+ }
11548
+ }
11549
+ function classifyVolatility(contentType) {
11550
+ switch (contentType) {
11551
+ case "documentation":
11552
+ case "receipt_proof_evidence":
11553
+ return "stable";
11554
+ case "file_tree":
11555
+ case "source_like":
11556
+ return "semi_stable";
11557
+ default:
11558
+ return "volatile";
11559
+ }
11560
+ }
11561
+ function classifyEvidenceRequirement(contentType, sensitivity) {
11562
+ if (sensitivity === "forbidden") return "forbidden";
11563
+ if (contentType === "receipt_proof_evidence") return "proof_critical";
11564
+ if (contentType === "test_output" || contentType === "diff") return "proof_critical";
11565
+ if (contentType === "log") return "helpful";
11566
+ if (contentType === "file_tree") return "noise";
11567
+ return "helpful";
11568
+ }
11569
+ function classifyRoleRelevance(contentType) {
11570
+ switch (contentType) {
11571
+ case "log":
11572
+ case "test_output":
11573
+ return ["executor", "reviewer", "proof_adapter"];
11574
+ case "diff":
11575
+ return ["reviewer", "proof_adapter"];
11576
+ case "json_tool_output":
11577
+ return ["executor", "reviewer"];
11578
+ case "file_tree":
11579
+ return ["executor"];
11580
+ case "receipt_proof_evidence":
11581
+ return ["proof_adapter", "receipt", "status"];
11582
+ case "conversation_history":
11583
+ return ["executor"];
11584
+ case "documentation":
11585
+ return ["executor", "reviewer"];
11586
+ default:
11587
+ return ["executor"];
11588
+ }
11589
+ }
11590
+ function estimateTokens(content) {
11591
+ return Math.ceil(content.length / 4);
11592
+ }
11593
+ function classifyItem(item2) {
11594
+ const contentType = classifyContentType(item2.content, item2.label);
11595
+ const sensitivity = classifySensitivity(item2.content);
11596
+ const persistence = classifyPersistence(sensitivity);
11597
+ const volatility = classifyVolatility(contentType);
11598
+ const evidenceRequirement = classifyEvidenceRequirement(contentType, sensitivity);
11599
+ const roleRelevance = classifyRoleRelevance(contentType);
11600
+ const tokens = estimateTokens(item2.content);
11601
+ return {
11602
+ contentType,
11603
+ sensitivity,
11604
+ persistence,
11605
+ roleRelevance,
11606
+ volatility,
11607
+ evidenceRequirement,
11608
+ estimatedTokens: tokens
11609
+ };
11610
+ }
11611
+ function containsSecrets(content) {
11612
+ return SECRET_PATTERNS2.some((p) => p.test(content));
11613
+ }
11614
+ function containsForbiddenContent(content) {
11615
+ return FORBIDDEN_PATTERNS.some((p) => p.test(content));
11616
+ }
11617
+
11618
+ // src/avorelo/kernel/context-control/evidence-store.ts
11619
+ import { createHash as createHash12 } from "node:crypto";
11620
+ var evidenceCounter = 0;
11621
+ function createEvidenceRef(kind, sourceType, safeSummary, originalContent) {
11622
+ evidenceCounter++;
11623
+ const hash = createHash12("sha256").update(originalContent).digest("hex").slice(0, 16);
11624
+ return {
11625
+ id: `ctx-ev-${Date.now()}-${evidenceCounter}`,
11626
+ kind,
11627
+ sourceType,
11628
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
11629
+ localOnly: true,
11630
+ safeSummary: safeSummary.slice(0, 200),
11631
+ retrievalPolicy: "available",
11632
+ redactionStatus: "clean",
11633
+ provenanceTags: [],
11634
+ contentHash: hash
11635
+ };
11636
+ }
11637
+ function createBlockedEvidenceRef(sourceType, reason) {
11638
+ evidenceCounter++;
11639
+ return {
11640
+ id: `ctx-ev-blocked-${Date.now()}-${evidenceCounter}`,
11641
+ kind: "BLOCKED",
11642
+ sourceType,
11643
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
11644
+ localOnly: true,
11645
+ safeSummary: `Blocked: ${reason.slice(0, 150)}`,
11646
+ retrievalPolicy: "forbidden",
11647
+ redactionStatus: "forbidden",
11648
+ provenanceTags: [],
11649
+ contentHash: ""
11650
+ };
11651
+ }
11652
+
11653
+ // src/avorelo/kernel/context-control/reducers/logs.ts
11654
+ var ERROR_PATTERNS = [
11655
+ /\b(?:ERROR|FATAL|CRITICAL|PANIC)\b/i,
11656
+ /\bfailed\b/i,
11657
+ /\berror\b/i,
11658
+ /\bException\b/,
11659
+ /\bTraceback\b/,
11660
+ /exit code [1-9]/i,
11661
+ /exited with (?:code )?[1-9]/i,
11662
+ /\bsegfault\b/i,
11663
+ /\bOOM\b/,
11664
+ /\bkilled\b/i
11665
+ ];
11666
+ var WARNING_PATTERNS = [
11667
+ /\bWARN(?:ING)?\b/i,
11668
+ /\bdeprecated\b/i,
11669
+ /\bskipped\b/i
11670
+ ];
11671
+ var COMMAND_PATTERNS = [
11672
+ /^\$\s+.+/m,
11673
+ /^>\s+.+/m,
11674
+ /^Running\s+/m,
11675
+ /^Executing\s+/m
11676
+ ];
11677
+ var SECRET_LINE_PATTERNS = [
11678
+ /(?:api[_-]?key|apikey|secret|token|password|passwd|pwd)\s*[:=]\s*\S+/i,
11679
+ /(?:sk-|pk-|rk-)[a-zA-Z0-9]{20,}/,
11680
+ /ghp_[a-zA-Z0-9]{36}/,
11681
+ /(?:aws|gcp|azure)[_-](?:access|secret|key)/i
11682
+ ];
11683
+ function isImportantLine(line) {
11684
+ return ERROR_PATTERNS.some((p) => p.test(line)) || WARNING_PATTERNS.some((p) => p.test(line)) || COMMAND_PATTERNS.some((p) => p.test(line));
11685
+ }
11686
+ function containsSecret(line) {
11687
+ return SECRET_LINE_PATTERNS.some((p) => p.test(line));
11688
+ }
11689
+ function redactSecretLine(line) {
11690
+ return line.replace(
11691
+ /((?:api[_-]?key|apikey|secret|token|password|passwd|pwd)\s*[:=]\s*)\S+/gi,
11692
+ "$1[REDACTED]"
11693
+ ).replace(
11694
+ /(?:sk-|pk-|rk-)[a-zA-Z0-9]{20,}/g,
11695
+ "[REDACTED_KEY]"
11696
+ ).replace(
11697
+ /ghp_[a-zA-Z0-9]{36}/g,
11698
+ "[REDACTED_GITHUB_TOKEN]"
11699
+ );
11700
+ }
11701
+ function reduceLogs(content, label) {
11702
+ const tokensBefore = estimateTokens(content);
11703
+ const lines = content.split("\n");
11704
+ if (lines.length <= 50) {
11705
+ const cleaned = lines.map((l) => containsSecret(l) ? redactSecretLine(l) : l).join("\n");
11706
+ return {
11707
+ reduced: cleaned,
11708
+ estimatedTokensBefore: tokensBefore,
11709
+ estimatedTokensAfter: estimateTokens(cleaned),
11710
+ evidenceRef: createEvidenceRef("LOG_REDUCTION", "log", `Log: ${label}`, content),
11711
+ proofImpact: "PASS",
11712
+ reasonCodes: lines.some(containsSecret) ? ["SECRET_REDACTED_IN_LOG"] : ["SHORT_LOG_KEPT"],
11713
+ blockedContent: false
11714
+ };
11715
+ }
11716
+ const importantLines = [];
11717
+ const repeatedCounts = /* @__PURE__ */ new Map();
11718
+ let totalLines = lines.length;
11719
+ let errorCount = 0;
11720
+ let warnCount = 0;
11721
+ let secretsRedacted = 0;
11722
+ for (let i = 0; i < lines.length; i++) {
11723
+ const line = lines[i];
11724
+ const trimmed = line.trim();
11725
+ if (!trimmed) continue;
11726
+ if (containsSecret(line)) {
11727
+ secretsRedacted++;
11728
+ const redacted = redactSecretLine(line);
11729
+ if (isImportantLine(line)) {
11730
+ importantLines.push(redacted);
11731
+ }
11732
+ continue;
11733
+ }
11734
+ if (isImportantLine(line)) {
11735
+ if (ERROR_PATTERNS.some((p) => p.test(line))) errorCount++;
11736
+ if (WARNING_PATTERNS.some((p) => p.test(line))) warnCount++;
11737
+ importantLines.push(line);
11738
+ const contextStart = Math.max(0, i - 2);
11739
+ const contextEnd = Math.min(lines.length - 1, i + 2);
11740
+ for (let j = contextStart; j <= contextEnd; j++) {
11741
+ if (j !== i && lines[j].trim() && !isImportantLine(lines[j])) {
11742
+ if (!containsSecret(lines[j])) {
11743
+ importantLines.push(` ${lines[j]}`);
11744
+ }
11745
+ }
11746
+ }
11747
+ continue;
11748
+ }
11749
+ const normalized = trimmed.replace(/\d+/g, "N").replace(/0x[a-fA-F0-9]+/g, "0xN");
11750
+ repeatedCounts.set(normalized, (repeatedCounts.get(normalized) || 0) + 1);
11751
+ }
11752
+ const repeatedSummary = [];
11753
+ for (const [pattern, count] of repeatedCounts) {
11754
+ if (count >= 3) {
11755
+ repeatedSummary.push(` (${count}x) ${pattern.slice(0, 120)}`);
11756
+ }
11757
+ }
11758
+ const parts = [
11759
+ `--- Log Summary: ${label} ---`,
11760
+ `Total lines: ${totalLines}`,
11761
+ `Errors: ${errorCount} | Warnings: ${warnCount} | Secrets redacted: ${secretsRedacted}`,
11762
+ "",
11763
+ "--- Important Lines ---",
11764
+ ...importantLines.slice(0, 100)
11765
+ ];
11766
+ if (repeatedSummary.length > 0) {
11767
+ parts.push("", "--- Repeated Patterns ---", ...repeatedSummary.slice(0, 20));
11768
+ }
11769
+ const reduced = parts.join("\n");
11770
+ const tokensAfter = estimateTokens(reduced);
11771
+ const reasonCodes = ["LARGE_LOG_REDUCED"];
11772
+ if (secretsRedacted > 0) reasonCodes.push("SECRET_REDACTED_IN_LOG");
11773
+ if (errorCount > 0) reasonCodes.push("ERRORS_PRESERVED");
11774
+ if (repeatedSummary.length > 0) reasonCodes.push("REPEATED_LINES_SUMMARIZED");
11775
+ const proofImpact = errorCount > 0 && importantLines.length > 0 ? "PASS" : "DEGRADED";
11776
+ return {
11777
+ reduced,
11778
+ estimatedTokensBefore: tokensBefore,
11779
+ estimatedTokensAfter: tokensAfter,
11780
+ evidenceRef: createEvidenceRef("LOG_REDUCTION", "log", `Log reduced: ${label}`, content),
11781
+ proofImpact,
11782
+ reasonCodes,
11783
+ blockedContent: false
11784
+ };
11785
+ }
11786
+
11787
+ // src/avorelo/kernel/context-control/reducers/json.ts
11788
+ var MAX_ARRAY_ITEMS = 3;
11789
+ var MAX_STRING_LENGTH2 = 200;
11790
+ var MAX_DEPTH = 6;
11791
+ function truncateValue(value, depth) {
11792
+ if (depth > MAX_DEPTH) return "[... nested beyond depth limit]";
11793
+ if (value === null || value === void 0) return value;
11794
+ if (typeof value === "boolean" || typeof value === "number") return value;
11795
+ if (typeof value === "string") {
11796
+ if (value.length > MAX_STRING_LENGTH2) {
11797
+ return value.slice(0, MAX_STRING_LENGTH2) + `... (${value.length} chars)`;
11798
+ }
11799
+ return value;
11800
+ }
11801
+ if (Array.isArray(value)) {
11802
+ if (value.length === 0) return [];
11803
+ const truncated = value.slice(0, MAX_ARRAY_ITEMS).map((v) => truncateValue(v, depth + 1));
11804
+ if (value.length > MAX_ARRAY_ITEMS) {
11805
+ truncated.push(`... (${value.length - MAX_ARRAY_ITEMS} more items, ${value.length} total)`);
11806
+ }
11807
+ return truncated;
11808
+ }
11809
+ if (typeof value === "object") {
11810
+ const obj = value;
11811
+ const keys = Object.keys(obj);
11812
+ const result3 = {};
11813
+ const priorityKeys = ["error", "message", "status", "code", "name", "type", "id", "path"];
11814
+ const sortedKeys = [
11815
+ ...priorityKeys.filter((k) => keys.includes(k)),
11816
+ ...keys.filter((k) => !priorityKeys.includes(k))
11817
+ ];
11818
+ for (const key of sortedKeys) {
11819
+ result3[key] = truncateValue(obj[key], depth + 1);
11820
+ }
11821
+ return result3;
11822
+ }
11823
+ return String(value);
11824
+ }
11825
+ function reduceJson(content, label) {
11826
+ const tokensBefore = estimateTokens(content);
11827
+ let parsed;
11828
+ try {
11829
+ parsed = JSON.parse(content);
11830
+ } catch {
11831
+ const fallback = content.slice(0, 2e3) + (content.length > 2e3 ? `
11832
+ ... (${content.length} chars total, malformed JSON)` : "");
11833
+ return {
11834
+ reduced: fallback,
11835
+ estimatedTokensBefore: tokensBefore,
11836
+ estimatedTokensAfter: estimateTokens(fallback),
11837
+ evidenceRef: createEvidenceRef("JSON_REDUCTION", "json_tool_output", `JSON fallback: ${label}`, content),
11838
+ proofImpact: "DEGRADED",
11839
+ reasonCodes: ["MALFORMED_JSON_TRUNCATED"],
11840
+ blockedContent: false
11841
+ };
11842
+ }
11843
+ const truncated = truncateValue(parsed, 0);
11844
+ const reduced = JSON.stringify(truncated, null, 2);
11845
+ const tokensAfter = estimateTokens(reduced);
11846
+ const reasonCodes = ["JSON_STRUCTURE_PRESERVED"];
11847
+ if (tokensAfter < tokensBefore * 0.8) {
11848
+ reasonCodes.push("JSON_ARRAYS_TRUNCATED");
11849
+ }
11850
+ return {
11851
+ reduced,
11852
+ estimatedTokensBefore: tokensBefore,
11853
+ estimatedTokensAfter: tokensAfter,
11854
+ evidenceRef: createEvidenceRef("JSON_REDUCTION", "json_tool_output", `JSON reduced: ${label}`, content),
11855
+ proofImpact: "PASS",
11856
+ reasonCodes,
11857
+ blockedContent: false
11858
+ };
11859
+ }
11860
+
11861
+ // src/avorelo/kernel/context-control/reducers/file-tree.ts
11862
+ var GENERATED_DIRS = /* @__PURE__ */ new Set([
11863
+ "node_modules",
11864
+ "dist",
11865
+ "build",
11866
+ "out",
11867
+ ".next",
11868
+ ".nuxt",
11869
+ ".output",
11870
+ "coverage",
11871
+ ".nyc_output",
11872
+ "__pycache__",
11873
+ ".pytest_cache",
11874
+ ".git",
11875
+ ".svn",
11876
+ ".hg",
11877
+ "vendor",
11878
+ "bower_components",
11879
+ ".cache",
11880
+ ".parcel-cache",
11881
+ ".turbo",
11882
+ "target",
11883
+ "bin",
11884
+ "obj",
11885
+ ".terraform",
11886
+ ".serverless"
11887
+ ]);
11888
+ var PRIORITY_PATTERNS = [
11889
+ /^src\//,
11890
+ /^lib\//,
11891
+ /^app\//,
11892
+ /^pages\//,
11893
+ /^components\//,
11894
+ /^tests?\//,
11895
+ /^__tests__\//,
11896
+ /^spec\//,
11897
+ /^scripts?\//,
11898
+ /^config/,
11899
+ /^\.(?:env|eslint|prettier|babel|jest|vitest)/,
11900
+ /(?:package|tsconfig|webpack|vite|rollup)\.(?:json|config|js|ts|mjs|cjs)$/,
11901
+ /(?:README|CHANGELOG|LICENSE|CLAUDE|AGENTS|CONTRIBUTING)\b/i,
11902
+ /^docs?\//
11903
+ ];
11904
+ function isPriority(path) {
11905
+ return PRIORITY_PATTERNS.some((p) => p.test(path));
11906
+ }
11907
+ function isGeneratedDir(segment) {
11908
+ return GENERATED_DIRS.has(segment.toLowerCase());
11909
+ }
11910
+ function reduceFileTree(content, label) {
11911
+ const tokensBefore = estimateTokens(content);
11912
+ const lines = content.split("\n").filter((l) => l.trim());
11913
+ if (lines.length <= 100) {
11914
+ return {
11915
+ reduced: content,
11916
+ estimatedTokensBefore: tokensBefore,
11917
+ estimatedTokensAfter: tokensBefore,
11918
+ evidenceRef: null,
11919
+ proofImpact: "PASS",
11920
+ reasonCodes: ["SMALL_TREE_KEPT"],
11921
+ blockedContent: false
11922
+ };
11923
+ }
11924
+ const priorityPaths = [];
11925
+ const generatedDirs = /* @__PURE__ */ new Map();
11926
+ const otherPaths = [];
11927
+ for (const line of lines) {
11928
+ const cleaned = line.replace(/^[├└│─\s│]+/, "").trim();
11929
+ if (!cleaned) continue;
11930
+ const firstSegment = cleaned.split("/")[0];
11931
+ if (isGeneratedDir(firstSegment)) {
11932
+ generatedDirs.set(firstSegment, (generatedDirs.get(firstSegment) || 0) + 1);
11933
+ continue;
11934
+ }
11935
+ if (isPriority(cleaned)) {
11936
+ priorityPaths.push(cleaned);
11937
+ } else {
11938
+ otherPaths.push(cleaned);
11939
+ }
11940
+ }
11941
+ const parts = [
11942
+ `--- File Tree Summary: ${label} ---`,
11943
+ `Total entries: ${lines.length}`,
11944
+ "",
11945
+ "--- Source & Config (priority) ---",
11946
+ ...priorityPaths.slice(0, 80)
11947
+ ];
11948
+ if (otherPaths.length > 0) {
11949
+ parts.push("", `--- Other (${otherPaths.length} entries) ---`);
11950
+ parts.push(...otherPaths.slice(0, 30));
11951
+ if (otherPaths.length > 30) {
11952
+ parts.push(` ... (${otherPaths.length - 30} more)`);
11953
+ }
11954
+ }
11955
+ if (generatedDirs.size > 0) {
11956
+ parts.push("", "--- Generated/Vendor (summarized) ---");
11957
+ for (const [dir, count] of generatedDirs) {
11958
+ parts.push(` ${dir}/ (${count} entries)`);
11959
+ }
11960
+ }
11961
+ const reduced = parts.join("\n");
11962
+ return {
11963
+ reduced,
11964
+ estimatedTokensBefore: tokensBefore,
11965
+ estimatedTokensAfter: estimateTokens(reduced),
11966
+ evidenceRef: createEvidenceRef("FILE_TREE_REDUCTION", "file_tree", `Tree reduced: ${label}`, content),
11967
+ proofImpact: "PASS",
11968
+ reasonCodes: ["FILE_TREE_SUMMARIZED", "GENERATED_DIRS_COLLAPSED"],
11969
+ blockedContent: false
11970
+ };
11971
+ }
11972
+
11973
+ // src/avorelo/kernel/context-control/reducers/test-output.ts
11974
+ var FAIL_PATTERNS = [
11975
+ /\b(?:FAIL|FAILED|FAILURE)\b/i,
11976
+ /✗|✘|×|❌/,
11977
+ /\bnot ok\b/i,
11978
+ /AssertionError/i,
11979
+ /\bExpected\b.*\bReceived\b/i,
11980
+ /\bexpected\b.*\bto (?:equal|be|match|include|have)\b/i,
11981
+ /Error:\s/,
11982
+ /\bat\s+\S+\s+\(/
11983
+ ];
11984
+ var PASS_PATTERNS = [
11985
+ /\b(?:PASS|PASSED|OK)\b/i,
11986
+ /✓|✔|✅/,
11987
+ /\bok\b/i
11988
+ ];
11989
+ var SUMMARY_PATTERNS = [
11990
+ /Tests?:\s*\d+/i,
11991
+ /Suites?:\s*\d+/i,
11992
+ /\d+\s+(?:passing|failing|pending|skipped)/i,
11993
+ /Test Files\s/i,
11994
+ /Duration[:\s]/i,
11995
+ /Time:\s/i,
11996
+ /Ran all test suites/i
11997
+ ];
11998
+ var COMMAND_PATTERNS2 = [
11999
+ /^\$\s+/,
12000
+ /^>\s+/,
12001
+ /^Running\s+/i,
12002
+ /^Executing\s+/i,
12003
+ /^npm\s+(?:run|test)/i,
12004
+ /^node\s+/,
12005
+ /^npx\s+/
12006
+ ];
12007
+ function reduceTestOutput(content, label) {
12008
+ const tokensBefore = estimateTokens(content);
12009
+ const lines = content.split("\n");
12010
+ if (lines.length <= 80) {
12011
+ return {
12012
+ reduced: content,
12013
+ estimatedTokensBefore: tokensBefore,
12014
+ estimatedTokensAfter: tokensBefore,
12015
+ evidenceRef: createEvidenceRef("TEST_OUTPUT_REDUCTION", "test_output", `Test output: ${label}`, content),
12016
+ proofImpact: "PASS",
12017
+ reasonCodes: ["SHORT_TEST_OUTPUT_KEPT"],
12018
+ blockedContent: false
12019
+ };
12020
+ }
12021
+ const failingLines = [];
12022
+ const summaryLines = [];
12023
+ const commandLines = [];
12024
+ let passingCount = 0;
12025
+ let failingCount = 0;
12026
+ let inFailBlock = false;
12027
+ let failBlockLines = 0;
12028
+ for (let i = 0; i < lines.length; i++) {
12029
+ const line = lines[i];
12030
+ if (COMMAND_PATTERNS2.some((p) => p.test(line))) {
12031
+ commandLines.push(line);
12032
+ continue;
12033
+ }
12034
+ if (SUMMARY_PATTERNS.some((p) => p.test(line))) {
12035
+ summaryLines.push(line);
12036
+ continue;
12037
+ }
12038
+ if (FAIL_PATTERNS.some((p) => p.test(line))) {
12039
+ inFailBlock = true;
12040
+ failBlockLines = 0;
12041
+ failingCount++;
12042
+ failingLines.push(line);
12043
+ continue;
12044
+ }
12045
+ if (inFailBlock && failBlockLines < 15) {
12046
+ failBlockLines++;
12047
+ failingLines.push(line);
12048
+ if (line.trim() === "" || failBlockLines >= 15) {
12049
+ inFailBlock = false;
12050
+ }
12051
+ continue;
12052
+ }
12053
+ if (PASS_PATTERNS.some((p) => p.test(line))) {
12054
+ passingCount++;
12055
+ inFailBlock = false;
12056
+ continue;
12057
+ }
12058
+ inFailBlock = false;
12059
+ }
12060
+ const parts = [
12061
+ `--- Test Output Summary: ${label} ---`
12062
+ ];
12063
+ if (commandLines.length > 0) {
12064
+ parts.push("Command: " + commandLines[0]);
12065
+ }
12066
+ parts.push(`Passing: ${passingCount} | Failing: ${failingCount}`);
12067
+ if (failingLines.length > 0) {
12068
+ parts.push("", "--- Failing Tests ---");
12069
+ parts.push(...failingLines.slice(0, 200));
12070
+ }
12071
+ if (summaryLines.length > 0) {
12072
+ parts.push("", "--- Summary ---");
12073
+ parts.push(...summaryLines);
12074
+ }
12075
+ if (failingCount === 0 && passingCount > 0) {
12076
+ parts.push("", "All tests passing.");
12077
+ }
12078
+ const reduced = parts.join("\n");
12079
+ const proofImpact = failingCount > 0 && failingLines.length > 0 ? "PASS" : failingCount > 0 ? "DEGRADED" : "PASS";
12080
+ return {
12081
+ reduced,
12082
+ estimatedTokensBefore: tokensBefore,
12083
+ estimatedTokensAfter: estimateTokens(reduced),
12084
+ evidenceRef: createEvidenceRef("TEST_OUTPUT_REDUCTION", "test_output", `Tests reduced: ${label}`, content),
12085
+ proofImpact,
12086
+ reasonCodes: [
12087
+ "TEST_OUTPUT_REDUCED",
12088
+ ...failingCount > 0 ? ["FAILING_TESTS_PRESERVED"] : ["ALL_TESTS_PASSING"],
12089
+ ...passingCount > 10 ? ["PASSING_TESTS_SUMMARIZED"] : []
12090
+ ],
12091
+ blockedContent: false
12092
+ };
12093
+ }
12094
+
12095
+ // src/avorelo/kernel/context-control/reducers/diff-summary.ts
12096
+ var GENERATED_FILE_PATTERNS = [
12097
+ /package-lock\.json$/,
12098
+ /yarn\.lock$/,
12099
+ /pnpm-lock\.yaml$/,
12100
+ /\.min\.\w+$/,
12101
+ /\.map$/,
12102
+ /dist\//,
12103
+ /build\//,
12104
+ /\.generated\./,
12105
+ /node_modules\//
12106
+ ];
12107
+ function isGeneratedFile(path) {
12108
+ return GENERATED_FILE_PATTERNS.some((p) => p.test(path));
12109
+ }
12110
+ function reduceDiffSummary(content, label) {
12111
+ const tokensBefore = estimateTokens(content);
12112
+ const lines = content.split("\n");
12113
+ const fileChanges = [];
12114
+ let totalInsertions = 0;
12115
+ let totalDeletions = 0;
12116
+ let currentFile = null;
12117
+ let currentInsertions = 0;
12118
+ let currentDeletions = 0;
12119
+ for (const line of lines) {
12120
+ const diffGit = line.match(/^diff --git a\/(.+?) b\//);
12121
+ if (diffGit) {
12122
+ if (currentFile) {
12123
+ fileChanges.push({
12124
+ path: currentFile,
12125
+ insertions: currentInsertions,
12126
+ deletions: currentDeletions,
12127
+ isGenerated: isGeneratedFile(currentFile)
12128
+ });
12129
+ totalInsertions += currentInsertions;
12130
+ totalDeletions += currentDeletions;
12131
+ }
12132
+ currentFile = diffGit[1];
12133
+ currentInsertions = 0;
12134
+ currentDeletions = 0;
12135
+ continue;
12136
+ }
12137
+ if (line.startsWith("+") && !line.startsWith("+++")) currentInsertions++;
12138
+ if (line.startsWith("-") && !line.startsWith("---")) currentDeletions++;
12139
+ }
12140
+ if (currentFile) {
12141
+ fileChanges.push({
12142
+ path: currentFile,
12143
+ insertions: currentInsertions,
12144
+ deletions: currentDeletions,
12145
+ isGenerated: isGeneratedFile(currentFile)
12146
+ });
12147
+ totalInsertions += currentInsertions;
12148
+ totalDeletions += currentDeletions;
12149
+ }
12150
+ if (fileChanges.length === 0) {
12151
+ const statLine = lines.find((l) => /\d+ files? changed/.test(l));
12152
+ if (statLine) {
12153
+ return {
12154
+ reduced: `--- Diff Summary: ${label} ---
12155
+ ${statLine}`,
12156
+ estimatedTokensBefore: tokensBefore,
12157
+ estimatedTokensAfter: estimateTokens(statLine),
12158
+ evidenceRef: createEvidenceRef("DIFF_SUMMARY", "diff", `Diff stats: ${label}`, content),
12159
+ proofImpact: "PASS",
12160
+ reasonCodes: ["DIFF_STAT_ONLY"],
12161
+ blockedContent: false
12162
+ };
12163
+ }
12164
+ return {
12165
+ reduced: `--- Diff Summary: ${label} ---
12166
+ No parseable diff content.`,
12167
+ estimatedTokensBefore: tokensBefore,
12168
+ estimatedTokensAfter: 10,
12169
+ evidenceRef: createEvidenceRef("DIFF_SUMMARY", "diff", `Diff empty: ${label}`, content),
12170
+ proofImpact: "UNKNOWN",
12171
+ reasonCodes: ["DIFF_NOT_PARSEABLE"],
12172
+ blockedContent: false
12173
+ };
12174
+ }
12175
+ const sourceFiles = fileChanges.filter((f) => !f.isGenerated);
12176
+ const generatedFiles = fileChanges.filter((f) => f.isGenerated);
12177
+ const riskMarkers = [];
12178
+ for (const f of sourceFiles) {
12179
+ if (/(?:auth|security|secret|credential|password|token)/i.test(f.path)) riskMarkers.push(`SECURITY_RELATED: ${f.path}`);
12180
+ if (/(?:migration|schema|database)/i.test(f.path)) riskMarkers.push(`MIGRATION: ${f.path}`);
12181
+ if (/(?:deploy|prod|release|ci|cd)/i.test(f.path)) riskMarkers.push(`DEPLOYMENT: ${f.path}`);
12182
+ }
12183
+ const parts = [
12184
+ `--- Diff Summary: ${label} ---`,
12185
+ `Files changed: ${fileChanges.length} (${sourceFiles.length} source, ${generatedFiles.length} generated)`,
12186
+ `Insertions: +${totalInsertions} | Deletions: -${totalDeletions}`
12187
+ ];
12188
+ if (riskMarkers.length > 0) {
12189
+ parts.push("", "Risk markers:", ...riskMarkers.map((r2) => ` \u26A0 ${r2}`));
12190
+ }
12191
+ parts.push("", "Source files:");
12192
+ for (const f of sourceFiles) {
12193
+ parts.push(` ${f.path} (+${f.insertions}/-${f.deletions})`);
12194
+ }
12195
+ if (generatedFiles.length > 0) {
12196
+ parts.push("", `Generated files: ${generatedFiles.length} (${generatedFiles.map((f) => f.path).join(", ")})`);
12197
+ }
12198
+ const reduced = parts.join("\n");
12199
+ return {
12200
+ reduced,
12201
+ estimatedTokensBefore: tokensBefore,
12202
+ estimatedTokensAfter: estimateTokens(reduced),
12203
+ evidenceRef: createEvidenceRef("DIFF_SUMMARY", "diff", `Diff summarized: ${label}`, content),
12204
+ proofImpact: "PASS",
12205
+ reasonCodes: ["DIFF_STATS_PRESERVED", "RAW_DIFF_NOT_PERSISTED", ...riskMarkers.length > 0 ? ["RISK_MARKERS_DETECTED"] : []],
12206
+ blockedContent: false
12207
+ };
12208
+ }
12209
+
12210
+ // src/avorelo/kernel/context-control/reducers/conversation.ts
12211
+ var OBJECTIVE_PATTERNS = [
12212
+ /\b(?:objective|goal|task|mission|purpose)\s*[:]/i,
12213
+ /\b(?:we need to|I need to|please|implement|fix|add|create|build|update|change|remove|refactor)\b/i
12214
+ ];
12215
+ var CONSTRAINT_PATTERNS = [
12216
+ /\b(?:must not|do not|don't|never|avoid|forbidden|required|constraint|boundary|limit)\b/i,
12217
+ /\b(?:before|after|unless|only if|except)\b/i
12218
+ ];
12219
+ var DECISION_PATTERNS = [
12220
+ /\b(?:decided|decision|chose|chosen|agreed|confirmed|approved|rejected|accepted)\b/i,
12221
+ /\b(?:we'll|we will|let's|approach|strategy|plan is)\b/i
12222
+ ];
12223
+ var UNRESOLVED_PATTERNS = [
12224
+ /\b(?:TODO|FIXME|HACK|QUESTION|TBD|unclear|not sure|need to figure|open question)\b/i,
12225
+ /\?\s*$/
12226
+ ];
12227
+ var STATUS_PATTERNS = [
12228
+ /\b(?:verified|tested|confirmed|working|broken|failing|passed|deployed|merged)\b/i,
12229
+ /\b(?:status|result|outcome|state)\s*[:]/i
12230
+ ];
12231
+ var NOISE_PATTERNS = [
12232
+ /^(?:okay|ok|sure|yes|no|thanks|thank you|got it|understood|right|exactly|perfect)[\.\!\s]*$/i,
12233
+ /^(?:let me|I'll|I will)\s+(?:check|look|see|read|examine)/i,
12234
+ /^(?:here's|here is)\s+(?:the|what)/i,
12235
+ /^(?:great|good|nice|excellent|awesome)/i
12236
+ ];
12237
+ function isNoise(line) {
12238
+ const trimmed = line.trim();
12239
+ if (!trimmed) return true;
12240
+ return NOISE_PATTERNS.some((p) => p.test(trimmed));
12241
+ }
12242
+ function matchesAny(line, patterns) {
12243
+ return patterns.some((p) => p.test(line));
12244
+ }
12245
+ function reduceConversation(content, label) {
12246
+ const tokensBefore = estimateTokens(content);
12247
+ const lines = content.split("\n");
12248
+ if (lines.length <= 60) {
12249
+ return {
12250
+ reduced: content,
12251
+ estimatedTokensBefore: tokensBefore,
12252
+ estimatedTokensAfter: tokensBefore,
12253
+ evidenceRef: createEvidenceRef("CONVERSATION_STATE_SUMMARY", "conversation_history", `Conversation: ${label}`, content),
12254
+ proofImpact: "PASS",
12255
+ reasonCodes: ["SHORT_CONVERSATION_KEPT"],
12256
+ blockedContent: false
12257
+ };
12258
+ }
12259
+ const objectives = [];
12260
+ const constraints = [];
12261
+ const decisions = [];
12262
+ const unresolved = [];
12263
+ const statusUpdates = [];
12264
+ let noiseRemoved = 0;
12265
+ for (const line of lines) {
12266
+ const trimmed = line.trim();
12267
+ if (!trimmed) continue;
12268
+ if (isNoise(trimmed)) {
12269
+ noiseRemoved++;
12270
+ continue;
12271
+ }
12272
+ if (matchesAny(trimmed, OBJECTIVE_PATTERNS)) objectives.push(trimmed);
12273
+ else if (matchesAny(trimmed, CONSTRAINT_PATTERNS)) constraints.push(trimmed);
12274
+ else if (matchesAny(trimmed, DECISION_PATTERNS)) decisions.push(trimmed);
12275
+ else if (matchesAny(trimmed, UNRESOLVED_PATTERNS)) unresolved.push(trimmed);
12276
+ else if (matchesAny(trimmed, STATUS_PATTERNS)) statusUpdates.push(trimmed);
12277
+ }
12278
+ const parts = [`--- Conversation Summary: ${label} ---`];
12279
+ if (objectives.length > 0) {
12280
+ parts.push("", "Objectives:", ...objectives.slice(0, 10).map((o) => ` - ${o.slice(0, 200)}`));
12281
+ }
12282
+ if (constraints.length > 0) {
12283
+ parts.push("", "Constraints:", ...constraints.slice(0, 10).map((c) => ` - ${c.slice(0, 200)}`));
12284
+ }
12285
+ if (decisions.length > 0) {
12286
+ parts.push("", "Decisions:", ...decisions.slice(0, 10).map((d) => ` - ${d.slice(0, 200)}`));
12287
+ }
12288
+ if (unresolved.length > 0) {
12289
+ parts.push("", "Unresolved:", ...unresolved.slice(0, 10).map((u) => ` - ${u.slice(0, 200)}`));
12290
+ }
12291
+ if (statusUpdates.length > 0) {
12292
+ parts.push("", "Latest status:", ...statusUpdates.slice(-5).map((s) => ` - ${s.slice(0, 200)}`));
12293
+ }
12294
+ parts.push("", `Noise removed: ${noiseRemoved} lines`);
12295
+ const reduced = parts.join("\n");
12296
+ return {
12297
+ reduced,
12298
+ estimatedTokensBefore: tokensBefore,
12299
+ estimatedTokensAfter: estimateTokens(reduced),
12300
+ evidenceRef: createEvidenceRef("CONVERSATION_STATE_SUMMARY", "conversation_history", `Conversation reduced: ${label}`, content),
12301
+ proofImpact: objectives.length > 0 || decisions.length > 0 ? "PASS" : "DEGRADED",
12302
+ reasonCodes: [
12303
+ "CONVERSATION_SUMMARIZED",
12304
+ ...noiseRemoved > 0 ? ["NOISE_REMOVED"] : [],
12305
+ ...objectives.length > 0 ? ["OBJECTIVES_PRESERVED"] : [],
12306
+ ...decisions.length > 0 ? ["DECISIONS_PRESERVED"] : [],
12307
+ ...unresolved.length > 0 ? ["UNRESOLVED_FLAGGED"] : []
12308
+ ],
12309
+ blockedContent: false
12310
+ };
12311
+ }
12312
+
12313
+ // src/avorelo/kernel/context-control/cache-align.ts
12314
+ function analyzeCacheAlignment(items) {
12315
+ let stableCount = 0;
12316
+ let semiStableCount = 0;
12317
+ let volatileCount = 0;
12318
+ const invalidationReasons = [];
12319
+ for (const item2 of items) {
12320
+ const contentType = classifyContentType(item2.content, item2.label);
12321
+ const volatility = classifyVolatility(contentType);
12322
+ switch (volatility) {
12323
+ case "stable":
12324
+ stableCount++;
12325
+ break;
12326
+ case "semi_stable":
12327
+ semiStableCount++;
12328
+ break;
12329
+ case "volatile":
12330
+ volatileCount++;
12331
+ break;
12332
+ }
12333
+ }
12334
+ const totalItems = items.length;
12335
+ const cacheBreakRisk = totalItems > 0 && volatileCount > stableCount;
12336
+ if (stableCount === 0 && totalItems > 0) {
12337
+ invalidationReasons.push("NO_STABLE_CONTEXT_BLOCKS");
12338
+ }
12339
+ if (volatileCount > stableCount * 2) {
12340
+ invalidationReasons.push("VOLATILE_DOMINATES_STABLE");
12341
+ }
12342
+ if (totalItems > 20) {
12343
+ invalidationReasons.push("HIGH_ITEM_COUNT_MAY_FRAGMENT_CACHE");
12344
+ }
12345
+ const layout = [];
12346
+ if (stableCount > 0) layout.push("1. System/product contract (stable)");
12347
+ if (stableCount > 0) layout.push("2. Project facts & conventions (stable)");
12348
+ if (semiStableCount > 0) layout.push("3. Repo map & dependencies (semi-stable)");
12349
+ if (volatileCount > 0) layout.push("4. Current task & tool output (volatile)");
12350
+ return {
12351
+ stableBlockCount: stableCount,
12352
+ semiStableBlockCount: semiStableCount,
12353
+ volatileBlockCount: volatileCount,
12354
+ cacheStablePrefixAvailable: stableCount > 0,
12355
+ cacheBreakRisk,
12356
+ cacheInvalidationReasons: invalidationReasons,
12357
+ suggestedPromptLayout: layout
12358
+ };
12359
+ }
12360
+
12361
+ // src/avorelo/kernel/context-control/diagnostics.ts
12362
+ function generateDiagnostics(result3) {
12363
+ const diagnostics = [];
12364
+ if (result3.blockedItemsCount > 0) {
12365
+ diagnostics.push({
12366
+ severity: "warning",
12367
+ code: "CONTEXT_ITEMS_BLOCKED",
12368
+ message: `${result3.blockedItemsCount} context item(s) were blocked due to forbidden or secret-like content.`,
12369
+ remediation: "Review blocked items and redact sensitive content before including in context.",
12370
+ safeForReceipt: true
12371
+ });
12372
+ }
12373
+ if (result3.proofImpact === "DEGRADED") {
12374
+ diagnostics.push({
12375
+ severity: "warning",
12376
+ code: "PROOF_IMPACT_DEGRADED",
12377
+ message: "Context compression may have removed proof-critical evidence.",
12378
+ remediation: "Rerun with evidence retrieval or use manual review to verify proof chain.",
12379
+ safeForReceipt: true
12380
+ });
12381
+ }
12382
+ if (result3.proofImpact === "UNKNOWN") {
12383
+ diagnostics.push({
12384
+ severity: "blocker",
12385
+ code: "PROOF_IMPACT_UNKNOWN",
12386
+ message: "Unable to determine proof impact of context compression.",
12387
+ remediation: "Review original context to determine if proof-critical evidence was affected.",
12388
+ safeForReceipt: true
12389
+ });
12390
+ }
12391
+ if (result3.compressionRatio > 0.95) {
12392
+ diagnostics.push({
12393
+ severity: "info",
12394
+ code: "HIGH_COMPRESSION_RATIO",
12395
+ message: `Context was compressed by ${Math.round(result3.compressionRatio * 100)}%. Verify that important context was preserved.`,
12396
+ remediation: "Check evidence refs to confirm key information is retrievable.",
12397
+ safeForReceipt: true
12398
+ });
12399
+ }
12400
+ if (result3.cacheAlignment.cacheBreakRisk) {
12401
+ diagnostics.push({
12402
+ severity: "info",
12403
+ code: "CACHE_BREAK_RISK",
12404
+ message: "Volatile context blocks outnumber stable blocks, reducing cache effectiveness.",
12405
+ remediation: "Move stable project context (system prompt, conventions) to the front of the prompt.",
12406
+ safeForReceipt: true
12407
+ });
12408
+ }
12409
+ if (!result3.cacheAlignment.cacheStablePrefixAvailable) {
12410
+ diagnostics.push({
12411
+ severity: "info",
12412
+ code: "NO_STABLE_PREFIX",
12413
+ message: "No stable context prefix detected. Provider prompt caching will be less effective.",
12414
+ remediation: "Add stable system/project context blocks at the beginning of the prompt.",
12415
+ safeForReceipt: true
12416
+ });
12417
+ }
12418
+ if (result3.estimatedInputTokensBefore > 1e5) {
12419
+ diagnostics.push({
12420
+ severity: "warning",
12421
+ code: "VERY_LARGE_CONTEXT",
12422
+ message: `Input context estimated at ${result3.estimatedInputTokensBefore.toLocaleString()} tokens before reduction.`,
12423
+ remediation: "Consider narrowing task scope or excluding unnecessary context sources.",
12424
+ safeForReceipt: true
12425
+ });
12426
+ }
12427
+ if (result3.evidenceRefs.length === 0 && result3.estimatedInputTokensBefore > result3.estimatedInputTokensAfter) {
12428
+ diagnostics.push({
12429
+ severity: "warning",
12430
+ code: "COMPRESSION_WITHOUT_EVIDENCE",
12431
+ message: "Context was compressed but no evidence refs were created for recovery.",
12432
+ remediation: "Ensure reducers create evidence refs for recoverable content.",
12433
+ safeForReceipt: true
12434
+ });
12435
+ }
12436
+ return diagnostics;
12437
+ }
12438
+ function buildReceiptSummary(result3) {
12439
+ const reductionPercent = result3.estimatedInputTokensBefore > 0 ? Math.round((result3.estimatedInputTokensBefore - result3.estimatedInputTokensAfter) / result3.estimatedInputTokensBefore * 100) : 0;
12440
+ let status;
12441
+ if (result3.decision === "BLOCK_FORBIDDEN_CONTEXT") {
12442
+ status = "BLOCKED";
12443
+ } else if (result3.proofImpact === "DEGRADED" || result3.proofImpact === "UNKNOWN") {
12444
+ status = "DEGRADED";
12445
+ } else if (result3.decision === "ALLOW_AS_IS" && result3.estimatedInputTokensBefore === result3.estimatedInputTokensAfter) {
12446
+ status = "INACTIVE";
12447
+ } else {
12448
+ status = "ACTIVE";
12449
+ }
12450
+ const summaryParts = [];
12451
+ if (status === "ACTIVE") {
12452
+ summaryParts.push(`Context reduced from ~${result3.estimatedInputTokensBefore.toLocaleString()} to ~${result3.estimatedInputTokensAfter.toLocaleString()} tokens (${reductionPercent}% reduction).`);
12453
+ } else if (status === "BLOCKED") {
12454
+ summaryParts.push("Context blocked due to forbidden content.");
12455
+ } else if (status === "DEGRADED") {
12456
+ summaryParts.push("Context compressed but proof chain may be weakened.");
12457
+ } else {
12458
+ summaryParts.push("Context passed through without reduction.");
12459
+ }
12460
+ if (result3.evidenceRefs.length > 0) {
12461
+ summaryParts.push(`${result3.evidenceRefs.length} evidence ref(s) available for retrieval.`);
12462
+ }
12463
+ return {
12464
+ contextControlStatus: status,
12465
+ estimatedContextBefore: result3.estimatedInputTokensBefore,
12466
+ estimatedContextSent: result3.estimatedInputTokensAfter,
12467
+ reductionPercent,
12468
+ evidenceRefCount: result3.evidenceRefs.length,
12469
+ blockedItemsCount: result3.blockedItemsCount,
12470
+ retrievalAvailable: result3.evidenceRefs.some((r2) => r2.retrievalPolicy === "available"),
12471
+ proofImpact: result3.proofImpact,
12472
+ topReasonCodes: result3.reasonCodes.slice(0, 5),
12473
+ summary: summaryParts.join(" ")
12474
+ };
12475
+ }
12476
+ function renderContextStats(summary) {
12477
+ const lines = [
12478
+ `Context Control: ${summary.contextControlStatus}`,
12479
+ `Estimated context before: ${summary.estimatedContextBefore.toLocaleString()} tokens`,
12480
+ `Estimated context sent: ${summary.estimatedContextSent.toLocaleString()} tokens`,
12481
+ `Reduction: ${summary.reductionPercent}%`,
12482
+ `Evidence refs: ${summary.evidenceRefCount}`,
12483
+ `Blocked items: ${summary.blockedItemsCount}`,
12484
+ `Retrieval available: ${summary.retrievalAvailable ? "yes" : "no"}`,
12485
+ `Proof impact: ${summary.proofImpact}`
12486
+ ];
12487
+ if (summary.topReasonCodes.length > 0) {
12488
+ lines.push(`Top reasons: ${summary.topReasonCodes.join(", ")}`);
12489
+ }
12490
+ return lines.join("\n");
12491
+ }
12492
+ function renderContextExplain(summary, diagnostics) {
12493
+ const parts = [
12494
+ renderContextStats(summary),
12495
+ "",
12496
+ "--- Explanation ---",
12497
+ summary.summary
12498
+ ];
12499
+ if (diagnostics.length > 0) {
12500
+ parts.push("", "--- Diagnostics ---");
12501
+ for (const d of diagnostics) {
12502
+ parts.push(`[${d.severity.toUpperCase()}] ${d.code}: ${d.message}`);
12503
+ parts.push(` Action: ${d.remediation}`);
12504
+ }
12505
+ }
12506
+ return parts.join("\n");
12507
+ }
12508
+
12509
+ // src/avorelo/kernel/context-control/learn.ts
12510
+ var KNOWN_FAILURE_MAPPINGS = [
12511
+ {
12512
+ pattern: /npm publish.*(?:OTP|auth|ENEEDAUTH)/i,
12513
+ candidateType: "WORKFLOW_CORRECTION",
12514
+ template: () => "When npm publish or dist-tag promotion requires auth/OTP, generate a local PowerShell script for the owner to run. Do not ask for OTP in chat.",
12515
+ target: "CLAUDE.md"
12516
+ },
12517
+ {
12518
+ pattern: /(?:EACCES|permission denied|EPERM)/i,
12519
+ candidateType: "TOOL_LIMITATION",
12520
+ template: (match) => `Permission error encountered: ${match.slice(0, 100)}. Consider running with elevated permissions or checking file ownership.`,
12521
+ target: "AGENTS.md"
12522
+ },
12523
+ {
12524
+ pattern: /(?:ENOSPC|disk full|no space)/i,
12525
+ candidateType: "TOOL_LIMITATION",
12526
+ template: () => "Disk space constraints detected. Clean build artifacts before large operations.",
12527
+ target: "AGENTS.md"
12528
+ },
12529
+ {
12530
+ pattern: /(?:timeout|ETIMEDOUT|ESOCKETTIMEDOUT)/i,
12531
+ candidateType: "WORKFLOW_CORRECTION",
12532
+ template: () => "Network timeouts are common in this environment. Use local-first approaches where possible.",
12533
+ target: "CLAUDE.md"
12534
+ },
12535
+ {
12536
+ pattern: /node_modules.*(?:large|huge|big|slow)/i,
12537
+ candidateType: "NOISE_PATTERN",
12538
+ template: () => "node_modules content should be excluded from context. Use package.json and lock file summaries instead.",
12539
+ target: "CLAUDE.md"
12540
+ }
12541
+ ];
12542
+ function isSafeCandidate(text) {
12543
+ const lower = text.toLowerCase();
12544
+ if (/(?:api[_-]?key|secret|token|password)\s*[:=]\s*\S{10,}/i.test(text)) return false;
12545
+ if (/-----BEGIN.*KEY-----/.test(text)) return false;
12546
+ if (/(?:ignore all|disregard|you are now|act as|pretend)/i.test(lower)) return false;
12547
+ return true;
12548
+ }
12549
+ function generateLearningCandidates(input) {
12550
+ const candidates = [];
12551
+ if (input.failurePatterns) {
12552
+ for (const failure of input.failurePatterns) {
12553
+ if (failure.occurrences < 2) continue;
12554
+ for (const mapping of KNOWN_FAILURE_MAPPINGS) {
12555
+ if (mapping.pattern.test(failure.pattern)) {
12556
+ const proposedText = mapping.template(failure.pattern);
12557
+ if (!isSafeCandidate(proposedText)) continue;
12558
+ candidates.push({
12559
+ candidateType: mapping.candidateType,
12560
+ sourceReceiptIds: failure.receiptIds.slice(0, 5),
12561
+ evidenceRefs: failure.evidenceRefs.slice(0, 5),
12562
+ confidence: failure.occurrences >= 5 ? "high" : failure.occurrences >= 3 ? "medium" : "low",
12563
+ proposedText,
12564
+ suggestedWriteTarget: mapping.target,
12565
+ requiresApproval: true,
12566
+ safeForPersistence: true,
12567
+ reasonCodes: [`REPEATED_FAILURE_${failure.occurrences}x`, `PATTERN_MATCH_${mapping.candidateType}`]
12568
+ });
12569
+ break;
12570
+ }
12571
+ }
12572
+ }
12573
+ }
12574
+ const receiptReasonCounts = /* @__PURE__ */ new Map();
12575
+ for (const receipt of input.receipts) {
12576
+ for (const code of receipt.topReasonCodes) {
12577
+ receiptReasonCounts.set(code, (receiptReasonCounts.get(code) || 0) + 1);
12578
+ }
12579
+ }
12580
+ for (const [code, count] of receiptReasonCounts) {
12581
+ if (count >= 3 && code.includes("BLOCKED")) {
12582
+ candidates.push({
12583
+ candidateType: "SAFETY_RULE",
12584
+ sourceReceiptIds: [],
12585
+ evidenceRefs: [],
12586
+ confidence: "medium",
12587
+ proposedText: `Frequently blocked context pattern: ${code}. Review whether this pattern should be allowlisted or permanently blocked.`,
12588
+ suggestedWriteTarget: "CLAUDE.md",
12589
+ requiresApproval: true,
12590
+ safeForPersistence: true,
12591
+ reasonCodes: [`FREQUENT_BLOCK_${count}x`, code]
12592
+ });
12593
+ }
12594
+ }
12595
+ return {
12596
+ candidates,
12597
+ dryRun: true,
12598
+ filesWritten: 0,
12599
+ summary: candidates.length > 0 ? `Generated ${candidates.length} learning candidate(s). All require explicit approval before writing.` : "No learning candidates generated from current evidence."
12600
+ };
12601
+ }
12602
+
12603
+ // src/avorelo/kernel/context-control/index.ts
12604
+ function selectReducer(item2) {
12605
+ const classification = item2.classification ?? classifyItem(item2);
12606
+ switch (classification.contentType) {
12607
+ case "log":
12608
+ return reduceLogs;
12609
+ case "json_tool_output":
12610
+ return reduceJson;
12611
+ case "file_tree":
12612
+ return reduceFileTree;
12613
+ case "test_output":
12614
+ return reduceTestOutput;
12615
+ case "diff":
12616
+ return reduceDiffSummary;
12617
+ case "conversation_history":
12618
+ return reduceConversation;
12619
+ default:
12620
+ return null;
12621
+ }
12622
+ }
12623
+ function isForbidden(item2, input) {
12624
+ if (containsForbiddenContent(item2.content)) return true;
12625
+ if (input.forbiddenContext) {
12626
+ for (const pattern of input.forbiddenContext) {
12627
+ if (item2.label.includes(pattern) || item2.content.includes(pattern)) return true;
12628
+ }
12629
+ }
12630
+ return false;
12631
+ }
12632
+ function isAllowed(item2, input) {
12633
+ if (!input.allowedContext || input.allowedContext.length === 0) return true;
12634
+ return input.allowedContext.some((a) => item2.label.includes(a) || item2.content.includes(a));
12635
+ }
12636
+ function needsManualApproval(item2, input) {
12637
+ if (input.riskLevel === "critical") return true;
12638
+ const classification = item2.classification ?? classifyItem(item2);
12639
+ if (classification.sensitivity === "secret_like" && input.redactionPolicy === "strict") return true;
12640
+ return false;
12641
+ }
12642
+ function processContextControl(input) {
12643
+ const classifiedItems = input.items.map((item2) => ({
12644
+ ...item2,
12645
+ classification: item2.classification ?? classifyItem(item2)
12646
+ }));
12647
+ const totalTokensBefore = classifiedItems.reduce((sum, item2) => sum + item2.classification.estimatedTokens, 0);
12648
+ const reducedParts = [];
12649
+ const evidenceRefs = [];
12650
+ const reasonCodes = [];
12651
+ const learningSignals = [];
12652
+ let blockedCount = 0;
12653
+ let overallProofImpact = "PASS";
12654
+ let overallDecision = "ALLOW_AS_IS";
12655
+ let overallReductionKind = "NONE";
12656
+ let anyReduced = false;
12657
+ let anyBlocked = false;
12658
+ for (const item2 of classifiedItems) {
12659
+ if (isForbidden(item2, input)) {
12660
+ blockedCount++;
12661
+ anyBlocked = true;
12662
+ evidenceRefs.push(createBlockedEvidenceRef(item2.classification.contentType, `Forbidden: ${item2.label}`));
12663
+ reasonCodes.push("FORBIDDEN_CONTEXT_BLOCKED");
12664
+ continue;
12665
+ }
12666
+ if (!isAllowed(item2, input)) {
12667
+ blockedCount++;
12668
+ evidenceRefs.push(createBlockedEvidenceRef(item2.classification.contentType, `Not in allowlist: ${item2.label}`));
12669
+ reasonCodes.push("CONTEXT_NOT_IN_ALLOWLIST");
12670
+ continue;
12671
+ }
12672
+ if (needsManualApproval(item2, input)) {
12673
+ blockedCount++;
12674
+ evidenceRefs.push(createBlockedEvidenceRef(item2.classification.contentType, `Requires approval: ${item2.label}`));
12675
+ reasonCodes.push("MANUAL_APPROVAL_REQUIRED");
12676
+ continue;
12677
+ }
12678
+ if (containsSecrets(item2.content)) {
12679
+ blockedCount++;
12680
+ anyBlocked = true;
12681
+ evidenceRefs.push(createBlockedEvidenceRef(item2.classification.contentType, `Secret-like content: ${item2.label}`));
12682
+ reasonCodes.push("SECRET_LIKE_CONTEXT_BLOCKED");
12683
+ continue;
12684
+ }
12685
+ const reducer = selectReducer(item2);
12686
+ if (reducer && item2.classification.estimatedTokens > 200) {
12687
+ const result3 = reducer(item2.content, item2.label);
12688
+ reducedParts.push(result3.reduced);
12689
+ if (result3.evidenceRef) evidenceRefs.push(result3.evidenceRef);
12690
+ reasonCodes.push(...result3.reasonCodes);
12691
+ anyReduced = true;
12692
+ if (result3.proofImpact === "DEGRADED") overallProofImpact = "DEGRADED";
12693
+ if (result3.proofImpact === "UNKNOWN" && overallProofImpact !== "DEGRADED") overallProofImpact = "UNKNOWN";
12694
+ } else {
12695
+ reducedParts.push(item2.content);
12696
+ }
12697
+ }
12698
+ const reducedContent = reducedParts.join("\n\n");
12699
+ const totalTokensAfter = estimateTokens(reducedContent);
12700
+ if (anyBlocked && blockedCount === classifiedItems.length) {
12701
+ overallDecision = "BLOCK_FORBIDDEN_CONTEXT";
12702
+ overallReductionKind = "BLOCKED";
12703
+ } else if (anyBlocked) {
12704
+ overallDecision = "COMPRESS_WITH_EVIDENCE";
12705
+ overallReductionKind = "BLOCKED";
12706
+ } else if (anyReduced) {
12707
+ overallDecision = "COMPRESS_WITH_EVIDENCE";
12708
+ const dominantType = classifiedItems.filter((i) => !isForbidden(i, input)).sort((a, b) => b.classification.estimatedTokens - a.classification.estimatedTokens)[0];
12709
+ if (dominantType) {
12710
+ const typeToKind = {
12711
+ log: "LOG_REDUCTION",
12712
+ json_tool_output: "JSON_REDUCTION",
12713
+ file_tree: "FILE_TREE_REDUCTION",
12714
+ test_output: "TEST_OUTPUT_REDUCTION",
12715
+ diff: "DIFF_SUMMARY",
12716
+ conversation_history: "CONVERSATION_STATE_SUMMARY"
12717
+ };
12718
+ overallReductionKind = typeToKind[dominantType.classification.contentType] ?? "NONE";
12719
+ }
12720
+ }
12721
+ if (totalTokensAfter > input.contextBudget) {
12722
+ reasonCodes.push("CONTEXT_EXCEEDS_BUDGET");
12723
+ if (overallDecision === "ALLOW_AS_IS") overallDecision = "ASK_FOR_NARROWER_SCOPE";
12724
+ }
12725
+ const compressionRatio = totalTokensBefore > 0 ? (totalTokensBefore - totalTokensAfter) / totalTokensBefore : 0;
12726
+ const deduplicatedReasonCodes = [...new Set(reasonCodes)];
12727
+ const cacheAlignment = analyzeCacheAlignment(classifiedItems);
12728
+ const partialResult = {
12729
+ decision: overallDecision,
12730
+ reductionKind: overallReductionKind,
12731
+ reasonCodes: deduplicatedReasonCodes,
12732
+ riskLevel: input.riskLevel ?? "low",
12733
+ safeForModel: !anyBlocked || blockedCount < classifiedItems.length,
12734
+ safeForPersistence: !deduplicatedReasonCodes.includes("SECRET_LIKE_CONTEXT_BLOCKED"),
12735
+ estimatedInputTokensBefore: totalTokensBefore,
12736
+ estimatedInputTokensAfter: totalTokensAfter,
12737
+ compressionRatio,
12738
+ evidenceRefs,
12739
+ blockedItemsCount: blockedCount,
12740
+ retrievalAvailable: evidenceRefs.some((r2) => r2.retrievalPolicy === "available"),
12741
+ proofImpact: overallProofImpact,
12742
+ receiptSafeSummary: null,
12743
+ diagnostics: [],
12744
+ cacheAlignment,
12745
+ learningSignals,
12746
+ reducedContent
12747
+ };
12748
+ partialResult.diagnostics = generateDiagnostics(partialResult);
12749
+ partialResult.receiptSafeSummary = buildReceiptSummary(partialResult);
12750
+ return partialResult;
12751
+ }
12752
+
11476
12753
  // src/avorelo/capabilities/runtime-flow/index.ts
11477
12754
  init_redaction();
11478
12755
  function runtimeDir(dir) {
@@ -11510,7 +12787,7 @@ function safeFallbackProjection(reasonCodes, extraVerifierPlan = []) {
11510
12787
  };
11511
12788
  }
11512
12789
  function freshRuntimeId(seed) {
11513
- return "rts_" + createHash12("sha256").update(seed).digest("hex").slice(0, 12);
12790
+ return "rts_" + createHash13("sha256").update(seed).digest("hex").slice(0, 12);
11514
12791
  }
11515
12792
  function coded(text) {
11516
12793
  try {
@@ -11860,6 +13137,54 @@ function runRuntimeSession(input) {
11860
13137
  } catch {
11861
13138
  base.contextPack = void 0;
11862
13139
  }
13140
+ try {
13141
+ if (compiledContextPacket) {
13142
+ const ccItems = compiledContextPacket.selectedRefs.map((ref2, i) => ({
13143
+ id: `cc_${i}`,
13144
+ label: ref2.label,
13145
+ content: `[${ref2.kind}] ${ref2.label} (${ref2.includeMode}/${ref2.safety})`
13146
+ }));
13147
+ const forbiddenLabels = compiledContextPacket.excludedRefs.map((r2) => r2.label);
13148
+ const budgetMap = { tiny: 4e3, small: 16e3, medium: 5e4, deep: 12e4 };
13149
+ const ccResult = processContextControl({
13150
+ consumerRole: "executor",
13151
+ items: ccItems,
13152
+ contextBudget: budgetMap[compiledContextPacket.contextBudget.targetSize] ?? 5e4,
13153
+ forbiddenContext: forbiddenLabels,
13154
+ redactionPolicy: "standard",
13155
+ riskLevel: c.riskClass === "critical" ? "critical" : c.riskClass
13156
+ });
13157
+ const summary = ccResult.receiptSafeSummary;
13158
+ const status = summary.controlStatus;
13159
+ const ref = (() => {
13160
+ try {
13161
+ const ccDir = join39(dir, ".avorelo", "context-control");
13162
+ mkdirSync24(ccDir, { recursive: true });
13163
+ const p = join39(ccDir, "latest.json");
13164
+ writeFileSync23(p, JSON.stringify(summary, null, 2));
13165
+ return p;
13166
+ } catch {
13167
+ return null;
13168
+ }
13169
+ })();
13170
+ const detail = `status=${status} context=${summary.estimatedContextBefore}\u2192${summary.estimatedContextSent} reduction=${summary.reductionPercent}%`;
13171
+ base.contextControl = {
13172
+ status,
13173
+ estimatedContextBefore: summary.estimatedContextBefore,
13174
+ estimatedContextAfter: summary.estimatedContextSent,
13175
+ reductionPercent: summary.reductionPercent,
13176
+ evidenceRefCount: summary.evidenceRefCount,
13177
+ blockedItemsCount: summary.blockedItemsCount,
13178
+ retrievalAvailable: summary.retrievalAvailable,
13179
+ proofImpact: summary.proofImpact,
13180
+ reasonCodes: summary.reasonCodes,
13181
+ ref
13182
+ };
13183
+ layers.push({ order: 3.5, layer: "context_control", capability: "context-control", status: "completed", ref, detail: coded(detail) });
13184
+ }
13185
+ } catch (e) {
13186
+ layers.push({ order: 3.5, layer: "context_control", capability: "context-control", status: "unavailable", ref: null, detail: coded(errCode(e)) });
13187
+ }
11863
13188
  if (plannedToolExecution) {
11864
13189
  const execCtx = {
11865
13190
  dir,
@@ -12402,6 +13727,18 @@ function buildControlCenter(dir, opts) {
12402
13727
  }
12403
13728
  } catch {
12404
13729
  }
13730
+ const contextControlSection = runtime?.contextControl ? {
13731
+ status: "available",
13732
+ controlStatus: runtime.contextControl.status,
13733
+ estimatedContextBefore: runtime.contextControl.estimatedContextBefore,
13734
+ estimatedContextAfter: runtime.contextControl.estimatedContextAfter,
13735
+ reductionPercent: runtime.contextControl.reductionPercent,
13736
+ evidenceRefCount: runtime.contextControl.evidenceRefCount,
13737
+ blockedItemsCount: runtime.contextControl.blockedItemsCount,
13738
+ retrievalAvailable: runtime.contextControl.retrievalAvailable,
13739
+ proofImpact: runtime.contextControl.proofImpact,
13740
+ reasonCodes: runtime.contextControl.reasonCodes
13741
+ } : { status: "unavailable" };
12405
13742
  const dash = buildLocalDashboard(dir, { now: opts.now, staleWindowMs: opts.staleWindowMs });
12406
13743
  const receiptsSection = {
12407
13744
  total: dash.totals.total,
@@ -12504,6 +13841,7 @@ function buildControlCenter(dir, opts) {
12504
13841
  continuity: continuitySection,
12505
13842
  efficiencySync: efficiencySection,
12506
13843
  contextCheck: contextCheckSection,
13844
+ contextControl: contextControlSection,
12507
13845
  receipts: receiptsSection,
12508
13846
  entitlementGate: entitlementGateSection,
12509
13847
  modelRouting: modelRoutingSection,
@@ -12543,6 +13881,7 @@ function renderText2(m) {
12543
13881
  lines.push(` Continuity:${s.continuity.status === "available" ? ` ${s.continuity.packetStatus} \xB7 ${s.continuity.safeNextActionCount} next action(s) \xB7 ${s.continuity.proofMissingCount} proof gap(s)` : " none"}`);
12544
13882
  lines.push(` Sync: ${s.efficiencySync.status === "available" ? `${s.efficiencySync.mode} \xB7 ${s.efficiencySync.eligibleCount} eligible / ${s.efficiencySync.blockedCount} blocked` : "none"}`);
12545
13883
  lines.push(` Context: ${s.contextCheck.status === "available" ? `${s.contextCheck.checkStatus} \xB7 risk=${s.contextCheck.riskLevel} \xB7 ${s.contextCheck.inputsChecked} source(s) \xB7 ${s.contextCheck.findingCount} finding(s) \xB7 policy=${s.contextCheck.policyPresent}` : "none"}`);
13884
+ lines.push(` Ctx ctrl: ${s.contextControl.status === "available" ? `${s.contextControl.controlStatus} \xB7 context=${s.contextControl.estimatedContextBefore}\u2192${s.contextControl.estimatedContextAfter} \xB7 reduction=${s.contextControl.reductionPercent}% \xB7 evidence=${s.contextControl.evidenceRefCount} \xB7 blocked=${s.contextControl.blockedItemsCount} \xB7 proof=${s.contextControl.proofImpact}` : "none"}`);
12546
13885
  lines.push(` Receipts: ${s.receipts.total} \xB7 done ${s.receipts.done} \xB7 blocked ${s.receipts.blocked} \xB7 needs-attention ${s.receipts.needsAttention} \xB7 stale ${s.receipts.stale}`);
12547
13886
  if (s.modelRouting.status === "available") {
12548
13887
  lines.push(` Routing: primitive=${s.modelRouting.selectedPrimitive} profile=${s.modelRouting.selectedModelProfile} resolver=${s.modelRouting.resolverStatus} provider=${s.modelRouting.providerClass}`);
@@ -12622,7 +13961,7 @@ function openControlCenter(dir, opts) {
12622
13961
  }
12623
13962
 
12624
13963
  // src/avorelo/capabilities/activation/init.ts
12625
- import { createHash as createHash13, randomUUID as randomUUID4 } from "node:crypto";
13964
+ import { createHash as createHash14, randomUUID as randomUUID4 } from "node:crypto";
12626
13965
  import { existsSync as existsSync41, mkdirSync as mkdirSync26, writeFileSync as writeFileSync25, readFileSync as readFileSync25, statSync as statSync4, accessSync, constants } from "node:fs";
12627
13966
  import { join as join41 } from "node:path";
12628
13967
  var ACTIVATION_V1_CONTRACT = "avorelo.activation.v1";
@@ -12637,7 +13976,7 @@ function activationPath(dir) {
12637
13976
  return join41(avoreloDir(dir), "activation.json");
12638
13977
  }
12639
13978
  function freshActivationId(seed) {
12640
- return "act_" + createHash13("sha256").update(seed).digest("hex").slice(0, 12);
13979
+ return "act_" + createHash14("sha256").update(seed).digest("hex").slice(0, 12);
12641
13980
  }
12642
13981
  function loadWorkspace(dir) {
12643
13982
  const p = workspacePath(dir);
@@ -12842,14 +14181,14 @@ function renderDogfoodCheck(r2) {
12842
14181
  }
12843
14182
 
12844
14183
  // src/avorelo/capabilities/core-readiness/index.ts
12845
- import { createHash as createHash15 } from "node:crypto";
14184
+ import { createHash as createHash16 } from "node:crypto";
12846
14185
  import { existsSync as existsSync43, readFileSync as readFileSync27 } from "node:fs";
12847
14186
  import { join as join43 } from "node:path";
12848
14187
 
12849
14188
  // src/avorelo/capabilities/canonical-readiness/index.ts
12850
14189
  import { existsSync as existsSync42, readFileSync as readFileSync26, readdirSync as readdirSync11, statSync as statSync5 } from "node:fs";
12851
14190
  import { join as join42 } from "node:path";
12852
- import { createHash as createHash14 } from "node:crypto";
14191
+ import { createHash as createHash15 } from "node:crypto";
12853
14192
  var FORBIDDEN_CLAIM_PATTERNS = [
12854
14193
  { code: "guaranteed_savings", re: /guaranteed savings|guarantee[sd]? .{0,20}savings/ },
12855
14194
  { code: "zero_leak_guarantee", re: /zero[- ]leak guarantee|guarantee[sd]? .{0,20}no leak|no secret will ever leak/ },
@@ -13055,7 +14394,7 @@ function buildCanonicalReadinessReport(target, opts = {}) {
13055
14394
  contract: "avorelo.canonicalReadiness.v1",
13056
14395
  schemaVersion: 1,
13057
14396
  createdAt,
13058
- readinessId: "rdy_" + createHash14("sha256").update(`${createdAt}:${result3}:${blockers.length}`).digest("hex").slice(0, 12),
14397
+ readinessId: "rdy_" + createHash15("sha256").update(`${createdAt}:${result3}:${blockers.length}`).digest("hex").slice(0, 12),
13059
14398
  result: result3,
13060
14399
  phaseCoverage,
13061
14400
  oldRepoCapabilityCoverage,
@@ -13248,7 +14587,7 @@ function buildCoreReadiness(opts) {
13248
14587
  contract: CORE_READINESS_CONTRACT,
13249
14588
  schemaVersion: 1,
13250
14589
  createdAt,
13251
- reportId: "core_" + createHash15("sha256").update(`${createdAt}:${result3}`).digest("hex").slice(0, 12),
14590
+ reportId: "core_" + createHash16("sha256").update(`${createdAt}:${result3}`).digest("hex").slice(0, 12),
13252
14591
  result: result3,
13253
14592
  checks,
13254
14593
  safetyInvariants,
@@ -16085,7 +17424,7 @@ var FORBIDDEN_KEYS2 = /* @__PURE__ */ new Set([
16085
17424
  "rawPath",
16086
17425
  "settings"
16087
17426
  ]);
16088
- var SECRET_PATTERNS2 = [
17427
+ var SECRET_PATTERNS3 = [
16089
17428
  /ghp_[A-Za-z0-9]{36}/,
16090
17429
  /gho_[A-Za-z0-9]{36}/,
16091
17430
  /github_pat_[A-Za-z0-9_]{22,}/,
@@ -16131,7 +17470,7 @@ function validateDogfoodLearningPayload(payload) {
16131
17470
  function inspectStringValue(val, key) {
16132
17471
  if (val.length > 256) return { valid: false, code: "value_too_long", detail: `${key}: ${val.length} chars` };
16133
17472
  if (val.includes("\n") && val.split("\n").length > 2) return { valid: false, code: "multiline_value", detail: key };
16134
- for (const pat of SECRET_PATTERNS2) {
17473
+ for (const pat of SECRET_PATTERNS3) {
16135
17474
  if (pat.test(val)) return { valid: false, code: "secret_pattern", detail: key };
16136
17475
  }
16137
17476
  if (PATH_PATTERN.test(val) && key !== "createdAt") return { valid: false, code: "path_value", detail: key };
@@ -16425,9 +17764,9 @@ function renderPayloadPreview(p) {
16425
17764
  }
16426
17765
 
16427
17766
  // src/avorelo/capabilities/cloud-sync/claim-token.ts
16428
- import { randomBytes, createHash as createHash16 } from "node:crypto";
17767
+ import { randomBytes, createHash as createHash17 } from "node:crypto";
16429
17768
  function generateLocalFingerprint(target) {
16430
- return createHash16("sha256").update(target).digest("hex").slice(0, 16);
17769
+ return createHash17("sha256").update(target).digest("hex").slice(0, 16);
16431
17770
  }
16432
17771
  var CLAIM_EXPIRY_MS = 24 * 60 * 60 * 1e3;
16433
17772
 
@@ -16733,7 +18072,7 @@ function getTelemetryConfig(dir, state) {
16733
18072
  }
16734
18073
 
16735
18074
  // src/avorelo/telemetry/privacy.ts
16736
- import { createHmac as createHmac2, createHash as createHash17, randomUUID as randomUUID9 } from "node:crypto";
18075
+ import { createHmac as createHmac2, createHash as createHash18, randomUUID as randomUUID9 } from "node:crypto";
16737
18076
  import { basename as basename4, resolve as resolve4 } from "node:path";
16738
18077
  var FORBIDDEN_FIELD_PATTERNS = [
16739
18078
  /rawprompt/i,
@@ -16892,7 +18231,7 @@ function inferAgentType(commandName) {
16892
18231
  function sanitizeTelemetryEvent(rawEvent, ctx) {
16893
18232
  const unsafeFields = detectUnsafeTelemetryFields(rawEvent);
16894
18233
  const excludedFields = new Set(unsafeFields);
16895
- const eventId = typeof rawEvent.eventId === "string" && rawEvent.eventId ? rawEvent.eventId : `evt_${createHash17("sha256").update(randomUUID9()).digest("hex").slice(0, 16)}`;
18234
+ const eventId = typeof rawEvent.eventId === "string" && rawEvent.eventId ? rawEvent.eventId : `evt_${createHash18("sha256").update(randomUUID9()).digest("hex").slice(0, 16)}`;
16896
18235
  const occurredAt = typeof rawEvent.occurredAt === "string" && rawEvent.occurredAt ? rawEvent.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
16897
18236
  const repoRoot2 = typeof rawEvent.repoRoot === "string" ? rawEvent.repoRoot : void 0;
16898
18237
  const remoteUrl = typeof rawEvent.remoteUrl === "string" ? rawEvent.remoteUrl : void 0;
@@ -18169,12 +19508,12 @@ function computeNextBestAction(outcome, counts) {
18169
19508
  }
18170
19509
 
18171
19510
  // src/avorelo/kernel/agent-artifact-guard/receipt.ts
18172
- import { createHash as createHash18 } from "node:crypto";
19511
+ import { createHash as createHash19 } from "node:crypto";
18173
19512
  function createReceipt(result3) {
18174
19513
  return {
18175
19514
  receiptType: "agent-artifact-guard-v1",
18176
19515
  scannedAt: result3.scannedAt,
18177
- projectRootHash: createHash18("sha256").update(result3.projectRoot).digest("hex"),
19516
+ projectRootHash: createHash19("sha256").update(result3.projectRoot).digest("hex"),
18178
19517
  filesScanned: result3.filesScanned,
18179
19518
  artifacts: result3.artifacts.map((a) => ({ kind: a.kind, path: a.path })),
18180
19519
  findingSummary: {
@@ -18882,17 +20221,22 @@ Activation taxonomy: ${preflight.taxonomy}
18882
20221
  lines.push("", " Fixed:");
18883
20222
  for (const f of fv.fixed) lines.push(` ${f}`);
18884
20223
  }
18885
- if (fv.needsAttention.length > 0) {
20224
+ const blockedItems = fv.needsAttention.filter((n) => n.startsWith("Blocked:"));
20225
+ if (blockedItems.length > 0) {
18886
20226
  lines.push("", " Needs attention:");
18887
- for (const n of fv.needsAttention) lines.push(` ${n}`);
20227
+ for (const n of blockedItems) lines.push(` ${n}`);
18888
20228
  }
18889
20229
  lines.push(
18890
20230
  "",
18891
20231
  ` Run entry: ${state.runEntry.installed ? "installed" : "not installed"}`,
18892
- ` Billing: ${state.billing.status}`,
18893
- ` Auth: ${state.auth.status}`,
18894
- ` Production: not ready`
20232
+ ` Agent Guard: available`,
20233
+ ` Receipts: working`
18895
20234
  );
20235
+ const optionalItems = fv.needsAttention.filter((n) => !n.startsWith("Blocked:"));
20236
+ if (optionalItems.length > 0) {
20237
+ lines.push("", " Optional (not required for local activation):");
20238
+ for (const n of optionalItems) lines.push(` ${n}`);
20239
+ }
18896
20240
  let linkResult = "no claim provided";
18897
20241
  if (claimToken) {
18898
20242
  const baseUrl = process.env.APP_BASE_URL ?? "https://app.avorelo.com";
@@ -18983,6 +20327,14 @@ async function cmdDoctor(args) {
18983
20327
  if (ctxResult.findings.length > 0) {
18984
20328
  for (const f of ctxResult.findings.slice(0, 3)) lines.push(` ${f.severity}: ${f.message}`);
18985
20329
  }
20330
+ const ccLatest = loadLatestRuntimeSession(target);
20331
+ if (ccLatest?.contextControl) {
20332
+ const cc = ccLatest.contextControl;
20333
+ lines.push("");
20334
+ lines.push(` Context Control: ${cc.status} (reduction=${cc.reductionPercent}%, evidence=${cc.evidenceRefCount}, blocked=${cc.blockedItemsCount})`);
20335
+ if (cc.blockedItemsCount > 0) lines.push(` WARNING: ${cc.blockedItemsCount} context item(s) blocked by policy`);
20336
+ if (cc.proofImpact === "degraded") lines.push(` WARNING: proof impact is degraded \u2014 evidence refs may be incomplete`);
20337
+ }
18986
20338
  try {
18987
20339
  const { getModelRegistry: getModelRegistry2, getLocalModels: getLocalModels2, getAllProviders: getAllProviders2, isProviderAvailable: isProviderAvailable2 } = (init_model_routing2(), __toCommonJS(model_routing_exports));
18988
20340
  const models = getModelRegistry2();
@@ -19120,6 +20472,7 @@ function cmdStatus(args) {
19120
20472
  ` detected: ${[contract.gitDetected ? "git" : "no-git", contract.packageDetected ? "package" : "no-package"].join(", ")}`,
19121
20473
  ` workspace: local-only \xB7 cloud not claimed`,
19122
20474
  ` last run: ${latest ? `${latest.status} (${latest.runtimeSessionId})` : "none yet"}`,
20475
+ ` ctx control: ${latest?.contextControl ? `${latest.contextControl.status} \xB7 reduction=${latest.contextControl.reductionPercent}%` : "not yet run"}`,
19123
20476
  ` routing: seamless model routing active (local-first, no credentials required)`,
19124
20477
  ` control ctr: available \u2014 avorelo control-center --target .`,
19125
20478
  ` next: ${contract.firstRunRecommended.command} \u2014 ${contract.firstRunRecommended.reason}`,
@@ -19901,8 +21254,64 @@ function cmdContext(args) {
19901
21254
  const asJson = args.includes("--json");
19902
21255
  const task = args.slice(1).find((a) => !a.startsWith("--") && a !== target);
19903
21256
  if (sub === "check") return cmdContextCheck(args.slice(1));
21257
+ if (sub === "stats") {
21258
+ const latest = loadLatestRuntimeSession(target);
21259
+ if (!latest?.contextControl) {
21260
+ process.stderr.write("No context control data yet. Run a session first.\n");
21261
+ return 1;
21262
+ }
21263
+ const cc = latest.contextControl;
21264
+ process.stdout.write(renderContextStats({
21265
+ contextControlStatus: cc.status === "optimized" ? "ACTIVE" : cc.status === "blocked" ? "BLOCKED" : "ACTIVE",
21266
+ estimatedContextBefore: cc.estimatedContextBefore,
21267
+ estimatedContextSent: cc.estimatedContextAfter,
21268
+ reductionPercent: cc.reductionPercent,
21269
+ evidenceRefCount: cc.evidenceRefCount,
21270
+ blockedItemsCount: cc.blockedItemsCount,
21271
+ retrievalAvailable: cc.retrievalAvailable,
21272
+ proofImpact: cc.proofImpact,
21273
+ topReasonCodes: cc.reasonCodes,
21274
+ summary: `Context control ${cc.status}`
21275
+ }) + "\n");
21276
+ return 0;
21277
+ }
21278
+ if (sub === "explain") {
21279
+ const latest = loadLatestRuntimeSession(target);
21280
+ if (!latest?.contextControl) {
21281
+ process.stderr.write("No context control data yet. Run a session first.\n");
21282
+ return 1;
21283
+ }
21284
+ const cc = latest.contextControl;
21285
+ process.stdout.write(renderContextExplain({
21286
+ contextControlStatus: cc.status === "optimized" ? "ACTIVE" : cc.status === "blocked" ? "BLOCKED" : "ACTIVE",
21287
+ estimatedContextBefore: cc.estimatedContextBefore,
21288
+ estimatedContextSent: cc.estimatedContextAfter,
21289
+ reductionPercent: cc.reductionPercent,
21290
+ evidenceRefCount: cc.evidenceRefCount,
21291
+ blockedItemsCount: cc.blockedItemsCount,
21292
+ retrievalAvailable: cc.retrievalAvailable,
21293
+ proofImpact: cc.proofImpact,
21294
+ topReasonCodes: cc.reasonCodes,
21295
+ summary: `Context control ${cc.status}`
21296
+ }, []) + "\n");
21297
+ return 0;
21298
+ }
21299
+ if (sub === "learn") {
21300
+ if (!args.includes("--dry-run")) {
21301
+ process.stderr.write("Usage: avorelo context learn --dry-run [--target <dir>]\nLearning candidates are dry-run only.\n");
21302
+ return 2;
21303
+ }
21304
+ const result3 = generateLearningCandidates({ failurePatterns: [], receipts: [] });
21305
+ process.stdout.write(`Learning candidates (dry-run): ${result3.candidates.length}
21306
+ `);
21307
+ for (const c of result3.candidates) {
21308
+ process.stdout.write(` - [${c.priority}] ${c.label}: ${c.description}
21309
+ `);
21310
+ }
21311
+ return 0;
21312
+ }
19904
21313
  if (sub !== "compile") {
19905
- process.stderr.write("Usage: avorelo context <compile|check> [args]\n");
21314
+ process.stderr.write("Usage: avorelo context <compile|check|stats|explain|learn> [args]\n");
19906
21315
  return 2;
19907
21316
  }
19908
21317
  if (!task) {
@@ -19966,6 +21375,22 @@ function cmdReceipt(args) {
19966
21375
  target
19967
21376
  );
19968
21377
  process.stdout.write(output.stdout + "\n");
21378
+ const latest = loadLatestRuntimeSession(target);
21379
+ if (latest?.contextControl && !asJson) {
21380
+ const cc = latest.contextControl;
21381
+ process.stdout.write([
21382
+ "",
21383
+ "Context Control:",
21384
+ ` Status: ${cc.status}`,
21385
+ ` Context before: ${cc.estimatedContextBefore}`,
21386
+ ` Context after: ${cc.estimatedContextAfter}`,
21387
+ ` Reduction: ${cc.reductionPercent}%`,
21388
+ ` Evidence refs: ${cc.evidenceRefCount}`,
21389
+ ` Blocked items: ${cc.blockedItemsCount}`,
21390
+ ` Proof impact: ${cc.proofImpact}`,
21391
+ ""
21392
+ ].join("\n"));
21393
+ }
19969
21394
  return output.exitCode;
19970
21395
  }
19971
21396
  process.stderr.write("Usage: avorelo receipt latest [--target <dir>] [--json]\n");
@@ -21469,6 +22894,7 @@ async function finalize(exitCode) {
21469
22894
  } catch {
21470
22895
  }
21471
22896
  if (_cmd !== "serve" && _cmd !== "webhook" && _cmd !== "sync") {
22897
+ process.exitCode = exitCode;
21472
22898
  setTimeout(() => process.exit(exitCode), 50).unref();
21473
22899
  }
21474
22900
  }