@useorgx/wizard 0.1.27 → 0.1.29

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
@@ -6229,6 +6229,8 @@ var DEFAULT_LIMIT_PER_SOURCE = 3;
6229
6229
  var DEFAULT_SINCE_DAYS = 30;
6230
6230
  var DEFAULT_MAX_BYTES_PER_FILE = 1e6;
6231
6231
  var AUDIT_RELEVANT_LINE_PATTERN = /\b(decision|decided|artifact|receipt|proof|commitment|committed|next action|follow[- ]?up|outcome|result|impact|roi|economics|token|cost|saved|open loop|gap|blocker|risk|owner|dri|writeback|rollback|quality score|mcp|tool call|orgx_emit_activity|orgx_apply_changeset|complete_with_proof|scaffold_initiative|mcp__orgx__)\b/i;
6232
+ var INSTRUCTION_BOILERPLATE_PATTERN = /^(?:#{1,6}\s*)?(?:agents\.md|instructions?|codex guardrails|precedence|read before you write|use exactly what was specified|don'?t confuse technologies|repo \+ scope hygiene|initiative \/ mcp discipline|ui quality bar|verification standards|secrets \+ safety|patch\/editing rules|commit \/ pr \/ merge protocol|output style|mcp integration|agent domains|skills|conventions)\b/i;
6233
+ var IMPERATIVE_BOILERPLATE_PATTERN = /^[-*]\s+(?:if the user|when the user|never|always|do not|don'?t|default to|treat|produce|pick|verify|avoid|match|use exactly|keep system boundaries|quote bracketed|for orgx|when capture tooling|if no meaningful|do \*\*not\*\*)\b/i;
6232
6234
  function parseAiSessionSources(value) {
6233
6235
  if (!value?.trim()) return [];
6234
6236
  const requested = value.split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
@@ -6284,7 +6286,9 @@ function extractClaudeMessageText(record) {
6284
6286
  return text2;
6285
6287
  }
6286
6288
  function keepAuditRelevantLines(text2) {
6287
- return text2.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && AUDIT_RELEVANT_LINE_PATTERN.test(line));
6289
+ return text2.split(/\r?\n/).map((line) => line.trim()).filter(
6290
+ (line) => line.length > 0 && AUDIT_RELEVANT_LINE_PATTERN.test(line) && !INSTRUCTION_BOILERPLATE_PATTERN.test(line) && !IMPERATIVE_BOILERPLATE_PATTERN.test(line)
6291
+ );
6288
6292
  }
6289
6293
  function collectJsonlFiles(root, source) {
6290
6294
  if (!existsSync5(root)) return [];
@@ -6908,6 +6912,10 @@ function shortHash(value, length = 16) {
6908
6912
  function sortedUnique(values) {
6909
6913
  return [...new Set(values)].sort();
6910
6914
  }
6915
+ function slugPart(value) {
6916
+ const normalized = normalizeFingerprintText(value).replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 64);
6917
+ return normalized || "unknown";
6918
+ }
6911
6919
  function sourceClientForImport(source) {
6912
6920
  const raw = `${source.sourceId} ${source.sourceLabel}`.toLowerCase();
6913
6921
  if (raw.includes("codex")) return "codex";
@@ -7169,6 +7177,491 @@ function buildKickoffs(findings, missed, score) {
7169
7177
  }
7170
7178
  return kickoffs.slice(0, 3);
7171
7179
  }
7180
+ function entityTypeForFinding(finding) {
7181
+ switch (finding.type) {
7182
+ case "decision":
7183
+ return "decision";
7184
+ case "artifact":
7185
+ return "artifact";
7186
+ case "blocker":
7187
+ return "blocker";
7188
+ case "person":
7189
+ return "person";
7190
+ case "business":
7191
+ return "business";
7192
+ case "product_surface":
7193
+ return "surface";
7194
+ case "goal":
7195
+ case "initiative_candidate":
7196
+ return "initiative";
7197
+ case "action":
7198
+ return /\b(outcome|shipped|completed|verified)\b/i.test(finding.summary) ? "outcome" : "task";
7199
+ case "missed_orchestration_opportunity":
7200
+ return "source";
7201
+ }
7202
+ }
7203
+ function trailKindForEntity(entityType) {
7204
+ switch (entityType) {
7205
+ case "decision":
7206
+ return "decision_trail";
7207
+ case "artifact":
7208
+ return "artifact_trail";
7209
+ case "person":
7210
+ return "person_trail";
7211
+ case "business":
7212
+ return "business_trail";
7213
+ case "blocker":
7214
+ return "blocker_trail";
7215
+ case "agent":
7216
+ return "agent_trail";
7217
+ case "tool":
7218
+ case "source":
7219
+ return "source_trail";
7220
+ case "outcome":
7221
+ return "outcome_trail";
7222
+ case "idea":
7223
+ return "idea_trail";
7224
+ case "initiative":
7225
+ case "workstream":
7226
+ case "milestone":
7227
+ case "task":
7228
+ case "surface":
7229
+ return "initiative_trail";
7230
+ }
7231
+ }
7232
+ function eventTypeForFinding(finding) {
7233
+ switch (finding.type) {
7234
+ case "decision":
7235
+ return "decision_inferred";
7236
+ case "artifact":
7237
+ return /\b(verified|proof|tested|passed)\b/i.test(finding.summary) ? "artifact_verified" : "artifact_created";
7238
+ case "blocker":
7239
+ return "blocker_detected";
7240
+ case "person":
7241
+ return "owner_assigned";
7242
+ case "business":
7243
+ return "signal_detected";
7244
+ case "product_surface":
7245
+ return "signal_detected";
7246
+ case "goal":
7247
+ case "initiative_candidate":
7248
+ return "initiative_created";
7249
+ case "action":
7250
+ return /\b(outcome|result|impact|roi)\b/i.test(finding.summary) ? "outcome_recorded" : "recommendation_generated";
7251
+ case "missed_orchestration_opportunity":
7252
+ return "source_connected";
7253
+ }
7254
+ }
7255
+ function trailStateForFindings(findings) {
7256
+ if (findings.some((finding) => finding.type === "blocker")) return "blocked";
7257
+ if (findings.some((finding) => finding.type === "missed_orchestration_opportunity")) return "missing_evidence";
7258
+ if (findings.some((finding) => /\b(contradict|conflict)\b/i.test(finding.summary))) return "contradicted";
7259
+ if (findings.some((finding) => /\b(verified|proof|passed|complete_with_proof)\b/i.test(finding.summary))) return "verified";
7260
+ if (findings.some((finding) => finding.type === "decision")) return "inferred";
7261
+ return "observed";
7262
+ }
7263
+ function trailValenceForFindings(findings, recurrence) {
7264
+ if (findings.some((finding) => finding.type === "blocker")) return recurrence > 1 ? "escalating" : "risk";
7265
+ if (findings.some((finding) => finding.type === "missed_orchestration_opportunity")) return "leak";
7266
+ if (findings.some((finding) => finding.type === "decision") && recurrence > 1) return "wasteful_recurrence";
7267
+ if (findings.some((finding) => finding.type === "business")) return "opportunity";
7268
+ if (findings.some((finding) => finding.type === "artifact")) return "healthy";
7269
+ return recurrence > 1 ? "useful_recurrence" : "opportunity";
7270
+ }
7271
+ function trailShapeForFindings(findings, recurrence) {
7272
+ const decisions = findings.filter((finding) => finding.type === "decision").length;
7273
+ const artifacts = findings.filter((finding) => finding.type === "artifact").length;
7274
+ if (decisions > artifacts && decisions > 0) return "decision_heavy_artifact_light";
7275
+ if (artifacts > decisions && artifacts > 0 && decisions === 0) return "artifact_heavy_decision_light";
7276
+ if (findings.some((finding) => finding.type === "blocker")) return "accelerating_issue";
7277
+ if (recurrence >= 3) return "chronic_recurrence";
7278
+ if (findings.some((finding) => /\b(resurface|again|back|revived|reappeared)\b/i.test(finding.summary))) return "zombie_revival";
7279
+ if (findings.some((finding) => /\b(verified|passed|shipped|completed)\b/i.test(finding.summary))) return "healthy_execution";
7280
+ return "dense_recent_cluster";
7281
+ }
7282
+ function buildWorkGraphTrails(findings, generatedAt) {
7283
+ const grouped = /* @__PURE__ */ new Map();
7284
+ for (const finding of findings) {
7285
+ const entityType = entityTypeForFinding(finding);
7286
+ const key = `${entityType}:${slugPart(finding.title)}`;
7287
+ grouped.set(key, [...grouped.get(key) ?? [], finding]);
7288
+ }
7289
+ return [...grouped.entries()].map(([key, group], index) => {
7290
+ const first = group[0];
7291
+ const entityType = entityTypeForFinding(first);
7292
+ const entityId = `${entityType}:${shortHash(key, 12)}`;
7293
+ const trailId = `trail:${shortHash({ key, evidence: group.map((finding) => finding.evidence_ref) }, 14)}`;
7294
+ const recurrence = group.length;
7295
+ const evidenceRefs = sortedUnique(group.map((finding) => finding.evidence_ref));
7296
+ const events = group.map((finding, eventIndex) => ({
7297
+ id: `${trailId}:event:${eventIndex + 1}`,
7298
+ trail_id: trailId,
7299
+ event_type: eventTypeForFinding(finding),
7300
+ entity_id: entityId,
7301
+ entity_type: entityType,
7302
+ timestamp: generatedAt,
7303
+ source_id: finding.source_id,
7304
+ source_type: finding.source_client,
7305
+ redacted_verbatim: finding.summary.slice(0, 320),
7306
+ confidence: finding.confidence,
7307
+ evidence_refs: [finding.evidence_ref],
7308
+ privacy_state: "redacted"
7309
+ }));
7310
+ const edges = events.slice(1).map((event, edgeIndex) => ({
7311
+ id: `${trailId}:edge:${edgeIndex + 1}`,
7312
+ from_event_id: events[edgeIndex].id,
7313
+ to_event_id: event.id,
7314
+ relation: group.some((finding) => finding.type === "blocker") ? "blocked" : "informed",
7315
+ state: recurrence > 1 ? "captured" : "inferred",
7316
+ confidence: Math.min(0.92, Math.max(0.58, event.confidence - 0.04)),
7317
+ evidence_refs: event.evidence_refs
7318
+ }));
7319
+ const confidence = group.reduce((total, finding) => total + finding.confidence, 0) / group.length;
7320
+ return {
7321
+ id: trailId,
7322
+ kind: trailKindForEntity(entityType),
7323
+ title: first.title,
7324
+ summary: first.summary,
7325
+ subject_entity_id: entityId,
7326
+ subject_entity_type: entityType,
7327
+ state: trailStateForFindings(group),
7328
+ valence: trailValenceForFindings(group, recurrence),
7329
+ confidence: Number(confidence.toFixed(2)),
7330
+ recurrence_score: Math.min(100, recurrence * 28 + evidenceRefs.length * 6),
7331
+ impact_score: Math.min(100, Math.round(first.confidence * 70) + recurrence * 8 + (index < 4 ? 10 : 0)),
7332
+ privacy_state: "redacted",
7333
+ events,
7334
+ edges,
7335
+ evidence_refs: evidenceRefs,
7336
+ blocker_ids: group.filter((finding) => finding.type === "blocker").map((finding) => finding.evidence_ref),
7337
+ recommendation_ids: [],
7338
+ created_at: generatedAt,
7339
+ updated_at: generatedAt,
7340
+ shape: trailShapeForFindings(group, recurrence)
7341
+ };
7342
+ });
7343
+ }
7344
+ function severityFor(count) {
7345
+ if (count >= 6) return "critical";
7346
+ if (count >= 3) return "high";
7347
+ if (count >= 2) return "medium";
7348
+ return "low";
7349
+ }
7350
+ function trailsForType(trails, entityType) {
7351
+ return trails.filter((trail) => trail.subject_entity_type === entityType);
7352
+ }
7353
+ function buildRecurringPatterns(coverage, findings, trails) {
7354
+ const patterns = [];
7355
+ const decisionTrails = trailsForType(trails, "decision");
7356
+ const artifactTrails = trailsForType(trails, "artifact");
7357
+ const blockerTrails = trailsForType(trails, "blocker");
7358
+ const personTrails = trailsForType(trails, "person");
7359
+ const businessTrails = trailsForType(trails, "business");
7360
+ const highRecurrence = trails.filter((trail) => trail.recurrence_score >= 56);
7361
+ if (decisionTrails.length > 0 && !coverage.orgxMcpCalled) {
7362
+ patterns.push({
7363
+ id: "pattern:trapped-decision",
7364
+ title: "Decisions are being made without durable OrgX writeback",
7365
+ description: `${decisionTrails.length} decision trail${decisionTrails.length === 1 ? "" : "s"} appeared while no OrgX MCP write was detected.`,
7366
+ pattern_type: "trapped_decision",
7367
+ affected_trail_ids: decisionTrails.map((trail) => trail.id),
7368
+ affected_entity_ids: decisionTrails.map((trail) => trail.subject_entity_id),
7369
+ recurrence_count: decisionTrails.length,
7370
+ severity: severityFor(decisionTrails.length + 1),
7371
+ confidence: coverage.orgxObserved ? 0.82 : 0.74,
7372
+ valence: "leak",
7373
+ root_cause_hypothesis: "Agents and humans are making useful choices, but the runtime is not promoting those choices into organizational memory.",
7374
+ recommended_runtime_action_id: "recommendation:promote-decisions"
7375
+ });
7376
+ }
7377
+ if (artifactTrails.length > 0 && personTrails.length === 0) {
7378
+ patterns.push({
7379
+ id: "pattern:orphaned-artifact",
7380
+ title: "Artifacts do not have visible ownership",
7381
+ description: `${artifactTrails.length} artifact trail${artifactTrails.length === 1 ? "" : "s"} appeared without a clear owner trail.`,
7382
+ pattern_type: "orphaned_artifact",
7383
+ affected_trail_ids: artifactTrails.map((trail) => trail.id),
7384
+ affected_entity_ids: artifactTrails.map((trail) => trail.subject_entity_id),
7385
+ recurrence_count: artifactTrails.length,
7386
+ severity: severityFor(artifactTrails.length),
7387
+ confidence: 0.72,
7388
+ valence: "risk",
7389
+ root_cause_hypothesis: "Work is becoming concrete, but downstream accountability is not being attached at creation time.",
7390
+ recommended_runtime_action_id: "recommendation:assign-owner"
7391
+ });
7392
+ }
7393
+ if (coverage.missing.length > 0) {
7394
+ const sourceTrails = trailsForType(trails, "source");
7395
+ patterns.push({
7396
+ id: "pattern:missing-source",
7397
+ title: "Important source coverage is missing",
7398
+ description: `Missing sources: ${coverage.missing.join(", ")}.`,
7399
+ pattern_type: "missing_source",
7400
+ affected_trail_ids: sourceTrails.map((trail) => trail.id),
7401
+ affected_entity_ids: sourceTrails.map((trail) => trail.subject_entity_id),
7402
+ recurrence_count: coverage.missing.length,
7403
+ severity: severityFor(coverage.missing.length),
7404
+ confidence: 0.78,
7405
+ valence: "leak",
7406
+ root_cause_hypothesis: "The scan can see work happening, but coordination and proof sources are not fully connected.",
7407
+ recommended_runtime_action_id: "recommendation:connect-source"
7408
+ });
7409
+ }
7410
+ if (coverage.mcpObserved && !coverage.orgxMcpCalled) {
7411
+ patterns.push({
7412
+ id: "pattern:tooling-mismatch",
7413
+ title: "MCP was present, but OrgX was not called",
7414
+ description: "The session mentions MCP/tooling activity, but no durable OrgX MCP call was detected.",
7415
+ pattern_type: "tooling_mismatch",
7416
+ affected_trail_ids: trails.map((trail) => trail.id).slice(0, 6),
7417
+ affected_entity_ids: trails.map((trail) => trail.subject_entity_id).slice(0, 6),
7418
+ recurrence_count: findings.filter((finding) => /\bmcp|tool\b/i.test(finding.summary)).length || 1,
7419
+ severity: "high",
7420
+ confidence: 0.8,
7421
+ valence: "leak",
7422
+ root_cause_hypothesis: "The available tool layer is not automatically closing the loop when work finishes.",
7423
+ recommended_runtime_action_id: "recommendation:install-runtime-hooks"
7424
+ });
7425
+ }
7426
+ if (highRecurrence.length > 0) {
7427
+ patterns.push({
7428
+ id: "pattern:repeated-work",
7429
+ title: "The same work shape is recurring",
7430
+ description: `${highRecurrence.length} trail${highRecurrence.length === 1 ? "" : "s"} repeat strongly enough to deserve durable operating memory.`,
7431
+ pattern_type: "repeated_work",
7432
+ affected_trail_ids: highRecurrence.map((trail) => trail.id),
7433
+ affected_entity_ids: highRecurrence.map((trail) => trail.subject_entity_id),
7434
+ recurrence_count: highRecurrence.reduce((total, trail) => total + trail.events.length, 0),
7435
+ severity: severityFor(highRecurrence.length),
7436
+ confidence: 0.7,
7437
+ valence: "useful_recurrence",
7438
+ root_cause_hypothesis: "Repeated work is creating a reusable operating pattern, but it is still only implicit.",
7439
+ recommended_runtime_action_id: "recommendation:launch-initiative"
7440
+ });
7441
+ }
7442
+ if (businessTrails.length > 0 && findings.every((finding) => finding.type !== "initiative_candidate")) {
7443
+ patterns.push({
7444
+ id: "pattern:business-signal-unclaimed",
7445
+ title: "Business signal has not become a launchable initiative",
7446
+ description: `${businessTrails.length} business trail${businessTrails.length === 1 ? "" : "s"} appeared without a matching initiative candidate.`,
7447
+ pattern_type: "business_signal_unclaimed",
7448
+ affected_trail_ids: businessTrails.map((trail) => trail.id),
7449
+ affected_entity_ids: businessTrails.map((trail) => trail.subject_entity_id),
7450
+ recurrence_count: businessTrails.length,
7451
+ severity: severityFor(businessTrails.length),
7452
+ confidence: 0.68,
7453
+ valence: "opportunity",
7454
+ root_cause_hypothesis: "Revenue or ROI signal exists, but the operating graph has not turned it into an account or initiative loop.",
7455
+ recommended_runtime_action_id: "recommendation:launch-initiative"
7456
+ });
7457
+ }
7458
+ if (blockerTrails.length > 0) {
7459
+ patterns.push({
7460
+ id: "pattern:handoff-friction",
7461
+ title: "Blockers are becoming handoff friction",
7462
+ description: `${blockerTrails.length} blocker trail${blockerTrails.length === 1 ? "" : "s"} need owner-visible resolution.`,
7463
+ pattern_type: "handoff_friction",
7464
+ affected_trail_ids: blockerTrails.map((trail) => trail.id),
7465
+ affected_entity_ids: blockerTrails.map((trail) => trail.subject_entity_id),
7466
+ recurrence_count: blockerTrails.length,
7467
+ severity: severityFor(blockerTrails.length + 1),
7468
+ confidence: 0.76,
7469
+ valence: "risk",
7470
+ root_cause_hypothesis: "Execution is producing unresolved edges that need to become assigned decisions or tasks.",
7471
+ recommended_runtime_action_id: "recommendation:assign-owner"
7472
+ });
7473
+ }
7474
+ return patterns.slice(0, 8);
7475
+ }
7476
+ function buildTrailRecommendations(patterns, trails) {
7477
+ const recommendations = [];
7478
+ const add = (recommendation) => {
7479
+ if (!recommendations.some((existing) => existing.id === recommendation.id)) {
7480
+ recommendations.push(recommendation);
7481
+ }
7482
+ };
7483
+ for (const pattern of patterns) {
7484
+ const evidenceRefs = sortedUnique(
7485
+ trails.filter((trail) => pattern.affected_trail_ids.includes(trail.id)).flatMap((trail) => trail.evidence_refs)
7486
+ ).slice(0, 8);
7487
+ if (pattern.pattern_type === "trapped_decision") {
7488
+ add({
7489
+ id: "recommendation:promote-decisions",
7490
+ title: "Promote trapped decisions",
7491
+ summary: "Turn inferred decisions into reviewed OrgX decision records with owners and downstream artifact links.",
7492
+ action_type: "promote_decision",
7493
+ trail_ids: pattern.affected_trail_ids,
7494
+ evidence_refs: evidenceRefs,
7495
+ priority: pattern.severity === "critical" || pattern.severity === "high" ? "p0" : "p1",
7496
+ expected_lift: "+decision durability",
7497
+ confidence: pattern.confidence
7498
+ });
7499
+ } else if (pattern.pattern_type === "orphaned_artifact") {
7500
+ add({
7501
+ id: "recommendation:assign-owner",
7502
+ title: "Assign ownership to orphaned artifacts",
7503
+ summary: "Attach owners and next actions to artifacts before they decay into unqueryable receipts.",
7504
+ action_type: "assign_owner",
7505
+ trail_ids: pattern.affected_trail_ids,
7506
+ evidence_refs: evidenceRefs,
7507
+ priority: "p1",
7508
+ expected_lift: "+owner clarity",
7509
+ confidence: pattern.confidence
7510
+ });
7511
+ } else if (pattern.pattern_type === "missing_source") {
7512
+ add({
7513
+ id: "recommendation:connect-source",
7514
+ title: "Connect missing source coverage",
7515
+ summary: "Close the evidence gap by connecting the coordination or proof sources where trails terminate.",
7516
+ action_type: "connect_source",
7517
+ trail_ids: pattern.affected_trail_ids,
7518
+ evidence_refs: evidenceRefs,
7519
+ priority: "p1",
7520
+ expected_lift: "+source confidence",
7521
+ confidence: pattern.confidence
7522
+ });
7523
+ } else if (pattern.pattern_type === "tooling_mismatch") {
7524
+ add({
7525
+ id: "recommendation:install-runtime-hooks",
7526
+ title: "Install runtime writeback hooks",
7527
+ summary: "Use post-session reconciliation so useful work becomes OrgX activity even when the agent forgets.",
7528
+ action_type: "verify_outcome",
7529
+ trail_ids: pattern.affected_trail_ids,
7530
+ evidence_refs: evidenceRefs,
7531
+ priority: "p0",
7532
+ expected_lift: "+continuous attribution",
7533
+ confidence: pattern.confidence
7534
+ });
7535
+ } else if (pattern.pattern_type === "business_signal_unclaimed" || pattern.pattern_type === "repeated_work") {
7536
+ add({
7537
+ id: "recommendation:launch-initiative",
7538
+ title: "Launch from this trail",
7539
+ summary: "Convert the highest-recurring evidence path into an OrgX initiative with proof requirements.",
7540
+ action_type: "launch_initiative",
7541
+ trail_ids: pattern.affected_trail_ids,
7542
+ evidence_refs: evidenceRefs,
7543
+ priority: pattern.severity === "critical" || pattern.severity === "high" ? "p0" : "p1",
7544
+ expected_lift: "+initiative readiness",
7545
+ confidence: pattern.confidence
7546
+ });
7547
+ }
7548
+ }
7549
+ if (recommendations.length === 0 && trails.length > 0) {
7550
+ const topTrail = [...trails].sort((a, b) => b.impact_score - a.impact_score)[0];
7551
+ add({
7552
+ id: "recommendation:inspect-top-trail",
7553
+ title: "Inspect the strongest trail",
7554
+ summary: "Review the highest-confidence evidence path and decide whether it should become durable OrgX memory.",
7555
+ action_type: "launch_initiative",
7556
+ trail_ids: [topTrail.id],
7557
+ evidence_refs: topTrail.evidence_refs,
7558
+ priority: "p2",
7559
+ expected_lift: "+operating memory",
7560
+ confidence: topTrail.confidence
7561
+ });
7562
+ }
7563
+ return recommendations.slice(0, 5);
7564
+ }
7565
+ function buildWorkGraphMirror(input) {
7566
+ const { coverage, generatedAt, patterns, recommendations, trails } = input;
7567
+ const topTrail = [...trails].sort((a, b) => b.impact_score - a.impact_score)[0];
7568
+ const topPattern = [...patterns].sort((a, b) => b.recurrence_count - a.recurrence_count)[0];
7569
+ const decisionCount = trailsForType(trails, "decision").length;
7570
+ const artifactCount = trailsForType(trails, "artifact").length;
7571
+ const blockerCount = trailsForType(trails, "blocker").length;
7572
+ const sourceGapCount = coverage.missing.length;
7573
+ const headline = topPattern ? topPattern.title : topTrail ? `${topTrail.title} is the clearest work trail` : "Your work is leaving an operating trail";
7574
+ const primaryClaimRefs = topTrail?.evidence_refs ?? [];
7575
+ const claims = [
7576
+ {
7577
+ id: "mirror:trail-count",
7578
+ text: `${trails.length} trails were detected across ${coverage.connected.length} connected source${coverage.connected.length === 1 ? "" : "s"}.`,
7579
+ evidence_refs: trails.flatMap((trail) => trail.evidence_refs).slice(0, 6),
7580
+ confidence: trails.length > 0 ? 0.82 : 0.55
7581
+ },
7582
+ {
7583
+ id: "mirror:decision-artifact-balance",
7584
+ text: `${decisionCount} decision trail${decisionCount === 1 ? "" : "s"} and ${artifactCount} artifact trail${artifactCount === 1 ? "" : "s"} were found.`,
7585
+ evidence_refs: trails.filter((trail) => trail.subject_entity_type === "decision" || trail.subject_entity_type === "artifact").flatMap((trail) => trail.evidence_refs).slice(0, 6),
7586
+ confidence: 0.78
7587
+ },
7588
+ {
7589
+ id: "mirror:missing-sources",
7590
+ text: sourceGapCount > 0 ? `${sourceGapCount} source gap${sourceGapCount === 1 ? "" : "s"} still limit attribution depth.` : "The connected sources are enough for a first operating profile.",
7591
+ evidence_refs: trailsForType(trails, "source").flatMap((trail) => trail.evidence_refs).slice(0, 4),
7592
+ confidence: sourceGapCount > 0 ? 0.76 : 0.66
7593
+ }
7594
+ ];
7595
+ const body = [
7596
+ `OrgX found ${trails.length} evidence trail${trails.length === 1 ? "" : "s"} across ${coverage.connected.join(", ") || "local sources"}.`,
7597
+ `The strongest signal is ${topPattern ? topPattern.title.toLowerCase() : topTrail?.title ?? "still forming"}.`,
7598
+ blockerCount > 0 ? `${blockerCount} blocker trail${blockerCount === 1 ? "" : "s"} need promotion into owner-visible work.` : "The healthiest trails already connect evidence to action.",
7599
+ recommendations[0] ? `The next durable move is: ${recommendations[0].title}.` : "The next move is to inspect the highest-confidence trail before publishing it."
7600
+ ].join(" ");
7601
+ return {
7602
+ headline,
7603
+ body,
7604
+ lens: "all",
7605
+ claims,
7606
+ ...topTrail ? { primary_trail_id: topTrail.id } : {},
7607
+ generated_at: generatedAt
7608
+ };
7609
+ }
7610
+ function buildTensionMetrics(input) {
7611
+ const { coverage, patterns, trails } = input;
7612
+ const decisionTrails = trailsForType(trails, "decision");
7613
+ const blockerTrails = trailsForType(trails, "blocker");
7614
+ const artifactTrails = trailsForType(trails, "artifact");
7615
+ const missingSourceTrails = trailsForType(trails, "source");
7616
+ const topReady = trails.filter((trail) => trail.impact_score >= 70 && trail.confidence >= 0.75);
7617
+ return [
7618
+ {
7619
+ id: "tension:work-leaks",
7620
+ label: "work leaks",
7621
+ value: String(patterns.filter((pattern) => pattern.valence === "leak" || pattern.valence === "risk").length),
7622
+ tone: patterns.some((pattern) => pattern.severity === "critical" || pattern.severity === "high") ? "danger" : "warning",
7623
+ trail_ids: patterns.flatMap((pattern) => pattern.affected_trail_ids).slice(0, 8),
7624
+ evidence_refs: trails.flatMap((trail) => trail.evidence_refs).slice(0, 8),
7625
+ explanation: "Patterns where evidence exists but ownership, source coverage, or writeback is incomplete."
7626
+ },
7627
+ {
7628
+ id: "tension:decisions-decaying",
7629
+ label: "decisions decaying",
7630
+ value: String(decisionTrails.filter((trail) => trail.state === "inferred" || trail.state === "missing_evidence").length),
7631
+ tone: decisionTrails.length > 0 && !coverage.orgxMcpCalled ? "danger" : "muted",
7632
+ trail_ids: decisionTrails.map((trail) => trail.id),
7633
+ evidence_refs: decisionTrails.flatMap((trail) => trail.evidence_refs).slice(0, 8),
7634
+ explanation: "Decision trails that have not been promoted into durable OrgX records."
7635
+ },
7636
+ {
7637
+ id: "tension:artifacts-orphaned",
7638
+ label: "artifacts orphaned",
7639
+ value: String(artifactTrails.filter((trail) => trail.state !== "verified").length),
7640
+ tone: artifactTrails.some((trail) => trail.shape === "artifact_heavy_decision_light") ? "warning" : "muted",
7641
+ trail_ids: artifactTrails.map((trail) => trail.id),
7642
+ evidence_refs: artifactTrails.flatMap((trail) => trail.evidence_refs).slice(0, 8),
7643
+ explanation: "Artifacts that exist without complete decision, verification, or owner context."
7644
+ },
7645
+ {
7646
+ id: "tension:sources-missing",
7647
+ label: "sources missing",
7648
+ value: String(coverage.missing.length),
7649
+ tone: coverage.missing.length > 0 ? "warning" : "good",
7650
+ trail_ids: missingSourceTrails.map((trail) => trail.id),
7651
+ evidence_refs: missingSourceTrails.flatMap((trail) => trail.evidence_refs).slice(0, 6),
7652
+ explanation: "Disconnected coordination or proof sources that limit attribution confidence."
7653
+ },
7654
+ {
7655
+ id: "tension:launch-ready",
7656
+ label: "launch ready",
7657
+ value: String(topReady.length),
7658
+ tone: topReady.length > 0 && blockerTrails.length === 0 ? "good" : "muted",
7659
+ trail_ids: topReady.map((trail) => trail.id).slice(0, 6),
7660
+ evidence_refs: topReady.flatMap((trail) => trail.evidence_refs).slice(0, 8),
7661
+ explanation: "High-confidence trails that can become initiatives, decisions, artifacts, or owner-visible follow-ups."
7662
+ }
7663
+ ];
7664
+ }
7172
7665
  function countFindingsByType(findings) {
7173
7666
  const counts = {};
7174
7667
  for (const finding of findings) {
@@ -7195,6 +7688,24 @@ function buildWorkGraphFingerprint(input) {
7195
7688
  priority: kickoff.priority
7196
7689
  })
7197
7690
  ).sort();
7691
+ const trailShapeHashes = input.trails.map(
7692
+ (trail) => shortHash({
7693
+ kind: trail.kind,
7694
+ subject_entity_type: trail.subject_entity_type,
7695
+ state: trail.state,
7696
+ valence: trail.valence,
7697
+ shape: trail.shape,
7698
+ title: normalizeFingerprintText(trail.title)
7699
+ })
7700
+ ).sort();
7701
+ const recurringPatternHashes = input.recurringPatterns.map(
7702
+ (pattern) => shortHash({
7703
+ pattern_type: pattern.pattern_type,
7704
+ severity: pattern.severity,
7705
+ title: normalizeFingerprintText(pattern.title),
7706
+ recurrence_count: pattern.recurrence_count
7707
+ })
7708
+ ).sort();
7198
7709
  const basis = {
7199
7710
  schema_version: WORK_GRAPH_SCHEMA_VERSION,
7200
7711
  fingerprint_version: WORK_GRAPH_FINGERPRINT_VERSION,
@@ -7211,6 +7722,8 @@ function buildWorkGraphFingerprint(input) {
7211
7722
  ),
7212
7723
  finding_type_counts: countFindingsByType(input.findings),
7213
7724
  pattern_hashes: patternHashes,
7725
+ trail_shape_hashes: trailShapeHashes,
7726
+ recurring_pattern_hashes: recurringPatternHashes,
7214
7727
  kickoff_hashes: kickoffHashes,
7215
7728
  raw_transcripts_included: false
7216
7729
  };
@@ -7241,13 +7754,30 @@ function buildSessionReconciliationReport(input) {
7241
7754
  const findings = buildWorkGraphFindings(input.imports);
7242
7755
  const missed = buildMissedOpportunities(coverage, findings);
7243
7756
  const allFindings = [...findings, ...missed];
7757
+ const trails = buildWorkGraphTrails(allFindings, generatedAt);
7758
+ const recurringPatterns = buildRecurringPatterns(coverage, allFindings, trails);
7244
7759
  const opportunityScore = scoreOpportunity(coverage, allFindings);
7245
7760
  const initiativeKickoffs = buildKickoffs(allFindings, missed, opportunityScore);
7761
+ const recommendations = buildTrailRecommendations(recurringPatterns, trails);
7762
+ const mirror = buildWorkGraphMirror({
7763
+ coverage,
7764
+ generatedAt,
7765
+ patterns: recurringPatterns,
7766
+ recommendations,
7767
+ trails
7768
+ });
7769
+ const tensionMetrics = buildTensionMetrics({
7770
+ coverage,
7771
+ patterns: recurringPatterns,
7772
+ trails
7773
+ });
7246
7774
  const fingerprint = buildWorkGraphFingerprint({
7247
7775
  connectedSources,
7248
7776
  findings: allFindings,
7249
7777
  kickoffs: initiativeKickoffs,
7250
7778
  missingSources,
7779
+ recurringPatterns,
7780
+ trails,
7251
7781
  workspace: input.workspace
7252
7782
  });
7253
7783
  const reportSeed = {
@@ -7277,6 +7807,11 @@ function buildSessionReconciliationReport(input) {
7277
7807
  events,
7278
7808
  findings: allFindings,
7279
7809
  missed_orchestration_opportunities: missed,
7810
+ trails,
7811
+ recurring_patterns: recurringPatterns,
7812
+ recommendations,
7813
+ mirror,
7814
+ tension_metrics: tensionMetrics,
7280
7815
  opportunity_score: opportunityScore,
7281
7816
  initiative_kickoffs: initiativeKickoffs,
7282
7817
  redaction_level: "summary_only",
@@ -7312,6 +7847,38 @@ function renderWorkGraphMarkdown(report) {
7312
7847
  lines.push(`OrgX observed: ${report.source_coverage.orgxObserved ? "yes" : "no"}`);
7313
7848
  lines.push(`OrgX MCP called: ${report.source_coverage.orgxMcpCalled ? "yes" : "no"}`);
7314
7849
  lines.push("");
7850
+ lines.push("## Mirror");
7851
+ lines.push("");
7852
+ lines.push(`### ${report.mirror.headline}`);
7853
+ lines.push("");
7854
+ lines.push(report.mirror.body);
7855
+ lines.push("");
7856
+ for (const claim of report.mirror.claims) {
7857
+ lines.push(`- ${claim.text} (${claim.evidence_refs.join(", ") || "no evidence refs"})`);
7858
+ }
7859
+ lines.push("");
7860
+ lines.push("## Live Tension");
7861
+ lines.push("");
7862
+ for (const metric of report.tension_metrics) {
7863
+ lines.push(`- ${metric.value} ${metric.label}: ${metric.explanation}`);
7864
+ }
7865
+ lines.push("");
7866
+ lines.push("## Work Graph Trails");
7867
+ lines.push("");
7868
+ for (const trail of report.trails.slice(0, 12)) {
7869
+ lines.push(`- [${trail.kind}] ${trail.title} \u2014 ${trail.state}, ${trail.valence}, ${trail.shape} (${trail.evidence_refs.join(", ")})`);
7870
+ }
7871
+ lines.push("");
7872
+ lines.push("## Recurring Patterns");
7873
+ lines.push("");
7874
+ if (report.recurring_patterns.length === 0) {
7875
+ lines.push("- No recurring patterns detected yet.");
7876
+ } else {
7877
+ for (const pattern of report.recurring_patterns) {
7878
+ lines.push(`- [${pattern.severity}] ${pattern.title}: ${pattern.root_cause_hypothesis}`);
7879
+ }
7880
+ }
7881
+ lines.push("");
7315
7882
  lines.push("## Top Findings");
7316
7883
  lines.push("");
7317
7884
  for (const finding of report.findings.slice(0, 12)) {
@@ -7334,6 +7901,12 @@ function renderWorkGraphMarkdown(report) {
7334
7901
  lines.push(`- [${kickoff.priority}] ${kickoff.title}: ${kickoff.summary}`);
7335
7902
  }
7336
7903
  lines.push("");
7904
+ lines.push("## Eject Bay Recommendations");
7905
+ lines.push("");
7906
+ for (const recommendation of report.recommendations) {
7907
+ lines.push(`- [${recommendation.priority}] ${recommendation.title}: ${recommendation.summary}`);
7908
+ }
7909
+ lines.push("");
7337
7910
  lines.push("## Signup Hydration");
7338
7911
  lines.push("");
7339
7912
  lines.push(`- Strategy: ${report.signup_hydration.strategy}`);
@@ -7991,7 +8564,11 @@ async function runWorkGraphCommand(options, defaults = {}) {
7991
8564
  finalState: report.final_state,
7992
8565
  opportunityScore: report.opportunity_score,
7993
8566
  missedOrchestration: report.missed_orchestration_opportunities.length,
7994
- kickoffCount: report.initiative_kickoffs.length
8567
+ kickoffCount: report.initiative_kickoffs.length,
8568
+ trailCount: report.trails.length,
8569
+ recurringPatternCount: report.recurring_patterns.length,
8570
+ topTrail: report.mirror.primary_trail_id ?? null,
8571
+ mirrorHeadline: report.mirror.headline
7995
8572
  }, null, 2));
7996
8573
  return;
7997
8574
  }
@@ -8003,6 +8580,12 @@ async function runWorkGraphCommand(options, defaults = {}) {
8003
8580
  const missed = report.missed_orchestration_opportunities.length;
8004
8581
  const missedColor = missed > 0 ? pc3.yellow : pc3.green;
8005
8582
  console.log(` ${missed > 0 ? ICON.warn : ICON.ok} ${missedColor("missed ")} ${pc3.dim(`${missed} orchestration opportunit${missed === 1 ? "y" : "ies"}`)}`);
8583
+ console.log(` ${ICON.ok} ${pc3.green("trails ")} ${pc3.dim(`${report.trails.length} trail${report.trails.length === 1 ? "" : "s"} \xB7 ${report.recurring_patterns.length} recurring pattern${report.recurring_patterns.length === 1 ? "" : "s"}`)}`);
8584
+ console.log(` ${ICON.skip} ${pc3.bold("mirror ")} ${report.mirror.headline}`);
8585
+ for (const metric of report.tension_metrics.slice(0, 4)) {
8586
+ const tone = metric.tone === "danger" ? pc3.red : metric.tone === "warning" ? pc3.yellow : metric.tone === "good" ? pc3.green : pc3.dim;
8587
+ console.log(` ${ICON.skip} ${tone(`${metric.value} ${metric.label}`)} ${pc3.dim(metric.explanation)}`);
8588
+ }
8006
8589
  for (const kickoff of report.initiative_kickoffs) {
8007
8590
  console.log(` ${ICON.skip} ${pc3.bold(kickoff.priority.padEnd(3))} ${kickoff.title}`);
8008
8591
  }
@@ -8965,7 +9548,7 @@ function printDoctorReport(report, assessment) {
8965
9548
  async function main() {
8966
9549
  const program = new Command();
8967
9550
  program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
8968
- const pkgVersion = true ? "0.1.27" : void 0;
9551
+ const pkgVersion = true ? "0.1.29" : void 0;
8969
9552
  program.version(pkgVersion ?? "unknown", "-V, --version");
8970
9553
  program.hook("preAction", () => {
8971
9554
  console.log(renderBanner(pkgVersion));
@@ -9672,6 +10255,13 @@ async function main() {
9672
10255
  });
9673
10256
  await runWorkGraphCommand(options);
9674
10257
  });
10258
+ workGraph.command("profile").description("Build a local OrgX Profile with Work Graph Trails, Mirror, tensions, and launch recommendations.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--from <sources>", "auto-import recent local AI sessions: codex, claude, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "5").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("--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("--json", "emit a JSON command summary").action(async (options) => {
10259
+ await safeTrackWizardTelemetry("work_graph_profile_started", {
10260
+ command: "work-graph profile",
10261
+ from: options.from ?? "manual"
10262
+ });
10263
+ await runWorkGraphCommand(options);
10264
+ });
9675
10265
  const sessions = program.command("sessions").description("Inspect and reconcile local AI sessions into OrgX-ready Work Graph reports.");
9676
10266
  sessions.command("reconcile").description("Backfill recent Codex and Claude sessions into a redacted Work Graph report.").option("--from <sources>", "auto-import recent local AI sessions: codex, claude, or all", "all").option("--session-limit <count>", "max recent sessions to import per selected source", "5").option("--session-days <days>", "lookback window for local AI-session imports", "7").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("--json", "emit a JSON command summary").action(async (options) => {
9677
10267
  await safeTrackWizardTelemetry("sessions_reconcile_started", {