@knpkv/herdr-work 0.6.0 → 0.7.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/store.js CHANGED
@@ -13,7 +13,7 @@ import { workHistoryError } from "./internal/history-validation.js";
13
13
  import { LaneOperationLedgerRow, LaneOperationTotalsRow, planLegacyLaneOperations, resolveLegacyLaneClaim } from "./internal/legacy-lane-claim.js";
14
14
  import { enforcesOneHandoffPerSession, SessionIndexDefinition, sessionIndexDefinitionQuery } from "./internal/session-index.js";
15
15
  import { goalActivityLimit, terminalCandidates, terminalCheckpoint, withoutBlockers } from "./internal/terminal-reconcile.js";
16
- import { admissionEvidence, isTerminalWorkState, WorkAdmissionTarget, WorkAgentBinding, WorkAgentBindingRequest, WorkCoordinatorSessionId, WorkDecisionHandoff, WorkDispatchHandoff, WorkExistingGoalRecovery, WorkGoal, WorkGoalAbandoned, WorkGoalAbandonment, WorkGoalCheckpoint, WorkGoalId, WorkGoalReassigned, WorkGoalReassignment, workHistoryMaxEvents, WorkLaneClaim, WorkLaneClaimed, WorkObservationEnvelope, workObservationMaxSkewMillis, WorkObservationSubject, WorkObservedAdmission, WorkObservedFact, workObservedFactMaxBytes, workObservedFactMaxRecords, WorkObservedFailure, WorkProspectiveAdmission, WorkPullRequestLink, workReconcilerHeadroom, WorkRecoveryTarget, workSnapshotMaxGoals } from "./model.js";
16
+ import { admissionEvidence, isTerminalWorkState, WorkAdmissionTarget, WorkAgentBinding, WorkAgentBindingRequest, WorkCoordinatorSessionId, WorkDecisionHandoff, WorkDispatchHandoff, WorkExistingGoalRecovery, WorkGoal, WorkGoalAbandoned, WorkGoalAbandonment, WorkGoalCheckpoint, WorkGoalId, WorkGoalReassigned, WorkGoalReassignment, workHistoryMaxEvents, WorkLaneClaim, WorkLaneClaimed, WorkObservationEnvelope, WorkObservationId, workObservationMaxSkewMillis, WorkObservationSubject, WorkObservedAdmission, WorkObservedFact, workObservedFactMaxBytes, workObservedFactMaxRecords, WorkObservedFailure, WorkProspectiveAdmission, WorkPullRequestLink, WorkReconcileOptions, workReconcilerHeadroom, WorkRecoveryTarget, workSnapshotMaxGoals } from "./model.js";
17
17
  import { asciiLower, canonicalSubject, observationSubject, reconcilerEventPrefix } from "./observed.js";
18
18
  const StoredEventRow = Schema.Struct({ record: Schema.String });
19
19
  const StoredEventRows = Schema.Array(StoredEventRow);
@@ -870,7 +870,8 @@ const readDecisionLedgerTotals = (database) => Schema.decodeUnknownSync(Decision
870
870
  FROM work_decision_totals WHERE singleton = 1`).get());
871
871
  const readLaneOperationLedgerTotals = (database) => Schema.decodeUnknownSync(LaneOperationLedgerTotalsRow)(database.prepare(`SELECT operation_count AS operationCount, operation_bytes AS operationBytes
872
872
  FROM work_lane_operation_totals WHERE singleton = 1`).get());
873
- const ObservationIdRow = Schema.Struct({ observationId: Schema.String });
873
+ const ObservationIdRow = Schema.Struct({ observationId: Schema.String, confirmedAt: Schema.Number });
874
+ const FailureLastAtRow = Schema.Struct({ lastAt: Schema.Number });
874
875
  const ReassignmentRow = Schema.Struct({ approvalJobId: Schema.String, goalId: Schema.String, record: Schema.String });
875
876
  /** Applies a reassignment's agent choice; `keep` is only reached when the goal has no target. */
876
877
  const withReassignedAgent = (goal, toAgent) => {
@@ -1273,7 +1274,8 @@ const ObservedFactRow = Schema.Struct({
1273
1274
  });
1274
1275
  const StoredFactRow = Schema.Struct({ observationId: Schema.String, confirmedAt: Schema.Number });
1275
1276
  const FactTotalsRow = Schema.Struct({ count: Schema.Number, bytes: Schema.Number });
1276
- const EvictionRow = Schema.Struct({ subject: Schema.String, bytes: Schema.Number });
1277
+ const EvictionRow = Schema.Struct({ subject: Schema.String, bytes: Schema.Number, age: Schema.Number });
1278
+ const EvictedThroughRow = Schema.Struct({ evictedThrough: Schema.Number });
1277
1279
  const canonicalObservation = (observation) => observation._tag === "agent"
1278
1280
  ? { ...observation, host: asciiLower(observation.host) }
1279
1281
  : { ...observation, repository: asciiLower(observation.repository) };
@@ -1292,6 +1294,13 @@ const writeObservations = (database, prepared) => {
1292
1294
  try {
1293
1295
  const readFact = database.prepare(`SELECT observation_id AS observationId, confirmed_at AS confirmedAt
1294
1296
  FROM work_observed_facts WHERE subject = ?`);
1297
+ // The newest time of any row eviction has removed. A subject with no row
1298
+ // may have had one, so a fact read no newer than this can't be shown to
1299
+ // be current, and is stale: eviction never makes an old read new again.
1300
+ const evictedRow = database.prepare("SELECT evicted_through AS evictedThrough FROM work_observed_eviction WHERE singleton = 1").get();
1301
+ const evictedThrough = evictedRow === undefined
1302
+ ? Number.NEGATIVE_INFINITY
1303
+ : Schema.decodeUnknownSync(EvictedThroughRow)(evictedRow).evictedThrough;
1295
1304
  const upsertFact = database.prepare(`INSERT INTO work_observed_facts (subject, observation_id, observed_at, confirmed_at, record)
1296
1305
  VALUES (?, ?, ?, ?, ?)
1297
1306
  ON CONFLICT (subject) DO UPDATE SET observation_id = excluded.observation_id,
@@ -1329,28 +1338,42 @@ const writeObservations = (database, prepared) => {
1329
1338
  recordFailure.run(item.subject, item.source, item.reason, item.observedAt, item.observedAt);
1330
1339
  return { _tag: "unknown", reason: item.reason, subject: item.subject };
1331
1340
  }
1341
+ if (stored === undefined && item.observedAt <= evictedThrough)
1342
+ return { _tag: "stale", subject: item.subject };
1343
+ // The same facts read before the stored confirmation confirm nothing now.
1344
+ if (stored?.observationId === item.observationId && stored.confirmedAt > item.observedAt) {
1345
+ return { _tag: "stale", subject: item.subject };
1346
+ }
1332
1347
  if (stored?.observationId === item.observationId) {
1333
1348
  confirmFact.run(item.observedAt, item.subject);
1334
1349
  endFailures.run(item.subject, item.observedAt);
1335
- return { _tag: "unchanged", subject: item.subject };
1350
+ return { _tag: "unchanged", observationId: item.observationId, subject: item.subject };
1336
1351
  }
1337
1352
  if (stored !== undefined && stored.confirmedAt >= item.observedAt)
1338
1353
  return { _tag: "stale", subject: item.subject };
1339
1354
  upsertFact.run(item.subject, item.observationId, item.observedAt, item.observedAt, item.record);
1340
1355
  endFailures.run(item.subject, item.observedAt);
1341
- return { _tag: "stored", subject: item.subject };
1356
+ return { _tag: "stored", observationId: item.observationId, subject: item.subject };
1342
1357
  });
1343
1358
  // Totals are read once and kept current as rows go, so eviction is one
1344
1359
  // indexed lookup and delete per row, not a full rescan per row.
1345
- const evict = (table, age, payload) => {
1360
+ // A failure disputes its subject's fact while it is newer than that fact's
1361
+ // confirmation; evicting such a failure evicts the fact with it, so a
1362
+ // disputed fact never outlives the record of its dispute.
1363
+ const removeDisputedFact = database.prepare(`DELETE FROM work_observed_facts WHERE subject = ? AND confirmed_at <
1364
+ (SELECT last_at FROM work_observed_failures WHERE subject = ?)`);
1365
+ let newestEvicted = Number.NEGATIVE_INFINITY;
1366
+ const evict = (table, age, payload, beforeRemove) => {
1346
1367
  const size = `length(CAST(subject AS BLOB)) + length(CAST(${payload} AS BLOB))`;
1347
1368
  const totals = Schema.decodeUnknownSync(FactTotalsRow)(database.prepare(`SELECT COUNT(*) AS count, COALESCE(SUM(${size}), 0) AS bytes FROM ${table}`).get());
1348
- const oldest = database.prepare(`SELECT subject, ${size} AS bytes FROM ${table} ORDER BY ${age} ASC, subject ASC LIMIT 1`);
1369
+ const oldest = database.prepare(`SELECT subject, ${size} AS bytes, ${age} AS age FROM ${table} ORDER BY ${age} ASC, subject ASC LIMIT 1`);
1349
1370
  const remove = database.prepare(`DELETE FROM ${table} WHERE subject = ?`);
1350
1371
  let { bytes, count } = totals;
1351
1372
  let evicted = 0;
1352
1373
  while (count > workObservedFactMaxRecords || bytes > workObservedFactMaxBytes) {
1353
1374
  const row = Schema.decodeUnknownSync(EvictionRow)(oldest.get());
1375
+ newestEvicted = Math.max(newestEvicted, row.age);
1376
+ evicted += beforeRemove?.(row.subject) ?? 0;
1354
1377
  remove.run(row.subject);
1355
1378
  count -= 1;
1356
1379
  bytes -= row.bytes;
@@ -1361,9 +1384,32 @@ const writeObservations = (database, prepared) => {
1361
1384
  // The least recently read rows go first: a fact by its last confirmation,
1362
1385
  // a failure by its latest failed read.
1363
1386
  const evicted = evict("work_observed_facts", "confirmed_at", "record") +
1364
- evict("work_observed_failures", "last_at", "reason");
1387
+ evict("work_observed_failures", "last_at", "reason", (subject) => Number(removeDisputedFact.run(subject, subject).changes));
1388
+ if (newestEvicted > evictedThrough) {
1389
+ database.prepare(`INSERT INTO work_observed_eviction (singleton, evicted_through) VALUES (1, ?)
1390
+ ON CONFLICT (singleton) DO UPDATE SET evicted_through = max(evicted_through, excluded.evicted_through)`).run(newestEvicted);
1391
+ }
1392
+ // Reported last, after every write and eviction in this call: a stored or
1393
+ // unchanged fact that a later envelope replaced, or eviction removed, is no
1394
+ // longer the subject's fact and confirms nothing.
1395
+ // Only a subject's last accepted read can still be its fact: an earlier one
1396
+ // with the same content (A, B, A) was replaced in between.
1397
+ const lastAccepted = new Map();
1398
+ outcomes.forEach((outcome, index) => {
1399
+ if (outcome._tag === "stored" || outcome._tag === "unchanged")
1400
+ lastAccepted.set(outcome.subject, index);
1401
+ });
1402
+ const finalOutcomes = outcomes.map((outcome, index) => {
1403
+ if (outcome._tag !== "stored" && outcome._tag !== "unchanged")
1404
+ return outcome;
1405
+ if (lastAccepted.get(outcome.subject) !== index)
1406
+ return { _tag: "stale", subject: outcome.subject };
1407
+ const row = readFact.get(outcome.subject);
1408
+ const current = row === undefined ? undefined : Schema.decodeUnknownSync(StoredFactRow)(row);
1409
+ return current?.observationId === outcome.observationId ? outcome : { _tag: "stale", subject: outcome.subject };
1410
+ });
1365
1411
  database.exec("COMMIT");
1366
- return { evicted, outcomes };
1412
+ return { evicted, outcomes: finalOutcomes };
1367
1413
  }
1368
1414
  catch (cause) {
1369
1415
  if (database.isTransaction)
@@ -1419,6 +1465,7 @@ export class WorkStore {
1419
1465
  try {
1420
1466
  migrateLegacyAuthorityTables(database);
1421
1467
  const hadLaneOperationLedger = database.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'work_lane_operations'").get() !== undefined;
1468
+ const hadEvictionWatermark = database.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'work_observed_eviction'").get() !== undefined;
1422
1469
  database.exec(`
1423
1470
  CREATE TABLE IF NOT EXISTS work_goal_events (
1424
1471
  event_id TEXT PRIMARY KEY,
@@ -1553,12 +1600,31 @@ export class WorkStore {
1553
1600
  );
1554
1601
  CREATE INDEX IF NOT EXISTS work_observed_failures_age
1555
1602
  ON work_observed_failures (last_at, subject);
1603
+ CREATE TABLE IF NOT EXISTS work_observed_eviction (
1604
+ singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
1605
+ evicted_through INTEGER NOT NULL
1606
+ );
1556
1607
  `);
1557
1608
  requireUniqueSessionIndex(database);
1558
1609
  const columns = Schema.decodeUnknownSync(Schema.Array(Schema.Struct({ name: Schema.String })))(database.prepare("PRAGMA table_info(work_goal_events)").all());
1559
1610
  if (!columns.some(({ name }) => name === "transaction_id")) {
1560
1611
  database.exec("ALTER TABLE work_goal_events ADD COLUMN transaction_id TEXT");
1561
1612
  }
1613
+ if (!hadEvictionWatermark) {
1614
+ // Older stores evicted without a watermark, and may have kept a fact
1615
+ // whose dispute they evicted. Their reads are a cache of the
1616
+ // providers, so they are dropped and every one becomes stale; the
1617
+ // next pass reads them again, newer.
1618
+ database.exec(`
1619
+ INSERT INTO work_observed_eviction (singleton, evicted_through)
1620
+ SELECT 1, max(at) FROM (
1621
+ SELECT confirmed_at AS at FROM work_observed_facts
1622
+ UNION ALL SELECT last_at FROM work_observed_failures
1623
+ ) HAVING max(at) IS NOT NULL;
1624
+ DELETE FROM work_observed_facts;
1625
+ DELETE FROM work_observed_failures;
1626
+ `);
1627
+ }
1562
1628
  if (!hadLaneOperationLedger) {
1563
1629
  database.exec(`
1564
1630
  INSERT OR IGNORE INTO work_lane_operations
@@ -2783,9 +2849,16 @@ export class WorkStore {
2783
2849
  const headRow = this.#database.prepare(`SELECT record FROM work_goal_events WHERE goal_id = ?
2784
2850
  ORDER BY occurred_at DESC, event_id DESC LIMIT 1`).get(decoded.goal.id);
2785
2851
  const head = headRow === undefined ? null : Schema.decodeUnknownSync(WorkGoalCheckpoint)(JSON.parse(Schema.decodeUnknownSync(StoredEventRow)(headRow).record));
2786
- const factRow = this.#database.prepare("SELECT observation_id AS observationId FROM work_observed_facts WHERE subject = ?").get(guard.fact.subject);
2852
+ const factRow = this.#database.prepare(`SELECT observation_id AS observationId, confirmed_at AS confirmedAt
2853
+ FROM work_observed_facts WHERE subject = ?`).get(guard.fact.subject);
2787
2854
  const fact = factRow === undefined ? null : Schema.decodeUnknownSync(ObservationIdRow)(factRow);
2788
- if (head?.eventId !== guard.head.eventId || fact?.observationId !== guard.fact.observationId) {
2855
+ const failureRow = this.#database.prepare("SELECT last_at AS lastAt FROM work_observed_failures WHERE subject = ?").get(guard.fact.subject);
2856
+ const failedAt = failureRow === undefined
2857
+ ? null
2858
+ : Schema.decodeUnknownSync(FailureLastAtRow)(failureRow).lastAt;
2859
+ // A failed read recorded while the plan was made also makes it stale.
2860
+ const stillFresh = fact !== null && (failedAt === null || failedAt <= fact.confirmedAt);
2861
+ if (head?.eventId !== guard.head.eventId || fact?.observationId !== guard.fact.observationId || !stillFresh) {
2789
2862
  return reject(new WorkGoalRevisionConflictError({
2790
2863
  actualEventId: head?.eventId ?? null,
2791
2864
  actualUpdatedAt: head?.goal.updatedAt ?? null,
@@ -3968,7 +4041,8 @@ export class WorkStore {
3968
4041
  reconcilerEvents
3969
4042
  };
3970
4043
  });
3971
- reconcile = Effect.fn("WorkStore.reconcile")(function* () {
4044
+ reconcile = Effect.fn("WorkStore.reconcile")(function* (request) {
4045
+ const options = yield* Schema.decodeUnknownEffect(WorkReconcileOptions)(request).pipe(Effect.mapError(storeError("reconcile.options")));
3972
4046
  const source = yield* this.snapshotInput();
3973
4047
  if (workHistoryMaxEvents - source.events.length < workReconcilerHeadroom) {
3974
4048
  return yield* new WorkProjectionError({
@@ -3977,13 +4051,20 @@ export class WorkStore {
3977
4051
  reason: "capacity_exceeded"
3978
4052
  });
3979
4053
  }
4054
+ // A confirmation names the fact the caller read; one that is no longer the
4055
+ // subject's stored fact (replaced, evicted) is the caller's stale view.
4056
+ const current = new Map(source.facts.map((fact) => [fact.subject, fact.observationId]));
4057
+ const outdated = options.confirmed.filter(({ observationId, subject }) => current.get(subject) !== observationId);
4058
+ if (outdated.length > 0) {
4059
+ return yield* new WorkStoreError({ cause: outdated, operation: "reconcile.confirmed" });
4060
+ }
3980
4061
  // A goal is stamped by the reconciler at most once, whatever its facts
3981
4062
  // look like later: a reopened goal stays the owner's.
3982
4063
  const stamped = new Map(source.reconcilerEvents.map(({ eventId, goalId }) => [goalId, eventId]));
3983
4064
  const cryptoService = this.#cryptoService;
3984
4065
  const now = yield* Clock.currentTimeMillis;
3985
4066
  const appendAt = (checkpoint, guard) => this.appendAt(checkpoint, guard);
3986
- return yield* Effect.forEach(terminalCandidates(source.events, source.facts), Effect.fnUntraced(function* (candidate) {
4067
+ return yield* Effect.forEach(terminalCandidates(source.events, source.facts, source.failures, new Set(options.confirmed.map(({ observationId, subject }) => `${subject}\u0000${observationId}`))), Effect.fnUntraced(function* (candidate) {
3987
4068
  const goalId = candidate.head.goal.id;
3988
4069
  const previous = stamped.get(goalId);
3989
4070
  if (previous !== undefined)
@@ -4042,10 +4123,10 @@ export class WorkStore {
4042
4123
  observation: canonicalObservation(envelope.observation)
4043
4124
  })
4044
4125
  .observation);
4045
- const digest = yield* cryptoService.digest("SHA-256", utf8.encode(record)).pipe(Effect.mapError(storeError("observe.digest")));
4126
+ const observationId = yield* cryptoService.digest("SHA-256", utf8.encode(record)).pipe(Effect.map(Hex.encode), Effect.flatMap(Schema.decodeUnknownEffect(WorkObservationId)), Effect.mapError(storeError("observe.digest")));
4046
4127
  return {
4047
4128
  _tag: "fact",
4048
- observationId: Hex.encode(digest),
4129
+ observationId,
4049
4130
  observedAt: Math.min(envelope.observedAt, clockNow),
4050
4131
  record,
4051
4132
  subject