@kynver-app/runtime 0.2.4 → 0.2.13

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 (39) hide show
  1. package/dist/cli.js +110 -59
  2. package/dist/dispatch-claim-release.d.ts +6 -0
  3. package/dist/doctor/local-store-cli.d.ts +11 -0
  4. package/dist/doctor/local-store.d.ts +35 -0
  5. package/dist/index.d.ts +4 -3
  6. package/dist/index.js +136 -85
  7. package/dist/local-run-store/admission-enforce.d.ts +38 -0
  8. package/dist/local-run-store/admission-shadow.d.ts +56 -0
  9. package/dist/local-run-store/dispatch-claim-recovery-startup.d.ts +11 -0
  10. package/dist/local-run-store/dispatch-claim-recovery.d.ts +54 -0
  11. package/dist/local-run-store/dispatch-receipts.d.ts +90 -0
  12. package/dist/local-run-store/index.d.ts +10 -0
  13. package/dist/local-run-store/index.js +21 -9
  14. package/dist/local-run-store/local-run-store.d.ts +26 -0
  15. package/dist/local-run-store/remote-surface-flags.d.ts +15 -0
  16. package/dist/local-run-store/small-surfaces.d.ts +37 -0
  17. package/dist/local-run-store/sqlite/sqlite-local-run-store.d.ts +14 -1
  18. package/dist/local-run-store/store-lifecycle.d.ts +38 -0
  19. package/dist/local-run-store/surface-flags.d.ts +47 -0
  20. package/dist/local-run-store/tick-posture.d.ts +27 -0
  21. package/dist/plan-persist/index.d.ts +1 -1
  22. package/dist/plan-persist/outbox-durability.d.ts +31 -0
  23. package/dist/plan-persist/outbox-store.d.ts +18 -0
  24. package/dist/plan-persist/types.d.ts +4 -0
  25. package/dist/repo-search.d.ts +13 -0
  26. package/dist/resource-gate.d.ts +9 -0
  27. package/dist/server/cleanup.js +14 -14
  28. package/dist/server/default-repo.js +1 -1
  29. package/dist/server/heavy-verification.js +1 -1
  30. package/dist/server/memory-cost-enforce.js +2 -2
  31. package/dist/server/memory-cost.js +2 -2
  32. package/dist/server/monitor.js +7 -7
  33. package/dist/server/repo-search.d.ts +1 -1
  34. package/dist/server/repo-search.js +1 -1
  35. package/dist/server/worker-policy.d.ts +1 -1
  36. package/dist/server/worker-policy.js +1 -1
  37. package/dist/util.d.ts +11 -0
  38. package/dist/worker-env.d.ts +40 -3
  39. package/package.json +1 -1
@@ -0,0 +1,38 @@
1
+ import type { LocalRunStore } from "./local-run-store.js";
2
+ import type { ClassifyOptions } from "./sqlite/sqlite-filesystem-policy.js";
3
+ interface LifecycleTestOverrides {
4
+ classifyOptions?: ClassifyOptions;
5
+ }
6
+ /** Test-only: inject filesystem-policy classification (cross-platform temp dirs). */
7
+ export declare function __setLocalRunStoreLifecycleTestOverrides(overrides: LifecycleTestOverrides): void;
8
+ export interface LocalRunStoreLifecycleStatus {
9
+ /** `open` — handle live; `unavailable` — open failed (reason set); `unopened` — not yet requested. */
10
+ state: "open" | "unavailable" | "unopened";
11
+ harnessRoot: string | null;
12
+ databasePath: string | null;
13
+ schemaVersion: number | null;
14
+ /** True when open had to quarantine a corrupt db and rebuild fresh. */
15
+ recovered: boolean;
16
+ quarantinedTo: string | null;
17
+ /** Failure classification when unavailable (message, no payloads). */
18
+ reason: string | null;
19
+ /** Total open attempts this process (retry churn indicator). */
20
+ openAttempts: number;
21
+ }
22
+ /** Backoff window before an unavailable store is re-probed (D1a precondition). */
23
+ export declare const LOCAL_RUN_STORE_OPEN_RETRY_MS: number;
24
+ /**
25
+ * The process-wide store handle, or `null` when the store cannot open.
26
+ * Never throws. A changed harness root (tests, reconfiguration) re-opens; a
27
+ * transient open failure is retried after the backoff window.
28
+ */
29
+ export declare function getLocalRunStore(nowMs?: number): LocalRunStore | null;
30
+ /** Lifecycle status without forcing an open (state `unopened` before first use). */
31
+ export declare function getLocalRunStoreLifecycleStatus(): LocalRunStoreLifecycleStatus;
32
+ /** Open (if needed) and report status in one call — the doctor/tick probe. */
33
+ export declare function probeLocalRunStore(): LocalRunStoreLifecycleStatus;
34
+ /** Close and forget the handle (tests, daemon shutdown). Never throws. */
35
+ export declare function closeLocalRunStore(): void;
36
+ /** Test-only: full reset including the process open-attempt counter. */
37
+ export declare function __resetLocalRunStoreLifecycleForTests(): void;
38
+ export {};
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Durable-harness D0 — per-surface migration flags for the local run store.
3
+ *
4
+ * Every surface migrates independently through `off` (default — today's
5
+ * behavior, byte-identical) → `shadow` (store written alongside the existing
6
+ * path; existing path authoritative; divergences counted) → `enforce` (store
7
+ * authoritative for the LOCAL decision). Unknown/empty values resolve to
8
+ * `off` with a recorded warning — a typo must never silently enable a mode.
9
+ *
10
+ * D0 lands the parser only; no surface consults its flag yet.
11
+ */
12
+ export type LocalRunStoreSurfaceMode = "off" | "shadow" | "enforce";
13
+ export type LocalRunStoreSurfaceKey = "dispatchReceipts" | "admission" | "planOutbox" | "keeper" | "meshLease" | "quota";
14
+ export interface LocalRunStoreSurfaceDefinition {
15
+ key: LocalRunStoreSurfaceKey;
16
+ env: string;
17
+ /** Plan milestone that wires the surface (operator orientation). */
18
+ milestone: string;
19
+ }
20
+ export declare const LOCAL_RUN_STORE_SURFACES: readonly LocalRunStoreSurfaceDefinition[];
21
+ export type LocalRunStoreSurfaceFlags = Record<LocalRunStoreSurfaceKey, LocalRunStoreSurfaceMode>;
22
+ /** Where each surface's effective mode came from (confirmation loop). */
23
+ export type LocalRunStoreSurfaceFlagSource = "env" | "server" | "default";
24
+ export interface ResolvedLocalRunStoreSurfaceFlags {
25
+ flags: LocalRunStoreSurfaceFlags;
26
+ sources: Record<LocalRunStoreSurfaceKey, LocalRunStoreSurfaceFlagSource>;
27
+ /** One entry per env var whose value was set but not a recognized mode. */
28
+ warnings: string[];
29
+ }
30
+ export declare function parseLocalRunStoreSurfaceMode(raw: string | undefined | null): {
31
+ mode: LocalRunStoreSurfaceMode;
32
+ unknown: boolean;
33
+ };
34
+ /**
35
+ * Effective per-surface modes with precedence
36
+ * env (explicitly set) > server-delivered policy > default `off`.
37
+ *
38
+ * The env var is the host-level override and local emergency brake; on the
39
+ * normal box (env unset everywhere) the server-delivered policy governs —
40
+ * boxes are administered from the backend, never by shell access
41
+ * (`remote-surface-flags.ts`). An UNKNOWN env value still wins the
42
+ * precedence as `off` (a typo must fail safe, not silently fall through to
43
+ * a server-delivered `enforce`).
44
+ */
45
+ export declare function resolveLocalRunStoreSurfaceFlags(env?: NodeJS.ProcessEnv): ResolvedLocalRunStoreSurfaceFlags;
46
+ /** True when any surface is past `off` (store activity expected on this host). */
47
+ export declare function anyLocalRunStoreSurfaceActive(flags: LocalRunStoreSurfaceFlags): boolean;
@@ -0,0 +1,27 @@
1
+ import { type LocalRunStoreSurfaceFlags } from "./surface-flags.js";
2
+ export interface LocalRunStoreTickPosture {
3
+ contractVersion: 1;
4
+ observedAt: string;
5
+ /** `open` | `unavailable` (a tick posture always probes, so never `unopened`). */
6
+ state: "open" | "unavailable" | "unopened";
7
+ schemaVersion: number | null;
8
+ /** True when this open had to quarantine a corrupt db and rebuild. */
9
+ recovered: boolean;
10
+ /** Failure class when unavailable (error name only — no message payload). */
11
+ unavailableClass: string | null;
12
+ flags: LocalRunStoreSurfaceFlags;
13
+ /** Where each effective mode came from — env override, server policy, or default. */
14
+ flagSources: Record<string, "env" | "server" | "default">;
15
+ flagWarningCount: number;
16
+ /** Per-surface shadow divergence counters (D1+; empty in D0). */
17
+ divergenceCounters: Record<string, number>;
18
+ }
19
+ export declare function buildLocalRunStoreTickPosture(options?: {
20
+ env?: NodeJS.ProcessEnv;
21
+ now?: () => Date;
22
+ /** Liveness probe for the stranded-claim scan (injected to avoid run-store cycles). */
23
+ hasLiveWorker?: (intent: {
24
+ runId: string;
25
+ workerName: string;
26
+ }) => boolean;
27
+ }): LocalRunStoreTickPosture;
@@ -2,7 +2,7 @@ export type { PlanPersistUserStatus, PlanPersistOperation, PlanOutboxItem, Persi
2
2
  export { hashPlanBody, hashSummary } from "./body-hash.js";
3
3
  export { persistPlan } from "./persist.js";
4
4
  export { drainPlanOutbox, loadOutboxById } from "./drain.js";
5
- export { listOutboxItems, findOutboxByIdempotencyKey } from "./outbox-store.js";
5
+ export { listOutboxItems, findOutboxByIdempotencyKey, writeOutboxItem } from "./outbox-store.js";
6
6
  export { formatPlanOutboxHandoffBlock, extractPlanOutboxFromTask, } from "./handoff.js";
7
7
  export { isTmpOnlyPath, planOutboxDir } from "./paths.js";
8
8
  export { PlanPersistError } from "./errors.js";
@@ -0,0 +1,31 @@
1
+ import type { LocalRunStoreSurfaceMode } from "../local-run-store/surface-flags.js";
2
+ export declare function planOutboxMode(env?: NodeJS.ProcessEnv): LocalRunStoreSurfaceMode;
3
+ /**
4
+ * A corrupt spool file was sighted. `shadow`: count only (caller keeps
5
+ * today's behavior). `enforce`: quarantine by rename (never delete) and tell
6
+ * the caller to continue. Returns true when the file was quarantined.
7
+ */
8
+ export declare function handleCorruptOutboxFile(paths: string[], now?: () => Date): boolean;
9
+ /**
10
+ * Per-item drain serialization. `enforce`: only the reservation winner may
11
+ * drain the item (crash backstop = TTL). `shadow`: a lost race is counted,
12
+ * the caller proceeds as today. Never throws.
13
+ */
14
+ export declare function tryAcquireDrainSlot(itemId: string, owner: string): {
15
+ proceed: boolean;
16
+ deduplicated: boolean;
17
+ };
18
+ export declare function releaseDrainSlot(itemId: string, owner: string): void;
19
+ /** Record the verified persist on the item's existing idempotency key. */
20
+ export declare function recordPlanPersistedReceipt(idempotencyKey: string, planId: string | null): void;
21
+ /** Archive intent receipt — recorded BEFORE the two renames (enforce). */
22
+ export declare function recordArchiveIntentReceipt(itemId: string): void;
23
+ /**
24
+ * ENFORCE-mode drain preamble: an item whose archive-intent receipt exists is
25
+ * a crash between the archive renames — complete the renames instead of
26
+ * re-persisting. Returns true when the item was (re)archived away.
27
+ */
28
+ export declare function completeHalfArchiveIfIntended(itemId: string, renameRemaining: () => void): boolean;
29
+ /** Counters snapshot for the operator-tick posture (surface active only). */
30
+ export declare function planOutboxCounters(): Record<string, number>;
31
+ export declare function __resetPlanOutboxCountersForTests(): void;
@@ -10,6 +10,24 @@ export declare function writeOutboxItem(input: PersistPlanInput, opts: {
10
10
  }): PlanOutboxItem;
11
11
  export declare function saveOutboxItem(item: PlanOutboxItem): void;
12
12
  export declare function archiveOutboxItem(item: PlanOutboxItem): void;
13
+ /**
14
+ * The bare renames (idempotent — each guarded by existsSync). ORDER MATTERS
15
+ * (D3 review N-1): the BODY moves first, the `.json` last, so the state a
16
+ * crash between the renames leaves behind is a LISTED item (json still in
17
+ * the outbox) with an archived body — which the next drain detects via the
18
+ * archive-intent receipt and completes. The reverse order left an invisible
19
+ * json-less orphan body no drain could ever see.
20
+ */
21
+ export declare function archiveOutboxItemFiles(item: PlanOutboxItem): void;
22
+ /**
23
+ * Filesystem-evidence archive completion (re-review N-7, ALL modes): the
24
+ * body sitting at its id-derived ARCHIVE destination can only mean a
25
+ * post-verified-persist archive began and crashed (or hit a transient json
26
+ * rename error) between the renames — the plan is already persisted. Finish
27
+ * the json rename so the item cannot wedge the drain (off/shadow have no
28
+ * receipt to consult; the fs state alone is proof). Store-free by design.
29
+ */
30
+ export declare function completeArchiveFromFilesystemEvidence(item: PlanOutboxItem): boolean;
13
31
  export declare function outboxItemPaths(item: PlanOutboxItem): {
14
32
  jsonPath: string;
15
33
  bodyPath: string;
@@ -83,9 +83,13 @@ export interface DrainOutboxResult {
83
83
  succeeded: number;
84
84
  stillQueued: number;
85
85
  failed: number;
86
+ /** D3 enforce: items skipped because another drainer holds the lease. */
87
+ deduplicated?: number;
86
88
  results: Array<{
87
89
  outboxId: string;
88
90
  userStatus: PlanPersistUserStatus;
89
91
  lastError?: string;
92
+ /** True when this row reports a skip, not a persist attempt. */
93
+ skipped?: boolean;
90
94
  }>;
91
95
  }
@@ -17,10 +17,23 @@ export declare function normalizeRgArgv(argv: string[]): {
17
17
  argv: string[];
18
18
  changed: boolean;
19
19
  };
20
+ /** Peel `bash -lc '…'` / `sh -c "…"` wrappers so rg normalization sees the inner script. */
21
+ export declare function unwrapShellWrapperCommand(command: string): {
22
+ command: string;
23
+ wrapped: boolean;
24
+ };
20
25
  export declare function normalizeRepoSearchCommand(command: string): {
21
26
  command: string;
22
27
  changed: boolean;
23
28
  };
29
+ export declare function isRgLikeCommand(command: string): boolean;
30
+ /** Ripgrep exit 1 with no error text is a successful read-only search (no matches), not a shell failure. */
31
+ export declare function shouldTreatRgNoMatchAsSuccess(input: {
32
+ command: string;
33
+ exitCode?: number;
34
+ stderr?: string;
35
+ interleaved?: string;
36
+ }): boolean;
24
37
  export declare function extractSearchMeta(meta: string): {
25
38
  pattern?: string;
26
39
  target?: string;
@@ -58,6 +58,15 @@ export declare function countActiveWorkers(runId: string): number;
58
58
  * infinity, never N" bug). This machine-wide count is what the gate must use.
59
59
  */
60
60
  export declare function countActiveWorkersGlobal(): number;
61
+ /**
62
+ * Identities of every active worker machine-wide (durable-harness D2a: the
63
+ * admission-shadow reconcile refreshes/releases slot reservations against
64
+ * exactly the records the gate counts).
65
+ */
66
+ export declare function listActiveWorkerIdentitiesGlobal(): Array<{
67
+ runId: string;
68
+ workerName: string;
69
+ }>;
61
70
  /**
62
71
  * Compute how many workers this host can run and how many dispatch slots remain.
63
72
  * Uses total RAM for steady-state capacity and free RAM as a hard safety gate.