@stigmer/server 3.39.0 → 3.39.1-dev.20260928194002

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 (33) hide show
  1. package/dist/domain/agentinstance/steps.d.ts +3 -1
  2. package/dist/domain/agentinstance/steps.d.ts.map +1 -1
  3. package/dist/domain/agentinstance/steps.js +12 -6
  4. package/dist/domain/agentinstance/steps.js.map +1 -1
  5. package/dist/domain/plugin/controller.d.ts.map +1 -1
  6. package/dist/domain/plugin/controller.js +10 -5
  7. package/dist/domain/plugin/controller.js.map +1 -1
  8. package/dist/domain/skill/controller.d.ts.map +1 -1
  9. package/dist/domain/skill/controller.js +7 -3
  10. package/dist/domain/skill/controller.js.map +1 -1
  11. package/dist/domain/workflow/controller.js +6 -3
  12. package/dist/domain/workflow/controller.js.map +1 -1
  13. package/dist/domain/workflowinstance/controller.d.ts +2 -2
  14. package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
  15. package/dist/domain/workflowinstance/controller.js +10 -5
  16. package/dist/domain/workflowinstance/controller.js.map +1 -1
  17. package/dist/domain/workflowinstance/steps.d.ts +5 -3
  18. package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
  19. package/dist/domain/workflowinstance/steps.js +14 -9
  20. package/dist/domain/workflowinstance/steps.js.map +1 -1
  21. package/package.json +6 -6
  22. package/src/domain/agentinstance/__tests__/store-faults.test.ts +69 -18
  23. package/src/domain/agentinstance/steps.ts +12 -6
  24. package/src/domain/plugin/__tests__/store-faults.test.ts +104 -0
  25. package/src/domain/plugin/controller.ts +10 -5
  26. package/src/domain/skill/__tests__/store-faults.test.ts +103 -0
  27. package/src/domain/skill/controller.ts +7 -3
  28. package/src/domain/workflow/__tests__/store-faults.test.ts +107 -0
  29. package/src/domain/workflow/controller.ts +6 -3
  30. package/src/domain/workflowinstance/__tests__/store-faults.test.ts +172 -0
  31. package/src/domain/workflowinstance/controller.ts +12 -7
  32. package/src/domain/workflowinstance/steps.ts +14 -10
  33. package/src/pipeline/__tests__/blind-not-found.test.ts +4 -20
@@ -99,6 +99,7 @@ import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-
99
99
  import { newValidateProtoStep } from "../../pipeline/steps/validation.js";
100
100
  import { newValidateVisibilityUpdateStep } from "../../pipeline/steps/validate-visibility.js";
101
101
  import { newDeleteVersionArchivesStep } from "../../pipeline/steps/version-archive.js";
102
+ import { ResourceNotFoundError } from "../../store/interface.js";
102
103
  import type { Store } from "../../store/interface.js";
103
104
  import { MAX_ZIP_SIZE, TRANSFER_LANE_NOT_CONFIGURED } from "./constants.js";
104
105
  import {
@@ -463,7 +464,7 @@ async function updateVisibility(
463
464
  return reqCtx.get(UPDATE_VISIBILITY_SKILL_KEY) as Skill;
464
465
  }
465
466
 
466
- /** Loads the skill by resource_id; ANY load failure → NotFound. */
467
+ /** Loads the skill by resource_id; a missing one answers NotFound, a store fault Internal. */
467
468
  function newLoadSkillForVisibilityUpdateStep(
468
469
  store: Store,
469
470
  ): PipelineStep<UpdateVisibilityDesc> {
@@ -478,8 +479,11 @@ function newLoadSkillForVisibilityUpdateStep(
478
479
  input.resourceId,
479
480
  SkillSchema,
480
481
  );
481
- } catch {
482
- throw notFoundError("skill", input.resourceId);
482
+ } catch (error) {
483
+ if (error instanceof ResourceNotFoundError) {
484
+ throw notFoundError("skill", input.resourceId);
485
+ }
486
+ throw internalError(error, "failed to load skill");
483
487
  }
484
488
  ctx.set(UPDATE_VISIBILITY_SKILL_KEY, skill);
485
489
  },
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Pins the store-fault contract of the workflow's visibility-update load: a
3
+ * typed ResourceNotFoundError answers NotFound with the domain's pinned copy
4
+ * (`workflow not found: <id>`), and any other store failure is an
5
+ * infrastructure fault answered as a sanitized Internal, never a NotFound that
6
+ * tells a client the workflow does not exist (stigmer/stigmer#1345).
7
+ *
8
+ * The surface is updateVisibility, reached through the registered handler on
9
+ * an in-process router. The composed suites reach only a real store, which
10
+ * cannot fail selectively, so it runs here against a store whose read throws.
11
+ * The validator and the default-instance creator are untouchable: a load that
12
+ * fails must stop the call before anything past it runs.
13
+ *
14
+ * Out of scope: the NotFound copy itself (wire contract).
15
+ */
16
+ import type { Client, ConnectError } from "@connectrpc/connect";
17
+ import { Code, createClient, createRouterTransport } from "@connectrpc/connect";
18
+ import { describe, expect, it } from "vitest";
19
+
20
+ import { WorkflowCommandController } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/command_pb";
21
+ import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
22
+
23
+ import { createLogger } from "../../../boot/logger.js";
24
+ import { createApiResourceInterceptor } from "../../../pipeline/interceptors/apiresource.js";
25
+ import { createVerifierChainInterceptor } from "../../../pipeline/interceptors/auth.js";
26
+ import {
27
+ errorOf,
28
+ failingStore,
29
+ untouchable,
30
+ } from "../../../pipeline/__tests__/support.js";
31
+ import { newPermissiveSingleTeamAuthorizer } from "../../../pipeline/steps/authorize.js";
32
+ import { ResourceNotFoundError } from "../../../store/interface.js";
33
+ import type { Store } from "../../../store/interface.js";
34
+
35
+ import { registerWorkflowServices } from "../controller.js";
36
+
37
+ const silentLogger = createLogger({
38
+ level: "error",
39
+ pretty: false,
40
+ write: () => {},
41
+ });
42
+
43
+ const WORKFLOW_ID = "wfl_storefault";
44
+
45
+ const NOT_FOUND_COPY = `workflow not found: ${WORKFLOW_ID}`;
46
+ const LOAD_FAULT_COPY = "failed to load workflow";
47
+
48
+ const MISSING = (): Error =>
49
+ new ResourceNotFoundError(`workflow/${WORKFLOW_ID}`);
50
+ const LOCKED = (): Error => new Error("SQLITE_BUSY: database is locked");
51
+
52
+ /**
53
+ * The registered handlers on an in-process router: the verifier chain stamps
54
+ * the trusted-local caller and the apiresource interceptor the kind, then
55
+ * Authorize and ValidateProto run and the load is the first step that reads
56
+ * the store.
57
+ */
58
+ function workflowCommand(
59
+ store: Store,
60
+ ): Client<typeof WorkflowCommandController> {
61
+ const transport = createRouterTransport(
62
+ (router) => {
63
+ registerWorkflowServices(router, {
64
+ store,
65
+ logger: silentLogger,
66
+ authorizer: newPermissiveSingleTeamAuthorizer(),
67
+ authorizationLifecycle: undefined,
68
+ validator: untouchable("validator"),
69
+ workflowInstanceCreator: untouchable("workflowInstanceCreator"),
70
+ });
71
+ },
72
+ {
73
+ router: {
74
+ interceptors: [
75
+ createVerifierChainInterceptor([], [], silentLogger),
76
+ createApiResourceInterceptor(),
77
+ ],
78
+ },
79
+ },
80
+ );
81
+ return createClient(WorkflowCommandController, transport);
82
+ }
83
+
84
+ describe("updateVisibility — LoadWorkflowForVisibilityUpdate", () => {
85
+ function surfaceError(store: Store): Promise<ConnectError> {
86
+ return errorOf(() =>
87
+ workflowCommand(store).updateVisibility({
88
+ resourceId: WORKFLOW_ID,
89
+ visibility: ApiResourceVisibility.visibility_private,
90
+ }),
91
+ );
92
+ }
93
+
94
+ it("a missing workflow answers NotFound with the domain's copy", async () => {
95
+ const error = await surfaceError(failingStore(MISSING()));
96
+
97
+ expect(error.code).toBe(Code.NotFound);
98
+ expect(error.rawMessage).toBe(NOT_FOUND_COPY);
99
+ });
100
+
101
+ it("any other store failure answers a sanitized Internal", async () => {
102
+ const error = await surfaceError(failingStore(LOCKED()));
103
+
104
+ expect(error.code).toBe(Code.Internal);
105
+ expect(error.rawMessage).toBe(LOAD_FAULT_COPY);
106
+ });
107
+ });
@@ -492,7 +492,7 @@ async function updateVisibility(
492
492
  return reqCtx.get(UPDATE_VISIBILITY_WORKFLOW_KEY) as Workflow;
493
493
  }
494
494
 
495
- /** Loads the workflow by resource_id; ANY load failure → NotFound. */
495
+ /** Loads the workflow by resource_id; a missing one answers NotFound, a store fault Internal. */
496
496
  function newLoadWorkflowForVisibilityUpdateStep(
497
497
  store: Store,
498
498
  ): PipelineStep<UpdateVisibilityDesc> {
@@ -507,8 +507,11 @@ function newLoadWorkflowForVisibilityUpdateStep(
507
507
  input.resourceId,
508
508
  WorkflowSchema,
509
509
  );
510
- } catch {
511
- throw notFoundError("workflow", input.resourceId);
510
+ } catch (error) {
511
+ if (error instanceof ResourceNotFoundError) {
512
+ throw notFoundError("workflow", input.resourceId);
513
+ }
514
+ throw internalError(error, "failed to load workflow");
512
515
  }
513
516
  ctx.set(UPDATE_VISIBILITY_WORKFLOW_KEY, workflow);
514
517
  },
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Pins the store-fault contract of the workflow instance's loads. The shared
3
+ * targeted-update load (updateVisibility and updateExecutionVisibility): a
4
+ * typed ResourceNotFoundError answers NotFound with the domain's pinned copy
5
+ * (`workflow instance not found: <id>`), and any other store failure is an
6
+ * infrastructure fault answered as a sanitized Internal, never a NotFound that
7
+ * tells a client the instance does not exist (stigmer/stigmer#1345). Create's
8
+ * parent-workflow load reads the workflow through the in-process query
9
+ * client, so the store's typed miss arrives as a Connect NotFound: that
10
+ * answers the pinned `Workflow not found: <id>`, and any other failure an
11
+ * Internal, never a missing parent (stigmer/stigmer#1351).
12
+ *
13
+ * Every surface is reached through the registered handler on an in-process
14
+ * router. The composed suites reach only a real store, which cannot fail
15
+ * selectively, so the updates run against a store whose read throws and
16
+ * create against a parent loader whose read throws. Whatever the surface does
17
+ * not need is untouchable: a load that fails must stop the call before
18
+ * anything past it runs.
19
+ *
20
+ * Out of scope: the NotFound copies themselves (wire contract).
21
+ */
22
+ import type { Client } from "@connectrpc/connect";
23
+ import {
24
+ Code,
25
+ ConnectError,
26
+ createClient,
27
+ createRouterTransport,
28
+ } from "@connectrpc/connect";
29
+ import { describe, expect, it } from "vitest";
30
+
31
+ import { WorkflowInstanceCommandController } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/command_pb";
32
+ import { WorkflowExecutionVisibility } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/spec_pb";
33
+ import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
34
+
35
+ import { createLogger } from "../../../boot/logger.js";
36
+ import { createApiResourceInterceptor } from "../../../pipeline/interceptors/apiresource.js";
37
+ import { createVerifierChainInterceptor } from "../../../pipeline/interceptors/auth.js";
38
+ import {
39
+ errorOf,
40
+ failingStore,
41
+ untouchable,
42
+ } from "../../../pipeline/__tests__/support.js";
43
+ import { INTERNAL_FALLBACK_MESSAGE } from "../../../pipeline/pipeline.js";
44
+ import { newPermissiveSingleTeamAuthorizer } from "../../../pipeline/steps/authorize.js";
45
+ import { ResourceNotFoundError } from "../../../store/interface.js";
46
+ import type { Store } from "../../../store/interface.js";
47
+
48
+ import { registerWorkflowInstanceServices } from "../controller.js";
49
+ import type { ParentWorkflowLoaderProvider } from "../steps.js";
50
+
51
+ const silentLogger = createLogger({
52
+ level: "error",
53
+ pretty: false,
54
+ write: () => {},
55
+ });
56
+
57
+ const INSTANCE_ID = "win_storefault";
58
+ const WORKFLOW_ID = "wfl_storefault";
59
+
60
+ const NOT_FOUND_COPY = `workflow instance not found: ${INSTANCE_ID}`;
61
+ const LOAD_FAULT_COPY = "failed to load workflow instance";
62
+ const PARENT_NOT_FOUND_COPY = `Workflow not found: ${WORKFLOW_ID}`;
63
+ const PARENT_LOAD_FAULT_COPY = "failed to load parent workflow";
64
+
65
+ const MISSING = (): Error =>
66
+ new ResourceNotFoundError(`workflow_instance/${INSTANCE_ID}`);
67
+ const LOCKED = (): Error => new Error("SQLITE_BUSY: database is locked");
68
+
69
+ /** What the workflow query's `get` answers for a missing and a faulted workflow. */
70
+ const PARENT_MISSING = (): Error =>
71
+ new ConnectError(`Workflow not found: ${WORKFLOW_ID}`, Code.NotFound);
72
+ const PARENT_FAULTED = (): Error =>
73
+ new ConnectError(INTERNAL_FALLBACK_MESSAGE, Code.Internal);
74
+
75
+ /**
76
+ * The registered handlers on an in-process router: the verifier chain stamps
77
+ * the trusted-local caller and the apiresource interceptor the kind, then
78
+ * Authorize and ValidateProto run and the load is the first step that reads
79
+ * the store or the parent.
80
+ */
81
+ function instanceCommand(
82
+ store: Store,
83
+ parentWorkflowLoader: ParentWorkflowLoaderProvider = untouchable(
84
+ "parentWorkflowLoader",
85
+ ),
86
+ ): Client<typeof WorkflowInstanceCommandController> {
87
+ const transport = createRouterTransport(
88
+ (router) => {
89
+ registerWorkflowInstanceServices(router, {
90
+ store,
91
+ logger: silentLogger,
92
+ authorizer: newPermissiveSingleTeamAuthorizer(),
93
+ authorizationLifecycle: undefined,
94
+ parentWorkflowLoader,
95
+ listReadScope: undefined,
96
+ });
97
+ },
98
+ {
99
+ router: {
100
+ interceptors: [
101
+ createVerifierChainInterceptor([], [], silentLogger),
102
+ createApiResourceInterceptor(),
103
+ ],
104
+ },
105
+ },
106
+ );
107
+ return createClient(WorkflowInstanceCommandController, transport);
108
+ }
109
+
110
+ describe.each([
111
+ {
112
+ surface: "updateVisibility — LoadInstanceForVisibilityUpdate",
113
+ call: (store: Store) =>
114
+ instanceCommand(store).updateVisibility({
115
+ resourceId: INSTANCE_ID,
116
+ visibility: ApiResourceVisibility.visibility_private,
117
+ }),
118
+ },
119
+ {
120
+ surface:
121
+ "updateExecutionVisibility — LoadInstanceForExecutionVisibilityUpdate",
122
+ call: (store: Store) =>
123
+ instanceCommand(store).updateExecutionVisibility({
124
+ resourceId: INSTANCE_ID,
125
+ executionVisibility: WorkflowExecutionVisibility.private,
126
+ }),
127
+ },
128
+ ])("$surface", ({ call }) => {
129
+ it("a missing workflow instance answers NotFound with the domain's copy", async () => {
130
+ const error = await errorOf(() => call(failingStore(MISSING())));
131
+
132
+ expect(error.code).toBe(Code.NotFound);
133
+ expect(error.rawMessage).toBe(NOT_FOUND_COPY);
134
+ });
135
+
136
+ it("any other store failure answers a sanitized Internal", async () => {
137
+ const error = await errorOf(() => call(failingStore(LOCKED())));
138
+
139
+ expect(error.code).toBe(Code.Internal);
140
+ expect(error.rawMessage).toBe(LOAD_FAULT_COPY);
141
+ });
142
+ });
143
+
144
+ describe("create — LoadParentWorkflow", () => {
145
+ function surfaceError(parentError: Error): Promise<ConnectError> {
146
+ const failingParent: ParentWorkflowLoaderProvider = () => ({
147
+ get: () => Promise.reject(parentError),
148
+ });
149
+ return errorOf(() =>
150
+ instanceCommand(untouchable("store"), failingParent).create({
151
+ apiVersion: "agentic.stigmer.ai/v1",
152
+ kind: "WorkflowInstance",
153
+ metadata: { name: "Store Fault Instance", org: "org_storefault" },
154
+ spec: { workflowId: WORKFLOW_ID },
155
+ }),
156
+ );
157
+ }
158
+
159
+ it("a missing parent workflow answers NotFound with the pinned copy", async () => {
160
+ const error = await surfaceError(PARENT_MISSING());
161
+
162
+ expect(error.code).toBe(Code.NotFound);
163
+ expect(error.rawMessage).toBe(PARENT_NOT_FOUND_COPY);
164
+ });
165
+
166
+ it("any other parent-load failure answers a sanitized Internal", async () => {
167
+ const error = await surfaceError(PARENT_FAULTED());
168
+
169
+ expect(error.code).toBe(Code.Internal);
170
+ expect(error.rawMessage).toBe(PARENT_LOAD_FAULT_COPY);
171
+ });
172
+ });
@@ -13,8 +13,8 @@
13
13
  *
14
14
  * Pipeline per RPC mirrors the Go step chains character-for-character.
15
15
  * Proven by workflowinstance.conformance.test.ts
16
- * (CONFORMANCE_TARGET=local) and the family test
17
- * ../workflow/__tests__/workflow.test.ts (the mutual edge makes the two
16
+ * (CONFORMANCE_TARGET=local), __tests__/store-faults.test.ts and the family
17
+ * test ../workflow/__tests__/workflow.test.ts (the mutual edge makes the two
18
18
  * domains one testable unit).
19
19
  */
20
20
  import type { ConnectRouter, HandlerContext } from "@connectrpc/connect";
@@ -104,6 +104,7 @@ import {
104
104
  newValidateVisibilityStep,
105
105
  newValidateVisibilityUpdateStep,
106
106
  } from "../../pipeline/steps/validate-visibility.js";
107
+ import { ResourceNotFoundError } from "../../store/interface.js";
107
108
  import type { Store } from "../../store/interface.js";
108
109
  import { workflowInstanceSearchExtractor } from "./search-extractor.js";
109
110
  import {
@@ -573,9 +574,10 @@ function newSetInstanceExecutionVisibilityStep(): PipelineStep<UpdateExecutionVi
573
574
  // ---------------------------------------------------------------------------
574
575
 
575
576
  /**
576
- * Loads the instance by resource_id; ANY load failure → NotFound. The
577
- * accessor keeps the input shape compiler-checked (both targeted-update
578
- * inputs carry resource_id, but the compiler should prove it, not a cast).
577
+ * Loads the instance by resource_id; a missing one answers NotFound, a store
578
+ * fault Internal. The accessor keeps the input shape compiler-checked (both
579
+ * targeted-update inputs carry resource_id, but the compiler should prove it,
580
+ * not a cast).
579
581
  */
580
582
  function newLoadInstanceStep<Desc extends DescMessage>(
581
583
  store: Store,
@@ -594,8 +596,11 @@ function newLoadInstanceStep<Desc extends DescMessage>(
594
596
  resourceId,
595
597
  WorkflowInstanceSchema,
596
598
  );
597
- } catch {
598
- throw notFoundError("workflow instance", resourceId);
599
+ } catch (error) {
600
+ if (error instanceof ResourceNotFoundError) {
601
+ throw notFoundError("workflow instance", resourceId);
602
+ }
603
+ throw internalError(error, "failed to load workflow instance");
599
604
  }
600
605
  ctx.set(instanceKey, instance);
601
606
  },
@@ -8,7 +8,7 @@
8
8
  * the family test ../workflow/__tests__/workflow.test.ts (the mutual edge
9
9
  * makes the two domains one testable unit).
10
10
  */
11
- import { ConnectError } from "@connectrpc/connect";
11
+ import { Code, ConnectError } from "@connectrpc/connect";
12
12
  import type { DescMessage } from "@bufbuild/protobuf";
13
13
 
14
14
  import { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/api_pb";
@@ -55,9 +55,11 @@ export type ParentWorkflowLoaderProvider = () => ParentWorkflowLoader;
55
55
 
56
56
  /**
57
57
  * LoadParentWorkflow — create.go: loads the workflow the instance
58
- * materializes and stashes it for the same-org rule. ANY load failure maps
59
- * to NotFound("Workflow", id) — Go folds every client error into that arm
60
- * (capital-W copy is the wire contract).
58
+ * materializes and stashes it for the same-org rule. The workflow is read
59
+ * through the in-process query client, so a missing one arrives as a Connect
60
+ * NotFound and answers NotFound("Workflow", id) (the capital-W copy is the
61
+ * wire contract); any other failure is a fault answered as Internal, never a
62
+ * missing parent.
61
63
  */
62
64
  export function newLoadParentWorkflowStep(
63
65
  loaderProvider: ParentWorkflowLoaderProvider,
@@ -74,12 +76,14 @@ export function newLoadParentWorkflowStep(
74
76
  try {
75
77
  parent = await loaderProvider().get(workflowId);
76
78
  } catch (error) {
77
- logger.warn("Parent workflow not found", {
78
- error:
79
- error instanceof ConnectError ? error.rawMessage : String(error),
80
- workflowId,
81
- });
82
- throw notFoundError("Workflow", workflowId);
79
+ if (error instanceof ConnectError && error.code === Code.NotFound) {
80
+ logger.warn("Parent workflow not found", {
81
+ error: error.rawMessage,
82
+ workflowId,
83
+ });
84
+ throw notFoundError("Workflow", workflowId);
85
+ }
86
+ throw internalError(error, "failed to load parent workflow");
83
87
  }
84
88
 
85
89
  ctx.set(PARENT_WORKFLOW_KEY, parent);
@@ -20,9 +20,8 @@
20
20
  *
21
21
  * The scan parses each module with the TypeScript compiler API rather than a
22
22
  * regular expression, because a catch block's extent (nested braces, a log
23
- * line before the throw) is a syntax question. `PENDING` is the list of known
24
- * blind sites still to be fixed; the scan must equal it exactly, so a new
25
- * blind site fails here, and so does a fixed site still listed.
23
+ * line before the throw) is a syntax question. The scan must find no blind
24
+ * site at all, so a new one fails here with its module and line.
26
25
  */
27
26
  import { readFileSync, readdirSync } from "node:fs";
28
27
  import path from "node:path";
@@ -34,19 +33,6 @@ import { describe, expect, it } from "vitest";
34
33
  const HERE = path.dirname(fileURLToPath(import.meta.url));
35
34
  const SRC = path.resolve(HERE, "../..");
36
35
 
37
- /** Known blind sites by module (relative to `src`), with their count. */
38
- const PENDING: ReadonlyMap<string, number> = new Map([
39
- // Store loads, stigmer/stigmer#1345 (fixed domain by domain).
40
- ["domain/plugin/controller.ts", 1],
41
- ["domain/skill/controller.ts", 1],
42
- ["domain/workflow/controller.ts", 1],
43
- ["domain/workflowinstance/controller.ts", 1],
44
- // Parent loads through the in-process chain that fold every RPC error,
45
- // validation included, stigmer/stigmer#1351.
46
- ["domain/agentinstance/steps.ts", 1],
47
- ["domain/workflowinstance/steps.ts", 1],
48
- ]);
49
-
50
36
  interface BlindSite {
51
37
  readonly module: string;
52
38
  readonly line: number;
@@ -258,7 +244,7 @@ describe("the blind-NotFound rule", () => {
258
244
  });
259
245
 
260
246
  describe("the server source", () => {
261
- it("has no blind NotFound beyond the pending list, and the list names only live sites", () => {
247
+ it("has no blind NotFound", () => {
262
248
  const sources = serverSources();
263
249
  const constructors = notFoundConstructors(sources);
264
250
  const found = new Map<string, number[]>();
@@ -278,8 +264,6 @@ describe("the server source", () => {
278
264
  const where = [...found]
279
265
  .flatMap(([module, lines]) => lines.map((line) => `${module}:${line}`))
280
266
  .join("\n");
281
- expect(counts, `blind NotFound sites found:\n${where}`).toEqual(
282
- Object.fromEntries(PENDING),
283
- );
267
+ expect(counts, `blind NotFound sites found:\n${where}`).toEqual({});
284
268
  });
285
269
  });