@karmaniverous/jeeves-meta 0.14.0 → 0.15.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/index.d.ts CHANGED
@@ -111,6 +111,12 @@ interface MetaExecutor {
111
111
  * @returns The subprocess result with output and optional token count.
112
112
  */
113
113
  spawn(task: string, options?: MetaSpawnOptions): Promise<MetaSpawnResult>;
114
+ /**
115
+ * Whether the executor has been aborted by the operator.
116
+ * When true, runPhase catch blocks should skip persisting _error
117
+ * because the abort route has already written the correct state.
118
+ */
119
+ readonly aborted?: boolean;
114
120
  }
115
121
 
116
122
  /**
@@ -283,6 +289,16 @@ type MetaError = z.infer<typeof metaErrorSchema>;
283
289
  * @module schema/meta
284
290
  */
285
291
 
292
+ /** Phase names in pipeline order. */
293
+ declare const phaseNames: readonly ["architect", "builder", "critic"];
294
+ /** A single synthesis phase name. */
295
+ type PhaseName = (typeof phaseNames)[number];
296
+ /** Valid states for a synthesis phase. */
297
+ declare const phaseStatuses: readonly ["fresh", "stale", "pending", "running", "failed"];
298
+ /** A single phase status value. */
299
+ type PhaseStatus = (typeof phaseStatuses)[number];
300
+ /** Per-phase state record. */
301
+ type PhaseState = Record<PhaseName, PhaseStatus>;
286
302
  /** Zod schema for the reserved (underscore-prefixed) meta.json properties. */
287
303
  declare const metaJsonSchema: z.ZodObject<{
288
304
  _id: z.ZodOptional<z.ZodUUID>;
@@ -317,6 +333,29 @@ declare const metaJsonSchema: z.ZodObject<{
317
333
  message: z.ZodString;
318
334
  }, z.core.$strip>>;
319
335
  _disabled: z.ZodOptional<z.ZodBoolean>;
336
+ _phaseState: z.ZodOptional<z.ZodObject<{
337
+ architect: z.ZodEnum<{
338
+ fresh: "fresh";
339
+ stale: "stale";
340
+ pending: "pending";
341
+ running: "running";
342
+ failed: "failed";
343
+ }>;
344
+ builder: z.ZodEnum<{
345
+ fresh: "fresh";
346
+ stale: "stale";
347
+ pending: "pending";
348
+ running: "running";
349
+ failed: "failed";
350
+ }>;
351
+ critic: z.ZodEnum<{
352
+ fresh: "fresh";
353
+ stale: "stale";
354
+ pending: "pending";
355
+ running: "running";
356
+ failed: "failed";
357
+ }>;
358
+ }, z.core.$strip>>;
320
359
  }, z.core.$loose>;
321
360
  /** Inferred type for meta.json. */
322
361
  type MetaJson = z.infer<typeof metaJsonSchema>;
@@ -380,11 +419,15 @@ declare const SERVICE_VERSION: string;
380
419
  declare function registerCustomCliCommands(program: Command): void;
381
420
 
382
421
  /**
383
- * Single-threaded synthesis queue with priority support and deduplication.
422
+ * Hybrid 3-layer synthesis queue.
423
+ *
424
+ * Layer 1: Current — the single item currently executing (at most one).
425
+ * Layer 2: Overrides — items manually enqueued via POST /synthesize with path.
426
+ * FIFO among overrides, ahead of automatic candidates.
427
+ * Layer 3: Automatic — computed on read, not persisted. All metas with a
428
+ * pending phase, ranked by scheduler priority.
384
429
  *
385
- * The scheduler enqueues the stalest candidate each tick. HTTP-triggered
386
- * synthesis requests get priority (inserted at front). A path appears at
387
- * most once in the queue; re-triggering returns the current position.
430
+ * Legacy: `pending` array is the union of overrides + automatic.
388
431
  *
389
432
  * @module queue
390
433
  */
@@ -395,6 +438,17 @@ interface QueueItem {
395
438
  priority: boolean;
396
439
  enqueuedAt: string;
397
440
  }
441
+ /** An override entry in the explicit queue layer. */
442
+ interface OverrideEntry {
443
+ path: string;
444
+ enqueuedAt: string;
445
+ }
446
+ /** The currently executing item with phase info. */
447
+ interface CurrentItem {
448
+ path: string;
449
+ phase: PhaseName;
450
+ startedAt: string;
451
+ }
398
452
  /** Result returned by {@link SynthesisQueue.enqueue}. */
399
453
  interface EnqueueResult {
400
454
  position: number;
@@ -410,28 +464,44 @@ interface QueueState {
410
464
  }>;
411
465
  }
412
466
  /**
413
- * Single-threaded synthesis queue.
467
+ * Hybrid 3-layer synthesis queue.
414
468
  *
415
- * Only one synthesis runs at a time. Priority items are inserted at the
416
- * front of the queue. Duplicate paths are rejected with their current
417
- * position returned.
469
+ * Only one synthesis runs at a time. Override items (explicit triggers)
470
+ * take priority over automatic candidates.
418
471
  */
419
472
  declare class SynthesisQueue {
473
+ /** Legacy queue (used by processQueue for backward compat). */
420
474
  private queue;
421
475
  private currentItem;
422
476
  private processing;
423
477
  private logger;
424
478
  private onEnqueueCallback;
425
- /**
426
- * Create a new SynthesisQueue.
427
- *
428
- * @param logger - Pino logger instance.
429
- */
479
+ /** Explicit override entries (3-layer model). */
480
+ private overrideEntries;
481
+ /** Currently executing item with phase info (3-layer model). */
482
+ private currentPhaseItem;
430
483
  constructor(logger: Logger);
484
+ /** Set a callback to invoke when a new (non-duplicate) item is enqueued. */
485
+ onEnqueue(callback: () => void): void;
431
486
  /**
432
- * Set a callback to invoke when a new (non-duplicate) item is enqueued.
487
+ * Add an explicit override entry (from POST /synthesize with path).
488
+ * Deduped by path. Returns position and whether already queued.
433
489
  */
434
- onEnqueue(callback: () => void): void;
490
+ enqueueOverride(path: string): EnqueueResult;
491
+ /** Dequeue the next override entry, or undefined if empty. */
492
+ dequeueOverride(): OverrideEntry | undefined;
493
+ /** Get all override entries (shallow copy). */
494
+ get overrides(): OverrideEntry[];
495
+ /** Clear all override entries. Returns count removed. */
496
+ clearOverrides(): number;
497
+ /** Check if a path is in the override layer. */
498
+ hasOverride(path: string): boolean;
499
+ /** Set the currently executing phase item. */
500
+ setCurrentPhase(path: string, phase: PhaseName): void;
501
+ /** Clear the current phase item. */
502
+ clearCurrentPhase(): void;
503
+ /** The currently executing phase item, or null. */
504
+ get currentPhase(): CurrentItem | null;
435
505
  /**
436
506
  * Add a path to the synthesis queue.
437
507
  *
@@ -440,11 +510,7 @@ declare class SynthesisQueue {
440
510
  * @returns Position and whether the path was already queued.
441
511
  */
442
512
  enqueue(path: string, priority?: boolean): EnqueueResult;
443
- /**
444
- * Remove and return the next item from the queue.
445
- *
446
- * @returns The next QueueItem, or undefined if the queue is empty.
447
- */
513
+ /** Remove and return the next item from the queue. */
448
514
  dequeue(): QueueItem | undefined;
449
515
  /** Mark the currently-running synthesis as complete. */
450
516
  complete(): void;
@@ -458,35 +524,23 @@ declare class SynthesisQueue {
458
524
  get pending(): QueueItem[];
459
525
  /**
460
526
  * Remove all pending items from the queue.
461
- *
462
527
  * Does not affect the currently-running item.
463
528
  *
464
529
  * @returns The number of items removed.
465
530
  */
466
531
  clear(): number;
467
- /**
468
- * Check whether a path is in the queue or currently being synthesized.
469
- *
470
- * @param path - Meta path to look up.
471
- * @returns True if the path is queued or currently running.
472
- */
532
+ /** Check whether a path is in the queue or currently being synthesized. */
473
533
  has(path: string): boolean;
474
- /**
475
- * Get the 0-indexed position of a path in the queue.
476
- *
477
- * @param path - Meta path to look up.
478
- * @returns Position index, or null if not found in the queue.
479
- */
534
+ /** Get the 0-indexed position of a path in the queue. */
480
535
  getPosition(path: string): number | null;
481
- /**
482
- * Return a snapshot of queue state for the /status endpoint.
483
- *
484
- * @returns Queue depth and item list.
485
- */
536
+ /** Dequeue the next item: overrides first, then legacy queue. */
537
+ private nextItem;
538
+ /** Return a snapshot of queue state for the /status endpoint. */
486
539
  getState(): QueueState;
487
540
  /**
488
- * Process queued items one at a time until the queue is empty.
541
+ * Process queued items one at a time until all queues are empty.
489
542
  *
543
+ * Override entries are processed first (FIFO), then legacy queue items.
490
544
  * Re-entry is prevented: if already processing, the call returns
491
545
  * immediately. Errors are logged and do not block subsequent items.
492
546
  *
@@ -573,14 +627,15 @@ declare class HttpWatcherClient implements WatcherClient {
573
627
  }
574
628
 
575
629
  /**
576
- * Croner-based scheduler that discovers the stalest meta candidate each tick
577
- * and enqueues it for synthesis.
630
+ * Croner-based scheduler that discovers the highest-priority ready phase
631
+ * across the corpus each tick and enqueues it for execution.
578
632
  *
579
633
  * @module scheduler
580
634
  */
581
635
 
582
636
  /**
583
- * Periodic scheduler that discovers stale meta candidates and enqueues them.
637
+ * Periodic scheduler that discovers the highest-priority ready phase
638
+ * across all metas and enqueues it for execution.
584
639
  *
585
640
  * Supports adaptive backoff when no candidates are found and hot-reloadable
586
641
  * cron expressions via {@link Scheduler.updateSchedule}.
@@ -604,23 +659,26 @@ declare class Scheduler {
604
659
  stop(): void;
605
660
  /** Hot-reload the cron schedule expression. */
606
661
  updateSchedule(expression: string): void;
607
- /** Reset backoff multiplier (call after successful synthesis). */
662
+ /** Reset backoff multiplier (call after successful phase execution). */
608
663
  resetBackoff(): void;
609
664
  /** Whether the scheduler is currently running. */
610
665
  get isRunning(): boolean;
611
666
  /** Next scheduled tick time, or null if not running. */
612
667
  get nextRunAt(): Date | null;
613
668
  /**
614
- * Single tick: discover stalest candidate and enqueue it.
669
+ * Single tick: discover the highest-priority ready phase and enqueue it.
615
670
  *
616
- * Skips if the queue is currently processing. Applies adaptive backoff
617
- * when no candidates are found.
671
+ * Applies adaptive backoff when no candidates are found.
618
672
  */
619
673
  private tick;
620
674
  /**
621
- * Discover the stalest meta candidate via watcher.
675
+ * Discover the highest-priority ready phase across the corpus.
676
+ *
677
+ * Uses phase-state-aware scheduling: priority order is
678
+ * critic (band 1) \> builder (band 2) \> architect (band 3),
679
+ * with weighted staleness as tiebreaker within a band.
622
680
  */
623
- private discoverStalest;
681
+ private discoverNextPhase;
624
682
  }
625
683
 
626
684
  /**
@@ -1073,6 +1131,8 @@ declare class GatewayExecutor implements MetaExecutor {
1073
1131
  private invoke;
1074
1132
  /** Look up totalTokens for a session via sessions_list. */
1075
1133
  private getSessionTokens;
1134
+ /** Whether this executor has been aborted by the operator. */
1135
+ get aborted(): boolean;
1076
1136
  /** Abort the currently running spawn, if any. */
1077
1137
  abort(): void;
1078
1138
  spawn(task: string, options?: MetaSpawnOptions): Promise<MetaSpawnResult>;
@@ -1224,6 +1284,8 @@ interface MergeOptions {
1224
1284
  * Used for timeout recovery where state advanced but content did not.
1225
1285
  */
1226
1286
  stateOnly?: boolean;
1287
+ /** Phase state record to persist. */
1288
+ phaseState?: PhaseState;
1227
1289
  }
1228
1290
  /**
1229
1291
  * Merge results into meta.json and write atomically.
@@ -1280,7 +1342,7 @@ declare class ProgressReporter {
1280
1342
  */
1281
1343
 
1282
1344
  /** Callback for synthesis progress events. */
1283
- type ProgressCallback = (event: ProgressEvent) => void | Promise<void>;
1345
+ type ProgressCallback$1 = (event: ProgressEvent) => void | Promise<void>;
1284
1346
  /** Result of a single orchestration cycle. */
1285
1347
  interface OrchestrateResult {
1286
1348
  /** Whether a synthesis was performed. */
@@ -1302,7 +1364,70 @@ interface OrchestrateResult {
1302
1364
  * @param targetPath - Optional: specific meta/owner path to synthesize instead of stalest candidate.
1303
1365
  * @returns Array with a single result.
1304
1366
  */
1305
- declare function orchestrate(config: MetaConfig, executor: MetaExecutor, watcher: WatcherClient, targetPath?: string, onProgress?: ProgressCallback, logger?: MinimalLogger): Promise<OrchestrateResult[]>;
1367
+ declare function orchestrate(config: MetaConfig, executor: MetaExecutor, watcher: WatcherClient, targetPath?: string, onProgress?: ProgressCallback$1, logger?: MinimalLogger): Promise<OrchestrateResult[]>;
1368
+
1369
+ /**
1370
+ * Per-phase executors for the phase-state machine.
1371
+ *
1372
+ * Each function runs exactly one phase on one meta, updates _phaseState
1373
+ * via pure transitions, and persists via the lock-staged write.
1374
+ *
1375
+ * @module orchestrator/runPhase
1376
+ */
1377
+
1378
+ /** Callback for synthesis progress events. */
1379
+ type ProgressCallback = (event: ProgressEvent) => void | Promise<void>;
1380
+ /** Result of running a single phase. */
1381
+ interface PhaseResult {
1382
+ /** Whether the phase executed (vs. was skipped). */
1383
+ executed: boolean;
1384
+ /** Updated phase state after execution. */
1385
+ phaseState: PhaseState;
1386
+ /** Updated meta.json content (if written). */
1387
+ updatedMeta?: MetaJson;
1388
+ /** Error if the phase failed. */
1389
+ error?: MetaError;
1390
+ /** Whether the full cycle is now complete (all phases fresh). */
1391
+ cycleComplete?: boolean;
1392
+ }
1393
+ declare function runArchitect(node: MetaNode, currentMeta: MetaJson, phaseState: PhaseState, config: MetaConfig, executor: MetaExecutor, watcher: WatcherClient, structureHash: string, onProgress?: ProgressCallback, logger?: MinimalLogger): Promise<PhaseResult>;
1394
+ declare function runBuilder(node: MetaNode, currentMeta: MetaJson, phaseState: PhaseState, config: MetaConfig, executor: MetaExecutor, watcher: WatcherClient, structureHash: string, onProgress?: ProgressCallback, logger?: MinimalLogger): Promise<PhaseResult>;
1395
+ declare function runCritic(node: MetaNode, currentMeta: MetaJson, phaseState: PhaseState, config: MetaConfig, executor: MetaExecutor, watcher: WatcherClient, structureHash: string, onProgress?: ProgressCallback, logger?: MinimalLogger): Promise<PhaseResult>;
1396
+
1397
+ /**
1398
+ * Phase-aware orchestration entry point.
1399
+ *
1400
+ * Replaces the old staleness-based orchestrate() with phase-state-machine
1401
+ * scheduling: each tick discovers all metas, computes invalidation,
1402
+ * auto-retries failed phases, selects the best phase candidate, and
1403
+ * executes exactly one phase.
1404
+ *
1405
+ * @module orchestrator/orchestratePhase
1406
+ */
1407
+
1408
+ /** Callback for synthesis progress events. */
1409
+ type PhaseProgressCallback = (event: ProgressEvent) => void | Promise<void>;
1410
+ /** Result of a single phase-aware orchestration tick. */
1411
+ interface OrchestratePhaseResult {
1412
+ /** Whether a phase was executed. */
1413
+ executed: boolean;
1414
+ /** Path to the meta that was selected. */
1415
+ metaPath?: string;
1416
+ /** Which phase was run. */
1417
+ phase?: PhaseName;
1418
+ /** The phase result (if executed). */
1419
+ phaseResult?: PhaseResult;
1420
+ /** Whether a full synthesis cycle completed (all phases fresh). */
1421
+ cycleComplete?: boolean;
1422
+ }
1423
+ /**
1424
+ * Run a single phase-aware orchestration tick.
1425
+ *
1426
+ * When targetPath is provided (override entry), runs the owed phase for
1427
+ * that specific meta. Otherwise, discovers all metas, computes invalidation,
1428
+ * and selects the best phase candidate corpus-wide.
1429
+ */
1430
+ declare function orchestratePhase(config: MetaConfig, executor: MetaExecutor, watcher: WatcherClient, targetPath?: string, onProgress?: PhaseProgressCallback, logger?: MinimalLogger): Promise<OrchestratePhaseResult>;
1306
1431
 
1307
1432
  /**
1308
1433
  * Weighted staleness formula for candidate selection.
@@ -1532,5 +1657,5 @@ declare function registerShutdownHandlers(deps: ShutdownDeps): void;
1532
1657
  */
1533
1658
  declare function startService(config: ServiceConfig, configPath?: string): Promise<void>;
1534
1659
 
1535
- export { DEFAULT_PORT, DEFAULT_PORT_STR, GatewayExecutor, HttpWatcherClient, MAX_STALENESS_SECONDS, ProgressReporter, RESTART_REQUIRED_FIELDS, RuleRegistrar, SERVICE_NAME, SERVICE_VERSION, Scheduler, SynthesisQueue, acquireLock, actualStaleness, buildArchitectTask, buildBuilderTask, buildContextPackage, buildCriticTask, buildOwnershipTree, cleanupStaleLocks, computeEffectiveStaleness, computeEma, computeStructureHash, createLogger, createServer, createSnapshot, discoverMetas, filterInScope, findNode, formatProgressEvent, getScopePrefix, hasSteerChanged, isArchitectTriggered, isLocked, isStale, listArchiveFiles, listMetas, loadServiceConfig, mergeAndWrite, metaConfigSchema, metaDescriptor, metaErrorSchema, metaJsonSchema, migrateConfigPath, normalizePath, orchestrate, parseArchitectOutput, parseBuilderOutput, parseCriticOutput, pruneArchive, readLatestArchive, readLockState, registerCustomCliCommands, registerRoutes, registerShutdownHandlers, releaseLock, resolveConfigPath, resolveMetaDir, selectCandidate, serviceConfigSchema, startService, toMetaError, verifyRuleApplication };
1536
- export type { BuilderOutput, EnqueueResult, GatewayExecutorOptions, HttpWatcherClientOptions, InferenceRuleSpec, LockState, LoggerConfig, MergeOptions, MetaConfig, MetaContext, MetaEntry, MetaError, MetaExecutor, MetaJson, MetaListResult, MetaListSummary, MetaNode, MetaSpawnOptions, MetaSpawnResult, MinimalLogger, OrchestrateResult, OwnershipTree, ProgressCallback, ProgressEvent, ProgressPhase, ProgressReporterConfig, QueueItem, QueueState, RouteDeps, ServerOptions, ServiceConfig, ServiceStats, StalenessCandidate, WatcherClient, WatcherScanPoint, WatcherScanRequest, WatcherScanResult };
1660
+ export { DEFAULT_PORT, DEFAULT_PORT_STR, GatewayExecutor, HttpWatcherClient, MAX_STALENESS_SECONDS, ProgressReporter, RESTART_REQUIRED_FIELDS, RuleRegistrar, SERVICE_NAME, SERVICE_VERSION, Scheduler, SynthesisQueue, acquireLock, actualStaleness, buildArchitectTask, buildBuilderTask, buildContextPackage, buildCriticTask, buildOwnershipTree, cleanupStaleLocks, computeEffectiveStaleness, computeEma, computeStructureHash, createLogger, createServer, createSnapshot, discoverMetas, filterInScope, findNode, formatProgressEvent, getScopePrefix, hasSteerChanged, isArchitectTriggered, isLocked, isStale, listArchiveFiles, listMetas, loadServiceConfig, mergeAndWrite, metaConfigSchema, metaDescriptor, metaErrorSchema, metaJsonSchema, migrateConfigPath, normalizePath, orchestrate, orchestratePhase, parseArchitectOutput, parseBuilderOutput, parseCriticOutput, pruneArchive, readLatestArchive, readLockState, registerCustomCliCommands, registerRoutes, registerShutdownHandlers, releaseLock, resolveConfigPath, resolveMetaDir, runArchitect, runBuilder, runCritic, selectCandidate, serviceConfigSchema, startService, toMetaError, verifyRuleApplication };
1661
+ export type { BuilderOutput, EnqueueResult, GatewayExecutorOptions, HttpWatcherClientOptions, InferenceRuleSpec, LockState, LoggerConfig, MergeOptions, MetaConfig, MetaContext, MetaEntry, MetaError, MetaExecutor, MetaJson, MetaListResult, MetaListSummary, MetaNode, MetaSpawnOptions, MetaSpawnResult, MinimalLogger, OrchestratePhaseResult, OrchestrateResult, OwnershipTree, PhaseProgressCallback, PhaseResult, ProgressCallback$1 as ProgressCallback, ProgressEvent, ProgressPhase, ProgressReporterConfig, QueueItem, QueueState, RouteDeps, ServerOptions, ServiceConfig, ServiceStats, StalenessCandidate, WatcherClient, WatcherScanPoint, WatcherScanRequest, WatcherScanResult };