@tomismeta/paperclip-aperture 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/worker.js CHANGED
@@ -4,17 +4,17 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
- // node_modules/.pnpm/@paperclipai+plugin-sdk@2026.318.0_react@19.2.4/node_modules/@paperclipai/plugin-sdk/dist/define-plugin.js
7
+ // node_modules/.pnpm/@paperclipai+plugin-sdk@2026.403.0_react@19.2.4/node_modules/@paperclipai/plugin-sdk/dist/define-plugin.js
8
8
  function definePlugin(definition) {
9
9
  return Object.freeze({ definition });
10
10
  }
11
11
 
12
- // node_modules/.pnpm/@paperclipai+plugin-sdk@2026.318.0_react@19.2.4/node_modules/@paperclipai/plugin-sdk/dist/worker-rpc-host.js
12
+ // node_modules/.pnpm/@paperclipai+plugin-sdk@2026.403.0_react@19.2.4/node_modules/@paperclipai/plugin-sdk/dist/worker-rpc-host.js
13
13
  import path from "node:path";
14
14
  import { createInterface } from "node:readline";
15
15
  import { fileURLToPath } from "node:url";
16
16
 
17
- // node_modules/.pnpm/@paperclipai+plugin-sdk@2026.318.0_react@19.2.4/node_modules/@paperclipai/plugin-sdk/dist/protocol.js
17
+ // node_modules/.pnpm/@paperclipai+plugin-sdk@2026.403.0_react@19.2.4/node_modules/@paperclipai/plugin-sdk/dist/protocol.js
18
18
  var JSONRPC_VERSION = "2.0";
19
19
  var JSONRPC_ERROR_CODES = {
20
20
  /** Invalid JSON was received by the server. */
@@ -144,7 +144,7 @@ var JsonRpcCallError = class extends Error {
144
144
  }
145
145
  };
146
146
 
147
- // node_modules/.pnpm/@paperclipai+plugin-sdk@2026.318.0_react@19.2.4/node_modules/@paperclipai/plugin-sdk/dist/worker-rpc-host.js
147
+ // node_modules/.pnpm/@paperclipai+plugin-sdk@2026.403.0_react@19.2.4/node_modules/@paperclipai/plugin-sdk/dist/worker-rpc-host.js
148
148
  var DEFAULT_RPC_TIMEOUT_MS = 3e4;
149
149
  function runWorker(plugin2, moduleUrl, options) {
150
150
  if (options?.stdin != null && options?.stdout != null) {
@@ -444,6 +444,7 @@ function startWorkerRpcHost(options) {
444
444
  projectId: input.projectId,
445
445
  goalId: input.goalId,
446
446
  parentId: input.parentId,
447
+ inheritExecutionWorkspaceFromIssueId: input.inheritExecutionWorkspaceFromIssueId,
447
448
  title: input.title,
448
449
  description: input.description,
449
450
  priority: input.priority,
@@ -611,6 +612,11 @@ function startWorkerRpcHost(options) {
611
612
  await callHost("metrics.write", { name, value, tags });
612
613
  }
613
614
  },
615
+ telemetry: {
616
+ async track(eventName, dimensions) {
617
+ await callHost("telemetry.track", { eventName, dimensions });
618
+ }
619
+ },
614
620
  logger: {
615
621
  info(message, meta) {
616
622
  notifyHost("log", { level: "info", message, meta });
@@ -4936,7 +4942,7 @@ var coerce = {
4936
4942
  };
4937
4943
  var NEVER = INVALID;
4938
4944
 
4939
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/constants.js
4945
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/constants.js
4940
4946
  var COMPANY_STATUSES = ["active", "paused", "archived"];
4941
4947
  var DEPLOYMENT_MODES = ["local_trusted", "authenticated"];
4942
4948
  var DEPLOYMENT_EXPOSURES = ["private", "public"];
@@ -4955,6 +4961,7 @@ var AGENT_ADAPTER_TYPES = [
4955
4961
  "http",
4956
4962
  "claude_local",
4957
4963
  "codex_local",
4964
+ "gemini_local",
4958
4965
  "opencode_local",
4959
4966
  "pi_local",
4960
4967
  "cursor",
@@ -5026,6 +5033,15 @@ var ISSUE_STATUSES = [
5026
5033
  "blocked",
5027
5034
  "cancelled"
5028
5035
  ];
5036
+ var INBOX_MINE_ISSUE_STATUSES = [
5037
+ "backlog",
5038
+ "todo",
5039
+ "in_progress",
5040
+ "in_review",
5041
+ "blocked",
5042
+ "done"
5043
+ ];
5044
+ var INBOX_MINE_ISSUE_STATUS_FILTER = INBOX_MINE_ISSUE_STATUSES.join(",");
5029
5045
  var ISSUE_PRIORITIES = ["critical", "high", "medium", "low"];
5030
5046
  var GOAL_LEVELS = ["company", "team", "agent", "task"];
5031
5047
  var GOAL_STATUSES = ["planned", "active", "achieved", "cancelled"];
@@ -5036,6 +5052,11 @@ var PROJECT_STATUSES = [
5036
5052
  "completed",
5037
5053
  "cancelled"
5038
5054
  ];
5055
+ var ROUTINE_STATUSES = ["active", "paused", "archived"];
5056
+ var ROUTINE_CONCURRENCY_POLICIES = ["coalesce_if_active", "always_enqueue", "skip_if_active"];
5057
+ var ROUTINE_CATCH_UP_POLICIES = ["skip_missed", "enqueue_missed_with_cap"];
5058
+ var ROUTINE_TRIGGER_SIGNING_MODES = ["bearer", "hmac_sha256"];
5059
+ var ROUTINE_VARIABLE_TYPES = ["text", "textarea", "number", "boolean", "select"];
5039
5060
  var APPROVAL_TYPES = ["hire_agent", "approve_ceo_strategy", "budget_override_required"];
5040
5061
  var SECRET_PROVIDERS = [
5041
5062
  "local_encrypted",
@@ -5142,6 +5163,7 @@ var PLUGIN_CAPABILITIES = [
5142
5163
  "agent.sessions.close",
5143
5164
  "activity.log.write",
5144
5165
  "metrics.write",
5166
+ "telemetry.track",
5145
5167
  // Plugin State
5146
5168
  "plugin.state.read",
5147
5169
  "plugin.state.write",
@@ -5253,13 +5275,40 @@ var PLUGIN_STATE_SCOPE_KINDS = [
5253
5275
  "run"
5254
5276
  ];
5255
5277
 
5256
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/instance.js
5278
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/types/feedback.js
5279
+ var FEEDBACK_TARGET_TYPES = ["issue_comment", "issue_document_revision"];
5280
+ var FEEDBACK_VOTE_VALUES = ["up", "down"];
5281
+ var FEEDBACK_DATA_SHARING_PREFERENCES = ["allowed", "not_allowed", "prompt"];
5282
+ var DEFAULT_FEEDBACK_DATA_SHARING_PREFERENCE = "prompt";
5283
+ var FEEDBACK_TRACE_STATUSES = ["local_only", "pending", "sent", "failed"];
5284
+
5285
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/feedback.js
5286
+ var feedbackTargetTypeSchema = external_exports.enum(FEEDBACK_TARGET_TYPES);
5287
+ var feedbackTraceStatusSchema = external_exports.enum(FEEDBACK_TRACE_STATUSES);
5288
+ var feedbackVoteValueSchema = external_exports.enum(FEEDBACK_VOTE_VALUES);
5289
+ var feedbackDataSharingPreferenceSchema = external_exports.enum(FEEDBACK_DATA_SHARING_PREFERENCES);
5290
+ var upsertIssueFeedbackVoteSchema = external_exports.object({
5291
+ targetType: feedbackTargetTypeSchema,
5292
+ targetId: external_exports.string().uuid(),
5293
+ vote: feedbackVoteValueSchema,
5294
+ reason: external_exports.string().trim().max(1e3).optional(),
5295
+ allowSharing: external_exports.boolean().optional()
5296
+ });
5297
+
5298
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/instance.js
5299
+ var instanceGeneralSettingsSchema = external_exports.object({
5300
+ censorUsernameInLogs: external_exports.boolean().default(false),
5301
+ keyboardShortcuts: external_exports.boolean().default(false),
5302
+ feedbackDataSharingPreference: feedbackDataSharingPreferenceSchema.default(DEFAULT_FEEDBACK_DATA_SHARING_PREFERENCE)
5303
+ }).strict();
5304
+ var patchInstanceGeneralSettingsSchema = instanceGeneralSettingsSchema.partial();
5257
5305
  var instanceExperimentalSettingsSchema = external_exports.object({
5258
- enableIsolatedWorkspaces: external_exports.boolean().default(false)
5306
+ enableIsolatedWorkspaces: external_exports.boolean().default(false),
5307
+ autoRestartDevServerWhenIdle: external_exports.boolean().default(false)
5259
5308
  }).strict();
5260
5309
  var patchInstanceExperimentalSettingsSchema = instanceExperimentalSettingsSchema.partial();
5261
5310
 
5262
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/budget.js
5311
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/budget.js
5263
5312
  var upsertBudgetPolicySchema = external_exports.object({
5264
5313
  scopeType: external_exports.enum(BUDGET_SCOPE_TYPES),
5265
5314
  scopeId: external_exports.string().uuid(),
@@ -5285,8 +5334,10 @@ var resolveBudgetIncidentSchema = external_exports.object({
5285
5334
  }
5286
5335
  });
5287
5336
 
5288
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/company.js
5337
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/company.js
5289
5338
  var logoAssetIdSchema = external_exports.string().uuid().nullable().optional();
5339
+ var brandColorSchema = external_exports.string().regex(/^#[0-9a-fA-F]{6}$/).nullable().optional();
5340
+ var feedbackDataSharingTermsVersionSchema = external_exports.string().min(1).nullable().optional();
5290
5341
  var createCompanySchema = external_exports.object({
5291
5342
  name: external_exports.string().min(1),
5292
5343
  description: external_exports.string().optional().nullable(),
@@ -5296,32 +5347,400 @@ var updateCompanySchema = createCompanySchema.partial().extend({
5296
5347
  status: external_exports.enum(COMPANY_STATUSES).optional(),
5297
5348
  spentMonthlyCents: external_exports.number().int().nonnegative().optional(),
5298
5349
  requireBoardApprovalForNewAgents: external_exports.boolean().optional(),
5299
- brandColor: external_exports.string().regex(/^#[0-9a-fA-F]{6}$/).nullable().optional(),
5350
+ feedbackDataSharingEnabled: external_exports.boolean().optional(),
5351
+ feedbackDataSharingConsentAt: external_exports.coerce.date().nullable().optional(),
5352
+ feedbackDataSharingConsentByUserId: external_exports.string().min(1).nullable().optional(),
5353
+ feedbackDataSharingTermsVersion: feedbackDataSharingTermsVersionSchema,
5354
+ brandColor: brandColorSchema,
5300
5355
  logoAssetId: logoAssetIdSchema
5301
5356
  });
5357
+ var updateCompanyBrandingSchema = external_exports.object({
5358
+ name: external_exports.string().min(1).optional(),
5359
+ description: external_exports.string().nullable().optional(),
5360
+ brandColor: brandColorSchema,
5361
+ logoAssetId: logoAssetIdSchema
5362
+ }).strict().refine((value) => value.name !== void 0 || value.description !== void 0 || value.brandColor !== void 0 || value.logoAssetId !== void 0, "At least one branding field must be provided");
5363
+
5364
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/company-skill.js
5365
+ var companySkillSourceTypeSchema = external_exports.enum(["local_path", "github", "url", "catalog", "skills_sh"]);
5366
+ var companySkillTrustLevelSchema = external_exports.enum(["markdown_only", "assets", "scripts_executables"]);
5367
+ var companySkillCompatibilitySchema = external_exports.enum(["compatible", "unknown", "invalid"]);
5368
+ var companySkillSourceBadgeSchema = external_exports.enum(["paperclip", "github", "local", "url", "catalog", "skills_sh"]);
5369
+ var companySkillFileInventoryEntrySchema = external_exports.object({
5370
+ path: external_exports.string().min(1),
5371
+ kind: external_exports.enum(["skill", "markdown", "reference", "script", "asset", "other"])
5372
+ });
5373
+ var companySkillSchema = external_exports.object({
5374
+ id: external_exports.string().uuid(),
5375
+ companyId: external_exports.string().uuid(),
5376
+ key: external_exports.string().min(1),
5377
+ slug: external_exports.string().min(1),
5378
+ name: external_exports.string().min(1),
5379
+ description: external_exports.string().nullable(),
5380
+ markdown: external_exports.string(),
5381
+ sourceType: companySkillSourceTypeSchema,
5382
+ sourceLocator: external_exports.string().nullable(),
5383
+ sourceRef: external_exports.string().nullable(),
5384
+ trustLevel: companySkillTrustLevelSchema,
5385
+ compatibility: companySkillCompatibilitySchema,
5386
+ fileInventory: external_exports.array(companySkillFileInventoryEntrySchema).default([]),
5387
+ metadata: external_exports.record(external_exports.unknown()).nullable(),
5388
+ createdAt: external_exports.coerce.date(),
5389
+ updatedAt: external_exports.coerce.date()
5390
+ });
5391
+ var companySkillListItemSchema = companySkillSchema.extend({
5392
+ attachedAgentCount: external_exports.number().int().nonnegative(),
5393
+ editable: external_exports.boolean(),
5394
+ editableReason: external_exports.string().nullable(),
5395
+ sourceLabel: external_exports.string().nullable(),
5396
+ sourceBadge: companySkillSourceBadgeSchema
5397
+ });
5398
+ var companySkillUsageAgentSchema = external_exports.object({
5399
+ id: external_exports.string().uuid(),
5400
+ name: external_exports.string().min(1),
5401
+ urlKey: external_exports.string().min(1),
5402
+ adapterType: external_exports.string().min(1),
5403
+ desired: external_exports.boolean(),
5404
+ actualState: external_exports.string().nullable()
5405
+ });
5406
+ var companySkillDetailSchema = companySkillSchema.extend({
5407
+ attachedAgentCount: external_exports.number().int().nonnegative(),
5408
+ usedByAgents: external_exports.array(companySkillUsageAgentSchema).default([]),
5409
+ editable: external_exports.boolean(),
5410
+ editableReason: external_exports.string().nullable(),
5411
+ sourceLabel: external_exports.string().nullable(),
5412
+ sourceBadge: companySkillSourceBadgeSchema
5413
+ });
5414
+ var companySkillUpdateStatusSchema = external_exports.object({
5415
+ supported: external_exports.boolean(),
5416
+ reason: external_exports.string().nullable(),
5417
+ trackingRef: external_exports.string().nullable(),
5418
+ currentRef: external_exports.string().nullable(),
5419
+ latestRef: external_exports.string().nullable(),
5420
+ hasUpdate: external_exports.boolean()
5421
+ });
5422
+ var companySkillImportSchema = external_exports.object({
5423
+ source: external_exports.string().min(1)
5424
+ });
5425
+ var companySkillProjectScanRequestSchema = external_exports.object({
5426
+ projectIds: external_exports.array(external_exports.string().uuid()).optional(),
5427
+ workspaceIds: external_exports.array(external_exports.string().uuid()).optional()
5428
+ });
5429
+ var companySkillProjectScanSkippedSchema = external_exports.object({
5430
+ projectId: external_exports.string().uuid(),
5431
+ projectName: external_exports.string().min(1),
5432
+ workspaceId: external_exports.string().uuid().nullable(),
5433
+ workspaceName: external_exports.string().nullable(),
5434
+ path: external_exports.string().nullable(),
5435
+ reason: external_exports.string().min(1)
5436
+ });
5437
+ var companySkillProjectScanConflictSchema = external_exports.object({
5438
+ slug: external_exports.string().min(1),
5439
+ key: external_exports.string().min(1),
5440
+ projectId: external_exports.string().uuid(),
5441
+ projectName: external_exports.string().min(1),
5442
+ workspaceId: external_exports.string().uuid(),
5443
+ workspaceName: external_exports.string().min(1),
5444
+ path: external_exports.string().min(1),
5445
+ existingSkillId: external_exports.string().uuid(),
5446
+ existingSkillKey: external_exports.string().min(1),
5447
+ existingSourceLocator: external_exports.string().nullable(),
5448
+ reason: external_exports.string().min(1)
5449
+ });
5450
+ var companySkillProjectScanResultSchema = external_exports.object({
5451
+ scannedProjects: external_exports.number().int().nonnegative(),
5452
+ scannedWorkspaces: external_exports.number().int().nonnegative(),
5453
+ discovered: external_exports.number().int().nonnegative(),
5454
+ imported: external_exports.array(companySkillSchema),
5455
+ updated: external_exports.array(companySkillSchema),
5456
+ skipped: external_exports.array(companySkillProjectScanSkippedSchema),
5457
+ conflicts: external_exports.array(companySkillProjectScanConflictSchema),
5458
+ warnings: external_exports.array(external_exports.string())
5459
+ });
5460
+ var companySkillCreateSchema = external_exports.object({
5461
+ name: external_exports.string().min(1),
5462
+ slug: external_exports.string().min(1).nullable().optional(),
5463
+ description: external_exports.string().nullable().optional(),
5464
+ markdown: external_exports.string().nullable().optional()
5465
+ });
5466
+ var companySkillFileDetailSchema = external_exports.object({
5467
+ skillId: external_exports.string().uuid(),
5468
+ path: external_exports.string().min(1),
5469
+ kind: external_exports.enum(["skill", "markdown", "reference", "script", "asset", "other"]),
5470
+ content: external_exports.string(),
5471
+ language: external_exports.string().nullable(),
5472
+ markdown: external_exports.boolean(),
5473
+ editable: external_exports.boolean()
5474
+ });
5475
+ var companySkillFileUpdateSchema = external_exports.object({
5476
+ path: external_exports.string().min(1),
5477
+ content: external_exports.string()
5478
+ });
5479
+
5480
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/adapter-skills.js
5481
+ var agentSkillStateSchema = external_exports.enum([
5482
+ "available",
5483
+ "configured",
5484
+ "installed",
5485
+ "missing",
5486
+ "stale",
5487
+ "external"
5488
+ ]);
5489
+ var agentSkillOriginSchema = external_exports.enum([
5490
+ "company_managed",
5491
+ "paperclip_required",
5492
+ "user_installed",
5493
+ "external_unknown"
5494
+ ]);
5495
+ var agentSkillSyncModeSchema = external_exports.enum([
5496
+ "unsupported",
5497
+ "persistent",
5498
+ "ephemeral"
5499
+ ]);
5500
+ var agentSkillEntrySchema = external_exports.object({
5501
+ key: external_exports.string().min(1),
5502
+ runtimeName: external_exports.string().min(1).nullable(),
5503
+ desired: external_exports.boolean(),
5504
+ managed: external_exports.boolean(),
5505
+ required: external_exports.boolean().optional(),
5506
+ requiredReason: external_exports.string().nullable().optional(),
5507
+ state: agentSkillStateSchema,
5508
+ origin: agentSkillOriginSchema.optional(),
5509
+ originLabel: external_exports.string().nullable().optional(),
5510
+ locationLabel: external_exports.string().nullable().optional(),
5511
+ readOnly: external_exports.boolean().optional(),
5512
+ sourcePath: external_exports.string().nullable().optional(),
5513
+ targetPath: external_exports.string().nullable().optional(),
5514
+ detail: external_exports.string().nullable().optional()
5515
+ });
5516
+ var agentSkillSnapshotSchema = external_exports.object({
5517
+ adapterType: external_exports.string().min(1),
5518
+ supported: external_exports.boolean(),
5519
+ mode: agentSkillSyncModeSchema,
5520
+ desiredSkills: external_exports.array(external_exports.string().min(1)),
5521
+ entries: external_exports.array(agentSkillEntrySchema),
5522
+ warnings: external_exports.array(external_exports.string())
5523
+ });
5524
+ var agentSkillSyncSchema = external_exports.object({
5525
+ desiredSkills: external_exports.array(external_exports.string().min(1))
5526
+ });
5527
+
5528
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/issue.js
5529
+ var ISSUE_EXECUTION_WORKSPACE_PREFERENCES = [
5530
+ "inherit",
5531
+ "shared_workspace",
5532
+ "isolated_workspace",
5533
+ "operator_branch",
5534
+ "reuse_existing",
5535
+ "agent_default"
5536
+ ];
5537
+ var executionWorkspaceStrategySchema = external_exports.object({
5538
+ type: external_exports.enum(["project_primary", "git_worktree", "adapter_managed", "cloud_sandbox"]).optional(),
5539
+ baseRef: external_exports.string().optional().nullable(),
5540
+ branchTemplate: external_exports.string().optional().nullable(),
5541
+ worktreeParentDir: external_exports.string().optional().nullable(),
5542
+ provisionCommand: external_exports.string().optional().nullable(),
5543
+ teardownCommand: external_exports.string().optional().nullable()
5544
+ }).strict();
5545
+ var issueExecutionWorkspaceSettingsSchema = external_exports.object({
5546
+ mode: external_exports.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional(),
5547
+ workspaceStrategy: executionWorkspaceStrategySchema.optional().nullable(),
5548
+ workspaceRuntime: external_exports.record(external_exports.unknown()).optional().nullable()
5549
+ }).strict();
5550
+ var issueAssigneeAdapterOverridesSchema = external_exports.object({
5551
+ adapterConfig: external_exports.record(external_exports.unknown()).optional(),
5552
+ useProjectWorkspace: external_exports.boolean().optional()
5553
+ }).strict();
5554
+ var createIssueSchema = external_exports.object({
5555
+ projectId: external_exports.string().uuid().optional().nullable(),
5556
+ projectWorkspaceId: external_exports.string().uuid().optional().nullable(),
5557
+ goalId: external_exports.string().uuid().optional().nullable(),
5558
+ parentId: external_exports.string().uuid().optional().nullable(),
5559
+ inheritExecutionWorkspaceFromIssueId: external_exports.string().uuid().optional().nullable(),
5560
+ title: external_exports.string().min(1),
5561
+ description: external_exports.string().optional().nullable(),
5562
+ status: external_exports.enum(ISSUE_STATUSES).optional().default("backlog"),
5563
+ priority: external_exports.enum(ISSUE_PRIORITIES).optional().default("medium"),
5564
+ assigneeAgentId: external_exports.string().uuid().optional().nullable(),
5565
+ assigneeUserId: external_exports.string().optional().nullable(),
5566
+ requestDepth: external_exports.number().int().nonnegative().optional().default(0),
5567
+ billingCode: external_exports.string().optional().nullable(),
5568
+ assigneeAdapterOverrides: issueAssigneeAdapterOverridesSchema.optional().nullable(),
5569
+ executionWorkspaceId: external_exports.string().uuid().optional().nullable(),
5570
+ executionWorkspacePreference: external_exports.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional().nullable(),
5571
+ executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(),
5572
+ labelIds: external_exports.array(external_exports.string().uuid()).optional()
5573
+ });
5574
+ var createIssueLabelSchema = external_exports.object({
5575
+ name: external_exports.string().trim().min(1).max(48),
5576
+ color: external_exports.string().regex(/^#(?:[0-9a-fA-F]{6})$/, "Color must be a 6-digit hex value")
5577
+ });
5578
+ var updateIssueSchema = createIssueSchema.partial().extend({
5579
+ comment: external_exports.string().min(1).optional(),
5580
+ reopen: external_exports.boolean().optional(),
5581
+ interrupt: external_exports.boolean().optional(),
5582
+ hiddenAt: external_exports.string().datetime().nullable().optional()
5583
+ });
5584
+ var checkoutIssueSchema = external_exports.object({
5585
+ agentId: external_exports.string().uuid(),
5586
+ expectedStatuses: external_exports.array(external_exports.enum(ISSUE_STATUSES)).nonempty()
5587
+ });
5588
+ var addIssueCommentSchema = external_exports.object({
5589
+ body: external_exports.string().min(1),
5590
+ reopen: external_exports.boolean().optional(),
5591
+ interrupt: external_exports.boolean().optional()
5592
+ });
5593
+ var linkIssueApprovalSchema = external_exports.object({
5594
+ approvalId: external_exports.string().uuid()
5595
+ });
5596
+ var createIssueAttachmentMetadataSchema = external_exports.object({
5597
+ issueCommentId: external_exports.string().uuid().optional().nullable()
5598
+ });
5599
+ var ISSUE_DOCUMENT_FORMATS = ["markdown"];
5600
+ var issueDocumentFormatSchema = external_exports.enum(ISSUE_DOCUMENT_FORMATS);
5601
+ var issueDocumentKeySchema = external_exports.string().trim().min(1).max(64).regex(/^[a-z0-9][a-z0-9_-]*$/, "Document key must be lowercase letters, numbers, _ or -");
5602
+ var upsertIssueDocumentSchema = external_exports.object({
5603
+ title: external_exports.string().trim().max(200).nullable().optional(),
5604
+ format: issueDocumentFormatSchema,
5605
+ body: external_exports.string().max(524288),
5606
+ changeSummary: external_exports.string().trim().max(500).nullable().optional(),
5607
+ baseRevisionId: external_exports.string().uuid().nullable().optional()
5608
+ });
5609
+ var restoreIssueDocumentRevisionSchema = external_exports.object({});
5610
+
5611
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/routine.js
5612
+ var routineVariableValueSchema = external_exports.union([external_exports.string(), external_exports.number().finite(), external_exports.boolean()]);
5613
+ var routineVariableSchema = external_exports.object({
5614
+ name: external_exports.string().trim().regex(/^[A-Za-z][A-Za-z0-9_]*$/),
5615
+ label: external_exports.string().trim().max(120).optional().nullable(),
5616
+ type: external_exports.enum(ROUTINE_VARIABLE_TYPES).optional().default("text"),
5617
+ defaultValue: routineVariableValueSchema.optional().nullable(),
5618
+ required: external_exports.boolean().optional().default(true),
5619
+ options: external_exports.array(external_exports.string().trim().min(1).max(120)).max(50).optional().default([])
5620
+ }).superRefine((value, ctx) => {
5621
+ if (value.type === "select" && value.options.length === 0) {
5622
+ ctx.addIssue({
5623
+ code: external_exports.ZodIssueCode.custom,
5624
+ path: ["options"],
5625
+ message: "Select variables require at least one option"
5626
+ });
5627
+ }
5628
+ if (value.type !== "select" && value.options.length > 0) {
5629
+ ctx.addIssue({
5630
+ code: external_exports.ZodIssueCode.custom,
5631
+ path: ["options"],
5632
+ message: "Only select variables can define options"
5633
+ });
5634
+ }
5635
+ if (value.type === "select" && value.defaultValue != null) {
5636
+ if (typeof value.defaultValue !== "string" || !value.options.includes(value.defaultValue)) {
5637
+ ctx.addIssue({
5638
+ code: external_exports.ZodIssueCode.custom,
5639
+ path: ["defaultValue"],
5640
+ message: "Select variable defaults must match one of the allowed options"
5641
+ });
5642
+ }
5643
+ }
5644
+ });
5645
+ var createRoutineSchema = external_exports.object({
5646
+ projectId: external_exports.string().uuid(),
5647
+ goalId: external_exports.string().uuid().optional().nullable(),
5648
+ parentIssueId: external_exports.string().uuid().optional().nullable(),
5649
+ title: external_exports.string().trim().min(1).max(200),
5650
+ description: external_exports.string().optional().nullable(),
5651
+ assigneeAgentId: external_exports.string().uuid(),
5652
+ priority: external_exports.enum(ISSUE_PRIORITIES).optional().default("medium"),
5653
+ status: external_exports.enum(ROUTINE_STATUSES).optional().default("active"),
5654
+ concurrencyPolicy: external_exports.enum(ROUTINE_CONCURRENCY_POLICIES).optional().default("coalesce_if_active"),
5655
+ catchUpPolicy: external_exports.enum(ROUTINE_CATCH_UP_POLICIES).optional().default("skip_missed"),
5656
+ variables: external_exports.array(routineVariableSchema).optional().default([])
5657
+ });
5658
+ var updateRoutineSchema = createRoutineSchema.partial();
5659
+ var baseTriggerSchema = external_exports.object({
5660
+ label: external_exports.string().trim().max(120).optional().nullable(),
5661
+ enabled: external_exports.boolean().optional().default(true)
5662
+ });
5663
+ var createRoutineTriggerSchema = external_exports.discriminatedUnion("kind", [
5664
+ baseTriggerSchema.extend({
5665
+ kind: external_exports.literal("schedule"),
5666
+ cronExpression: external_exports.string().trim().min(1),
5667
+ timezone: external_exports.string().trim().min(1).default("UTC")
5668
+ }),
5669
+ baseTriggerSchema.extend({
5670
+ kind: external_exports.literal("webhook"),
5671
+ signingMode: external_exports.enum(ROUTINE_TRIGGER_SIGNING_MODES).optional().default("bearer"),
5672
+ replayWindowSec: external_exports.number().int().min(30).max(86400).optional().default(300)
5673
+ }),
5674
+ baseTriggerSchema.extend({
5675
+ kind: external_exports.literal("api")
5676
+ })
5677
+ ]);
5678
+ var updateRoutineTriggerSchema = external_exports.object({
5679
+ label: external_exports.string().trim().max(120).optional().nullable(),
5680
+ enabled: external_exports.boolean().optional(),
5681
+ cronExpression: external_exports.string().trim().min(1).optional().nullable(),
5682
+ timezone: external_exports.string().trim().min(1).optional().nullable(),
5683
+ signingMode: external_exports.enum(ROUTINE_TRIGGER_SIGNING_MODES).optional().nullable(),
5684
+ replayWindowSec: external_exports.number().int().min(30).max(86400).optional().nullable()
5685
+ });
5686
+ var runRoutineSchema = external_exports.object({
5687
+ triggerId: external_exports.string().uuid().optional().nullable(),
5688
+ payload: external_exports.record(external_exports.unknown()).optional().nullable(),
5689
+ variables: external_exports.record(routineVariableValueSchema).optional().nullable(),
5690
+ idempotencyKey: external_exports.string().trim().max(255).optional().nullable(),
5691
+ source: external_exports.enum(["manual", "api"]).optional().default("manual"),
5692
+ executionWorkspaceId: external_exports.string().uuid().optional().nullable(),
5693
+ executionWorkspacePreference: external_exports.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional().nullable(),
5694
+ executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable()
5695
+ });
5696
+ var rotateRoutineTriggerSecretSchema = external_exports.object({});
5302
5697
 
5303
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/company-portability.js
5698
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/company-portability.js
5304
5699
  var portabilityIncludeSchema = external_exports.object({
5305
5700
  company: external_exports.boolean().optional(),
5306
- agents: external_exports.boolean().optional()
5701
+ agents: external_exports.boolean().optional(),
5702
+ projects: external_exports.boolean().optional(),
5703
+ issues: external_exports.boolean().optional(),
5704
+ skills: external_exports.boolean().optional()
5307
5705
  }).partial();
5308
- var portabilitySecretRequirementSchema = external_exports.object({
5706
+ var portabilityEnvInputSchema = external_exports.object({
5309
5707
  key: external_exports.string().min(1),
5310
5708
  description: external_exports.string().nullable(),
5311
5709
  agentSlug: external_exports.string().min(1).nullable(),
5312
- providerHint: external_exports.string().nullable()
5710
+ kind: external_exports.enum(["secret", "plain"]),
5711
+ requirement: external_exports.enum(["required", "optional"]),
5712
+ defaultValue: external_exports.string().nullable(),
5713
+ portability: external_exports.enum(["portable", "system_dependent"])
5313
5714
  });
5715
+ var portabilityFileEntrySchema = external_exports.union([
5716
+ external_exports.string(),
5717
+ external_exports.object({
5718
+ encoding: external_exports.literal("base64"),
5719
+ data: external_exports.string(),
5720
+ contentType: external_exports.string().min(1).optional().nullable()
5721
+ })
5722
+ ]);
5314
5723
  var portabilityCompanyManifestEntrySchema = external_exports.object({
5315
5724
  path: external_exports.string().min(1),
5316
5725
  name: external_exports.string().min(1),
5317
5726
  description: external_exports.string().nullable(),
5318
5727
  brandColor: external_exports.string().nullable(),
5319
- requireBoardApprovalForNewAgents: external_exports.boolean()
5728
+ logoPath: external_exports.string().nullable(),
5729
+ requireBoardApprovalForNewAgents: external_exports.boolean(),
5730
+ feedbackDataSharingEnabled: external_exports.boolean().default(false),
5731
+ feedbackDataSharingConsentAt: external_exports.string().datetime().nullable().default(null),
5732
+ feedbackDataSharingConsentByUserId: external_exports.string().nullable().default(null),
5733
+ feedbackDataSharingTermsVersion: external_exports.string().nullable().default(null)
5734
+ });
5735
+ var portabilitySidebarOrderSchema = external_exports.object({
5736
+ agents: external_exports.array(external_exports.string().min(1)).default([]),
5737
+ projects: external_exports.array(external_exports.string().min(1)).default([])
5320
5738
  });
5321
5739
  var portabilityAgentManifestEntrySchema = external_exports.object({
5322
5740
  slug: external_exports.string().min(1),
5323
5741
  name: external_exports.string().min(1),
5324
5742
  path: external_exports.string().min(1),
5743
+ skills: external_exports.array(external_exports.string().min(1)).default([]),
5325
5744
  role: external_exports.string().min(1),
5326
5745
  title: external_exports.string().nullable(),
5327
5746
  icon: external_exports.string().nullable(),
@@ -5334,6 +5753,84 @@ var portabilityAgentManifestEntrySchema = external_exports.object({
5334
5753
  budgetMonthlyCents: external_exports.number().int().nonnegative(),
5335
5754
  metadata: external_exports.record(external_exports.unknown()).nullable()
5336
5755
  });
5756
+ var portabilitySkillManifestEntrySchema = external_exports.object({
5757
+ key: external_exports.string().min(1),
5758
+ slug: external_exports.string().min(1),
5759
+ name: external_exports.string().min(1),
5760
+ path: external_exports.string().min(1),
5761
+ description: external_exports.string().nullable(),
5762
+ sourceType: external_exports.string().min(1),
5763
+ sourceLocator: external_exports.string().nullable(),
5764
+ sourceRef: external_exports.string().nullable(),
5765
+ trustLevel: external_exports.string().nullable(),
5766
+ compatibility: external_exports.string().nullable(),
5767
+ metadata: external_exports.record(external_exports.unknown()).nullable(),
5768
+ fileInventory: external_exports.array(external_exports.object({
5769
+ path: external_exports.string().min(1),
5770
+ kind: external_exports.string().min(1)
5771
+ })).default([])
5772
+ });
5773
+ var portabilityProjectManifestEntrySchema = external_exports.object({
5774
+ slug: external_exports.string().min(1),
5775
+ name: external_exports.string().min(1),
5776
+ path: external_exports.string().min(1),
5777
+ description: external_exports.string().nullable(),
5778
+ ownerAgentSlug: external_exports.string().min(1).nullable(),
5779
+ leadAgentSlug: external_exports.string().min(1).nullable(),
5780
+ targetDate: external_exports.string().nullable(),
5781
+ color: external_exports.string().nullable(),
5782
+ status: external_exports.string().nullable(),
5783
+ executionWorkspacePolicy: external_exports.record(external_exports.unknown()).nullable(),
5784
+ workspaces: external_exports.array(external_exports.object({
5785
+ key: external_exports.string().min(1),
5786
+ name: external_exports.string().min(1),
5787
+ sourceType: external_exports.string().nullable(),
5788
+ repoUrl: external_exports.string().nullable(),
5789
+ repoRef: external_exports.string().nullable(),
5790
+ defaultRef: external_exports.string().nullable(),
5791
+ visibility: external_exports.string().nullable(),
5792
+ setupCommand: external_exports.string().nullable(),
5793
+ cleanupCommand: external_exports.string().nullable(),
5794
+ metadata: external_exports.record(external_exports.unknown()).nullable(),
5795
+ isPrimary: external_exports.boolean()
5796
+ })).default([]),
5797
+ metadata: external_exports.record(external_exports.unknown()).nullable()
5798
+ });
5799
+ var portabilityIssueRoutineTriggerManifestEntrySchema = external_exports.object({
5800
+ kind: external_exports.string().min(1),
5801
+ label: external_exports.string().nullable(),
5802
+ enabled: external_exports.boolean(),
5803
+ cronExpression: external_exports.string().nullable(),
5804
+ timezone: external_exports.string().nullable(),
5805
+ signingMode: external_exports.string().nullable(),
5806
+ replayWindowSec: external_exports.number().int().nullable()
5807
+ });
5808
+ var portabilityIssueRoutineManifestEntrySchema = external_exports.object({
5809
+ concurrencyPolicy: external_exports.string().nullable(),
5810
+ catchUpPolicy: external_exports.string().nullable(),
5811
+ variables: external_exports.array(routineVariableSchema).nullable().optional(),
5812
+ triggers: external_exports.array(portabilityIssueRoutineTriggerManifestEntrySchema).default([])
5813
+ });
5814
+ var portabilityIssueManifestEntrySchema = external_exports.object({
5815
+ slug: external_exports.string().min(1),
5816
+ identifier: external_exports.string().min(1).nullable(),
5817
+ title: external_exports.string().min(1),
5818
+ path: external_exports.string().min(1),
5819
+ projectSlug: external_exports.string().min(1).nullable(),
5820
+ projectWorkspaceKey: external_exports.string().min(1).nullable(),
5821
+ assigneeAgentSlug: external_exports.string().min(1).nullable(),
5822
+ description: external_exports.string().nullable(),
5823
+ recurring: external_exports.boolean().default(false),
5824
+ routine: portabilityIssueRoutineManifestEntrySchema.nullable(),
5825
+ legacyRecurrence: external_exports.record(external_exports.unknown()).nullable(),
5826
+ status: external_exports.string().nullable(),
5827
+ priority: external_exports.string().nullable(),
5828
+ labelIds: external_exports.array(external_exports.string().min(1)).default([]),
5829
+ billingCode: external_exports.string().nullable(),
5830
+ executionWorkspaceSettings: external_exports.record(external_exports.unknown()).nullable(),
5831
+ assigneeAdapterOverrides: external_exports.record(external_exports.unknown()).nullable(),
5832
+ metadata: external_exports.record(external_exports.unknown()).nullable()
5833
+ });
5337
5834
  var portabilityManifestSchema = external_exports.object({
5338
5835
  schemaVersion: external_exports.number().int().positive(),
5339
5836
  generatedAt: external_exports.string().datetime(),
@@ -5343,21 +5840,24 @@ var portabilityManifestSchema = external_exports.object({
5343
5840
  }).nullable(),
5344
5841
  includes: external_exports.object({
5345
5842
  company: external_exports.boolean(),
5346
- agents: external_exports.boolean()
5843
+ agents: external_exports.boolean(),
5844
+ projects: external_exports.boolean(),
5845
+ issues: external_exports.boolean(),
5846
+ skills: external_exports.boolean()
5347
5847
  }),
5348
5848
  company: portabilityCompanyManifestEntrySchema.nullable(),
5849
+ sidebar: portabilitySidebarOrderSchema.nullable(),
5349
5850
  agents: external_exports.array(portabilityAgentManifestEntrySchema),
5350
- requiredSecrets: external_exports.array(portabilitySecretRequirementSchema).default([])
5851
+ skills: external_exports.array(portabilitySkillManifestEntrySchema).default([]),
5852
+ projects: external_exports.array(portabilityProjectManifestEntrySchema).default([]),
5853
+ issues: external_exports.array(portabilityIssueManifestEntrySchema).default([]),
5854
+ envInputs: external_exports.array(portabilityEnvInputSchema).default([])
5351
5855
  });
5352
5856
  var portabilitySourceSchema = external_exports.discriminatedUnion("type", [
5353
5857
  external_exports.object({
5354
5858
  type: external_exports.literal("inline"),
5355
- manifest: portabilityManifestSchema,
5356
- files: external_exports.record(external_exports.string())
5357
- }),
5358
- external_exports.object({
5359
- type: external_exports.literal("url"),
5360
- url: external_exports.string().url()
5859
+ rootPath: external_exports.string().min(1).optional().nullable(),
5860
+ files: external_exports.record(portabilityFileEntrySchema)
5361
5861
  }),
5362
5862
  external_exports.object({
5363
5863
  type: external_exports.literal("github"),
@@ -5380,17 +5880,34 @@ var portabilityAgentSelectionSchema = external_exports.union([
5380
5880
  ]);
5381
5881
  var portabilityCollisionStrategySchema = external_exports.enum(["rename", "skip", "replace"]);
5382
5882
  var companyPortabilityExportSchema = external_exports.object({
5383
- include: portabilityIncludeSchema.optional()
5883
+ include: portabilityIncludeSchema.optional(),
5884
+ agents: external_exports.array(external_exports.string().min(1)).optional(),
5885
+ skills: external_exports.array(external_exports.string().min(1)).optional(),
5886
+ projects: external_exports.array(external_exports.string().min(1)).optional(),
5887
+ issues: external_exports.array(external_exports.string().min(1)).optional(),
5888
+ projectIssues: external_exports.array(external_exports.string().min(1)).optional(),
5889
+ selectedFiles: external_exports.array(external_exports.string().min(1)).optional(),
5890
+ expandReferencedSkills: external_exports.boolean().optional(),
5891
+ sidebarOrder: portabilitySidebarOrderSchema.partial().optional()
5384
5892
  });
5385
5893
  var companyPortabilityPreviewSchema = external_exports.object({
5386
5894
  source: portabilitySourceSchema,
5387
5895
  include: portabilityIncludeSchema.optional(),
5388
5896
  target: portabilityTargetSchema,
5389
5897
  agents: portabilityAgentSelectionSchema.optional(),
5390
- collisionStrategy: portabilityCollisionStrategySchema.optional()
5898
+ collisionStrategy: portabilityCollisionStrategySchema.optional(),
5899
+ nameOverrides: external_exports.record(external_exports.string().min(1), external_exports.string().min(1)).optional(),
5900
+ selectedFiles: external_exports.array(external_exports.string().min(1)).optional()
5901
+ });
5902
+ var portabilityAdapterOverrideSchema = external_exports.object({
5903
+ adapterType: external_exports.string().min(1),
5904
+ adapterConfig: external_exports.record(external_exports.unknown()).optional()
5905
+ });
5906
+ var companyPortabilityImportSchema = companyPortabilityPreviewSchema.extend({
5907
+ adapterOverrides: external_exports.record(external_exports.string().min(1), portabilityAdapterOverrideSchema).optional()
5391
5908
  });
5392
5909
 
5393
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/secret.js
5910
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/secret.js
5394
5911
  var envBindingPlainSchema = external_exports.object({
5395
5912
  type: external_exports.literal("plain"),
5396
5913
  value: external_exports.string()
@@ -5423,10 +5940,22 @@ var updateSecretSchema = external_exports.object({
5423
5940
  externalRef: external_exports.string().optional().nullable()
5424
5941
  });
5425
5942
 
5426
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/agent.js
5943
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/agent.js
5427
5944
  var agentPermissionsSchema = external_exports.object({
5428
5945
  canCreateAgents: external_exports.boolean().optional().default(false)
5429
5946
  });
5947
+ var agentInstructionsBundleModeSchema = external_exports.enum(["managed", "external"]);
5948
+ var updateAgentInstructionsBundleSchema = external_exports.object({
5949
+ mode: agentInstructionsBundleModeSchema.optional(),
5950
+ rootPath: external_exports.string().trim().min(1).nullable().optional(),
5951
+ entryFile: external_exports.string().trim().min(1).optional(),
5952
+ clearLegacyPromptTemplate: external_exports.boolean().optional().default(false)
5953
+ });
5954
+ var upsertAgentInstructionsFileSchema = external_exports.object({
5955
+ path: external_exports.string().trim().min(1),
5956
+ content: external_exports.string(),
5957
+ clearLegacyPromptTemplate: external_exports.boolean().optional().default(false)
5958
+ });
5430
5959
  var adapterConfigSchema = external_exports.record(external_exports.unknown()).superRefine((value, ctx) => {
5431
5960
  const envValue = value.env;
5432
5961
  if (envValue === void 0)
@@ -5447,6 +5976,7 @@ var createAgentSchema = external_exports.object({
5447
5976
  icon: external_exports.enum(AGENT_ICON_NAMES).optional().nullable(),
5448
5977
  reportsTo: external_exports.string().uuid().optional().nullable(),
5449
5978
  capabilities: external_exports.string().optional().nullable(),
5979
+ desiredSkills: external_exports.array(external_exports.string().min(1)).optional(),
5450
5980
  adapterType: external_exports.enum(AGENT_ADAPTER_TYPES).optional().default("process"),
5451
5981
  adapterConfig: adapterConfigSchema.optional().default({}),
5452
5982
  runtimeConfig: external_exports.record(external_exports.unknown()).optional().default({}),
@@ -5460,6 +5990,7 @@ var createAgentHireSchema = createAgentSchema.extend({
5460
5990
  });
5461
5991
  var updateAgentSchema = createAgentSchema.omit({ permissions: true }).partial().extend({
5462
5992
  permissions: external_exports.never().optional(),
5993
+ replaceAdapterConfig: external_exports.boolean().optional(),
5463
5994
  status: external_exports.enum(AGENT_STATUSES).optional(),
5464
5995
  spentMonthlyCents: external_exports.number().int().nonnegative().optional()
5465
5996
  });
@@ -5470,6 +6001,10 @@ var updateAgentInstructionsPathSchema = external_exports.object({
5470
6001
  var createAgentKeySchema = external_exports.object({
5471
6002
  name: external_exports.string().min(1).default("default")
5472
6003
  });
6004
+ var agentMineInboxQuerySchema = external_exports.object({
6005
+ userId: external_exports.string().trim().min(1),
6006
+ status: external_exports.string().trim().min(1).optional().default(INBOX_MINE_ISSUE_STATUS_FILTER)
6007
+ });
5473
6008
  var wakeAgentSchema = external_exports.object({
5474
6009
  source: external_exports.enum(["timer", "assignment", "on_demand", "automation"]).optional().default("on_demand"),
5475
6010
  triggerDetail: external_exports.enum(["manual", "ping", "callback", "system"]).optional(),
@@ -5485,11 +6020,12 @@ var testAdapterEnvironmentSchema = external_exports.object({
5485
6020
  adapterConfig: adapterConfigSchema.optional().default({})
5486
6021
  });
5487
6022
  var updateAgentPermissionsSchema = external_exports.object({
5488
- canCreateAgents: external_exports.boolean()
6023
+ canCreateAgents: external_exports.boolean(),
6024
+ canAssignTasks: external_exports.boolean()
5489
6025
  });
5490
6026
 
5491
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/project.js
5492
- var executionWorkspaceStrategySchema = external_exports.object({
6027
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/project.js
6028
+ var executionWorkspaceStrategySchema2 = external_exports.object({
5493
6029
  type: external_exports.enum(["project_primary", "git_worktree", "adapter_managed", "cloud_sandbox"]).optional(),
5494
6030
  baseRef: external_exports.string().optional().nullable(),
5495
6031
  branchTemplate: external_exports.string().optional().nullable(),
@@ -5502,13 +6038,17 @@ var projectExecutionWorkspacePolicySchema = external_exports.object({
5502
6038
  defaultMode: external_exports.enum(["shared_workspace", "isolated_workspace", "operator_branch", "adapter_default"]).optional(),
5503
6039
  allowIssueOverride: external_exports.boolean().optional(),
5504
6040
  defaultProjectWorkspaceId: external_exports.string().uuid().optional().nullable(),
5505
- workspaceStrategy: executionWorkspaceStrategySchema.optional().nullable(),
6041
+ workspaceStrategy: executionWorkspaceStrategySchema2.optional().nullable(),
5506
6042
  workspaceRuntime: external_exports.record(external_exports.unknown()).optional().nullable(),
5507
6043
  branchPolicy: external_exports.record(external_exports.unknown()).optional().nullable(),
5508
6044
  pullRequestPolicy: external_exports.record(external_exports.unknown()).optional().nullable(),
5509
6045
  runtimePolicy: external_exports.record(external_exports.unknown()).optional().nullable(),
5510
6046
  cleanupPolicy: external_exports.record(external_exports.unknown()).optional().nullable()
5511
6047
  }).strict();
6048
+ var projectWorkspaceRuntimeConfigSchema = external_exports.object({
6049
+ workspaceRuntime: external_exports.record(external_exports.unknown()).optional().nullable(),
6050
+ desiredState: external_exports.enum(["running", "stopped"]).optional().nullable()
6051
+ }).strict();
5512
6052
  var projectWorkspaceSourceTypeSchema = external_exports.enum(["local_path", "git_repo", "remote_managed", "non_git_path"]);
5513
6053
  var projectWorkspaceVisibilitySchema = external_exports.enum(["default", "advanced"]);
5514
6054
  var projectWorkspaceFields = {
@@ -5524,7 +6064,8 @@ var projectWorkspaceFields = {
5524
6064
  remoteProvider: external_exports.string().optional().nullable(),
5525
6065
  remoteWorkspaceRef: external_exports.string().optional().nullable(),
5526
6066
  sharedWorkspaceKey: external_exports.string().optional().nullable(),
5527
- metadata: external_exports.record(external_exports.unknown()).optional().nullable()
6067
+ metadata: external_exports.record(external_exports.unknown()).optional().nullable(),
6068
+ runtimeConfig: projectWorkspaceRuntimeConfigSchema.optional().nullable()
5528
6069
  };
5529
6070
  function validateProjectWorkspace(value, ctx) {
5530
6071
  const sourceType = value.sourceType ?? "local_path";
@@ -5576,112 +6117,34 @@ var createProjectSchema = external_exports.object({
5576
6117
  });
5577
6118
  var updateProjectSchema = external_exports.object(projectFields).partial();
5578
6119
 
5579
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/issue.js
5580
- var executionWorkspaceStrategySchema2 = external_exports.object({
5581
- type: external_exports.enum(["project_primary", "git_worktree", "adapter_managed", "cloud_sandbox"]).optional(),
5582
- baseRef: external_exports.string().optional().nullable(),
5583
- branchTemplate: external_exports.string().optional().nullable(),
5584
- worktreeParentDir: external_exports.string().optional().nullable(),
5585
- provisionCommand: external_exports.string().optional().nullable(),
5586
- teardownCommand: external_exports.string().optional().nullable()
5587
- }).strict();
5588
- var issueExecutionWorkspaceSettingsSchema = external_exports.object({
5589
- mode: external_exports.enum(["inherit", "shared_workspace", "isolated_workspace", "operator_branch", "reuse_existing", "agent_default"]).optional(),
5590
- workspaceStrategy: executionWorkspaceStrategySchema2.optional().nullable(),
5591
- workspaceRuntime: external_exports.record(external_exports.unknown()).optional().nullable()
5592
- }).strict();
5593
- var issueAssigneeAdapterOverridesSchema = external_exports.object({
5594
- adapterConfig: external_exports.record(external_exports.unknown()).optional(),
5595
- useProjectWorkspace: external_exports.boolean().optional()
5596
- }).strict();
5597
- var createIssueSchema = external_exports.object({
5598
- projectId: external_exports.string().uuid().optional().nullable(),
5599
- projectWorkspaceId: external_exports.string().uuid().optional().nullable(),
5600
- goalId: external_exports.string().uuid().optional().nullable(),
5601
- parentId: external_exports.string().uuid().optional().nullable(),
5602
- title: external_exports.string().min(1),
5603
- description: external_exports.string().optional().nullable(),
5604
- status: external_exports.enum(ISSUE_STATUSES).optional().default("backlog"),
5605
- priority: external_exports.enum(ISSUE_PRIORITIES).optional().default("medium"),
5606
- assigneeAgentId: external_exports.string().uuid().optional().nullable(),
5607
- assigneeUserId: external_exports.string().optional().nullable(),
5608
- requestDepth: external_exports.number().int().nonnegative().optional().default(0),
5609
- billingCode: external_exports.string().optional().nullable(),
5610
- assigneeAdapterOverrides: issueAssigneeAdapterOverridesSchema.optional().nullable(),
5611
- executionWorkspaceId: external_exports.string().uuid().optional().nullable(),
5612
- executionWorkspacePreference: external_exports.enum([
5613
- "inherit",
5614
- "shared_workspace",
5615
- "isolated_workspace",
5616
- "operator_branch",
5617
- "reuse_existing",
5618
- "agent_default"
5619
- ]).optional().nullable(),
5620
- executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(),
5621
- labelIds: external_exports.array(external_exports.string().uuid()).optional()
5622
- });
5623
- var createIssueLabelSchema = external_exports.object({
5624
- name: external_exports.string().trim().min(1).max(48),
5625
- color: external_exports.string().regex(/^#(?:[0-9a-fA-F]{6})$/, "Color must be a 6-digit hex value")
5626
- });
5627
- var updateIssueSchema = createIssueSchema.partial().extend({
5628
- comment: external_exports.string().min(1).optional(),
5629
- hiddenAt: external_exports.string().datetime().nullable().optional()
5630
- });
5631
- var checkoutIssueSchema = external_exports.object({
5632
- agentId: external_exports.string().uuid(),
5633
- expectedStatuses: external_exports.array(external_exports.enum(ISSUE_STATUSES)).nonempty()
5634
- });
5635
- var addIssueCommentSchema = external_exports.object({
5636
- body: external_exports.string().min(1),
5637
- reopen: external_exports.boolean().optional(),
5638
- interrupt: external_exports.boolean().optional()
5639
- });
5640
- var linkIssueApprovalSchema = external_exports.object({
5641
- approvalId: external_exports.string().uuid()
5642
- });
5643
- var createIssueAttachmentMetadataSchema = external_exports.object({
5644
- issueCommentId: external_exports.string().uuid().optional().nullable()
5645
- });
5646
- var ISSUE_DOCUMENT_FORMATS = ["markdown"];
5647
- var issueDocumentFormatSchema = external_exports.enum(ISSUE_DOCUMENT_FORMATS);
5648
- var issueDocumentKeySchema = external_exports.string().trim().min(1).max(64).regex(/^[a-z0-9][a-z0-9_-]*$/, "Document key must be lowercase letters, numbers, _ or -");
5649
- var upsertIssueDocumentSchema = external_exports.object({
5650
- title: external_exports.string().trim().max(200).nullable().optional(),
5651
- format: issueDocumentFormatSchema,
5652
- body: external_exports.string().max(524288),
5653
- changeSummary: external_exports.string().trim().max(500).nullable().optional(),
5654
- baseRevisionId: external_exports.string().uuid().nullable().optional()
5655
- });
5656
-
5657
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/work-product.js
5658
- var issueWorkProductTypeSchema = external_exports.enum([
5659
- "preview_url",
5660
- "runtime_service",
5661
- "pull_request",
5662
- "branch",
5663
- "commit",
5664
- "artifact",
5665
- "document"
5666
- ]);
5667
- var issueWorkProductStatusSchema = external_exports.enum([
5668
- "active",
5669
- "ready_for_review",
5670
- "approved",
5671
- "changes_requested",
5672
- "merged",
5673
- "closed",
5674
- "failed",
5675
- "archived",
5676
- "draft"
5677
- ]);
5678
- var issueWorkProductReviewStateSchema = external_exports.enum([
5679
- "none",
5680
- "needs_board_review",
5681
- "approved",
5682
- "changes_requested"
5683
- ]);
5684
- var createIssueWorkProductSchema = external_exports.object({
6120
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/work-product.js
6121
+ var issueWorkProductTypeSchema = external_exports.enum([
6122
+ "preview_url",
6123
+ "runtime_service",
6124
+ "pull_request",
6125
+ "branch",
6126
+ "commit",
6127
+ "artifact",
6128
+ "document"
6129
+ ]);
6130
+ var issueWorkProductStatusSchema = external_exports.enum([
6131
+ "active",
6132
+ "ready_for_review",
6133
+ "approved",
6134
+ "changes_requested",
6135
+ "merged",
6136
+ "closed",
6137
+ "failed",
6138
+ "archived",
6139
+ "draft"
6140
+ ]);
6141
+ var issueWorkProductReviewStateSchema = external_exports.enum([
6142
+ "none",
6143
+ "needs_board_review",
6144
+ "approved",
6145
+ "changes_requested"
6146
+ ]);
6147
+ var createIssueWorkProductSchema = external_exports.object({
5685
6148
  projectId: external_exports.string().uuid().optional().nullable(),
5686
6149
  executionWorkspaceId: external_exports.string().uuid().optional().nullable(),
5687
6150
  runtimeServiceId: external_exports.string().uuid().optional().nullable(),
@@ -5700,7 +6163,7 @@ var createIssueWorkProductSchema = external_exports.object({
5700
6163
  });
5701
6164
  var updateIssueWorkProductSchema = createIssueWorkProductSchema.partial();
5702
6165
 
5703
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/execution-workspace.js
6166
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/execution-workspace.js
5704
6167
  var executionWorkspaceStatusSchema = external_exports.enum([
5705
6168
  "active",
5706
6169
  "idle",
@@ -5708,14 +6171,111 @@ var executionWorkspaceStatusSchema = external_exports.enum([
5708
6171
  "archived",
5709
6172
  "cleanup_failed"
5710
6173
  ]);
6174
+ var executionWorkspaceConfigSchema = external_exports.object({
6175
+ provisionCommand: external_exports.string().optional().nullable(),
6176
+ teardownCommand: external_exports.string().optional().nullable(),
6177
+ cleanupCommand: external_exports.string().optional().nullable(),
6178
+ workspaceRuntime: external_exports.record(external_exports.unknown()).optional().nullable(),
6179
+ desiredState: external_exports.enum(["running", "stopped"]).optional().nullable()
6180
+ }).strict();
6181
+ var executionWorkspaceCloseReadinessStateSchema = external_exports.enum([
6182
+ "ready",
6183
+ "ready_with_warnings",
6184
+ "blocked"
6185
+ ]);
6186
+ var executionWorkspaceCloseActionKindSchema = external_exports.enum([
6187
+ "archive_record",
6188
+ "stop_runtime_services",
6189
+ "cleanup_command",
6190
+ "teardown_command",
6191
+ "git_worktree_remove",
6192
+ "git_branch_delete",
6193
+ "remove_local_directory"
6194
+ ]);
6195
+ var executionWorkspaceCloseActionSchema = external_exports.object({
6196
+ kind: executionWorkspaceCloseActionKindSchema,
6197
+ label: external_exports.string(),
6198
+ description: external_exports.string(),
6199
+ command: external_exports.string().nullable()
6200
+ }).strict();
6201
+ var executionWorkspaceCloseLinkedIssueSchema = external_exports.object({
6202
+ id: external_exports.string().uuid(),
6203
+ identifier: external_exports.string().nullable(),
6204
+ title: external_exports.string(),
6205
+ status: external_exports.string(),
6206
+ isTerminal: external_exports.boolean()
6207
+ }).strict();
6208
+ var executionWorkspaceCloseGitReadinessSchema = external_exports.object({
6209
+ repoRoot: external_exports.string().nullable(),
6210
+ workspacePath: external_exports.string().nullable(),
6211
+ branchName: external_exports.string().nullable(),
6212
+ baseRef: external_exports.string().nullable(),
6213
+ hasDirtyTrackedFiles: external_exports.boolean(),
6214
+ hasUntrackedFiles: external_exports.boolean(),
6215
+ dirtyEntryCount: external_exports.number().int().nonnegative(),
6216
+ untrackedEntryCount: external_exports.number().int().nonnegative(),
6217
+ aheadCount: external_exports.number().int().nonnegative().nullable(),
6218
+ behindCount: external_exports.number().int().nonnegative().nullable(),
6219
+ isMergedIntoBase: external_exports.boolean().nullable(),
6220
+ createdByRuntime: external_exports.boolean()
6221
+ }).strict();
6222
+ var workspaceRuntimeServiceSchema = external_exports.object({
6223
+ id: external_exports.string(),
6224
+ companyId: external_exports.string().uuid(),
6225
+ projectId: external_exports.string().uuid().nullable(),
6226
+ projectWorkspaceId: external_exports.string().uuid().nullable(),
6227
+ executionWorkspaceId: external_exports.string().uuid().nullable(),
6228
+ issueId: external_exports.string().uuid().nullable(),
6229
+ scopeType: external_exports.enum(["project_workspace", "execution_workspace", "run", "agent"]),
6230
+ scopeId: external_exports.string().nullable(),
6231
+ serviceName: external_exports.string(),
6232
+ status: external_exports.enum(["starting", "running", "stopped", "failed"]),
6233
+ lifecycle: external_exports.enum(["shared", "ephemeral"]),
6234
+ reuseKey: external_exports.string().nullable(),
6235
+ command: external_exports.string().nullable(),
6236
+ cwd: external_exports.string().nullable(),
6237
+ port: external_exports.number().int().nullable(),
6238
+ url: external_exports.string().nullable(),
6239
+ provider: external_exports.enum(["local_process", "adapter_managed"]),
6240
+ providerRef: external_exports.string().nullable(),
6241
+ ownerAgentId: external_exports.string().uuid().nullable(),
6242
+ startedByRunId: external_exports.string().uuid().nullable(),
6243
+ lastUsedAt: external_exports.coerce.date(),
6244
+ startedAt: external_exports.coerce.date(),
6245
+ stoppedAt: external_exports.coerce.date().nullable(),
6246
+ stopPolicy: external_exports.record(external_exports.unknown()).nullable(),
6247
+ healthStatus: external_exports.enum(["unknown", "healthy", "unhealthy"]),
6248
+ createdAt: external_exports.coerce.date(),
6249
+ updatedAt: external_exports.coerce.date()
6250
+ }).strict();
6251
+ var executionWorkspaceCloseReadinessSchema = external_exports.object({
6252
+ workspaceId: external_exports.string().uuid(),
6253
+ state: executionWorkspaceCloseReadinessStateSchema,
6254
+ blockingReasons: external_exports.array(external_exports.string()),
6255
+ warnings: external_exports.array(external_exports.string()),
6256
+ linkedIssues: external_exports.array(executionWorkspaceCloseLinkedIssueSchema),
6257
+ plannedActions: external_exports.array(executionWorkspaceCloseActionSchema),
6258
+ isDestructiveCloseAllowed: external_exports.boolean(),
6259
+ isSharedWorkspace: external_exports.boolean(),
6260
+ isProjectPrimaryWorkspace: external_exports.boolean(),
6261
+ git: executionWorkspaceCloseGitReadinessSchema.nullable(),
6262
+ runtimeServices: external_exports.array(workspaceRuntimeServiceSchema)
6263
+ }).strict();
5711
6264
  var updateExecutionWorkspaceSchema = external_exports.object({
6265
+ name: external_exports.string().min(1).optional(),
6266
+ cwd: external_exports.string().optional().nullable(),
6267
+ repoUrl: external_exports.string().optional().nullable(),
6268
+ baseRef: external_exports.string().optional().nullable(),
6269
+ branchName: external_exports.string().optional().nullable(),
6270
+ providerRef: external_exports.string().optional().nullable(),
5712
6271
  status: executionWorkspaceStatusSchema.optional(),
5713
6272
  cleanupEligibleAt: external_exports.string().datetime().optional().nullable(),
5714
6273
  cleanupReason: external_exports.string().optional().nullable(),
6274
+ config: executionWorkspaceConfigSchema.optional().nullable(),
5715
6275
  metadata: external_exports.record(external_exports.unknown()).optional().nullable()
5716
6276
  }).strict();
5717
6277
 
5718
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/goal.js
6278
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/goal.js
5719
6279
  var createGoalSchema = external_exports.object({
5720
6280
  title: external_exports.string().min(1),
5721
6281
  description: external_exports.string().optional().nullable(),
@@ -5726,7 +6286,7 @@ var createGoalSchema = external_exports.object({
5726
6286
  });
5727
6287
  var updateGoalSchema = createGoalSchema.partial();
5728
6288
 
5729
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/approval.js
6289
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/approval.js
5730
6290
  var createApprovalSchema = external_exports.object({
5731
6291
  type: external_exports.enum(APPROVAL_TYPES),
5732
6292
  requestedByAgentId: external_exports.string().uuid().optional().nullable(),
@@ -5748,7 +6308,7 @@ var addApprovalCommentSchema = external_exports.object({
5748
6308
  body: external_exports.string().min(1)
5749
6309
  });
5750
6310
 
5751
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/cost.js
6311
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/cost.js
5752
6312
  var createCostEventSchema = external_exports.object({
5753
6313
  agentId: external_exports.string().uuid(),
5754
6314
  issueId: external_exports.string().uuid().optional().nullable(),
@@ -5773,7 +6333,7 @@ var updateBudgetSchema = external_exports.object({
5773
6333
  budgetMonthlyCents: external_exports.number().int().nonnegative()
5774
6334
  });
5775
6335
 
5776
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/finance.js
6336
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/finance.js
5777
6337
  var createFinanceEventSchema = external_exports.object({
5778
6338
  agentId: external_exports.string().uuid().optional().nullable(),
5779
6339
  issueId: external_exports.string().uuid().optional().nullable(),
@@ -5804,12 +6364,12 @@ var createFinanceEventSchema = external_exports.object({
5804
6364
  currency: value.currency.toUpperCase()
5805
6365
  }));
5806
6366
 
5807
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/asset.js
6367
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/asset.js
5808
6368
  var createAssetImageMetadataSchema = external_exports.object({
5809
6369
  namespace: external_exports.string().trim().min(1).max(120).regex(/^[a-zA-Z0-9/_-]+$/).optional()
5810
6370
  });
5811
6371
 
5812
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/access.js
6372
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/access.js
5813
6373
  var createCompanyInviteSchema = external_exports.object({
5814
6374
  allowedJoinTypes: external_exports.enum(INVITE_JOIN_TYPES).default("both"),
5815
6375
  defaultsPayload: external_exports.record(external_exports.string(), external_exports.unknown()).optional().nullable(),
@@ -5838,6 +6398,19 @@ var listJoinRequestsQuerySchema = external_exports.object({
5838
6398
  var claimJoinRequestApiKeySchema = external_exports.object({
5839
6399
  claimSecret: external_exports.string().min(16).max(256)
5840
6400
  });
6401
+ var boardCliAuthAccessLevelSchema = external_exports.enum([
6402
+ "board",
6403
+ "instance_admin_required"
6404
+ ]);
6405
+ var createCliAuthChallengeSchema = external_exports.object({
6406
+ command: external_exports.string().min(1).max(240),
6407
+ clientName: external_exports.string().max(120).optional().nullable(),
6408
+ requestedAccess: boardCliAuthAccessLevelSchema.default("board"),
6409
+ requestedCompanyId: external_exports.string().uuid().optional().nullable()
6410
+ });
6411
+ var resolveCliAuthChallengeSchema = external_exports.object({
6412
+ token: external_exports.string().min(16).max(256)
6413
+ });
5841
6414
  var updateMemberPermissionsSchema = external_exports.object({
5842
6415
  grants: external_exports.array(external_exports.object({
5843
6416
  permissionKey: external_exports.enum(PERMISSION_KEYS),
@@ -5848,7 +6421,7 @@ var updateUserCompanyAccessSchema = external_exports.object({
5848
6421
  companyIds: external_exports.array(external_exports.string().uuid()).default([])
5849
6422
  });
5850
6423
 
5851
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/validators/plugin.js
6424
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/validators/plugin.js
5852
6425
  var jsonSchemaSchema = external_exports.record(external_exports.unknown()).refine((val) => {
5853
6426
  if (Object.keys(val).length === 0)
5854
6427
  return true;
@@ -6217,7 +6790,7 @@ var listPluginStateSchema = external_exports.object({
6217
6790
  namespace: external_exports.string().min(1).optional()
6218
6791
  });
6219
6792
 
6220
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/api.js
6793
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/api.js
6221
6794
  var API_PREFIX = "/api";
6222
6795
  var API = {
6223
6796
  health: `${API_PREFIX}/health`,
@@ -6238,7 +6811,7 @@ var API = {
6238
6811
  admin: `${API_PREFIX}/admin`
6239
6812
  };
6240
6813
 
6241
- // node_modules/.pnpm/@paperclipai+shared@2026.318.0/node_modules/@paperclipai/shared/dist/config-schema.js
6814
+ // node_modules/.pnpm/@paperclipai+shared@2026.403.0/node_modules/@paperclipai/shared/dist/config-schema.js
6242
6815
  var configMetaSchema = external_exports.object({
6243
6816
  version: external_exports.literal(1),
6244
6817
  updatedAt: external_exports.string(),
@@ -6315,12 +6888,16 @@ var secretsConfigSchema = external_exports.object({
6315
6888
  keyFilePath: "~/.paperclip/instances/default/secrets/master.key"
6316
6889
  })
6317
6890
  });
6891
+ var telemetryConfigSchema = external_exports.object({
6892
+ enabled: external_exports.boolean().default(true)
6893
+ }).default({});
6318
6894
  var paperclipConfigSchema = external_exports.object({
6319
6895
  $meta: configMetaSchema,
6320
6896
  llm: llmConfigSchema.optional(),
6321
6897
  database: databaseConfigSchema,
6322
6898
  logging: loggingConfigSchema,
6323
6899
  server: serverConfigSchema,
6900
+ telemetry: telemetryConfigSchema,
6324
6901
  auth: authConfigSchema.default({
6325
6902
  baseUrlMode: "auto",
6326
6903
  disableSignUp: false
@@ -6378,7 +6955,7 @@ var paperclipConfigSchema = external_exports.object({
6378
6955
  }
6379
6956
  });
6380
6957
 
6381
- // node_modules/.pnpm/@tomismeta+aperture-core@0.4.0/node_modules/@tomismeta/aperture-core/public-dist/index.js
6958
+ // node_modules/.pnpm/@tomismeta+aperture-core@0.5.0/node_modules/@tomismeta/aperture-core/public-dist/index.js
6382
6959
  import { join, dirname } from "path";
6383
6960
  import { readFile, mkdir, writeFile, rename } from "fs/promises";
6384
6961
  function scoreCandidate(candidate) {
@@ -6490,14 +7067,14 @@ function buildAttentionView(taskViews, options = {}) {
6490
7067
  let interruptive = [];
6491
7068
  let ambient = [];
6492
7069
  for (const taskView of taskViews) {
6493
- if (taskView.active) {
6494
- if (isBackground(taskView.active)) {
6495
- ambient.push(taskView.active);
7070
+ if (taskView.now) {
7071
+ if (isBackground(taskView.now)) {
7072
+ ambient.push(taskView.now);
6496
7073
  } else {
6497
- interruptive.push(taskView.active);
7074
+ interruptive.push(taskView.now);
6498
7075
  }
6499
7076
  }
6500
- interruptive.push(...taskView.queued);
7077
+ interruptive.push(...taskView.next);
6501
7078
  ambient.push(...taskView.ambient);
6502
7079
  }
6503
7080
  const referenceNow = options.now ?? latestTimestamp([...interruptive, ...ambient]);
@@ -6518,37 +7095,37 @@ function buildAttentionView(taskViews, options = {}) {
6518
7095
  ambient.sort((left, right) => compareFrames(left, right, referenceNow));
6519
7096
  if (options.operatorPresence === "absent") {
6520
7097
  return {
6521
- active: null,
6522
- queued: interruptive,
7098
+ now: null,
7099
+ next: interruptive,
6523
7100
  ambient
6524
7101
  };
6525
7102
  }
6526
7103
  if (interruptive.length > 0) {
6527
- const [active, ...queued] = interruptive;
7104
+ const [now, ...next] = interruptive;
6528
7105
  return {
6529
- active: active ?? null,
6530
- queued,
7106
+ now: now ?? null,
7107
+ next,
6531
7108
  ambient
6532
7109
  };
6533
7110
  }
6534
7111
  if (ambient.length > 0) {
6535
- const [active, ...rest] = ambient;
6536
- if (active && (scoreAttentionFrame(active, { now: referenceNow }) <= 0 || options.globalAttentionState === "overloaded" && scoreAttentionFrame(active, { now: referenceNow }) < 200)) {
7112
+ const [now, ...rest] = ambient;
7113
+ if (now && (scoreAttentionFrame(now, { now: referenceNow }) <= 0 || options.globalAttentionState === "overloaded" && scoreAttentionFrame(now, { now: referenceNow }) < 200)) {
6537
7114
  return {
6538
- active: null,
6539
- queued: [],
7115
+ now: null,
7116
+ next: [],
6540
7117
  ambient
6541
7118
  };
6542
7119
  }
6543
7120
  return {
6544
- active: active ?? null,
6545
- queued: [],
7121
+ now: now ?? null,
7122
+ next: [],
6546
7123
  ambient: rest
6547
7124
  };
6548
7125
  }
6549
7126
  return {
6550
- active: null,
6551
- queued: [],
7127
+ now: null,
7128
+ next: [],
6552
7129
  ambient: []
6553
7130
  };
6554
7131
  }
@@ -6581,7 +7158,7 @@ function latestTimestamp(frames) {
6581
7158
  function deriveAttentionState(summary) {
6582
7159
  const enoughPresentedForPattern = summary.counts.presented >= 5;
6583
7160
  const enoughObservedForPressure = summary.counts.presented + summary.counts.deferred >= 5;
6584
- if (enoughObservedForPressure && summary.counts.deferred >= 3 && summary.deferred.queued + summary.deferred.suppressed >= 3) {
7161
+ if (enoughObservedForPressure && summary.counts.deferred >= 3 && summary.deferred.next + summary.deferred.suppressed >= 3) {
6585
7162
  return "overloaded";
6586
7163
  }
6587
7164
  if (enoughPresentedForPattern && summary.dismissalRate >= 0.6 && summary.deferred.suppressed >= 2) {
@@ -6802,7 +7379,8 @@ var JUDGMENT_DEFAULTS = {
6802
7379
  stackingBoost: 1,
6803
7380
  relationRepeatBoost: 1,
6804
7381
  relationEscalationBoost: 2,
6805
- actionableThreshold: 4
7382
+ actionableThreshold: 4,
7383
+ staleAfterMs: 15 * 6e4
6806
7384
  }
6807
7385
  };
6808
7386
  function deriveAttentionBurden(summary, pressure, attentionState, operatorPresence = "present", now) {
@@ -6852,7 +7430,7 @@ function deriveAttentionBurden(summary, pressure, attentionState, operatorPresen
6852
7430
  reasons.push("recent deferrals are accumulating");
6853
7431
  } else if (deferredCount >= defaults.deferredCount.elevated) {
6854
7432
  score += 1;
6855
- reasons.push("recent deferrals suggest active burden");
7433
+ reasons.push("recent deferrals suggest growing burden");
6856
7434
  }
6857
7435
  if (interruptiveVisible >= defaults.interruptiveVisible.high) {
6858
7436
  score += 2;
@@ -7015,7 +7593,7 @@ function countInterruptiveVisible(attentionView) {
7015
7593
  if (!attentionView) {
7016
7594
  return 0;
7017
7595
  }
7018
- return [attentionView.active, ...attentionView.queued].filter((frame) => frame !== null).filter(isInterruptive).length;
7596
+ return [attentionView.now, ...attentionView.next].filter((frame) => frame !== null).filter(isInterruptive).length;
7019
7597
  }
7020
7598
  function isInterruptive(frame) {
7021
7599
  return frame.mode !== "status" || frame.consequence === "high" || frame.tone === "critical";
@@ -7032,12 +7610,14 @@ var baseAttentionSurfaceCapabilities = {
7032
7610
  }
7033
7611
  };
7034
7612
  function createAttentionEvidenceContext(input = {}) {
7613
+ const taskSignalSummary = input.taskSignalSummary ?? emptyAttentionSignalSummary();
7035
7614
  return {
7036
7615
  currentFrame: input.currentFrame ?? null,
7037
7616
  currentTaskView: input.currentTaskView ?? emptyTaskView(),
7038
7617
  currentEpisode: input.currentEpisode ?? null,
7039
7618
  attentionView: input.attentionView ?? emptyAttentionView(),
7040
- taskSignalSummary: input.taskSignalSummary ?? emptyAttentionSignalSummary(),
7619
+ taskSignalSummary,
7620
+ continuitySignalSummary: input.continuitySignalSummary ?? taskSignalSummary,
7041
7621
  globalSignalSummary: input.globalSignalSummary ?? emptyAttentionSignalSummary(),
7042
7622
  taskAttentionState: input.taskAttentionState ?? "monitoring",
7043
7623
  globalAttentionState: input.globalAttentionState ?? "monitoring",
@@ -7060,6 +7640,7 @@ function buildAttentionEvidenceInput(input = {}) {
7060
7640
  ...input.currentEpisode !== void 0 ? { currentEpisode: input.currentEpisode } : {},
7061
7641
  ...input.attentionView !== void 0 ? { attentionView: input.attentionView } : {},
7062
7642
  ...input.taskSignalSummary !== void 0 ? { taskSignalSummary: input.taskSignalSummary } : {},
7643
+ ...input.continuitySignalSummary !== void 0 ? { continuitySignalSummary: input.continuitySignalSummary } : {},
7063
7644
  ...input.globalSignalSummary !== void 0 ? { globalSignalSummary: input.globalSignalSummary } : {},
7064
7645
  ...input.taskAttentionState !== void 0 ? { taskAttentionState: input.taskAttentionState } : {},
7065
7646
  ...input.globalAttentionState !== void 0 ? { globalAttentionState: input.globalAttentionState } : {},
@@ -7099,19 +7680,19 @@ function resolveAttentionEvidenceContext(currentFrame, input = {}, referenceTime
7099
7680
  });
7100
7681
  }
7101
7682
  function isAttentionEvidenceContext(input) {
7102
- return "currentFrame" in input && "currentTaskView" in input && "currentEpisode" in input && "attentionView" in input && "taskSignalSummary" in input && "globalSignalSummary" in input && "taskAttentionState" in input && "globalAttentionState" in input && "pressureForecast" in input && "attentionBurden" in input && "surfaceCapabilities" in input && "operatorPresence" in input && input.currentFrame !== void 0 && input.currentTaskView !== void 0 && input.currentEpisode !== void 0 && input.attentionView !== void 0 && input.taskSignalSummary !== void 0 && input.globalSignalSummary !== void 0 && input.taskAttentionState !== void 0 && input.globalAttentionState !== void 0 && input.pressureForecast !== void 0 && input.attentionBurden !== void 0 && input.surfaceCapabilities !== void 0 && input.operatorPresence !== void 0;
7683
+ return "currentFrame" in input && "currentTaskView" in input && "currentEpisode" in input && "attentionView" in input && "taskSignalSummary" in input && "continuitySignalSummary" in input && "globalSignalSummary" in input && "taskAttentionState" in input && "globalAttentionState" in input && "pressureForecast" in input && "attentionBurden" in input && "surfaceCapabilities" in input && "operatorPresence" in input && input.currentFrame !== void 0 && input.currentTaskView !== void 0 && input.currentEpisode !== void 0 && input.attentionView !== void 0 && input.taskSignalSummary !== void 0 && input.continuitySignalSummary !== void 0 && input.globalSignalSummary !== void 0 && input.taskAttentionState !== void 0 && input.globalAttentionState !== void 0 && input.pressureForecast !== void 0 && input.attentionBurden !== void 0 && input.surfaceCapabilities !== void 0 && input.operatorPresence !== void 0;
7103
7684
  }
7104
7685
  function emptyTaskView() {
7105
7686
  return {
7106
- active: null,
7107
- queued: [],
7687
+ now: null,
7688
+ next: [],
7108
7689
  ambient: []
7109
7690
  };
7110
7691
  }
7111
7692
  function emptyAttentionView() {
7112
7693
  return {
7113
- active: null,
7114
- queued: [],
7694
+ now: null,
7695
+ next: [],
7115
7696
  ambient: []
7116
7697
  };
7117
7698
  }
@@ -7132,7 +7713,7 @@ function emptyAttentionSignalSummary() {
7132
7713
  attentionShifted: 0
7133
7714
  },
7134
7715
  deferred: {
7135
- queued: 0,
7716
+ next: 0,
7136
7717
  suppressed: 0,
7137
7718
  manual: 0
7138
7719
  },
@@ -7155,11 +7736,15 @@ function readSemanticRelationTarget(relationHints) {
7155
7736
  var DEFAULTS = JUDGMENT_DEFAULTS.episodeEvidence;
7156
7737
  var EpisodeTracker = class {
7157
7738
  byKey = /* @__PURE__ */ new Map();
7739
+ byId = /* @__PURE__ */ new Map();
7158
7740
  byInteractionId = /* @__PURE__ */ new Map();
7741
+ nextSequenceByKey = /* @__PURE__ */ new Map();
7159
7742
  assign(candidate) {
7160
7743
  const key = buildEpisodeKey(candidate);
7161
7744
  const existingId = this.byInteractionId.get(candidate.interactionId);
7162
- const record = (existingId ? this.findById(existingId) : void 0) ?? this.byKey.get(key) ?? this.createRecord(key, candidate);
7745
+ const boundRecord = existingId ? this.byId.get(existingId) : void 0;
7746
+ const keyedRecord = boundRecord ? null : this.byKey.get(key);
7747
+ const record = boundRecord ?? this.resolveAssignableRecord(key, keyedRecord, candidate);
7163
7748
  record.interactions.add(candidate.interactionId);
7164
7749
  record.lastInteractionId = candidate.interactionId;
7165
7750
  record.updatedAt = candidate.timestamp;
@@ -7176,6 +7761,7 @@ var EpisodeTracker = class {
7176
7761
  record.evidenceReasons = evidence.reasons;
7177
7762
  record.state = nextEpisodeState(record.state, candidate, record, evidence.score);
7178
7763
  this.byKey.set(record.key, record);
7764
+ this.byId.set(record.id, record);
7179
7765
  this.byInteractionId.set(candidate.interactionId, record.id);
7180
7766
  return {
7181
7767
  ...candidate,
@@ -7192,12 +7778,17 @@ var EpisodeTracker = class {
7192
7778
  if (!episodeId) {
7193
7779
  return;
7194
7780
  }
7195
- const record = this.findById(episodeId);
7781
+ const record = this.byId.get(episodeId);
7196
7782
  if (!record) {
7197
7783
  return;
7198
7784
  }
7199
- record.state = "resolved";
7200
- this.byKey.set(record.key, record);
7785
+ if (this.byKey.get(record.key)?.id === record.id) {
7786
+ this.byKey.delete(record.key);
7787
+ }
7788
+ this.byId.delete(record.id);
7789
+ for (const relatedInteractionId of record.interactions) {
7790
+ this.byInteractionId.delete(relatedInteractionId);
7791
+ }
7201
7792
  }
7202
7793
  readFrameEpisode(frame) {
7203
7794
  if (!frame) {
@@ -7221,8 +7812,10 @@ var EpisodeTracker = class {
7221
7812
  return { id, key, state, size, evidenceScore, evidenceReasons, lastInteractionId, updatedAt };
7222
7813
  }
7223
7814
  createRecord(key, candidate) {
7815
+ const nextSequence = (this.nextSequenceByKey.get(key) ?? 0) + 1;
7816
+ this.nextSequenceByKey.set(key, nextSequence);
7224
7817
  return {
7225
- id: `episode:${key}`,
7818
+ id: `episode:${key}:${nextSequence}`,
7226
7819
  key,
7227
7820
  state: candidate.blocking ? "actionable" : "emerging",
7228
7821
  size: 0,
@@ -7237,13 +7830,26 @@ var EpisodeTracker = class {
7237
7830
  relationKinds: new Set((candidate.relationHints ?? []).map((hint) => hint.kind))
7238
7831
  };
7239
7832
  }
7240
- findById(id) {
7241
- for (const record of this.byKey.values()) {
7242
- if (record.id === id) {
7243
- return record;
7244
- }
7833
+ resolveAssignableRecord(key, current, candidate) {
7834
+ if (!current) {
7835
+ return this.createRecord(key, candidate);
7245
7836
  }
7246
- return void 0;
7837
+ if (this.shouldRollEpisode(current, candidate.timestamp)) {
7838
+ current.state = "stale";
7839
+ return this.createRecord(key, candidate);
7840
+ }
7841
+ return current;
7842
+ }
7843
+ shouldRollEpisode(record, nextTimestamp) {
7844
+ if (isDormantEpisodeState(record.state)) {
7845
+ return true;
7846
+ }
7847
+ const previousMs = Date.parse(record.updatedAt);
7848
+ const nextMs = Date.parse(nextTimestamp);
7849
+ if (Number.isNaN(previousMs) || Number.isNaN(nextMs)) {
7850
+ return false;
7851
+ }
7852
+ return nextMs - previousMs >= DEFAULTS.staleAfterMs;
7247
7853
  }
7248
7854
  };
7249
7855
  function buildEpisodeKey(candidate) {
@@ -7255,6 +7861,12 @@ function buildEpisodeKey(candidate) {
7255
7861
  function readFrameEpisodeId(frame) {
7256
7862
  return frame ? readString(frame.metadata?.episode, "id") : null;
7257
7863
  }
7864
+ function readFrameEpisodeState(frame) {
7865
+ return frame ? readState(frame.metadata?.episode, "state") : null;
7866
+ }
7867
+ function isDormantEpisodeState(state) {
7868
+ return state === "stale" || state === "resolved";
7869
+ }
7258
7870
  function episodeAnchor(candidate) {
7259
7871
  const relationAnchor = readSemanticRelationTarget(candidate.relationHints);
7260
7872
  if (relationAnchor) {
@@ -7485,10 +8097,13 @@ function detectSemanticRelationHints(text) {
7485
8097
  return dedupeRelationHints(hints);
7486
8098
  }
7487
8099
  function inferConsequenceFromSemanticText(text, fallback, toolFamily) {
8100
+ if (isRoutineSuccessObservation(text)) {
8101
+ return fallback;
8102
+ }
7488
8103
  if (toolFamily === "read" || toolFamily === "search") {
7489
8104
  return fallback;
7490
8105
  }
7491
- if (containsAnySemanticPhrase(text, HIGH_RISK_PHRASES)) {
8106
+ if (containsAnySemanticRiskPhrase(text, HIGH_RISK_PHRASES)) {
7492
8107
  return "high";
7493
8108
  }
7494
8109
  if (toolFamily === "write" || toolFamily === "edit" || toolFamily === "bash") {
@@ -7496,9 +8111,82 @@ function inferConsequenceFromSemanticText(text, fallback, toolFamily) {
7496
8111
  }
7497
8112
  return fallback;
7498
8113
  }
8114
+ function detectObservationalFailureStatus(text, toolFamily) {
8115
+ if (toolFamily !== "edit" && toolFamily !== "read") {
8116
+ return false;
8117
+ }
8118
+ return containsAnySemanticPhrase(text, OBSERVATIONAL_READBACK_PHRASES) || looksLikeTaggedFileObservation(text) || looksLikeReadObservationPayload(text);
8119
+ }
8120
+ function detectRoutineObservationalFailureLowConsequence(text, toolFamily) {
8121
+ if (toolFamily === "search") {
8122
+ return looksLikeSearchResultOutput(text);
8123
+ }
8124
+ if (toolFamily === "read") {
8125
+ if (looksLikeSearchResultOutput(text)) {
8126
+ return true;
8127
+ }
8128
+ if (!looksLikeTaggedFileObservation(text) && !looksLikeReadObservationPayload(text)) {
8129
+ return false;
8130
+ }
8131
+ if (looksLikeSourceCodeObservation(text)) {
8132
+ return false;
8133
+ }
8134
+ return looksLikeLogObservation(text) || looksLikeBuildMetadataObservation(text);
8135
+ }
8136
+ return false;
8137
+ }
8138
+ function detectExpectedDiagnosticFailure(text, toolFamily) {
8139
+ if (toolFamily !== "bash") {
8140
+ return false;
8141
+ }
8142
+ return containsAnySemanticPhrase(text, EXPECTED_DIAGNOSTIC_FAILURE_PHRASES) && !containsAnySemanticPhrase(text, TERMINAL_FAILURE_PHRASES);
8143
+ }
7499
8144
  function containsAnySemanticPhrase(value, phrases) {
7500
8145
  return phrases.some((phrase) => value.includes(phrase));
7501
8146
  }
8147
+ function containsAnySemanticRiskPhrase(value, phrases) {
8148
+ return phrases.some((phrase) => containsSemanticRiskPhrase(value, phrase));
8149
+ }
8150
+ function containsSemanticRiskPhrase(value, phrase) {
8151
+ const normalizedPhrase = normalizeSemanticText(phrase);
8152
+ if (!normalizedPhrase) {
8153
+ return false;
8154
+ }
8155
+ if (!normalizedPhrase.includes(" ")) {
8156
+ return hasWord(value, normalizedPhrase);
8157
+ }
8158
+ return new RegExp(`(?:^|\\s)${escapeRegExp(normalizedPhrase)}(?:\\s|$)`).test(value);
8159
+ }
8160
+ function looksLikeReadObservationPayload(text) {
8161
+ if (!containsPathLikeToken(text)) {
8162
+ return false;
8163
+ }
8164
+ return containsAnySemanticPhrase(text, OBSERVATIONAL_PAYLOAD_PHRASES) || containsCodeLikeContent(text) || containsLineNumberedCodeContent(text);
8165
+ }
8166
+ function looksLikeTaggedFileObservation(text) {
8167
+ return containsAnySemanticPhrase(text, TAGGED_FILE_OBSERVATION_PHRASES) && containsPathLikeToken(text);
8168
+ }
8169
+ function looksLikeSearchResultOutput(text) {
8170
+ return SEARCH_RESULT_OUTPUT_PATTERN.test(text) || containsPathLikeToken(text) && /\bmatch(?:es)?\b/.test(text);
8171
+ }
8172
+ function containsPathLikeToken(text) {
8173
+ return PATH_LIKE_TOKEN_PATTERN.test(text);
8174
+ }
8175
+ function containsCodeLikeContent(text) {
8176
+ return CODE_CONTENT_PATTERN.test(text);
8177
+ }
8178
+ function containsLineNumberedCodeContent(text) {
8179
+ return LINE_NUMBERED_CODE_PATTERN.test(text);
8180
+ }
8181
+ function looksLikeSourceCodeObservation(text) {
8182
+ return SOURCE_CODE_PATH_PATTERN.test(text) || SOURCE_CODE_FILENAME_PATTERN.test(text) || SOURCE_CODE_CONTENT_PATTERN.test(text) || LINE_NUMBERED_SOURCE_CODE_PATTERN.test(text);
8183
+ }
8184
+ function looksLikeLogObservation(text) {
8185
+ return LOG_OUTPUT_PATTERN.test(text) || containsAnySemanticPhrase(text, LOG_LIKE_OBSERVATION_PHRASES);
8186
+ }
8187
+ function looksLikeBuildMetadataObservation(text) {
8188
+ return BUILD_METADATA_PATTERN.test(text) || containsAnySemanticPhrase(text, BUILD_METADATA_PHRASES);
8189
+ }
7502
8190
  function readMetadataToolFamily(metadata) {
7503
8191
  const value = metadata?.toolFamily;
7504
8192
  return typeof value === "string" ? value : null;
@@ -7574,6 +8262,70 @@ var HIGH_RISK_PHRASES = [
7574
8262
  "kill process",
7575
8263
  "migrate"
7576
8264
  ];
8265
+ var OBSERVATIONAL_READBACK_PHRASES = [
8266
+ "result of running cat -n",
8267
+ "result of running sed -n",
8268
+ "result of running grep",
8269
+ "result of running ls",
8270
+ "result of running find",
8271
+ "here s the result of running cat -n",
8272
+ "here s the result of running sed -n"
8273
+ ];
8274
+ var OBSERVATIONAL_PAYLOAD_PHRASES = [
8275
+ "observation",
8276
+ "contents of",
8277
+ "showing first",
8278
+ "showing top",
8279
+ "found"
8280
+ ];
8281
+ var TAGGED_FILE_OBSERVATION_PHRASES = [
8282
+ "path",
8283
+ "type file",
8284
+ "content"
8285
+ ];
8286
+ var ROUTINE_SUCCESS_PHRASES = [
8287
+ "ran successfully and did not produce any output",
8288
+ "command ran successfully and did not produce any output",
8289
+ "completed successfully and did not produce any output"
8290
+ ];
8291
+ var LOG_LIKE_OBSERVATION_PHRASES = [
8292
+ "tool-output",
8293
+ "dmesg"
8294
+ ];
8295
+ var BUILD_METADATA_PHRASES = [
8296
+ "makefile",
8297
+ "spdx-license-identifier",
8298
+ "patchlevel",
8299
+ "sublevel",
8300
+ "extraversion"
8301
+ ];
8302
+ var PATH_LIKE_TOKEN_PATTERN = /(?:^|\s)\/[a-z0-9._-]+(?:\/[a-z0-9._-]+)+(?:\s|$)/;
8303
+ var SEARCH_RESULT_OUTPUT_PATTERN = /\bfound\s+\d+\s+match(?:es)?\b|\bshowing\s+(?:first|top)\s+\d+\b|\bmatch(?:es)?\s+in\s+\d+\s+files?\b/;
8304
+ var CODE_CONTENT_PATTERN = /\b(import|from|export|class|def|function|const|let|var|return)\b/;
8305
+ var LINE_NUMBERED_CODE_PATTERN = /\b\d+\s+(?:import|from|export|class|def|function|const|let|var|return)\b/;
8306
+ var SOURCE_CODE_PATH_PATTERN = /\/[a-z0-9._/-]+\.(?:c|cc|cpp|cxx|h|hpp|ts|tsx|js|jsx|py|rb|go|rs|java|kt|swift)(?:\b|\/)/;
8307
+ var SOURCE_CODE_FILENAME_PATTERN = /\b[a-z0-9.-]+\.(?:c|cc|cpp|cxx|h|hpp|ts|tsx|js|jsx|py|rb|go|rs|java|kt|swift)\b/;
8308
+ var SOURCE_CODE_CONTENT_PATTERN = /\b(static|struct|enum|typedef|void|int|char|bool|return)\b/;
8309
+ var LINE_NUMBERED_SOURCE_CODE_PATTERN = /\b\d+\s+(?:static|struct|enum|typedef|void|int|char|bool|return)\b/;
8310
+ var LOG_OUTPUT_PATTERN = /\b\d+\s+\[\s*\d+\.\d+\]\s+[a-z0-9_.:-]+/;
8311
+ var BUILD_METADATA_PATTERN = /\b(?:version|patchlevel|sublevel|extraversion)\b/;
8312
+ var EXPECTED_DIAGNOSTIC_FAILURE_PHRASES = [
8313
+ "form is valid false",
8314
+ "form without instance is valid false",
8315
+ "form errors",
8316
+ "errorlist",
8317
+ "decompress result"
8318
+ ];
8319
+ var TERMINAL_FAILURE_PHRASES = [
8320
+ "traceback",
8321
+ "exception",
8322
+ "permission denied",
8323
+ "command not found",
8324
+ "segmentation fault"
8325
+ ];
8326
+ function isRoutineSuccessObservation(text) {
8327
+ return containsAnySemanticPhrase(text, ROUTINE_SUCCESS_PHRASES);
8328
+ }
7577
8329
  var REPEAT_PHRASES = [
7578
8330
  "still",
7579
8331
  "again",
@@ -7732,11 +8484,12 @@ var EventEvaluator = class {
7732
8484
  evaluateHumanInput(event) {
7733
8485
  const actions = this.createActions(event);
7734
8486
  const responseSpec = this.createResponseSpec(event, actions);
8487
+ const toolFamily = event.request.kind === "approval" ? event.toolFamily : void 0;
7735
8488
  return {
7736
8489
  taskId: event.taskId,
7737
8490
  interactionId: event.interactionId,
7738
8491
  ...event.source !== void 0 ? { source: event.source } : {},
7739
- ...event.toolFamily !== void 0 ? { toolFamily: event.toolFamily } : {},
8492
+ ...toolFamily !== void 0 ? { toolFamily } : {},
7740
8493
  ...event.activityClass !== void 0 ? { activityClass: event.activityClass } : {},
7741
8494
  mode: event.request.kind,
7742
8495
  tone: event.tone ?? "focused",
@@ -7968,8 +8721,8 @@ var evaluateBackgroundPolicyGateRule = (input) => {
7968
8721
  autoApprove: false,
7969
8722
  mayInterrupt: false,
7970
8723
  requiresOperatorResponse: false,
7971
- minimumPresentation: "ambient",
7972
- minimumPresentationIsSticky: true,
8724
+ minimumLane: "ambient",
8725
+ minimumLaneIsSticky: true,
7973
8726
  rationale: ["background work should remain peripheral by default"]
7974
8727
  }
7975
8728
  );
@@ -7984,8 +8737,8 @@ var evaluateBlockingPolicyGateRule = (input) => {
7984
8737
  autoApprove: false,
7985
8738
  mayInterrupt: true,
7986
8739
  requiresOperatorResponse: true,
7987
- minimumPresentation: "active",
7988
- minimumPresentationIsSticky: false,
8740
+ minimumLane: "now",
8741
+ minimumLaneIsSticky: false,
7989
8742
  rationale: ["blocking interactions require explicit operator attention"]
7990
8743
  }
7991
8744
  );
@@ -8000,11 +8753,11 @@ function readBoundedToolFamily(input) {
8000
8753
  if (input.mode === "status") {
8001
8754
  return readExplicitToolFamily(input);
8002
8755
  }
8003
- if (input.activityClass !== void 0 && input.activityClass !== "permission_request") {
8004
- return readExplicitToolFamily(input);
8005
- }
8006
8756
  if (input.mode !== "approval") {
8007
- return readExplicitToolFamily(input);
8757
+ return null;
8758
+ }
8759
+ if (input.activityClass !== void 0 && input.activityClass !== "permission_request") {
8760
+ return null;
8008
8761
  }
8009
8762
  return inferToolFamily(input);
8010
8763
  }
@@ -8014,6 +8767,20 @@ function sourceKey(source) {
8014
8767
  }
8015
8768
  return source.kind ?? source.id;
8016
8769
  }
8770
+ function readAttentionLane(value) {
8771
+ switch (value) {
8772
+ case "ambient":
8773
+ return "ambient";
8774
+ case "next":
8775
+ case "queue":
8776
+ return "next";
8777
+ case "now":
8778
+ case "active":
8779
+ return "now";
8780
+ default:
8781
+ return void 0;
8782
+ }
8783
+ }
8017
8784
  function matchPolicyRule(judgmentConfig, candidate) {
8018
8785
  const policy = judgmentConfig?.policy;
8019
8786
  if (!policy) {
@@ -8028,16 +8795,6 @@ function matchPolicyRule(judgmentConfig, candidate) {
8028
8795
  }
8029
8796
  return void 0;
8030
8797
  }
8031
- function readAttentionPresentationFloor(value) {
8032
- switch (value) {
8033
- case "ambient":
8034
- case "queue":
8035
- case "active":
8036
- return value;
8037
- default:
8038
- return void 0;
8039
- }
8040
- }
8041
8798
  function inferConfiguredPolicyToolFamily(candidate) {
8042
8799
  if (!isToolPolicyCandidate(candidate)) {
8043
8800
  return null;
@@ -8102,10 +8859,10 @@ var evaluateConfiguredPolicyGateRule = (input) => {
8102
8859
  const policyRule = matchPolicyRule(judgmentConfig, candidate);
8103
8860
  const requireContextExpansion = toolOverride?.requireContextExpansion === true || policyRule?.requireContextExpansion === true;
8104
8861
  const autoApprove = policyRule?.autoApprove === true && candidate.mode === "approval" && candidate.responseSpec.kind === "approval" && !requireContextExpansion;
8105
- const minimumPresentation = readAttentionPresentationFloor(toolOverride?.defaultPresentation) ?? policyRule?.minimumPresentation ?? (requireContextExpansion ? "active" : void 0);
8862
+ const minimumLane = readAttentionLane(toolOverride?.minimumLane ?? toolOverride?.defaultPresentation) ?? readAttentionLane(policyRule?.minimumLane) ?? (requireContextExpansion ? "now" : void 0);
8106
8863
  const mayInterrupt = policyRule?.mayInterrupt;
8107
- const requiresOperatorResponse = !autoApprove && (candidate.blocking || minimumPresentation === "active" || requireContextExpansion);
8108
- if (minimumPresentation === void 0 && mayInterrupt === void 0 && !toolOverride && !autoApprove) {
8864
+ const requiresOperatorResponse = !autoApprove && (candidate.blocking || minimumLane === "now" || requireContextExpansion);
8865
+ if (minimumLane === void 0 && mayInterrupt === void 0 && !toolOverride && !autoApprove) {
8109
8866
  return noopPolicyGateRule("configured_policy");
8110
8867
  }
8111
8868
  const rationale = [];
@@ -8123,8 +8880,8 @@ var evaluateConfiguredPolicyGateRule = (input) => {
8123
8880
  autoApprove: true,
8124
8881
  mayInterrupt: false,
8125
8882
  requiresOperatorResponse: false,
8126
- minimumPresentation: "ambient",
8127
- minimumPresentationIsSticky: true,
8883
+ minimumLane: "ambient",
8884
+ minimumLaneIsSticky: true,
8128
8885
  rationale
8129
8886
  }
8130
8887
  );
@@ -8137,8 +8894,8 @@ var evaluateConfiguredPolicyGateRule = (input) => {
8137
8894
  autoApprove: false,
8138
8895
  mayInterrupt: true,
8139
8896
  requiresOperatorResponse: true,
8140
- minimumPresentation: "active",
8141
- minimumPresentationIsSticky: false,
8897
+ minimumLane: "now",
8898
+ minimumLaneIsSticky: false,
8142
8899
  rationale
8143
8900
  }
8144
8901
  );
@@ -8149,8 +8906,8 @@ var evaluateConfiguredPolicyGateRule = (input) => {
8149
8906
  autoApprove: false,
8150
8907
  mayInterrupt: mayInterrupt ?? false,
8151
8908
  requiresOperatorResponse,
8152
- minimumPresentation: minimumPresentation ?? (candidate.blocking ? "active" : "queue"),
8153
- minimumPresentationIsSticky: minimumPresentation !== void 0 || mayInterrupt === false,
8909
+ minimumLane: minimumLane ?? (candidate.blocking ? "now" : "next"),
8910
+ minimumLaneIsSticky: minimumLane !== void 0 || mayInterrupt === false,
8154
8911
  rationale
8155
8912
  }
8156
8913
  );
@@ -8161,8 +8918,8 @@ var evaluateInterruptiveDefaultPolicyGateRule = () => verdictPolicyGateRule(
8161
8918
  autoApprove: false,
8162
8919
  mayInterrupt: true,
8163
8920
  requiresOperatorResponse: false,
8164
- minimumPresentation: "queue",
8165
- minimumPresentationIsSticky: false,
8921
+ minimumLane: "next",
8922
+ minimumLaneIsSticky: false,
8166
8923
  rationale: ["urgent non-blocking work may compete for interruptive attention"]
8167
8924
  }
8168
8925
  );
@@ -8236,7 +8993,7 @@ var evaluateInterruptEligibilityCriterionRule = (input) => {
8236
8993
  peripheralResolution,
8237
8994
  evidence
8238
8995
  } = input;
8239
- if (!policyVerdict.mayInterrupt && policyVerdict.minimumPresentationIsSticky) {
8996
+ if (!policyVerdict.mayInterrupt && policyVerdict.minimumLaneIsSticky) {
8240
8997
  return verdictPolicyCriterionRule(
8241
8998
  "interrupt_eligibility",
8242
8999
  preservedPeripheralCriterionVerdict(
@@ -8245,7 +9002,7 @@ var evaluateInterruptEligibilityCriterionRule = (input) => {
8245
9002
  )
8246
9003
  );
8247
9004
  }
8248
- if (candidate.blocking || candidate.episodeState === "actionable" || policyVerdict.autoApprove || policyVerdict.requiresOperatorResponse || policyVerdict.minimumPresentation === "active") {
9005
+ if (candidate.blocking || candidate.episodeState === "actionable" || policyVerdict.autoApprove || policyVerdict.requiresOperatorResponse || policyVerdict.minimumLane === "now") {
8249
9006
  return verdictPolicyCriterionRule(
8250
9007
  "interrupt_eligibility",
8251
9008
  clearCriterionVerdict(criterion)
@@ -8280,10 +9037,12 @@ var evaluateNoActiveFrameCriterionRule = (input) => {
8280
9037
  return noopPolicyCriterionRule("no_active_frame");
8281
9038
  }
8282
9039
  if (candidate.episodeId !== void 0 && [
8283
- evidence.attentionView.active,
8284
- ...evidence.attentionView.queued,
9040
+ evidence.attentionView.now,
9041
+ ...evidence.attentionView.next,
8285
9042
  ...evidence.attentionView.ambient
8286
- ].filter((frame) => frame !== null).some((frame) => frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId)) {
9043
+ ].filter((frame) => frame !== null).some(
9044
+ (frame) => frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId && !isDormantEpisodeState(readFrameEpisodeState(frame))
9045
+ )) {
8287
9046
  return noopPolicyCriterionRule("no_active_frame");
8288
9047
  }
8289
9048
  if (candidateScore >= criterion.activationThreshold) {
@@ -8317,7 +9076,7 @@ var evaluateOperatorAbsenceCriterionRule = (input) => {
8317
9076
  criterion,
8318
9077
  peripheralResolution,
8319
9078
  ambiguity: null,
8320
- rationale: ["operator absence keeps interruptive work peripheral until active attention returns"]
9079
+ rationale: ["operator absence keeps interruptive work peripheral until foreground attention returns"]
8321
9080
  }
8322
9081
  );
8323
9082
  };
@@ -8332,8 +9091,8 @@ var evaluatePeripheralStatusPolicyGateRule = (input) => {
8332
9091
  autoApprove: false,
8333
9092
  mayInterrupt: false,
8334
9093
  requiresOperatorResponse: false,
8335
- minimumPresentation: "ambient",
8336
- minimumPresentationIsSticky: false,
9094
+ minimumLane: "ambient",
9095
+ minimumLaneIsSticky: false,
8337
9096
  rationale: ["non-critical status work should start in the periphery"]
8338
9097
  }
8339
9098
  );
@@ -8490,8 +9249,8 @@ var AttentionPolicy = class {
8490
9249
  autoApprove: false,
8491
9250
  mayInterrupt: true,
8492
9251
  requiresOperatorResponse: false,
8493
- minimumPresentation: "queue",
8494
- minimumPresentationIsSticky: false,
9252
+ minimumLane: "next",
9253
+ minimumLaneIsSticky: false,
8495
9254
  rationale: ["urgent non-blocking work may compete for interruptive attention"]
8496
9255
  };
8497
9256
  return {
@@ -8559,7 +9318,7 @@ var AttentionPolicy = class {
8559
9318
  };
8560
9319
  }
8561
9320
  readPeripheralResolution(policyVerdict) {
8562
- return policyVerdict.minimumPresentation === "ambient" ? "ambient" : "queue";
9321
+ return policyVerdict.minimumLane === "ambient" ? "ambient" : "queue";
8563
9322
  }
8564
9323
  readSourceTrustAdjustment(candidate) {
8565
9324
  const sourceKey2 = candidate.source?.kind ?? candidate.source?.id;
@@ -8683,7 +9442,7 @@ function interruptClassForFrame(frame) {
8683
9442
  return 0;
8684
9443
  }
8685
9444
  function interruptClassForCandidate(candidate, policyVerdict) {
8686
- if (candidate.blocking || policyVerdict.requiresOperatorResponse || policyVerdict.minimumPresentation === "active") {
9445
+ if (candidate.blocking || policyVerdict.requiresOperatorResponse || policyVerdict.minimumLane === "now") {
8687
9446
  return 3;
8688
9447
  }
8689
9448
  if (candidate.tone === "critical" || candidate.consequence === "high") {
@@ -8781,31 +9540,35 @@ function isSameDecisionStream(activeFrame, candidate) {
8781
9540
  return false;
8782
9541
  }
8783
9542
  var evaluateDeferralEscalationContinuityRule = (input) => {
8784
- const activeFrame = input.evidence.currentFrame;
8785
9543
  const { candidate, context, evidence } = input;
8786
- if (!activeFrame || context.currentScore === null) {
9544
+ const activeFrame = evidence.attentionView.now ?? evidence.currentFrame;
9545
+ if (!activeFrame) {
9546
+ return noopContinuityRule("deferral_escalation");
9547
+ }
9548
+ const currentScore = activeFrame === evidence.currentFrame ? context.currentScore : scoreAttentionFrame(activeFrame, { now: candidate.timestamp });
9549
+ if (currentScore === null) {
8787
9550
  return noopContinuityRule("deferral_escalation");
8788
9551
  }
8789
9552
  if (candidate.blocking || candidate.priority === "background" || isBlockingFrame(activeFrame)) {
8790
9553
  return noopContinuityRule("deferral_escalation");
8791
9554
  }
8792
- const taskSummary = evidence.taskSignalSummary;
8793
- const repeatedlyDeferred = taskSummary.counts.deferred >= JUDGMENT_DEFAULTS.queuePlanner.deferredEscalationThreshold;
8794
- const repeatedlyReturned = taskSummary.counts.returned >= JUDGMENT_DEFAULTS.queuePlanner.returnedEscalationThreshold;
8795
- if (!repeatedlyDeferred && !repeatedlyReturned) {
9555
+ if (!hasResurfacingPressure(evidence.continuitySignalSummary)) {
8796
9556
  return noopContinuityRule("deferral_escalation");
8797
9557
  }
8798
- if (context.candidateScore < context.currentScore - JUDGMENT_DEFAULTS.queuePlanner.escalationScoreSlack) {
9558
+ if (context.candidateScore < currentScore - JUDGMENT_DEFAULTS.queuePlanner.escalationScoreSlack) {
8799
9559
  return noopContinuityRule("deferral_escalation");
8800
9560
  }
8801
9561
  return overrideContinuityRule(
8802
9562
  "deferral_escalation",
8803
9563
  { kind: "activate", candidate },
8804
9564
  priorityForFrame(activeFrame),
8805
- context.currentScore,
8806
- ["repeated deferral makes this task more deserving of current focus"]
9565
+ currentScore,
9566
+ ["repeated deferral or resurfacing makes this task more deserving of current focus"]
8807
9567
  );
8808
9568
  };
9569
+ function hasResurfacingPressure(summary) {
9570
+ return summary.counts.deferred >= JUDGMENT_DEFAULTS.queuePlanner.deferredEscalationThreshold || summary.counts.returned >= JUDGMENT_DEFAULTS.queuePlanner.returnedEscalationThreshold;
9571
+ }
8809
9572
  var evaluateMinimumDwellContinuityRule = (input) => {
8810
9573
  const activeFrame = input.evidence.currentFrame;
8811
9574
  const { candidate, context, evidence, helpers, routed, plannerDefaults } = input;
@@ -8843,7 +9606,7 @@ var evaluateSameEpisodeContinuityRule = (input) => {
8843
9606
  return noopContinuityRule("same_episode");
8844
9607
  }
8845
9608
  const currentEpisodeId = readFrameEpisodeId(activeFrame);
8846
- if (!currentEpisodeId || currentEpisodeId !== candidate.episodeId) {
9609
+ if (!currentEpisodeId || currentEpisodeId !== candidate.episodeId || isDormantEpisodeState(readFrameEpisodeState(activeFrame))) {
8847
9610
  return noopContinuityRule("same_episode");
8848
9611
  }
8849
9612
  if (candidate.blocking && !isBlockingFrame(activeFrame)) {
@@ -8852,7 +9615,7 @@ var evaluateSameEpisodeContinuityRule = (input) => {
8852
9615
  { kind: "activate", candidate },
8853
9616
  priorityForFrame(activeFrame),
8854
9617
  context.currentScore,
8855
- ["the active episode has progressed into an interruptive step"]
9618
+ ["the current episode has progressed into an interruptive step that belongs in now"]
8856
9619
  );
8857
9620
  }
8858
9621
  if (candidate.blocking && hasSemanticRelationKind(candidate.relationHints, "supersedes")) {
@@ -8861,15 +9624,18 @@ var evaluateSameEpisodeContinuityRule = (input) => {
8861
9624
  { kind: "activate", candidate },
8862
9625
  priorityForFrame(activeFrame),
8863
9626
  context.currentScore,
8864
- ["the active episode has advanced to a superseding step"]
9627
+ ["the current episode has advanced to a superseding step that belongs in now"]
8865
9628
  );
8866
9629
  }
9630
+ if (hasResurfacingPressure(evidence.continuitySignalSummary)) {
9631
+ return noopContinuityRule("same_episode");
9632
+ }
8867
9633
  return overrideContinuityRule(
8868
9634
  "same_episode",
8869
9635
  helpers.peripheralDecision(candidate, context.policyVerdict, evidence.surfaceCapabilities),
8870
9636
  priorityForFrame(activeFrame),
8871
9637
  context.currentScore,
8872
- ["related work stays bundled with the active episode"]
9638
+ ["related work stays bundled with the current episode already in now"]
8873
9639
  );
8874
9640
  };
8875
9641
  var evaluateSameInteractionContinuityRule = (input) => {
@@ -8894,13 +9660,18 @@ var evaluateVisibleEpisodeContinuityRule = (input) => {
8894
9660
  return noopContinuityRule("visible_episode");
8895
9661
  }
8896
9662
  const visibleRelatedFrames = [
8897
- evidence.attentionView.active,
8898
- ...evidence.attentionView.queued,
9663
+ evidence.attentionView.now,
9664
+ ...evidence.attentionView.next,
8899
9665
  ...evidence.attentionView.ambient
8900
- ].filter((frame) => frame !== null).filter((frame) => frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId);
9666
+ ].filter((frame) => frame !== null).filter(
9667
+ (frame) => frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId && !isDormantEpisodeState(readFrameEpisodeState(frame))
9668
+ );
8901
9669
  if (visibleRelatedFrames.length === 0 || !(candidate.episodeState === "batched" || (candidate.episodeSize ?? 1) >= 2 || visibleRelatedFrames.length >= 2)) {
8902
9670
  return noopContinuityRule("visible_episode");
8903
9671
  }
9672
+ if (hasResurfacingPressure(evidence.continuitySignalSummary)) {
9673
+ return noopContinuityRule("visible_episode");
9674
+ }
8904
9675
  return overrideContinuityRule(
8905
9676
  "visible_episode",
8906
9677
  helpers.batchedDecision(
@@ -8951,14 +9722,16 @@ var AttentionPlanner = class {
8951
9722
  };
8952
9723
  }
8953
9724
  batchedDecision(candidate, policyVerdict, attentionView, surfaceCapabilities) {
8954
- const episodeIsAlreadyInterruptive = candidate.episodeId !== void 0 && [attentionView?.active, ...attentionView?.queued ?? []].filter((frame) => frame !== null).some((frame) => frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId);
9725
+ const episodeIsAlreadyInterruptive = candidate.episodeId !== void 0 && [attentionView?.now, ...attentionView?.next ?? []].filter((frame) => frame !== null).some(
9726
+ (frame) => frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId && !isDormantEpisodeState(readFrameEpisodeState(frame))
9727
+ );
8955
9728
  if (episodeIsAlreadyInterruptive) {
8956
9729
  return { kind: "queue", candidate };
8957
9730
  }
8958
9731
  return this.peripheralDecision(candidate, policyVerdict, surfaceCapabilities);
8959
9732
  }
8960
9733
  suppressedDecision(candidate, policyVerdict, utility, surfaceCapabilities) {
8961
- if ((utility.components.deferralAffinity > 0 || utility.components.consequenceCalibration > 0) && policyVerdict.minimumPresentation !== "active") {
9734
+ if ((utility.components.deferralAffinity > 0 || utility.components.consequenceCalibration > 0) && policyVerdict.minimumLane !== "now") {
8962
9735
  return { kind: "queue", candidate };
8963
9736
  }
8964
9737
  return this.peripheralDecision(candidate, policyVerdict, surfaceCapabilities);
@@ -8973,11 +9746,13 @@ var AttentionPlanner = class {
8973
9746
  if (!attentionView) {
8974
9747
  return false;
8975
9748
  }
8976
- const relatedEpisodeVisible = candidate.episodeId !== void 0 && [attentionView.active, ...attentionView.queued].filter((frame) => frame !== null).some((frame) => frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId);
9749
+ const relatedEpisodeVisible = candidate.episodeId !== void 0 && [attentionView.now, ...attentionView.next].filter((frame) => frame !== null).some(
9750
+ (frame) => frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId && !isDormantEpisodeState(readFrameEpisodeState(frame))
9751
+ );
8977
9752
  if (relatedEpisodeVisible) {
8978
9753
  return true;
8979
9754
  }
8980
- const urgentBacklog = [attentionView.active, ...attentionView.queued].filter((frame) => frame !== null).filter((frame) => {
9755
+ const urgentBacklog = [attentionView.now, ...attentionView.next].filter((frame) => frame !== null).filter((frame) => {
8981
9756
  if (frame.interactionId === candidate.interactionId) {
8982
9757
  return false;
8983
9758
  }
@@ -8992,7 +9767,7 @@ var AttentionPlanner = class {
8992
9767
  if (pressureForecast.overloadRisk === "low") {
8993
9768
  return false;
8994
9769
  }
8995
- if (candidate.blocking || policyVerdict.requiresOperatorResponse || policyVerdict.minimumPresentation === "active") {
9770
+ if (candidate.blocking || policyVerdict.requiresOperatorResponse || policyVerdict.minimumLane === "now") {
8996
9771
  return false;
8997
9772
  }
8998
9773
  if (candidate.consequence === "high" || candidate.tone === "critical") {
@@ -9013,7 +9788,7 @@ var AttentionPlanner = class {
9013
9788
  if (!activeFrame) {
9014
9789
  if (actionableEpisode) {
9015
9790
  if (evidence.pressureForecast.overloadRisk === "high") {
9016
- reasons.push("the episode has become actionable, but predicted overload keeps it queued instead of interrupting");
9791
+ reasons.push("the episode has become actionable, but predicted overload keeps it in next instead of surfacing it now");
9017
9792
  return {
9018
9793
  decision: { kind: "queue", candidate },
9019
9794
  currentPriority: null,
@@ -9052,7 +9827,7 @@ var AttentionPlanner = class {
9052
9827
  reasons
9053
9828
  };
9054
9829
  }
9055
- if (!context.policyVerdict.mayInterrupt && context.policyVerdict.minimumPresentation === "ambient") {
9830
+ if (!context.policyVerdict.mayInterrupt && context.policyVerdict.minimumLane === "ambient") {
9056
9831
  reasons.push("policy keeps this interaction ambient until stronger context arrives");
9057
9832
  return {
9058
9833
  decision: this.peripheralDecision(candidate, context.policyVerdict, evidence.surfaceCapabilities),
@@ -9061,7 +9836,7 @@ var AttentionPlanner = class {
9061
9836
  reasons
9062
9837
  };
9063
9838
  }
9064
- reasons.push("no current frame is active for this task");
9839
+ reasons.push("nothing is in now for this task");
9065
9840
  return {
9066
9841
  decision: { kind: "activate", candidate },
9067
9842
  currentPriority: null,
@@ -9075,7 +9850,7 @@ var AttentionPlanner = class {
9075
9850
  if (actionableEpisode) {
9076
9851
  if (currentBlocking || evidence.pressureForecast.overloadRisk === "high") {
9077
9852
  reasons.push(
9078
- currentBlocking ? "the episode has become actionable, but current blocking work keeps it queued" : "the episode has become actionable, but predicted overload keeps it queued"
9853
+ currentBlocking ? "the episode has become actionable, but current blocking work keeps it in next" : "the episode has become actionable, but predicted overload keeps it in next"
9079
9854
  );
9080
9855
  return {
9081
9856
  decision: { kind: "queue", candidate },
@@ -9102,7 +9877,7 @@ var AttentionPlanner = class {
9102
9877
  reasons
9103
9878
  };
9104
9879
  }
9105
- reasons.push("the episode has become actionable, so it stays queued even though policy still prevents interrupting");
9880
+ reasons.push("the episode has become actionable, so it stays in next even though policy still prevents interrupting");
9106
9881
  return {
9107
9882
  decision: { kind: "queue", candidate },
9108
9883
  currentPriority,
@@ -9111,6 +9886,15 @@ var AttentionPlanner = class {
9111
9886
  };
9112
9887
  }
9113
9888
  if (currentBlocking && !candidate.blocking) {
9889
+ if (hasResurfacingPressure(evidence.continuitySignalSummary)) {
9890
+ reasons.push("blocking work keeps resurfacing backlog in next so it stays visible until focus can return");
9891
+ return {
9892
+ decision: { kind: "queue", candidate },
9893
+ currentPriority,
9894
+ currentScore,
9895
+ reasons
9896
+ };
9897
+ }
9114
9898
  reasons.push("blocking work keeps non-blocking updates in the periphery");
9115
9899
  return {
9116
9900
  decision: this.peripheralDecision(candidate, context.policyVerdict, evidence.surfaceCapabilities),
@@ -9143,8 +9927,17 @@ var AttentionPlanner = class {
9143
9927
  };
9144
9928
  }
9145
9929
  if (this.shouldSuppressForBacklog(candidate, evidence.attentionView, candidate.timestamp)) {
9930
+ if (hasResurfacingPressure(evidence.continuitySignalSummary)) {
9931
+ reasons.push("existing urgent backlog keeps resurfacing work in next so it remains visible");
9932
+ return {
9933
+ decision: { kind: "queue", candidate },
9934
+ currentPriority,
9935
+ currentScore,
9936
+ reasons
9937
+ };
9938
+ }
9146
9939
  reasons.push(
9147
- context.utility.components.deferralAffinity > 0 ? "existing urgent backlog defers this work, but memory keeps it queued because it usually returns after deferral" : "existing urgent backlog keeps lower-value status work queued"
9940
+ context.utility.components.deferralAffinity > 0 ? "existing urgent backlog defers this work, but memory keeps it in next because it usually returns after deferral" : "existing urgent backlog keeps lower-value status work in next"
9148
9941
  );
9149
9942
  return {
9150
9943
  decision: this.suppressedDecision(
@@ -9238,7 +10031,7 @@ function parseReferenceTime(value) {
9238
10031
  return Number.isNaN(timestamp) ? 0 : timestamp;
9239
10032
  }
9240
10033
  function selectPeripheralBucket(candidate, policyVerdict, surfaceCapabilities = baseAttentionSurfaceCapabilities) {
9241
- if (policyVerdict.minimumPresentation === "ambient" && canRemainAmbientOnSurface(candidate, surfaceCapabilities)) {
10034
+ if (policyVerdict.minimumLane === "ambient" && canRemainAmbientOnSurface(candidate, surfaceCapabilities)) {
9242
10035
  return "ambient";
9243
10036
  }
9244
10037
  return "queue";
@@ -9585,85 +10378,7 @@ var AttentionSignalStore = class _AttentionSignalStore {
9585
10378
  return [...this.byTaskId.values()].flat().sort((left, right) => left.timestamp.localeCompare(right.timestamp));
9586
10379
  }
9587
10380
  summarize(taskId) {
9588
- const signals = this.list(taskId);
9589
- const recentSignals = this.recentSignals(signals);
9590
- const counts = {
9591
- presented: 0,
9592
- viewed: 0,
9593
- responded: 0,
9594
- dismissed: 0,
9595
- deferred: 0,
9596
- contextExpanded: 0,
9597
- contextSkipped: 0,
9598
- timedOut: 0,
9599
- returned: 0,
9600
- attentionShifted: 0
9601
- };
9602
- const deferred = {
9603
- queued: 0,
9604
- suppressed: 0,
9605
- manual: 0
9606
- };
9607
- let responseLatencyTotal = 0;
9608
- let responseLatencyCount = 0;
9609
- let dismissalLatencyTotal = 0;
9610
- let dismissalLatencyCount = 0;
9611
- for (const signal of recentSignals) {
9612
- switch (signal.kind) {
9613
- case "presented":
9614
- counts.presented += 1;
9615
- break;
9616
- case "viewed":
9617
- counts.viewed += 1;
9618
- break;
9619
- case "responded":
9620
- counts.responded += 1;
9621
- if (signal.latencyMs !== void 0) {
9622
- responseLatencyTotal += signal.latencyMs;
9623
- responseLatencyCount += 1;
9624
- }
9625
- break;
9626
- case "dismissed":
9627
- counts.dismissed += 1;
9628
- if (signal.latencyMs !== void 0) {
9629
- dismissalLatencyTotal += signal.latencyMs;
9630
- dismissalLatencyCount += 1;
9631
- }
9632
- break;
9633
- case "deferred":
9634
- counts.deferred += 1;
9635
- if (signal.reason !== void 0) {
9636
- deferred[signal.reason] += 1;
9637
- }
9638
- break;
9639
- case "context_expanded":
9640
- counts.contextExpanded += 1;
9641
- break;
9642
- case "context_skipped":
9643
- counts.contextSkipped += 1;
9644
- break;
9645
- case "timed_out":
9646
- counts.timedOut += 1;
9647
- break;
9648
- case "returned":
9649
- counts.returned += 1;
9650
- break;
9651
- case "attention_shifted":
9652
- counts.attentionShifted += 1;
9653
- break;
9654
- }
9655
- }
9656
- return {
9657
- recentSignals: recentSignals.length,
9658
- lifetimeSignals: signals.length,
9659
- counts,
9660
- deferred,
9661
- responseRate: counts.presented > 0 ? counts.responded / counts.presented : 0,
9662
- dismissalRate: counts.presented > 0 ? counts.dismissed / counts.presented : 0,
9663
- averageResponseLatencyMs: responseLatencyCount > 0 ? Math.round(responseLatencyTotal / responseLatencyCount) : null,
9664
- averageDismissalLatencyMs: dismissalLatencyCount > 0 ? Math.round(dismissalLatencyTotal / dismissalLatencyCount) : null,
9665
- lastSignalAt: signals.length > 0 ? signals[signals.length - 1]?.timestamp ?? null : null
9666
- };
10381
+ return summarizeAttentionSignals(this.list(taskId));
9667
10382
  }
9668
10383
  recentSignals(signals) {
9669
10384
  const bounded = signals.slice(-32);
@@ -9685,6 +10400,106 @@ var AttentionSignalStore = class _AttentionSignalStore {
9685
10400
  return recent.length > 0 ? recent : bounded;
9686
10401
  }
9687
10402
  };
10403
+ var RECENT_WINDOW_MS = 30 * 60 * 1e3;
10404
+ function summarizeAttentionSignals(signals) {
10405
+ const recentSignals = recentAttentionSignals(signals);
10406
+ const counts = {
10407
+ presented: 0,
10408
+ viewed: 0,
10409
+ responded: 0,
10410
+ dismissed: 0,
10411
+ deferred: 0,
10412
+ contextExpanded: 0,
10413
+ contextSkipped: 0,
10414
+ timedOut: 0,
10415
+ returned: 0,
10416
+ attentionShifted: 0
10417
+ };
10418
+ const deferred = {
10419
+ next: 0,
10420
+ suppressed: 0,
10421
+ manual: 0
10422
+ };
10423
+ let responseLatencyTotal = 0;
10424
+ let responseLatencyCount = 0;
10425
+ let dismissalLatencyTotal = 0;
10426
+ let dismissalLatencyCount = 0;
10427
+ for (const signal of recentSignals) {
10428
+ switch (signal.kind) {
10429
+ case "presented":
10430
+ counts.presented += 1;
10431
+ break;
10432
+ case "viewed":
10433
+ counts.viewed += 1;
10434
+ break;
10435
+ case "responded":
10436
+ counts.responded += 1;
10437
+ if (signal.latencyMs !== void 0) {
10438
+ responseLatencyTotal += signal.latencyMs;
10439
+ responseLatencyCount += 1;
10440
+ }
10441
+ break;
10442
+ case "dismissed":
10443
+ counts.dismissed += 1;
10444
+ if (signal.latencyMs !== void 0) {
10445
+ dismissalLatencyTotal += signal.latencyMs;
10446
+ dismissalLatencyCount += 1;
10447
+ }
10448
+ break;
10449
+ case "deferred":
10450
+ counts.deferred += 1;
10451
+ if (signal.reason !== void 0) {
10452
+ deferred[signal.reason] += 1;
10453
+ }
10454
+ break;
10455
+ case "context_expanded":
10456
+ counts.contextExpanded += 1;
10457
+ break;
10458
+ case "context_skipped":
10459
+ counts.contextSkipped += 1;
10460
+ break;
10461
+ case "timed_out":
10462
+ counts.timedOut += 1;
10463
+ break;
10464
+ case "returned":
10465
+ counts.returned += 1;
10466
+ break;
10467
+ case "attention_shifted":
10468
+ counts.attentionShifted += 1;
10469
+ break;
10470
+ }
10471
+ }
10472
+ return {
10473
+ recentSignals: recentSignals.length,
10474
+ lifetimeSignals: signals.length,
10475
+ counts,
10476
+ deferred,
10477
+ responseRate: counts.presented > 0 ? counts.responded / counts.presented : 0,
10478
+ dismissalRate: counts.presented > 0 ? counts.dismissed / counts.presented : 0,
10479
+ averageResponseLatencyMs: responseLatencyCount > 0 ? Math.round(responseLatencyTotal / responseLatencyCount) : null,
10480
+ averageDismissalLatencyMs: dismissalLatencyCount > 0 ? Math.round(dismissalLatencyTotal / dismissalLatencyCount) : null,
10481
+ lastSignalAt: signals.length > 0 ? signals[signals.length - 1]?.timestamp ?? null : null
10482
+ };
10483
+ }
10484
+ function recentAttentionSignals(signals) {
10485
+ const bounded = signals.slice(-32);
10486
+ const latestTimestamp2 = bounded[bounded.length - 1]?.timestamp;
10487
+ if (latestTimestamp2 === void 0) {
10488
+ return bounded;
10489
+ }
10490
+ const latestMs = Date.parse(latestTimestamp2);
10491
+ if (Number.isNaN(latestMs)) {
10492
+ return bounded;
10493
+ }
10494
+ const recent = bounded.filter((signal) => {
10495
+ const signalMs = Date.parse(signal.timestamp);
10496
+ if (Number.isNaN(signalMs)) {
10497
+ return true;
10498
+ }
10499
+ return latestMs - signalMs <= RECENT_WINDOW_MS;
10500
+ });
10501
+ return recent.length > 0 ? recent : bounded;
10502
+ }
9688
10503
  async function readMarkdownFile(path2, fallback, parse) {
9689
10504
  try {
9690
10505
  const content = await readFile(path2, "utf8");
@@ -9782,9 +10597,14 @@ function parseJudgmentConfig(content) {
9782
10597
  continue;
9783
10598
  }
9784
10599
  if (section === "Policy" && ruleName) {
10600
+ const scalar = parseScalar(bullet.value);
10601
+ const key = normalizeJudgmentRuleKey(camelKey(bullet.key));
9785
10602
  policy.set(ruleName, {
9786
10603
  ...policy.get(ruleName) ?? {},
9787
- [camelKey(bullet.key)]: parseScalar(bullet.value)
10604
+ ...key === "minimumLane" ? (() => {
10605
+ const lane = readAttentionLane(scalar);
10606
+ return lane === void 0 ? {} : { minimumLane: lane };
10607
+ })() : { [key]: scalar }
9788
10608
  });
9789
10609
  continue;
9790
10610
  }
@@ -9823,6 +10643,14 @@ function parseJudgmentConfig(content) {
9823
10643
  ...plannerDefaults.size > 0 ? { plannerDefaults: Object.fromEntries(plannerDefaults.entries()) } : {}
9824
10644
  };
9825
10645
  }
10646
+ function normalizeJudgmentRuleKey(key) {
10647
+ switch (key) {
10648
+ case "minimumPresentation":
10649
+ return "minimumLane";
10650
+ default:
10651
+ return key;
10652
+ }
10653
+ }
9826
10654
  function readNumber2(value) {
9827
10655
  return value !== void 0 && /^-?\d+(?:\.\d+)?$/.test(value) ? Number(value) : null;
9828
10656
  }
@@ -9880,6 +10708,10 @@ function signalMetadataForFrame(frame) {
9880
10708
  if (key) {
9881
10709
  metadata.sourceKey = key;
9882
10710
  }
10711
+ const episode = frame.metadata?.episode;
10712
+ if (episode && typeof episode === "object" && !Array.isArray(episode)) {
10713
+ metadata.episode = episode;
10714
+ }
9883
10715
  return metadata;
9884
10716
  }
9885
10717
  function signalMetadataForCandidate(candidate) {
@@ -10149,7 +10981,13 @@ function inferSemanticInterpretation(event) {
10149
10981
  factors: ["task.started"],
10150
10982
  relationHints: [],
10151
10983
  confidence: "high",
10152
- reasons: semanticReasonsForLifecycle("task_started")
10984
+ reasons: semanticReasonsForLifecycle("task_started"),
10985
+ provenance: inferredSemanticProvenance([
10986
+ "intentFrame",
10987
+ "activityClass",
10988
+ "consequence",
10989
+ "confidence"
10990
+ ])
10153
10991
  };
10154
10992
  case "task.updated":
10155
10993
  return inferTaskUpdateSemantics(event);
@@ -10163,7 +11001,13 @@ function inferSemanticInterpretation(event) {
10163
11001
  factors: ["task.completed"],
10164
11002
  relationHints: [],
10165
11003
  confidence: "high",
10166
- reasons: semanticReasonsForLifecycle("completion")
11004
+ reasons: semanticReasonsForLifecycle("completion"),
11005
+ provenance: inferredSemanticProvenance([
11006
+ "intentFrame",
11007
+ "activityClass",
11008
+ "consequence",
11009
+ "confidence"
11010
+ ])
10167
11011
  };
10168
11012
  case "task.cancelled":
10169
11013
  return {
@@ -10174,7 +11018,16 @@ function inferSemanticInterpretation(event) {
10174
11018
  factors: ["task.cancelled"],
10175
11019
  relationHints: [],
10176
11020
  confidence: "high",
10177
- reasons: semanticReasonsForTaskStatus("completed", { wasCancelled: true })
11021
+ reasons: semanticReasonsForTaskStatus("completed", { wasCancelled: true }),
11022
+ provenance: {
11023
+ ...inferredSemanticProvenance([
11024
+ "intentFrame",
11025
+ "activityClass",
11026
+ "consequence",
11027
+ "confidence"
11028
+ ]),
11029
+ ...event.reason ? inferredSemanticProvenance(["whyNow"]) : {}
11030
+ }
10178
11031
  };
10179
11032
  }
10180
11033
  }
@@ -10183,19 +11036,69 @@ function inferTaskUpdateSemantics(event) {
10183
11036
  const impliedAsk = detectImpliedOperatorAsk(text);
10184
11037
  const relationHints = detectSemanticRelationHints(text);
10185
11038
  const taxonomyInput = buildTaxonomyInput(event.title, event.summary, event.toolFamily);
10186
- const toolFamily = readExplicitSemanticToolFamily(taxonomyInput) ?? inferSemanticToolFamily(taxonomyInput) ?? void 0;
11039
+ const { toolFamily, source: toolFamilySource } = resolveSemanticToolFamily(taxonomyInput, true);
11040
+ const relationProvenance = relationHints.length > 0 ? inferredSemanticProvenance(["relationHints"]) : {};
11041
+ const observationalFailure = event.status === "failed" && detectObservationalFailureStatus(text, toolFamily);
11042
+ const routineObservationalFailureLowConsequence = event.status === "failed" && detectRoutineObservationalFailureLowConsequence(text, toolFamily);
11043
+ const expectedDiagnosticFailure = event.status === "failed" && detectExpectedDiagnosticFailure(text, toolFamily);
10187
11044
  switch (event.status) {
10188
11045
  case "failed":
10189
- return {
10190
- intentFrame: "failure",
10191
- activityClass: "tool_failure",
11046
+ if (observationalFailure) {
11047
+ return {
11048
+ intentFrame: "status_update",
11049
+ activityClass: "status_update",
11050
+ ...toolFamily ? { toolFamily } : {},
11051
+ consequence: inferConsequenceFromSemanticText(
11052
+ text,
11053
+ routineObservationalFailureLowConsequence ? "low" : "high",
11054
+ toolFamily
11055
+ ),
11056
+ factors: ["task.updated", "failed", "observational_failure"],
11057
+ relationHints,
11058
+ confidence: "high",
11059
+ reasons: [
11060
+ "task status indicates failure but the update reads like observational output"
11061
+ ],
11062
+ provenance: {
11063
+ ...inferredSemanticProvenance([
11064
+ "intentFrame",
11065
+ "activityClass",
11066
+ "consequence",
11067
+ "confidence"
11068
+ ]),
11069
+ ...semanticToolFamilyProvenance(toolFamilySource),
11070
+ ...relationProvenance
11071
+ }
11072
+ };
11073
+ }
11074
+ return {
11075
+ intentFrame: "failure",
11076
+ activityClass: "tool_failure",
10192
11077
  ...toolFamily ? { toolFamily } : {},
10193
- consequence: inferConsequenceFromSemanticText(text, "high", toolFamily),
11078
+ consequence: inferConsequenceFromSemanticText(
11079
+ text,
11080
+ routineObservationalFailureLowConsequence ? "low" : expectedDiagnosticFailure ? "medium" : "high",
11081
+ toolFamily
11082
+ ),
10194
11083
  whyNow: semanticWhyNowForTaskStatus("failed") ?? "Work has failed and should be reviewed.",
10195
11084
  factors: ["task.updated", "failed"],
10196
11085
  relationHints,
10197
11086
  confidence: impliedAsk ? "medium" : "high",
10198
- reasons: semanticReasonsForTaskStatus("failed", { impliedAsk })
11087
+ reasons: expectedDiagnosticFailure ? [
11088
+ ...semanticReasonsForTaskStatus("failed", { impliedAsk }),
11089
+ "failure content looks like expected diagnostic output from repro work"
11090
+ ] : semanticReasonsForTaskStatus("failed", { impliedAsk }),
11091
+ provenance: {
11092
+ ...inferredSemanticProvenance([
11093
+ "intentFrame",
11094
+ "activityClass",
11095
+ "consequence",
11096
+ "whyNow",
11097
+ "confidence"
11098
+ ]),
11099
+ ...semanticToolFamilyProvenance(toolFamilySource),
11100
+ ...relationProvenance
11101
+ }
10199
11102
  };
10200
11103
  case "blocked":
10201
11104
  return {
@@ -10207,7 +11110,18 @@ function inferTaskUpdateSemantics(event) {
10207
11110
  factors: ["task.updated", "blocked"],
10208
11111
  relationHints,
10209
11112
  confidence: impliedAsk ? "medium" : "high",
10210
- reasons: semanticReasonsForTaskStatus("blocked", { impliedAsk })
11113
+ reasons: semanticReasonsForTaskStatus("blocked", { impliedAsk }),
11114
+ provenance: {
11115
+ ...inferredSemanticProvenance([
11116
+ "intentFrame",
11117
+ "activityClass",
11118
+ "consequence",
11119
+ "whyNow",
11120
+ "confidence"
11121
+ ]),
11122
+ ...semanticToolFamilyProvenance(toolFamilySource),
11123
+ ...relationProvenance
11124
+ }
10211
11125
  };
10212
11126
  case "running":
10213
11127
  case "waiting":
@@ -10224,17 +11138,32 @@ function inferTaskUpdateSemantics(event) {
10224
11138
  factors: ["task.updated", event.status],
10225
11139
  relationHints,
10226
11140
  confidence: impliedAsk ? "low" : "high",
10227
- reasons: semanticReasonsForTaskStatus(event.status, { impliedAsk })
11141
+ reasons: semanticReasonsForTaskStatus(event.status, { impliedAsk }),
11142
+ provenance: {
11143
+ ...inferredSemanticProvenance([
11144
+ "intentFrame",
11145
+ "activityClass",
11146
+ "consequence",
11147
+ "confidence"
11148
+ ]),
11149
+ ...semanticToolFamilyProvenance(toolFamilySource),
11150
+ ...impliedAsk ? inferredSemanticProvenance(["whyNow"]) : {},
11151
+ ...relationProvenance
11152
+ }
10228
11153
  };
10229
11154
  }
10230
11155
  }
10231
11156
  function inferHumanInputSemantics(event) {
10232
11157
  const taxonomyInput = buildTaxonomyInput(event.title, event.summary, event.toolFamily, event.context);
10233
- const toolFamily = readExplicitSemanticToolFamily(taxonomyInput) ?? inferSemanticToolFamily(taxonomyInput) ?? void 0;
11158
+ const { toolFamily, source: toolFamilySource } = resolveSemanticToolFamily(
11159
+ taxonomyInput,
11160
+ event.request.kind === "approval"
11161
+ );
10234
11162
  const text = normalizeSemanticText(`${event.title} ${event.summary}`);
10235
11163
  const relationHints = detectSemanticRelationHints(text);
10236
11164
  const baseConsequence = event.riskHint ?? consequenceFromRequestKind(event.request.kind, toolFamily);
10237
11165
  const consequence = inferConsequenceFromSemanticText(text, baseConsequence, toolFamily);
11166
+ const relationProvenance = relationHints.length > 0 ? inferredSemanticProvenance(["relationHints"]) : {};
10238
11167
  return {
10239
11168
  intentFrame: semanticIntentFrameForRequestKind(event.request.kind),
10240
11169
  activityClass: semanticActivityClassForRequestKind(event.request.kind),
@@ -10243,13 +11172,52 @@ function inferHumanInputSemantics(event) {
10243
11172
  whyNow: semanticWhyNowForRequestKind(event.request.kind, consequence),
10244
11173
  factors: ["human.input.requested", event.request.kind],
10245
11174
  relationHints,
10246
- confidence: event.riskHint ? "high" : toolFamily ? "medium" : "low",
11175
+ confidence: event.riskHint ? "high" : event.request.kind === "approval" && toolFamily ? "medium" : "low",
10247
11176
  reasons: [
10248
11177
  event.riskHint ? "source provided an explicit risk hint" : "request kind establishes an explicit operator decision point",
10249
- ...toolFamily ? ["tool family was inferred or supplied"] : []
10250
- ]
11178
+ ...toolFamilySource === "explicit" ? ["tool family was supplied by the source or context"] : toolFamilySource === "inferred" ? ["tool family was inferred from approval wording"] : []
11179
+ ],
11180
+ provenance: {
11181
+ ...inferredSemanticProvenance(["intentFrame", "activityClass", "whyNow"]),
11182
+ ...semanticToolFamilyProvenance(toolFamilySource),
11183
+ ...event.riskHint ? sourceSemanticProvenance(["consequence", "confidence"]) : inferredSemanticProvenance(["consequence", "confidence"]),
11184
+ ...relationProvenance
11185
+ }
10251
11186
  };
10252
11187
  }
11188
+ function inferredSemanticProvenance(fields) {
11189
+ return semanticFieldProvenance(fields, "inferred");
11190
+ }
11191
+ function sourceSemanticProvenance(fields) {
11192
+ return semanticFieldProvenance(fields, "source");
11193
+ }
11194
+ function semanticFieldProvenance(fields, kind) {
11195
+ return Object.fromEntries(fields.map((field) => [field, kind]));
11196
+ }
11197
+ function semanticToolFamilyProvenance(source) {
11198
+ switch (source) {
11199
+ case "explicit":
11200
+ return sourceSemanticProvenance(["toolFamily"]);
11201
+ case "inferred":
11202
+ return inferredSemanticProvenance(["toolFamily"]);
11203
+ default:
11204
+ return {};
11205
+ }
11206
+ }
11207
+ function resolveSemanticToolFamily(input, allowTextInference) {
11208
+ const explicit = readExplicitSemanticToolFamily(input);
11209
+ if (explicit) {
11210
+ return { toolFamily: explicit, source: "explicit" };
11211
+ }
11212
+ if (!allowTextInference) {
11213
+ return { source: "none" };
11214
+ }
11215
+ const inferred = inferSemanticToolFamily(input);
11216
+ if (inferred) {
11217
+ return { toolFamily: inferred, source: "inferred" };
11218
+ }
11219
+ return { source: "none" };
11220
+ }
10253
11221
  function applySemanticHints(inferred, hints) {
10254
11222
  if (!hints) {
10255
11223
  return inferred;
@@ -10259,7 +11227,23 @@ function applySemanticHints(inferred, hints) {
10259
11227
  ...pickDefined(hints),
10260
11228
  factors: dedupeSemanticStrings([...inferred.factors ?? [], ...hints.factors ?? []]),
10261
11229
  relationHints: [...hints.relationHints ?? inferred.relationHints],
10262
- reasons: dedupeSemanticStrings([...inferred.reasons ?? [], ...hints.reasons ?? []])
11230
+ reasons: dedupeSemanticStrings([...inferred.reasons ?? [], ...hints.reasons ?? []]),
11231
+ provenance: {
11232
+ ...inferred.provenance ?? {},
11233
+ ...hintedSemanticProvenance(hints)
11234
+ }
11235
+ };
11236
+ }
11237
+ function hintedSemanticProvenance(hints) {
11238
+ return {
11239
+ ...hints.intentFrame !== void 0 ? { intentFrame: "hint" } : {},
11240
+ ...hints.activityClass !== void 0 ? { activityClass: "hint" } : {},
11241
+ ...hints.toolFamily !== void 0 ? { toolFamily: "hint" } : {},
11242
+ ...hints.consequence !== void 0 ? { consequence: "hint" } : {},
11243
+ ...hints.whyNow !== void 0 ? { whyNow: "hint" } : {},
11244
+ ...hints.relationHints !== void 0 ? { relationHints: "hint" } : {},
11245
+ ...hints.confidence !== void 0 ? { confidence: "hint" } : {},
11246
+ ...hints.abstained !== void 0 ? { abstained: "hint" } : {}
10263
11247
  };
10264
11248
  }
10265
11249
  function pickDefined(value) {
@@ -10351,6 +11335,7 @@ function normalizeHumanInput(event, semantic) {
10351
11335
  base: event.provenance,
10352
11336
  semantic
10353
11337
  });
11338
+ const toolFamily = event.request.kind === "approval" ? event.toolFamily ?? semantic.toolFamily : void 0;
10354
11339
  return {
10355
11340
  id: event.id,
10356
11341
  type: event.type,
@@ -10358,7 +11343,7 @@ function normalizeHumanInput(event, semantic) {
10358
11343
  interactionId: event.interactionId,
10359
11344
  timestamp: event.timestamp,
10360
11345
  ...event.source !== void 0 ? { source: event.source } : {},
10361
- ...event.toolFamily !== void 0 ? { toolFamily: event.toolFamily } : semantic.toolFamily !== void 0 ? { toolFamily: semantic.toolFamily } : {},
11346
+ ...toolFamily !== void 0 ? { toolFamily } : {},
10362
11347
  ...event.activityClass !== void 0 ? { activityClass: event.activityClass } : semantic.activityClass !== void 0 ? { activityClass: semantic.activityClass } : {},
10363
11348
  semantic,
10364
11349
  title: event.title,
@@ -10433,9 +11418,14 @@ function parseUserProfile(content) {
10433
11418
  continue;
10434
11419
  }
10435
11420
  if (section === "Tool Overrides" && tool) {
11421
+ const scalar = parseScalar(bullet.value);
11422
+ const key = normalizeToolOverrideKey(camelKey2(bullet.key));
10436
11423
  toolOverrides.set(tool, {
10437
11424
  ...toolOverrides.get(tool) ?? {},
10438
- [camelKey2(bullet.key)]: parseScalar(bullet.value)
11425
+ ...key === "minimumLane" ? (() => {
11426
+ const lane = readAttentionLane(scalar);
11427
+ return lane === void 0 ? {} : { minimumLane: lane };
11428
+ })() : { [key]: scalar }
10439
11429
  });
10440
11430
  }
10441
11431
  }
@@ -10464,6 +11454,15 @@ function parseUserProfile(content) {
10464
11454
  } : {}
10465
11455
  };
10466
11456
  }
11457
+ function normalizeToolOverrideKey(key) {
11458
+ switch (key) {
11459
+ case "defaultPresentation":
11460
+ case "minimumPresentation":
11461
+ return "minimumLane";
11462
+ default:
11463
+ return key;
11464
+ }
11465
+ }
10467
11466
  function parseMemoryProfile(content) {
10468
11467
  const meta = /* @__PURE__ */ new Map();
10469
11468
  const toolFamilies = /* @__PURE__ */ new Map();
@@ -10629,33 +11628,33 @@ var TaskViewStore = class {
10629
11628
  taskViews = /* @__PURE__ */ new Map();
10630
11629
  get(taskId) {
10631
11630
  return this.taskViews.get(taskId) ?? {
10632
- active: null,
10633
- queued: [],
11631
+ now: null,
11632
+ next: [],
10634
11633
  ambient: []
10635
11634
  };
10636
11635
  }
10637
- setActive(taskId, frame) {
11636
+ setNow(taskId, frame) {
10638
11637
  const taskView = this.get(taskId);
10639
- const nextQueued = taskView.queued.filter((item2) => item2.interactionId !== frame.interactionId);
10640
- const previousActive = taskView.active && taskView.active.interactionId !== frame.interactionId ? taskView.active : null;
11638
+ const nextFrames = taskView.next.filter((item2) => item2.interactionId !== frame.interactionId);
11639
+ const previousNow = taskView.now && taskView.now.interactionId !== frame.interactionId ? taskView.now : null;
10641
11640
  const next = {
10642
- active: frame,
10643
- queued: previousActive ? [previousActive, ...nextQueued] : nextQueued,
11641
+ now: frame,
11642
+ next: previousNow ? [previousNow, ...nextFrames] : nextFrames,
10644
11643
  ambient: taskView.ambient.filter((item2) => item2.interactionId !== frame.interactionId)
10645
11644
  };
10646
11645
  this.taskViews.set(taskId, next);
10647
11646
  return next;
10648
11647
  }
10649
- enqueue(taskId, frame) {
10650
- return this.upsert(taskId, "queued", frame);
11648
+ addNext(taskId, frame) {
11649
+ return this.upsert(taskId, "next", frame);
10651
11650
  }
10652
11651
  addAmbient(taskId, frame) {
10653
11652
  return this.upsert(taskId, "ambient", frame);
10654
11653
  }
10655
11654
  clear(taskId) {
10656
11655
  const next = {
10657
- active: null,
10658
- queued: [],
11656
+ now: null,
11657
+ next: [],
10659
11658
  ambient: []
10660
11659
  };
10661
11660
  this.taskViews.set(taskId, next);
@@ -10664,8 +11663,8 @@ var TaskViewStore = class {
10664
11663
  discard(taskId, interactionId) {
10665
11664
  const taskView = this.get(taskId);
10666
11665
  const next = {
10667
- active: taskView.active?.interactionId === interactionId ? null : taskView.active,
10668
- queued: taskView.queued.filter((frame) => frame.interactionId !== interactionId),
11666
+ now: taskView.now?.interactionId === interactionId ? null : taskView.now,
11667
+ next: taskView.next.filter((frame) => frame.interactionId !== interactionId),
10669
11668
  ambient: taskView.ambient.filter((frame) => frame.interactionId !== interactionId)
10670
11669
  };
10671
11670
  this.taskViews.set(taskId, next);
@@ -10673,30 +11672,30 @@ var TaskViewStore = class {
10673
11672
  }
10674
11673
  resolve(taskId, interactionId) {
10675
11674
  const taskView = this.get(taskId);
10676
- const remainingQueued = taskView.queued.filter((frame) => frame.interactionId !== interactionId);
11675
+ const remainingNext = taskView.next.filter((frame) => frame.interactionId !== interactionId);
10677
11676
  const remainingAmbient = taskView.ambient.filter((frame) => frame.interactionId !== interactionId);
10678
- let nextActive = taskView.active;
10679
- if (nextActive?.interactionId === interactionId) {
10680
- nextActive = remainingQueued.shift() ?? null;
11677
+ let nextNow = taskView.now;
11678
+ if (nextNow?.interactionId === interactionId) {
11679
+ nextNow = remainingNext.shift() ?? null;
10681
11680
  }
10682
11681
  const next = {
10683
- active: nextActive,
10684
- queued: remainingQueued,
11682
+ now: nextNow,
11683
+ next: remainingNext,
10685
11684
  ambient: remainingAmbient
10686
11685
  };
10687
11686
  this.taskViews.set(taskId, next);
10688
11687
  return next;
10689
11688
  }
10690
- upsert(taskId, bucket, frame) {
11689
+ upsert(taskId, lane, frame) {
10691
11690
  const taskView = this.get(taskId);
10692
- const dedupedQueued = taskView.queued.filter((item2) => item2.interactionId !== frame.interactionId);
11691
+ const dedupedNext = taskView.next.filter((item2) => item2.interactionId !== frame.interactionId);
10693
11692
  const dedupedAmbient = taskView.ambient.filter((item2) => item2.interactionId !== frame.interactionId);
10694
- const demotingActive = taskView.active?.interactionId === frame.interactionId;
10695
- const nextActive = demotingActive ? dedupedQueued.shift() ?? null : taskView.active;
11693
+ const demotingNow = taskView.now?.interactionId === frame.interactionId;
11694
+ const nextNow = demotingNow ? dedupedNext.shift() ?? null : taskView.now;
10696
11695
  const next = {
10697
- active: nextActive,
10698
- queued: bucket === "queued" ? [frame, ...dedupedQueued] : dedupedQueued,
10699
- ambient: bucket === "ambient" ? [frame, ...dedupedAmbient] : dedupedAmbient
11696
+ now: nextNow,
11697
+ next: lane === "next" ? [frame, ...dedupedNext] : dedupedNext,
11698
+ ambient: lane === "ambient" ? [frame, ...dedupedAmbient] : dedupedAmbient
10700
11699
  };
10701
11700
  this.taskViews.set(taskId, next);
10702
11701
  return next;
@@ -10705,6 +11704,84 @@ var TaskViewStore = class {
10705
11704
  return this.taskViews.values();
10706
11705
  }
10707
11706
  };
11707
+ var APERTURE_INTERNAL_TRACE_SUBSCRIBE = /* @__PURE__ */ Symbol("aperture.internal.subscribeTrace");
11708
+ function isCandidateTraceLike(trace) {
11709
+ return trace.evaluation.kind === "candidate";
11710
+ }
11711
+ function isCandidateTrace(trace) {
11712
+ return isCandidateTraceLike(trace);
11713
+ }
11714
+ function toPublicApertureTrace(trace) {
11715
+ if (trace.evaluation.kind === "noop") {
11716
+ return {
11717
+ timestamp: trace.timestamp,
11718
+ event: trace.event,
11719
+ evaluation: { kind: "noop" }
11720
+ };
11721
+ }
11722
+ if (trace.evaluation.kind === "clear") {
11723
+ return {
11724
+ timestamp: trace.timestamp,
11725
+ event: trace.event,
11726
+ evaluation: {
11727
+ kind: "clear",
11728
+ taskId: trace.evaluation.taskId
11729
+ }
11730
+ };
11731
+ }
11732
+ if (!isCandidateTrace(trace)) {
11733
+ throw new Error("Unexpected internal trace variant");
11734
+ }
11735
+ return {
11736
+ timestamp: trace.timestamp,
11737
+ event: trace.event,
11738
+ evaluation: { kind: "candidate" },
11739
+ ...trace.semantic !== void 0 ? { semantic: trace.semantic } : {},
11740
+ policyRules: {
11741
+ gateEvaluations: trace.policyRules.gateEvaluations.map((evaluation) => ({
11742
+ rule: evaluation.rule,
11743
+ kind: evaluation.kind,
11744
+ rationale: [...evaluation.rationale]
11745
+ })),
11746
+ criterion: trace.policyRules.criterion ? {
11747
+ criterion: {
11748
+ activationThreshold: trace.policyRules.criterion.criterion.activationThreshold,
11749
+ promotionMargin: trace.policyRules.criterion.criterion.promotionMargin
11750
+ },
11751
+ peripheralResolution: trace.policyRules.criterion.peripheralResolution,
11752
+ ambiguity: trace.policyRules.criterion.ambiguity ? {
11753
+ kind: trace.policyRules.criterion.ambiguity.kind,
11754
+ reason: trace.policyRules.criterion.ambiguity.reason,
11755
+ resolution: trace.policyRules.criterion.ambiguity.resolution
11756
+ } : null,
11757
+ rationale: [...trace.policyRules.criterion.rationale]
11758
+ } : null,
11759
+ criterionEvaluations: trace.policyRules.criterionEvaluations.map((evaluation) => ({
11760
+ rule: evaluation.rule,
11761
+ kind: evaluation.kind,
11762
+ rationale: [...evaluation.rationale]
11763
+ }))
11764
+ },
11765
+ coordination: {
11766
+ kind: trace.coordination.kind,
11767
+ resultLane: trace.coordination.resultLane,
11768
+ candidateScore: trace.coordination.candidateScore,
11769
+ currentScore: trace.coordination.currentScore,
11770
+ currentPriority: trace.coordination.currentPriority,
11771
+ ambiguity: trace.coordination.ambiguity ? {
11772
+ kind: trace.coordination.ambiguity.kind,
11773
+ reason: trace.coordination.ambiguity.reason,
11774
+ resolution: trace.coordination.ambiguity.resolution
11775
+ } : null,
11776
+ reasons: [...trace.coordination.reasons],
11777
+ continuityEvaluations: trace.coordination.continuityEvaluations.map((evaluation) => ({
11778
+ rule: evaluation.rule,
11779
+ kind: evaluation.kind,
11780
+ rationale: [...evaluation.rationale]
11781
+ }))
11782
+ }
11783
+ };
11784
+ }
10708
11785
  var TraceRecorder = class {
10709
11786
  recordNoop(snapshot) {
10710
11787
  return {
@@ -10720,6 +11797,7 @@ var TraceRecorder = class {
10720
11797
  }
10721
11798
  recordCandidate(snapshot, input) {
10722
11799
  const { original, adjusted, explanation, result } = input;
11800
+ const semantic = buildSemanticSummary(snapshot.event, adjusted);
10723
11801
  return {
10724
11802
  ...snapshot,
10725
11803
  evaluation: {
@@ -10731,6 +11809,7 @@ var TraceRecorder = class {
10731
11809
  scoreOffset: adjusted.attentionScoreOffset ?? 0,
10732
11810
  rationale: adjusted.attentionRationale ?? []
10733
11811
  },
11812
+ ...semantic !== void 0 ? { semantic } : {},
10734
11813
  episode: buildEpisodeSummary(adjusted),
10735
11814
  policy: explanation.policy,
10736
11815
  policyRules: {
@@ -10750,7 +11829,7 @@ var TraceRecorder = class {
10750
11829
  },
10751
11830
  coordination: {
10752
11831
  kind: explanation.decision.kind,
10753
- resultBucket: findResultBucket(snapshot.attentionView, adjusted.taskId, adjusted.interactionId, explanation.decision.kind),
11832
+ resultLane: findResultLane(snapshot.attentionView, adjusted.taskId, adjusted.interactionId, explanation.decision.kind),
10754
11833
  candidateScore: explanation.candidateScore,
10755
11834
  currentScore: explanation.currentScore,
10756
11835
  currentPriority: explanation.currentPriority,
@@ -10780,15 +11859,173 @@ function buildEpisodeSummary(candidate) {
10780
11859
  updatedAt: candidate.timestamp
10781
11860
  };
10782
11861
  }
10783
- function findResultBucket(attentionView, taskId, interactionId, decisionKind) {
11862
+ function buildSemanticSummary(event, adjusted) {
11863
+ const semantic = event.semantic;
11864
+ if (!semantic) {
11865
+ return void 0;
11866
+ }
11867
+ return {
11868
+ intentFrame: semantic.intentFrame,
11869
+ ...semantic.activityClass !== void 0 ? { activityClass: semantic.activityClass } : {},
11870
+ ...semantic.toolFamily !== void 0 ? { toolFamily: semantic.toolFamily } : {},
11871
+ ...semantic.consequence !== void 0 ? { consequence: semantic.consequence } : {},
11872
+ ...semantic.confidence !== void 0 ? { confidence: semantic.confidence } : {},
11873
+ ...semantic.abstained === true ? { abstained: true } : {},
11874
+ ...semantic.whyNow !== void 0 ? { whyNow: semantic.whyNow } : {},
11875
+ relationHints: semantic.relationHints,
11876
+ factors: semantic.factors,
11877
+ reasons: semantic.reasons,
11878
+ influence: buildSemanticInfluence(event, adjusted),
11879
+ impact: buildSemanticImpact(event, adjusted),
11880
+ ...semantic.provenance !== void 0 ? { provenance: semantic.provenance } : {}
11881
+ };
11882
+ }
11883
+ function buildSemanticInfluence(event, adjusted) {
11884
+ const semantic = event.semantic;
11885
+ if (!semantic) {
11886
+ return [];
11887
+ }
11888
+ const influence = [];
11889
+ if (event.type === "task.updated") {
11890
+ influence.push("task status stayed authoritative; semantic details only affected context, continuity, and ambiguity handling");
11891
+ if ("activityClass" in event && event.activityClass === semantic.activityClass && semantic.activityClass !== void 0) {
11892
+ influence.push("activity class enriched canonical status facts");
11893
+ }
11894
+ if (event.toolFamily === semantic.toolFamily && semantic.toolFamily !== void 0) {
11895
+ influence.push("tool family enriched canonical status facts without changing the route");
11896
+ }
11897
+ if (semantic.relationHints.length > 0) {
11898
+ influence.push("relation hints informed continuity handling");
11899
+ }
11900
+ if (semantic.abstained === true) {
11901
+ influence.push("semantic abstention can keep non-blocking status work peripheral until clearer evidence arrives");
11902
+ } else if (semantic.confidence === "low") {
11903
+ influence.push("low semantic confidence can keep non-blocking status work peripheral until the signal is clearer");
11904
+ }
11905
+ return influence;
11906
+ }
11907
+ if (event.type === "human.input.requested") {
11908
+ if ("activityClass" in event && event.activityClass === semantic.activityClass && semantic.activityClass !== void 0) {
11909
+ influence.push("activity class was projected into the canonical request");
11910
+ }
11911
+ if (event.consequence === semantic.consequence && semantic.consequence !== void 0) {
11912
+ influence.push("semantic consequence set the canonical human-input consequence");
11913
+ }
11914
+ if (semantic.toolFamily !== void 0) {
11915
+ if (event.request.kind === "approval") {
11916
+ influence.push("tool family remained decision-bearing on the approval path");
11917
+ } else {
11918
+ influence.push("tool family stayed context-only on the question/form path");
11919
+ }
11920
+ }
11921
+ if (semantic.relationHints.length > 0) {
11922
+ influence.push("relation hints informed continuity handling");
11923
+ }
11924
+ if (semantic.abstained === true) {
11925
+ influence.push(
11926
+ adjusted.blocking ? "semantic abstention stayed visible but did not downgrade blocking work" : "semantic abstention constrained non-blocking routing"
11927
+ );
11928
+ } else if (semantic.confidence === "low") {
11929
+ influence.push(
11930
+ adjusted.blocking ? "semantic low confidence stayed visible but did not downgrade blocking work" : "low semantic confidence constrained non-blocking routing"
11931
+ );
11932
+ }
11933
+ if (influence.length === 0) {
11934
+ influence.push("semantic interpretation mostly stayed context-only beyond the explicit request");
11935
+ }
11936
+ return influence;
11937
+ }
11938
+ influence.push("semantic interpretation was recorded for explanation only");
11939
+ return influence;
11940
+ }
11941
+ function buildSemanticImpact(event, adjusted) {
11942
+ const semantic = event.semantic;
11943
+ const decisionBearing = /* @__PURE__ */ new Set();
11944
+ const explanatory = /* @__PURE__ */ new Set();
11945
+ if (!semantic) {
11946
+ return {
11947
+ decisionBearing: [],
11948
+ explanatory: []
11949
+ };
11950
+ }
11951
+ explanatory.add("intent");
11952
+ if (semantic.activityClass !== void 0) {
11953
+ explanatory.add("activity");
11954
+ }
11955
+ if (semantic.toolFamily !== void 0) {
11956
+ explanatory.add("tool");
11957
+ }
11958
+ if (semantic.consequence !== void 0) {
11959
+ explanatory.add("consequence");
11960
+ }
11961
+ if (semantic.whyNow !== void 0) {
11962
+ explanatory.add("why now");
11963
+ }
11964
+ if (semantic.relationHints.length > 0) {
11965
+ explanatory.add("relations");
11966
+ }
11967
+ if (semantic.confidence !== void 0) {
11968
+ explanatory.add("confidence");
11969
+ }
11970
+ if (semantic.abstained === true) {
11971
+ explanatory.add("abstention");
11972
+ }
11973
+ switch (event.type) {
11974
+ case "task.updated":
11975
+ if ("activityClass" in event && event.activityClass === semantic.activityClass && semantic.activityClass !== void 0) {
11976
+ promoteSemanticField(explanatory, decisionBearing, "activity", "activity (canonical)");
11977
+ }
11978
+ if (semantic.toolFamily !== void 0 && event.toolFamily === semantic.toolFamily) {
11979
+ promoteSemanticField(explanatory, decisionBearing, "tool", "tool (bounded)");
11980
+ }
11981
+ if (semantic.relationHints.length > 0) {
11982
+ promoteSemanticField(explanatory, decisionBearing, "relations", "relations (continuity)");
11983
+ }
11984
+ break;
11985
+ case "human.input.requested":
11986
+ if ("activityClass" in event && event.activityClass === semantic.activityClass && semantic.activityClass !== void 0) {
11987
+ promoteSemanticField(explanatory, decisionBearing, "activity", "activity (canonical)");
11988
+ }
11989
+ if (semantic.consequence !== void 0 && event.consequence === semantic.consequence) {
11990
+ promoteSemanticField(explanatory, decisionBearing, "consequence", "consequence (canonical)");
11991
+ }
11992
+ if (semantic.toolFamily !== void 0 && event.request.kind === "approval") {
11993
+ promoteSemanticField(explanatory, decisionBearing, "tool", "tool (approval path)");
11994
+ }
11995
+ if (semantic.relationHints.length > 0) {
11996
+ promoteSemanticField(explanatory, decisionBearing, "relations", "relations (continuity)");
11997
+ }
11998
+ break;
11999
+ default:
12000
+ if (semantic.relationHints.length > 0) {
12001
+ promoteSemanticField(explanatory, decisionBearing, "relations", "relations (continuity)");
12002
+ }
12003
+ break;
12004
+ }
12005
+ if (!adjusted.blocking && semantic.confidence === "low") {
12006
+ promoteSemanticField(explanatory, decisionBearing, "confidence", "confidence (ambiguity)");
12007
+ }
12008
+ if (!adjusted.blocking && semantic.abstained === true) {
12009
+ promoteSemanticField(explanatory, decisionBearing, "abstention", "abstention (ambiguity)");
12010
+ }
12011
+ return {
12012
+ decisionBearing: [...decisionBearing],
12013
+ explanatory: [...explanatory]
12014
+ };
12015
+ }
12016
+ function promoteSemanticField(explanatory, decisionBearing, fieldLabel, decisionLabel) {
12017
+ explanatory.delete(fieldLabel);
12018
+ decisionBearing.add(decisionLabel);
12019
+ }
12020
+ function findResultLane(attentionView, taskId, interactionId, decisionKind) {
10784
12021
  if (decisionKind === "auto_approve" || decisionKind === "clear") {
10785
12022
  return "none";
10786
12023
  }
10787
- if (attentionView.active && attentionView.active.taskId === taskId && attentionView.active.interactionId === interactionId) {
10788
- return "active";
12024
+ if (attentionView.now && attentionView.now.taskId === taskId && attentionView.now.interactionId === interactionId) {
12025
+ return "now";
10789
12026
  }
10790
- if (attentionView.queued.some((frame) => frame.taskId === taskId && frame.interactionId === interactionId)) {
10791
- return "queued";
12027
+ if (attentionView.next.some((frame) => frame.taskId === taskId && frame.interactionId === interactionId)) {
12028
+ return "next";
10792
12029
  }
10793
12030
  if (attentionView.ambient.some((frame) => frame.taskId === taskId && frame.interactionId === interactionId)) {
10794
12031
  return "ambient";
@@ -10802,6 +12039,7 @@ var ApertureCore = class _ApertureCore {
10802
12039
  responseListeners = /* @__PURE__ */ new Set();
10803
12040
  signalListeners = /* @__PURE__ */ new Set();
10804
12041
  traceListeners = /* @__PURE__ */ new Set();
12042
+ internalTraceListeners = /* @__PURE__ */ new Set();
10805
12043
  taskViews = new TaskViewStore();
10806
12044
  signals = new AttentionSignalStore();
10807
12045
  episodes = new EpisodeTracker();
@@ -10969,7 +12207,8 @@ var ApertureCore = class _ApertureCore {
10969
12207
  taskSummary,
10970
12208
  globalSummary
10971
12209
  ));
10972
- const explanation = this.coordinator.explain(evidence.currentFrame, candidate, evidence);
12210
+ const candidateEvidence = this.augmentContinuitySignalSummary(event.taskId, candidate, evidence);
12211
+ const explanation = this.coordinator.explain(evidence.currentFrame, candidate, candidateEvidence);
10973
12212
  let result;
10974
12213
  switch (explanation.decision.kind) {
10975
12214
  case "auto_approve":
@@ -10996,17 +12235,39 @@ var ApertureCore = class _ApertureCore {
10996
12235
  );
10997
12236
  break;
10998
12237
  case "activate":
10999
- result = explanation.decision.candidate.episodeId && this.findPeripheralEpisodeFrame(explanation.decision.candidate.episodeId, preAttentionView) ? this.materializePeripheralFrame(
12238
+ result = this.shouldRetireSupersededEpisodeFrames(
11000
12239
  explanation.decision.candidate,
11001
- selectPeripheralBucket(
11002
- explanation.decision.candidate,
11003
- explanation.policy,
11004
- evidence.surfaceCapabilities
11005
- ),
11006
12240
  preAttentionView
11007
- ) : this.commitFrame(this.applyResponseExpiry(
11008
- this.planner.plan(explanation.decision.candidate, evidence.currentFrame)
11009
- ));
12241
+ ) ? this.commitFrame(
12242
+ this.applyResponseExpiry(
12243
+ this.planner.plan(explanation.decision.candidate, evidence.currentFrame)
12244
+ ),
12245
+ this.findSupersededEpisodeFrames(
12246
+ explanation.decision.candidate,
12247
+ preAttentionView
12248
+ )
12249
+ ) : (() => {
12250
+ const existingPeripheralFrame = explanation.decision.candidate.episodeId ? this.findPeripheralEpisodeFrame(explanation.decision.candidate.episodeId, preAttentionView) : null;
12251
+ if (existingPeripheralFrame && this.shouldPromotePeripheralEpisodeFrame(explanation)) {
12252
+ return this.promotePeripheralEpisodeFrame(
12253
+ explanation.decision.candidate,
12254
+ existingPeripheralFrame.frame
12255
+ );
12256
+ }
12257
+ return existingPeripheralFrame ? this.materializePeripheralFrame(
12258
+ explanation.decision.candidate,
12259
+ selectPeripheralBucket(
12260
+ explanation.decision.candidate,
12261
+ explanation.policy,
12262
+ evidence.surfaceCapabilities
12263
+ ),
12264
+ preAttentionView
12265
+ ) : this.commitFrame(
12266
+ this.applyResponseExpiry(
12267
+ this.planner.plan(explanation.decision.candidate, evidence.currentFrame)
12268
+ )
12269
+ );
12270
+ })();
11010
12271
  break;
11011
12272
  }
11012
12273
  const postAttentionView = this.getAttentionView();
@@ -11033,7 +12294,7 @@ var ApertureCore = class _ApertureCore {
11033
12294
  }
11034
12295
  }
11035
12296
  getFrame(taskId) {
11036
- return this.taskViews.get(taskId).active ?? null;
12297
+ return this.taskViews.get(taskId).now ?? null;
11037
12298
  }
11038
12299
  subscribe(taskId, listener) {
11039
12300
  const listeners = this.frameListeners.get(taskId) ?? /* @__PURE__ */ new Set();
@@ -11084,6 +12345,12 @@ var ApertureCore = class _ApertureCore {
11084
12345
  this.traceListeners.delete(listener);
11085
12346
  };
11086
12347
  }
12348
+ [APERTURE_INTERNAL_TRACE_SUBSCRIBE](listener) {
12349
+ this.internalTraceListeners.add(listener);
12350
+ return () => {
12351
+ this.internalTraceListeners.delete(listener);
12352
+ };
12353
+ }
11087
12354
  submit(response) {
11088
12355
  this.assertValidFrameResponse(response);
11089
12356
  const current = this.findFrameByInteractionId(response.taskId, response.interactionId);
@@ -11096,15 +12363,15 @@ var ApertureCore = class _ApertureCore {
11096
12363
  `response for interaction ${response.interactionId} expired at ${expiredAt} and must be revalidated before submission`
11097
12364
  );
11098
12365
  }
12366
+ const previousAttentionView = this.getAttentionView();
11099
12367
  const timestamp = this.nowIso();
11100
12368
  this.recordSignal(this.signalForResponse(current, response, timestamp));
11101
12369
  this.episodes.resolveInteraction(response.interactionId);
11102
- const previousTaskView = this.taskViews.get(response.taskId);
11103
12370
  const taskView = this.taskViews.resolve(response.taskId, response.interactionId);
11104
- const newPrimary = taskView.active;
12371
+ const newPrimary = taskView.now;
12372
+ const nextAttentionView = this.getAttentionView();
12373
+ this.recordAttentionTransition(previousAttentionView, nextAttentionView, timestamp);
11105
12374
  if (newPrimary) {
11106
- this.recordAttentionShift(previousTaskView.active, newPrimary, timestamp);
11107
- this.recordReturnSignal(previousTaskView, newPrimary, timestamp);
11108
12375
  this.notifyFrame(response.taskId, newPrimary);
11109
12376
  } else {
11110
12377
  this.notifyFrame(response.taskId, null);
@@ -11196,12 +12463,27 @@ var ApertureCore = class _ApertureCore {
11196
12463
  listener(signal);
11197
12464
  }
11198
12465
  }
11199
- commitFrame(frame) {
11200
- const previousTaskView = this.taskViews.get(frame.taskId);
11201
- const previousActive = previousTaskView.active;
11202
- const taskView = this.taskViews.setActive(frame.taskId, frame);
11203
- this.recordAttentionShift(previousActive, frame, frame.timing.updatedAt);
11204
- this.recordReturnSignal(previousTaskView, frame, frame.timing.updatedAt);
12466
+ commitFrame(frame, retiredFrames = []) {
12467
+ const previousAttentionView = this.getAttentionView();
12468
+ const retiredKeys = /* @__PURE__ */ new Set();
12469
+ for (const retiredFrame of retiredFrames) {
12470
+ const key = `${retiredFrame.taskId}::${retiredFrame.interactionId}`;
12471
+ if (retiredKeys.has(key)) {
12472
+ continue;
12473
+ }
12474
+ retiredKeys.add(key);
12475
+ const retiredTaskView = this.taskViews.discard(
12476
+ retiredFrame.taskId,
12477
+ retiredFrame.interactionId
12478
+ );
12479
+ if (retiredFrame.taskId !== frame.taskId) {
12480
+ this.notifyFrame(retiredFrame.taskId, retiredTaskView.now);
12481
+ this.notifyTaskView(retiredFrame.taskId, retiredTaskView);
12482
+ }
12483
+ }
12484
+ const taskView = this.taskViews.setNow(frame.taskId, frame);
12485
+ const nextAttentionView = this.getAttentionView();
12486
+ this.recordAttentionTransition(previousAttentionView, nextAttentionView, frame.timing.updatedAt);
11205
12487
  this.recordSignal({
11206
12488
  kind: "presented",
11207
12489
  taskId: frame.taskId,
@@ -11230,6 +12512,7 @@ var ApertureCore = class _ApertureCore {
11230
12512
  currentEpisode: this.episodes.readFrameEpisode(currentFrame),
11231
12513
  attentionView,
11232
12514
  taskSignalSummary,
12515
+ continuitySignalSummary: taskSignalSummary,
11233
12516
  globalSignalSummary,
11234
12517
  taskAttentionState,
11235
12518
  globalAttentionState,
@@ -11238,30 +12521,39 @@ var ApertureCore = class _ApertureCore {
11238
12521
  }), this.timeSource());
11239
12522
  }
11240
12523
  applyClear(taskId) {
12524
+ const previousAttentionView = this.getAttentionView();
11241
12525
  const existingTaskView = this.taskViews.get(taskId);
11242
- const hadAnyVisibleState = existingTaskView.active !== null || existingTaskView.queued.length > 0 || existingTaskView.ambient.length > 0;
12526
+ const hadAnyVisibleState = existingTaskView.now !== null || existingTaskView.next.length > 0 || existingTaskView.ambient.length > 0;
11243
12527
  if (!hadAnyVisibleState) {
11244
12528
  return null;
11245
12529
  }
12530
+ for (const frame of [existingTaskView.now, ...existingTaskView.next, ...existingTaskView.ambient]) {
12531
+ if (!frame) {
12532
+ continue;
12533
+ }
12534
+ this.episodes.resolveInteraction(frame.interactionId);
12535
+ }
11246
12536
  const taskView = this.taskViews.clear(taskId);
12537
+ const nextAttentionView = this.getAttentionView();
12538
+ this.recordAttentionTransition(previousAttentionView, nextAttentionView, this.nowIso());
11247
12539
  this.notifyFrame(taskId, null);
11248
12540
  this.notifyTaskView(taskId, taskView);
11249
12541
  this.notifyAttentionView();
11250
12542
  return null;
11251
12543
  }
11252
12544
  queueFrame(taskId, frame) {
11253
- const taskView = this.taskViews.enqueue(taskId, frame);
11254
- this.recordDeferredSignal(frame, "queued");
12545
+ const taskView = this.taskViews.addNext(taskId, frame);
12546
+ this.recordDeferredSignal(frame, "next");
11255
12547
  this.notifyTaskView(taskId, taskView);
11256
12548
  this.notifyAttentionView();
11257
- return taskView.active ?? frame;
12549
+ return taskView.now ?? frame;
11258
12550
  }
11259
12551
  addAmbientFrame(taskId, frame) {
11260
12552
  const taskView = this.taskViews.addAmbient(taskId, frame);
11261
12553
  this.recordDeferredSignal(frame, "suppressed");
11262
12554
  this.notifyTaskView(taskId, taskView);
11263
12555
  this.notifyAttentionView();
11264
- return taskView.active ?? frame;
12556
+ return taskView.now ?? frame;
11265
12557
  }
11266
12558
  materializePeripheralFrame(candidate, bucket, attentionView) {
11267
12559
  const existing = candidate.episodeId ? this.findPeripheralEpisodeFrame(candidate.episodeId, attentionView) : null;
@@ -11277,15 +12569,38 @@ var ApertureCore = class _ApertureCore {
11277
12569
  };
11278
12570
  const previousTaskView = this.taskViews.discard(existing.frame.taskId, existing.frame.interactionId);
11279
12571
  this.notifyTaskView(existing.frame.taskId, previousTaskView);
11280
- const nextTaskView = nextBucket === "queue" ? this.taskViews.enqueue(merged.taskId, merged) : this.taskViews.addAmbient(merged.taskId, merged);
11281
- this.recordDeferredSignal(merged, nextBucket === "queue" ? "queued" : "suppressed", candidate);
12572
+ const nextTaskView = nextBucket === "queue" ? this.taskViews.addNext(merged.taskId, merged) : this.taskViews.addAmbient(merged.taskId, merged);
12573
+ this.recordDeferredSignal(merged, nextBucket === "queue" ? "next" : "suppressed", candidate);
11282
12574
  this.notifyTaskView(merged.taskId, nextTaskView);
11283
12575
  this.notifyAttentionView();
11284
12576
  return merged;
11285
12577
  }
12578
+ promotePeripheralEpisodeFrame(candidate, existingFrame) {
12579
+ const planned = this.applyResponseExpiry(this.planner.plan(candidate, existingFrame));
12580
+ const promoted = {
12581
+ ...planned,
12582
+ id: existingFrame.id
12583
+ };
12584
+ return this.commitFrame(promoted, [existingFrame]);
12585
+ }
11286
12586
  findFrameByInteractionId(taskId, interactionId) {
11287
12587
  return this.findFrame(taskId, interactionId);
11288
12588
  }
12589
+ shouldRetireSupersededEpisodeFrames(candidate, attentionView) {
12590
+ return this.findSupersededEpisodeFrames(candidate, attentionView).length > 0;
12591
+ }
12592
+ findSupersededEpisodeFrames(candidate, attentionView) {
12593
+ if (!candidate.episodeId || !hasSemanticRelationKind(candidate.relationHints, "supersedes")) {
12594
+ return [];
12595
+ }
12596
+ return [
12597
+ attentionView.now,
12598
+ ...attentionView.next,
12599
+ ...attentionView.ambient
12600
+ ].filter(
12601
+ (frame) => frame !== null && frame.interactionId !== candidate.interactionId && readFrameEpisodeId(frame) === candidate.episodeId && !isDormantEpisodeState(readFrameEpisodeState(frame))
12602
+ );
12603
+ }
11289
12604
  applyResponseExpiry(frame) {
11290
12605
  if (this.responseExpiryMs === void 0 || frame.responseSpec?.kind === "none") {
11291
12606
  return frame;
@@ -11315,16 +12630,52 @@ var ApertureCore = class _ApertureCore {
11315
12630
  return expiresAt;
11316
12631
  }
11317
12632
  findPeripheralEpisodeFrame(episodeId, attentionView) {
11318
- const queued = attentionView.queued.find((frame) => readFrameEpisodeId(frame) === episodeId);
12633
+ const queued = attentionView.next.find(
12634
+ (frame) => readFrameEpisodeId(frame) === episodeId && !isDormantEpisodeState(readFrameEpisodeState(frame))
12635
+ );
11319
12636
  if (queued) {
11320
12637
  return { frame: queued, bucket: "queue" };
11321
12638
  }
11322
- const ambient = attentionView.ambient.find((frame) => readFrameEpisodeId(frame) === episodeId);
12639
+ const ambient = attentionView.ambient.find(
12640
+ (frame) => readFrameEpisodeId(frame) === episodeId && !isDormantEpisodeState(readFrameEpisodeState(frame))
12641
+ );
11323
12642
  if (ambient) {
11324
12643
  return { frame: ambient, bucket: "ambient" };
11325
12644
  }
11326
12645
  return null;
11327
12646
  }
12647
+ augmentContinuitySignalSummary(taskId, candidate, evidence) {
12648
+ const continuitySignalSummary = this.resolveContinuitySignalSummary(taskId, candidate, evidence.taskSignalSummary);
12649
+ if (continuitySignalSummary === evidence.taskSignalSummary) {
12650
+ return evidence;
12651
+ }
12652
+ return {
12653
+ ...evidence,
12654
+ continuitySignalSummary
12655
+ };
12656
+ }
12657
+ resolveContinuitySignalSummary(taskId, candidate, taskSignalSummary) {
12658
+ if (!candidate.episodeId) {
12659
+ return taskSignalSummary;
12660
+ }
12661
+ const taskSignals = this.signals.list(taskId);
12662
+ const relatedEpisodeSignals = this.signals.list().filter(
12663
+ (signal) => signal.taskId !== taskId && readSignalEpisodeId(signal) === candidate.episodeId
12664
+ );
12665
+ if (relatedEpisodeSignals.length === 0) {
12666
+ return taskSignalSummary;
12667
+ }
12668
+ return summarizeAttentionSignals(
12669
+ [...taskSignals, ...relatedEpisodeSignals].sort(
12670
+ (left, right) => left.timestamp.localeCompare(right.timestamp)
12671
+ )
12672
+ );
12673
+ }
12674
+ shouldPromotePeripheralEpisodeFrame(explanation) {
12675
+ return explanation.continuityEvaluations?.some(
12676
+ (evaluation) => evaluation.rule === "deferral_escalation" && evaluation.kind === "override" && evaluation.decision?.kind === "activate"
12677
+ ) ?? false;
12678
+ }
11328
12679
  recordDeferredSignal(frame, reason, sourceFrame = frame) {
11329
12680
  this.recordSignal({
11330
12681
  kind: "deferred",
@@ -11354,9 +12705,13 @@ var ApertureCore = class _ApertureCore {
11354
12705
  }
11355
12706
  }
11356
12707
  notifyTrace(trace) {
11357
- for (const listener of this.traceListeners) {
12708
+ for (const listener of this.internalTraceListeners) {
11358
12709
  listener(trace);
11359
12710
  }
12711
+ const publicTrace = toPublicApertureTrace(trace);
12712
+ for (const listener of this.traceListeners) {
12713
+ listener(publicTrace);
12714
+ }
11360
12715
  }
11361
12716
  signalForResponse(frame, response, timestamp) {
11362
12717
  const latencyMs = this.calculateLatency(frame, timestamp);
@@ -11410,8 +12765,17 @@ var ApertureCore = class _ApertureCore {
11410
12765
  }
11411
12766
  return Math.max(0, completedAt - startedAt);
11412
12767
  }
12768
+ recordAttentionTransition(previousAttentionView, nextAttentionView, timestamp) {
12769
+ const previous = previousAttentionView.now;
12770
+ const next = nextAttentionView.now;
12771
+ if (!next) {
12772
+ return;
12773
+ }
12774
+ this.recordAttentionShift(previous, next, timestamp);
12775
+ this.recordReturnSignal(previousAttentionView, next, timestamp);
12776
+ }
11413
12777
  recordAttentionShift(previous, next, timestamp) {
11414
- if (!previous || previous.interactionId === next.interactionId) {
12778
+ if (!previous || sameFrame(previous, next)) {
11415
12779
  return;
11416
12780
  }
11417
12781
  const destinationSignal = {
@@ -11438,8 +12802,8 @@ var ApertureCore = class _ApertureCore {
11438
12802
  });
11439
12803
  }
11440
12804
  }
11441
- recordReturnSignal(previousTaskView, next, timestamp) {
11442
- const from = previousTaskView.queued.some((frame) => frame.interactionId === next.interactionId) ? "queued" : previousTaskView.ambient.some((frame) => frame.interactionId === next.interactionId) ? "ambient" : null;
12805
+ recordReturnSignal(previousAttentionView, next, timestamp) {
12806
+ const from = previousAttentionView.next.some((frame) => sameFrame(frame, next)) ? "next" : previousAttentionView.ambient.some((frame) => sameFrame(frame, next)) ? "ambient" : null;
11443
12807
  if (!from) {
11444
12808
  return;
11445
12809
  }
@@ -11450,7 +12814,8 @@ var ApertureCore = class _ApertureCore {
11450
12814
  timestamp,
11451
12815
  frameId: next.id,
11452
12816
  ...next.source !== void 0 ? { source: next.source } : {},
11453
- from
12817
+ from,
12818
+ metadata: signalMetadataForFrame(next)
11454
12819
  });
11455
12820
  }
11456
12821
  observationSignal(kind, taskId, interactionId, frame, options) {
@@ -11467,10 +12832,10 @@ var ApertureCore = class _ApertureCore {
11467
12832
  }
11468
12833
  findFrame(taskId, interactionId) {
11469
12834
  const taskView = this.taskViews.get(taskId);
11470
- if (taskView.active?.interactionId === interactionId) {
11471
- return taskView.active;
12835
+ if (taskView.now?.interactionId === interactionId) {
12836
+ return taskView.now;
11472
12837
  }
11473
- const queued = taskView.queued.find((frame) => frame.interactionId === interactionId);
12838
+ const queued = taskView.next.find((frame) => frame.interactionId === interactionId);
11474
12839
  if (queued) {
11475
12840
  return queued;
11476
12841
  }
@@ -11606,6 +12971,17 @@ var ApertureCore = class _ApertureCore {
11606
12971
  }
11607
12972
  }
11608
12973
  };
12974
+ function readSignalEpisodeId(signal) {
12975
+ const episode = signal.metadata?.episode;
12976
+ if (!episode || typeof episode !== "object" || Array.isArray(episode)) {
12977
+ return null;
12978
+ }
12979
+ const id = episode.id;
12980
+ return typeof id === "string" && id.length > 0 ? id : null;
12981
+ }
12982
+ function sameFrame(left, right) {
12983
+ return left.id === right.id || left.taskId === right.taskId && left.interactionId === right.interactionId;
12984
+ }
11609
12985
 
11610
12986
  // src/aperture/types.ts
11611
12987
  function toStoredFrame(frame) {
@@ -11632,12 +13008,12 @@ function createEmptySnapshot(companyId) {
11632
13008
  return {
11633
13009
  companyId,
11634
13010
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11635
- active: null,
11636
- queued: [],
13011
+ now: null,
13012
+ next: [],
11637
13013
  ambient: [],
11638
13014
  counts: {
11639
- active: 0,
11640
- queued: 0,
13015
+ now: 0,
13016
+ next: 0,
11641
13017
  ambient: 0,
11642
13018
  total: 0
11643
13019
  }
@@ -11654,26 +13030,82 @@ function createEmptyReviewState(companyId) {
11654
13030
  };
11655
13031
  }
11656
13032
  function createAttentionSnapshot(companyId, view, lastEvent, updatedAt) {
11657
- const active = toStoredFrame(view.active);
11658
- const queued = view.queued.map((frame) => toStoredFrame(frame)).filter((frame) => frame !== null);
13033
+ const legacyView = view;
13034
+ const now = toStoredFrame("now" in view ? view.now : legacyView.active ?? null);
13035
+ const next = ("next" in view ? view.next : legacyView.queued ?? []).map((frame) => toStoredFrame(frame)).filter((frame) => frame !== null);
11659
13036
  const ambient = view.ambient.map((frame) => toStoredFrame(frame)).filter((frame) => frame !== null);
11660
13037
  return {
11661
13038
  companyId,
11662
13039
  updatedAt: updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
11663
- active,
11664
- queued,
13040
+ now,
13041
+ next,
11665
13042
  ambient,
11666
13043
  counts: {
11667
- active: active ? 1 : 0,
11668
- queued: queued.length,
13044
+ now: now ? 1 : 0,
13045
+ next: next.length,
11669
13046
  ambient: ambient.length,
11670
- total: (active ? 1 : 0) + queued.length + ambient.length
13047
+ total: (now ? 1 : 0) + next.length + ambient.length
11671
13048
  },
11672
13049
  ...lastEvent ? { lastEvent } : {}
11673
13050
  };
11674
13051
  }
13052
+ function asRecord(value) {
13053
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
13054
+ }
13055
+ function asStoredFrame(value) {
13056
+ const frame = asRecord(value);
13057
+ if (!frame) return null;
13058
+ return typeof frame.taskId === "string" && typeof frame.interactionId === "string" ? frame : null;
13059
+ }
13060
+ function asStoredFrames(value) {
13061
+ if (!Array.isArray(value)) return [];
13062
+ return value.map(asStoredFrame).filter((frame) => frame !== null);
13063
+ }
13064
+ function normalizeAttentionSnapshot(companyId, value) {
13065
+ const snapshot = asRecord(value);
13066
+ if (!snapshot) return null;
13067
+ if (snapshot.companyId !== companyId || typeof snapshot.updatedAt !== "string") return null;
13068
+ const legacyCounts = asRecord(snapshot.counts);
13069
+ const review = asRecord(snapshot.review);
13070
+ const unread = asRecord(review?.unread);
13071
+ const now = asStoredFrame(snapshot.now ?? snapshot.active ?? null);
13072
+ const next = asStoredFrames(snapshot.next ?? snapshot.queued ?? []);
13073
+ const ambient = asStoredFrames(snapshot.ambient);
13074
+ return {
13075
+ companyId,
13076
+ updatedAt: snapshot.updatedAt,
13077
+ now,
13078
+ next,
13079
+ ambient,
13080
+ counts: {
13081
+ now: typeof legacyCounts?.now === "number" ? legacyCounts.now : typeof legacyCounts?.active === "number" ? legacyCounts.active : now ? 1 : 0,
13082
+ next: typeof legacyCounts?.next === "number" ? legacyCounts.next : typeof legacyCounts?.queued === "number" ? legacyCounts.queued : next.length,
13083
+ ambient: typeof legacyCounts?.ambient === "number" ? legacyCounts.ambient : ambient.length,
13084
+ total: typeof legacyCounts?.total === "number" ? legacyCounts.total : (now ? 1 : 0) + next.length + ambient.length
13085
+ },
13086
+ ...review ? {
13087
+ review: {
13088
+ ...typeof review.lastSeenAt === "string" ? { lastSeenAt: review.lastSeenAt } : {},
13089
+ unread: {
13090
+ now: typeof unread?.now === "number" ? unread.now : typeof unread?.active === "number" ? unread.active : 0,
13091
+ next: typeof unread?.next === "number" ? unread.next : typeof unread?.queued === "number" ? unread.queued : 0,
13092
+ ambient: typeof unread?.ambient === "number" ? unread.ambient : 0,
13093
+ total: typeof unread?.total === "number" ? unread.total : 0
13094
+ }
13095
+ }
13096
+ } : {},
13097
+ ...asRecord(snapshot.lastEvent) ? {
13098
+ lastEvent: {
13099
+ eventType: String(snapshot.lastEvent.eventType),
13100
+ ...typeof snapshot.lastEvent.entityId === "string" ? { entityId: snapshot.lastEvent.entityId } : {},
13101
+ ...typeof snapshot.lastEvent.entityType === "string" ? { entityType: snapshot.lastEvent.entityType } : {}
13102
+ }
13103
+ } : {}
13104
+ };
13105
+ }
11675
13106
 
11676
13107
  // src/aperture/core-store.ts
13108
+ var MAX_TRACE_HISTORY = 100;
11677
13109
  var ApertureCompanyStore = class {
11678
13110
  sessions = /* @__PURE__ */ new Map();
11679
13111
  ingest(companyId, event, source) {
@@ -11695,6 +13127,9 @@ var ApertureCompanyStore = class {
11695
13127
  getLedger(companyId) {
11696
13128
  return [...this.sessions.get(companyId)?.ledger ?? []];
11697
13129
  }
13130
+ getTraces(companyId) {
13131
+ return [...this.sessions.get(companyId)?.traces ?? []];
13132
+ }
11698
13133
  appendLedgerEntry(companyId, entry) {
11699
13134
  const session = this.ensureSession(companyId);
11700
13135
  session.ledger = [...session.ledger, entry];
@@ -11748,12 +13183,8 @@ var ApertureCompanyStore = class {
11748
13183
  return this.getLedger(companyId);
11749
13184
  }
11750
13185
  rebuildFromLedger(companyId, ledger) {
11751
- const session = {
11752
- core: new ApertureCore(),
11753
- snapshot: null,
11754
- ledger: [...ledger],
11755
- eventCount: 0
11756
- };
13186
+ const session = this.createSession();
13187
+ session.ledger = [...ledger];
11757
13188
  let lastSource;
11758
13189
  let lastOccurredAt;
11759
13190
  for (const entry of ledger) {
@@ -11776,13 +13207,22 @@ var ApertureCompanyStore = class {
11776
13207
  ensureSession(companyId) {
11777
13208
  let session = this.sessions.get(companyId);
11778
13209
  if (session) return session;
11779
- session = {
11780
- core: new ApertureCore(),
13210
+ session = this.createSession();
13211
+ this.sessions.set(companyId, session);
13212
+ return session;
13213
+ }
13214
+ createSession() {
13215
+ const core = new ApertureCore();
13216
+ const session = {
13217
+ core,
11781
13218
  snapshot: null,
11782
13219
  ledger: createEmptyLedger(),
11783
- eventCount: 0
13220
+ eventCount: 0,
13221
+ traces: []
11784
13222
  };
11785
- this.sessions.set(companyId, session);
13223
+ core.onTrace((trace) => {
13224
+ session.traces = [...session.traces.slice(-(MAX_TRACE_HISTORY - 1)), trace];
13225
+ });
11786
13226
  return session;
11787
13227
  }
11788
13228
  };
@@ -11834,6 +13274,37 @@ function emitAttentionUpdate(ctx, event) {
11834
13274
  ctx.streams.open(ATTENTION_UPDATES_STREAM, event.companyId);
11835
13275
  ctx.streams.emit(ATTENTION_UPDATES_STREAM, event);
11836
13276
  }
13277
+ async function trackFocusTelemetry(ctx, eventName, dimensions) {
13278
+ try {
13279
+ await ctx.telemetry.track(eventName, {
13280
+ surface: "focus",
13281
+ ...dimensions ?? {}
13282
+ });
13283
+ } catch (error) {
13284
+ ctx.logger.warn("Failed to emit Focus telemetry", {
13285
+ eventName,
13286
+ error: error instanceof Error ? error.message : String(error)
13287
+ });
13288
+ }
13289
+ }
13290
+ async function logFocusActivity(ctx, entry) {
13291
+ try {
13292
+ await ctx.activity.log({
13293
+ companyId: entry.companyId,
13294
+ message: entry.message,
13295
+ ...entry.entityType ? { entityType: entry.entityType } : {},
13296
+ ...entry.entityId ? { entityId: entry.entityId } : {},
13297
+ ...entry.metadata ? { metadata: entry.metadata } : {}
13298
+ });
13299
+ } catch (error) {
13300
+ ctx.logger.warn("Failed to write Focus activity log entry", {
13301
+ message: entry.message,
13302
+ entityType: entry.entityType,
13303
+ entityId: entry.entityId,
13304
+ error: error instanceof Error ? error.message : String(error)
13305
+ });
13306
+ }
13307
+ }
11837
13308
  async function runAttentionMutation(ctx, store, companyId, mutation) {
11838
13309
  const prior = companyMutationQueue.get(companyId) ?? Promise.resolve();
11839
13310
  let release;
@@ -11922,12 +13393,46 @@ function buildSeenReviewState(review, companyId, taskIds, suppress = false) {
11922
13393
  function snapshotContainsTask(snapshot, taskId) {
11923
13394
  if (!snapshot) return false;
11924
13395
  const frames = [
11925
- ...snapshot.active ? [snapshot.active] : [],
11926
- ...snapshot.queued,
13396
+ ...snapshot.now ? [snapshot.now] : [],
13397
+ ...snapshot.next,
11927
13398
  ...snapshot.ambient
11928
13399
  ];
11929
13400
  return frames.some((frame) => frame.taskId === taskId);
11930
13401
  }
13402
+ function entityTypeFromTaskId(taskId) {
13403
+ const separatorIndex = taskId.indexOf(":");
13404
+ return separatorIndex > 0 ? taskId.slice(0, separatorIndex) : "unknown";
13405
+ }
13406
+ function defaultCounts() {
13407
+ return {
13408
+ now: 0,
13409
+ next: 0,
13410
+ ambient: 0,
13411
+ total: 0
13412
+ };
13413
+ }
13414
+ function laneForTask(snapshot, taskId) {
13415
+ if (!snapshot) return "ui_only";
13416
+ if (snapshot.now?.taskId === taskId) return "now";
13417
+ if (snapshot.next.some((frame) => frame.taskId === taskId)) return "next";
13418
+ if (snapshot.ambient.some((frame) => frame.taskId === taskId)) return "ambient";
13419
+ return "ui_only";
13420
+ }
13421
+ function focusDimensions(snapshot, taskId) {
13422
+ const lane = laneForTask(snapshot, taskId);
13423
+ const entityType = entityTypeFromTaskId(taskId);
13424
+ const frame = lane === "ui_only" ? null : lane === "now" ? snapshot?.now ?? null : lane === "next" ? snapshot?.next.find((candidate) => candidate.taskId === taskId) ?? null : snapshot?.ambient.find((candidate) => candidate.taskId === taskId) ?? null;
13425
+ return {
13426
+ entityType,
13427
+ lane,
13428
+ ...frame?.mode ? { mode: frame.mode } : {},
13429
+ ...frame?.source?.kind ? { sourceKind: frame.source.kind } : {},
13430
+ ...typeof frame?.metadata?.liveReconciled === "boolean" ? { liveReconciled: frame.metadata.liveReconciled } : {}
13431
+ };
13432
+ }
13433
+ function approvalIdFromTaskId(taskId) {
13434
+ return taskId.startsWith("approval:") ? taskId.slice("approval:".length) : null;
13435
+ }
11931
13436
  function registerActionHandlers(ctx, store) {
11932
13437
  ctx.actions.register("acknowledge-frame", async (params) => {
11933
13438
  const companyId = requireCompanyId(params);
@@ -11944,6 +13449,7 @@ function registerActionHandlers(ctx, store) {
11944
13449
  },
11945
13450
  apertureResponse: response
11946
13451
  };
13452
+ const currentSnapshot = store.getSnapshot(companyId);
11947
13453
  const currentReview = await loadReviewState(ctx, companyId);
11948
13454
  const review = buildSeenReviewState(currentReview, companyId, [taskId], true);
11949
13455
  const { snapshot } = await runAttentionMutation(ctx, store, companyId, () => {
@@ -11957,6 +13463,9 @@ function registerActionHandlers(ctx, store) {
11957
13463
  updatedAt: snapshot.updatedAt,
11958
13464
  counts: snapshot.counts
11959
13465
  });
13466
+ await trackFocusTelemetry(ctx, "frame_acknowledged", {
13467
+ ...focusDimensions(currentSnapshot, taskId)
13468
+ });
11960
13469
  return { ok: true, snapshot };
11961
13470
  });
11962
13471
  ctx.actions.register("comment-on-issue", async (params) => {
@@ -11972,6 +13481,7 @@ function registerActionHandlers(ctx, store) {
11972
13481
  throw new Error("Issue comment target does not match the selected frame.");
11973
13482
  }
11974
13483
  const comment = await ctx.issues.createComment(issueId, body, companyId);
13484
+ const currentSnapshot = store.getSnapshot(companyId);
11975
13485
  const currentReview = await loadReviewState(ctx, companyId);
11976
13486
  const review = buildSeenReviewState(currentReview, companyId, [taskId], false);
11977
13487
  await persistReviewState(ctx, companyId, review);
@@ -11980,11 +13490,20 @@ function registerActionHandlers(ctx, store) {
11980
13490
  reason: "action",
11981
13491
  eventType: "plugin.local.comment",
11982
13492
  updatedAt: review.updatedAt,
11983
- counts: store.getSnapshot(companyId)?.counts ?? {
11984
- active: 0,
11985
- queued: 0,
11986
- ambient: 0,
11987
- total: 0
13493
+ counts: store.getSnapshot(companyId)?.counts ?? defaultCounts()
13494
+ });
13495
+ await trackFocusTelemetry(ctx, "issue_comment_submitted", {
13496
+ ...focusDimensions(currentSnapshot, taskId),
13497
+ actionKind: "comment"
13498
+ });
13499
+ await logFocusActivity(ctx, {
13500
+ companyId,
13501
+ message: "Posted an issue comment from Focus.",
13502
+ entityType: "issue",
13503
+ entityId: issueId,
13504
+ metadata: {
13505
+ source: "focus",
13506
+ taskId
11988
13507
  }
11989
13508
  });
11990
13509
  return { ok: true, comment, review };
@@ -12037,6 +13556,21 @@ function registerActionHandlers(ctx, store) {
12037
13556
  updatedAt: snapshot.updatedAt,
12038
13557
  counts: snapshot.counts
12039
13558
  });
13559
+ await trackFocusTelemetry(ctx, "approval_response_recorded", {
13560
+ ...focusDimensions(currentSnapshot, taskId),
13561
+ decision: decision === "request-revision" ? "request_revision" : decision
13562
+ });
13563
+ await logFocusActivity(ctx, {
13564
+ companyId,
13565
+ message: decision === "approve" ? "Approved a Focus approval." : decision === "reject" ? "Rejected a Focus approval." : "Requested revision on a Focus approval.",
13566
+ entityType: "approval",
13567
+ entityId: approvalIdFromTaskId(taskId) ?? taskId,
13568
+ metadata: {
13569
+ source: "focus",
13570
+ decision,
13571
+ taskId
13572
+ }
13573
+ });
12040
13574
  return { ok: true, snapshot, review };
12041
13575
  });
12042
13576
  ctx.actions.register("mark-attention-seen", async (params) => {
@@ -12053,12 +13587,10 @@ function registerActionHandlers(ctx, store) {
12053
13587
  reason: "action",
12054
13588
  eventType: "plugin.local.seen",
12055
13589
  updatedAt: review.updatedAt,
12056
- counts: store.getSnapshot(companyId)?.counts ?? {
12057
- active: 0,
12058
- queued: 0,
12059
- ambient: 0,
12060
- total: 0
12061
- }
13590
+ counts: store.getSnapshot(companyId)?.counts ?? defaultCounts()
13591
+ });
13592
+ await trackFocusTelemetry(ctx, "attention_seen_marked", {
13593
+ frameCount: taskIds.length
12062
13594
  });
12063
13595
  return { ok: true, review };
12064
13596
  });
@@ -12165,14 +13697,14 @@ function frameSortScore(frame, lane) {
12165
13697
  const toneWeight3 = frame.tone === "critical" ? 40 : frame.tone === "focused" ? 25 : 5;
12166
13698
  const consequenceWeight3 = frame.consequence === "high" ? 30 : frame.consequence === "medium" ? 15 : 0;
12167
13699
  const modeWeight = frame.mode === "approval" ? 12 : frame.mode === "choice" ? 8 : 0;
12168
- const laneWeight = lane === "active" ? 20 : lane === "queued" ? 10 : 0;
13700
+ const laneWeight = lane === "now" ? 20 : lane === "next" ? 10 : 0;
12169
13701
  const budgetWeight = isBudgetOverride(frame) ? 10 : 0;
12170
13702
  return toneWeight3 + consequenceWeight3 + modeWeight + laneWeight + budgetWeight + frameSemanticWeight(frame);
12171
13703
  }
12172
13704
  function emptyLaneCounts() {
12173
13705
  return {
12174
- active: 0,
12175
- queued: 0,
13706
+ now: 0,
13707
+ next: 0,
12176
13708
  ambient: 0,
12177
13709
  total: 0
12178
13710
  };
@@ -12198,10 +13730,10 @@ function isFrameUnread(frame, snapshotUpdatedAt, review) {
12198
13730
  }
12199
13731
  function calculateUnreadCounts(snapshot, review) {
12200
13732
  const unread = emptyLaneCounts();
12201
- if (snapshot.active && isFrameUnread(snapshot.active, snapshot.updatedAt, review)) unread.active += 1;
12202
- unread.queued = snapshot.queued.filter((frame) => isFrameUnread(frame, snapshot.updatedAt, review)).length;
13733
+ if (snapshot.now && isFrameUnread(snapshot.now, snapshot.updatedAt, review)) unread.now += 1;
13734
+ unread.next = snapshot.next.filter((frame) => isFrameUnread(frame, snapshot.updatedAt, review)).length;
12203
13735
  unread.ambient = snapshot.ambient.filter((frame) => isFrameUnread(frame, snapshot.updatedAt, review)).length;
12204
- unread.total = unread.active + unread.queued + unread.ambient;
13736
+ unread.total = unread.now + unread.next + unread.ambient;
12205
13737
  return unread;
12206
13738
  }
12207
13739
  function attachReviewState(snapshot, review) {
@@ -12217,33 +13749,33 @@ function mergeStoredFrames(snapshot, companyId, candidates, review, nowIso = (/*
12217
13749
  const base = snapshot ?? {
12218
13750
  companyId,
12219
13751
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
12220
- active: null,
12221
- queued: [],
13752
+ now: null,
13753
+ next: [],
12222
13754
  ambient: [],
12223
13755
  counts: emptyLaneCounts()
12224
13756
  };
12225
13757
  const candidateTaskIds = new Set(candidates.map((candidate) => candidate.frame.taskId));
12226
13758
  const baseEntries = [
12227
- ...base.active ? [{ frame: base.active, lane: "active" }] : [],
12228
- ...base.queued.map((frame) => ({ frame, lane: "queued" })),
13759
+ ...base.now ? [{ frame: base.now, lane: "now" }] : [],
13760
+ ...base.next.map((frame) => ({ frame, lane: "next" })),
12229
13761
  ...base.ambient.map((frame) => ({ frame, lane: "ambient" }))
12230
13762
  ].filter((candidate) => !candidateTaskIds.has(candidate.frame.taskId));
12231
13763
  const filtered = [...baseEntries, ...candidates].filter((candidate) => !isFrameSuppressed(candidate.frame, base.updatedAt, review));
12232
13764
  const actionable = filtered.filter((candidate) => candidate.lane !== "ambient").sort((left, right) => compareCandidates(left, right, base.updatedAt));
12233
13765
  const ambient = filtered.filter((candidate) => candidate.lane === "ambient").filter((candidate) => !isAmbientExpired(candidate.frame, base.updatedAt, nowIso)).sort((left, right) => compareCandidates(left, right, base.updatedAt));
12234
- const active = actionable.shift()?.frame ?? null;
12235
- const queued = actionable.map((candidate) => candidate.frame);
13766
+ const now = actionable.shift()?.frame ?? null;
13767
+ const next = actionable.map((candidate) => candidate.frame);
12236
13768
  const ambientFrames = ambient.map((candidate) => candidate.frame);
12237
13769
  return attachReviewState({
12238
13770
  ...base,
12239
- active,
12240
- queued,
13771
+ now,
13772
+ next,
12241
13773
  ambient: ambientFrames,
12242
13774
  counts: {
12243
- active: active ? 1 : 0,
12244
- queued: queued.length,
13775
+ now: now ? 1 : 0,
13776
+ next: next.length,
12245
13777
  ambient: ambientFrames.length,
12246
- total: (active ? 1 : 0) + queued.length + ambientFrames.length
13778
+ total: (now ? 1 : 0) + next.length + ambientFrames.length
12247
13779
  }
12248
13780
  }, review);
12249
13781
  }
@@ -12603,8 +14135,8 @@ function issueLane(issue, comment, evidence) {
12603
14135
  if ((issue.status === "blocked" || issue.status === "in_review") && (hasIntent(evidence.analysis, "resolution") || evidence.documentSignal.resolvesArtifactRequest)) {
12604
14136
  return comment || issue.isUnreadForMe || evidence.documentSignal.hasDocuments ? "ambient" : null;
12605
14137
  }
12606
- if (issue.status === "blocked") return issue.priority === "critical" ? "active" : "queued";
12607
- if (issue.status === "in_review") return "queued";
14138
+ if (issue.status === "blocked") return issue.priority === "critical" ? "now" : "next";
14139
+ if (issue.status === "in_review") return "next";
12608
14140
  if (comment || issue.isUnreadForMe) return "ambient";
12609
14141
  return null;
12610
14142
  }
@@ -12679,9 +14211,9 @@ function issueFrame(issue, comment, documents, directory) {
12679
14211
  };
12680
14212
  }
12681
14213
  function agentLane(agent) {
12682
- if (agent.status === "error") return "active";
12683
- if (agent.status === "pending_approval") return "queued";
12684
- if (agent.status === "paused" && agent.pauseReason === "budget") return "queued";
14214
+ if (agent.status === "error") return "now";
14215
+ if (agent.status === "pending_approval") return "next";
14216
+ if (agent.status === "paused" && agent.pauseReason === "budget") return "next";
12685
14217
  if (agent.status === "paused") return "ambient";
12686
14218
  return null;
12687
14219
  }
@@ -12823,11 +14355,6 @@ async function reconcileAttentionSnapshot(ctx, companyId, snapshot, review, conf
12823
14355
  }
12824
14356
 
12825
14357
  // src/handlers/data.ts
12826
- function isAttentionSnapshot(value, companyId) {
12827
- if (!value || typeof value !== "object") return false;
12828
- const snapshot = value;
12829
- return snapshot.companyId === companyId && typeof snapshot.updatedAt === "string" && !!snapshot.counts && typeof snapshot.counts.active === "number" && typeof snapshot.counts.queued === "number" && typeof snapshot.counts.ambient === "number" && typeof snapshot.counts.total === "number" && Array.isArray(snapshot.queued) && Array.isArray(snapshot.ambient);
12830
- }
12831
14358
  function isLedgerSource(value) {
12832
14359
  if (!value || typeof value !== "object") return false;
12833
14360
  const source = value;
@@ -12905,6 +14432,7 @@ async function loadAttentionState(ctx, store, companyId) {
12905
14432
  stateKey: ATTENTION_REVIEW_STATE_KEY
12906
14433
  });
12907
14434
  const baseLedger = inMemoryLedger.length > 0 ? inMemoryLedger : isAttentionLedger(persistedLedger) ? persistedLedger : createEmptyLedger();
14435
+ const normalizedPersistedSnapshot = normalizeAttentionSnapshot(companyId, persistedSnapshot);
12908
14436
  const snapshot = store.rebuildFromLedger(companyId, baseLedger);
12909
14437
  const reviewState = deriveReviewStateFromLedger(
12910
14438
  companyId,
@@ -12913,7 +14441,7 @@ async function loadAttentionState(ctx, store, companyId) {
12913
14441
  );
12914
14442
  return {
12915
14443
  persistedLedger,
12916
- persistedSnapshot,
14444
+ persistedSnapshot: normalizedPersistedSnapshot,
12917
14445
  persistedReview,
12918
14446
  baseLedger,
12919
14447
  snapshot,
@@ -12944,12 +14472,12 @@ function registerDataHandlers(ctx, store) {
12944
14472
  } = await loadAttentionState(ctx, store, companyId);
12945
14473
  const reconciledSnapshot = await loadReconciledAttentionSnapshot(ctx, companyId, snapshot, reviewState);
12946
14474
  const shouldPersistLedger = !isAttentionLedger(persistedLedger) || !sameJson(persistedLedger, baseLedger);
12947
- const shouldPersistSnapshot = !isAttentionSnapshot(persistedSnapshot, companyId) || !sameJson(persistedSnapshot, snapshot);
14475
+ const shouldPersistSnapshot = !persistedSnapshot || !sameJson(persistedSnapshot, snapshot);
12948
14476
  const shouldPersistReview = !isAttentionReviewState(persistedReview, companyId) || !sameJson(persistedReview, reviewState);
12949
14477
  if (shouldPersistLedger) await persistLedger(ctx, companyId, baseLedger);
12950
14478
  if (shouldPersistSnapshot) await persistSnapshot(ctx, companyId, snapshot);
12951
14479
  if (shouldPersistReview) await persistReviewState(ctx, companyId, reviewState);
12952
- if (!isAttentionLedger(persistedLedger) && isAttentionSnapshot(persistedSnapshot, companyId)) {
14480
+ if (!isAttentionLedger(persistedLedger) && persistedSnapshot) {
12953
14481
  ctx.logger.warn("Legacy snapshot found without replay ledger; rebuilt state may be partial until new events arrive.", {
12954
14482
  companyId
12955
14483
  });
@@ -12968,12 +14496,12 @@ function registerDataHandlers(ctx, store) {
12968
14496
  } = await loadAttentionState(ctx, store, companyId);
12969
14497
  const reconciledSnapshot = await loadReconciledAttentionSnapshot(ctx, companyId, snapshot, reviewState);
12970
14498
  const shouldPersistLedger = !isAttentionLedger(persistedLedger) || !sameJson(persistedLedger, baseLedger);
12971
- const shouldPersistSnapshot = !isAttentionSnapshot(persistedSnapshot, companyId) || !sameJson(persistedSnapshot, snapshot);
14499
+ const shouldPersistSnapshot = !persistedSnapshot || !sameJson(persistedSnapshot, snapshot);
12972
14500
  const shouldPersistReview = !isAttentionReviewState(persistedReview, companyId) || !sameJson(persistedReview, reviewState);
12973
14501
  if (shouldPersistLedger) await persistLedger(ctx, companyId, baseLedger);
12974
14502
  if (shouldPersistSnapshot) await persistSnapshot(ctx, companyId, snapshot);
12975
14503
  if (shouldPersistReview) await persistReviewState(ctx, companyId, reviewState);
12976
- if (!isAttentionLedger(persistedLedger) && isAttentionSnapshot(persistedSnapshot, companyId)) {
14504
+ if (!isAttentionLedger(persistedLedger) && persistedSnapshot) {
12977
14505
  ctx.logger.warn("Legacy snapshot found without replay ledger; rebuilt state may be partial until new events arrive.", {
12978
14506
  companyId
12979
14507
  });
@@ -12998,11 +14526,17 @@ function registerDataHandlers(ctx, store) {
12998
14526
  ledger: baseLedger,
12999
14527
  eventEntries: baseLedger.filter((entry) => entry.kind === "event"),
13000
14528
  responseEntries: baseLedger.filter((entry) => entry.kind === "response"),
14529
+ traces: store.getTraces(companyId),
13001
14530
  snapshot,
13002
14531
  reconciledSnapshot,
13003
14532
  review: reviewState
13004
14533
  };
13005
14534
  });
14535
+ ctx.data.register("attention-traces", async (params) => {
14536
+ const companyId = requireCompanyId(params);
14537
+ await loadAttentionState(ctx, store, companyId);
14538
+ return store.getTraces(companyId);
14539
+ });
13006
14540
  ctx.data.register("attention-replay-scenario", async (params) => {
13007
14541
  const companyId = requireCompanyId(params);
13008
14542
  const { baseLedger, snapshot } = await loadAttentionState(ctx, store, companyId);
@@ -13012,12 +14546,12 @@ function registerDataHandlers(ctx, store) {
13012
14546
  description: "Replay scenario exported from the Paperclip Aperture plugin ledger.",
13013
14547
  doctrineTags: ["paperclip", "aperture", "replay-export"],
13014
14548
  expectations: {
13015
- finalActiveInteractionId: snapshot.active?.interactionId ?? null,
13016
- queuedInteractionIds: snapshot.queued.map((frame) => frame.interactionId),
14549
+ finalNowInteractionId: snapshot.now?.interactionId ?? null,
14550
+ nextInteractionIds: snapshot.next.map((frame) => frame.interactionId),
13017
14551
  ambientInteractionIds: snapshot.ambient.map((frame) => frame.interactionId),
13018
- resultBucketCounts: {
13019
- active: snapshot.counts.active,
13020
- queued: snapshot.counts.queued,
14552
+ resultLaneCounts: {
14553
+ now: snapshot.counts.now,
14554
+ next: snapshot.counts.next,
13021
14555
  ambient: snapshot.counts.ambient
13022
14556
  }
13023
14557
  },
@@ -13043,7 +14577,7 @@ function registerDataHandlers(ctx, store) {
13043
14577
  });
13044
14578
  }
13045
14579
 
13046
- // node_modules/.pnpm/@tomismeta+aperture-core@0.4.0/node_modules/@tomismeta/aperture-core/public-dist/semantic.js
14580
+ // node_modules/.pnpm/@tomismeta+aperture-core@0.5.0/node_modules/@tomismeta/aperture-core/public-dist/semantic.js
13047
14581
  function normalizeSemanticText2(value) {
13048
14582
  return value.toLowerCase().replace(/[^a-z0-9/.-]+/g, " ").trim();
13049
14583
  }
@@ -13091,10 +14625,13 @@ function detectSemanticRelationHints2(text) {
13091
14625
  return dedupeRelationHints2(hints);
13092
14626
  }
13093
14627
  function inferConsequenceFromSemanticText2(text, fallback, toolFamily) {
14628
+ if (isRoutineSuccessObservation2(text)) {
14629
+ return fallback;
14630
+ }
13094
14631
  if (toolFamily === "read" || toolFamily === "search") {
13095
14632
  return fallback;
13096
14633
  }
13097
- if (containsAnySemanticPhrase2(text, HIGH_RISK_PHRASES2)) {
14634
+ if (containsAnySemanticRiskPhrase2(text, HIGH_RISK_PHRASES2)) {
13098
14635
  return "high";
13099
14636
  }
13100
14637
  if (toolFamily === "write" || toolFamily === "edit" || toolFamily === "bash") {
@@ -13102,9 +14639,82 @@ function inferConsequenceFromSemanticText2(text, fallback, toolFamily) {
13102
14639
  }
13103
14640
  return fallback;
13104
14641
  }
14642
+ function detectObservationalFailureStatus2(text, toolFamily) {
14643
+ if (toolFamily !== "edit" && toolFamily !== "read") {
14644
+ return false;
14645
+ }
14646
+ return containsAnySemanticPhrase2(text, OBSERVATIONAL_READBACK_PHRASES2) || looksLikeTaggedFileObservation2(text) || looksLikeReadObservationPayload2(text);
14647
+ }
14648
+ function detectRoutineObservationalFailureLowConsequence2(text, toolFamily) {
14649
+ if (toolFamily === "search") {
14650
+ return looksLikeSearchResultOutput2(text);
14651
+ }
14652
+ if (toolFamily === "read") {
14653
+ if (looksLikeSearchResultOutput2(text)) {
14654
+ return true;
14655
+ }
14656
+ if (!looksLikeTaggedFileObservation2(text) && !looksLikeReadObservationPayload2(text)) {
14657
+ return false;
14658
+ }
14659
+ if (looksLikeSourceCodeObservation2(text)) {
14660
+ return false;
14661
+ }
14662
+ return looksLikeLogObservation2(text) || looksLikeBuildMetadataObservation2(text);
14663
+ }
14664
+ return false;
14665
+ }
14666
+ function detectExpectedDiagnosticFailure2(text, toolFamily) {
14667
+ if (toolFamily !== "bash") {
14668
+ return false;
14669
+ }
14670
+ return containsAnySemanticPhrase2(text, EXPECTED_DIAGNOSTIC_FAILURE_PHRASES2) && !containsAnySemanticPhrase2(text, TERMINAL_FAILURE_PHRASES2);
14671
+ }
13105
14672
  function containsAnySemanticPhrase2(value, phrases) {
13106
14673
  return phrases.some((phrase) => value.includes(phrase));
13107
14674
  }
14675
+ function containsAnySemanticRiskPhrase2(value, phrases) {
14676
+ return phrases.some((phrase) => containsSemanticRiskPhrase2(value, phrase));
14677
+ }
14678
+ function containsSemanticRiskPhrase2(value, phrase) {
14679
+ const normalizedPhrase = normalizeSemanticText2(phrase);
14680
+ if (!normalizedPhrase) {
14681
+ return false;
14682
+ }
14683
+ if (!normalizedPhrase.includes(" ")) {
14684
+ return hasWord2(value, normalizedPhrase);
14685
+ }
14686
+ return new RegExp(`(?:^|\\s)${escapeRegExp2(normalizedPhrase)}(?:\\s|$)`).test(value);
14687
+ }
14688
+ function looksLikeReadObservationPayload2(text) {
14689
+ if (!containsPathLikeToken2(text)) {
14690
+ return false;
14691
+ }
14692
+ return containsAnySemanticPhrase2(text, OBSERVATIONAL_PAYLOAD_PHRASES2) || containsCodeLikeContent2(text) || containsLineNumberedCodeContent2(text);
14693
+ }
14694
+ function looksLikeTaggedFileObservation2(text) {
14695
+ return containsAnySemanticPhrase2(text, TAGGED_FILE_OBSERVATION_PHRASES2) && containsPathLikeToken2(text);
14696
+ }
14697
+ function looksLikeSearchResultOutput2(text) {
14698
+ return SEARCH_RESULT_OUTPUT_PATTERN2.test(text) || containsPathLikeToken2(text) && /\bmatch(?:es)?\b/.test(text);
14699
+ }
14700
+ function containsPathLikeToken2(text) {
14701
+ return PATH_LIKE_TOKEN_PATTERN2.test(text);
14702
+ }
14703
+ function containsCodeLikeContent2(text) {
14704
+ return CODE_CONTENT_PATTERN2.test(text);
14705
+ }
14706
+ function containsLineNumberedCodeContent2(text) {
14707
+ return LINE_NUMBERED_CODE_PATTERN2.test(text);
14708
+ }
14709
+ function looksLikeSourceCodeObservation2(text) {
14710
+ return SOURCE_CODE_PATH_PATTERN2.test(text) || SOURCE_CODE_FILENAME_PATTERN2.test(text) || SOURCE_CODE_CONTENT_PATTERN2.test(text) || LINE_NUMBERED_SOURCE_CODE_PATTERN2.test(text);
14711
+ }
14712
+ function looksLikeLogObservation2(text) {
14713
+ return LOG_OUTPUT_PATTERN2.test(text) || containsAnySemanticPhrase2(text, LOG_LIKE_OBSERVATION_PHRASES2);
14714
+ }
14715
+ function looksLikeBuildMetadataObservation2(text) {
14716
+ return BUILD_METADATA_PATTERN2.test(text) || containsAnySemanticPhrase2(text, BUILD_METADATA_PHRASES2);
14717
+ }
13108
14718
  function readMetadataToolFamily2(metadata) {
13109
14719
  const value = metadata?.toolFamily;
13110
14720
  return typeof value === "string" ? value : null;
@@ -13180,6 +14790,70 @@ var HIGH_RISK_PHRASES2 = [
13180
14790
  "kill process",
13181
14791
  "migrate"
13182
14792
  ];
14793
+ var OBSERVATIONAL_READBACK_PHRASES2 = [
14794
+ "result of running cat -n",
14795
+ "result of running sed -n",
14796
+ "result of running grep",
14797
+ "result of running ls",
14798
+ "result of running find",
14799
+ "here s the result of running cat -n",
14800
+ "here s the result of running sed -n"
14801
+ ];
14802
+ var OBSERVATIONAL_PAYLOAD_PHRASES2 = [
14803
+ "observation",
14804
+ "contents of",
14805
+ "showing first",
14806
+ "showing top",
14807
+ "found"
14808
+ ];
14809
+ var TAGGED_FILE_OBSERVATION_PHRASES2 = [
14810
+ "path",
14811
+ "type file",
14812
+ "content"
14813
+ ];
14814
+ var ROUTINE_SUCCESS_PHRASES2 = [
14815
+ "ran successfully and did not produce any output",
14816
+ "command ran successfully and did not produce any output",
14817
+ "completed successfully and did not produce any output"
14818
+ ];
14819
+ var LOG_LIKE_OBSERVATION_PHRASES2 = [
14820
+ "tool-output",
14821
+ "dmesg"
14822
+ ];
14823
+ var BUILD_METADATA_PHRASES2 = [
14824
+ "makefile",
14825
+ "spdx-license-identifier",
14826
+ "patchlevel",
14827
+ "sublevel",
14828
+ "extraversion"
14829
+ ];
14830
+ var PATH_LIKE_TOKEN_PATTERN2 = /(?:^|\s)\/[a-z0-9._-]+(?:\/[a-z0-9._-]+)+(?:\s|$)/;
14831
+ var SEARCH_RESULT_OUTPUT_PATTERN2 = /\bfound\s+\d+\s+match(?:es)?\b|\bshowing\s+(?:first|top)\s+\d+\b|\bmatch(?:es)?\s+in\s+\d+\s+files?\b/;
14832
+ var CODE_CONTENT_PATTERN2 = /\b(import|from|export|class|def|function|const|let|var|return)\b/;
14833
+ var LINE_NUMBERED_CODE_PATTERN2 = /\b\d+\s+(?:import|from|export|class|def|function|const|let|var|return)\b/;
14834
+ var SOURCE_CODE_PATH_PATTERN2 = /\/[a-z0-9._/-]+\.(?:c|cc|cpp|cxx|h|hpp|ts|tsx|js|jsx|py|rb|go|rs|java|kt|swift)(?:\b|\/)/;
14835
+ var SOURCE_CODE_FILENAME_PATTERN2 = /\b[a-z0-9.-]+\.(?:c|cc|cpp|cxx|h|hpp|ts|tsx|js|jsx|py|rb|go|rs|java|kt|swift)\b/;
14836
+ var SOURCE_CODE_CONTENT_PATTERN2 = /\b(static|struct|enum|typedef|void|int|char|bool|return)\b/;
14837
+ var LINE_NUMBERED_SOURCE_CODE_PATTERN2 = /\b\d+\s+(?:static|struct|enum|typedef|void|int|char|bool|return)\b/;
14838
+ var LOG_OUTPUT_PATTERN2 = /\b\d+\s+\[\s*\d+\.\d+\]\s+[a-z0-9_.:-]+/;
14839
+ var BUILD_METADATA_PATTERN2 = /\b(?:version|patchlevel|sublevel|extraversion)\b/;
14840
+ var EXPECTED_DIAGNOSTIC_FAILURE_PHRASES2 = [
14841
+ "form is valid false",
14842
+ "form without instance is valid false",
14843
+ "form errors",
14844
+ "errorlist",
14845
+ "decompress result"
14846
+ ];
14847
+ var TERMINAL_FAILURE_PHRASES2 = [
14848
+ "traceback",
14849
+ "exception",
14850
+ "permission denied",
14851
+ "command not found",
14852
+ "segmentation fault"
14853
+ ];
14854
+ function isRoutineSuccessObservation2(text) {
14855
+ return containsAnySemanticPhrase2(text, ROUTINE_SUCCESS_PHRASES2);
14856
+ }
13183
14857
  var REPEAT_PHRASES2 = [
13184
14858
  "still",
13185
14859
  "again",
@@ -13328,7 +15002,13 @@ function inferSemanticInterpretation2(event) {
13328
15002
  factors: ["task.started"],
13329
15003
  relationHints: [],
13330
15004
  confidence: "high",
13331
- reasons: semanticReasonsForLifecycle2("task_started")
15005
+ reasons: semanticReasonsForLifecycle2("task_started"),
15006
+ provenance: inferredSemanticProvenance2([
15007
+ "intentFrame",
15008
+ "activityClass",
15009
+ "consequence",
15010
+ "confidence"
15011
+ ])
13332
15012
  };
13333
15013
  case "task.updated":
13334
15014
  return inferTaskUpdateSemantics2(event);
@@ -13342,7 +15022,13 @@ function inferSemanticInterpretation2(event) {
13342
15022
  factors: ["task.completed"],
13343
15023
  relationHints: [],
13344
15024
  confidence: "high",
13345
- reasons: semanticReasonsForLifecycle2("completion")
15025
+ reasons: semanticReasonsForLifecycle2("completion"),
15026
+ provenance: inferredSemanticProvenance2([
15027
+ "intentFrame",
15028
+ "activityClass",
15029
+ "consequence",
15030
+ "confidence"
15031
+ ])
13346
15032
  };
13347
15033
  case "task.cancelled":
13348
15034
  return {
@@ -13353,7 +15039,16 @@ function inferSemanticInterpretation2(event) {
13353
15039
  factors: ["task.cancelled"],
13354
15040
  relationHints: [],
13355
15041
  confidence: "high",
13356
- reasons: semanticReasonsForTaskStatus2("completed", { wasCancelled: true })
15042
+ reasons: semanticReasonsForTaskStatus2("completed", { wasCancelled: true }),
15043
+ provenance: {
15044
+ ...inferredSemanticProvenance2([
15045
+ "intentFrame",
15046
+ "activityClass",
15047
+ "consequence",
15048
+ "confidence"
15049
+ ]),
15050
+ ...event.reason ? inferredSemanticProvenance2(["whyNow"]) : {}
15051
+ }
13357
15052
  };
13358
15053
  }
13359
15054
  }
@@ -13362,19 +15057,69 @@ function inferTaskUpdateSemantics2(event) {
13362
15057
  const impliedAsk = detectImpliedOperatorAsk2(text);
13363
15058
  const relationHints = detectSemanticRelationHints2(text);
13364
15059
  const taxonomyInput = buildTaxonomyInput2(event.title, event.summary, event.toolFamily);
13365
- const toolFamily = readExplicitSemanticToolFamily2(taxonomyInput) ?? inferSemanticToolFamily2(taxonomyInput) ?? void 0;
15060
+ const { toolFamily, source: toolFamilySource } = resolveSemanticToolFamily2(taxonomyInput, true);
15061
+ const relationProvenance = relationHints.length > 0 ? inferredSemanticProvenance2(["relationHints"]) : {};
15062
+ const observationalFailure = event.status === "failed" && detectObservationalFailureStatus2(text, toolFamily);
15063
+ const routineObservationalFailureLowConsequence = event.status === "failed" && detectRoutineObservationalFailureLowConsequence2(text, toolFamily);
15064
+ const expectedDiagnosticFailure = event.status === "failed" && detectExpectedDiagnosticFailure2(text, toolFamily);
13366
15065
  switch (event.status) {
13367
15066
  case "failed":
15067
+ if (observationalFailure) {
15068
+ return {
15069
+ intentFrame: "status_update",
15070
+ activityClass: "status_update",
15071
+ ...toolFamily ? { toolFamily } : {},
15072
+ consequence: inferConsequenceFromSemanticText2(
15073
+ text,
15074
+ routineObservationalFailureLowConsequence ? "low" : "high",
15075
+ toolFamily
15076
+ ),
15077
+ factors: ["task.updated", "failed", "observational_failure"],
15078
+ relationHints,
15079
+ confidence: "high",
15080
+ reasons: [
15081
+ "task status indicates failure but the update reads like observational output"
15082
+ ],
15083
+ provenance: {
15084
+ ...inferredSemanticProvenance2([
15085
+ "intentFrame",
15086
+ "activityClass",
15087
+ "consequence",
15088
+ "confidence"
15089
+ ]),
15090
+ ...semanticToolFamilyProvenance2(toolFamilySource),
15091
+ ...relationProvenance
15092
+ }
15093
+ };
15094
+ }
13368
15095
  return {
13369
15096
  intentFrame: "failure",
13370
15097
  activityClass: "tool_failure",
13371
15098
  ...toolFamily ? { toolFamily } : {},
13372
- consequence: inferConsequenceFromSemanticText2(text, "high", toolFamily),
15099
+ consequence: inferConsequenceFromSemanticText2(
15100
+ text,
15101
+ routineObservationalFailureLowConsequence ? "low" : expectedDiagnosticFailure ? "medium" : "high",
15102
+ toolFamily
15103
+ ),
13373
15104
  whyNow: semanticWhyNowForTaskStatus2("failed") ?? "Work has failed and should be reviewed.",
13374
15105
  factors: ["task.updated", "failed"],
13375
15106
  relationHints,
13376
15107
  confidence: impliedAsk ? "medium" : "high",
13377
- reasons: semanticReasonsForTaskStatus2("failed", { impliedAsk })
15108
+ reasons: expectedDiagnosticFailure ? [
15109
+ ...semanticReasonsForTaskStatus2("failed", { impliedAsk }),
15110
+ "failure content looks like expected diagnostic output from repro work"
15111
+ ] : semanticReasonsForTaskStatus2("failed", { impliedAsk }),
15112
+ provenance: {
15113
+ ...inferredSemanticProvenance2([
15114
+ "intentFrame",
15115
+ "activityClass",
15116
+ "consequence",
15117
+ "whyNow",
15118
+ "confidence"
15119
+ ]),
15120
+ ...semanticToolFamilyProvenance2(toolFamilySource),
15121
+ ...relationProvenance
15122
+ }
13378
15123
  };
13379
15124
  case "blocked":
13380
15125
  return {
@@ -13386,7 +15131,18 @@ function inferTaskUpdateSemantics2(event) {
13386
15131
  factors: ["task.updated", "blocked"],
13387
15132
  relationHints,
13388
15133
  confidence: impliedAsk ? "medium" : "high",
13389
- reasons: semanticReasonsForTaskStatus2("blocked", { impliedAsk })
15134
+ reasons: semanticReasonsForTaskStatus2("blocked", { impliedAsk }),
15135
+ provenance: {
15136
+ ...inferredSemanticProvenance2([
15137
+ "intentFrame",
15138
+ "activityClass",
15139
+ "consequence",
15140
+ "whyNow",
15141
+ "confidence"
15142
+ ]),
15143
+ ...semanticToolFamilyProvenance2(toolFamilySource),
15144
+ ...relationProvenance
15145
+ }
13390
15146
  };
13391
15147
  case "running":
13392
15148
  case "waiting":
@@ -13403,17 +15159,32 @@ function inferTaskUpdateSemantics2(event) {
13403
15159
  factors: ["task.updated", event.status],
13404
15160
  relationHints,
13405
15161
  confidence: impliedAsk ? "low" : "high",
13406
- reasons: semanticReasonsForTaskStatus2(event.status, { impliedAsk })
15162
+ reasons: semanticReasonsForTaskStatus2(event.status, { impliedAsk }),
15163
+ provenance: {
15164
+ ...inferredSemanticProvenance2([
15165
+ "intentFrame",
15166
+ "activityClass",
15167
+ "consequence",
15168
+ "confidence"
15169
+ ]),
15170
+ ...semanticToolFamilyProvenance2(toolFamilySource),
15171
+ ...impliedAsk ? inferredSemanticProvenance2(["whyNow"]) : {},
15172
+ ...relationProvenance
15173
+ }
13407
15174
  };
13408
15175
  }
13409
15176
  }
13410
15177
  function inferHumanInputSemantics2(event) {
13411
15178
  const taxonomyInput = buildTaxonomyInput2(event.title, event.summary, event.toolFamily, event.context);
13412
- const toolFamily = readExplicitSemanticToolFamily2(taxonomyInput) ?? inferSemanticToolFamily2(taxonomyInput) ?? void 0;
15179
+ const { toolFamily, source: toolFamilySource } = resolveSemanticToolFamily2(
15180
+ taxonomyInput,
15181
+ event.request.kind === "approval"
15182
+ );
13413
15183
  const text = normalizeSemanticText2(`${event.title} ${event.summary}`);
13414
15184
  const relationHints = detectSemanticRelationHints2(text);
13415
15185
  const baseConsequence = event.riskHint ?? consequenceFromRequestKind2(event.request.kind, toolFamily);
13416
15186
  const consequence = inferConsequenceFromSemanticText2(text, baseConsequence, toolFamily);
15187
+ const relationProvenance = relationHints.length > 0 ? inferredSemanticProvenance2(["relationHints"]) : {};
13417
15188
  return {
13418
15189
  intentFrame: semanticIntentFrameForRequestKind2(event.request.kind),
13419
15190
  activityClass: semanticActivityClassForRequestKind2(event.request.kind),
@@ -13422,13 +15193,52 @@ function inferHumanInputSemantics2(event) {
13422
15193
  whyNow: semanticWhyNowForRequestKind2(event.request.kind, consequence),
13423
15194
  factors: ["human.input.requested", event.request.kind],
13424
15195
  relationHints,
13425
- confidence: event.riskHint ? "high" : toolFamily ? "medium" : "low",
15196
+ confidence: event.riskHint ? "high" : event.request.kind === "approval" && toolFamily ? "medium" : "low",
13426
15197
  reasons: [
13427
15198
  event.riskHint ? "source provided an explicit risk hint" : "request kind establishes an explicit operator decision point",
13428
- ...toolFamily ? ["tool family was inferred or supplied"] : []
13429
- ]
15199
+ ...toolFamilySource === "explicit" ? ["tool family was supplied by the source or context"] : toolFamilySource === "inferred" ? ["tool family was inferred from approval wording"] : []
15200
+ ],
15201
+ provenance: {
15202
+ ...inferredSemanticProvenance2(["intentFrame", "activityClass", "whyNow"]),
15203
+ ...semanticToolFamilyProvenance2(toolFamilySource),
15204
+ ...event.riskHint ? sourceSemanticProvenance2(["consequence", "confidence"]) : inferredSemanticProvenance2(["consequence", "confidence"]),
15205
+ ...relationProvenance
15206
+ }
13430
15207
  };
13431
15208
  }
15209
+ function inferredSemanticProvenance2(fields) {
15210
+ return semanticFieldProvenance2(fields, "inferred");
15211
+ }
15212
+ function sourceSemanticProvenance2(fields) {
15213
+ return semanticFieldProvenance2(fields, "source");
15214
+ }
15215
+ function semanticFieldProvenance2(fields, kind) {
15216
+ return Object.fromEntries(fields.map((field) => [field, kind]));
15217
+ }
15218
+ function semanticToolFamilyProvenance2(source) {
15219
+ switch (source) {
15220
+ case "explicit":
15221
+ return sourceSemanticProvenance2(["toolFamily"]);
15222
+ case "inferred":
15223
+ return inferredSemanticProvenance2(["toolFamily"]);
15224
+ default:
15225
+ return {};
15226
+ }
15227
+ }
15228
+ function resolveSemanticToolFamily2(input, allowTextInference) {
15229
+ const explicit = readExplicitSemanticToolFamily2(input);
15230
+ if (explicit) {
15231
+ return { toolFamily: explicit, source: "explicit" };
15232
+ }
15233
+ if (!allowTextInference) {
15234
+ return { source: "none" };
15235
+ }
15236
+ const inferred = inferSemanticToolFamily2(input);
15237
+ if (inferred) {
15238
+ return { toolFamily: inferred, source: "inferred" };
15239
+ }
15240
+ return { source: "none" };
15241
+ }
13432
15242
  function applySemanticHints2(inferred, hints) {
13433
15243
  if (!hints) {
13434
15244
  return inferred;
@@ -13438,7 +15248,23 @@ function applySemanticHints2(inferred, hints) {
13438
15248
  ...pickDefined2(hints),
13439
15249
  factors: dedupeSemanticStrings2([...inferred.factors ?? [], ...hints.factors ?? []]),
13440
15250
  relationHints: [...hints.relationHints ?? inferred.relationHints],
13441
- reasons: dedupeSemanticStrings2([...inferred.reasons ?? [], ...hints.reasons ?? []])
15251
+ reasons: dedupeSemanticStrings2([...inferred.reasons ?? [], ...hints.reasons ?? []]),
15252
+ provenance: {
15253
+ ...inferred.provenance ?? {},
15254
+ ...hintedSemanticProvenance2(hints)
15255
+ }
15256
+ };
15257
+ }
15258
+ function hintedSemanticProvenance2(hints) {
15259
+ return {
15260
+ ...hints.intentFrame !== void 0 ? { intentFrame: "hint" } : {},
15261
+ ...hints.activityClass !== void 0 ? { activityClass: "hint" } : {},
15262
+ ...hints.toolFamily !== void 0 ? { toolFamily: "hint" } : {},
15263
+ ...hints.consequence !== void 0 ? { consequence: "hint" } : {},
15264
+ ...hints.whyNow !== void 0 ? { whyNow: "hint" } : {},
15265
+ ...hints.relationHints !== void 0 ? { relationHints: "hint" } : {},
15266
+ ...hints.confidence !== void 0 ? { confidence: "hint" } : {},
15267
+ ...hints.abstained !== void 0 ? { abstained: "hint" } : {}
13442
15268
  };
13443
15269
  }
13444
15270
  function pickDefined2(value) {
@@ -13941,6 +15767,7 @@ function mapPluginEventToAperture(event) {
13941
15767
 
13942
15768
  // src/handlers/events.ts
13943
15769
  var SUBSCRIBED_EVENTS = [
15770
+ "activity.logged",
13944
15771
  "approval.created",
13945
15772
  "approval.decided",
13946
15773
  "approval.approved",
@@ -13956,6 +15783,11 @@ var SUBSCRIBED_EVENTS = [
13956
15783
  "agent.run.cancelled",
13957
15784
  "agent.status_changed"
13958
15785
  ];
15786
+ var ATTENTION_ACTIVITY_ACTIONS = /* @__PURE__ */ new Set([
15787
+ "issue.document_created",
15788
+ "issue.document_updated",
15789
+ "issue.document_deleted"
15790
+ ]);
13959
15791
  function shouldCaptureEvent(config, eventType) {
13960
15792
  if ((eventType === "issue.created" || eventType === "issue.updated" || eventType === "issue.comment.created" || eventType === "issue.comment_added") && config.captureIssueLifecycle === false) {
13961
15793
  return false;
@@ -13994,6 +15826,32 @@ async function enrichIssuePayload(ctx, event) {
13994
15826
  async function handleEvent(ctx, store, event) {
13995
15827
  const config = await ctx.config.get();
13996
15828
  if (!shouldCaptureEvent(config, event.eventType)) return;
15829
+ if (event.eventType === "activity.logged") {
15830
+ const payload = event.payload && typeof event.payload === "object" ? event.payload : {};
15831
+ const action = typeof payload.action === "string" ? payload.action : void 0;
15832
+ const entityType = typeof payload.entityType === "string" ? payload.entityType : event.entityType;
15833
+ if (entityType === "issue" && action && ATTENTION_ACTIVITY_ACTIONS.has(action)) {
15834
+ emitAttentionUpdate(ctx, {
15835
+ companyId: event.companyId,
15836
+ reason: "event",
15837
+ eventType: `activity.${action}`,
15838
+ updatedAt: event.occurredAt,
15839
+ counts: store.getSnapshot(event.companyId)?.counts ?? {
15840
+ now: 0,
15841
+ next: 0,
15842
+ ambient: 0,
15843
+ total: 0
15844
+ }
15845
+ });
15846
+ ctx.logger.info("Triggered Focus refresh from activity log event", {
15847
+ companyId: event.companyId,
15848
+ action,
15849
+ entityId: event.entityId,
15850
+ entityType
15851
+ });
15852
+ }
15853
+ return;
15854
+ }
13997
15855
  const enriched = await enrichIssuePayload(ctx, event);
13998
15856
  const mapped = mapPluginEventToAperture(enriched);
13999
15857
  if (!mapped) return;