avorelo 0.3.0 → 0.3.2

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 +10 -5
  2. package/dist/avorelo.mjs +1141 -242
  3. package/package.json +1 -1
package/dist/avorelo.mjs CHANGED
@@ -362,6 +362,16 @@ function listReceipts(dir) {
362
362
  }
363
363
  return out;
364
364
  }
365
+ function readReceipt(dir, receiptId) {
366
+ const path = join(localReceiptDir(dir), `${receiptId}.json`);
367
+ if (!existsSync(path)) return null;
368
+ try {
369
+ const r2 = JSON.parse(readFileSync(path, "utf8"));
370
+ return r2 && typeof r2.receiptId === "string" ? r2 : null;
371
+ } catch {
372
+ return null;
373
+ }
374
+ }
365
375
  var init_receipts = __esm({
366
376
  "src/avorelo/kernel/receipts/index.ts"() {
367
377
  init_redaction();
@@ -5659,9 +5669,9 @@ function executeMultiAgentReview(reviewPlan, executorResult, plan, ctx) {
5659
5669
  break;
5660
5670
  }
5661
5671
  }
5662
- const finalVerdict = determineFinalVerdict(rounds, stopCondition);
5672
+ const finalVerdict2 = determineFinalVerdict(rounds, stopCondition);
5663
5673
  const routedToManualGate = stopCondition === "REVIEWER_DISAGREEMENT" || stopCondition === "MAX_REVIEW_ROUNDS_REACHED" || stopCondition === "VERIFIER_OVERRIDE";
5664
- const modelConsensusOnly = finalVerdict === "approved" && rounds.every((r2) => r2.verifierPassed === null);
5674
+ const modelConsensusOnly = finalVerdict2 === "approved" && rounds.every((r2) => r2.verifierPassed === null);
5665
5675
  const reasonCodes = [
5666
5676
  ...reviewPlan.triggerReasonCodes,
5667
5677
  `REVIEW_ROUNDS:${rounds.length}`,
@@ -5673,7 +5683,7 @@ function executeMultiAgentReview(reviewPlan, executorResult, plan, ctx) {
5673
5683
  attempted: true,
5674
5684
  roundsCompleted: rounds.length,
5675
5685
  maxRoundsReached: stopCondition === "MAX_REVIEW_ROUNDS_REACHED",
5676
- finalVerdict,
5686
+ finalVerdict: finalVerdict2,
5677
5687
  rounds,
5678
5688
  totalDurationMs: Date.now() - start,
5679
5689
  reasonCodes,
@@ -6523,7 +6533,7 @@ init_run();
6523
6533
  init_work_contract();
6524
6534
  init_receipts();
6525
6535
  init_state_ledger();
6526
- import { writeFileSync as writeFileSync37, mkdirSync as mkdirSync39, existsSync as existsSync61, readFileSync as readFileSync46, appendFileSync as appendFileSync11, rmSync as rmSync3, unlinkSync as unlinkSync4 } from "node:fs";
6536
+ import { writeFileSync as writeFileSync37, mkdirSync as mkdirSync39, existsSync as existsSync62, readFileSync as readFileSync46, appendFileSync as appendFileSync11, rmSync as rmSync3, unlinkSync as unlinkSync4 } from "node:fs";
6527
6537
  import { join as join61 } from "node:path";
6528
6538
 
6529
6539
  // src/avorelo/capabilities/activation/index.ts
@@ -6604,93 +6614,170 @@ function doctor(targetDir) {
6604
6614
  return { ok: checks.every((c) => c.passed), checks, hookLatencyMs: fired.latencyMs };
6605
6615
  }
6606
6616
 
6607
- // src/avorelo/capabilities/activation/activation-state.ts
6608
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12, existsSync as existsSync25 } from "node:fs";
6609
- import { join as join23, resolve as resolve3 } from "node:path";
6610
- init_redaction();
6611
- var ACTIVATION_STATE_CONTRACT = "avorelo.activationState.v1";
6612
- var ACTIVATION_STATE_DIR = ".avorelo/activation";
6613
- var ACTIVATION_STATE_FILE = "activation-state.json";
6614
- function writeActivationState(targetDir, state) {
6615
- const dir = join23(targetDir, ACTIVATION_STATE_DIR);
6616
- mkdirSync12(dir, { recursive: true });
6617
- const path = join23(dir, ACTIVATION_STATE_FILE);
6618
- const safe = redact(state).value;
6619
- writeFileSync12(path, JSON.stringify(safe, null, 2));
6620
- return path;
6621
- }
6622
- function readActivationState(targetDir) {
6623
- const path = join23(targetDir, ACTIVATION_STATE_DIR, ACTIVATION_STATE_FILE);
6624
- if (!existsSync25(path)) return null;
6617
+ // src/avorelo/capabilities/activation/activation-preflight.ts
6618
+ import { existsSync as existsSync25 } from "node:fs";
6619
+ import { execSync } from "node:child_process";
6620
+ import { platform, tmpdir as tmpdir2 } from "node:os";
6621
+ function runPreflight(targetDir) {
6622
+ const checks = [];
6623
+ const isWindows = platform() === "win32";
6624
+ let nodeOk = false;
6625
6625
  try {
6626
- const raw = readFileSync12(path, "utf8");
6627
- const parsed = JSON.parse(raw);
6628
- if (parsed.contract !== ACTIVATION_STATE_CONTRACT && parsed.contract !== "avorelo.activationState.v2") return null;
6629
- return parsed;
6626
+ const v = execSync("node --version", { encoding: "utf8", timeout: 5e3 }).trim();
6627
+ nodeOk = v.startsWith("v");
6628
+ checks.push({ id: "node_available", label: "Node.js available", passed: nodeOk, details: v });
6630
6629
  } catch {
6631
- return null;
6630
+ checks.push({ id: "node_available", label: "Node.js available", passed: false, details: "node not found in PATH", recovery: "Install Node.js from https://nodejs.org (LTS recommended)" });
6632
6631
  }
6633
- }
6634
- function verifyActivationState(targetDir) {
6635
- const checks = [];
6636
- const state = readActivationState(targetDir);
6637
- if (!state) {
6638
- checks.push({ id: "state_exists", passed: false, reason: "Activation state not found" });
6639
- return { valid: false, checks };
6632
+ let npmOk = false;
6633
+ try {
6634
+ const v = execSync("npm --version", { encoding: "utf8", timeout: 5e3 }).trim();
6635
+ npmOk = true;
6636
+ checks.push({ id: "npm_available", label: "npm available", passed: true, details: `npm ${v}` });
6637
+ } catch {
6638
+ checks.push({ id: "npm_available", label: "npm available", passed: false, details: "npm not found in PATH", recovery: "npm is included with Node.js \u2014 reinstall Node.js from https://nodejs.org" });
6640
6639
  }
6641
- checks.push({ id: "state_exists", passed: true, reason: "Activation state found" });
6642
- const validContracts = [ACTIVATION_STATE_CONTRACT, "avorelo.activationState.v2"];
6643
- const contractOk = validContracts.includes(state.contract);
6644
- checks.push({ id: "contract_valid", passed: contractOk, reason: contractOk ? "Contract matches" : `Expected ${ACTIVATION_STATE_CONTRACT} or v2, got ${state.contract}` });
6645
- checks.push({ id: "redacted", passed: state.redacted === true, reason: state.redacted ? "State is redacted" : "State is NOT redacted" });
6646
- const raw2 = state;
6647
- const billingLive = raw2.billing?.billingLive;
6648
- checks.push({ id: "billing_not_live", passed: billingLive === false, reason: billingLive === false ? "Billing not live" : "BILLING IS LIVE \u2014 violation" });
6649
- const authLive = raw2.cloud?.authLive ?? raw2.auth?.sessionAvailable === true;
6650
- checks.push({ id: "auth_not_live", passed: !authLive, reason: !authLive ? "Auth not live" : "AUTH IS LIVE \u2014 violation" });
6651
- const cloudSyncLive = raw2.cloud?.cloudSyncLive;
6652
- checks.push({ id: "cloud_sync_not_live", passed: cloudSyncLive === false, reason: cloudSyncLive === false ? "Cloud sync not live" : "CLOUD SYNC IS LIVE \u2014 violation" });
6653
- checks.push({ id: "production_not_ready", passed: state.productionReady === false, reason: state.productionReady === false ? "Production not ready (correct)" : "PRODUCTION MARKED READY \u2014 violation" });
6654
- const raw = JSON.stringify(state);
6655
- const hasSecret = carriesRawSecret(raw);
6656
- checks.push({ id: "no_secrets", passed: !hasSecret, reason: hasSecret ? "RAW SECRET DETECTED in state" : "No raw secrets" });
6657
- const legacyTokens = ["wuz", "cco", "claudecode-optimizer"];
6658
- const oldNaming = legacyTokens.some((t) => raw.toLowerCase().includes(t));
6659
- checks.push({ id: "no_old_naming", passed: !oldNaming, reason: oldNaming ? "Old naming leakage detected" : "No old naming leakage" });
6660
- return { valid: checks.every((c) => c.passed), checks };
6640
+ let npxOk = false;
6641
+ try {
6642
+ const v = execSync("npx --version", { encoding: "utf8", timeout: 5e3 }).trim();
6643
+ npxOk = true;
6644
+ checks.push({ id: "npx_available", label: "npx available", passed: true, details: `npx ${v}` });
6645
+ } catch {
6646
+ checks.push({ id: "npx_available", label: "npx available", passed: false, details: "npx not found in PATH", recovery: "npx is included with npm 5.2+. Update Node.js to get a recent npm." });
6647
+ }
6648
+ let cacheOk = false;
6649
+ try {
6650
+ const cachePath = execSync("npm config get cache", { encoding: "utf8", timeout: 5e3 }).trim();
6651
+ if (cachePath && existsSync25(cachePath)) {
6652
+ cacheOk = true;
6653
+ checks.push({ id: "npm_cache_writable", label: "npm cache directory accessible", passed: true, details: "cache directory exists" });
6654
+ } else {
6655
+ checks.push({
6656
+ id: "npm_cache_writable",
6657
+ label: "npm cache directory accessible",
6658
+ passed: false,
6659
+ details: "cache path does not exist",
6660
+ recovery: isWindows ? 'Use a temporary cache. PowerShell: $env:npm_config_cache="$env:TEMP\\npm-cache-avorelo"; npx -y avorelo@latest activate. cmd.exe: cmd /c "set npm_config_cache=%TEMP%\\npm-cache-avorelo && npx -y avorelo@latest activate"' : "Use a temporary cache: npm_config_cache=$(mktemp -d) npx -y avorelo@latest activate"
6661
+ });
6662
+ }
6663
+ } catch {
6664
+ checks.push({
6665
+ id: "npm_cache_writable",
6666
+ label: "npm cache directory accessible",
6667
+ passed: false,
6668
+ details: "could not read npm cache config",
6669
+ recovery: isWindows ? 'Use a temporary cache. PowerShell: $env:npm_config_cache="$env:TEMP\\npm-cache-avorelo"; npx -y avorelo@latest activate. cmd.exe: cmd /c "set npm_config_cache=%TEMP%\\npm-cache-avorelo && npx -y avorelo@latest activate"' : "Use a temporary cache: npm_config_cache=$(mktemp -d) npx -y avorelo@latest activate"
6670
+ });
6671
+ }
6672
+ let tempOk = false;
6673
+ try {
6674
+ const td = tmpdir2();
6675
+ tempOk = existsSync25(td);
6676
+ checks.push({ id: "temp_dir_writable", label: "Temp directory writable", passed: tempOk, details: tempOk ? "temp dir accessible" : "temp dir not found" });
6677
+ } catch {
6678
+ checks.push({ id: "temp_dir_writable", label: "Temp directory writable", passed: false, details: "cannot access temp directory" });
6679
+ }
6680
+ let targetOk = false;
6681
+ try {
6682
+ targetOk = existsSync25(targetDir);
6683
+ checks.push({ id: "target_dir_writable", label: "Target directory exists", passed: targetOk, details: targetOk ? "directory accessible" : "directory not found" });
6684
+ } catch {
6685
+ checks.push({ id: "target_dir_writable", label: "Target directory exists", passed: false, details: "cannot access target directory" });
6686
+ }
6687
+ let psOk = true;
6688
+ if (isWindows) {
6689
+ try {
6690
+ const policy = execSync("powershell -NoProfile -Command Get-ExecutionPolicy", { encoding: "utf8", timeout: 5e3 }).trim().toLowerCase();
6691
+ const blocked = policy === "restricted" || policy === "allsigned";
6692
+ psOk = !blocked;
6693
+ checks.push({
6694
+ id: "powershell_execution_policy",
6695
+ label: "PowerShell execution policy",
6696
+ passed: psOk,
6697
+ details: `Policy: ${policy}`,
6698
+ recovery: blocked ? "PowerShell is blocking script execution. Use Command Prompt instead:\n cmd /c npx -y avorelo@latest activate" : void 0
6699
+ });
6700
+ } catch {
6701
+ checks.push({ id: "powershell_execution_policy", label: "PowerShell execution policy", passed: true, details: "could not check (non-PowerShell shell)" });
6702
+ }
6703
+ }
6704
+ let registryOk = false;
6705
+ try {
6706
+ const result3 = execSync("npm view avorelo@latest version", { encoding: "utf8", timeout: 15e3 }).trim();
6707
+ registryOk = /^\d+\.\d+\.\d+/.test(result3);
6708
+ checks.push({ id: "network_npm_registry", label: "npm registry reachable", passed: registryOk, details: registryOk ? `latest: ${result3}` : "unexpected response" });
6709
+ } catch {
6710
+ checks.push({ id: "network_npm_registry", label: "npm registry reachable", passed: false, details: "cannot reach npm registry", recovery: "Check your network connection. If behind a proxy, configure npm: npm config set proxy <url>" });
6711
+ }
6712
+ const allPassed = checks.every((c) => c.passed);
6713
+ const canStart = nodeOk && npmOk && npxOk;
6714
+ let fallbackCommand;
6715
+ if (!allPassed && isWindows) {
6716
+ fallbackCommand = buildWindowsFallbackCommand();
6717
+ }
6718
+ const taxonomy = allPassed ? "READY" : canStart ? "LOCAL_PREFLIGHT_FAILED" : "BLOCKED_BY_RUNNER_BEFORE_AVORELO_STARTED";
6719
+ return { ok: allPassed, canStart, checks, fallbackCommand, taxonomy };
6661
6720
  }
6662
- function repairActivationState(targetDir) {
6663
- const state = readActivationState(targetDir);
6664
- if (!state) {
6665
- return { repaired: false, message: "No activation state found. Run: npx avorelo activate" };
6721
+ function buildWindowsFallbackCommand() {
6722
+ return [
6723
+ ":: Avorelo activation \u2014 safe Windows fallback",
6724
+ ":: Run this in Command Prompt (cmd.exe), not PowerShell",
6725
+ "set AVORELO_TEMP=%TEMP%\\avorelo-activate-%RANDOM%",
6726
+ "mkdir %AVORELO_TEMP%",
6727
+ "set npm_config_cache=%AVORELO_TEMP%\\npm-cache",
6728
+ "cd /d %AVORELO_TEMP%",
6729
+ "npx -y avorelo@latest activate",
6730
+ "npx -y avorelo@latest status"
6731
+ ].join("\n");
6732
+ }
6733
+ function formatPreflightReport(result3) {
6734
+ const lines = ["", "Avorelo Activation Preflight", ""];
6735
+ for (const c of result3.checks) {
6736
+ const icon = c.passed ? "\u2713" : "\u2717";
6737
+ lines.push(` ${icon} ${c.label}: ${c.details}`);
6738
+ if (!c.passed && c.recovery) {
6739
+ for (const line of c.recovery.split("\n")) {
6740
+ lines.push(` \u2192 ${line}`);
6741
+ }
6742
+ }
6666
6743
  }
6667
- const validContracts2 = [ACTIVATION_STATE_CONTRACT, "avorelo.activationState.v2"];
6668
- if (!validContracts2.includes(state.contract)) {
6669
- return { repaired: false, message: `Corrupt contract: ${state.contract}. Run: npx avorelo activate (will re-create)` };
6744
+ lines.push("");
6745
+ if (result3.ok) {
6746
+ lines.push(" All checks passed. Ready to activate.");
6747
+ } else if (result3.canStart) {
6748
+ lines.push(" Some checks failed but activation can attempt to proceed.");
6749
+ lines.push(" Fix the issues above for the best experience.");
6750
+ } else {
6751
+ lines.push(" Activation cannot start in this environment.");
6752
+ lines.push(" Avorelo requires Node.js and npm to be available.");
6753
+ if (result3.fallbackCommand) {
6754
+ lines.push("");
6755
+ lines.push(" Safe fallback command:");
6756
+ for (const line of result3.fallbackCommand.split("\n")) {
6757
+ lines.push(` ${line}`);
6758
+ }
6759
+ }
6670
6760
  }
6671
- return { repaired: true, message: "Activation state is valid." };
6761
+ lines.push("");
6762
+ return lines.join("\n");
6672
6763
  }
6673
6764
 
6674
- // src/avorelo/capabilities/activation/activation-runner.ts
6675
- import { join as join27 } from "node:path";
6676
- import { existsSync as existsSync29 } from "node:fs";
6677
-
6678
6765
  // src/avorelo/capabilities/activation/activation-detector.ts
6679
- import { existsSync as existsSync26, readFileSync as readFileSync13 } from "node:fs";
6680
- import { join as join24 } from "node:path";
6681
- import { execSync } from "node:child_process";
6682
- import { platform } from "node:os";
6766
+ import { existsSync as existsSync26, readFileSync as readFileSync12 } from "node:fs";
6767
+ import { join as join23 } from "node:path";
6768
+ import { execSync as execSync2 } from "node:child_process";
6769
+ import { platform as platform2 } from "node:os";
6683
6770
  function tryExec(cmd, cwd) {
6684
6771
  try {
6685
- return execSync(cmd, { cwd, stdio: "pipe", timeout: 5e3 }).toString().trim();
6772
+ return execSync2(cmd, { cwd, stdio: "pipe", timeout: 5e3 }).toString().trim();
6686
6773
  } catch {
6687
6774
  return null;
6688
6775
  }
6689
6776
  }
6690
6777
  function commandExists(cmd) {
6691
6778
  try {
6692
- const check = platform() === "win32" ? `where ${cmd}` : `which ${cmd}`;
6693
- execSync(check, { stdio: "pipe", timeout: 3e3 });
6779
+ const check = platform2() === "win32" ? `where ${cmd}` : `which ${cmd}`;
6780
+ execSync2(check, { stdio: "pipe", timeout: 3e3 });
6694
6781
  return true;
6695
6782
  } catch {
6696
6783
  return false;
@@ -6707,18 +6794,18 @@ function detectRepoIdentity(dir) {
6707
6794
  function detectEnvironment(dir) {
6708
6795
  const nodeVersion = tryExec("node --version", dir);
6709
6796
  let packageManager = null;
6710
- if (existsSync26(join24(dir, "pnpm-lock.yaml"))) packageManager = "pnpm";
6711
- else if (existsSync26(join24(dir, "yarn.lock"))) packageManager = "yarn";
6712
- else if (existsSync26(join24(dir, "bun.lockb"))) packageManager = "bun";
6713
- else if (existsSync26(join24(dir, "package-lock.json"))) packageManager = "npm";
6714
- else if (existsSync26(join24(dir, "package.json"))) packageManager = "npm";
6797
+ if (existsSync26(join23(dir, "pnpm-lock.yaml"))) packageManager = "pnpm";
6798
+ else if (existsSync26(join23(dir, "yarn.lock"))) packageManager = "yarn";
6799
+ else if (existsSync26(join23(dir, "bun.lockb"))) packageManager = "bun";
6800
+ else if (existsSync26(join23(dir, "package-lock.json"))) packageManager = "npm";
6801
+ else if (existsSync26(join23(dir, "package.json"))) packageManager = "npm";
6715
6802
  let framework = null;
6716
6803
  let testCommand = null;
6717
6804
  let sitePreviewCommand = null;
6718
- const pkgPath = join24(dir, "package.json");
6805
+ const pkgPath = join23(dir, "package.json");
6719
6806
  if (existsSync26(pkgPath)) {
6720
6807
  try {
6721
- const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
6808
+ const pkg = JSON.parse(readFileSync12(pkgPath, "utf8"));
6722
6809
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
6723
6810
  if (deps.next) framework = "next";
6724
6811
  else if (deps.react) framework = "react";
@@ -6732,29 +6819,29 @@ function detectEnvironment(dir) {
6732
6819
  } catch {
6733
6820
  }
6734
6821
  }
6735
- if (existsSync26(join24(dir, "main.wasp"))) framework = "wasp";
6736
- return { os: platform(), nodeVersion, packageManager, framework, testCommand, sitePreviewCommand };
6822
+ if (existsSync26(join23(dir, "main.wasp"))) framework = "wasp";
6823
+ return { os: platform2(), nodeVersion, packageManager, framework, testCommand, sitePreviewCommand };
6737
6824
  }
6738
6825
  function detectAiTools(dir) {
6739
6826
  return {
6740
- claudeCodeDetected: existsSync26(join24(dir, ".claude")) || existsSync26(join24(dir, ".claude", "settings.json")),
6741
- codexDetected: existsSync26(join24(dir, ".codex")),
6742
- cursorDetected: existsSync26(join24(dir, ".cursor")),
6743
- agentsMdDetected: existsSync26(join24(dir, "AGENTS.md")),
6744
- claudeMdDetected: existsSync26(join24(dir, "CLAUDE.md")),
6745
- cursorRulesDetected: existsSync26(join24(dir, ".cursor", "rules")),
6746
- codexConfigDetected: existsSync26(join24(dir, ".codex", "config.toml")) || existsSync26(join24(dir, "codex.json"))
6827
+ claudeCodeDetected: existsSync26(join23(dir, ".claude")) || existsSync26(join23(dir, ".claude", "settings.json")),
6828
+ codexDetected: existsSync26(join23(dir, ".codex")),
6829
+ cursorDetected: existsSync26(join23(dir, ".cursor")),
6830
+ agentsMdDetected: existsSync26(join23(dir, "AGENTS.md")),
6831
+ claudeMdDetected: existsSync26(join23(dir, "CLAUDE.md")),
6832
+ cursorRulesDetected: existsSync26(join23(dir, ".cursor", "rules")),
6833
+ codexConfigDetected: existsSync26(join23(dir, ".codex", "config.toml")) || existsSync26(join23(dir, "codex.json"))
6747
6834
  };
6748
6835
  }
6749
6836
  function detectModelsAndTools(dir) {
6750
- const ROOT2 = join24(import.meta.dirname, "..", "..", "..", "..");
6837
+ const ROOT2 = join23(import.meta.dirname, "..", "..", "..", "..");
6751
6838
  const env = process.env;
6752
6839
  return {
6753
- skillsRegistryAvailable: existsSync26(join24(ROOT2, "src/avorelo/validation/skill-operating-system/registry.ts")),
6754
- modelRouterAvailable: existsSync26(join24(ROOT2, "src/avorelo/validation/model-routing/index.ts")),
6755
- primitiveRouterAvailable: existsSync26(join24(ROOT2, "tools/route-primitive.ts")),
6756
- scannersAvailable: existsSync26(join24(ROOT2, "src/avorelo/validation/scanners/index.ts")),
6757
- browserProofAvailable: commandExists("playwright") || commandExists("npx") && existsSync26(join24(dir, "node_modules", "@playwright")),
6840
+ skillsRegistryAvailable: existsSync26(join23(ROOT2, "src/avorelo/validation/skill-operating-system/registry.ts")),
6841
+ modelRouterAvailable: existsSync26(join23(ROOT2, "src/avorelo/validation/model-routing/index.ts")),
6842
+ primitiveRouterAvailable: existsSync26(join23(ROOT2, "tools/route-primitive.ts")),
6843
+ scannersAvailable: existsSync26(join23(ROOT2, "src/avorelo/validation/scanners/index.ts")),
6844
+ browserProofAvailable: commandExists("playwright") || commandExists("npx") && existsSync26(join23(dir, "node_modules", "@playwright")),
6758
6845
  githubAvailable: commandExists("gh"),
6759
6846
  billingEnvDetected: !!(env.LEMON_SQUEEZY_PRO_CHECKOUT_URL || env.LEMON_SQUEEZY_API_KEY),
6760
6847
  authEnvDetected: !!(env.AUTH_SECRET || env.JWT_SECRET || env.SESSION_SECRET),
@@ -6788,8 +6875,79 @@ function runFullDetection(dir) {
6788
6875
  return { repo, environment, aiTools, modelsAndTools, summary: { toolsDetected, modelsDetected, missingAdvisory } };
6789
6876
  }
6790
6877
 
6878
+ // src/avorelo/capabilities/activation/activation-state.ts
6879
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12, existsSync as existsSync27 } from "node:fs";
6880
+ import { join as join24, resolve as resolve3 } from "node:path";
6881
+ init_redaction();
6882
+ var ACTIVATION_STATE_CONTRACT = "avorelo.activationState.v1";
6883
+ var ACTIVATION_STATE_DIR = ".avorelo/activation";
6884
+ var ACTIVATION_STATE_FILE = "activation-state.json";
6885
+ function writeActivationState(targetDir, state) {
6886
+ const dir = join24(targetDir, ACTIVATION_STATE_DIR);
6887
+ mkdirSync12(dir, { recursive: true });
6888
+ const path = join24(dir, ACTIVATION_STATE_FILE);
6889
+ const safe = redact(state).value;
6890
+ writeFileSync12(path, JSON.stringify(safe, null, 2));
6891
+ return path;
6892
+ }
6893
+ function readActivationState(targetDir) {
6894
+ const path = join24(targetDir, ACTIVATION_STATE_DIR, ACTIVATION_STATE_FILE);
6895
+ if (!existsSync27(path)) return null;
6896
+ try {
6897
+ const raw = readFileSync13(path, "utf8");
6898
+ const parsed = JSON.parse(raw);
6899
+ if (parsed.contract !== ACTIVATION_STATE_CONTRACT && parsed.contract !== "avorelo.activationState.v2") return null;
6900
+ return parsed;
6901
+ } catch {
6902
+ return null;
6903
+ }
6904
+ }
6905
+ function verifyActivationState(targetDir) {
6906
+ const checks = [];
6907
+ const state = readActivationState(targetDir);
6908
+ if (!state) {
6909
+ checks.push({ id: "state_exists", passed: false, reason: "Activation state not found" });
6910
+ return { valid: false, checks };
6911
+ }
6912
+ checks.push({ id: "state_exists", passed: true, reason: "Activation state found" });
6913
+ const validContracts = [ACTIVATION_STATE_CONTRACT, "avorelo.activationState.v2"];
6914
+ const contractOk = validContracts.includes(state.contract);
6915
+ checks.push({ id: "contract_valid", passed: contractOk, reason: contractOk ? "Contract matches" : `Expected ${ACTIVATION_STATE_CONTRACT} or v2, got ${state.contract}` });
6916
+ checks.push({ id: "redacted", passed: state.redacted === true, reason: state.redacted ? "State is redacted" : "State is NOT redacted" });
6917
+ const raw2 = state;
6918
+ const billingLive = raw2.billing?.billingLive;
6919
+ checks.push({ id: "billing_not_live", passed: billingLive === false, reason: billingLive === false ? "Billing not live" : "BILLING IS LIVE \u2014 violation" });
6920
+ const authLive = raw2.cloud?.authLive ?? raw2.auth?.sessionAvailable === true;
6921
+ checks.push({ id: "auth_not_live", passed: !authLive, reason: !authLive ? "Auth not live" : "AUTH IS LIVE \u2014 violation" });
6922
+ const cloudSyncLive = raw2.cloud?.cloudSyncLive;
6923
+ checks.push({ id: "cloud_sync_not_live", passed: cloudSyncLive === false, reason: cloudSyncLive === false ? "Cloud sync not live" : "CLOUD SYNC IS LIVE \u2014 violation" });
6924
+ checks.push({ id: "production_not_ready", passed: state.productionReady === false, reason: state.productionReady === false ? "Production not ready (correct)" : "PRODUCTION MARKED READY \u2014 violation" });
6925
+ const raw = JSON.stringify(state);
6926
+ const hasSecret = carriesRawSecret(raw);
6927
+ checks.push({ id: "no_secrets", passed: !hasSecret, reason: hasSecret ? "RAW SECRET DETECTED in state" : "No raw secrets" });
6928
+ const legacyTokens = ["wuz", "cco", "claudecode-optimizer"];
6929
+ const oldNaming = legacyTokens.some((t) => raw.toLowerCase().includes(t));
6930
+ checks.push({ id: "no_old_naming", passed: !oldNaming, reason: oldNaming ? "Old naming leakage detected" : "No old naming leakage" });
6931
+ return { valid: checks.every((c) => c.passed), checks };
6932
+ }
6933
+ function repairActivationState(targetDir) {
6934
+ const state = readActivationState(targetDir);
6935
+ if (!state) {
6936
+ return { repaired: false, message: "No activation state found. Run: npx avorelo activate" };
6937
+ }
6938
+ const validContracts2 = [ACTIVATION_STATE_CONTRACT, "avorelo.activationState.v2"];
6939
+ if (!validContracts2.includes(state.contract)) {
6940
+ return { repaired: false, message: `Corrupt contract: ${state.contract}. Run: npx avorelo activate (will re-create)` };
6941
+ }
6942
+ return { repaired: true, message: "Activation state is valid." };
6943
+ }
6944
+
6945
+ // src/avorelo/capabilities/activation/activation-runner.ts
6946
+ import { join as join27 } from "node:path";
6947
+ import { existsSync as existsSync30 } from "node:fs";
6948
+
6791
6949
  // src/avorelo/capabilities/activation/activation-repair.ts
6792
- import { existsSync as existsSync27, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13, readFileSync as readFileSync14, appendFileSync as appendFileSync2 } from "node:fs";
6950
+ import { existsSync as existsSync28, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13, readFileSync as readFileSync14, appendFileSync as appendFileSync2 } from "node:fs";
6793
6951
  import { join as join25 } from "node:path";
6794
6952
  function runSafeRepairs(targetDir) {
6795
6953
  const repairs = [];
@@ -6805,7 +6963,7 @@ function runSafeRepairs(targetDir) {
6805
6963
  ];
6806
6964
  for (const d of dirs) {
6807
6965
  const p = join25(targetDir, d);
6808
- if (!existsSync27(p)) {
6966
+ if (!existsSync28(p)) {
6809
6967
  try {
6810
6968
  mkdirSync13(p, { recursive: true });
6811
6969
  repairs.push({ id: `create_dir_${d.replace(/[/.]/g, "_")}`, label: `Create ${d}`, status: "applied", path: p });
@@ -6818,7 +6976,7 @@ function runSafeRepairs(targetDir) {
6818
6976
  }
6819
6977
  repairGitignore(targetDir, repairs);
6820
6978
  const contractPath = join25(targetDir, ".avorelo", "run-entry", "activation-contract.json");
6821
- if (!existsSync27(contractPath)) {
6979
+ if (!existsSync28(contractPath)) {
6822
6980
  try {
6823
6981
  writeFileSync13(contractPath, JSON.stringify({
6824
6982
  contract: "avorelo.activationContract.v1",
@@ -6843,7 +7001,7 @@ var GITIGNORE_BLOCK = `${GITIGNORE_MARKER_START}
6843
7001
  ${GITIGNORE_MARKER_END}`;
6844
7002
  function repairGitignore(targetDir, repairs) {
6845
7003
  const gitignorePath = join25(targetDir, ".gitignore");
6846
- if (!existsSync27(gitignorePath)) {
7004
+ if (!existsSync28(gitignorePath)) {
6847
7005
  try {
6848
7006
  writeFileSync13(gitignorePath, GITIGNORE_BLOCK + "\n");
6849
7007
  repairs.push({ id: "gitignore_create", label: "Create .gitignore with Avorelo block", status: "applied", path: gitignorePath });
@@ -6870,7 +7028,7 @@ function repairGitignore(targetDir, repairs) {
6870
7028
  }
6871
7029
 
6872
7030
  // src/avorelo/capabilities/activation/activation-run-entry.ts
6873
- import { existsSync as existsSync28, readFileSync as readFileSync15, writeFileSync as writeFileSync14, mkdirSync as mkdirSync14 } from "node:fs";
7031
+ import { existsSync as existsSync29, readFileSync as readFileSync15, writeFileSync as writeFileSync14, mkdirSync as mkdirSync14 } from "node:fs";
6874
7032
  import { join as join26, dirname as dirname3 } from "node:path";
6875
7033
  var MARKER_START = "<!-- >>> Avorelo Run Entry (managed \u2014 do not edit between markers) >>> -->";
6876
7034
  var MARKER_END = "<!-- <<< Avorelo Run Entry <<< -->";
@@ -6895,14 +7053,14 @@ Commands:
6895
7053
  ${MARKER_END}`;
6896
7054
  function installBlock(filePath, blockContent) {
6897
7055
  const dir = dirname3(filePath);
6898
- if (!existsSync28(dir)) {
7056
+ if (!existsSync29(dir)) {
6899
7057
  try {
6900
7058
  mkdirSync14(dir, { recursive: true });
6901
7059
  } catch {
6902
7060
  return { path: filePath, action: "blocked", reason: "Cannot create directory" };
6903
7061
  }
6904
7062
  }
6905
- if (!existsSync28(filePath)) {
7063
+ if (!existsSync29(filePath)) {
6906
7064
  try {
6907
7065
  writeFileSync14(filePath, blockContent + "\n");
6908
7066
  return { path: filePath, action: "created" };
@@ -6941,14 +7099,14 @@ function installRunEntry(targetDir) {
6941
7099
  const claudeMd = join26(targetDir, "CLAUDE.md");
6942
7100
  surfaces.push(installBlock(claudeMd, RUN_ENTRY_BLOCK));
6943
7101
  const agentsMd = join26(targetDir, "AGENTS.md");
6944
- if (existsSync28(agentsMd)) {
7102
+ if (existsSync29(agentsMd)) {
6945
7103
  surfaces.push(installBlock(agentsMd, RUN_ENTRY_BLOCK));
6946
7104
  } else {
6947
7105
  surfaces.push({ path: agentsMd, action: "skipped", reason: "AGENTS.md does not exist \u2014 not creating" });
6948
7106
  advisory.push("AGENTS.md not present");
6949
7107
  }
6950
7108
  const cursorDir = join26(targetDir, ".cursor", "rules");
6951
- if (existsSync28(join26(targetDir, ".cursor"))) {
7109
+ if (existsSync29(join26(targetDir, ".cursor"))) {
6952
7110
  const cursorRule = join26(cursorDir, "avorelo.mdc");
6953
7111
  const cursorBlock = [
6954
7112
  "---",
@@ -6961,7 +7119,7 @@ function installRunEntry(targetDir) {
6961
7119
  "Check `npx avorelo status` before starting work.",
6962
7120
  "Use Avorelo validators for proof. Do not claim production readiness without receipts."
6963
7121
  ].join("\n");
6964
- if (!existsSync28(cursorRule)) {
7122
+ if (!existsSync29(cursorRule)) {
6965
7123
  try {
6966
7124
  mkdirSync14(cursorDir, { recursive: true });
6967
7125
  writeFileSync14(cursorRule, cursorBlock + "\n");
@@ -6975,7 +7133,7 @@ function installRunEntry(targetDir) {
6975
7133
  } else {
6976
7134
  advisory.push(".cursor not present");
6977
7135
  }
6978
- if (existsSync28(join26(targetDir, ".codex"))) {
7136
+ if (existsSync29(join26(targetDir, ".codex"))) {
6979
7137
  advisory.push("Codex detected \u2014 manual run-entry recommended");
6980
7138
  }
6981
7139
  let contractPath;
@@ -7636,7 +7794,7 @@ function runFullActivation(targetDir) {
7636
7794
  nextAction: "Run: npx avorelo status"
7637
7795
  };
7638
7796
  const dashboardPath = join27(targetDir, ".avorelo", "dashboard", "index.html");
7639
- const localDashboard = { available: existsSync29(dashboardPath), path: existsSync29(dashboardPath) ? dashboardPath : void 0 };
7797
+ const localDashboard = { available: existsSync30(dashboardPath), path: existsSync30(dashboardPath) ? dashboardPath : void 0 };
7640
7798
  const blockers = repairsBlocked.length;
7641
7799
  const activationStatus = blockers > 0 ? "blocked" : "active_with_holds";
7642
7800
  const existingState = readActivationState(targetDir);
@@ -8017,7 +8175,7 @@ function prepareDashboardHtmlWithEntitlements(html, model) {
8017
8175
 
8018
8176
  // src/avorelo/adapters/lemon-squeezy/subscription-store.ts
8019
8177
  init_redaction();
8020
- import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync15, readFileSync as readFileSync16, readdirSync as readdirSync8, existsSync as existsSync30, renameSync } from "node:fs";
8178
+ import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync15, readFileSync as readFileSync16, readdirSync as readdirSync8, existsSync as existsSync31, renameSync } from "node:fs";
8021
8179
  import { join as join28 } from "node:path";
8022
8180
  import { randomUUID as randomUUID3 } from "node:crypto";
8023
8181
  function subscriptionDir(baseDir) {
@@ -8043,7 +8201,7 @@ function writeSubscription(baseDir, record) {
8043
8201
  function readSubscription(baseDir, providerSubscriptionId) {
8044
8202
  const dir = subscriptionDir(baseDir);
8045
8203
  const path = join28(dir, `sub_${providerSubscriptionId}.json`);
8046
- if (!existsSync30(path)) return null;
8204
+ if (!existsSync31(path)) return null;
8047
8205
  try {
8048
8206
  const r2 = JSON.parse(readFileSync16(path, "utf8"));
8049
8207
  return r2 && typeof r2.id === "string" && typeof r2.plan === "string" ? r2 : null;
@@ -8065,7 +8223,7 @@ function readSubscriptionByUser(baseDir, userId) {
8065
8223
  }
8066
8224
  function listSubscriptions(baseDir) {
8067
8225
  const dir = subscriptionDir(baseDir);
8068
- if (!existsSync30(dir)) return [];
8226
+ if (!existsSync31(dir)) return [];
8069
8227
  const out = [];
8070
8228
  for (const f of readdirSync8(dir)) {
8071
8229
  if (!f.endsWith(".json") || f.includes(".tmp.")) continue;
@@ -8088,7 +8246,7 @@ function writeUnmatchedEvent(baseDir, event) {
8088
8246
  }
8089
8247
  function listUnmatchedEvents(baseDir) {
8090
8248
  const dir = unmatchedDir(baseDir);
8091
- if (!existsSync30(dir)) return [];
8249
+ if (!existsSync31(dir)) return [];
8092
8250
  const out = [];
8093
8251
  for (const f of readdirSync8(dir)) {
8094
8252
  if (!f.endsWith(".json") || f.includes(".tmp.")) continue;
@@ -8351,12 +8509,12 @@ function open(dir, opts) {
8351
8509
 
8352
8510
  // src/avorelo/capabilities/control-center/index.ts
8353
8511
  init_redaction();
8354
- import { mkdirSync as mkdirSync25, writeFileSync as writeFileSync24, existsSync as existsSync39, readFileSync as readFileSync24 } from "node:fs";
8512
+ import { mkdirSync as mkdirSync25, writeFileSync as writeFileSync24, existsSync as existsSync40, readFileSync as readFileSync24 } from "node:fs";
8355
8513
  import { join as join40 } from "node:path";
8356
8514
 
8357
8515
  // src/avorelo/capabilities/runtime-flow/index.ts
8358
8516
  import { createHash as createHash12 } from "node:crypto";
8359
- import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, appendFileSync as appendFileSync9, readFileSync as readFileSync23, existsSync as existsSync38 } from "node:fs";
8517
+ import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, appendFileSync as appendFileSync9, readFileSync as readFileSync23, existsSync as existsSync39 } from "node:fs";
8360
8518
  import { join as join39 } from "node:path";
8361
8519
 
8362
8520
  // src/avorelo/kernel/work-contract/routing.ts
@@ -8621,7 +8779,7 @@ init_session();
8621
8779
 
8622
8780
  // src/avorelo/capabilities/context-compiler/index.ts
8623
8781
  import { createHash as createHash7 } from "node:crypto";
8624
- import { appendFileSync as appendFileSync3, existsSync as existsSync31, mkdirSync as mkdirSync17, readFileSync as readFileSync17, writeFileSync as writeFileSync17 } from "node:fs";
8782
+ import { appendFileSync as appendFileSync3, existsSync as existsSync32, mkdirSync as mkdirSync17, readFileSync as readFileSync17, writeFileSync as writeFileSync17 } from "node:fs";
8625
8783
  import { join as join30 } from "node:path";
8626
8784
 
8627
8785
  // src/avorelo/capabilities/secret-boundary/index.ts
@@ -9281,7 +9439,7 @@ function writeContextPack(dir, pack) {
9281
9439
  }
9282
9440
 
9283
9441
  // src/avorelo/capabilities/continuity/index.ts
9284
- import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync18, readFileSync as readFileSync18, existsSync as existsSync32, appendFileSync as appendFileSync4 } from "node:fs";
9442
+ import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync18, readFileSync as readFileSync18, existsSync as existsSync33, appendFileSync as appendFileSync4 } from "node:fs";
9285
9443
  import { join as join31 } from "node:path";
9286
9444
  init_redactor();
9287
9445
  var DAY_MS = 24 * 60 * 60 * 1e3;
@@ -9437,7 +9595,7 @@ function writeContinuity(dir, packet) {
9437
9595
  }
9438
9596
  function loadLatestContinuity(dir) {
9439
9597
  const latest = join31(continuityDir(dir), "latest.json");
9440
- if (!existsSync32(latest)) return null;
9598
+ if (!existsSync33(latest)) return null;
9441
9599
  try {
9442
9600
  const p = JSON.parse(readFileSync18(latest, "utf8"));
9443
9601
  return p && p.contract === "avorelo.nextRunContinuity.v1" ? p : null;
@@ -9448,7 +9606,7 @@ function loadLatestContinuity(dir) {
9448
9606
 
9449
9607
  // src/avorelo/capabilities/token-cost-evidence/index.ts
9450
9608
  init_redactor();
9451
- import { mkdirSync as mkdirSync19, readFileSync as readFileSync19, existsSync as existsSync33, appendFileSync as appendFileSync5 } from "node:fs";
9609
+ import { mkdirSync as mkdirSync19, readFileSync as readFileSync19, existsSync as existsSync34, appendFileSync as appendFileSync5 } from "node:fs";
9452
9610
  import { join as join32 } from "node:path";
9453
9611
  import { createHash as createHash8 } from "node:crypto";
9454
9612
  var FORBIDDEN_IMPORT_KEYS = [
@@ -9744,7 +9902,7 @@ function writeTokenCostEvidence(dir, e) {
9744
9902
  }
9745
9903
  function loadTokenCostEvidence(dir) {
9746
9904
  const path = join32(evidenceDir(dir), "token-cost.jsonl");
9747
- if (!existsSync33(path)) return [];
9905
+ if (!existsSync34(path)) return [];
9748
9906
  const out = [];
9749
9907
  for (const line of readFileSync19(path, "utf8").split(/\r?\n/)) {
9750
9908
  if (!line.trim()) continue;
@@ -9759,7 +9917,7 @@ function loadTokenCostEvidence(dir) {
9759
9917
 
9760
9918
  // src/avorelo/capabilities/proof-report/index.ts
9761
9919
  init_redactor();
9762
- import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync20, appendFileSync as appendFileSync6, existsSync as existsSync34, readFileSync as readFileSync20 } from "node:fs";
9920
+ import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync20, appendFileSync as appendFileSync6, existsSync as existsSync35, readFileSync as readFileSync20 } from "node:fs";
9763
9921
  import { join as join33 } from "node:path";
9764
9922
  import { createHash as createHash9 } from "node:crypto";
9765
9923
  var rs = (s) => redactString2(String(s ?? ""), "handoff", "report").redacted;
@@ -9916,7 +10074,7 @@ function writeProofReport(dir, r2) {
9916
10074
  }
9917
10075
  function loadLatestProofReport(dir) {
9918
10076
  const latest = join33(reportsDir(dir), "proof-report.latest.json");
9919
- if (!existsSync34(latest)) return null;
10077
+ if (!existsSync35(latest)) return null;
9920
10078
  try {
9921
10079
  return JSON.parse(readFileSync20(latest, "utf8"));
9922
10080
  } catch {
@@ -9926,7 +10084,7 @@ function loadLatestProofReport(dir) {
9926
10084
 
9927
10085
  // src/avorelo/capabilities/value-ledger/index.ts
9928
10086
  init_redactor();
9929
- import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync21, readFileSync as readFileSync21, existsSync as existsSync35, appendFileSync as appendFileSync7 } from "node:fs";
10087
+ import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync21, readFileSync as readFileSync21, existsSync as existsSync36, appendFileSync as appendFileSync7 } from "node:fs";
9930
10088
  import { join as join34 } from "node:path";
9931
10089
  import { createHash as createHash10 } from "node:crypto";
9932
10090
  function safeText2(s) {
@@ -10075,7 +10233,7 @@ function appendValueLedgerEntry(dir, e) {
10075
10233
  }
10076
10234
  function loadValueLedgerEntries(dir) {
10077
10235
  const path = join34(ledgerDir(dir), "value-ledger.jsonl");
10078
- if (!existsSync35(path)) return [];
10236
+ if (!existsSync36(path)) return [];
10079
10237
  const out = [];
10080
10238
  for (const line of readFileSync21(path, "utf8").split(/\r?\n/)) {
10081
10239
  if (!line.trim()) continue;
@@ -10251,7 +10409,7 @@ import { mkdirSync as mkdirSync23, writeFileSync as writeFileSync22 } from "node
10251
10409
  import { join as join38 } from "node:path";
10252
10410
 
10253
10411
  // src/avorelo/capabilities/context-check/scanner.ts
10254
- import { existsSync as existsSync36, readdirSync as readdirSync9, statSync as statSync3, openSync, readSync, closeSync } from "node:fs";
10412
+ import { existsSync as existsSync37, readdirSync as readdirSync9, statSync as statSync3, openSync, readSync, closeSync } from "node:fs";
10255
10413
  import { join as join36, relative, sep as sep3 } from "node:path";
10256
10414
  var BYTES_PER_TOKEN_ESTIMATE = 4;
10257
10415
  var MAX_SCAN_DEPTH = 5;
@@ -10306,7 +10464,7 @@ function extractReferences(content) {
10306
10464
  function scanClaude(repoRoot2) {
10307
10465
  const sources = [];
10308
10466
  const rootMd = join36(repoRoot2, "CLAUDE.md");
10309
- if (existsSync36(rootMd)) {
10467
+ if (existsSync37(rootMd)) {
10310
10468
  const meta = fileMeta(rootMd);
10311
10469
  if (meta) {
10312
10470
  const content = safeRead(rootMd);
@@ -10320,7 +10478,7 @@ function scanClaude(repoRoot2) {
10320
10478
  }
10321
10479
  }
10322
10480
  const claudeDir = join36(repoRoot2, ".claude");
10323
- if (existsSync36(claudeDir)) {
10481
+ if (existsSync37(claudeDir)) {
10324
10482
  try {
10325
10483
  for (const entry of walkDir(claudeDir, 3)) {
10326
10484
  if (!entry.endsWith(".md") && !entry.endsWith(".json") && !entry.endsWith(".txt")) continue;
@@ -10365,7 +10523,7 @@ function scanClaude(repoRoot2) {
10365
10523
  }
10366
10524
  function scanAgents(repoRoot2) {
10367
10525
  const agentsMd = join36(repoRoot2, "AGENTS.md");
10368
- if (!existsSync36(agentsMd)) return [];
10526
+ if (!existsSync37(agentsMd)) return [];
10369
10527
  const meta = fileMeta(agentsMd);
10370
10528
  if (!meta) return [];
10371
10529
  const content = safeRead(agentsMd);
@@ -10380,9 +10538,9 @@ function scanAgents(repoRoot2) {
10380
10538
  function scanCursor(repoRoot2) {
10381
10539
  const sources = [];
10382
10540
  const cursorDir = join36(repoRoot2, ".cursor");
10383
- if (!existsSync36(cursorDir)) return sources;
10541
+ if (!existsSync37(cursorDir)) return sources;
10384
10542
  const rulesDir = join36(cursorDir, "rules");
10385
- if (existsSync36(rulesDir)) {
10543
+ if (existsSync37(rulesDir)) {
10386
10544
  try {
10387
10545
  for (const entry of walkDir(rulesDir, 2)) {
10388
10546
  if (!entry.endsWith(".mdc") && !entry.endsWith(".md") && !entry.endsWith(".txt")) continue;
@@ -10404,7 +10562,7 @@ function scanCursor(repoRoot2) {
10404
10562
  }
10405
10563
  }
10406
10564
  const cursorrules = join36(repoRoot2, ".cursorrules");
10407
- if (existsSync36(cursorrules)) {
10565
+ if (existsSync37(cursorrules)) {
10408
10566
  const meta = fileMeta(cursorrules);
10409
10567
  if (meta) {
10410
10568
  sources.push({
@@ -10430,7 +10588,7 @@ function extractCursorGlobs(content) {
10430
10588
  function scanCodex(repoRoot2) {
10431
10589
  const sources = [];
10432
10590
  const codexMd = join36(repoRoot2, "CODEX.md");
10433
- if (existsSync36(codexMd)) {
10591
+ if (existsSync37(codexMd)) {
10434
10592
  const meta = fileMeta(codexMd);
10435
10593
  if (meta) {
10436
10594
  sources.push({
@@ -10443,7 +10601,7 @@ function scanCodex(repoRoot2) {
10443
10601
  }
10444
10602
  }
10445
10603
  const codexDir = join36(repoRoot2, ".codex");
10446
- if (existsSync36(codexDir)) {
10604
+ if (existsSync37(codexDir)) {
10447
10605
  try {
10448
10606
  for (const entry of walkDir(codexDir, 2)) {
10449
10607
  const meta = fileMeta(entry);
@@ -10467,7 +10625,7 @@ function scanGeneric(repoRoot2) {
10467
10625
  const knownFiles = [".github/copilot-instructions.md", "CONTRIBUTING.md"];
10468
10626
  for (const rel of knownFiles) {
10469
10627
  const full = join36(repoRoot2, rel);
10470
- if (existsSync36(full)) {
10628
+ if (existsSync37(full)) {
10471
10629
  const meta = fileMeta(full);
10472
10630
  if (meta) {
10473
10631
  sources.push({
@@ -10503,7 +10661,7 @@ function* walkDir(dir, maxDepth, depth = 0) {
10503
10661
  }
10504
10662
 
10505
10663
  // src/avorelo/capabilities/context-check/classifier.ts
10506
- import { existsSync as existsSync37 } from "node:fs";
10664
+ import { existsSync as existsSync38 } from "node:fs";
10507
10665
  import { join as join37, dirname as dirname4 } from "node:path";
10508
10666
  var OVERSIZE_WARNING_TOKENS = 8e3;
10509
10667
  var OVERSIZE_ATTENTION_TOKENS = 25e3;
@@ -10529,7 +10687,7 @@ function checkBrokenReferences(src, repoRoot2) {
10529
10687
  for (const ref of src.references) {
10530
10688
  const resolvedPath = join37(repoRoot2, dirname4(src.path), ref);
10531
10689
  const resolvedFromRoot = join37(repoRoot2, ref);
10532
- if (!existsSync37(resolvedPath) && !existsSync37(resolvedFromRoot)) {
10690
+ if (!existsSync38(resolvedPath) && !existsSync38(resolvedFromRoot)) {
10533
10691
  findings.push({
10534
10692
  code: "BROKEN_CONTEXT_REFERENCE",
10535
10693
  severity: "warning",
@@ -10586,7 +10744,7 @@ function checkRuleMatchesNoFiles(src, repoRoot2) {
10586
10744
  for (const glob of src.appliesToPaths) {
10587
10745
  if (glob.includes("*")) continue;
10588
10746
  const target = join37(repoRoot2, glob);
10589
- if (!existsSync37(target)) {
10747
+ if (!existsSync38(target)) {
10590
10748
  return [{
10591
10749
  code: "RULE_MATCHES_NO_FILES",
10592
10750
  severity: "info",
@@ -10984,6 +11142,477 @@ function buildSummary(status, sourceCount, findingCount) {
10984
11142
 
10985
11143
  // src/avorelo/capabilities/runtime-flow/index.ts
10986
11144
  init_redaction();
11145
+
11146
+ // src/avorelo/kernel/work-controls/index.ts
11147
+ var BUILTIN_CONTROLS = [
11148
+ {
11149
+ controlId: "secrets_guard",
11150
+ title: "Secrets Guard",
11151
+ purpose: "Block tasks, commands, syncs, and receipts that would leak secrets or env values.",
11152
+ enforcementPoints: ["before_task_start", "before_shell_command", "before_secret_or_env_access", "before_cloud_sync", "before_receipt_finalize"],
11153
+ defaultState: "enabled",
11154
+ packaging: { free: true, pro: true, teams: true },
11155
+ localOnlyBehavior: "Detects secret and env exposure locally, returns coded findings only, never persists raw values.",
11156
+ cloudBehavior: "Never allows raw secret or env material into sync payloads.",
11157
+ dataPersisted: ["reason codes", "redaction classes", "safe next actions"],
11158
+ testsRequired: ["no raw env persistence", "no secret printing", "DENY short-circuit"],
11159
+ uiCopy: "Block secret or env leakage."
11160
+ },
11161
+ {
11162
+ controlId: "scope_drift_guard",
11163
+ title: "Scope Drift Guard",
11164
+ purpose: "Stop broad or out-of-scope work before it silently expands.",
11165
+ enforcementPoints: ["before_task_start", "before_file_write"],
11166
+ defaultState: "enabled",
11167
+ packaging: { free: true, pro: true, teams: true },
11168
+ localOnlyBehavior: "Uses route and write-scope metadata only.",
11169
+ cloudBehavior: "Only safe scope codes may be synced.",
11170
+ dataPersisted: ["reason codes", "triggered control id"],
11171
+ testsRequired: ["ASK for broad scope", "DENY for out-of-scope writes"],
11172
+ uiCopy: "Stop scope drift before it spreads."
11173
+ },
11174
+ {
11175
+ controlId: "risky_action_approval",
11176
+ title: "Risky Action Approval",
11177
+ purpose: "Ask before risky work starts when the routed task already requires confirmation or manual review.",
11178
+ enforcementPoints: ["before_task_start"],
11179
+ defaultState: "enabled",
11180
+ packaging: { free: true, pro: true, teams: true },
11181
+ localOnlyBehavior: "Maps current route/risk/proof metadata to a clear ASK verdict.",
11182
+ cloudBehavior: "Only approval-required state may be synced, never task content.",
11183
+ dataPersisted: ["verdict", "reason codes", "approval-required flag"],
11184
+ testsRequired: ["ASK requires explicit approval", "approval clears ASK but not DENY"],
11185
+ uiCopy: "Ask before risky actions."
11186
+ },
11187
+ {
11188
+ controlId: "shell_command_approval",
11189
+ title: "Shell Command Approval",
11190
+ purpose: "Ask before risky shell commands and deny obviously destructive ones.",
11191
+ enforcementPoints: ["before_shell_command"],
11192
+ defaultState: "enabled",
11193
+ packaging: { free: true, pro: true, teams: true },
11194
+ localOnlyBehavior: "Evaluates the command string locally and never stores terminal output.",
11195
+ cloudBehavior: "Only coded gate outcomes may sync.",
11196
+ dataPersisted: ["reason codes", "verdict"],
11197
+ testsRequired: ["ASK for risky commands", "DENY for destructive commands"],
11198
+ uiCopy: "Ask before risky shell commands."
11199
+ },
11200
+ {
11201
+ controlId: "file_write_approval",
11202
+ title: "File Write Approval",
11203
+ purpose: "Require confirmation before sensitive file writes.",
11204
+ enforcementPoints: ["before_file_write"],
11205
+ defaultState: "enabled",
11206
+ packaging: { free: true, pro: true, teams: true },
11207
+ localOnlyBehavior: "Uses path classification only, not file contents.",
11208
+ cloudBehavior: "Only write gate metadata may sync.",
11209
+ dataPersisted: ["reason codes", "verdict"],
11210
+ testsRequired: ["ASK for sensitive writes"],
11211
+ uiCopy: "Ask before sensitive file writes."
11212
+ },
11213
+ {
11214
+ controlId: "dependency_install_approval",
11215
+ title: "Dependency Install Approval",
11216
+ purpose: "Pause before package installs or dependency changes.",
11217
+ enforcementPoints: ["before_dependency_install", "before_shell_command"],
11218
+ defaultState: "enabled",
11219
+ packaging: { free: true, pro: true, teams: true },
11220
+ localOnlyBehavior: "Uses command metadata only.",
11221
+ cloudBehavior: "Only approval-required metadata may sync.",
11222
+ dataPersisted: ["reason codes", "verdict"],
11223
+ testsRequired: ["ASK for dependency install"],
11224
+ uiCopy: "Ask before dependency installs."
11225
+ },
11226
+ {
11227
+ controlId: "release_guard",
11228
+ title: "Release Guard",
11229
+ purpose: "Require explicit approval before package publish or release tagging.",
11230
+ enforcementPoints: ["before_package_publish", "before_release_tag", "before_task_start"],
11231
+ defaultState: "enabled",
11232
+ packaging: { free: true, pro: true, teams: true },
11233
+ localOnlyBehavior: "Evaluates release intent locally and records approval state.",
11234
+ cloudBehavior: "Only release gate receipts may sync.",
11235
+ dataPersisted: ["verdict", "reason codes", "approval-required flag"],
11236
+ testsRequired: ["ASK for publish", "ASK for release tag"],
11237
+ uiCopy: "Prevent publish or release without approval."
11238
+ },
11239
+ {
11240
+ controlId: "production_deploy_guard",
11241
+ title: "Production Deploy Guard",
11242
+ purpose: "Escalate production-impacting work beyond a normal ASK.",
11243
+ enforcementPoints: ["before_production_deploy", "before_task_start"],
11244
+ defaultState: "enabled",
11245
+ packaging: { free: true, pro: true, teams: true },
11246
+ localOnlyBehavior: "Records the stronger approval requirement locally.",
11247
+ cloudBehavior: "Only coded escalation metadata may sync.",
11248
+ dataPersisted: ["verdict", "reason codes", "approval-required flag"],
11249
+ testsRequired: ["ESCALATE for production deploy without stronger approval"],
11250
+ uiCopy: "Require stronger approval for production deploys."
11251
+ },
11252
+ {
11253
+ controlId: "proof_required_before_done",
11254
+ title: "Proof Required Before Done",
11255
+ purpose: "Block done claims until outcome and post-action proof exist.",
11256
+ enforcementPoints: ["after_agent_claims_done", "before_receipt_finalize", "before_test_claim"],
11257
+ defaultState: "enabled",
11258
+ packaging: { free: true, pro: true, teams: true },
11259
+ localOnlyBehavior: "Checks proof metadata only; never stores raw test logs or diffs.",
11260
+ cloudBehavior: "Only proof status may sync.",
11261
+ dataPersisted: ["proof-required flag", "reason codes", "safe next actions"],
11262
+ testsRequired: ["REQUIRE_PROOF without evidence", "proof gate deterministic"],
11263
+ uiCopy: "Require proof before done."
11264
+ },
11265
+ {
11266
+ controlId: "raw_payload_upload_guard",
11267
+ title: "Raw Prompt/Source/Diff Upload Guard",
11268
+ purpose: "Deny cloud sync when raw prompt, source, diff, env, terminal, or secret payloads are present.",
11269
+ enforcementPoints: ["before_cloud_sync"],
11270
+ defaultState: "enabled",
11271
+ packaging: { free: true, pro: true, teams: true },
11272
+ localOnlyBehavior: "Evaluates payload safety flags locally before any sync attempt.",
11273
+ cloudBehavior: "Hard-denies unsafe sync.",
11274
+ dataPersisted: ["reason codes", "verdict"],
11275
+ testsRequired: ["no raw prompt upload", "no raw source upload", "no raw diff upload"],
11276
+ uiCopy: "Receipts, not raw source."
11277
+ },
11278
+ {
11279
+ controlId: "model_worthiness_guard",
11280
+ title: "Model Worthiness Guard",
11281
+ purpose: "Warn when a trivial task is not worth an expensive or deep review path.",
11282
+ enforcementPoints: ["before_task_start"],
11283
+ defaultState: "warn_only",
11284
+ packaging: { free: true, pro: true, teams: true },
11285
+ localOnlyBehavior: "Uses routing/task metadata only.",
11286
+ cloudBehavior: "Only safe warning metadata may sync.",
11287
+ dataPersisted: ["warning reason codes"],
11288
+ testsRequired: ["WARN for trivial task with expensive model request"],
11289
+ uiCopy: "Warn when deep review is not worth it."
11290
+ }
11291
+ ];
11292
+ var CONTROL_BY_ID = new Map(BUILTIN_CONTROLS.map((control) => [control.controlId, control]));
11293
+ var VERDICT_PRECEDENCE = [
11294
+ "DENY",
11295
+ "ESCALATE",
11296
+ "ASK",
11297
+ "REQUIRE_PROOF",
11298
+ "WARN",
11299
+ "ALLOW",
11300
+ "NOOP"
11301
+ ];
11302
+ var DESTRUCTIVE_SHELL_RE = /\b(rm\s+-rf|del\s+\/s|drop\s+table|git\s+push\s+--force|mkfs|dd\s+if=)\b/i;
11303
+ var RISKY_SHELL_RE = /\b(npm\s+publish|git\s+tag|railway|netlify|vercel|docker\s+push|kubectl|terraform\s+apply)\b/i;
11304
+ var DEPENDENCY_INSTALL_RE = /\b(npm|pnpm|yarn|bun)\s+(install|add)\b/i;
11305
+ function hasRawPayload(ctx) {
11306
+ return !!(ctx.containsRawPrompt || ctx.containsRawSource || ctx.containsRawSecret || ctx.containsEnvValue || ctx.containsGitDiff || ctx.containsTerminalLog);
11307
+ }
11308
+ function hasProof(ctx) {
11309
+ const levels = ctx.evidenceLevels ?? [];
11310
+ return levels.includes("OUTCOME") && levels.includes("POST_ACTION");
11311
+ }
11312
+ function buildTrigger(controlId, enforcementPoint, verdict, reason, reasonCodes, nextAction) {
11313
+ const def = CONTROL_BY_ID.get(controlId);
11314
+ return {
11315
+ controlId,
11316
+ title: def.title,
11317
+ verdict,
11318
+ enforcementPoint,
11319
+ reason,
11320
+ reasonCodes,
11321
+ nextAction
11322
+ };
11323
+ }
11324
+ function evaluateSecretsGuard(point, ctx) {
11325
+ if (point === "before_cloud_sync" && hasRawPayload(ctx)) {
11326
+ return buildTrigger(
11327
+ "raw_payload_upload_guard",
11328
+ point,
11329
+ "DENY",
11330
+ "Cloud sync is blocked because the payload still contains raw prompt, source, diff, secret, env, or terminal data.",
11331
+ ["RAW_PAYLOAD_BLOCKED"],
11332
+ "Redact the payload and sync metadata only."
11333
+ );
11334
+ }
11335
+ if (ctx.safeRunDecision === "block" || ctx.containsRawSecret || ctx.containsEnvValue) {
11336
+ return buildTrigger(
11337
+ "secrets_guard",
11338
+ point,
11339
+ "DENY",
11340
+ "This action would expose secret or env material beyond Avorelo's trust boundary.",
11341
+ ["SECRET_OR_ENV_EXPOSURE"],
11342
+ "Remove the secret/env access, rotate if needed, and retry with safe references only."
11343
+ );
11344
+ }
11345
+ return null;
11346
+ }
11347
+ function evaluateScopeGuard(point, ctx) {
11348
+ if (point === "before_file_write" && ctx.outOfScopeWrite) {
11349
+ return buildTrigger(
11350
+ "scope_drift_guard",
11351
+ point,
11352
+ "DENY",
11353
+ "The requested write is outside the approved work scope.",
11354
+ ["OUT_OF_SCOPE_WRITE"],
11355
+ "Narrow the task or explicitly approve the additional scope before writing."
11356
+ );
11357
+ }
11358
+ if (point === "before_task_start" && ctx.route === "needs_decision") {
11359
+ return buildTrigger(
11360
+ "scope_drift_guard",
11361
+ point,
11362
+ "ASK",
11363
+ "The task scope is too broad or ambiguous to start safely without a confirmation step.",
11364
+ ["SCOPE_CONFIRMATION_REQUIRED"],
11365
+ "Clarify the scope, target files, or success criteria before continuing."
11366
+ );
11367
+ }
11368
+ return null;
11369
+ }
11370
+ function evaluateRiskyActionApproval(point, ctx) {
11371
+ if (point !== "before_task_start") return null;
11372
+ if (ctx.approvalPolicy === "require_confirmation" || ctx.approvalPolicy === "require_manual_review") {
11373
+ if (ctx.userApproved) {
11374
+ return buildTrigger(
11375
+ "risky_action_approval",
11376
+ point,
11377
+ "ALLOW",
11378
+ "The risky action had an explicit approval, so Avorelo can proceed without weakening safety.",
11379
+ ["RISKY_ACTION_APPROVED"],
11380
+ null
11381
+ );
11382
+ }
11383
+ return buildTrigger(
11384
+ "risky_action_approval",
11385
+ point,
11386
+ "ASK",
11387
+ "This task has enough risk that it needs an explicit approval before work starts.",
11388
+ ["RISKY_ACTION_APPROVAL_REQUIRED"],
11389
+ "Confirm the risky action before continuing."
11390
+ );
11391
+ }
11392
+ return null;
11393
+ }
11394
+ function evaluateShellCommand(point, ctx) {
11395
+ if (point !== "before_shell_command" || !ctx.command) return null;
11396
+ if (DESTRUCTIVE_SHELL_RE.test(ctx.command)) {
11397
+ return buildTrigger(
11398
+ "shell_command_approval",
11399
+ point,
11400
+ "DENY",
11401
+ "The shell command is destructive enough that Avorelo blocks it by default.",
11402
+ ["DESTRUCTIVE_SHELL_COMMAND"],
11403
+ "Use a safer command or get the destructive step handled outside the automated flow."
11404
+ );
11405
+ }
11406
+ if (ctx.dependencyInstallRequested || DEPENDENCY_INSTALL_RE.test(ctx.command)) {
11407
+ if (ctx.userApproved) {
11408
+ return buildTrigger(
11409
+ "dependency_install_approval",
11410
+ point,
11411
+ "ALLOW",
11412
+ "The dependency install had explicit approval.",
11413
+ ["DEPENDENCY_INSTALL_APPROVED"],
11414
+ null
11415
+ );
11416
+ }
11417
+ return buildTrigger(
11418
+ "dependency_install_approval",
11419
+ point,
11420
+ "ASK",
11421
+ "Dependency installation is paused until the user explicitly approves it.",
11422
+ ["DEPENDENCY_INSTALL_APPROVAL_REQUIRED"],
11423
+ "Approve the dependency install, or use the existing lockfile and local dependencies only."
11424
+ );
11425
+ }
11426
+ if (RISKY_SHELL_RE.test(ctx.command)) {
11427
+ if (ctx.userApproved) {
11428
+ return buildTrigger(
11429
+ "shell_command_approval",
11430
+ point,
11431
+ "ALLOW",
11432
+ "The risky shell command had explicit approval.",
11433
+ ["SHELL_COMMAND_APPROVED"],
11434
+ null
11435
+ );
11436
+ }
11437
+ return buildTrigger(
11438
+ "shell_command_approval",
11439
+ point,
11440
+ "ASK",
11441
+ "This shell command can change external or release state and needs explicit approval.",
11442
+ ["SHELL_COMMAND_APPROVAL_REQUIRED"],
11443
+ "Approve the shell command before continuing."
11444
+ );
11445
+ }
11446
+ return null;
11447
+ }
11448
+ function evaluateFileWrite(point, ctx) {
11449
+ if (point !== "before_file_write" || !ctx.sensitiveFilePath) return null;
11450
+ if (ctx.userApproved) {
11451
+ return buildTrigger(
11452
+ "file_write_approval",
11453
+ point,
11454
+ "ALLOW",
11455
+ "The sensitive file write had explicit approval.",
11456
+ ["FILE_WRITE_APPROVED"],
11457
+ null
11458
+ );
11459
+ }
11460
+ return buildTrigger(
11461
+ "file_write_approval",
11462
+ point,
11463
+ "ASK",
11464
+ "This write touches a sensitive surface and needs confirmation first.",
11465
+ ["SENSITIVE_FILE_WRITE_APPROVAL_REQUIRED"],
11466
+ "Approve the write or narrow the task to a non-sensitive path."
11467
+ );
11468
+ }
11469
+ function evaluateRelease(point, ctx) {
11470
+ if (point === "before_task_start" && ctx.productionImpact) {
11471
+ if (ctx.adminApproved || ctx.teamApproved) {
11472
+ return buildTrigger(
11473
+ "production_deploy_guard",
11474
+ point,
11475
+ "ALLOW",
11476
+ "The production-impacting task has stronger approval coverage.",
11477
+ ["PRODUCTION_APPROVED"],
11478
+ null
11479
+ );
11480
+ }
11481
+ return buildTrigger(
11482
+ "production_deploy_guard",
11483
+ point,
11484
+ "ESCALATE",
11485
+ "Production-impacting work needs stronger approval than a normal ASK.",
11486
+ ["PRODUCTION_ESCALATION_REQUIRED"],
11487
+ "Get stronger approval before changing production-facing state."
11488
+ );
11489
+ }
11490
+ if (point === "before_package_publish" || point === "before_release_tag") {
11491
+ if (ctx.userApproved) {
11492
+ return buildTrigger(
11493
+ "release_guard",
11494
+ point,
11495
+ "ALLOW",
11496
+ "The release step has explicit approval.",
11497
+ ["RELEASE_APPROVED"],
11498
+ null
11499
+ );
11500
+ }
11501
+ return buildTrigger(
11502
+ "release_guard",
11503
+ point,
11504
+ "ASK",
11505
+ "Package publish and release tagging stay paused until explicitly approved.",
11506
+ ["RELEASE_APPROVAL_REQUIRED"],
11507
+ "Approve the release step before continuing."
11508
+ );
11509
+ }
11510
+ if (point === "before_production_deploy") {
11511
+ if (ctx.adminApproved || ctx.teamApproved) {
11512
+ return buildTrigger(
11513
+ "production_deploy_guard",
11514
+ point,
11515
+ "ALLOW",
11516
+ "The production deploy has stronger approval coverage.",
11517
+ ["PRODUCTION_APPROVED"],
11518
+ null
11519
+ );
11520
+ }
11521
+ return buildTrigger(
11522
+ "production_deploy_guard",
11523
+ point,
11524
+ "ESCALATE",
11525
+ "Production deploys need stronger approval than a normal ASK.",
11526
+ ["PRODUCTION_ESCALATION_REQUIRED"],
11527
+ "Get the stronger production approval before deploying."
11528
+ );
11529
+ }
11530
+ return null;
11531
+ }
11532
+ function evaluateProof(point, ctx) {
11533
+ if (point !== "after_agent_claims_done" && point !== "before_receipt_finalize" && point !== "before_test_claim") return null;
11534
+ if (!ctx.agentClaimsDone) return null;
11535
+ if (hasProof(ctx)) {
11536
+ return buildTrigger(
11537
+ "proof_required_before_done",
11538
+ point,
11539
+ "ALLOW",
11540
+ "Outcome and post-action evidence are present, so the done claim can stand.",
11541
+ ["PROOF_PRESENT"],
11542
+ null
11543
+ );
11544
+ }
11545
+ return buildTrigger(
11546
+ "proof_required_before_done",
11547
+ point,
11548
+ "REQUIRE_PROOF",
11549
+ "The agent claimed done before outcome and post-action proof existed.",
11550
+ ["PROOF_REQUIRED_BEFORE_DONE"],
11551
+ "Run the missing verification and attach outcome plus post-action evidence before marking done."
11552
+ );
11553
+ }
11554
+ function evaluateModelWorthiness(point, ctx) {
11555
+ if (point !== "before_task_start") return null;
11556
+ if (!ctx.expensiveModelRequested || !ctx.taskSeemsTrivial) return null;
11557
+ return buildTrigger(
11558
+ "model_worthiness_guard",
11559
+ point,
11560
+ "WARN",
11561
+ "This task looks trivial relative to the requested review depth.",
11562
+ ["MODEL_WORTHINESS_WARN"],
11563
+ "Use a lighter-weight path unless deeper review is actually needed."
11564
+ );
11565
+ }
11566
+ function finalVerdict(triggers) {
11567
+ if (triggers.length === 0) return "NOOP";
11568
+ for (const verdict of VERDICT_PRECEDENCE) {
11569
+ if (triggers.some((trigger) => trigger.verdict === verdict)) return verdict;
11570
+ }
11571
+ return "NOOP";
11572
+ }
11573
+ function listWorkControls() {
11574
+ return BUILTIN_CONTROLS.map((control) => ({ ...control, enforcementPoints: [...control.enforcementPoints], packaging: { ...control.packaging }, dataPersisted: [...control.dataPersisted], testsRequired: [...control.testsRequired] }));
11575
+ }
11576
+ function getWorkControl(controlId) {
11577
+ const found = CONTROL_BY_ID.get(controlId);
11578
+ if (!found) return null;
11579
+ return {
11580
+ ...found,
11581
+ enforcementPoints: [...found.enforcementPoints],
11582
+ packaging: { ...found.packaging },
11583
+ dataPersisted: [...found.dataPersisted],
11584
+ testsRequired: [...found.testsRequired]
11585
+ };
11586
+ }
11587
+ function evaluateWorkControls(enforcementPoint, ctx) {
11588
+ const triggers = [
11589
+ evaluateSecretsGuard(enforcementPoint, ctx),
11590
+ evaluateScopeGuard(enforcementPoint, ctx),
11591
+ evaluateRiskyActionApproval(enforcementPoint, ctx),
11592
+ evaluateShellCommand(enforcementPoint, ctx),
11593
+ evaluateFileWrite(enforcementPoint, ctx),
11594
+ evaluateRelease(enforcementPoint, ctx),
11595
+ evaluateProof(enforcementPoint, ctx),
11596
+ evaluateModelWorthiness(enforcementPoint, ctx)
11597
+ ].filter((trigger) => trigger !== null);
11598
+ const verdict = finalVerdict(triggers);
11599
+ const reasonCodes = Array.from(new Set(triggers.flatMap((trigger) => trigger.reasonCodes)));
11600
+ const safeNextActions = Array.from(new Set(triggers.map((trigger) => trigger.nextAction).filter((value) => typeof value === "string" && value.length > 0)));
11601
+ const blockingTrigger = triggers.find((trigger) => trigger.verdict === verdict) ?? null;
11602
+ return {
11603
+ enforcementPoint,
11604
+ finalVerdict: verdict,
11605
+ finalReason: blockingTrigger?.reason ?? "No relevant work control fired.",
11606
+ reasonCodes,
11607
+ approvalRequired: triggers.some((trigger) => trigger.verdict === "ASK" || trigger.verdict === "ESCALATE"),
11608
+ proofRequired: triggers.some((trigger) => trigger.verdict === "REQUIRE_PROOF"),
11609
+ triggers,
11610
+ safeNextActions,
11611
+ deterministic: true
11612
+ };
11613
+ }
11614
+
11615
+ // src/avorelo/capabilities/runtime-flow/index.ts
10987
11616
  function runtimeDir(dir) {
10988
11617
  return join39(dir, ".avorelo", "runtime");
10989
11618
  }
@@ -11018,6 +11647,22 @@ function safeFallbackProjection(reasonCodes, extraVerifierPlan = []) {
11018
11647
  containsRawSecret: false
11019
11648
  };
11020
11649
  }
11650
+ function toRuntimeWorkControls(evaluation) {
11651
+ return {
11652
+ enforcementPoint: evaluation.enforcementPoint,
11653
+ finalVerdict: evaluation.finalVerdict,
11654
+ finalReason: evaluation.finalReason,
11655
+ reasonCodes: evaluation.reasonCodes,
11656
+ approvalRequired: evaluation.approvalRequired,
11657
+ proofRequired: evaluation.proofRequired,
11658
+ triggeredControls: evaluation.triggers.map((trigger) => ({
11659
+ controlId: trigger.controlId,
11660
+ verdict: trigger.verdict,
11661
+ reasonCodes: trigger.reasonCodes
11662
+ })),
11663
+ safeNextActions: evaluation.safeNextActions
11664
+ };
11665
+ }
11021
11666
  function freshRuntimeId(seed) {
11022
11667
  return "rts_" + createHash12("sha256").update(seed).digest("hex").slice(0, 12);
11023
11668
  }
@@ -11082,6 +11727,20 @@ function runRuntimeSession(input) {
11082
11727
  const routing = decideRouting({ task, dir, planTier });
11083
11728
  const c = routing.contract;
11084
11729
  const displayTask = routing.displayTask;
11730
+ const taskStartControls = evaluateWorkControls("before_task_start", {
11731
+ task: displayTask,
11732
+ planTier,
11733
+ route: c.route,
11734
+ riskClass: c.riskClass,
11735
+ proofTier: c.proofTier,
11736
+ approvalPolicy: c.approvalPolicy,
11737
+ safeRunDecision: c.safetyBoundary.safeRunDecision,
11738
+ secretRiskCodes: c.safetyBoundary.secretRiskCodes,
11739
+ userApproved: routing.gate === "allow",
11740
+ productionImpact: /deploy|release|publish|production|prod/i.test(displayTask),
11741
+ taskSeemsTrivial: c.route === "deterministic_only" && c.riskClass === "low",
11742
+ expensiveModelRequested: c.route === "deep_reasoning_required"
11743
+ });
11085
11744
  const layers = [{
11086
11745
  order: 1,
11087
11746
  layer: "safety_and_routing",
@@ -11109,6 +11768,7 @@ function runRuntimeSession(input) {
11109
11768
  safeRunDecision: c.safetyBoundary.safeRunDecision,
11110
11769
  secretRiskCodes: c.safetyBoundary.secretRiskCodes ?? []
11111
11770
  },
11771
+ workControls: toRuntimeWorkControls(taskStartControls),
11112
11772
  layers,
11113
11773
  redacted: true,
11114
11774
  containsRawSecret: false,
@@ -11653,7 +12313,7 @@ function writeRuntimeSession(dir, record) {
11653
12313
  }
11654
12314
  function loadLatestRuntimeSession(dir) {
11655
12315
  const path = join39(runtimeDir(dir), "session.latest.json");
11656
- if (!existsSync38(path)) return null;
12316
+ if (!existsSync39(path)) return null;
11657
12317
  try {
11658
12318
  return JSON.parse(readFileSync23(path, "utf8"));
11659
12319
  } catch {
@@ -11673,6 +12333,8 @@ function buildRuntimeSessionSyncMetadata(record) {
11673
12333
  riskClass: record.riskClass,
11674
12334
  proofTier: record.proofTier,
11675
12335
  approvalPolicy: record.approvalPolicy,
12336
+ workControlVerdict: record.workControls.finalVerdict,
12337
+ workControlTriggerCount: record.workControls.triggeredControls.length,
11676
12338
  layerStatuses,
11677
12339
  secretRiskCodes: record.safetyBoundary.secretRiskCodes,
11678
12340
  canShowSavings: record.proof?.canShowSavings ?? false,
@@ -11688,6 +12350,8 @@ function validateRuntimeSession(record) {
11688
12350
  if (record.containsRawSecret !== false) reasons.push("contains_raw_secret");
11689
12351
  if (record.containsRawPrompt !== false) reasons.push("contains_raw_prompt");
11690
12352
  if (record.containsRawSourceDump !== false) reasons.push("contains_raw_source_dump");
12353
+ if (!record.workControls) reasons.push("work_controls_missing");
12354
+ else if (record.workControls.finalVerdict === "REQUIRE_PROOF" && record.gate === "allow") reasons.push("proof_required_task_started");
11691
12355
  if (record.gate === "blocked" && (record.session || record.context || record.continuity || record.tokenCost || record.proof || record.value || record.efficiencySync)) {
11692
12356
  reasons.push("blocked_gate_ran_downstream");
11693
12357
  }
@@ -11778,6 +12442,18 @@ function buildControlCenter(dir, opts) {
11778
12442
  } : { status: "unavailable" };
11779
12443
  if (runtime) sources.push(avoreloPath(dir, "runtime", "session.latest.json"));
11780
12444
  else notes.push('No runtime session yet \u2014 run `avorelo run "<task>"` to create one.');
12445
+ const workControlsSection = runtime?.workControls ? {
12446
+ status: "available",
12447
+ enforcementPoint: runtime.workControls.enforcementPoint,
12448
+ finalVerdict: runtime.workControls.finalVerdict,
12449
+ approvalRequired: runtime.workControls.approvalRequired,
12450
+ proofRequired: runtime.workControls.proofRequired,
12451
+ triggeredCount: runtime.workControls.triggeredControls.length,
12452
+ controls: runtime.workControls.triggeredControls.map((control) => ({
12453
+ controlId: control.controlId,
12454
+ verdict: control.verdict
12455
+ }))
12456
+ } : { status: "unavailable" };
11781
12457
  const contextPackSection = runtime?.contextPack ? {
11782
12458
  status: "available",
11783
12459
  contextPackId: runtime.contextPack.contextPackId,
@@ -11836,7 +12512,7 @@ function buildControlCenter(dir, opts) {
11836
12512
  let contextCheckSection = { status: "unavailable" };
11837
12513
  try {
11838
12514
  const ccPath = avoreloPath(dir, "context-check", "latest.json");
11839
- if (existsSync39(ccPath)) {
12515
+ if (existsSync40(ccPath)) {
11840
12516
  const raw = JSON.parse(readFileSync24(ccPath, "utf8"));
11841
12517
  contextCheckSection = {
11842
12518
  status: "available",
@@ -11945,6 +12621,7 @@ function buildControlCenter(dir, opts) {
11945
12621
  workspace: dir,
11946
12622
  sections: {
11947
12623
  runtimeSession: runtimeSection,
12624
+ workControls: workControlsSection,
11948
12625
  contextPack: contextPackSection,
11949
12626
  proof: proofSection,
11950
12627
  value: valueSection,
@@ -11979,6 +12656,7 @@ function renderText2(m) {
11979
12656
  } else {
11980
12657
  lines.push(" Runtime: none yet");
11981
12658
  }
12659
+ lines.push(` Controls: ${s.workControls.status === "available" ? `${s.workControls.finalVerdict} at ${s.workControls.enforcementPoint} \xB7 approval=${s.workControls.approvalRequired} \xB7 proof=${s.workControls.proofRequired} \xB7 triggers=${s.workControls.triggeredCount}` : "none"}`);
11982
12660
  lines.push(` Ctx pack: ${s.contextPack.status === "available" ? `${s.contextPack.contextPackId} \xB7 consumer=${s.contextPack.consumer} adapter=${s.contextPack.selectedAdapter} \xB7 refs=${s.contextPack.allowedCount}/${s.contextPack.forbiddenCount} blocked \xB7 budget=${s.contextPack.budget} used=${s.contextPack.contextBudgetUsed} \xB7 tags=${s.contextPack.provenanceTagCount}` : "none"}`);
11983
12661
  lines.push(` Proof: ${s.proof.status === "available" ? `${s.proof.reportId} \xB7 savings ${s.proof.canShowSavings ? "shown" : `not claimed (${s.proof.savingsRefusalReason ?? "no_comparative_evidence"})`}` : "none"}`);
11984
12662
  lines.push(` Token/cost:${s.costEvidence.status === "available" ? ` ${s.costEvidence.confidence} \xB7 costSummary=${s.costEvidence.canShowCostSummary} \xB7 ${s.costEvidence.evidenceCount} item(s)` : " none"}`);
@@ -12046,6 +12724,7 @@ function renderHtml2(m) {
12046
12724
  <h1>Avorelo \u2014 Local Control Center</h1>
12047
12725
  <table>
12048
12726
  ${row("Runtime", s.runtimeSession.status === "available" ? `${esc2(s.runtimeSession.sessionStatus)} \xB7 gate=${esc2(s.runtimeSession.gate)} route=${esc2(s.runtimeSession.route)} risk=${esc2(s.runtimeSession.riskClass)} proof=${esc2(s.runtimeSession.proofTier)}<div>${layers}</div>` : '<span class="muted">none yet</span>')}
12727
+ ${row("Controls", s.workControls.status === "available" ? `${esc2(s.workControls.finalVerdict)} \xB7 point=${esc2(s.workControls.enforcementPoint)} \xB7 approval=${esc2(s.workControls.approvalRequired)} \xB7 proof=${esc2(s.workControls.proofRequired)} \xB7 triggers=${esc2(s.workControls.triggeredCount)}${(s.workControls.controls ?? []).length ? `<div class="muted">${(s.workControls.controls ?? []).map((c) => `${esc2(c.controlId)}=${esc2(c.verdict)}`).join(" \xB7 ")}</div>` : ""}` : '<span class="muted">none</span>')}
12049
12728
  ${row("Ctx pack", s.contextPack.status === "available" ? `${esc2(s.contextPack.contextPackId)} \xB7 consumer=${esc2(s.contextPack.consumer)} adapter=${esc2(s.contextPack.selectedAdapter)} \xB7 refs=${esc2(s.contextPack.allowedCount)}/${esc2(s.contextPack.forbiddenCount)} blocked \xB7 budget=${esc2(s.contextPack.budget)} used=${esc2(s.contextPack.contextBudgetUsed)} \xB7 tags=${esc2(s.contextPack.provenanceTagCount)}` : '<span class="muted">none</span>')}
12050
12729
  ${row("Proof", s.proof.status === "available" ? `${esc2(s.proof.reportId)} \xB7 savings ${s.proof.canShowSavings ? "shown" : `<b>not claimed</b> (${esc2(s.proof.savingsRefusalReason ?? "no_comparative_evidence")})`}` : '<span class="muted">none</span>')}
12051
12730
  ${row("Token/cost", s.costEvidence.status === "available" ? `${esc2(s.costEvidence.confidence)} \xB7 costSummary=${esc2(s.costEvidence.canShowCostSummary)} \xB7 ${esc2(s.costEvidence.evidenceCount)} item(s)` : '<span class="muted">none</span>')}
@@ -12071,7 +12750,7 @@ function openControlCenter(dir, opts) {
12071
12750
 
12072
12751
  // src/avorelo/capabilities/activation/init.ts
12073
12752
  import { createHash as createHash13, randomUUID as randomUUID4 } from "node:crypto";
12074
- import { existsSync as existsSync40, mkdirSync as mkdirSync26, writeFileSync as writeFileSync25, readFileSync as readFileSync25, statSync as statSync4, accessSync, constants } from "node:fs";
12753
+ import { existsSync as existsSync41, mkdirSync as mkdirSync26, writeFileSync as writeFileSync25, readFileSync as readFileSync25, statSync as statSync4, accessSync, constants } from "node:fs";
12075
12754
  import { join as join41 } from "node:path";
12076
12755
  var ACTIVATION_V1_CONTRACT = "avorelo.activation.v1";
12077
12756
  var WORKSPACE_V1_CONTRACT = "avorelo.workspace.v1";
@@ -12089,7 +12768,7 @@ function freshActivationId(seed) {
12089
12768
  }
12090
12769
  function loadWorkspace(dir) {
12091
12770
  const p = workspacePath(dir);
12092
- if (!existsSync40(p)) return null;
12771
+ if (!existsSync41(p)) return null;
12093
12772
  try {
12094
12773
  const w = JSON.parse(readFileSync25(p, "utf8"));
12095
12774
  return w.contract === WORKSPACE_V1_CONTRACT && typeof w.workspaceId === "string" ? w : null;
@@ -12114,9 +12793,9 @@ function buildActivationContract(dir, opts) {
12114
12793
  } catch {
12115
12794
  packageManager = null;
12116
12795
  }
12117
- const packageDetected = existsSync40(join41(dir, "package.json"));
12796
+ const packageDetected = existsSync41(join41(dir, "package.json"));
12118
12797
  const repoDetected = packageDetected || gitDetected;
12119
- const avoreloDirReady = existsSync40(avoreloDir(dir));
12798
+ const avoreloDirReady = existsSync41(avoreloDir(dir));
12120
12799
  const initialized = !!existing;
12121
12800
  const firstRunRecommended = !initialized ? { command: `avorelo init --target ${dir}`, reason: "Initialize the local Avorelo workspace first." } : { command: `avorelo run "run tests" --target ${dir}`, reason: "Run your first focused task; Avorelo saves proof locally." };
12122
12801
  const limitations = [
@@ -12151,7 +12830,7 @@ function buildActivationContract(dir, opts) {
12151
12830
  function initWorkspace(dir, opts) {
12152
12831
  const now = opts?.now ?? Date.now();
12153
12832
  try {
12154
- if (!existsSync40(dir)) return { ok: false, created: false, reason: "target_does_not_exist" };
12833
+ if (!existsSync41(dir)) return { ok: false, created: false, reason: "target_does_not_exist" };
12155
12834
  if (!statSync4(dir).isDirectory()) return { ok: false, created: false, reason: "target_not_a_directory" };
12156
12835
  } catch {
12157
12836
  return { ok: false, created: false, reason: "target_not_accessible" };
@@ -12291,11 +12970,11 @@ function renderDogfoodCheck(r2) {
12291
12970
 
12292
12971
  // src/avorelo/capabilities/core-readiness/index.ts
12293
12972
  import { createHash as createHash15 } from "node:crypto";
12294
- import { existsSync as existsSync42, readFileSync as readFileSync27 } from "node:fs";
12973
+ import { existsSync as existsSync43, readFileSync as readFileSync27 } from "node:fs";
12295
12974
  import { join as join43 } from "node:path";
12296
12975
 
12297
12976
  // src/avorelo/capabilities/canonical-readiness/index.ts
12298
- import { existsSync as existsSync41, readFileSync as readFileSync26, readdirSync as readdirSync11, statSync as statSync5 } from "node:fs";
12977
+ import { existsSync as existsSync42, readFileSync as readFileSync26, readdirSync as readdirSync11, statSync as statSync5 } from "node:fs";
12299
12978
  import { join as join42 } from "node:path";
12300
12979
  import { createHash as createHash14 } from "node:crypto";
12301
12980
  var FORBIDDEN_CLAIM_PATTERNS = [
@@ -12380,7 +13059,7 @@ var OLD_CAP_SPECS = [
12380
13059
  { capability: "Seamless Model & Primitive Routing", evidence: ["src/avorelo/kernel/model-routing/index.ts", "src/avorelo/kernel/model-routing/resolver.ts", "src/avorelo/kernel/model-routing/verifier.ts"], status: "adapted", notes: ["Phase 10; deterministic-first cascade, upgrade-only session memory, safety-verified projections"] }
12381
13060
  ];
12382
13061
  function has(root, rel) {
12383
- return existsSync41(join42(root, rel));
13062
+ return existsSync42(join42(root, rel));
12384
13063
  }
12385
13064
  function read(root, rel) {
12386
13065
  try {
@@ -12392,7 +13071,7 @@ function read(root, rel) {
12392
13071
  function walkFiles(root, rel, exts) {
12393
13072
  const out = [];
12394
13073
  const base = join42(root, rel);
12395
- if (!existsSync41(base)) return out;
13074
+ if (!existsSync42(base)) return out;
12396
13075
  const rec = (dir) => {
12397
13076
  for (const name of readdirSync11(dir)) {
12398
13077
  const p = join42(dir, name);
@@ -12536,7 +13215,7 @@ function repoRoot() {
12536
13215
  return join43(import.meta.dirname, "..", "..", "..", "..");
12537
13216
  }
12538
13217
  function has2(root, rel) {
12539
- return existsSync42(join43(root, rel));
13218
+ return existsSync43(join43(root, rel));
12540
13219
  }
12541
13220
  function buildCoreReadiness(opts) {
12542
13221
  const now = opts?.now ?? Date.now();
@@ -12843,18 +13522,18 @@ init_stop_continue_gate();
12843
13522
  init_state_ledger();
12844
13523
  init_receipts();
12845
13524
  init_redaction();
12846
- import { readFileSync as readFileSync28, existsSync as existsSync43, statSync as statSync6 } from "node:fs";
13525
+ import { readFileSync as readFileSync28, existsSync as existsSync44, statSync as statSync6 } from "node:fs";
12847
13526
  import { execFileSync as execFileSync2 } from "node:child_process";
12848
13527
  function readBack(dir, check) {
12849
13528
  const id = check.artifactId ?? `sot_${check.kind}`;
12850
13529
  const resolve5 = (p) => p.startsWith("/") || /^[A-Za-z]:/.test(p) ? p : `${dir}/${p}`;
12851
13530
  try {
12852
13531
  if (check.kind === "file_absent") {
12853
- const passed2 = !existsSync43(resolve5(check.path));
13532
+ const passed2 = !existsSync44(resolve5(check.path));
12854
13533
  return { artifact: passed2 ? { artifactId: id, kind: "source_of_truth_readback", ref: `sot:absent:${check.path}` } : null, passed: passed2, reasonCode: passed2 ? "READBACK_ABSENT_OK" : "READBACK_UNEXPECTEDLY_PRESENT", check };
12855
13534
  }
12856
13535
  const p = resolve5(check.path);
12857
- if (!existsSync43(p)) return { artifact: null, passed: false, reasonCode: "READBACK_FILE_MISSING", check };
13536
+ if (!existsSync44(p)) return { artifact: null, passed: false, reasonCode: "READBACK_FILE_MISSING", check };
12858
13537
  const actual = readFileSync28(p, "utf8");
12859
13538
  const passed = check.kind === "file_equals" ? actual.trim() === check.expected.trim() : actual.includes(check.expected);
12860
13539
  return { artifact: passed ? { artifactId: id, kind: "source_of_truth_readback", ref: `sot:${check.kind}:${check.path}` } : null, passed, reasonCode: passed ? "READBACK_MATCH" : "READBACK_MISMATCH", check };
@@ -12877,7 +13556,7 @@ function checkEnvironmentIntegrity(dir, signals) {
12877
13556
  if (signals?.staleProcess) reasonCodes.push("STALE_PROCESS");
12878
13557
  return { compromised: reasonCodes.length > 0, reasonCodes };
12879
13558
  }
12880
- function evaluateProof(input) {
13559
+ function evaluateProof2(input) {
12881
13560
  const declared = input.artifacts ?? [];
12882
13561
  const readbacks = (input.readbacks ?? []).map((c) => readBack(input.dir, c));
12883
13562
  const readbackArtifacts = readbacks.map((r2) => r2.artifact).filter((a) => a !== null);
@@ -12918,7 +13597,7 @@ function evaluateProof(input) {
12918
13597
  }
12919
13598
  function loadProofInput(dir) {
12920
13599
  const p = `${dir}/.avorelo/proof-input.json`;
12921
- if (!existsSync43(p)) return null;
13600
+ if (!existsSync44(p)) return null;
12922
13601
  try {
12923
13602
  return JSON.parse(readFileSync28(p, "utf8"));
12924
13603
  } catch {
@@ -12927,17 +13606,18 @@ function loadProofInput(dir) {
12927
13606
  }
12928
13607
 
12929
13608
  // src/avorelo/surfaces/public-web/index.ts
12930
- import { mkdirSync as mkdirSync27, copyFileSync as copyFileSync2, readdirSync as readdirSync12, existsSync as existsSync44 } from "node:fs";
13609
+ import { mkdirSync as mkdirSync27, copyFileSync as copyFileSync2, readdirSync as readdirSync12, existsSync as existsSync45 } from "node:fs";
12931
13610
  import { join as join44, dirname as dirname5 } from "node:path";
12932
13611
  import { fileURLToPath as fileURLToPath2 } from "node:url";
12933
13612
  var __dirname = dirname5(fileURLToPath2(import.meta.url));
12934
13613
  var STATIC_DIR = join44(__dirname, "static");
12935
13614
  function buildSite(outDir) {
12936
13615
  mkdirSync27(outDir, { recursive: true });
12937
- if (!existsSync44(STATIC_DIR)) {
13616
+ if (!existsSync45(STATIC_DIR)) {
12938
13617
  return { ok: false, outDir, pages: [], indexPath: "" };
12939
13618
  }
12940
- const files = readdirSync12(STATIC_DIR).filter((f) => /\.(html|js|css|png|svg|ico|json|txt|xml|webmanifest)$/.test(f));
13619
+ const NETLIFY_FILES = ["_redirects", "_headers"];
13620
+ const files = readdirSync12(STATIC_DIR).filter((f) => /\.(html|js|css|png|svg|ico|json|txt|xml|webmanifest)$/.test(f) || NETLIFY_FILES.includes(f));
12941
13621
  for (const f of files) {
12942
13622
  copyFileSync2(join44(STATIC_DIR, f), join44(outDir, f));
12943
13623
  }
@@ -12951,7 +13631,7 @@ function buildSite(outDir) {
12951
13631
 
12952
13632
  // src/avorelo/surfaces/preview-server/index.ts
12953
13633
  import { createServer } from "node:http";
12954
- import { readFileSync as readFileSync29, existsSync as existsSync45, statSync as statSync7 } from "node:fs";
13634
+ import { readFileSync as readFileSync29, existsSync as existsSync46, statSync as statSync7 } from "node:fs";
12955
13635
  import { join as join45, normalize, extname, sep as sep4 } from "node:path";
12956
13636
  var MIME = {
12957
13637
  ".html": "text/html; charset=utf-8",
@@ -12971,7 +13651,7 @@ function resolveRequestPath(root, urlPath) {
12971
13651
  const abs = normalize(join45(rootNorm, candidate));
12972
13652
  if (abs !== rootNorm && !abs.startsWith(rootNorm.endsWith(sep4) ? rootNorm : rootNorm + sep4)) return null;
12973
13653
  try {
12974
- if (!existsSync45(abs) || !statSync7(abs).isFile()) return null;
13654
+ if (!existsSync46(abs) || !statSync7(abs).isFile()) return null;
12975
13655
  } catch {
12976
13656
  return null;
12977
13657
  }
@@ -13486,12 +14166,12 @@ init_resume_packet();
13486
14166
  init_registry();
13487
14167
 
13488
14168
  // src/avorelo/capabilities/update-notice/index.ts
13489
- import { existsSync as existsSync46, readFileSync as readFileSync30, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28 } from "node:fs";
14169
+ import { existsSync as existsSync47, readFileSync as readFileSync30, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28 } from "node:fs";
13490
14170
  import { join as join46, dirname as dirname6 } from "node:path";
13491
14171
  var STATE_PATH = ".avorelo/notice-state.json";
13492
14172
  function readNoticeState(dir) {
13493
14173
  const filePath = join46(dir, STATE_PATH);
13494
- if (!existsSync46(filePath)) {
14174
+ if (!existsSync47(filePath)) {
13495
14175
  return { lastSeenVersion: "", dismissedVersions: [], quietMode: false, lastCheckedAt: "" };
13496
14176
  }
13497
14177
  try {
@@ -13503,7 +14183,7 @@ function readNoticeState(dir) {
13503
14183
  function writeNoticeState(dir, state) {
13504
14184
  const filePath = join46(dir, STATE_PATH);
13505
14185
  const d = dirname6(filePath);
13506
- if (!existsSync46(d)) mkdirSync28(d, { recursive: true });
14186
+ if (!existsSync47(d)) mkdirSync28(d, { recursive: true });
13507
14187
  writeFileSync26(filePath, JSON.stringify(state, null, 2));
13508
14188
  }
13509
14189
  function getCurrentVersion() {
@@ -13559,7 +14239,7 @@ function getNoticeState(dir) {
13559
14239
  }
13560
14240
 
13561
14241
  // src/avorelo/capabilities/registry-freshness/index.ts
13562
- import { existsSync as existsSync47, readFileSync as readFileSync31, writeFileSync as writeFileSync27, mkdirSync as mkdirSync29 } from "node:fs";
14242
+ import { existsSync as existsSync48, readFileSync as readFileSync31, writeFileSync as writeFileSync27, mkdirSync as mkdirSync29 } from "node:fs";
13563
14243
  import { join as join47, dirname as dirname7 } from "node:path";
13564
14244
  var REGISTRY_FRESHNESS_CONTRACT = "avorelo.registryFreshness.v1";
13565
14245
  var CACHE_FILE = ".avorelo/registry-freshness-cache.json";
@@ -13591,7 +14271,7 @@ function isSuppressed() {
13591
14271
  }
13592
14272
  function readCache(dir) {
13593
14273
  const p = join47(dir, CACHE_FILE);
13594
- if (!existsSync47(p)) return null;
14274
+ if (!existsSync48(p)) return null;
13595
14275
  try {
13596
14276
  return JSON.parse(readFileSync31(p, "utf8"));
13597
14277
  } catch {
@@ -13695,10 +14375,10 @@ init_drift_detector();
13695
14375
  init_intervention();
13696
14376
  import { readdirSync as readdirSync13, statSync as statSync9 } from "node:fs";
13697
14377
  import { join as join48, relative as relative2 } from "node:path";
13698
- import { execSync as execSync2 } from "node:child_process";
14378
+ import { execSync as execSync3 } from "node:child_process";
13699
14379
  function getGitChangedFiles(dir) {
13700
14380
  try {
13701
- const out = execSync2("git diff --name-only", { cwd: dir, stdio: "pipe", timeout: 5e3 }).toString().trim();
14381
+ const out = execSync3("git diff --name-only", { cwd: dir, stdio: "pipe", timeout: 5e3 }).toString().trim();
13702
14382
  if (!out) return [];
13703
14383
  return out.split("\n").map((f) => f.trim()).filter(Boolean);
13704
14384
  } catch {
@@ -13707,7 +14387,7 @@ function getGitChangedFiles(dir) {
13707
14387
  }
13708
14388
  function getGitUntrackedFiles(dir) {
13709
14389
  try {
13710
- const out = execSync2("git ls-files --others --exclude-standard", { cwd: dir, stdio: "pipe", timeout: 5e3 }).toString().trim();
14390
+ const out = execSync3("git ls-files --others --exclude-standard", { cwd: dir, stdio: "pipe", timeout: 5e3 }).toString().trim();
13711
14391
  if (!out) return [];
13712
14392
  return out.split("\n").map((f) => f.trim()).filter(Boolean);
13713
14393
  } catch {
@@ -13833,7 +14513,7 @@ function watchWithFixture(dir, fixture) {
13833
14513
  }
13834
14514
 
13835
14515
  // src/avorelo/capabilities/workspace/monorepo.ts
13836
- import { existsSync as existsSync49, readFileSync as readFileSync33, readdirSync as readdirSync14, statSync as statSync10 } from "node:fs";
14516
+ import { existsSync as existsSync50, readFileSync as readFileSync33, readdirSync as readdirSync14, statSync as statSync10 } from "node:fs";
13837
14517
  import { join as join49 } from "node:path";
13838
14518
  function expandGlobDirs(dir, patterns) {
13839
14519
  const results = [];
@@ -13841,16 +14521,16 @@ function expandGlobDirs(dir, patterns) {
13841
14521
  const clean = pattern.replace(/\/\*$/, "").replace(/\*$/, "");
13842
14522
  if (!clean) continue;
13843
14523
  const base = join49(dir, clean);
13844
- if (!existsSync49(base)) continue;
14524
+ if (!existsSync50(base)) continue;
13845
14525
  if (clean.includes("*")) continue;
13846
14526
  try {
13847
14527
  const stat = statSync10(base);
13848
14528
  if (stat.isDirectory()) {
13849
- if (existsSync49(join49(base, "package.json"))) {
14529
+ if (existsSync50(join49(base, "package.json"))) {
13850
14530
  results.push(base);
13851
14531
  } else {
13852
14532
  for (const entry of readdirSync14(base, { withFileTypes: true })) {
13853
- if (entry.isDirectory() && existsSync49(join49(base, entry.name, "package.json"))) {
14533
+ if (entry.isDirectory() && existsSync50(join49(base, entry.name, "package.json"))) {
13854
14534
  results.push(join49(base, entry.name));
13855
14535
  }
13856
14536
  }
@@ -13873,9 +14553,9 @@ function buildWorkspace(dir, wsPath) {
13873
14553
  name,
13874
14554
  path: wsPath,
13875
14555
  relativePath: rel,
13876
- hasPackageJson: existsSync49(join49(wsPath, "package.json")),
13877
- hasAgentsMd: existsSync49(join49(wsPath, "AGENTS.md")),
13878
- hasCursorRules: existsSync49(join49(wsPath, ".cursor"))
14556
+ hasPackageJson: existsSync50(join49(wsPath, "package.json")),
14557
+ hasAgentsMd: existsSync50(join49(wsPath, "AGENTS.md")),
14558
+ hasCursorRules: existsSync50(join49(wsPath, ".cursor"))
13879
14559
  };
13880
14560
  }
13881
14561
  function detectMonorepo(dir) {
@@ -13906,7 +14586,7 @@ function detectMonorepo(dir) {
13906
14586
  } catch {
13907
14587
  }
13908
14588
  const pnpmPath = join49(dir, "pnpm-workspace.yaml");
13909
- if (existsSync49(pnpmPath)) {
14589
+ if (existsSync50(pnpmPath)) {
13910
14590
  try {
13911
14591
  const content = readFileSync33(pnpmPath, "utf8");
13912
14592
  const match = content.match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);
@@ -13927,10 +14607,10 @@ function detectMonorepo(dir) {
13927
14607
  }
13928
14608
  for (const conventionDir of ["apps", "packages"]) {
13929
14609
  const convPath = join49(dir, conventionDir);
13930
- if (existsSync49(convPath)) {
14610
+ if (existsSync50(convPath)) {
13931
14611
  try {
13932
14612
  const entries = readdirSync14(convPath, { withFileTypes: true });
13933
- const workspacePaths = entries.filter((e) => e.isDirectory() && existsSync49(join49(convPath, e.name, "package.json"))).map((e) => join49(convPath, e.name));
14613
+ const workspacePaths = entries.filter((e) => e.isDirectory() && existsSync50(join49(convPath, e.name, "package.json"))).map((e) => join49(convPath, e.name));
13934
14614
  if (workspacePaths.length > 0) {
13935
14615
  return {
13936
14616
  isMonorepo: true,
@@ -13947,7 +14627,7 @@ function detectMonorepo(dir) {
13947
14627
  }
13948
14628
 
13949
14629
  // src/avorelo/capabilities/feedback/config.ts
13950
- import { existsSync as existsSync50, readFileSync as readFileSync34, writeFileSync as writeFileSync28, mkdirSync as mkdirSync30 } from "node:fs";
14630
+ import { existsSync as existsSync51, readFileSync as readFileSync34, writeFileSync as writeFileSync28, mkdirSync as mkdirSync30 } from "node:fs";
13951
14631
  import { join as join50, dirname as dirname8 } from "node:path";
13952
14632
  var CONFIG_PATH = ".avorelo/config.json";
13953
14633
  var DEFAULTS = {
@@ -13959,7 +14639,7 @@ var DEFAULTS = {
13959
14639
  };
13960
14640
  function readConfig(dir) {
13961
14641
  const p = join50(dir, CONFIG_PATH);
13962
- if (!existsSync50(p)) return {};
14642
+ if (!existsSync51(p)) return {};
13963
14643
  try {
13964
14644
  return JSON.parse(readFileSync34(p, "utf8"));
13965
14645
  } catch {
@@ -13990,9 +14670,9 @@ function optOut(dir) {
13990
14670
 
13991
14671
  // src/avorelo/capabilities/feedback/bundle.ts
13992
14672
  init_redaction();
13993
- import { existsSync as existsSync51, readFileSync as readFileSync35, writeFileSync as writeFileSync29, mkdirSync as mkdirSync31, readdirSync as readdirSync15 } from "node:fs";
14673
+ import { existsSync as existsSync52, readFileSync as readFileSync35, writeFileSync as writeFileSync29, mkdirSync as mkdirSync31, readdirSync as readdirSync15 } from "node:fs";
13994
14674
  import { join as join51 } from "node:path";
13995
- import { platform as platform2, release, arch } from "node:os";
14675
+ import { platform as platform3, release, arch } from "node:os";
13996
14676
  init_registry();
13997
14677
  init_session_store();
13998
14678
  function getVersion() {
@@ -14004,11 +14684,11 @@ function getVersion() {
14004
14684
  }
14005
14685
  }
14006
14686
  function detectPackageManager(dir) {
14007
- if (existsSync51(join51(dir, "pnpm-lock.yaml"))) return "pnpm";
14008
- if (existsSync51(join51(dir, "yarn.lock"))) return "yarn";
14009
- if (existsSync51(join51(dir, "bun.lockb"))) return "bun";
14010
- if (existsSync51(join51(dir, "package-lock.json"))) return "npm";
14011
- if (existsSync51(join51(dir, "package.json"))) return "npm";
14687
+ if (existsSync52(join51(dir, "pnpm-lock.yaml"))) return "pnpm";
14688
+ if (existsSync52(join51(dir, "yarn.lock"))) return "yarn";
14689
+ if (existsSync52(join51(dir, "bun.lockb"))) return "bun";
14690
+ if (existsSync52(join51(dir, "package-lock.json"))) return "npm";
14691
+ if (existsSync52(join51(dir, "package.json"))) return "npm";
14012
14692
  return null;
14013
14693
  }
14014
14694
  function detectFramework(dir) {
@@ -14029,7 +14709,7 @@ function detectFramework(dir) {
14029
14709
  }
14030
14710
  function countReceipts(dir) {
14031
14711
  const receiptsDir = join51(dir, ".avorelo", "receipts");
14032
- if (!existsSync51(receiptsDir)) return { total: 0, done: 0, blocked: 0, inProgress: 0 };
14712
+ if (!existsSync52(receiptsDir)) return { total: 0, done: 0, blocked: 0, inProgress: 0 };
14033
14713
  let done = 0, blocked = 0, inProgress = 0;
14034
14714
  try {
14035
14715
  for (const f of readdirSync15(receiptsDir).filter((f2) => f2.endsWith(".json"))) {
@@ -14056,7 +14736,7 @@ function prepareFeedbackBundle(dir) {
14056
14736
  bundleId: `fb_${Date.now().toString(36)}`,
14057
14737
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
14058
14738
  avorelo: { version: getVersion() },
14059
- platform: { os: platform2(), release: release(), arch: arch(), nodeVersion: process.version },
14739
+ platform: { os: platform3(), release: release(), arch: arch(), nodeVersion: process.version },
14060
14740
  workspace: {
14061
14741
  packageManager: detectPackageManager(dir),
14062
14742
  framework: detectFramework(dir),
@@ -14294,11 +14974,11 @@ function result(classification, risk, reasonCodes, humanGateConditions) {
14294
14974
  import { randomUUID as randomUUID6 } from "node:crypto";
14295
14975
 
14296
14976
  // src/avorelo/capabilities/loop-control/check-detection.ts
14297
- import { readFileSync as readFileSync36, existsSync as existsSync52 } from "node:fs";
14977
+ import { readFileSync as readFileSync36, existsSync as existsSync53 } from "node:fs";
14298
14978
  import { join as join52 } from "node:path";
14299
14979
  function detectFromPackageJson(cwd) {
14300
14980
  const pkgPath = join52(cwd, "package.json");
14301
- if (!existsSync52(pkgPath)) return [];
14981
+ if (!existsSync53(pkgPath)) return [];
14302
14982
  try {
14303
14983
  const pkg = JSON.parse(readFileSync36(pkgPath, "utf8"));
14304
14984
  const scripts = pkg.scripts ?? {};
@@ -14321,19 +15001,19 @@ function detectFromPackageJson(cwd) {
14321
15001
  }
14322
15002
  }
14323
15003
  function detectFromPython(cwd) {
14324
- if (existsSync52(join52(cwd, "pytest.ini")) || existsSync52(join52(cwd, "pyproject.toml")) || existsSync52(join52(cwd, "setup.py"))) {
15004
+ if (existsSync53(join52(cwd, "pytest.ini")) || existsSync53(join52(cwd, "pyproject.toml")) || existsSync53(join52(cwd, "setup.py"))) {
14325
15005
  return [{ checkId: "chk_pytest", label: "pytest", command: "python -m pytest", source: "python" }];
14326
15006
  }
14327
15007
  return [];
14328
15008
  }
14329
15009
  function detectFromGo(cwd) {
14330
- if (existsSync52(join52(cwd, "go.mod"))) {
15010
+ if (existsSync53(join52(cwd, "go.mod"))) {
14331
15011
  return [{ checkId: "chk_go_test", label: "go test", command: "go test ./...", source: "go.mod" }];
14332
15012
  }
14333
15013
  return [];
14334
15014
  }
14335
15015
  function detectFromRust(cwd) {
14336
- if (existsSync52(join52(cwd, "Cargo.toml"))) {
15016
+ if (existsSync53(join52(cwd, "Cargo.toml"))) {
14337
15017
  return [{ checkId: "chk_cargo_test", label: "cargo test", command: "cargo test", source: "Cargo.toml" }];
14338
15018
  }
14339
15019
  return [];
@@ -14573,7 +15253,7 @@ function detectIterationDrift(input) {
14573
15253
  }
14574
15254
 
14575
15255
  // src/avorelo/capabilities/loop-control/checks-runner.ts
14576
- import { execSync as execSync3 } from "node:child_process";
15256
+ import { execSync as execSync4 } from "node:child_process";
14577
15257
  var CHECK_TIMEOUT_MS = 12e4;
14578
15258
  var MAX_OUTPUT_LENGTH = 200;
14579
15259
  function truncateOutput(s) {
@@ -14589,7 +15269,7 @@ function runCheck(check, cwd) {
14589
15269
  return { ...check, lastResult: "skipped", lastOutput: "no command configured" };
14590
15270
  }
14591
15271
  try {
14592
- execSync3(check.command, {
15272
+ execSync4(check.command, {
14593
15273
  cwd,
14594
15274
  timeout: CHECK_TIMEOUT_MS,
14595
15275
  stdio: ["pipe", "pipe", "pipe"],
@@ -14606,10 +15286,10 @@ function runAllChecks(checks, cwd) {
14606
15286
  }
14607
15287
 
14608
15288
  // src/avorelo/capabilities/loop-control/git-observer.ts
14609
- import { execSync as execSync4 } from "node:child_process";
15289
+ import { execSync as execSync5 } from "node:child_process";
14610
15290
  function getChangedFiles(cwd, since) {
14611
15291
  try {
14612
- const output = execSync4(`git diff --name-only ${since}`, {
15292
+ const output = execSync5(`git diff --name-only ${since}`, {
14613
15293
  cwd,
14614
15294
  encoding: "utf-8",
14615
15295
  timeout: 1e4,
@@ -14622,7 +15302,7 @@ function getChangedFiles(cwd, since) {
14622
15302
  }
14623
15303
  function getCurrentHead(cwd) {
14624
15304
  try {
14625
- return execSync4("git rev-parse HEAD", { cwd, encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
15305
+ return execSync5("git rev-parse HEAD", { cwd, encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
14626
15306
  } catch {
14627
15307
  return null;
14628
15308
  }
@@ -14630,7 +15310,7 @@ function getCurrentHead(cwd) {
14630
15310
 
14631
15311
  // src/avorelo/capabilities/loop-control/loop-metadata.ts
14632
15312
  init_redaction();
14633
- import { mkdirSync as mkdirSync32, writeFileSync as writeFileSync30, readFileSync as readFileSync37, existsSync as existsSync53, readdirSync as readdirSync16 } from "node:fs";
15313
+ import { mkdirSync as mkdirSync32, writeFileSync as writeFileSync30, readFileSync as readFileSync37, existsSync as existsSync54, readdirSync as readdirSync16 } from "node:fs";
14634
15314
  import { join as join53 } from "node:path";
14635
15315
  function classifyFile(file, allowed, disallowed) {
14636
15316
  for (const d of disallowed) {
@@ -14718,7 +15398,7 @@ function persistLoopMetadata(dir, metadata) {
14718
15398
  }
14719
15399
  function readLoopMetadata(dir, loopId) {
14720
15400
  const path = join53(loopDir(dir), `${loopId}.json`);
14721
- if (!existsSync53(path)) return null;
15401
+ if (!existsSync54(path)) return null;
14722
15402
  try {
14723
15403
  const data = JSON.parse(readFileSync37(path, "utf8"));
14724
15404
  return data && data.contract === "avorelo.loopMetadata.v1" ? data : null;
@@ -14728,7 +15408,7 @@ function readLoopMetadata(dir, loopId) {
14728
15408
  }
14729
15409
  function readLatestLoopMetadata(dir) {
14730
15410
  const d = loopDir(dir);
14731
- if (!existsSync53(d)) return null;
15411
+ if (!existsSync54(d)) return null;
14732
15412
  try {
14733
15413
  const files = readdirSync16(d).filter((f) => f.startsWith("loop_") && f.endsWith(".json"));
14734
15414
  if (files.length === 0) return null;
@@ -14751,7 +15431,7 @@ function readLatestLoopMetadata(dir) {
14751
15431
  }
14752
15432
  function readActiveLoop(dir) {
14753
15433
  const path = join53(loopDir(dir), "active.json");
14754
- if (!existsSync53(path)) return null;
15434
+ if (!existsSync54(path)) return null;
14755
15435
  try {
14756
15436
  return JSON.parse(readFileSync37(path, "utf8"));
14757
15437
  } catch {
@@ -14765,7 +15445,7 @@ function writeActiveLoop(dir, loopId, status) {
14765
15445
  }
14766
15446
  function clearActiveLoop(dir) {
14767
15447
  const path = join53(loopDir(dir), "active.json");
14768
- if (existsSync53(path)) {
15448
+ if (existsSync54(path)) {
14769
15449
  writeFileSync30(path, JSON.stringify({ loopId: null, status: "none" }));
14770
15450
  }
14771
15451
  }
@@ -15006,7 +15686,7 @@ async function runLoop(input) {
15006
15686
  }
15007
15687
 
15008
15688
  // src/avorelo/adapters/claude-code/loop-adapter.ts
15009
- import { execSync as execSync5 } from "node:child_process";
15689
+ import { execSync as execSync6 } from "node:child_process";
15010
15690
  var MAX_LOG_LENGTH = 200;
15011
15691
  var ITERATION_TIMEOUT_MS = 3e5;
15012
15692
  function truncate(s) {
@@ -15036,7 +15716,7 @@ function buildPrompt2(input) {
15036
15716
  }
15037
15717
  function detectPermissionFlag() {
15038
15718
  try {
15039
- const help2 = execSync5("claude --help", { timeout: 5e3, stdio: ["pipe", "pipe", "pipe"], encoding: "utf-8" });
15719
+ const help2 = execSync6("claude --help", { timeout: 5e3, stdio: ["pipe", "pipe", "pipe"], encoding: "utf-8" });
15040
15720
  if (help2.includes("--permission-mode")) return "--permission-mode bypassPermissions";
15041
15721
  } catch {
15042
15722
  }
@@ -15065,7 +15745,7 @@ var claudeCodeLoopAdapter = {
15065
15745
  const prompt = buildPrompt2(input);
15066
15746
  if (!_cachedPermFlag) _cachedPermFlag = detectPermissionFlag();
15067
15747
  try {
15068
- execSync5(
15748
+ execSync6(
15069
15749
  `claude --print ${_cachedPermFlag} "${prompt.replace(/"/g, '\\"')}"`,
15070
15750
  {
15071
15751
  cwd: input.cwd,
@@ -15100,7 +15780,7 @@ var claudeCodeLoopAdapter = {
15100
15780
  },
15101
15781
  isAvailable() {
15102
15782
  try {
15103
- execSync5("claude --version", { timeout: 5e3, stdio: ["pipe", "pipe", "pipe"], encoding: "utf-8" });
15783
+ execSync6("claude --version", { timeout: 5e3, stdio: ["pipe", "pipe", "pipe"], encoding: "utf-8" });
15104
15784
  return true;
15105
15785
  } catch {
15106
15786
  return false;
@@ -15109,7 +15789,7 @@ var claudeCodeLoopAdapter = {
15109
15789
  };
15110
15790
 
15111
15791
  // src/avorelo/capabilities/settings/index.ts
15112
- import { existsSync as existsSync54, readFileSync as readFileSync38, writeFileSync as writeFileSync31, mkdirSync as mkdirSync33 } from "node:fs";
15792
+ import { existsSync as existsSync55, readFileSync as readFileSync38, writeFileSync as writeFileSync31, mkdirSync as mkdirSync33 } from "node:fs";
15113
15793
  import { join as join54, dirname as dirname9 } from "node:path";
15114
15794
  var SETTINGS_CONTRACT = "avorelo.settings.v1";
15115
15795
  var SETTINGS_PATH = ".avorelo/settings.json";
@@ -15176,7 +15856,7 @@ function buildDefaultSettings(opts) {
15176
15856
  }
15177
15857
  function loadSettings(dir) {
15178
15858
  const p = join54(dir, SETTINGS_PATH);
15179
- if (!existsSync54(p)) return null;
15859
+ if (!existsSync55(p)) return null;
15180
15860
  try {
15181
15861
  const s = JSON.parse(readFileSync38(p, "utf8"));
15182
15862
  return s.contract === SETTINGS_CONTRACT ? s : null;
@@ -15283,7 +15963,7 @@ var ALPHA_NOTICE = [
15283
15963
  ].join("\n");
15284
15964
 
15285
15965
  // src/avorelo/capabilities/update-channel/index.ts
15286
- import { existsSync as existsSync55, readFileSync as readFileSync39, writeFileSync as writeFileSync32, mkdirSync as mkdirSync34 } from "node:fs";
15966
+ import { existsSync as existsSync56, readFileSync as readFileSync39, writeFileSync as writeFileSync32, mkdirSync as mkdirSync34 } from "node:fs";
15287
15967
  import { join as join55, dirname as dirname10 } from "node:path";
15288
15968
  var UPDATE_CHANNEL_CONTRACT = "avorelo.updateChannel.v1";
15289
15969
  var UPDATE_MANIFEST_CONTRACT = "avorelo.updateManifest.v1";
@@ -15298,10 +15978,10 @@ function getCurrentVersion4() {
15298
15978
  }
15299
15979
  function detectInstallMethod(root) {
15300
15980
  const r2 = root ?? join55(dirname10(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/, "$1")), "../../../..");
15301
- if (existsSync55(join55(r2, ".git"))) return "source-checkout";
15981
+ if (existsSync56(join55(r2, ".git"))) return "source-checkout";
15302
15982
  try {
15303
15983
  const p = join55(r2, "package.json");
15304
- if (existsSync55(p)) {
15984
+ if (existsSync56(p)) {
15305
15985
  const pkg = JSON.parse(readFileSync39(p, "utf8"));
15306
15986
  if (pkg._resolved) return "npm-global";
15307
15987
  if (pkg._where) return "npm-local";
@@ -15312,7 +15992,7 @@ function detectInstallMethod(root) {
15312
15992
  }
15313
15993
  function loadManifest(dir) {
15314
15994
  const p = join55(dir, ".avorelo", "update-manifest.json");
15315
- if (!existsSync55(p)) return null;
15995
+ if (!existsSync56(p)) return null;
15316
15996
  try {
15317
15997
  const m = JSON.parse(readFileSync39(p, "utf8"));
15318
15998
  return m.contract === UPDATE_MANIFEST_CONTRACT ? m : null;
@@ -15454,7 +16134,7 @@ function renderUpdateApply(r2) {
15454
16134
  }
15455
16135
 
15456
16136
  // src/avorelo/capabilities/dogfood-learning/index.ts
15457
- import { existsSync as existsSync56, readFileSync as readFileSync40, writeFileSync as writeFileSync33, mkdirSync as mkdirSync35, readdirSync as readdirSync17, unlinkSync as unlinkSync3 } from "node:fs";
16137
+ import { existsSync as existsSync57, readFileSync as readFileSync40, writeFileSync as writeFileSync33, mkdirSync as mkdirSync35, readdirSync as readdirSync17, unlinkSync as unlinkSync3 } from "node:fs";
15458
16138
  import { join as join56, dirname as dirname11 } from "node:path";
15459
16139
  import { randomUUID as randomUUID8 } from "node:crypto";
15460
16140
  var DOGFOOD_LEARNING_CONTRACT = "avorelo.dogfoodLearning.v1";
@@ -15651,7 +16331,7 @@ function ensureQueueDir(dir) {
15651
16331
  }
15652
16332
  function countQueuedEvents(dir) {
15653
16333
  const qd = queueDir(dir);
15654
- if (!existsSync56(qd)) return 0;
16334
+ if (!existsSync57(qd)) return 0;
15655
16335
  try {
15656
16336
  return readdirSync17(qd).filter((f) => f.endsWith(".json")).length;
15657
16337
  } catch {
@@ -15669,7 +16349,7 @@ function queueEvent(dir, payload) {
15669
16349
  }
15670
16350
  function loadQueuedEvents(dir) {
15671
16351
  const qd = queueDir(dir);
15672
- if (!existsSync56(qd)) return [];
16352
+ if (!existsSync57(qd)) return [];
15673
16353
  const files = readdirSync17(qd).filter((f) => f.endsWith(".json")).sort();
15674
16354
  const events = [];
15675
16355
  for (const f of files) {
@@ -15683,7 +16363,7 @@ function loadQueuedEvents(dir) {
15683
16363
  }
15684
16364
  function purgeQueue(dir) {
15685
16365
  const qd = queueDir(dir);
15686
- if (!existsSync56(qd)) return { purged: 0 };
16366
+ if (!existsSync57(qd)) return { purged: 0 };
15687
16367
  const files = readdirSync17(qd).filter((f) => f.endsWith(".json"));
15688
16368
  for (const f of files) {
15689
16369
  try {
@@ -15878,7 +16558,7 @@ function generateLocalFingerprint(target) {
15878
16558
  var CLAIM_EXPIRY_MS = 24 * 60 * 60 * 1e3;
15879
16559
 
15880
16560
  // src/avorelo/capabilities/cloud-sync/cli-auth-state.ts
15881
- import { existsSync as existsSync57, readFileSync as readFileSync41, writeFileSync as writeFileSync34, mkdirSync as mkdirSync36 } from "node:fs";
16561
+ import { existsSync as existsSync58, readFileSync as readFileSync41, writeFileSync as writeFileSync34, mkdirSync as mkdirSync36 } from "node:fs";
15882
16562
  import { join as join57 } from "node:path";
15883
16563
  function authDir(baseDir) {
15884
16564
  return join57(baseDir, ".avorelo", "auth");
@@ -15895,7 +16575,7 @@ function writeCliAuthState(baseDir, state) {
15895
16575
  }
15896
16576
  function readCliAuthState(baseDir) {
15897
16577
  const path = authPath(baseDir);
15898
- if (!existsSync57(path)) return null;
16578
+ if (!existsSync58(path)) return null;
15899
16579
  try {
15900
16580
  const raw = JSON.parse(readFileSync41(path, "utf8"));
15901
16581
  if (!raw || typeof raw.token !== "string" || typeof raw.workspaceId !== "string") return null;
@@ -15911,7 +16591,7 @@ function buildAuthHeaders(authState) {
15911
16591
  }
15912
16592
 
15913
16593
  // src/avorelo/capabilities/cloud-sync/claim-state.ts
15914
- import { existsSync as existsSync58, readFileSync as readFileSync42, writeFileSync as writeFileSync35, mkdirSync as mkdirSync37 } from "node:fs";
16594
+ import { existsSync as existsSync59, readFileSync as readFileSync42, writeFileSync as writeFileSync35, mkdirSync as mkdirSync37 } from "node:fs";
15915
16595
  import { join as join58 } from "node:path";
15916
16596
  function claimDir(baseDir) {
15917
16597
  return join58(baseDir, ".avorelo", "claim");
@@ -15928,7 +16608,7 @@ function writeClaimState(baseDir, state) {
15928
16608
  }
15929
16609
  function readClaimState(baseDir) {
15930
16610
  const path = claimPath(baseDir);
15931
- if (!existsSync58(path)) return null;
16611
+ if (!existsSync59(path)) return null;
15932
16612
  try {
15933
16613
  const raw = JSON.parse(readFileSync42(path, "utf8"));
15934
16614
  if (!raw || typeof raw.workspaceId !== "string" || typeof raw.claimedAt !== "string") return null;
@@ -15951,6 +16631,9 @@ var RUNTIME_ACTIONS = [
15951
16631
  { action: "cli.status", capabilityKey: "session_value_visible", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Show activation status", freeFallbackExists: true },
15952
16632
  { action: "cli.open", capabilityKey: "session_value_visible", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Local receipts dashboard", freeFallbackExists: true },
15953
16633
  { action: "cli.control_center", capabilityKey: "session_value_visible", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Local Control Center", freeFallbackExists: true },
16634
+ { action: "cli.controls", capabilityKey: "session_value_visible", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Inspect built-in Work Controls", freeFallbackExists: true },
16635
+ { action: "cli.receipt", capabilityKey: "session_proof_summary", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Inspect latest local receipt", freeFallbackExists: true },
16636
+ { action: "cli.proof", capabilityKey: "session_proof_summary", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Validate latest proof status", freeFallbackExists: true },
15954
16637
  { action: "cli.doctor", capabilityKey: "scope_safety_check_basic", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Health check", freeFallbackExists: true },
15955
16638
  { action: "cli.verify", capabilityKey: "session_proof_summary", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Validate activation state", freeFallbackExists: true },
15956
16639
  { action: "cli.billing", capabilityKey: "session_value_visible", minimumTier: "free", surface: "cli", fallback: "allow", reason: "Billing readiness (read-only)", freeFallbackExists: true },
@@ -15989,6 +16672,9 @@ var FREE_COMMANDS = /* @__PURE__ */ new Set([
15989
16672
  "status",
15990
16673
  "open",
15991
16674
  "control-center",
16675
+ "controls",
16676
+ "receipt",
16677
+ "proof",
15992
16678
  "doctor",
15993
16679
  "verify",
15994
16680
  "billing",
@@ -16070,7 +16756,7 @@ function formatCliGateMessage(gateResult) {
16070
16756
  }
16071
16757
 
16072
16758
  // src/avorelo/telemetry/local-store.ts
16073
- import { appendFileSync as appendFileSync10, existsSync as existsSync59, mkdirSync as mkdirSync38, readFileSync as readFileSync44, writeFileSync as writeFileSync36 } from "node:fs";
16759
+ import { appendFileSync as appendFileSync10, existsSync as existsSync60, mkdirSync as mkdirSync38, readFileSync as readFileSync44, writeFileSync as writeFileSync36 } from "node:fs";
16074
16760
  import { dirname as dirname13 } from "node:path";
16075
16761
 
16076
16762
  // src/avorelo/telemetry/config.ts
@@ -16084,7 +16770,7 @@ var TELEMETRY_STATE_FILE = "telemetry-state.json";
16084
16770
  var TELEMETRY_BATCH_SIZE = 100;
16085
16771
  var TELEMETRY_PERIOD_MS = 6 * 60 * 60 * 1e3;
16086
16772
  var TELEMETRY_OPPORTUNISTIC_MS = 24 * 60 * 60 * 1e3;
16087
- var TELEMETRY_TIMEOUT_MS = 750;
16773
+ var TELEMETRY_TIMEOUT_MS = 2e3;
16088
16774
  function getPackageVersion() {
16089
16775
  for (const rel of ["../../../package.json", "../../../../package.json", "../../../../../package.json"]) {
16090
16776
  try {
@@ -16392,7 +17078,7 @@ function safeParseJson(text) {
16392
17078
  }
16393
17079
  }
16394
17080
  function readJsonl(path) {
16395
- if (!existsSync59(path)) return [];
17081
+ if (!existsSync60(path)) return [];
16396
17082
  const lines = readFileSync44(path, "utf8").split(/\r?\n/);
16397
17083
  const values = [];
16398
17084
  for (const line of lines) {
@@ -16415,7 +17101,7 @@ function writeJsonl(path, values) {
16415
17101
  }
16416
17102
  function ensureTelemetryState(dir, now = Date.now()) {
16417
17103
  const paths = getTelemetryConfig(dir, buildTelemetryState(now));
16418
- if (existsSync59(paths.statePath)) {
17104
+ if (existsSync60(paths.statePath)) {
16419
17105
  const parsed = safeParseJson(readFileSync44(paths.statePath, "utf8"));
16420
17106
  if (parsed?.contract === "avorelo.telemetry.state.v1") return parsed;
16421
17107
  }
@@ -16903,11 +17589,11 @@ function renderTelemetryPreview(preview) {
16903
17589
  }
16904
17590
 
16905
17591
  // src/avorelo/telemetry/integration-detection.ts
16906
- import { existsSync as existsSync60, readFileSync as readFileSync45 } from "node:fs";
17592
+ import { existsSync as existsSync61, readFileSync as readFileSync45 } from "node:fs";
16907
17593
  import { join as join60 } from "node:path";
16908
17594
  function detectGitProviderFromConfig(dir) {
16909
17595
  const configPath = join60(dir, ".git", "config");
16910
- if (!existsSync60(configPath)) return "unknown";
17596
+ if (!existsSync61(configPath)) return "unknown";
16911
17597
  try {
16912
17598
  const content = readFileSync45(configPath, "utf8").toLowerCase();
16913
17599
  if (content.includes("github.com")) return "github";
@@ -16919,15 +17605,15 @@ function detectGitProviderFromConfig(dir) {
16919
17605
  }
16920
17606
  }
16921
17607
  function detectCiProvider(dir) {
16922
- if (existsSync60(join60(dir, ".github", "workflows"))) return "github_actions";
16923
- if (existsSync60(join60(dir, ".gitlab-ci.yml"))) return "gitlab_ci";
16924
- if (existsSync60(join60(dir, ".circleci", "config.yml"))) return "circle";
16925
- if (existsSync60(join60(dir, "Jenkinsfile"))) return "jenkins";
17608
+ if (existsSync61(join60(dir, ".github", "workflows"))) return "github_actions";
17609
+ if (existsSync61(join60(dir, ".gitlab-ci.yml"))) return "gitlab_ci";
17610
+ if (existsSync61(join60(dir, ".circleci", "config.yml"))) return "circle";
17611
+ if (existsSync61(join60(dir, "Jenkinsfile"))) return "jenkins";
16926
17612
  return "unknown";
16927
17613
  }
16928
17614
  function detectRepoVisibility(dir) {
16929
17615
  const configPath = join60(dir, ".git", "config");
16930
- if (!existsSync60(configPath)) return "unknown";
17616
+ if (!existsSync61(configPath)) return "unknown";
16931
17617
  try {
16932
17618
  const content = readFileSync45(configPath, "utf8").toLowerCase();
16933
17619
  if (content.includes("github.com")) {
@@ -17104,6 +17790,10 @@ function help() {
17104
17790
  " status [--target <dir>] Show activation and session status",
17105
17791
  " open [--target <dir>] [--format html|json|text] Local receipts dashboard",
17106
17792
  " control-center [--target <dir>] [--format html|json|text] Local Control Center (read-only, all local state)",
17793
+ " controls list [--json] List built-in Work Controls",
17794
+ " controls explain <control> [--json] Explain one built-in Work Control",
17795
+ " receipt latest [--target <dir>] [--json] Show the latest local receipt",
17796
+ " proof check [--target <dir>] [--json] Validate the latest proof status",
17107
17797
  " doctor [--target <dir>] Health check (adapters, hooks, session)",
17108
17798
  " verify [--target <dir>] Validate activation state invariants",
17109
17799
  " uninstall [--target <dir>] Remove all Avorelo-managed content",
@@ -17175,10 +17865,12 @@ function cmdRun(args) {
17175
17865
  process.stdout.write(JSON.stringify({ fixture: name, decision: gate.decision, confidence: gate.confidence, reasonCodes: gate.reasonCodes, receipt }, null, 2) + "\n");
17176
17866
  return gate.decision === "STOP_DONE" ? 0 : 1;
17177
17867
  }
17178
- function cmdActivate(args) {
17868
+ async function cmdActivate(args) {
17179
17869
  const target = arg(args, "--target", process.cwd());
17180
17870
  const installHooksFlag = args.includes("--install-hooks");
17181
17871
  const approve = args.includes("--approve");
17872
+ const claimToken = arg(args, "--claim");
17873
+ const scope = arg(args, "--scope") ?? "project-wide";
17182
17874
  if (installHooksFlag) {
17183
17875
  if (!approve) {
17184
17876
  process.stderr.write("Hook installation requires explicit approval. Add --approve to confirm.\n");
@@ -17199,6 +17891,18 @@ function cmdActivate(args) {
17199
17891
  return 2;
17200
17892
  }
17201
17893
  }
17894
+ const preflight = runPreflight(target);
17895
+ if (!preflight.canStart) {
17896
+ process.stderr.write(formatPreflightReport(preflight));
17897
+ process.stderr.write(`
17898
+ Activation taxonomy: ${preflight.taxonomy}
17899
+ `);
17900
+ return 2;
17901
+ }
17902
+ if (!preflight.ok) {
17903
+ process.stderr.write(formatPreflightReport(preflight));
17904
+ process.stderr.write("Continuing with activation despite warnings...\n\n");
17905
+ }
17202
17906
  const state = runFullActivation(target);
17203
17907
  const contract = createWorkContract({ contractId: "canonical-activate", objective: "full local-first activation", allowedPaths: [join61(target, ".avorelo")], planTier: "Free" });
17204
17908
  const ledger = new StateLedger();
@@ -17218,12 +17922,15 @@ function cmdActivate(args) {
17218
17922
  state.receipts.push({ id: receipt.receiptId, path: join61(target, ".avorelo", "receipts", `${receipt.receiptId}.json`), type: "canonical_activation" });
17219
17923
  persistActivationV2(target, state);
17220
17924
  persistReceipt(target, receipt);
17925
+ const detection = runFullDetection(target);
17926
+ const fingerprint = generateLocalFingerprint(target);
17221
17927
  const fv = state.firstValue;
17222
17928
  const lines = [
17223
17929
  "",
17224
17930
  "Avorelo activated.",
17225
17931
  "",
17226
17932
  ` Mode: ${state.activationMode}`,
17933
+ ` Scope: ${scope}`,
17227
17934
  ` Status: ${state.activationStatus}`,
17228
17935
  ` State: ${join61(target, ACTIVATION_STATE_DIR, ACTIVATION_STATE_FILE)}`
17229
17936
  ];
@@ -17232,6 +17939,10 @@ function cmdActivate(args) {
17232
17939
  for (const f of fv.found.slice(0, 8)) lines.push(` ${f}`);
17233
17940
  if (fv.found.length > 8) lines.push(` ... and ${fv.found.length - 8} more`);
17234
17941
  }
17942
+ if (detection.summary.toolsDetected.length > 0) {
17943
+ lines.push("", " Coding tools detected:");
17944
+ for (const t of detection.summary.toolsDetected) lines.push(` ${t}`);
17945
+ }
17235
17946
  if (fv.fixed.length > 0) {
17236
17947
  lines.push("", " Fixed:");
17237
17948
  for (const f of fv.fixed) lines.push(` ${f}`);
@@ -17245,7 +17956,38 @@ function cmdActivate(args) {
17245
17956
  ` Run entry: ${state.runEntry.installed ? "installed" : "not installed"}`,
17246
17957
  ` Billing: ${state.billing.status}`,
17247
17958
  ` Auth: ${state.auth.status}`,
17248
- ` Production: not ready`,
17959
+ ` Production: not ready`
17960
+ );
17961
+ let linkResult = "no claim provided";
17962
+ if (claimToken) {
17963
+ const baseUrl = process.env.APP_BASE_URL ?? "https://app.avorelo.com";
17964
+ try {
17965
+ const resp = await fetch(`${baseUrl}/api/activation/link`, {
17966
+ method: "POST",
17967
+ headers: { "Content-Type": "application/json" },
17968
+ body: JSON.stringify({
17969
+ token: claimToken,
17970
+ fingerprint,
17971
+ version: avoreloVersion(),
17972
+ toolsDetected: detection.summary.toolsDetected,
17973
+ osFamily: detection.environment.os,
17974
+ nodeVersion: detection.environment.nodeVersion ?? null,
17975
+ taxonomy: "ACTIVATION_SUCCEEDED_LOCALLY"
17976
+ })
17977
+ });
17978
+ if (resp.ok) {
17979
+ const data = await resp.json();
17980
+ linkResult = data.linked ? "linked" : data.error ?? "unknown";
17981
+ } else {
17982
+ const err = await resp.json().catch(() => ({ error: resp.statusText }));
17983
+ linkResult = `failed: ${err.error ?? resp.statusText}`;
17984
+ }
17985
+ } catch (e) {
17986
+ linkResult = `error: ${e.message}`;
17987
+ }
17988
+ lines.push(` Dashboard: ${linkResult === "linked" ? "linked to account" : linkResult}`);
17989
+ }
17990
+ lines.push(
17249
17991
  "",
17250
17992
  ` Next: ${fv.nextAction}`,
17251
17993
  ""
@@ -17253,6 +17995,14 @@ function cmdActivate(args) {
17253
17995
  process.stdout.write(lines.join("\n"));
17254
17996
  return 0;
17255
17997
  }
17998
+ function cmdPreflight(args) {
17999
+ const target = arg(args, "--target", process.cwd());
18000
+ const result3 = runPreflight(target);
18001
+ process.stdout.write(formatPreflightReport(result3));
18002
+ process.stdout.write(`Taxonomy: ${result3.taxonomy}
18003
+ `);
18004
+ return result3.canStart ? 0 : 2;
18005
+ }
17256
18006
  async function cmdDoctor(args) {
17257
18007
  const target = arg(args, "--target", process.cwd());
17258
18008
  const r2 = doctor(target);
@@ -17524,6 +18274,140 @@ function cmdControlCenter(args) {
17524
18274
  process.stdout.write(JSON.stringify({ ok: true, htmlPath, runtime: model.sections.runtimeSession.status, sources: model.sources.length }, null, 2) + "\n");
17525
18275
  return 0;
17526
18276
  }
18277
+ function cmdControls(args) {
18278
+ const sub = args[0] && !args[0].startsWith("--") ? args[0] : "list";
18279
+ const asJson = args.includes("--json");
18280
+ if (sub === "list") {
18281
+ const controls = listWorkControls();
18282
+ if (asJson) {
18283
+ process.stdout.write(JSON.stringify(controls, null, 2) + "\n");
18284
+ return 0;
18285
+ }
18286
+ process.stdout.write([
18287
+ "",
18288
+ "Avorelo Work Controls",
18289
+ ...controls.map((control) => ` ${control.controlId}: ${control.uiCopy} [${control.defaultState}]`),
18290
+ ""
18291
+ ].join("\n"));
18292
+ return 0;
18293
+ }
18294
+ if (sub === "explain") {
18295
+ const controlId = args.find((value, index) => index > 0 && !value.startsWith("--"));
18296
+ if (!controlId) {
18297
+ process.stderr.write("Usage: avorelo controls explain <control> [--json]\n");
18298
+ return 2;
18299
+ }
18300
+ const control = getWorkControl(controlId);
18301
+ if (!control) {
18302
+ process.stderr.write(`Unknown Work Control: ${controlId}
18303
+ `);
18304
+ return 1;
18305
+ }
18306
+ if (asJson) {
18307
+ process.stdout.write(JSON.stringify(control, null, 2) + "\n");
18308
+ return 0;
18309
+ }
18310
+ process.stdout.write([
18311
+ "",
18312
+ `${control.title} (${control.controlId})`,
18313
+ ` Purpose: ${control.purpose}`,
18314
+ ` Points: ${control.enforcementPoints.join(", ")}`,
18315
+ ` Default: ${control.defaultState}`,
18316
+ ` Packaging: Free=${control.packaging.free} Pro=${control.packaging.pro} Teams=${control.packaging.teams}`,
18317
+ ` Local: ${control.localOnlyBehavior}`,
18318
+ ` Cloud: ${control.cloudBehavior}`,
18319
+ ` Persisted: ${control.dataPersisted.join(", ")}`,
18320
+ ` Tests: ${control.testsRequired.join(", ")}`,
18321
+ ` UI copy: ${control.uiCopy}`,
18322
+ ""
18323
+ ].join("\n"));
18324
+ return 0;
18325
+ }
18326
+ process.stderr.write("Usage: avorelo controls <list|explain> [<control>] [--json]\n");
18327
+ return 2;
18328
+ }
18329
+ function latestReceiptFor(dir) {
18330
+ return listReceipts(dir).sort((a, b) => {
18331
+ const aw = typeof a.writtenAt === "number" ? a.writtenAt : -1;
18332
+ const bw = typeof b.writtenAt === "number" ? b.writtenAt : -1;
18333
+ if (aw !== bw) return bw - aw;
18334
+ return b.receiptId.localeCompare(a.receiptId);
18335
+ })[0] ?? null;
18336
+ }
18337
+ function cmdReceipt(args) {
18338
+ const sub = args[0] && !args[0].startsWith("--") ? args[0] : "latest";
18339
+ const target = arg(args, "--target", process.cwd());
18340
+ const asJson = args.includes("--json");
18341
+ if (sub !== "latest") {
18342
+ process.stderr.write("Usage: avorelo receipt latest [--target <dir>] [--json]\n");
18343
+ return 2;
18344
+ }
18345
+ const latest = latestReceiptFor(target);
18346
+ if (!latest) {
18347
+ if (asJson) {
18348
+ process.stdout.write(JSON.stringify({ status: "none", message: "no receipts found" }, null, 2) + "\n");
18349
+ return 0;
18350
+ }
18351
+ process.stdout.write("\nNo receipts found yet. Run a controlled session first.\n\n");
18352
+ return 0;
18353
+ }
18354
+ const full = readReceipt(target, latest.receiptId) ?? latest;
18355
+ if (asJson) {
18356
+ process.stdout.write(JSON.stringify(full, null, 2) + "\n");
18357
+ return 0;
18358
+ }
18359
+ process.stdout.write([
18360
+ "",
18361
+ `Latest receipt: ${full.receiptId}`,
18362
+ ` Contract: ${full.contractId}`,
18363
+ ` Decision: ${full.decision}`,
18364
+ ` Evidence: ${full.evidenceLevels.join(", ") || "none"}`,
18365
+ ` Reasons: ${full.decisionBasis.reasonCodes.join(", ") || "none"}`,
18366
+ ` Next: ${full.safeNextActions.join("; ") || "none"}`,
18367
+ ""
18368
+ ].join("\n"));
18369
+ return 0;
18370
+ }
18371
+ function cmdProof(args) {
18372
+ const sub = args[0] && !args[0].startsWith("--") ? args[0] : "check";
18373
+ const target = arg(args, "--target", process.cwd());
18374
+ const asJson = args.includes("--json");
18375
+ if (sub !== "check") {
18376
+ process.stderr.write("Usage: avorelo proof check [--target <dir>] [--json]\n");
18377
+ return 2;
18378
+ }
18379
+ const report = loadLatestProofReport(target) ?? buildProofReportFromLocalEvidence(target);
18380
+ const summary = summarizeProofReport(report);
18381
+ const validation = validateProofReport(report);
18382
+ const payload = {
18383
+ reportId: report.reportId,
18384
+ valid: validation.valid,
18385
+ reasons: validation.reasons,
18386
+ canShowCostSummary: summary.canShowCostSummary,
18387
+ canShowSavings: summary.canShowSavings,
18388
+ savingsRefusalReason: summary.savingsRefusalReason,
18389
+ sections: summary.sections
18390
+ };
18391
+ if (asJson) {
18392
+ process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
18393
+ return validation.valid ? 0 : 1;
18394
+ }
18395
+ process.stdout.write([
18396
+ "",
18397
+ `Proof check: ${report.reportId}`,
18398
+ ` Valid: ${validation.valid}`,
18399
+ ` Found: ${summary.sections.found}`,
18400
+ ` Protected: ${summary.sections.protected}`,
18401
+ ` Verified: ${summary.sections.verified}`,
18402
+ ` Attention: ${summary.sections.needsAttention}`,
18403
+ ` Next: ${summary.sections.next}`,
18404
+ ` Cost: ${summary.canShowCostSummary ? "available" : "unavailable"}`,
18405
+ ` Savings: ${summary.canShowSavings ? "shown" : "not claimed"}${summary.savingsRefusalReason ? ` (${summary.savingsRefusalReason})` : ""}`,
18406
+ validation.reasons.length ? ` Issues: ${validation.reasons.join(", ")}` : " Issues: none",
18407
+ ""
18408
+ ].join("\n"));
18409
+ return validation.valid ? 0 : 1;
18410
+ }
17527
18411
  function cmdVerify(args) {
17528
18412
  const target = arg(args, "--target", process.cwd());
17529
18413
  const stateVerify = verifyActivationState(target);
@@ -17537,7 +18421,7 @@ function cmdVerify(args) {
17537
18421
  const input = loadProofInput(target);
17538
18422
  if (input) {
17539
18423
  const contract = createWorkContract({ contractId: "verify", objective: input.objective ?? "verify real-workflow proof", allowedPaths: [join61(target, "src")], planTier: "Free" });
17540
- const r2 = evaluateProof({ contract, artifacts: input.artifacts, readbacks: input.readbacks, dir: target, sampleSize: input.sampleSize, receiptId: "rcpt_verify" });
18424
+ const r2 = evaluateProof2({ contract, artifacts: input.artifacts, readbacks: input.readbacks, dir: target, sampleSize: input.sampleSize, receiptId: "rcpt_verify" });
17541
18425
  process.stdout.write(JSON.stringify({ scope: "full", activationState: { valid: true }, proof: { decision: r2.decision, confidence: r2.confidence } }, null, 2) + "\n");
17542
18426
  return r2.decision === "STOP_DONE" ? 0 : 1;
17543
18427
  }
@@ -18039,7 +18923,7 @@ function cmdTokenCost(args) {
18039
18923
  }
18040
18924
  if (sub === "import" || sub === "validate") {
18041
18925
  const file = arg(args, "--file");
18042
- if (!file || !existsSync61(file)) {
18926
+ if (!file || !existsSync62(file)) {
18043
18927
  process.stderr.write("Usage: avorelo token-cost " + sub + " --file <path> [--json]\n");
18044
18928
  return 2;
18045
18929
  }
@@ -18186,7 +19070,7 @@ function cmdContextCheck(args) {
18186
19070
  const ci = args.includes("--ci");
18187
19071
  const wcPath = arg(args, "--work-contract");
18188
19072
  let workContract;
18189
- if (wcPath && existsSync61(wcPath)) {
19073
+ if (wcPath && existsSync62(wcPath)) {
18190
19074
  try {
18191
19075
  workContract = JSON.parse(readFileSync46(wcPath, "utf8"));
18192
19076
  } catch {
@@ -18251,7 +19135,7 @@ function cmdSecretBoundary(args) {
18251
19135
  const asJson = args.includes("--json");
18252
19136
  let content = arg(args, "--content");
18253
19137
  const file = arg(args, "--file");
18254
- if (file && existsSync61(file)) content = readFileSync46(file, "utf8");
19138
+ if (file && existsSync62(file)) content = readFileSync46(file, "utf8");
18255
19139
  if (content === void 0) content = "";
18256
19140
  if (sub === "scan" || sub === void 0) {
18257
19141
  const r2 = scanContent({ content, sourceKind: file ? "file" : "tool_output" });
@@ -18318,7 +19202,7 @@ function cmdExplain(args) {
18318
19202
  const changedFiles = [];
18319
19203
  for (const { adapter } of detected) {
18320
19204
  const surface = adapter.getInstructionSurface(target);
18321
- if (surface && existsSync61(surface)) changedFiles.push(surface);
19205
+ if (surface && existsSync62(surface)) changedFiles.push(surface);
18322
19206
  }
18323
19207
  if (changedFiles.length > 0) {
18324
19208
  lines.push(" Changed:");
@@ -18492,7 +19376,7 @@ function cmdFeedback(args) {
18492
19376
  }
18493
19377
  if (sub === "share") {
18494
19378
  const file = arg(args, "--file");
18495
- if (!file || !existsSync61(file)) {
19379
+ if (!file || !existsSync62(file)) {
18496
19380
  process.stderr.write("Usage: avorelo feedback share --file <bundle-path>\n");
18497
19381
  return 2;
18498
19382
  }
@@ -18796,7 +19680,7 @@ No loop metadata found for ${loopId}.
18796
19680
  if (sub === "doctor") {
18797
19681
  const issues = [];
18798
19682
  const ok = [];
18799
- if (existsSync61(join61(target, ".git"))) {
19683
+ if (existsSync62(join61(target, ".git"))) {
18800
19684
  ok.push("Git repository detected");
18801
19685
  } else {
18802
19686
  issues.push("Not a git repository \u2014 loop needs git for drift detection");
@@ -18856,7 +19740,7 @@ function cmdUninstallAll(args) {
18856
19740
  const preserved = adapterResult.preserved;
18857
19741
  const avoreloDir2 = join61(target, ".avorelo");
18858
19742
  try {
18859
- if (existsSync61(avoreloDir2)) {
19743
+ if (existsSync62(avoreloDir2)) {
18860
19744
  rmSync3(avoreloDir2, { recursive: true, force: true });
18861
19745
  removed.push(avoreloDir2);
18862
19746
  }
@@ -19505,6 +20389,8 @@ function main(argv) {
19505
20389
  return cmdSupport(rest);
19506
20390
  case "activate":
19507
20391
  return cmdActivate(rest);
20392
+ case "preflight":
20393
+ return cmdPreflight(rest);
19508
20394
  case "doctor":
19509
20395
  return cmdDoctor(rest);
19510
20396
  case "uninstall":
@@ -19523,6 +20409,12 @@ function main(argv) {
19523
20409
  return cmdOpen(rest);
19524
20410
  case "control-center":
19525
20411
  return cmdControlCenter(rest);
20412
+ case "controls":
20413
+ return cmdControls(rest);
20414
+ case "receipt":
20415
+ return cmdReceipt(rest);
20416
+ case "proof":
20417
+ return cmdProof(rest);
19526
20418
  case "verify":
19527
20419
  return cmdVerify(rest);
19528
20420
  case "site":
@@ -19722,14 +20614,21 @@ async function finalize(exitCode) {
19722
20614
  recordCliTelemetry(exitCode);
19723
20615
  } catch {
19724
20616
  }
19725
- sendDueTelemetry(CLI_TELEMETRY_SNAPSHOT.target).catch(() => {
19726
- });
19727
20617
  if (_cmd && LEARNING_COMMANDS.has(_cmd)) {
19728
20618
  try {
19729
20619
  emitLearningEvent(process.cwd(), { commandName: _cmd, commandStatus: exitCode === 0 ? "ok" : "error", eventType: "command" });
19730
20620
  } catch {
19731
20621
  }
19732
20622
  }
20623
+ try {
20624
+ const telemetryDone = sendDueTelemetry(CLI_TELEMETRY_SNAPSHOT.target).catch(() => {
20625
+ });
20626
+ await Promise.race([telemetryDone, new Promise((r2) => {
20627
+ const t = setTimeout(r2, 2e3);
20628
+ if (typeof t.unref === "function") t.unref();
20629
+ })]);
20630
+ } catch {
20631
+ }
19733
20632
  if (_cmd !== "serve" && _cmd !== "webhook" && _cmd !== "sync") {
19734
20633
  setTimeout(() => process.exit(exitCode), 50).unref();
19735
20634
  }