@kynver-app/runtime 0.1.73 → 0.1.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/active-harness-workers.d.ts +11 -0
  2. package/dist/cleanup-evidence.d.ts +10 -0
  3. package/dist/cleanup-execute.d.ts +1 -0
  4. package/dist/cleanup-guards.d.ts +2 -0
  5. package/dist/cleanup-retention-config.d.ts +3 -0
  6. package/dist/cleanup-run-directory.d.ts +20 -0
  7. package/dist/cleanup-types.d.ts +25 -1
  8. package/dist/cli.js +2439 -751
  9. package/dist/cli.js.map +4 -4
  10. package/dist/cron/hermes-provider-notice.d.ts +1 -0
  11. package/dist/harness-lease-owner.d.ts +13 -0
  12. package/dist/index.d.ts +10 -3
  13. package/dist/index.js +2715 -760
  14. package/dist/index.js.map +4 -4
  15. package/dist/landing-contract-gate.d.ts +1 -0
  16. package/dist/model-routing.d.ts +4 -1
  17. package/dist/orchestration-providers/audit.d.ts +3 -0
  18. package/dist/orchestration-providers/capabilities.d.ts +3 -0
  19. package/dist/orchestration-providers/claude-oauth-binding.d.ts +6 -0
  20. package/dist/orchestration-providers/codex-oauth-binding.d.ts +5 -0
  21. package/dist/orchestration-providers/codex-orchestration-adapter.d.ts +13 -0
  22. package/dist/orchestration-providers/cost-router.d.ts +24 -0
  23. package/dist/orchestration-providers/cursor-oauth-binding.d.ts +5 -0
  24. package/dist/orchestration-providers/hermes-cli-adapter.d.ts +15 -0
  25. package/dist/orchestration-providers/hermes-openai-codex-binding.d.ts +15 -0
  26. package/dist/orchestration-providers/index.d.ts +13 -0
  27. package/dist/orchestration-providers/inventory.d.ts +31 -0
  28. package/dist/orchestration-providers/oauth-binding-utils.d.ts +21 -0
  29. package/dist/orchestration-providers/routing.d.ts +16 -0
  30. package/dist/orchestration-providers/types.d.ts +45 -0
  31. package/dist/paths.d.ts +9 -1
  32. package/dist/pipeline-tick.d.ts +3 -0
  33. package/dist/post-restart-unblock.d.ts +24 -0
  34. package/dist/providers/codex.d.ts +9 -0
  35. package/dist/providers/hermes-codex.d.ts +9 -0
  36. package/dist/providers/model-preflight.d.ts +2 -0
  37. package/dist/providers/openai-codex-resilience.d.ts +33 -0
  38. package/dist/retry-limits.d.ts +1 -1
  39. package/dist/stale-reconcile.d.ts +2 -0
  40. package/dist/status.d.ts +6 -0
  41. package/dist/supervisor.d.ts +1 -0
  42. package/dist/worker-metadata-paths.d.ts +26 -0
  43. package/dist/worker-metadata-reconcile.d.ts +19 -0
  44. package/package.json +1 -1
@@ -11,6 +11,7 @@ export interface WorkerLandingContract {
11
11
  targetPrUrls: string[];
12
12
  targetPrUrl?: string | null;
13
13
  repairEnforceOriginalPr?: boolean;
14
+ requiresTargetPrReconciliation?: boolean;
14
15
  }
15
16
  export type WorkerLandingContractBlockReason = "unrelated_implementation_pr" | "missing_target_pr_reconciliation" | "incomplete_target_pr_landing" | "duplicate_repair_pr" | "missing_repair_target_reconciliation";
16
17
  export interface WorkerLandingContractVerdict {
@@ -1,16 +1,19 @@
1
1
  import { type KynverUserConfig } from "./config.js";
2
+ import type { OrchestrationRoutingAudit } from "./orchestration-providers/types.js";
2
3
  /** Conservative default — Sonnet for ordinary harness work (not Opus). */
3
4
  export declare const GLOBAL_DEFAULT_MODEL = "claude-sonnet-4-6";
4
5
  export declare const CURSOR_DEFAULT_MODEL = "composer-2.5";
5
6
  export interface ModelRoutingDecision {
6
7
  /** Model id passed to the provider CLI (undefined → provider default). */
7
8
  model?: string;
8
- /** Worker provider key (`claude` | `cursor`). */
9
+ /** Worker provider key (`claude` | `cursor` | `codex`). */
9
10
  provider: string;
10
11
  /** Audit trail for Command Center / worker.json. */
11
12
  rule: string;
12
13
  /** Original task/board model request when inferred from metadata. */
13
14
  requestedModel?: string;
15
+ /** Provider/auth/cost audit for orchestration routing (no secrets). */
16
+ orchestrationAudit?: OrchestrationRoutingAudit;
14
17
  }
15
18
  /** Resolve global default: config → env → Sonnet. */
16
19
  export declare function resolveGlobalDefaultModel(config?: KynverUserConfig): string;
@@ -0,0 +1,3 @@
1
+ import type { OrchestrationRoutingAudit } from "./types.js";
2
+ export declare function sanitizeOrchestrationAudit(audit: OrchestrationRoutingAudit): OrchestrationRoutingAudit;
3
+ export declare function orchestrationAuditForWorkerJson(audit: OrchestrationRoutingAudit): OrchestrationRoutingAudit;
@@ -0,0 +1,3 @@
1
+ import type { OrchestrationProviderCapability, OrchestrationProviderId } from "./types.js";
2
+ export declare function getOrchestrationProviderCapability(id: OrchestrationProviderId): OrchestrationProviderCapability;
3
+ export declare function listOrchestrationProviderCapabilities(): OrchestrationProviderCapability[];
@@ -0,0 +1,6 @@
1
+ import type { OrchestrationProviderBindingStatus } from "./types.js";
2
+ /**
3
+ * Probe Claude Code OAuth on the local runner. Never reads or returns raw OAuth tokens.
4
+ * ANTHROPIC_API_KEY is reported separately as api_key_env (cloud credits path).
5
+ */
6
+ export declare function probeClaudeOAuthBinding(nowIso?: string): OrchestrationProviderBindingStatus;
@@ -0,0 +1,5 @@
1
+ import type { OrchestrationProviderBindingStatus } from "./types.js";
2
+ /**
3
+ * Probe BYO Codex OAuth on the local runner. Never reads or returns raw OAuth tokens.
4
+ */
5
+ export declare function probeCodexOAuthBinding(nowIso?: string): OrchestrationProviderBindingStatus;
@@ -0,0 +1,13 @@
1
+ import { type HermesOpenAiCodexBindingStatus } from "./hermes-openai-codex-binding.js";
2
+ import type { OrchestrationProviderBindingStatus } from "./types.js";
3
+ /** How low-cost Codex orchestration authenticates on this host. */
4
+ export type CodexOrchestrationPath = "codex_cli" | "hermes_openai_codex" | "none";
5
+ export interface CodexOrchestrationAdapterStatus extends OrchestrationProviderBindingStatus {
6
+ path: CodexOrchestrationPath;
7
+ hermesOpenAiCodex?: HermesOpenAiCodexBindingStatus;
8
+ }
9
+ /**
10
+ * Resolve the best local Codex/OpenAI orchestration path: standalone `codex` CLI first,
11
+ * then Hermes-managed `openai-codex` subscription when the CLI is absent or unbound.
12
+ */
13
+ export declare function resolveCodexOrchestrationAdapter(nowIso?: string): CodexOrchestrationAdapterStatus;
@@ -0,0 +1,24 @@
1
+ import type { OrchestrationProviderInventory } from "./inventory.js";
2
+ import type { OrchestrationProviderBindingStatus, OrchestrationProviderId, OrchestrationRiskClass } from "./types.js";
3
+ export declare function providerCapableForRisk(providerId: OrchestrationProviderId, riskClass: OrchestrationRiskClass): boolean;
4
+ export declare function compareProviderCandidates(a: {
5
+ providerId: OrchestrationProviderId;
6
+ binding: OrchestrationProviderBindingStatus;
7
+ }, b: {
8
+ providerId: OrchestrationProviderId;
9
+ binding: OrchestrationProviderBindingStatus;
10
+ }): number;
11
+ export interface CheapestCapableSelection {
12
+ providerId: OrchestrationProviderId;
13
+ binding: OrchestrationProviderBindingStatus;
14
+ escalatedFrom?: OrchestrationProviderId;
15
+ escalatedReason?: string;
16
+ }
17
+ /**
18
+ * Pick the lowest-cost ready provider that can run the given risk class.
19
+ * Sorts by cost tier, then prefers local OAuth CLI over metered API-key paths.
20
+ */
21
+ export declare function selectCheapestCapableProvider(input: {
22
+ inventory: OrchestrationProviderInventory;
23
+ riskClass: OrchestrationRiskClass;
24
+ }): CheapestCapableSelection | null;
@@ -0,0 +1,5 @@
1
+ import type { OrchestrationProviderBindingStatus } from "./types.js";
2
+ /**
3
+ * Probe Cursor/Composer OAuth on the local runner. Never reads or returns raw OAuth tokens.
4
+ */
5
+ export declare function probeCursorOAuthBinding(nowIso?: string): OrchestrationProviderBindingStatus;
@@ -0,0 +1,15 @@
1
+ import type { OrchestrationAuthSource } from "./types.js";
2
+ export interface HermesCliAdapterStatus {
3
+ adapterId: "hermes";
4
+ cliAvailable: boolean;
5
+ profileBound: boolean;
6
+ authSource: OrchestrationAuthSource;
7
+ sessionFingerprint?: string;
8
+ checkedAt: string;
9
+ note?: string;
10
+ }
11
+ /**
12
+ * Best-effort Hermes Forge CLI adapter probe. Cloud/API keys in ~/.hermes/.env are
13
+ * reported as api_key_env — distinct from harness worker BYO OAuth inventory.
14
+ */
15
+ export declare function probeHermesCliAdapter(nowIso?: string): HermesCliAdapterStatus;
@@ -0,0 +1,15 @@
1
+ import type { OrchestrationAuthSource } from "./types.js";
2
+ export type HermesOpenAiCodexPath = "hermes_openai_codex";
3
+ export interface HermesOpenAiCodexBindingStatus {
4
+ path: HermesOpenAiCodexPath;
5
+ ready: boolean;
6
+ authSource: OrchestrationAuthSource;
7
+ sessionFingerprint?: string;
8
+ checkedAt: string;
9
+ note?: string;
10
+ }
11
+ /**
12
+ * Probe Hermes-managed OpenAI Codex subscription (ChatGPT backend-api/codex).
13
+ * Uses exit-code-only `hermes auth status` — never reads auth.json token payloads.
14
+ */
15
+ export declare function probeHermesOpenAiCodexBinding(nowIso?: string): HermesOpenAiCodexBindingStatus;
@@ -0,0 +1,13 @@
1
+ export * from "./types.js";
2
+ export * from "./capabilities.js";
3
+ export * from "./oauth-binding-utils.js";
4
+ export * from "./codex-oauth-binding.js";
5
+ export * from "./cursor-oauth-binding.js";
6
+ export * from "./claude-oauth-binding.js";
7
+ export * from "./hermes-cli-adapter.js";
8
+ export * from "./hermes-openai-codex-binding.js";
9
+ export * from "./codex-orchestration-adapter.js";
10
+ export * from "./inventory.js";
11
+ export * from "./cost-router.js";
12
+ export * from "./routing.js";
13
+ export * from "./audit.js";
@@ -0,0 +1,31 @@
1
+ import { type CodexOrchestrationPath } from "./codex-orchestration-adapter.js";
2
+ import { type HermesCliAdapterStatus } from "./hermes-cli-adapter.js";
3
+ import { type HermesOpenAiCodexBindingStatus } from "./hermes-openai-codex-binding.js";
4
+ import type { OrchestrationProviderBindingStatus, OrchestrationProviderId } from "./types.js";
5
+ export interface OrchestrationCloudApiCredits {
6
+ /** ANTHROPIC_API_KEY configured on host (cloud billing — not BYO OAuth). */
7
+ anthropicApiKey: boolean;
8
+ /** OPENAI_API_KEY configured on host (cloud billing — distinct from Codex OAuth). */
9
+ openaiApiKey: boolean;
10
+ /** CODEX_API_KEY configured on host (OpenAI Codex cloud path). */
11
+ codexApiKey: boolean;
12
+ }
13
+ export interface OrchestrationProviderInventory {
14
+ generatedAt: string;
15
+ bindings: Record<OrchestrationProviderId, OrchestrationProviderBindingStatus>;
16
+ /** API-key cloud paths — separate from local OAuth CLI sessions. */
17
+ cloudApiCredits: OrchestrationCloudApiCredits;
18
+ hermes: HermesCliAdapterStatus;
19
+ hermesOpenAiCodex: HermesOpenAiCodexBindingStatus;
20
+ codexAdapterPath: CodexOrchestrationPath;
21
+ readyCount: number;
22
+ }
23
+ export interface BuildOrchestrationProviderInventoryOptions {
24
+ nowIso?: () => string;
25
+ }
26
+ /**
27
+ * Probe all harness orchestration CLI providers on this host.
28
+ * Never reads or returns raw OAuth tokens or API key values.
29
+ */
30
+ export declare function buildOrchestrationProviderInventory(options?: BuildOrchestrationProviderInventoryOptions): OrchestrationProviderInventory;
31
+ export declare function probeOrchestrationProviderBinding(providerId: OrchestrationProviderId, nowIso?: string): OrchestrationProviderBindingStatus;
@@ -0,0 +1,21 @@
1
+ /** Fingerprint from file metadata only — never reads token payload. */
2
+ export declare function fingerprintAuthStore(filePath: string): string | undefined;
3
+ export declare function envKeyFingerprint(envKey: string): string;
4
+ export declare function resolveCliBin(defaultBin: string, envKeys: string[]): string;
5
+ export declare function probeCliCommand(bin: string, args: string[], options?: {
6
+ timeoutMs?: number;
7
+ okNote?: string;
8
+ failPrefix?: string;
9
+ }): {
10
+ ok: boolean;
11
+ note?: string;
12
+ };
13
+ /** Exit-code-only probe — stdout/stderr are discarded to avoid leaking auth payloads. */
14
+ export declare function probeCliExitCodeOnly(bin: string, args: string[], options?: {
15
+ timeoutMs?: number;
16
+ okNote?: string;
17
+ failNote?: string;
18
+ }): {
19
+ ok: boolean;
20
+ note?: string;
21
+ };
@@ -0,0 +1,16 @@
1
+ import type { OrchestrationProviderInventory } from "./inventory.js";
2
+ import type { OrchestrationProviderBindingStatus, OrchestrationRiskClass, OrchestrationRoutingDecision } from "./types.js";
3
+ export declare function classifyOrchestrationRisk(task: Record<string, unknown>): OrchestrationRiskClass;
4
+ export interface ResolveOrchestrationRoutingInput {
5
+ task?: Record<string, unknown> | null;
6
+ explicitProvider?: string | null;
7
+ explicitModel?: string | null;
8
+ codexBinding?: OrchestrationProviderBindingStatus | null;
9
+ inventory?: OrchestrationProviderInventory | null;
10
+ preferLowCost?: boolean;
11
+ }
12
+ /**
13
+ * Cost-aware harness orchestration routing: cheapest capable provider first,
14
+ * preferring local OAuth CLI sessions over metered API-key paths; escalate when needed.
15
+ */
16
+ export declare function resolveOrchestrationRouting(input: ResolveOrchestrationRoutingInput): OrchestrationRoutingDecision;
@@ -0,0 +1,45 @@
1
+ /** Harness / orchestration executor identity (distinct from LLM vendor strings). */
2
+ export type OrchestrationProviderId = "cursor" | "codex" | "claude";
3
+ /** How the worker authenticates — never includes secret material. */
4
+ export type OrchestrationAuthSource = "oauth_local" | "api_key_env" | "subscription_hermes" | "runner_token" | "none";
5
+ export type OrchestrationCostTier = "low" | "medium" | "high";
6
+ export type OrchestrationRiskClass = "low" | "elevated" | "privileged";
7
+ export interface OrchestrationProviderCapability {
8
+ id: OrchestrationProviderId;
9
+ displayName: string;
10
+ costTier: OrchestrationCostTier;
11
+ /** Supported auth modes for this provider on a user runner. */
12
+ authSources: OrchestrationAuthSource[];
13
+ /** May run routine orchestration (progress sync, status, low-risk board ops). */
14
+ supportsLowRiskOrchestration: boolean;
15
+ /** May run privileged platform actions (DB, deploy, secrets) — always false for BYO Codex. */
16
+ supportsPrivilegedPlatformActions: boolean;
17
+ }
18
+ /** Non-secret local session marker for audit (fingerprint only). */
19
+ export interface OrchestrationProviderBindingStatus {
20
+ providerId: OrchestrationProviderId;
21
+ ready: boolean;
22
+ authSource: OrchestrationAuthSource;
23
+ /** sha256 prefix of non-secret binding metadata — never a raw OAuth token. */
24
+ sessionFingerprint?: string;
25
+ checkedAt: string;
26
+ note?: string;
27
+ }
28
+ export interface OrchestrationRoutingAudit {
29
+ provider: OrchestrationProviderId;
30
+ model?: string;
31
+ authSource: OrchestrationAuthSource;
32
+ costTier: OrchestrationCostTier;
33
+ riskClass: OrchestrationRiskClass;
34
+ costRationale: string;
35
+ routingRule: string;
36
+ /** When routing escalated away from the preferred low-cost provider. */
37
+ escalatedFrom?: OrchestrationProviderId;
38
+ escalatedReason?: string;
39
+ }
40
+ export interface OrchestrationRoutingDecision {
41
+ provider: OrchestrationProviderId;
42
+ model?: string;
43
+ rule: string;
44
+ audit: OrchestrationRoutingAudit;
45
+ }
package/dist/paths.d.ts CHANGED
@@ -1,5 +1,13 @@
1
- /** Canonical harness root for CLI/workers. Server mirror: agent-os.harness-root.ts */
1
+ /**
2
+ * Canonical harness root: the directory that contains `runs/` and `worktrees/`.
3
+ * Strips mistaken trailing layout segments (e.g. env set to `.../harness/runs`).
4
+ * Server mirror: agent-os.harness-root.ts
5
+ */
6
+ export declare function normalizeHarnessRoot(root: string): string;
7
+ /** Canonical harness root for CLI/workers. */
2
8
  export declare function resolveHarnessRoot(): string;
9
+ export declare function harnessRunsDir(harnessRoot: string): string;
10
+ export declare function harnessWorktreesDir(harnessRoot: string): string;
3
11
  export declare function getHarnessPaths(): {
4
12
  harnessRoot: string;
5
13
  runsDir: string;
@@ -6,7 +6,10 @@ export interface PipelineTickResult {
6
6
  runId: string;
7
7
  agentOsId: string;
8
8
  execute: boolean;
9
+ /** Gate sampled before operator tick (Command Center heartbeat). */
9
10
  resourceGate: RunnerResourceGateShape;
11
+ /** Gate re-sampled after completion replay + board lifecycle sync — used for dispatch. */
12
+ dispatchResourceGate: RunnerResourceGateShape;
10
13
  leaseRenewal?: Awaited<ReturnType<typeof renewActiveTaskLeases>>;
11
14
  completedWorkers: Array<{
12
15
  worker: string;
@@ -0,0 +1,24 @@
1
+ export interface UnblockWorkerOutcome {
2
+ runId: string;
3
+ worker: string;
4
+ taskId: string;
5
+ agentOsId: string;
6
+ leaseOwner: string;
7
+ action: "released" | "skipped" | "error";
8
+ reason: string;
9
+ }
10
+ export interface PostRestartUnblockResult {
11
+ dryRun: boolean;
12
+ released: UnblockWorkerOutcome[];
13
+ skipped: UnblockWorkerOutcome[];
14
+ errors: UnblockWorkerOutcome[];
15
+ }
16
+ /**
17
+ * Scan all local run records for dead dispatched workers and release their
18
+ * server-side leases so the linked AgentTasks are requeued. Safe to run
19
+ * multiple times — the server `releaseLease` is owner-guarded and idempotent
20
+ * (a mismatched or already-released owner returns 409 / ok:false, not an
21
+ * error that breaks the loop).
22
+ */
23
+ export declare function postRestartUnblock(args: Record<string, string | boolean>): Promise<PostRestartUnblockResult>;
24
+ export declare function postRestartUnblockCli(args: Record<string, string | boolean>): Promise<void>;
@@ -0,0 +1,9 @@
1
+ import type { WorkerProvider } from "./types.js";
2
+ /** Default Codex model for harness orchestration (override with --model). */
3
+ export declare const CODEX_DEFAULT_MODEL = "gpt-5.4";
4
+ /**
5
+ * Build argv for `codex exec` headless orchestration.
6
+ * Uses read-only sandbox + no approval prompts for low-risk harness slices.
7
+ */
8
+ export declare function buildCodexExecArgv(model: string, prompt: string): string[];
9
+ export declare const codexProvider: WorkerProvider;
@@ -0,0 +1,9 @@
1
+ import type { WorkerProvider } from "./types.js";
2
+ /** Default model when routing through Hermes openai-codex subscription. */
3
+ export declare const HERMES_OPENAI_CODEX_DEFAULT_MODEL = "gpt-5.4";
4
+ /**
5
+ * Non-interactive Hermes chat argv for openai-codex subscription orchestration.
6
+ * `-Q` suppresses banners; `--accept-hooks` avoids TTY approval prompts.
7
+ */
8
+ export declare function buildHermesOpenAiCodexChatArgv(model: string, prompt: string): string[];
9
+ export declare const hermesCodexProvider: WorkerProvider;
@@ -28,4 +28,6 @@ export declare function preflightClaudeModel(model: string | undefined, defaultM
28
28
  * reasoning levels, so suffixed ids pass through; we only flag a Claude-family
29
29
  * model that was clearly meant for the `claude` provider.
30
30
  */
31
+ /** Preflight for `codex` provider — accepts OpenAI/Codex model ids; rejects Claude-family ids. */
32
+ export declare function preflightCodexModel(model: string | undefined, defaultModel: string): ModelPreflightResult;
31
33
  export declare function preflightCursorModel(model: string | undefined, defaultModel: string): ModelPreflightResult;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Classify transient OpenAI Codex / ChatGPT backend failures and build plain-English
3
+ * operator notices. Shared by harness orchestration and Hermes cron delivery UX.
4
+ */
5
+ export declare const OPENAI_CODEX_PROVIDER = "openai-codex";
6
+ export type OpenAiCodexErrorClass = "upstream_503" | "connection_refused" | "connection_reset" | "sse_no_event" | "sse_idle_timeout" | "rate_limit" | "billing" | "auth" | "unknown";
7
+ export declare const TRANSIENT_OPENAI_CODEX_ERROR_CLASSES: ReadonlySet<OpenAiCodexErrorClass>;
8
+ export type ClassifiedOpenAiCodexError = {
9
+ errorClass: OpenAiCodexErrorClass;
10
+ summary: string;
11
+ statusCode?: number;
12
+ transient: boolean;
13
+ };
14
+ export declare function redactProviderErrorText(text: string, maxLen?: number): string;
15
+ export declare function classifyOpenAiCodexError(error: unknown, statusCode?: number): ClassifiedOpenAiCodexError;
16
+ export declare function resolveOpenAiCodexRetryBudget(input: {
17
+ platform?: string | null;
18
+ provider?: string | null;
19
+ defaultRetries?: number;
20
+ env?: NodeJS.ProcessEnv;
21
+ }): number;
22
+ export type CodexFailureNoticeInput = {
23
+ jobName?: string;
24
+ provider?: string;
25
+ model?: string;
26
+ errorClass: OpenAiCodexErrorClass;
27
+ summary: string;
28
+ attempts: number;
29
+ platform?: string;
30
+ degraded?: boolean;
31
+ };
32
+ export declare function formatOpenAiCodexFailureNotice(input: CodexFailureNoticeInput): string;
33
+ export declare function formatCronJobDeliveryFailure(jobName: string, notice: string): string;
@@ -1,6 +1,6 @@
1
1
  /** Local dispatch retry/cooldown limits. */
2
2
  export interface HarnessRetryLimits {
3
- /** Advisory max task attempts surfaced to operator/dispatch (default 3). */
3
+ /** Advisory max task attempts surfaced to operator/dispatch (default 4, matches AgentOS). */
4
4
  maxTaskAttempts: number;
5
5
  /** Minimum ms between dispatch starts for the same run (default 5s). */
6
6
  dispatchCooldownMs: number;
@@ -1,4 +1,5 @@
1
1
  import { type RunFinalizeResult } from "./finalize.js";
2
+ import { reconcileWorkerMetadata } from "./worker-metadata-reconcile.js";
2
3
  /** No heartbeat this long + dead PID → reconcile as exited. */
3
4
  export declare const STALE_RECONCILE_HEARTBEAT_MS: number;
4
5
  export interface StaleWorkerReconcileOutcome {
@@ -10,6 +11,7 @@ export interface StaleWorkerReconcileOutcome {
10
11
  export interface ReconcileStaleWorkersResult {
11
12
  workers: StaleWorkerReconcileOutcome[];
12
13
  finalizedRuns: RunFinalizeResult[];
14
+ metadataReconcile: ReturnType<typeof reconcileWorkerMetadata>;
13
15
  }
14
16
  /**
15
17
  * Reconcile workers that exited without updating worker.json, and optionally
package/dist/status.d.ts CHANGED
@@ -59,11 +59,15 @@ export interface HarnessWorkerRecord {
59
59
  personaSlug?: string;
60
60
  personaEvidence?: PersonaContextEvidenceSnapshot;
61
61
  leaseOwner?: string;
62
+ /** Fencing token from claim — sent on renew/completion when set. */
63
+ leaseToken?: string;
62
64
  dispatched?: boolean;
63
65
  startedAt?: string;
64
66
  /** Routing audit — which rule selected model/provider (dispatch inference). */
65
67
  routingRule?: string;
66
68
  requestedModel?: string;
69
+ /** Orchestration provider/model/auth-source/cost audit (no OAuth secrets). */
70
+ orchestrationAudit?: import("./orchestration-providers/types.js").OrchestrationRoutingAudit;
67
71
  /** Board task metadata for landing/PR-handoff gates (set at dispatch). */
68
72
  executorRef?: string;
69
73
  parentTaskId?: string;
@@ -148,6 +152,8 @@ export interface RawHarnessWorkerStatus {
148
152
  headCommit?: string;
149
153
  /** Paths removed via `kynver worker discard-disposable` before completion POST. */
150
154
  disposableArtifactsRemoved?: string[];
155
+ /** Fencing token from claim — echoed on completion when set. */
156
+ leaseToken?: string;
151
157
  }
152
158
  export interface WorkerStatusOptions {
153
159
  /** Branch ref for ancestry when baseCommit is not set. */
@@ -17,6 +17,7 @@ export interface SpawnWorkerOptions {
17
17
  personaSlug?: string | null;
18
18
  personaEvidence?: PersonaContextEvidenceSnapshot | null;
19
19
  leaseOwner?: string;
20
+ leaseToken?: string;
20
21
  dispatched?: boolean;
21
22
  provider?: string;
22
23
  routingRule?: string;
@@ -0,0 +1,26 @@
1
+ /** True when a persisted harness path contains the historical `runs/runs` segment. */
2
+ export declare function hasNestedRunsSegment(filePath: string): boolean;
3
+ /**
4
+ * Rewrite a nested `.../runs/runs/<runId>/...` path to canonical `.../runs/<runId>/...`.
5
+ * Returns the input unchanged when no nested segment is present.
6
+ */
7
+ export declare function repairNestedRunsPath(filePath: string, harnessRoot: string): string;
8
+ export declare function canonicalRunDir(harnessRoot: string, runId: string): string;
9
+ export declare function canonicalWorkerDir(harnessRoot: string, runId: string, workerName: string): string;
10
+ /** Historical mistaken layout when harness root ended in `/runs`. */
11
+ export declare function legacyNestedWorkerDir(harnessRoot: string, runId: string, workerName: string): string;
12
+ export declare function workerArtifactFileNames(): readonly string[];
13
+ export declare function workerArtifactPaths(workerDir: string): {
14
+ workerJsonPath: string;
15
+ stdoutPath: string;
16
+ stderrPath: string;
17
+ heartbeatPath: string;
18
+ lastStatusPath: string;
19
+ };
20
+ /** Resolve the best on-disk worker.json path for a run worker entry. */
21
+ export declare function resolveWorkerJsonPath(input: {
22
+ harnessRoot: string;
23
+ runId: string;
24
+ workerName: string;
25
+ statusPath?: string;
26
+ }): string;
@@ -0,0 +1,19 @@
1
+ export interface WorkerMetadataReconcileOutcome {
2
+ runId: string;
3
+ worker: string;
4
+ action: "materialized_run_symlink" | "repaired_run_index" | "repaired_worker_paths" | "relocated_artifacts" | "synthesized_worker_json" | "marked_abandoned" | "skipped";
5
+ reason: string;
6
+ }
7
+ export interface WorkerMetadataReconcileResult {
8
+ workers: WorkerMetadataReconcileOutcome[];
9
+ }
10
+ /**
11
+ * Repair historical harness worker metadata:
12
+ * - fix run.json index paths that still reference nested `runs/runs`
13
+ * - relocate split artifacts into canonical worker dirs
14
+ * - synthesize missing worker.json from last-status/heartbeat/stdout when possible
15
+ * - mark empty abandoned worker dirs truthfully
16
+ */
17
+ export declare function reconcileWorkerMetadata(): WorkerMetadataReconcileResult;
18
+ /** JSON summary for CLI / verifier scripts. */
19
+ export declare function reconcileWorkerMetadataCli(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kynver-app/runtime",
3
- "version": "0.1.73",
3
+ "version": "0.1.76",
4
4
  "description": "Kynver AgentOS local execution runtime and CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",