@useorgx/wizard 0.1.42 → 0.1.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -6502,14 +6502,15 @@ function loadAiSessionImports(options) {
6502
6502
 
6503
6503
  // src/lib/work-graph-source-adapters.ts
6504
6504
  import { createHash as createHash3 } from "crypto";
6505
- import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync4, statSync as statSync4 } from "fs";
6505
+ import { execFileSync } from "child_process";
6506
+ import { closeSync, existsSync as existsSync6, openSync, readFileSync as readFileSync4, readdirSync as readdirSync4, readSync, statSync as statSync4 } from "fs";
6506
6507
  import { homedir as homedir2 } from "os";
6507
6508
  import { basename as basename3, join as join5, resolve } from "path";
6508
- var CLIENT_SOURCES = ["claude_code", "codex", "opencode", "goose", "cursor"];
6509
+ var CLIENT_SOURCES = ["claude_code", "codex", "opencode", "goose", "cursor", "github", "slack"];
6509
6510
  var DEFAULT_LIMIT_PER_SOURCE2 = 8;
6510
6511
  var DEFAULT_SINCE_DAYS2 = 45;
6511
6512
  var DEFAULT_MAX_BYTES_PER_FILE2 = 2e6;
6512
- var WORK_SIGNAL_PATTERN = /\b(decision|decided|tradeoff|artifact|implemented|created|changed|edited|shipped|verified|test|proof|commit|blocked|blocker|failed|fails|error|timeout|permission|owner|handoff|mcp__|orgx_|tool call|schema|zod|next action|follow[- ]?up|initiative|agent|skill|recipe|workflow|customer|business|launch|deploy)\b/i;
6513
+ var WORK_SIGNAL_PATTERN = /\b(decision|decided|approved|assigned|tradeoff|artifact|implemented|created|changed|edited|shipped|verified|test|proof|commit|pr|blocked|blocker|failed|fails|error|timeout|permission|owner|handoff|mcp__|orgx_|tool call|schema|zod|next action|follow[- ]?up|initiative|agent|skill|recipe|workflow|customer|business|launch|deploy)\b/i;
6513
6514
  function parseInvestigationSourceList(value) {
6514
6515
  if (!value?.trim() || value.trim().toLowerCase() === "manual") return [];
6515
6516
  const requested = value.split(",").map((item) => item.trim().toLowerCase().replace(/-/g, "_")).filter(Boolean);
@@ -6518,7 +6519,7 @@ function parseInvestigationSourceList(value) {
6518
6519
  const invalid = deduped.filter((source) => !CLIENT_SOURCES.includes(source));
6519
6520
  if (invalid.length > 0) {
6520
6521
  throw new Error(
6521
- `Unsupported investigation source: ${invalid.join(", ")}. Use claude, codex, opencode, goose, cursor, or all.`
6522
+ `Unsupported investigation source: ${invalid.join(", ")}. Use claude, codex, opencode, goose, cursor, github, slack, or all.`
6522
6523
  );
6523
6524
  }
6524
6525
  return deduped;
@@ -6585,6 +6586,10 @@ function clientLabel(client) {
6585
6586
  return "goose sessions";
6586
6587
  case "cursor":
6587
6588
  return "Cursor workspace evidence";
6589
+ case "github":
6590
+ return "Git/GitHub proof";
6591
+ case "slack":
6592
+ return "Slack coordination";
6588
6593
  }
6589
6594
  }
6590
6595
  function redactedText(value, limit = 900) {
@@ -6626,6 +6631,18 @@ function makeRawEvent(input) {
6626
6631
  redaction_applied: true
6627
6632
  };
6628
6633
  }
6634
+ function runRuntimeCli(command, args, cwd) {
6635
+ try {
6636
+ return execFileSync(command, args, {
6637
+ cwd,
6638
+ encoding: "utf8",
6639
+ stdio: ["ignore", "pipe", "ignore"],
6640
+ timeout: 5e3
6641
+ });
6642
+ } catch {
6643
+ return null;
6644
+ }
6645
+ }
6629
6646
  function parseJsonLine2(line) {
6630
6647
  try {
6631
6648
  return JSON.parse(line);
@@ -6633,6 +6650,25 @@ function parseJsonLine2(line) {
6633
6650
  return null;
6634
6651
  }
6635
6652
  }
6653
+ function readTextWindow(path, stats, maxBytes) {
6654
+ if (stats.size <= maxBytes) {
6655
+ return { text: readFileSync4(path, "utf8"), truncated: false };
6656
+ }
6657
+ const bytesToRead = Math.min(stats.size, maxBytes);
6658
+ const buffer = Buffer.alloc(bytesToRead);
6659
+ const fd = openSync(path, "r");
6660
+ try {
6661
+ readSync(fd, buffer, 0, bytesToRead, stats.size - bytesToRead);
6662
+ } finally {
6663
+ closeSync(fd);
6664
+ }
6665
+ const raw = buffer.toString("utf8");
6666
+ const firstNewline = raw.indexOf("\n");
6667
+ return {
6668
+ text: firstNewline >= 0 ? raw.slice(firstNewline + 1) : raw,
6669
+ truncated: true
6670
+ };
6671
+ }
6636
6672
  function asText2(value) {
6637
6673
  if (typeof value === "string") return value;
6638
6674
  if (Array.isArray(value)) {
@@ -6668,6 +6704,22 @@ function timestampFor(record, statsMtime) {
6668
6704
  }
6669
6705
  return new Date(statsMtime).toISOString();
6670
6706
  }
6707
+ function mapOrgxRuntimePacket(record, fallbackTimestamp) {
6708
+ if (!isRecord(record) || record.type !== "orgx_work_graph_runtime_event") return [];
6709
+ const timestamp = timestampFor(record, Date.parse(fallbackTimestamp));
6710
+ const role = record.role === "user" || record.role === "assistant" || record.role === "tool" || record.role === "meta" ? record.role : "meta";
6711
+ const toolName = stringField(record, "tool_name", "toolName", "name") ?? void 0;
6712
+ const text2 = asText2(record.content) || asText2(record.message) || asText2(record.text) || asText2(record.summary) || redactedText(JSON.stringify(record));
6713
+ const requestedKind = stringField(record, "event_kind", "kind");
6714
+ const kind = toolName ? requestedKind === "tool_call_error" ? "tool_call_error" : toolName.startsWith("mcp__") ? "mcp_tool_call" : "tool_call_start" : requestedKind === "decision" ? "assistant_reasoning" : requestedKind === "blocker" ? "tool_call_error" : requestedKind === "artifact" ? "file_edit" : requestedKind === "outcome" ? "test_run" : role === "user" ? "user_prompt" : "assistant_text";
6715
+ return [{
6716
+ kind,
6717
+ role,
6718
+ text: text2,
6719
+ ...toolName ? { toolName } : {},
6720
+ timestamp
6721
+ }];
6722
+ }
6671
6723
  function mapCodexRecord(record, fallbackTimestamp) {
6672
6724
  if (!isRecord(record)) return [];
6673
6725
  const timestamp = timestampFor(record, Date.parse(fallbackTimestamp));
@@ -6745,23 +6797,26 @@ function mapClaudeRecord(record, fallbackTimestamp) {
6745
6797
  }
6746
6798
  function readJsonlCandidate(candidate, options) {
6747
6799
  const stats = safeStat(candidate.path);
6748
- if (!stats || stats.size > options.maxBytesPerFile) {
6800
+ if (!stats) {
6749
6801
  return {
6802
+ collectionMethods: [],
6750
6803
  events: [],
6751
6804
  filesRead: 0,
6752
- filesSkipped: [{ path: candidate.path, reason: stats ? "schema_version_unsupported" : "permission_denied" }],
6805
+ filesSkipped: [{ path: candidate.path, reason: "permission_denied" }],
6753
6806
  notes: [],
6754
6807
  searchedSessions: 0
6755
6808
  };
6756
6809
  }
6757
- const lines = readFileSync4(candidate.path, "utf8").split(/\r?\n/);
6810
+ const window = readTextWindow(candidate.path, stats, options.maxBytesPerFile);
6811
+ const lines = window.text.split(/\r?\n/);
6758
6812
  const fallbackTimestamp = new Date(stats.mtimeMs).toISOString();
6759
6813
  const sessionId = basename3(candidate.path).replace(/\.[^.]+$/, "");
6760
6814
  const events = [];
6761
6815
  for (const [index, line] of lines.entries()) {
6762
6816
  if (!line.trim()) continue;
6763
6817
  const record = parseJsonLine2(line);
6764
- const mapped = candidate.source === "codex" ? mapCodexRecord(record, fallbackTimestamp) : candidate.source === "claude_code" ? mapClaudeRecord(record, fallbackTimestamp) : mapGenericJsonRecord(record, fallbackTimestamp);
6818
+ const runtimePacket = mapOrgxRuntimePacket(record, fallbackTimestamp);
6819
+ const mapped = runtimePacket.length > 0 ? runtimePacket : candidate.source === "codex" ? mapCodexRecord(record, fallbackTimestamp) : candidate.source === "claude_code" ? mapClaudeRecord(record, fallbackTimestamp) : mapGenericJsonRecord(record, fallbackTimestamp);
6765
6820
  for (const [partIndex, item] of mapped.entries()) {
6766
6821
  if (!item.text && !item.toolName) continue;
6767
6822
  events.push(makeRawEvent({
@@ -6771,6 +6826,7 @@ function readJsonlCandidate(candidate, options) {
6771
6826
  path: candidate.path,
6772
6827
  payload: {
6773
6828
  extraction_mode: candidate.extractionMode,
6829
+ collection_method: "local_store",
6774
6830
  relative_source_path: candidate.path,
6775
6831
  text_summary: redactedText(item.text),
6776
6832
  tool_name: item.toolName
@@ -6784,10 +6840,11 @@ function readJsonlCandidate(candidate, options) {
6784
6840
  }
6785
6841
  }
6786
6842
  return {
6843
+ collectionMethods: ["local_store"],
6787
6844
  events,
6788
6845
  filesRead: 1,
6789
6846
  filesSkipped: [],
6790
- notes: [],
6847
+ notes: window.truncated ? [`Read the latest ${options.maxBytesPerFile} bytes from oversized JSONL source instead of skipping it.`] : [],
6791
6848
  searchedSessions: 1
6792
6849
  };
6793
6850
  }
@@ -6819,6 +6876,7 @@ function readJsonCandidate(candidate, options) {
6819
6876
  const stats = safeStat(candidate.path);
6820
6877
  if (!stats || stats.size > options.maxBytesPerFile) {
6821
6878
  return {
6879
+ collectionMethods: [],
6822
6880
  events: [],
6823
6881
  filesRead: 0,
6824
6882
  filesSkipped: [{ path: candidate.path, reason: stats ? "schema_version_unsupported" : "permission_denied" }],
@@ -6831,6 +6889,7 @@ function readJsonCandidate(candidate, options) {
6831
6889
  parsed = JSON.parse(readFileSync4(candidate.path, "utf8"));
6832
6890
  } catch {
6833
6891
  return {
6892
+ collectionMethods: [],
6834
6893
  events: [],
6835
6894
  filesRead: 0,
6836
6895
  filesSkipped: [{ path: candidate.path, reason: "binary_or_corrupt" }],
@@ -6845,14 +6904,16 @@ function readJsonCandidate(candidate, options) {
6845
6904
  (record, index) => mapGenericJsonRecord(record, fallbackTimestamp).map(
6846
6905
  (item, partIndex) => makeRawEvent({
6847
6906
  client: candidate.source,
6848
- kind: item.kind,
6907
+ kind: candidate.source === "slack" ? "slack_message" : candidate.source === "github" && item.kind === "assistant_text" ? "pr_event" : item.kind,
6849
6908
  now: options.now,
6850
6909
  path: candidate.path,
6851
6910
  payload: {
6852
6911
  extraction_mode: candidate.extractionMode,
6912
+ collection_method: "local_store",
6853
6913
  relative_source_path: candidate.path,
6854
6914
  text_summary: redactedText(item.text),
6855
- tool_name: item.toolName
6915
+ tool_name: item.toolName,
6916
+ actor: isRecord(record) ? stringField(record, "user", "username", "actor", "author", "sender") : void 0
6856
6917
  },
6857
6918
  rawRowId: String(index),
6858
6919
  role: item.role,
@@ -6863,6 +6924,7 @@ function readJsonCandidate(candidate, options) {
6863
6924
  )
6864
6925
  );
6865
6926
  return {
6927
+ collectionMethods: ["local_store"],
6866
6928
  events,
6867
6929
  filesRead: 1,
6868
6930
  filesSkipped: [],
@@ -6893,6 +6955,7 @@ function readMarkdownCandidate(candidate, options) {
6893
6955
  const stats = safeStat(candidate.path);
6894
6956
  if (!stats || stats.size > options.maxBytesPerFile) {
6895
6957
  return {
6958
+ collectionMethods: [],
6896
6959
  events: [],
6897
6960
  filesRead: 0,
6898
6961
  filesSkipped: [{ path: candidate.path, reason: stats ? "schema_version_unsupported" : "permission_denied" }],
@@ -6910,6 +6973,7 @@ function readMarkdownCandidate(candidate, options) {
6910
6973
  path: candidate.path,
6911
6974
  payload: {
6912
6975
  extraction_mode: candidate.extractionMode,
6976
+ collection_method: "local_store",
6913
6977
  relative_source_path: candidate.path,
6914
6978
  text_summary: redactedText(text2, 1200),
6915
6979
  tool_usage_state: candidate.path.includes("mcp.json") ? "configured" : void 0
@@ -6920,6 +6984,7 @@ function readMarkdownCandidate(candidate, options) {
6920
6984
  uriSuffix: "markdown:0"
6921
6985
  });
6922
6986
  return {
6987
+ collectionMethods: ["local_store"],
6923
6988
  events: [event],
6924
6989
  filesRead: 1,
6925
6990
  filesSkipped: [],
@@ -6927,6 +6992,158 @@ function readMarkdownCandidate(candidate, options) {
6927
6992
  searchedSessions: 1
6928
6993
  };
6929
6994
  }
6995
+ function readGitReflogCandidate(candidate, options) {
6996
+ const stats = safeStat(candidate.path);
6997
+ if (!stats || stats.size > options.maxBytesPerFile) {
6998
+ return {
6999
+ collectionMethods: [],
7000
+ events: [],
7001
+ filesRead: 0,
7002
+ filesSkipped: [{ path: candidate.path, reason: stats ? "schema_version_unsupported" : "permission_denied" }],
7003
+ notes: [],
7004
+ searchedSessions: 0
7005
+ };
7006
+ }
7007
+ const lines = readFileSync4(candidate.path, "utf8").split(/\r?\n/).filter(Boolean).slice(-250);
7008
+ const events = [];
7009
+ const fallbackTimestamp = new Date(stats.mtimeMs).toISOString();
7010
+ for (const [index, line] of lines.entries()) {
7011
+ const [meta = "", message = ""] = line.split(" ");
7012
+ const parts = meta.trim().split(/\s+/);
7013
+ const commitSha = parts[1] ?? parts[0] ?? "";
7014
+ if (!/^[0-9a-f]{12,40}$/i.test(commitSha)) continue;
7015
+ const timestampSeconds = Number(parts.at(-2));
7016
+ const timestamp = Number.isFinite(timestampSeconds) ? new Date(timestampSeconds * 1e3).toISOString() : fallbackTimestamp;
7017
+ const actor = meta.match(/^[0-9a-f]{40}\s+[0-9a-f]{40}\s+(.+?)\s+\d+\s+[+-]\d{4}/i)?.[1]?.trim();
7018
+ const summary = message.trim() || `commit ${commitSha.slice(0, 12)}`;
7019
+ events.push(makeRawEvent({
7020
+ client: "github",
7021
+ kind: "commit",
7022
+ now: options.now,
7023
+ path: candidate.path,
7024
+ payload: {
7025
+ extraction_mode: candidate.extractionMode,
7026
+ collection_method: "local_store",
7027
+ relative_source_path: candidate.path,
7028
+ text_summary: redactedText(`Commit ${commitSha.slice(0, 12)}: ${summary}`),
7029
+ commit_sha: commitSha,
7030
+ actor,
7031
+ proof_kind: "commit_landed"
7032
+ },
7033
+ rawByteOffset: index,
7034
+ role: "meta",
7035
+ sessionId: "git-reflog-head",
7036
+ timestamp,
7037
+ uriSuffix: `reflog:${index}:${commitSha.slice(0, 12)}`
7038
+ }));
7039
+ }
7040
+ return {
7041
+ collectionMethods: ["local_store"],
7042
+ events,
7043
+ filesRead: 1,
7044
+ filesSkipped: [],
7045
+ notes: ["Git reflog evidence is local commit proof; remote PR metadata still requires a GitHub export or API-backed source."],
7046
+ searchedSessions: 1
7047
+ };
7048
+ }
7049
+ function collectGithubRuntimeCli(input) {
7050
+ const insideRepo = runRuntimeCli("git", ["rev-parse", "--is-inside-work-tree"], input.cwd)?.trim() === "true";
7051
+ if (!insideRepo) return null;
7052
+ const since = `${input.sinceDays} days ago`;
7053
+ const log = runRuntimeCli("git", [
7054
+ "log",
7055
+ `--since=${since}`,
7056
+ `--max-count=${Math.max(1, input.limit)}`,
7057
+ "--format=%H%x1f%an%x1f%aI%x1f%s"
7058
+ ], input.cwd);
7059
+ const events = [];
7060
+ const notes = ["GitHub source collected through the local git runtime CLI before falling back to repository files."];
7061
+ if (log?.trim()) {
7062
+ for (const [index, line] of log.trim().split(/\r?\n/).entries()) {
7063
+ const [commitSha, actor, timestamp, subject] = line.split("");
7064
+ if (!commitSha || !timestamp || !subject) continue;
7065
+ events.push(makeRawEvent({
7066
+ client: "github",
7067
+ kind: "commit",
7068
+ now: input.now,
7069
+ path: input.cwd,
7070
+ payload: {
7071
+ extraction_mode: "terminal_log",
7072
+ collection_method: "runtime_cli",
7073
+ runtime_cli: "git log",
7074
+ text_summary: redactedText(`Commit ${commitSha.slice(0, 12)}: ${subject}`),
7075
+ commit_sha: commitSha,
7076
+ actor: actor ? redactedText(actor, 120) : void 0,
7077
+ proof_kind: "commit_landed"
7078
+ },
7079
+ rawRowId: String(index),
7080
+ role: "meta",
7081
+ sessionId: "git-log",
7082
+ timestamp,
7083
+ uriSuffix: `git-log:${index}:${commitSha.slice(0, 12)}`
7084
+ }));
7085
+ }
7086
+ }
7087
+ const ghJson = runRuntimeCli("gh", [
7088
+ "pr",
7089
+ "list",
7090
+ "--state",
7091
+ "all",
7092
+ "--limit",
7093
+ String(Math.max(1, Math.min(30, input.limit))),
7094
+ "--json",
7095
+ "number,title,state,url,mergedAt,updatedAt,author,headRefName"
7096
+ ], input.cwd);
7097
+ if (ghJson?.trim()) {
7098
+ try {
7099
+ const prs = JSON.parse(ghJson);
7100
+ if (Array.isArray(prs)) {
7101
+ for (const [index, pr] of prs.entries()) {
7102
+ if (!isRecord(pr)) continue;
7103
+ const title = typeof pr.title === "string" ? pr.title : `PR ${String(pr.number ?? index + 1)}`;
7104
+ const timestamp = typeof pr.mergedAt === "string" && pr.mergedAt ? pr.mergedAt : typeof pr.updatedAt === "string" && pr.updatedAt ? pr.updatedAt : input.now.toISOString();
7105
+ const author = isRecord(pr.author) && typeof pr.author.login === "string" ? pr.author.login : void 0;
7106
+ events.push(makeRawEvent({
7107
+ client: "github",
7108
+ kind: "pr_event",
7109
+ now: input.now,
7110
+ path: input.cwd,
7111
+ payload: {
7112
+ extraction_mode: "terminal_log",
7113
+ collection_method: "runtime_cli",
7114
+ runtime_cli: "gh pr list",
7115
+ text_summary: redactedText(`PR ${String(pr.number ?? index + 1)} ${String(pr.state ?? "UNKNOWN")}: ${title}`),
7116
+ actor: author,
7117
+ pr_number: pr.number,
7118
+ pr_state: pr.state,
7119
+ pr_url: pr.url,
7120
+ proof_kind: pr.state === "MERGED" ? "commit_landed" : "pull_request_seen"
7121
+ },
7122
+ rawRowId: String(index),
7123
+ role: "meta",
7124
+ sessionId: "gh-pr-list",
7125
+ timestamp,
7126
+ uriSuffix: `gh-pr:${String(pr.number ?? index + 1)}`
7127
+ }));
7128
+ }
7129
+ }
7130
+ } catch {
7131
+ notes.push("gh pr list returned unreadable JSON; git commit evidence was still retained.");
7132
+ }
7133
+ } else {
7134
+ notes.push("GitHub CLI PR metadata was unavailable; install or authenticate gh to attach PR/review proof.");
7135
+ }
7136
+ if (events.length === 0) return null;
7137
+ return {
7138
+ collectionMethods: ["runtime_cli"],
7139
+ collector: "runtime_cli",
7140
+ events,
7141
+ filesRead: 0,
7142
+ filesSkipped: [],
7143
+ notes,
7144
+ searchedSessions: new Set(events.map((event) => event.session_id)).size
7145
+ };
7146
+ }
6930
7147
  function discoverCandidates(source, env, sinceMs) {
6931
7148
  const candidates = [];
6932
7149
  const addFiles = (paths, extractionMode, predicate) => {
@@ -6943,9 +7160,16 @@ function discoverCandidates(source, env, sinceMs) {
6943
7160
  }
6944
7161
  };
6945
7162
  if (source === "codex") {
6946
- addFiles([CODEX_SESSIONS_DIR], "jsonl", (path) => path.endsWith(".jsonl"));
7163
+ addFiles([
7164
+ "$CWD/.orgx/work-graph/runtime-events/codex",
7165
+ CODEX_SESSIONS_DIR
7166
+ ], "jsonl", (path) => path.endsWith(".jsonl"));
6947
7167
  } else if (source === "claude_code") {
6948
- addFiles([CLAUDE_PROJECTS_DIR], "jsonl", (path) => path.endsWith(".jsonl"));
7168
+ addFiles([
7169
+ "$CWD/.orgx/work-graph/runtime-events/claude-code",
7170
+ "$CWD/.orgx/work-graph/runtime-events/claude",
7171
+ CLAUDE_PROJECTS_DIR
7172
+ ], "jsonl", (path) => path.endsWith(".jsonl"));
6949
7173
  } else if (source === "opencode") {
6950
7174
  addFiles([
6951
7175
  "~/.local/share/opencode/storage/session",
@@ -6976,6 +7200,19 @@ function discoverCandidates(source, env, sinceMs) {
6976
7200
  "~/Library/Application Support/Cursor/User/workspaceStorage",
6977
7201
  "~/.config/Cursor/User/workspaceStorage"
6978
7202
  ], "sqlite", (path) => path.endsWith("state.vscdb"));
7203
+ } else if (source === "github") {
7204
+ addFiles(["$CWD/.git/logs/HEAD"], "terminal_log", (path) => path.endsWith("/.git/logs/HEAD"));
7205
+ addFiles([
7206
+ "$CWD/.orgx/github",
7207
+ "$CWD/.github/work-graph",
7208
+ "~/.orgx/github"
7209
+ ], "json", (path) => path.endsWith(".json"));
7210
+ } else if (source === "slack") {
7211
+ addFiles([
7212
+ "$CWD/.orgx/slack",
7213
+ "$CWD/.slack",
7214
+ "~/.orgx/slack"
7215
+ ], "json", (path) => path.endsWith(".json"));
6979
7216
  }
6980
7217
  return candidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
6981
7218
  }
@@ -6990,10 +7227,23 @@ function discoverOverrideCandidates(source, root, sinceMs) {
6990
7227
  }
6991
7228
  return candidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
6992
7229
  }
7230
+ function collectRuntimeCliSource(source, env, options) {
7231
+ if (source === "github") {
7232
+ return collectGithubRuntimeCli({
7233
+ cwd: env.cwd,
7234
+ limit: options.limit,
7235
+ now: options.now,
7236
+ sinceDays: options.sinceDays
7237
+ });
7238
+ }
7239
+ return null;
7240
+ }
6993
7241
  function findingTypeFromEvent(event) {
6994
7242
  const text2 = `${event.payload.text_summary ?? ""}
6995
7243
  ${event.payload.tool_name ?? ""}`;
6996
7244
  if (!WORK_SIGNAL_PATTERN.test(text2)) return null;
7245
+ if (event.kind === "commit" || event.kind === "pr_event") return "artifact";
7246
+ if (event.kind === "slack_message") return /\b(decision|approved|owner|handoff|blocked|launch)\b/i.test(text2) ? "decision" : "action";
6997
7247
  if (/\b(decision|decided|tradeoff|architecture|approval)\b/i.test(text2)) return "decision";
6998
7248
  if (/\b(blocked|blocker|failed|fails|error|timeout|permission|schema|zod|invalid)\b/i.test(text2)) return "blocker";
6999
7249
  if (/\b(artifact|implemented|created|changed|edited|commit|pr|file|shipped|deploy)\b/i.test(text2)) return "artifact";
@@ -7032,6 +7282,12 @@ function extractionFromEvents(input) {
7032
7282
  event_id: event.event_id,
7033
7283
  event_kind: event.kind,
7034
7284
  extraction_mode: event.payload.extraction_mode,
7285
+ collection_method: event.payload.collection_method,
7286
+ runtime_cli: event.payload.runtime_cli,
7287
+ actor: event.payload.actor,
7288
+ commit_sha: event.payload.commit_sha,
7289
+ proof_kind: event.payload.proof_kind ?? (event.kind === "commit" ? "commit_landed" : void 0),
7290
+ owner_ref: event.kind === "slack_message" ? event.payload.actor : void 0,
7035
7291
  provider: event.provider,
7036
7292
  tool_name: event.payload.tool_name
7037
7293
  }
@@ -7043,6 +7299,7 @@ function extractionFromEvents(input) {
7043
7299
  extraction_id: `${input.client}:investigation:${hash([input.client, input.events.map((event) => event.event_id)], 12)}`,
7044
7300
  source_client: workGraphSourceClient(input.client),
7045
7301
  source_label: clientLabel(input.client),
7302
+ collection_methods: [...new Set(input.collectionMethods)].sort(),
7046
7303
  searched_sources: [...new Set(input.events.map((event) => String(event.payload.relative_source_path ?? event.session_id)))].slice(0, 30),
7047
7304
  search_queries: [
7048
7305
  {
@@ -7072,6 +7329,7 @@ function loadWorkGraphInvestigationSourceData(options) {
7072
7329
  home: options.home ?? homedir2()
7073
7330
  };
7074
7331
  const sinceMs = now.getTime() - (options.sinceDays ?? DEFAULT_SINCE_DAYS2) * 24 * 60 * 60 * 1e3;
7332
+ const sinceDays = options.sinceDays ?? DEFAULT_SINCE_DAYS2;
7075
7333
  const limit = Math.max(1, options.limitPerSource ?? DEFAULT_LIMIT_PER_SOURCE2);
7076
7334
  const maxBytesPerFile = Math.max(1, options.maxBytesPerFile ?? DEFAULT_MAX_BYTES_PER_FILE2);
7077
7335
  const rawEvents = [];
@@ -7083,23 +7341,26 @@ function loadWorkGraphInvestigationSourceData(options) {
7083
7341
  if (options.claudeProjectsDir) sourceOverrides.set("claude_code", resolve(options.claudeProjectsDir));
7084
7342
  for (const source of options.sources) {
7085
7343
  const overrideRoot = sourceOverrides.get(source);
7344
+ const runtimeCliResult = overrideRoot ? null : collectRuntimeCliSource(source, env, { limit, now, sinceDays });
7086
7345
  const candidates = (overrideRoot ? discoverOverrideCandidates(source, overrideRoot, sinceMs) : discoverCandidates(source, env, sinceMs)).slice(0, limit);
7087
- if (candidates.length === 0) {
7346
+ if (!runtimeCliResult && candidates.length === 0) {
7088
7347
  missingSources.push(`${clientLabel(source)} store`);
7089
7348
  continue;
7090
7349
  }
7091
- const sourceEvents = [];
7350
+ const sourceEvents = runtimeCliResult ? [...runtimeCliResult.events] : [];
7351
+ const collectionMethods = runtimeCliResult ? [...runtimeCliResult.collectionMethods] : [];
7092
7352
  const filesSkipped = [];
7093
- let filesRead = 0;
7094
- const notes = [];
7353
+ let filesRead = runtimeCliResult?.filesRead ?? 0;
7354
+ const notes = runtimeCliResult?.notes ? [...runtimeCliResult.notes] : [];
7095
7355
  for (const candidate of candidates) {
7096
7356
  if (candidate.extractionMode === "sqlite") {
7097
7357
  filesSkipped.push({ path: candidate.path, reason: "schema_version_unsupported" });
7098
7358
  notes.push(`${candidate.path} detected; SQLite extraction is reserved for the cloud/runtime adapter reader.`);
7099
7359
  continue;
7100
7360
  }
7101
- const result = candidate.path.endsWith(".jsonl") ? readJsonlCandidate(candidate, { maxBytesPerFile, now }) : candidate.path.endsWith(".json") && !candidate.path.endsWith("mcp.json") ? readJsonCandidate(candidate, { maxBytesPerFile, now }) : readMarkdownCandidate(candidate, { maxBytesPerFile, now });
7361
+ const result = candidate.source === "github" && candidate.extractionMode === "terminal_log" ? readGitReflogCandidate(candidate, { maxBytesPerFile, now }) : candidate.path.endsWith(".jsonl") ? readJsonlCandidate(candidate, { maxBytesPerFile, now }) : candidate.path.endsWith(".json") && !candidate.path.endsWith("mcp.json") ? readJsonCandidate(candidate, { maxBytesPerFile, now }) : readMarkdownCandidate(candidate, { maxBytesPerFile, now });
7102
7362
  sourceEvents.push(...result.events);
7363
+ collectionMethods.push(...result.collectionMethods);
7103
7364
  filesRead += result.filesRead;
7104
7365
  filesSkipped.push(...result.filesSkipped);
7105
7366
  notes.push(...result.notes);
@@ -7107,6 +7368,7 @@ function loadWorkGraphInvestigationSourceData(options) {
7107
7368
  rawEvents.push(...sourceEvents);
7108
7369
  clientExtractions.push(extractionFromEvents({
7109
7370
  client: source,
7371
+ collectionMethods,
7110
7372
  events: sourceEvents,
7111
7373
  filesRead,
7112
7374
  filesSkipped,
@@ -7854,6 +8116,9 @@ function providerForClient2(client) {
7854
8116
  return "unknown";
7855
8117
  }
7856
8118
  function eventKindForFinding(finding) {
8119
+ if (finding.source_client === "github") return finding.type === "outcome" ? "test_run" : "commit";
8120
+ if (finding.source_client === "slack") return "slack_message";
8121
+ if (finding.source_client === "orgx_runtime_hook" || finding.source_client === "mcp") return "mcp_tool_call";
7857
8122
  if (finding.type === "decision") return "assistant_reasoning";
7858
8123
  if (finding.type === "artifact") return "file_edit";
7859
8124
  if (finding.type === "blocker") return "tool_call_error";
@@ -7882,6 +8147,10 @@ function rawEventFromFinding(finding, index, generatedAt) {
7882
8147
  finding_type: finding.type,
7883
8148
  source_id: finding.source_id,
7884
8149
  confidence: finding.confidence,
8150
+ commit_sha: finding.metadata.commit_sha,
8151
+ owner_ref: finding.metadata.owner_ref,
8152
+ proof_kind: finding.metadata.proof_kind,
8153
+ writeback_ref: finding.metadata.writeback_ref,
7885
8154
  redacted_verbatim: typeof finding.metadata.redacted_verbatim === "string" ? finding.metadata.redacted_verbatim : finding.summary.slice(0, 420)
7886
8155
  };
7887
8156
  return {
@@ -7985,7 +8254,31 @@ function bottleneckClassForText(text2) {
7985
8254
  if (/owner|handoff|dri|approval/i.test(text2)) return "human_handoff_missing";
7986
8255
  return null;
7987
8256
  }
7988
- function terminalForTrail(trail) {
8257
+ function terminalForTrail(trail, events = [], findings = []) {
8258
+ const proofRef = trail.evidence_refs[0];
8259
+ const proofFromEvent = events.find((event) => event.kind === "commit" || event.kind === "pr_event" || event.kind === "test_run");
8260
+ const mcpWriteback = events.find(
8261
+ (event) => event.kind === "mcp_tool_call" && /\borgx|complete_with_proof|record_outcome|writeback|orgx_emit_activity\b/i.test(
8262
+ `${event.payload.tool_name ?? ""}
8263
+ ${event.payload.text_summary ?? ""}`
8264
+ )
8265
+ );
8266
+ const githubFinding = findings.find(
8267
+ (finding) => finding.source_client === "github" || /commit_landed|pull request|github|commit/i.test(JSON.stringify(finding.metadata ?? {}))
8268
+ );
8269
+ const runtimeFinding = findings.find(
8270
+ (finding) => finding.source_client === "orgx_runtime_hook" || finding.source_client === "mcp" || /mcp_writeback_succeeded|complete_with_proof|record_outcome|orgx_emit_activity/i.test(JSON.stringify(finding.metadata ?? {}))
8271
+ );
8272
+ const proofState = (kind, ref) => ref ? { kind, ref } : { kind };
8273
+ const verifiedProof = proofFromEvent?.kind === "commit" || proofFromEvent?.kind === "pr_event" || githubFinding ? proofState("commit_landed", proofFromEvent?.event_id ?? githubFinding?.evidence_ref ?? proofRef) : proofFromEvent?.kind === "test_run" ? proofState("test_passed", proofFromEvent.event_id) : mcpWriteback || runtimeFinding ? proofState("mcp_writeback_succeeded", mcpWriteback?.event_id ?? runtimeFinding?.evidence_ref ?? proofRef) : null;
8274
+ if (verifiedProof) {
8275
+ return {
8276
+ state: "shipped",
8277
+ proof: verifiedProof,
8278
+ classified_by: "deterministic",
8279
+ classification_basis: ["terminal_proof_event_present"]
8280
+ };
8281
+ }
7989
8282
  if (trail.state === "verified" || trail.valence === "healthy") {
7990
8283
  return {
7991
8284
  state: "shipped",
@@ -8035,7 +8328,7 @@ function buildWorkLoops(input) {
8035
8328
  ...matchedFindings.map((finding) => finding.summary)
8036
8329
  ].join("\n");
8037
8330
  const bottleneck = bottleneckClassForText(text2);
8038
- const terminal = terminalForTrail(trail);
8331
+ const terminal = terminalForTrail(trail, matchedEvents, matchedFindings);
8039
8332
  const confidence = clamp(
8040
8333
  trail.confidence || matchedFindings.reduce((total, finding) => total + finding.confidence, 0) / Math.max(1, matchedFindings.length)
8041
8334
  );
@@ -8338,10 +8631,43 @@ function buildCorpusManifest(input) {
8338
8631
  0
8339
8632
  );
8340
8633
  const sessions = manifests.reduce((total, source) => total + source.sessions, 0);
8634
+ const byClient = Object.fromEntries(
8635
+ manifests.map((source) => {
8636
+ const sourceEvents = input.events.filter((event) => event.source_id === source.source_id);
8637
+ const skippedCount = source.files_skipped.reduce((total, skipped) => total + skipped.count, 0);
8638
+ const limitations = [
8639
+ ...Object.values(source.capability_cells).flatMap((cell) => cell.blockers_to_full),
8640
+ ...source.status === "missing" || source.status === "supported_not_connected" ? ["source_not_connected"] : [],
8641
+ ...source.status === "detected_not_read" ? ["detected_without_readable_events"] : []
8642
+ ];
8643
+ return [
8644
+ source.source_id,
8645
+ {
8646
+ detected: source.status === "connected" || source.status === "partial" || source.status === "detected_not_read" || source.storage_paths_resolved.length > 0,
8647
+ connected: source.status === "connected" || source.status === "partial",
8648
+ status: source.status,
8649
+ extractionMode: source.extraction_mode,
8650
+ provider: source.provider,
8651
+ sessions: source.sessions,
8652
+ turns: source.message_turns,
8653
+ toolCalls: source.tool_calls,
8654
+ mcpToolCalls: source.mcp_tool_calls,
8655
+ commands: sourceEvents.filter((event) => event.kind === "shell_command").length,
8656
+ fileEdits: sourceEvents.filter((event) => event.kind === "file_edit").length,
8657
+ tests: sourceEvents.filter((event) => event.kind === "test_run").length,
8658
+ errors: sourceEvents.filter((event) => event.kind === "tool_call_error" || event.kind === "error_emitted").length,
8659
+ skipped: skippedCount,
8660
+ limitations: Array.from(new Set(limitations)).sort(),
8661
+ schemaVersionDetected: source.storage_version_detected
8662
+ }
8663
+ ];
8664
+ })
8665
+ );
8341
8666
  return {
8342
8667
  audit_id: input.auditId,
8343
8668
  ran_at: input.generatedAt,
8344
8669
  sources: manifests,
8670
+ byClient,
8345
8671
  totals: {
8346
8672
  files_seen: Math.max(filesSeen, input.auditMethod.searched_session_files),
8347
8673
  files_read: Math.max(filesRead, input.auditMethod.searched_session_files - input.auditMethod.skipped_session_files),
@@ -8630,10 +8956,11 @@ function buildMirror(input) {
8630
8956
  const dropped = input.loops.filter((loop) => !loop.survived_critic).length;
8631
8957
  const terminal = topFamily?.shared_terminal_state ?? "ongoing";
8632
8958
  const terminalPhrase = `${articleFor(terminal)} ${terminal}`;
8959
+ const topSourceLabels = input.corpus.sources.filter((source) => source.status === "connected" || source.status === "partial").slice(0, 4).map((source) => source.brand.name).join(", ");
8633
8960
  const text2 = [
8634
- `You have AI-assisted work spread across ${sourceCount} connected or partial source${sourceCount === 1 ? "" : "s"}, but the execution record is still incomplete.`,
8635
- topFamily ? `The clearest repeated loop is ${topFamily.semantic_centroid}: ${topFamily.appearances} appearance${topFamily.appearances === 1 ? "" : "s"} with ${terminalPhrase} state.` : topLoop ? `The clearest work loop is "${topLoop.origin.intent}", but it still needs more chronology before OrgX should call it recurring.` : "The corpus did not produce a verified work loop yet.",
8636
- input.counterfactuals[0] ? `OrgX can point to the exact event where it would have called ${input.counterfactuals[0].orgx_capability.tool} and what entity it would have created.` : "Counterfactual repair is waiting on a higher-confidence loop with resolved citations.",
8961
+ `Your AI-assisted work spans ${sourceCount} connected or partial source${sourceCount === 1 ? "" : "s"}${topSourceLabels ? ` (${topSourceLabels})` : ""}, but the execution record is still incomplete.`,
8962
+ topFamily ? `The clearest repeated loop is "${topFamily.semantic_centroid}": ${topFamily.appearances} appearance${topFamily.appearances === 1 ? "" : "s"} ending in ${terminalPhrase} state.` : topLoop ? `The clearest work loop is "${topLoop.origin.intent}", but it needs more chronology before OrgX should call it recurring.` : "The corpus did not produce a verified work loop yet.",
8963
+ input.counterfactuals[0] ? `The earned repair is concrete: OrgX can point to the event where it would have called ${input.counterfactuals[0].orgx_capability.tool} and the entity it would have created.` : "Counterfactual repair is waiting on a higher-confidence loop with resolved citations.",
8637
8964
  `The current estimate is ${input.impact.time_saved_hours_per_week} recoverable hours/week, grounded in ${input.impact.basis[0] ?? "resolved work-loop evidence"}.`,
8638
8965
  dropped > 0 ? `${dropped} weak signal${dropped === 1 ? " was" : "s were"} kept out of the public readout because the citations or critic score did not clear the bar.` : "Every surfaced loop cleared citation verification and the critic floor."
8639
8966
  ].join(" ");
@@ -8906,6 +9233,9 @@ function titleFromText(text2, fallback) {
8906
9233
  if (lower.includes("mcp__orgx__orgx_search") && lower.includes("zod")) {
8907
9234
  return "OrgX MCP orgx_search is failing schema validation";
8908
9235
  }
9236
+ if (lower.includes("mcporgxlistentities") || lower.includes("listentities")) {
9237
+ return "OrgX entity lookup needs human-readable evidence mapping";
9238
+ }
8909
9239
  if (lower.includes("orgx_write") && lower.includes("auto_continue") && lower.includes("dispatch")) {
8910
9240
  return "orgx_write creates ready streams without dispatching agent runs";
8911
9241
  }
@@ -9144,7 +9474,7 @@ ${extractionText}`.toLowerCase();
9144
9474
  ...sourceClients.includes("slack") ? ["Slack coordination"] : []
9145
9475
  ];
9146
9476
  const inferredMissing = [
9147
- ...missingSources,
9477
+ ...missingSources.map(normalizeMissingSourceLabel),
9148
9478
  ...sourceClients.includes("slack") ? [] : ["Slack coordination"],
9149
9479
  ...sourceClients.includes("github") ? [] : ["GitHub PR/commit proof"],
9150
9480
  ...allText.includes("hook") || allText.includes("outbox") ? [] : ["Runtime hook outbox replay"]
@@ -9160,7 +9490,7 @@ ${extractionText}`.toLowerCase();
9160
9490
  });
9161
9491
  const partialCount = manifests.filter((manifest) => manifest.status === "partial").length;
9162
9492
  const coverageScore = clampScore2(
9163
- 28 + Math.min(34, connected.length * 7) + Math.min(18, findings.length * 2) + (sourceClients.includes("codex") ? 6 : 0) + (sourceClients.includes("claude") || sourceClients.includes("claude-code") ? 6 : 0) + (sourceClients.includes("cursor") ? 4 : 0) + (sourceClients.includes("opencode") ? 4 : 0) + (sourceClients.includes("goose") ? 4 : 0) - missing.length * 7 - partialCount * 3
9493
+ 28 + Math.min(34, connected.length * 7) + Math.min(18, findings.length * 2) + (sourceClients.includes("codex") ? 6 : 0) + (sourceClients.includes("claude") || sourceClients.includes("claude-code") ? 6 : 0) + (sourceClients.includes("cursor") ? 4 : 0) + (sourceClients.includes("opencode") ? 4 : 0) + (sourceClients.includes("goose") ? 4 : 0) + (sourceClients.includes("github") ? 6 : 0) + (sourceClients.includes("slack") ? 5 : 0) + (sourceClients.includes("orgx_runtime_hook") || sourceClients.includes("mcp") ? 7 : 0) - partialCount * 3
9164
9494
  );
9165
9495
  return {
9166
9496
  connected,
@@ -9173,7 +9503,7 @@ ${extractionText}`.toLowerCase();
9173
9503
  manifests,
9174
9504
  notes: [
9175
9505
  "OrgX/MCP writeback is one coverage signal; it is not required for the audit to find useful work.",
9176
- missing.length > 0 ? `Coverage is limited by missing sources: ${missing.join(", ")}.` : "Connected sources are sufficient for a first-pass operating profile, but still require user review."
9506
+ missing.length > 0 ? `Additional sources can raise the ceiling: ${missing.join(", ")}.` : "Connected sources are sufficient for a first-pass operating profile, but still require user review."
9177
9507
  ]
9178
9508
  };
9179
9509
  }
@@ -9301,6 +9631,17 @@ function labelForSourceClient(sourceClient) {
9301
9631
  return sourceClient.replace(/[-_]/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
9302
9632
  }
9303
9633
  }
9634
+ function normalizeMissingSourceLabel(source) {
9635
+ if (/slack/i.test(source)) return "Slack coordination";
9636
+ if (/github|git\/github|commit|pr/i.test(source)) return "GitHub PR/commit proof";
9637
+ if (/runtime|hook|outbox/i.test(source)) return "Runtime hook outbox replay";
9638
+ if (/codex/i.test(source)) return "Codex session history";
9639
+ if (/claude/i.test(source)) return "Claude Code sessions";
9640
+ if (/cursor/i.test(source)) return "Cursor workspace history";
9641
+ if (/opencode/i.test(source)) return "OpenCode sessions";
9642
+ if (/goose/i.test(source)) return "goose sessions";
9643
+ return source.replace(/\s+(?:store|readable events|audit-relevant session lines)$/i, "").trim();
9644
+ }
9304
9645
  function summarizeClientExtractions(clientExtractions) {
9305
9646
  return clientExtractions.map((extraction, index) => {
9306
9647
  const extractionId = normalizeClientExtractionId(extraction, index);
@@ -9308,6 +9649,7 @@ function summarizeClientExtractions(clientExtractions) {
9308
9649
  extraction_id: extractionId,
9309
9650
  source_client: normalizeSourceClient(extraction.source_client),
9310
9651
  source_label: extraction.source_label?.trim() || `${extraction.source_client || "Unknown"} AI-client extraction`,
9652
+ collection_methods: [...new Set(extraction.collection_methods ?? [])].sort(),
9311
9653
  searched_source_count: extraction.searched_sources?.length ?? 0,
9312
9654
  searched_session_count: extraction.extraction_quality?.searched_session_count ?? 0,
9313
9655
  skipped_session_count: extraction.extraction_quality?.skipped_session_count ?? 0,
@@ -9332,6 +9674,7 @@ function buildClientExtractionEvents(clientExtractions) {
9332
9674
  ].join(" "),
9333
9675
  evidence_ref: `${summary.extraction_id}:summary`,
9334
9676
  metadata: {
9677
+ collection_methods: summary.collection_methods,
9335
9678
  finding_count: summary.finding_count,
9336
9679
  query_count: summary.query_count,
9337
9680
  searched_source_count: summary.searched_source_count,
@@ -9364,6 +9707,10 @@ function buildAuditMethod(input) {
9364
9707
  const explicit = numberFromImportMetadata(source, "retained_line_count");
9365
9708
  return total + (explicit || source.text.split(/\r?\n/).filter(Boolean).length);
9366
9709
  }, 0);
9710
+ const extractionRetainedLines = extractionSummaries.reduce(
9711
+ (total, summary) => total + summary.finding_count,
9712
+ 0
9713
+ );
9367
9714
  const skippedFiles = input.imports.reduce(
9368
9715
  (total, source) => total + numberFromImportMetadata(source, "skipped_file_count"),
9369
9716
  0
@@ -9385,7 +9732,7 @@ function buildAuditMethod(input) {
9385
9732
  searched_session_files: input.imports.length + extractionSearchedSessions,
9386
9733
  skipped_session_files: skippedFiles + extractionSkippedSessions,
9387
9734
  searched_message_count: searchedMessages,
9388
- retained_evidence_lines: retainedLines,
9735
+ retained_evidence_lines: retainedLines + extractionRetainedLines,
9389
9736
  searched_source_groups: sourceGroups.length,
9390
9737
  extraction_lenses: input.extractionProtocol.schema.source_search_strategy.map((lens) => lens.lens),
9391
9738
  client_native_packs: nativePacks,
@@ -9837,7 +10184,7 @@ function estimateImpactProjection(input) {
9837
10184
  `${blockerEvents} blocker event${blockerEvents === 1 ? "" : "s"} at 45 minutes of reconstruction/coordination each.`,
9838
10185
  `${decisionEvents} decision event${decisionEvents === 1 ? "" : "s"} at 27 minutes of rediscovery/promotion each.`,
9839
10186
  `${missedCount} missed orchestration signal${missedCount === 1 ? "" : "s"} at 39 minutes of manual writeback each.`,
9840
- `${coverage.missing.length} missing source${coverage.missing.length === 1 ? "" : "s"} reducing attribution confidence.`
10187
+ `${coverage.missing.length} source gap${coverage.missing.length === 1 ? "" : "s"} increasing the AQ ceiling rather than lowering the current score.`
9841
10188
  ],
9842
10189
  assumptions: [
9843
10190
  "Uses a conservative $200/hour blended founder/operator cost for public-safe value estimates.",
@@ -9852,7 +10199,7 @@ function scoreExecutionQuality(input) {
9852
10199
  const unknownCount = findings.filter((finding) => finding.source_client === "unknown").length;
9853
10200
  const multiEventTrails = trails.filter((trail) => trail.events.length > 1).length;
9854
10201
  const evidenceCoverage = clampScore2(
9855
- (coverage.coverage_score ?? 50) + Math.min(18, coverage.connected.length * 3) - coverage.missing.length * 4
10202
+ (coverage.coverage_score ?? 50) + Math.min(18, coverage.connected.length * 3)
9856
10203
  );
9857
10204
  const sourceAttribution = clampScore2(
9858
10205
  34 + uniqueClients.filter((client) => client !== "unknown").length * 10 + (coverage.manifests?.filter((manifest) => manifest.status === "connected").length ?? 0) * 6 - unknownCount * 8
@@ -9881,10 +10228,305 @@ function scoreExecutionQuality(input) {
9881
10228
  notes: [
9882
10229
  "10/10 requires client-native extraction per source, multi-event chronology, source-specific evidence, and action recommendations tied to impact.",
9883
10230
  multiEventTrails === trails.length ? "Every evidence path has multiple events." : `${trails.length - multiEventTrails} finding${trails.length - multiEventTrails === 1 ? "" : "s"} still need more chronology before they should be called recurring.`,
9884
- coverage.missing.length > 0 ? `Missing source coverage: ${coverage.missing.join(", ")}.` : "No required source gaps were declared for this run."
10231
+ coverage.missing.length > 0 ? `AQ ceiling sources not connected yet: ${coverage.missing.join(", ")}.` : "No required source gaps were declared for this run."
10232
+ ]
10233
+ };
10234
+ }
10235
+ function scorePageQuality(input) {
10236
+ const { auditMethod, coverage, impact, mirror, recommendations, trails } = input;
10237
+ const body = `${mirror.headline}
10238
+ ${mirror.body}
10239
+ ${mirror.claims.map((claim) => claim.text).join("\n")}`;
10240
+ const lowerBody = body.toLowerCase();
10241
+ const namedMissingSources = coverage.missing.filter(
10242
+ (source) => lowerBody.includes(source.toLowerCase()) || lowerBody.includes(source.toLowerCase().replace(/ pr\/commit proof/i, ""))
10243
+ ).length;
10244
+ const evidenceRefs = new Set(mirror.claims.flatMap((claim) => claim.evidence_refs));
10245
+ const topTrail = selectPublicTopTrail(trails);
10246
+ const hasSpecificShape = /\b\d+ finding/.test(body) && /\b\d+ decision/.test(body) && /\b\d+ artifact/.test(body);
10247
+ const hasReaderFrame = /\byou\b|\byour\b/i.test(body);
10248
+ const hasPrivacyFrame = /\braw transcripts?\b/i.test(body);
10249
+ const hasImpactFrame = impact.time_saved_hours_per_week > 0 && /\brecoverable hours\/week\b|\bhours\/week\b/i.test(body) && /\$[0-9,]+\/month\b/i.test(body);
10250
+ const hasRepairFrame = recommendations.length > 0 && /\bnext repair\b|\blinked proof\b|\bowner-visible\b/i.test(body);
10251
+ const hasGapFrame = coverage.missing.length === 0 || /\bmissing proof\b|\bsource gap\b|\bproof chain\b/i.test(body) && namedMissingSources > 0;
10252
+ const awkwardCopyPenalty = [
10253
+ /\ba ongoing\b/i,
10254
+ /\[brief impact\]/i,
10255
+ /\bdetected across\b/i,
10256
+ /\bno evidence refs\b/i
10257
+ ].filter((pattern) => pattern.test(body)).length * 8;
10258
+ const clarity = clampScore2(
10259
+ 72 + (mirror.headline.length >= 24 && mirror.headline.length <= 96 ? 8 : 0) + (hasSpecificShape ? 10 : 0) + (topTrail ? 6 : 0) + (auditMethod.retained_evidence_lines > 0 ? 4 : 0) + (hasGapFrame ? 6 : 0) - awkwardCopyPenalty
10260
+ );
10261
+ const pageImpact = clampScore2(
10262
+ 64 + (hasImpactFrame ? 16 : 0) + (impact.estimated_monthly_value_usd > 0 ? 7 : 0) + (recommendations.length > 0 ? 8 : 0) + (topTrail?.impact_score && topTrail.impact_score >= 60 ? 5 : 0)
10263
+ );
10264
+ const resonance = clampScore2(
10265
+ 66 + (hasReaderFrame ? 10 : 0) + (/\boperating leak\b|\bbusiness system\b|\bproof chain\b/i.test(body) ? 10 : 0) + (coverage.connected.length >= 2 ? 4 : 0) + (trails.length >= 8 ? 6 : 0)
10266
+ );
10267
+ const trust = clampScore2(
10268
+ 62 + (hasPrivacyFrame ? 10 : 0) + (hasGapFrame ? 12 : 0) + Math.min(10, evidenceRefs.size * 2) + Math.min(6, namedMissingSources * 2)
10269
+ );
10270
+ const repairReadiness = clampScore2(
10271
+ 62 + (hasRepairFrame ? 14 : 0) + Math.min(12, recommendations.length * 4) + (recommendations.some((recommendation) => recommendation.priority === "p0") ? 8 : 0) + (coverage.missing.length > 0 && hasGapFrame ? 4 : 0)
10272
+ );
10273
+ const overall = clampScore2(
10274
+ clarity * 0.24 + pageImpact * 0.22 + resonance * 0.2 + trust * 0.18 + repairReadiness * 0.16
10275
+ );
10276
+ return {
10277
+ overall,
10278
+ clarity,
10279
+ impact: pageImpact,
10280
+ resonance,
10281
+ trust,
10282
+ repair_readiness: repairReadiness,
10283
+ notes: [
10284
+ "This rates the quality of the public readout, not the underlying work evidence score.",
10285
+ hasGapFrame ? "The readout names the proof gaps instead of hiding them." : "The readout should name the missing proof sources more explicitly.",
10286
+ hasRepairFrame ? "The page gives a concrete repair path tied to proof and ownership." : "The page needs a sharper next repair tied to owner-visible proof."
10287
+ ]
10288
+ };
10289
+ }
10290
+ function buildAgenticQuotient(input) {
10291
+ const { auditMethod, coverage, executionQuality, findings, recommendations, trails } = input;
10292
+ const connectedLabels = sortedUnique(coverage.connected);
10293
+ const connectedClients = sortedUnique(findings.map((finding) => finding.source_client).filter((client) => client !== "unknown"));
10294
+ const aiClientCount = connectedClients.filter(
10295
+ (client) => ["codex", "claude", "claude-code", "cursor", "opencode", "goose"].includes(client)
10296
+ ).length;
10297
+ const proofSourceCount = connectedClients.filter(
10298
+ (client) => ["github", "slack", "mcp", "orgx_runtime_hook"].includes(client)
10299
+ ).length;
10300
+ const toolSignalCount = findings.filter(
10301
+ (finding) => finding.type === "missed_orchestration_opportunity" || /\b(?:mcp__|tool|agent|skill|recipe|workflow)\b/i.test(`${finding.title}
10302
+ ${finding.summary}`)
10303
+ ).length;
10304
+ const decisionCount = findings.filter((finding) => finding.type === "decision").length;
10305
+ const artifactCount = findings.filter((finding) => finding.type === "artifact").length;
10306
+ const outcomeCount = findings.filter((finding) => finding.type === "outcome").length;
10307
+ const blockerCount = findings.filter((finding) => finding.type === "blocker").length;
10308
+ const verifiedTrailCount = trails.filter(
10309
+ (trail) => trail.state === "verified" || trail.valence === "healthy" || trail.events.some(
10310
+ (event) => event.event_type === "artifact_verified" || event.event_type === "outcome_recorded" || event.source_type === "github" || event.source_type === "orgx_runtime_hook" || event.source_type === "mcp"
10311
+ )
10312
+ ).length;
10313
+ const multiEventTrailCount = trails.filter((trail) => trail.events.length > 1).length;
10314
+ const sourceBonus = clampScore2(
10315
+ Math.min(18, connectedLabels.length * 3) + aiClientCount * 3 + proofSourceCount * 4
10316
+ );
10317
+ const rawStackScore = clampScore2(
10318
+ 24 + sourceBonus + Math.min(18, auditMethod.searched_session_files / 8) + Math.min(14, toolSignalCount * 2) + Math.min(12, findings.length) + (coverage.mcpObserved ? 5 : 0)
10319
+ );
10320
+ const rawDurabilityScore = clampScore2(
10321
+ 30 + Math.min(14, decisionCount * 3) + Math.min(14, artifactCount * 3) + Math.min(12, outcomeCount * 4) + Math.min(12, verifiedTrailCount * 4) + Math.min(10, multiEventTrailCount * 2) + (coverage.orgxMcpCalled ? 8 : 0) + Math.min(8, recommendations.length * 2)
10322
+ );
10323
+ const totalTrails = trails.length;
10324
+ const trailPassesCritic = (trail) => trail.events.length >= 2 && (trail.state === "verified" || trail.valence === "healthy" || trail.events.some(
10325
+ (event) => event.event_type === "artifact_verified" || event.event_type === "outcome_recorded" || event.source_type === "github" || event.source_type === "orgx_runtime_hook" || event.source_type === "mcp"
10326
+ ));
10327
+ const passingTrails = trails.filter(trailPassesCritic).length;
10328
+ const criticPassRatio = totalTrails > 0 ? passingTrails / totalTrails : 0.35;
10329
+ const chronologyDepth = executionQuality.trail_depth;
10330
+ const chronologyFactor = 0.55 + 0.45 * (Math.max(0, Math.min(100, chronologyDepth)) / 100);
10331
+ const criticFactor = 0.5 + 0.5 * Math.max(0, Math.min(1, criticPassRatio));
10332
+ const honestyMultiplier = Math.max(0.35, Math.min(1, criticFactor * chronologyFactor));
10333
+ const stackScore = clampScore2(rawStackScore * (0.7 + 0.3 * honestyMultiplier));
10334
+ const durabilityScore = clampScore2(rawDurabilityScore * honestyMultiplier);
10335
+ const aq = clampScore2(stackScore * 0.3 + durabilityScore * 0.7);
10336
+ const repairQuests = buildAgenticRepairQuests({
10337
+ coverage,
10338
+ findings,
10339
+ recommendations
10340
+ });
10341
+ const repairLift = repairQuests.reduce((total, quest) => total + quest.expected_aq_lift, 0);
10342
+ const ceiling = clampScore2(aq + Math.min(36, repairLift));
10343
+ const agenticGap = Math.max(0, ceiling - aq);
10344
+ const contextLeakScore = clampScore2(
10345
+ blockerCount * 10 + findings.filter((finding) => finding.type === "missed_orchestration_opportunity").length * 8 + trails.filter((trail) => trail.state === "blocked" || trail.state === "stale" || trail.valence === "risk").length * 4
10346
+ );
10347
+ const archetype = assignAgenticArchetype({
10348
+ stackScore,
10349
+ durabilityScore,
10350
+ contextLeakScore,
10351
+ agenticGap,
10352
+ criticPassRatio,
10353
+ coverage,
10354
+ findings
10355
+ });
10356
+ return {
10357
+ aq,
10358
+ stack_score: stackScore,
10359
+ durability_score: durabilityScore,
10360
+ agentic_gap: agenticGap,
10361
+ ceiling,
10362
+ source_bonus: sourceBonus,
10363
+ context_leak_score: contextLeakScore,
10364
+ archetype,
10365
+ repair_quests: repairQuests,
10366
+ notes: [
10367
+ "AQ is source-positive: connected sources, proof, and runtime writeback raise the current score; missing sources raise the ceiling and repair quests instead of lowering the current score.",
10368
+ `Audit quality remains separate at ${executionQuality.overall}/100 so the public page can be compelling without inflating evidence truth.`,
10369
+ `Honesty ceiling applied: critic-pass ${Math.round(criticPassRatio * 100)}% \xD7 chronology depth ${chronologyDepth}/100 caps the score at ${Math.round(100 * honestyMultiplier)}.`
9885
10370
  ]
9886
10371
  };
9887
10372
  }
10373
+ function buildAgenticRepairQuests(input) {
10374
+ const quests = [];
10375
+ const add = (quest) => {
10376
+ if (quests.some((existing) => existing.id === quest.id)) return;
10377
+ quests.push(quest);
10378
+ };
10379
+ for (const gap of input.coverage.missing) {
10380
+ if (/github|commit|pr/i.test(gap)) {
10381
+ add({
10382
+ id: "connect-github-proof",
10383
+ title: "Connect GitHub proof",
10384
+ expected_aq_lift: 12,
10385
+ reason: "Attach commits, PRs, reviews, and CI state to decisions and artifacts.",
10386
+ source_gap: gap,
10387
+ action_type: "connect_source"
10388
+ });
10389
+ } else if (/slack/i.test(gap)) {
10390
+ add({
10391
+ id: "connect-slack-coordination",
10392
+ title: "Connect Slack coordination",
10393
+ expected_aq_lift: 9,
10394
+ reason: "Attach owner, approval, and handoff context to the work graph.",
10395
+ source_gap: gap,
10396
+ action_type: "connect_source"
10397
+ });
10398
+ } else if (/runtime|hook|outbox/i.test(gap)) {
10399
+ add({
10400
+ id: "enable-runtime-hooks",
10401
+ title: "Enable runtime hooks",
10402
+ expected_aq_lift: 18,
10403
+ reason: "Convert agent work into durable OrgX writeback without relying on humans to remember reporting.",
10404
+ source_gap: gap,
10405
+ action_type: "enable_runtime_hook"
10406
+ });
10407
+ } else {
10408
+ add({
10409
+ id: `connect-${shortHash(gap, 8)}`,
10410
+ title: `Connect ${gap}`,
10411
+ expected_aq_lift: 5,
10412
+ reason: "Add another proof surface to increase confidence and source confluence.",
10413
+ source_gap: gap,
10414
+ action_type: "connect_source"
10415
+ });
10416
+ }
10417
+ }
10418
+ if (input.findings.some((finding) => finding.type === "decision")) {
10419
+ add({
10420
+ id: "promote-trapped-decisions",
10421
+ title: "Promote trapped decisions",
10422
+ expected_aq_lift: 7,
10423
+ reason: "Move decisions from session text into durable OrgX records with evidence refs.",
10424
+ action_type: "promote_decisions"
10425
+ });
10426
+ }
10427
+ if (input.findings.some((finding) => finding.type === "artifact")) {
10428
+ add({
10429
+ id: "attach-artifact-proof",
10430
+ title: "Attach proof to top artifacts",
10431
+ expected_aq_lift: 6,
10432
+ reason: "Link artifacts to commits, tests, deploys, or review proof.",
10433
+ action_type: "attach_proof"
10434
+ });
10435
+ }
10436
+ for (const recommendation of input.recommendations.slice(0, 1)) {
10437
+ add({
10438
+ id: `launch-${recommendation.id}`,
10439
+ title: recommendation.title,
10440
+ expected_aq_lift: recommendation.priority === "p0" ? 8 : 5,
10441
+ reason: recommendation.summary,
10442
+ action_type: "launch_repair"
10443
+ });
10444
+ }
10445
+ return quests.sort((left, right) => right.expected_aq_lift - left.expected_aq_lift).slice(0, 6);
10446
+ }
10447
+ function assignAgenticArchetype(input) {
10448
+ const { stackScore, durabilityScore, contextLeakScore, agenticGap, criticPassRatio } = input;
10449
+ const toolFailureCount = input.findings.filter(
10450
+ (finding) => finding.type === "blocker" && /\b(?:mcp|schema|tool|zod|invalid)\b/i.test(`${finding.title}
10451
+ ${finding.summary}`)
10452
+ ).length;
10453
+ const hauntingSignals = toolFailureCount + (input.coverage.mcpObserved ? 1 : 0) + (contextLeakScore >= 40 ? 1 : 0);
10454
+ const agentSignalCount = input.findings.filter(
10455
+ (finding) => /\b(?:agent|subagent|delegate|orchestrator|worker)\b/i.test(`${finding.title}
10456
+ ${finding.summary}`)
10457
+ ).length;
10458
+ const decisionCount = input.findings.filter((finding) => finding.type === "decision").length;
10459
+ if (stackScore >= 70 && durabilityScore >= 70 && agenticGap <= 15) {
10460
+ return {
10461
+ id: "ai_native_operator",
10462
+ label: "AI-Native Operator",
10463
+ roast: "The agents are working and the receipts mostly survive contact with reality.",
10464
+ truth: "Your work is both agent-rich and increasingly durable.",
10465
+ repair: "Scale the loop into weekly deltas and team-level source coverage."
10466
+ };
10467
+ }
10468
+ if (durabilityScore >= 80 && criticPassRatio >= 0.85 && contextLeakScore <= 20) {
10469
+ return {
10470
+ id: "proof_maximalist",
10471
+ label: "Proof Maximalist",
10472
+ roast: "Annoyingly competent. Receipts attached.",
10473
+ truth: "Verification and ownership are the strong parts of your system.",
10474
+ repair: "Use the proof base to widen the agent stack."
10475
+ };
10476
+ }
10477
+ if (stackScore >= 70 && durabilityScore <= 50 && hauntingSignals >= 3) {
10478
+ return {
10479
+ id: "mcp_necromancer",
10480
+ label: "MCP Necromancer",
10481
+ roast: "You summoned the tools; a few still need contracts.",
10482
+ truth: "Your stack is rich, but repeated tool failures are leaking context.",
10483
+ repair: "Add runtime hook replay and tool-contract proof before expanding the stack."
10484
+ };
10485
+ }
10486
+ if (stackScore >= 70 && durabilityScore > 50 && durabilityScore < 65) {
10487
+ return {
10488
+ id: "context_leaker",
10489
+ label: "Context Leaker",
10490
+ roast: "Your stack is cooking. Your operating memory is evaporating.",
10491
+ truth: "A lot is happening, but too much of it dies in sessions.",
10492
+ repair: "Enable runtime hooks, connect proof sources, and promote trapped decisions."
10493
+ };
10494
+ }
10495
+ if (agentSignalCount >= 3 && durabilityScore < 65) {
10496
+ return {
10497
+ id: "agent_wrangler",
10498
+ label: "Agent Wrangler",
10499
+ roast: "You have agents. They do not yet have an operating system.",
10500
+ truth: "Delegation is happening, but coordination proof is thin.",
10501
+ repair: "Promote owner-visible workstreams and attach proof to agent handoffs."
10502
+ };
10503
+ }
10504
+ if (decisionCount >= 2 && durabilityScore < 62) {
10505
+ return {
10506
+ id: "decision_ghost",
10507
+ label: "Decision Ghost",
10508
+ roast: "Your best calls are haunting transcripts instead of steering work.",
10509
+ truth: "Decision evidence exists, but durable decision records are weak.",
10510
+ repair: "Promote decisions with commit, owner, and outcome refs."
10511
+ };
10512
+ }
10513
+ if (stackScore < 60 && durabilityScore >= 68) {
10514
+ return {
10515
+ id: "careful_operator",
10516
+ label: "Careful Operator",
10517
+ roast: "Small stack, strong receipts.",
10518
+ truth: "You use fewer agents, but the work you do run tends to compound.",
10519
+ repair: "Add one new client or proof source without weakening durability."
10520
+ };
10521
+ }
10522
+ return {
10523
+ id: "prompt_tourist",
10524
+ label: "Prompt Tourist",
10525
+ roast: "You are early enough that the score is still honest, not embarrassing.",
10526
+ truth: "There is not enough durable agent work yet to call this a compounding system.",
10527
+ repair: "Pick one client, run real work through it, then connect proof."
10528
+ };
10529
+ }
9888
10530
  function inferFinalState(findings) {
9889
10531
  if (findings.some((finding) => finding.type === "blocker")) return "blocked";
9890
10532
  if (findings.some((finding) => finding.type === "artifact" || finding.type === "outcome" || /\b(shipped|completed|done|verified)\b/i.test(finding.summary))) {
@@ -10416,7 +11058,9 @@ function buildWorkGraphMirror(input) {
10416
11058
  trails.flatMap((trail) => trail.events.map((event) => event.source_type))
10417
11059
  );
10418
11060
  const sourcePhrase = sourceClients.length > 0 ? sourceClients.map(labelForSourceClient).join(", ") : coverage.connected.join(", ") || "local sources";
10419
- const headline = blockerCount > 0 ? "Your AI work is shipping, but the execution record is incomplete" : sourceGapCount > 0 ? "Your AI work is visible, but the proof chain is incomplete" : topPattern ? "Your work has a recurring operating pattern worth preserving" : topTrail ? "Your work is becoming an operating profile" : "Your work is leaving evidence OrgX can organize";
11061
+ const namedSourceGaps = coverage.missing.slice(0, 5);
11062
+ const sourceGapPhrase = namedSourceGaps.length > 0 ? namedSourceGaps.join(", ") : "no declared source gaps";
11063
+ const headline = blockerCount > 0 ? "AI-native receipts: your agents are working, but the proof chain is thin" : sourceGapCount > 0 ? "AI-native receipts: your sessions describe a business system, but the proof chain is thin" : topPattern ? "Your work has a recurring operating pattern worth preserving" : topTrail ? "Your work is becoming an operating profile" : "Your work is leaving evidence OrgX can organize";
10420
11064
  const domainPhrase = domains.length > 0 ? domains.slice(0, 4).map((domain) => domain.label).join(", ") : "the connected work surface";
10421
11065
  const toolPhrase = skillToolSignals.length > 0 ? skillToolSignals.slice(0, 4).map((signal) => signal.label).join(", ") : "client sessions and available tools";
10422
11066
  const primaryClaimRefs = topTrail?.evidence_refs ?? [];
@@ -10446,16 +11090,26 @@ function buildWorkGraphMirror(input) {
10446
11090
  confidence: impact.confidence
10447
11091
  }] : []
10448
11092
  ];
10449
- const searchClaim = auditMethod ? `OrgX searched ${auditMethod.searched_session_files} AI-client session files and ${auditMethod.searched_message_count} message turns across ${sourcePhrase}; it retained ${auditMethod.retained_evidence_lines} evidence lines and excluded raw transcripts.` : `OrgX searched your AI-client session evidence across ${sourcePhrase} without requiring OrgX tool calls to be present.`;
10450
- const topIssue = topTrail ? `The highest-risk issue is ${topTrail.title.toLowerCase()}.` : topPattern ? `The highest-risk pattern is ${topPattern.title.toLowerCase()}.` : "The first profile is forming from sparse evidence and should be reviewed before promotion.";
11093
+ const searchClaim = auditMethod ? `OrgX searched ${auditMethod.searched_session_files} AI-client session file${auditMethod.searched_session_files === 1 ? "" : "s"}${auditMethod.searched_message_count > 0 ? ` and ${auditMethod.searched_message_count} message turns` : ""} across ${sourcePhrase}; it kept ${auditMethod.retained_evidence_lines} public-safe evidence line${auditMethod.retained_evidence_lines === 1 ? "" : "s"} and left raw transcripts out.` : `OrgX searched your AI-client session evidence across ${sourcePhrase} without requiring OrgX tool calls to be present.`;
11094
+ const topIssue = topTrail ? `The clearest operating leak is "${topTrail.title}".` : topPattern ? `The clearest operating pattern is "${topPattern.title}".` : "The first profile is forming from sparse evidence and should be reviewed before promotion.";
11095
+ const proofGapSentence = sourceGapCount > 0 ? `What keeps the page from feeling decisive is not the amount of activity; it is missing proof from ${sourceGapPhrase}.` : "The proof chain is strong enough to publish as a first-pass operating profile, with human review still in the loop.";
11096
+ const evidenceShapeSentence = [
11097
+ `${trails.length} finding${trails.length === 1 ? "" : "s"}`,
11098
+ `${decisionCount} decision${decisionCount === 1 ? "" : "s"}`,
11099
+ `${artifactCount} artifact${artifactCount === 1 ? "" : "s"}`,
11100
+ blockerCount > 0 ? `${blockerCount} blocker${blockerCount === 1 ? "" : "s"}` : null
11101
+ ].filter(Boolean).join(", ");
11102
+ const recommendation = recommendations[0];
11103
+ const repairSentence = recommendation ? `The next repair is ${recommendation.title}: it should turn the strongest evidence path into owner-visible work with linked proof, not another summary.` : "The next move is to inspect the highest-confidence finding before publishing it.";
10451
11104
  const body = [
10452
11105
  searchClaim,
10453
- `It found ${trails.length} evidence-backed finding${trails.length === 1 ? "" : "s"} across ${domainPhrase}, with ${toolPhrase} showing up as the strongest skills, tools, or sources.`,
11106
+ "This is receipts over vibes: the score should rise when more runtime proof connects, not fall because a source is not installed yet.",
11107
+ `The shape is specific: ${evidenceShapeSentence} across ${domainPhrase}, with ${toolPhrase} showing up as the strongest skills, tools, or sources.`,
10454
11108
  topIssue,
10455
11109
  blockerCount > 0 ? `${blockerCount} blocker finding${blockerCount === 1 ? "" : "s"} show work returning as new work instead of becoming owner-visible resolution.` : `${decisionCount} decision finding${decisionCount === 1 ? "" : "s"} and ${artifactCount} artifact finding${artifactCount === 1 ? "" : "s"} show where work can become durable.`,
10456
- sourceGapCount > 0 ? `${sourceGapCount} source gap${sourceGapCount === 1 ? "" : "s"} still limit trust: ownership, handoffs, GitHub proof, Slack coordination, or later verification.` : "The connected sources are enough for a first public-safe profile, pending human review.",
11110
+ proofGapSentence,
10457
11111
  impact ? `Left unresolved, the profile estimates ${impact.time_saved_hours_per_week} recoverable hours/week and about $${impact.estimated_monthly_value_usd.toLocaleString("en-US")}/month in operator leverage.` : "",
10458
- recommendations[0] ? `The next repair is concrete: ${recommendations[0].title}.` : "The next move is to inspect the highest-confidence finding before publishing it."
11112
+ repairSentence
10459
11113
  ].filter(Boolean).join(" ");
10460
11114
  return {
10461
11115
  headline,
@@ -11016,6 +11670,22 @@ function buildSessionReconciliationReport(input) {
11016
11670
  skillToolSignals,
11017
11671
  trails
11018
11672
  });
11673
+ const pageQuality = scorePageQuality({
11674
+ auditMethod,
11675
+ coverage,
11676
+ impact: impactProjection,
11677
+ mirror,
11678
+ recommendations,
11679
+ trails
11680
+ });
11681
+ const agenticQuotient = buildAgenticQuotient({
11682
+ auditMethod,
11683
+ coverage,
11684
+ executionQuality,
11685
+ findings: allFindings,
11686
+ recommendations,
11687
+ trails
11688
+ });
11019
11689
  const tensionMetrics = buildTensionMetrics({
11020
11690
  coverage,
11021
11691
  impact: impactProjection,
@@ -11095,6 +11765,8 @@ function buildSessionReconciliationReport(input) {
11095
11765
  attribution_spine: attributionSpine,
11096
11766
  opportunity_score: opportunityScore,
11097
11767
  execution_quality: executionQuality,
11768
+ page_quality: pageQuality,
11769
+ agentic_quotient: agenticQuotient,
11098
11770
  impact_projection: impactProjection,
11099
11771
  investigation,
11100
11772
  initiative_kickoffs: initiativeKickoffs,
@@ -11142,7 +11814,58 @@ function renderWorkGraphExtractionProtocolMarkdown(protocol = buildWorkGraphExtr
11142
11814
  lines.push("```");
11143
11815
  return lines.join("\n");
11144
11816
  }
11145
- function renderWorkGraphMarkdown(report) {
11817
+ function markdownText(value, fallback) {
11818
+ if (typeof value !== "string") return fallback;
11819
+ const trimmed = value.trim();
11820
+ if (!trimmed || /^undefined$/i.test(trimmed) || /^null$/i.test(trimmed)) return fallback;
11821
+ return trimmed;
11822
+ }
11823
+ function markdownNumber(value, fallback = 0) {
11824
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
11825
+ }
11826
+ function markdownStrings(value) {
11827
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
11828
+ }
11829
+ function markdownSources(value) {
11830
+ return markdownStrings(value).map((source) => labelForSourceClient(normalizeSourceClient(source))).join(", ") || "source evidence";
11831
+ }
11832
+ function markdownPublicTitle(title, fallback) {
11833
+ const source = markdownText(title, fallback);
11834
+ return titleFromText(source, fallback);
11835
+ }
11836
+ function markdownPublicTrails(report) {
11837
+ const primary = report.mirror.primary_trail_id ? report.trails.find((trail) => trail.id === report.mirror.primary_trail_id) : selectPublicTopTrail(report.trails);
11838
+ const ranked = [...report.trails].sort((left, right) => publicTrailRank(right) - publicTrailRank(left));
11839
+ return primary ? [primary, ...ranked.filter((trail) => trail.id !== primary.id)] : ranked;
11840
+ }
11841
+ function renderWorkGraphShareables(report, options) {
11842
+ const lines = [];
11843
+ lines.push("## Shareables");
11844
+ lines.push("");
11845
+ if (options.publicUrl) {
11846
+ lines.push(`Profile URL: ${options.publicUrl}`);
11847
+ const separator = options.publicUrl.includes("?") ? "&" : "?";
11848
+ lines.push(`Headline card: ${options.publicUrl}/opengraph-image?v=headline`);
11849
+ lines.push(`Stack card: ${options.publicUrl}/opengraph-image?v=stack`);
11850
+ lines.push(`Receipt card: ${options.publicUrl}/opengraph-image?v=receipt`);
11851
+ lines.push(`Gap card: ${options.publicUrl}/opengraph-image?v=gap`);
11852
+ lines.push(`Weekly wrapped card: ${options.publicUrl}/opengraph-image?v=wrapped`);
11853
+ lines.push(`Tracked share URL: ${options.publicUrl}${separator}ref=share&v=headline`);
11854
+ if (options.reviewUrl) lines.push(`Review URL: ${options.reviewUrl}`);
11855
+ } else {
11856
+ lines.push("- Publish with --public-share to create profile and share-card URLs.");
11857
+ }
11858
+ lines.push("");
11859
+ const aq = report.agentic_quotient;
11860
+ const topQuest = aq.repair_quests[0];
11861
+ lines.push("Suggested share copy:");
11862
+ lines.push(`- AQ ${aq.aq}. Stack ${aq.stack_score}. Durable ${aq.durability_score}. Gap ${aq.agentic_gap}. ${aq.archetype.label}. Receipts attached.`);
11863
+ lines.push(`- Just ran my AQ. ${topQuest ? `Next repair: ${topQuest.title} (+${topQuest.expected_aq_lift} AQ).` : "The gap is the game."}`);
11864
+ lines.push(`- Receipts > vibes. AQ ${aq.aq} with ${report.impact_projection.time_saved_hours_per_week}h/week recoverable.`);
11865
+ lines.push("");
11866
+ return lines;
11867
+ }
11868
+ function renderWorkGraphMarkdown(report, options = {}) {
11146
11869
  const lines = [];
11147
11870
  lines.push("# OrgX Investigation Engine");
11148
11871
  lines.push("");
@@ -11153,6 +11876,7 @@ function renderWorkGraphMarkdown(report) {
11153
11876
  lines.push(`Hydration key: ${report.signup_hydration.hydration_key}`);
11154
11877
  lines.push(`Final state: ${report.final_state}`);
11155
11878
  lines.push("");
11879
+ lines.push(...renderWorkGraphShareables(report, options));
11156
11880
  lines.push("## AI-Client Search Protocol");
11157
11881
  lines.push("");
11158
11882
  lines.push(`Schema: ${report.extraction_protocol.schema_version}`);
@@ -11188,7 +11912,7 @@ function renderWorkGraphMarkdown(report) {
11188
11912
  lines.push(`Earned counterfactuals: ${report.investigation.counterfactuals.length}`);
11189
11913
  lines.push("");
11190
11914
  lines.push("Mirror:");
11191
- lines.push(report.investigation.mirror_paragraph.text);
11915
+ lines.push(markdownText(report.investigation.mirror_paragraph.text, report.mirror.body));
11192
11916
  lines.push("");
11193
11917
  if (report.investigation.counterfactuals[0]) {
11194
11918
  const counterfactual = report.investigation.counterfactuals[0];
@@ -11229,7 +11953,7 @@ function renderWorkGraphMarkdown(report) {
11229
11953
  lines.push("- No domain clusters reached the public-summary threshold.");
11230
11954
  } else {
11231
11955
  for (const domain of report.domain_coverage) {
11232
- lines.push(`- ${domain.label}: ${domain.finding_count} findings across ${domain.source_clients.join(", ")}. ${domain.summary}`);
11956
+ lines.push(`- ${markdownText(domain.label, "Work evidence")}: ${markdownNumber(domain.finding_count)} findings across ${markdownSources(domain.source_clients)}. ${markdownText(domain.summary, "Evidence cluster retained for public review.")}`);
11233
11957
  }
11234
11958
  }
11235
11959
  lines.push("");
@@ -11239,7 +11963,8 @@ function renderWorkGraphMarkdown(report) {
11239
11963
  lines.push("- No repeated skill/tool signals reached the public-summary threshold.");
11240
11964
  } else {
11241
11965
  for (const signal of report.skill_tool_signals) {
11242
- lines.push(`- [${signal.kind}] ${signal.label}: ${signal.mention_count} mention${signal.mention_count === 1 ? "" : "s"} across ${signal.source_clients.join(", ")}.`);
11966
+ const mentionCount = markdownNumber(signal.mention_count);
11967
+ lines.push(`- [${markdownText(signal.kind, "source")}] ${markdownText(signal.label, "Work source")}: ${mentionCount} mention${mentionCount === 1 ? "" : "s"} across ${markdownSources(signal.source_clients)}.`);
11243
11968
  }
11244
11969
  }
11245
11970
  lines.push("");
@@ -11253,6 +11978,28 @@ function renderWorkGraphMarkdown(report) {
11253
11978
  lines.push(`Automation potential: ${report.opportunity_score.automation_potential}/100`);
11254
11979
  lines.push(`OrgX fit: ${report.opportunity_score.orgx_fit}/100`);
11255
11980
  lines.push("");
11981
+ lines.push("## Agentic Quotient");
11982
+ lines.push("");
11983
+ lines.push(`AQ: ${report.agentic_quotient.aq}/100`);
11984
+ lines.push(`Stack score: ${report.agentic_quotient.stack_score}/100`);
11985
+ lines.push(`Durability score: ${report.agentic_quotient.durability_score}/100`);
11986
+ lines.push(`Agentic gap: ${report.agentic_quotient.agentic_gap}`);
11987
+ lines.push(`Ceiling: ${report.agentic_quotient.ceiling}/100`);
11988
+ lines.push(`Archetype: ${report.agentic_quotient.archetype.label}`);
11989
+ lines.push(report.agentic_quotient.archetype.roast);
11990
+ lines.push(report.agentic_quotient.archetype.truth);
11991
+ lines.push("");
11992
+ if (report.agentic_quotient.repair_quests.length > 0) {
11993
+ lines.push("Repair quests:");
11994
+ for (const quest of report.agentic_quotient.repair_quests) {
11995
+ lines.push(`- +${quest.expected_aq_lift} AQ ${quest.title}: ${quest.reason}`);
11996
+ }
11997
+ lines.push("");
11998
+ }
11999
+ for (const note of report.agentic_quotient.notes) {
12000
+ lines.push(`- ${note}`);
12001
+ }
12002
+ lines.push("");
11256
12003
  lines.push("## Execution Quality");
11257
12004
  lines.push("");
11258
12005
  lines.push(`Overall: ${report.execution_quality.overall}/100`);
@@ -11266,6 +12013,18 @@ function renderWorkGraphMarkdown(report) {
11266
12013
  lines.push(`- ${note}`);
11267
12014
  }
11268
12015
  lines.push("");
12016
+ lines.push("## Page Quality");
12017
+ lines.push("");
12018
+ lines.push(`Overall: ${report.page_quality.overall}/100`);
12019
+ lines.push(`Clarity: ${report.page_quality.clarity}/100`);
12020
+ lines.push(`Impact: ${report.page_quality.impact}/100`);
12021
+ lines.push(`Resonance: ${report.page_quality.resonance}/100`);
12022
+ lines.push(`Trust: ${report.page_quality.trust}/100`);
12023
+ lines.push(`Repair readiness: ${report.page_quality.repair_readiness}/100`);
12024
+ for (const note of report.page_quality.notes) {
12025
+ lines.push(`- ${note}`);
12026
+ }
12027
+ lines.push("");
11269
12028
  lines.push("## Impact Projection");
11270
12029
  lines.push("");
11271
12030
  lines.push(`Time saved: ${report.impact_projection.time_saved_hours_per_week}h/week`);
@@ -11288,7 +12047,7 @@ function renderWorkGraphMarkdown(report) {
11288
12047
  lines.push("");
11289
12048
  lines.push("Source manifests:");
11290
12049
  for (const manifest of report.source_coverage.manifests) {
11291
- lines.push(`- [${manifest.status}] ${manifest.source_label}: ${manifest.finding_count} findings, ${manifest.searched_session_count} searched / ${manifest.skipped_session_count} skipped sessions, confidence ${manifest.confidence}`);
12050
+ lines.push(`- [${markdownText(manifest.status, "observed")}] ${markdownText(manifest.source_label, "Work source")}: ${markdownNumber(manifest.finding_count)} findings, ${markdownNumber(manifest.searched_session_count)} searched / ${markdownNumber(manifest.skipped_session_count)} skipped sessions, confidence ${markdownNumber(manifest.confidence)}`);
11292
12051
  }
11293
12052
  }
11294
12053
  lines.push("");
@@ -11299,19 +12058,23 @@ function renderWorkGraphMarkdown(report) {
11299
12058
  lines.push(report.mirror.body);
11300
12059
  lines.push("");
11301
12060
  for (const claim of report.mirror.claims) {
11302
- lines.push(`- ${claim.text} (${claim.evidence_refs.join(", ") || "no evidence refs"})`);
12061
+ lines.push(`- ${markdownText(claim.text, "Claim retained for review")} (${markdownStrings(claim.evidence_refs).join(", ") || "evidence refs pending"})`);
11303
12062
  }
11304
12063
  lines.push("");
11305
12064
  lines.push("## Operating Leakage");
11306
12065
  lines.push("");
11307
- for (const metric of report.tension_metrics) {
11308
- lines.push(`- ${metric.value} ${metric.label}: ${metric.explanation}`);
12066
+ if (report.tension_metrics.length === 0) {
12067
+ lines.push("- No operating leakage metrics reached the public-summary threshold.");
12068
+ } else {
12069
+ for (const metric of report.tension_metrics) {
12070
+ lines.push(`- ${markdownText(metric.value, "0")} ${markdownText(metric.label, "signal")}: ${markdownText(metric.explanation, "Evidence retained for review.")}`);
12071
+ }
11309
12072
  }
11310
12073
  lines.push("");
11311
12074
  lines.push("## Evidence Paths");
11312
12075
  lines.push("");
11313
- for (const trail of report.trails.slice(0, 12)) {
11314
- lines.push(`- [${trail.kind}] ${trail.title} \u2014 ${trail.state}, ${trail.valence}, ${trail.shape} (${trail.evidence_refs.join(", ")})`);
12076
+ for (const trail of markdownPublicTrails(report).slice(0, 12)) {
12077
+ lines.push(`- [${markdownText(trail.kind, "trail")}] ${markdownPublicTitle(trail.title, "Work trail")} - ${markdownText(trail.state, "observed")}, ${markdownText(trail.valence, "neutral")}, ${markdownText(trail.shape, "single_signal")} (${markdownStrings(trail.evidence_refs).join(", ") || "evidence refs pending"})`);
11315
12078
  }
11316
12079
  lines.push("");
11317
12080
  lines.push("## Recurring Patterns");
@@ -11320,14 +12083,14 @@ function renderWorkGraphMarkdown(report) {
11320
12083
  lines.push("- No recurring patterns detected yet.");
11321
12084
  } else {
11322
12085
  for (const pattern of report.recurring_patterns) {
11323
- lines.push(`- [${pattern.severity}] ${pattern.title}: ${pattern.root_cause_hypothesis}`);
12086
+ lines.push(`- [${markdownText(pattern.severity, "medium")}] ${markdownPublicTitle(pattern.title, "Recurring work pattern")}: ${markdownText(pattern.root_cause_hypothesis, "The same work shape is recurring without a durable repair.")}`);
11324
12087
  }
11325
12088
  }
11326
12089
  lines.push("");
11327
12090
  lines.push("## Top Findings");
11328
12091
  lines.push("");
11329
12092
  for (const finding of report.findings.slice(0, 12)) {
11330
- lines.push(`- [${finding.type}] ${finding.title} (${finding.evidence_ref})`);
12093
+ lines.push(`- [${markdownText(finding.type, "finding")}] ${markdownPublicTitle(finding.title, "Work finding")} (${markdownText(finding.evidence_ref, "evidence ref pending")})`);
11331
12094
  }
11332
12095
  lines.push("");
11333
12096
  lines.push("## Missed Orchestration");
@@ -12418,7 +13181,7 @@ async function readAuditImports(options, interactive) {
12418
13181
  }
12419
13182
  if (imports.length === 0) {
12420
13183
  const sourceHint = sources.length > 0 ? ` No audit-relevant lines were found in ${sources.join(", ")} sessions.` : "";
12421
- throw new Error(`Audit input is required.${sourceHint} Pass --input <file>, pipe text, or use --from claude,codex,opencode,goose,cursor,all.`);
13184
+ throw new Error(`Audit input is required.${sourceHint} Pass --input <file>, pipe text, or use --from claude,codex,opencode,goose,cursor,github,slack,all.`);
12422
13185
  }
12423
13186
  return {
12424
13187
  connectedSources,
@@ -12617,6 +13380,53 @@ function runWorkGraphExtractionSchemaCommand(options) {
12617
13380
  const markdown = renderWorkGraphExtractionProtocolMarkdown(protocol);
12618
13381
  console.log(markdown);
12619
13382
  }
13383
+ function normalizeRuntimePacketSource(source) {
13384
+ const normalized = source.trim().toLowerCase().replace(/_/g, "-");
13385
+ if (normalized === "codex") return "codex";
13386
+ if (normalized === "claude" || normalized === "claude-code" || normalized === "claude_code") return "claude-code";
13387
+ throw new Error("Unsupported runtime event source. Use codex or claude.");
13388
+ }
13389
+ function normalizeRuntimePacketRole(role) {
13390
+ const normalized = role?.trim().toLowerCase();
13391
+ if (normalized === "user" || normalized === "assistant" || normalized === "tool" || normalized === "meta") {
13392
+ return normalized;
13393
+ }
13394
+ return "assistant";
13395
+ }
13396
+ function runWorkGraphRuntimeEventCommand(options) {
13397
+ const source = normalizeRuntimePacketSource(options.source);
13398
+ const cwd = resolve2(options.cwd?.trim() || process.cwd());
13399
+ const outputRoot = resolve2(cwd, options.outputDir?.trim() || ".orgx/work-graph/runtime-events");
13400
+ const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
13401
+ const timestamp = generatedAt.replace(/[:.]/g, "-");
13402
+ const summary = options.summary?.trim() || options.message?.trim();
13403
+ if (!summary) {
13404
+ throw new Error("Runtime event summary is required. Pass --summary or --message.");
13405
+ }
13406
+ const packet = {
13407
+ type: "orgx_work_graph_runtime_event",
13408
+ schema_version: "1.0.0",
13409
+ source_client: source,
13410
+ timestamp: generatedAt,
13411
+ role: normalizeRuntimePacketRole(options.role),
13412
+ event_kind: options.eventKind?.trim() || "artifact",
13413
+ summary,
13414
+ content: summary,
13415
+ ...options.toolName?.trim() ? { tool_name: options.toolName.trim() } : {},
13416
+ cwd,
13417
+ collection_method: "runtime_packet",
13418
+ redaction_state: "agent_redacted"
13419
+ };
13420
+ const path = resolve2(outputRoot, source, `${timestamp}-${process.pid}.jsonl`);
13421
+ writeTextFile(path, `${JSON.stringify(packet)}
13422
+ `, { mode: 384 });
13423
+ if (options.json) {
13424
+ console.log(JSON.stringify({ ok: true, path, source, collectedBy: "work-graph profile --from all" }, null, 2));
13425
+ return;
13426
+ }
13427
+ console.log(` ${ICON.ok} ${pc3.green("runtime event")} ${pc3.dim(path)}`);
13428
+ console.log(` ${ICON.skip} ${pc3.dim("collect with")} ${pc3.bold("orgx-wizard work-graph profile --from all")}`);
13429
+ }
12620
13430
  async function runWorkGraphCommand(options, defaults = {}) {
12621
13431
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
12622
13432
  const commandOptions = {
@@ -12689,6 +13499,9 @@ async function runWorkGraphCommand(options, defaults = {}) {
12689
13499
  }
12690
13500
  }
12691
13501
  }
13502
+ if (published?.publicUrl || published?.reviewUrl) {
13503
+ writeTextFile(markdownPath, renderWorkGraphMarkdown(report, published));
13504
+ }
12692
13505
  if (commandOptions.json) {
12693
13506
  console.log(JSON.stringify({
12694
13507
  jsonPath,
@@ -12698,7 +13511,9 @@ async function runWorkGraphCommand(options, defaults = {}) {
12698
13511
  hydrationKey: report.signup_hydration.hydration_key,
12699
13512
  finalState: report.final_state,
12700
13513
  opportunityScore: report.opportunity_score,
13514
+ agenticQuotient: report.agentic_quotient,
12701
13515
  executionQuality: report.execution_quality,
13516
+ pageQuality: report.page_quality,
12702
13517
  impactProjection: report.impact_projection,
12703
13518
  missedOrchestration: report.missed_orchestration_opportunities.length,
12704
13519
  clientExtractionCount: report.client_extractions.length,
@@ -12718,7 +13533,10 @@ async function runWorkGraphCommand(options, defaults = {}) {
12718
13533
  console.log(` ${ICON.ok} ${pc3.green("state ")} ${pc3.dim(report.final_state)}`);
12719
13534
  console.log(` ${ICON.ok} ${pc3.green("extractions ")} ${pc3.dim(String(report.client_extractions.length))}`);
12720
13535
  console.log(` ${ICON.ok} ${pc3.green("score ")} ${pc3.dim(formatWorkGraphScoreLine(report.opportunity_score))}`);
12721
- console.log(` ${ICON.ok} ${pc3.green("quality ")} ${pc3.dim(`${report.execution_quality.overall}/100 \xB7 coverage ${report.source_coverage.coverage_score ?? 0}/100`)}`);
13536
+ console.log(` ${ICON.ok} ${pc3.green("AQ ")} ${pc3.dim(`${report.agentic_quotient.aq}/100 \xB7 Stack ${report.agentic_quotient.stack_score}/100 \xB7 Durable ${report.agentic_quotient.durability_score}/100 \xB7 Gap ${report.agentic_quotient.agentic_gap}`)}`);
13537
+ console.log(` ${ICON.ok} ${pc3.green("archetype ")} ${pc3.dim(report.agentic_quotient.archetype.label)}`);
13538
+ console.log(` ${ICON.ok} ${pc3.green("audit quality ")} ${pc3.dim(`${report.execution_quality.overall}/100 \xB7 coverage ${report.source_coverage.coverage_score ?? 0}/100`)}`);
13539
+ console.log(` ${ICON.ok} ${pc3.green("page quality ")} ${pc3.dim(`${report.page_quality.overall}/100 \xB7 clarity ${report.page_quality.clarity}/100 \xB7 trust ${report.page_quality.trust}/100`)}`);
12722
13540
  console.log(` ${ICON.ok} ${pc3.green("impact ")} ${pc3.dim(`${report.impact_projection.time_saved_hours_per_week}h/week \xB7 +${report.impact_projection.acceleration_percent}% acceleration \xB7 ~$${report.impact_projection.estimated_monthly_value_usd.toLocaleString("en-US")}/month`)}`);
12723
13541
  const missed = report.missed_orchestration_opportunities.length;
12724
13542
  const missedColor = missed > 0 ? pc3.yellow : pc3.green;
@@ -13695,7 +14513,7 @@ function printDoctorReport(report, assessment) {
13695
14513
  async function main() {
13696
14514
  const program = new Command();
13697
14515
  program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
13698
- const pkgVersion = true ? "0.1.42" : void 0;
14516
+ const pkgVersion = true ? "0.1.44" : void 0;
13699
14517
  program.version(pkgVersion ?? "unknown", "-V, --version");
13700
14518
  program.hook("preAction", (_thisCommand, actionCommand) => {
13701
14519
  if (Boolean(actionCommand.optsWithGlobals().json)) return;
@@ -14385,7 +15203,7 @@ async function main() {
14385
15203
  jsonOutput: Boolean(options.json)
14386
15204
  });
14387
15205
  });
14388
- program.command("audit").description("Run the AI-native Founder Loop self-audit from pasted or file-based AI-session context.").option("--input <path>", "AI-session transcript or summary file; stdin is used when piped").option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "3").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for audit import").option("--claude-projects-dir <path>", "override Claude projects directory for audit import").option("--source-label <label>", "label for the imported AI-session source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only audits").option("--output-dir <path>", "directory for generated audit JSON and Markdown", ".orgx/audits").option("--attach-to-initiative <id>", "attach the generated audit artifact to an existing OrgX initiative").option("--create-initiative", "create an OrgX initiative from the generated audit plan").option("--write-follow-up", "create one approval-gated OrgX follow-up task from the audit recommendation").option("--workstream-id <id>", "optional workstream id for the generated follow-up task").option("--milestone-id <id>", "optional milestone id for the generated follow-up task").option("--dry-run", "exercise OrgX write paths without sending writes").option("--yes", "approve OrgX write flags in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
15206
+ program.command("audit").description("Run the AI-native Founder Loop self-audit from pasted or file-based AI-session context.").option("--input <path>", "AI-session transcript or summary file; stdin is used when piped").option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, github, slack, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "3").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for audit import").option("--claude-projects-dir <path>", "override Claude projects directory for audit import").option("--source-label <label>", "label for the imported AI-session source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only audits").option("--output-dir <path>", "directory for generated audit JSON and Markdown", ".orgx/audits").option("--attach-to-initiative <id>", "attach the generated audit artifact to an existing OrgX initiative").option("--create-initiative", "create an OrgX initiative from the generated audit plan").option("--write-follow-up", "create one approval-gated OrgX follow-up task from the audit recommendation").option("--workstream-id <id>", "optional workstream id for the generated follow-up task").option("--milestone-id <id>", "optional milestone id for the generated follow-up task").option("--dry-run", "exercise OrgX write paths without sending writes").option("--yes", "approve OrgX write flags in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
14389
15207
  await safeTrackWizardTelemetry("audit_started", {
14390
15208
  attach_to_initiative: Boolean(options.attachToInitiative),
14391
15209
  command: "audit",
@@ -14403,14 +15221,17 @@ async function main() {
14403
15221
  });
14404
15222
  runWorkGraphExtractionSchemaCommand(options);
14405
15223
  });
14406
- workGraph.command("preview").description("Preview the OrgX Profile evidence findings without writing to OrgX.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "15").option("--session-days <days>", "lookback window for local AI-session imports", "60").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--source-label <label>", "label for the imported manual source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only previews").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--json", "emit a JSON command summary").action(async (options) => {
15224
+ workGraph.command("runtime-event").description("Write a redacted Codex/Claude runtime packet into the Work Graph collector directory.").requiredOption("--source <source>", "agent source writing the packet: codex or claude").option("--summary <text>", "public-safe summary of the decision, artifact, blocker, outcome, or tool event").option("--message <text>", "alias for --summary").option("--event-kind <kind>", "event kind hint: decision, artifact, blocker, outcome, tool_call_error", "artifact").option("--role <role>", "source role: user, assistant, tool, or meta", "assistant").option("--tool-name <name>", "tool name when the packet represents a tool call").option("--cwd <path>", "workspace root that owns the collector directory").option("--output-dir <path>", "collector root relative to cwd", ".orgx/work-graph/runtime-events").option("--json", "emit a JSON summary").action((options) => {
15225
+ runWorkGraphRuntimeEventCommand(options);
15226
+ });
15227
+ workGraph.command("preview").description("Preview the OrgX Profile evidence findings without writing to OrgX.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, github, slack, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "15").option("--session-days <days>", "lookback window for local AI-session imports", "60").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--source-label <label>", "label for the imported manual source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only previews").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--json", "emit a JSON command summary").action(async (options) => {
14407
15228
  await safeTrackWizardTelemetry("work_graph_preview_started", {
14408
15229
  command: "work-graph preview",
14409
15230
  from: options.from ?? "manual"
14410
15231
  });
14411
15232
  await runWorkGraphCommand(options);
14412
15233
  });
14413
- workGraph.command("profile").description("Build a local OrgX Profile with evidence findings, domain coverage, source confidence, and repair recommendations.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "25").option("--session-days <days>", "lookback window for local AI-session imports", "60").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--source-label <label>", "label for the imported manual source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only profiles").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--publish", "publish the generated OrgX Profile to OrgX and return a shareable URL").option("--public-share", "create a public redacted /work-graph/<token> share when publishing").option("--attach-artifact", "attach the report as an OrgX artifact when an initiative/entity is provided").option("--attach-to-initiative <id>", "attach the report to an existing OrgX initiative").option("--entity-type <type>", "entity type for artifact attachment: project, initiative, milestone, task, decision").option("--entity-id <id>", "entity id for artifact attachment").option("--artifact-url <url>", "override the artifact URL stored in OrgX").option("--yes", "approve publish/write prompts in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
15234
+ workGraph.command("profile").description("Build a local OrgX Profile with evidence findings, domain coverage, source confidence, and repair recommendations.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, github, slack, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "25").option("--session-days <days>", "lookback window for local AI-session imports", "60").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--source-label <label>", "label for the imported manual source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only profiles").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--publish", "publish the generated OrgX Profile to OrgX and return a shareable URL").option("--public-share", "create a public redacted /work-graph/<token> share when publishing").option("--attach-artifact", "attach the report as an OrgX artifact when an initiative/entity is provided").option("--attach-to-initiative <id>", "attach the report to an existing OrgX initiative").option("--entity-type <type>", "entity type for artifact attachment: project, initiative, milestone, task, decision").option("--entity-id <id>", "entity id for artifact attachment").option("--artifact-url <url>", "override the artifact URL stored in OrgX").option("--yes", "approve publish/write prompts in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
14414
15235
  await safeTrackWizardTelemetry("work_graph_profile_started", {
14415
15236
  command: "work-graph profile",
14416
15237
  from: options.from ?? "manual"
@@ -14418,7 +15239,7 @@ async function main() {
14418
15239
  await runWorkGraphCommand(options);
14419
15240
  });
14420
15241
  const sessions = program.command("sessions").description("Inspect and reconcile local AI sessions into OrgX-ready Work Graph reports.");
14421
- sessions.command("reconcile").description("Backfill recent Claude Code, Codex, OpenCode, goose, and Cursor sessions into a redacted OrgX Profile report.").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, or all", "all").option("--session-limit <count>", "max recent sessions to import per selected source", "25").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only reconciliation").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--publish", "publish the generated OrgX Profile to OrgX and return a shareable URL").option("--public-share", "create a public redacted /work-graph/<token> share when publishing").option("--attach-artifact", "attach the report as an OrgX artifact when an initiative/entity is provided").option("--attach-to-initiative <id>", "attach the report to an existing OrgX initiative").option("--entity-type <type>", "entity type for artifact attachment: project, initiative, milestone, task, decision").option("--entity-id <id>", "entity id for artifact attachment").option("--artifact-url <url>", "override the artifact URL stored in OrgX").option("--yes", "approve publish/write prompts in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
15242
+ sessions.command("reconcile").description("Backfill recent Claude Code, Codex, OpenCode, goose, and Cursor sessions into a redacted OrgX Profile report.").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, github, slack, or all", "all").option("--session-limit <count>", "max recent sessions to import per selected source", "25").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only reconciliation").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--publish", "publish the generated OrgX Profile to OrgX and return a shareable URL").option("--public-share", "create a public redacted /work-graph/<token> share when publishing").option("--attach-artifact", "attach the report as an OrgX artifact when an initiative/entity is provided").option("--attach-to-initiative <id>", "attach the report to an existing OrgX initiative").option("--entity-type <type>", "entity type for artifact attachment: project, initiative, milestone, task, decision").option("--entity-id <id>", "entity id for artifact attachment").option("--artifact-url <url>", "override the artifact URL stored in OrgX").option("--yes", "approve publish/write prompts in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
14422
15243
  await safeTrackWizardTelemetry("sessions_reconcile_started", {
14423
15244
  command: "sessions reconcile",
14424
15245
  from: options.from ?? "all"