@pome-sh/checks 0.3.10 → 0.4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @pome-sh/checks
2
2
 
3
+ ## 0.4.1 — 2026-09-01
4
+
5
+ Doc-only: a build-config comment no longer references the removed
6
+ `@pome-sh/adapter-claude-sdk` package. No API or behaviour change.
7
+
8
+ ## 0.4.0 — 2026-08-29
9
+
10
+ **Every twin's `parseSeed` refuses a key no seed field matches** (F-1689). The
11
+ github, slack and stripe schemas this package re-exports are `z.strictObject` at
12
+ every level; gmail and linear already were. A misspelled field used to be an
13
+ absence rather than an error — the seed parsed clean, the twin booted, and the
14
+ route that should have served the field answered `[]`.
15
+
16
+ This is the SQLite-free door pome-cloud reaches `parseSeed` through, so the
17
+ refusal lands on the hosted seed path with it. `packages/checks/test/seed-strictness.test.ts`
18
+ is the gate: it walks each twin's own zod tree, so a nested object added later
19
+ without strictness reds even though nothing in that file names it.
20
+
21
+ All five `parseSeed`s drop a top-level `_meta` before validating — Pome's own
22
+ provenance block, dropped rather than declared so it stays out of each schema's
23
+ declared field set.
24
+
25
+ `@pome-sh/twin-stripe/seed` is a zod-only leaf now (F-584): `applySeed` and its
26
+ row inserts moved to that twin's `apply-seed.ts`, so the module this package
27
+ bundles for `stripe.seedSchema` no longer reaches `./domain/schema.js`. This
28
+ package never re-exported `applySeed` — `surface.test.ts` asserts it does not —
29
+ so nothing it serves changes. What changes is that the declaration it bundles is
30
+ now reachable from a consumer with no SQLite, which is what let the CLI stop
31
+ hand-copying the stripe seed shape.
32
+
33
+ `slack` gains the `SlackStateSeed` type, matching the other four twins.
34
+
35
+ `github.parseSeed` refuses a seed that claims one number for two entities in a
36
+ repository (F-1153) — an issue and a pull request, two pull requests, or two
37
+ issues. Issues and pull requests share one per-repo counter, so a number names
38
+ one entity or the other. This is a NEW refusal on a seed that parsed clean
39
+ before, and it is what makes the applier's renumber unambiguous.
40
+
3
41
  ## 0.3.10 — 2026-08-29
4
42
 
5
43
  **Comment only.** The `stripe.refund-count` / `stripe.refund-exists` source file
@@ -23,7 +23,7 @@ export declare const failureInjectionRuleSchema: z.ZodObject<{
23
23
  }>>;
24
24
  status: z.ZodNumber;
25
25
  body: z.ZodUnknown;
26
- }, z.core.$strip>;
26
+ }, z.core.$strict>;
27
27
  export type FailureInjectionStore = {
28
28
  setRules(rules: FailureInjectionRule[]): void;
29
29
  clear(): void;
@@ -8,7 +8,7 @@ export declare const seedSchema: z.ZodObject<{
8
8
  Organization: "Organization";
9
9
  }>>;
10
10
  name: z.ZodDefault<z.ZodString>;
11
- }, z.core.$strip>>>;
11
+ }, z.core.$strict>>>;
12
12
  repositories: z.ZodArray<z.ZodObject<{
13
13
  owner: z.ZodString;
14
14
  name: z.ZodString;
@@ -20,13 +20,13 @@ export declare const seedSchema: z.ZodObject<{
20
20
  name: z.ZodString;
21
21
  color: z.ZodDefault<z.ZodString>;
22
22
  description: z.ZodDefault<z.ZodString>;
23
- }, z.core.$strip>>>;
23
+ }, z.core.$strict>>>;
24
24
  files: z.ZodDefault<z.ZodArray<z.ZodObject<{
25
25
  path: z.ZodString;
26
26
  content: z.ZodOptional<z.ZodString>;
27
27
  branch: z.ZodOptional<z.ZodString>;
28
28
  renamed_from: z.ZodOptional<z.ZodString>;
29
- }, z.core.$strip>>>;
29
+ }, z.core.$strict>>>;
30
30
  milestones: z.ZodDefault<z.ZodArray<z.ZodObject<{
31
31
  number: z.ZodOptional<z.ZodNumber>;
32
32
  title: z.ZodString;
@@ -36,11 +36,11 @@ export declare const seedSchema: z.ZodObject<{
36
36
  closed: "closed";
37
37
  }>>;
38
38
  due_on: z.ZodOptional<z.ZodString>;
39
- }, z.core.$strip>>>;
39
+ }, z.core.$strict>>>;
40
40
  tags: z.ZodDefault<z.ZodArray<z.ZodObject<{
41
41
  name: z.ZodString;
42
42
  target: z.ZodOptional<z.ZodString>;
43
- }, z.core.$strip>>>;
43
+ }, z.core.$strict>>>;
44
44
  releases: z.ZodDefault<z.ZodArray<z.ZodObject<{
45
45
  tag_name: z.ZodString;
46
46
  name: z.ZodOptional<z.ZodString>;
@@ -49,7 +49,7 @@ export declare const seedSchema: z.ZodObject<{
49
49
  draft: z.ZodDefault<z.ZodBoolean>;
50
50
  prerelease: z.ZodDefault<z.ZodBoolean>;
51
51
  author: z.ZodOptional<z.ZodString>;
52
- }, z.core.$strip>>>;
52
+ }, z.core.$strict>>>;
53
53
  issues: z.ZodDefault<z.ZodArray<z.ZodObject<{
54
54
  number: z.ZodOptional<z.ZodNumber>;
55
55
  title: z.ZodString;
@@ -63,8 +63,8 @@ export declare const seedSchema: z.ZodObject<{
63
63
  comments: z.ZodDefault<z.ZodArray<z.ZodObject<{
64
64
  body: z.ZodString;
65
65
  author: z.ZodOptional<z.ZodString>;
66
- }, z.core.$strip>>>;
67
- }, z.core.$strip>>>;
66
+ }, z.core.$strict>>>;
67
+ }, z.core.$strict>>>;
68
68
  pull_requests: z.ZodDefault<z.ZodArray<z.ZodObject<{
69
69
  number: z.ZodOptional<z.ZodNumber>;
70
70
  title: z.ZodString;
@@ -84,7 +84,7 @@ export declare const seedSchema: z.ZodObject<{
84
84
  COMMENTED: "COMMENTED";
85
85
  }>>;
86
86
  body: z.ZodDefault<z.ZodString>;
87
- }, z.core.$strip>>>;
87
+ }, z.core.$strict>>>;
88
88
  statuses: z.ZodDefault<z.ZodArray<z.ZodObject<{
89
89
  context: z.ZodDefault<z.ZodString>;
90
90
  state: z.ZodDefault<z.ZodEnum<{
@@ -94,11 +94,11 @@ export declare const seedSchema: z.ZodObject<{
94
94
  pending: "pending";
95
95
  }>>;
96
96
  description: z.ZodDefault<z.ZodString>;
97
- }, z.core.$strip>>>;
97
+ }, z.core.$strict>>>;
98
98
  comments: z.ZodDefault<z.ZodArray<z.ZodObject<{
99
99
  body: z.ZodString;
100
100
  author: z.ZodOptional<z.ZodString>;
101
- }, z.core.$strip>>>;
101
+ }, z.core.$strict>>>;
102
102
  review_comments: z.ZodDefault<z.ZodArray<z.ZodObject<{
103
103
  body: z.ZodString;
104
104
  path: z.ZodString;
@@ -108,10 +108,10 @@ export declare const seedSchema: z.ZodObject<{
108
108
  RIGHT: "RIGHT";
109
109
  }>>;
110
110
  author: z.ZodOptional<z.ZodString>;
111
- }, z.core.$strip>>>;
112
- }, z.core.$strip>>>;
113
- }, z.core.$strip>>;
114
- }, z.core.$strip>;
111
+ }, z.core.$strict>>>;
112
+ }, z.core.$strict>>>;
113
+ }, z.core.$strict>>;
114
+ }, z.core.$strict>;
115
115
  export type ParsedGitHubStateSeed = z.output<typeof seedSchema>;
116
116
  export declare function parseSeed(input: unknown): ParsedGitHubStateSeed;
117
117
  /**
@@ -1,11 +1,12 @@
1
1
  import { z } from "zod";
2
2
  import type { SlackStateSeed } from "./types.js";
3
+ export type { SlackStateSeed } from "./types.js";
3
4
  export declare const seedSchema: z.ZodObject<{
4
5
  team: z.ZodPrefault<z.ZodObject<{
5
6
  id: z.ZodOptional<z.ZodString>;
6
7
  name: z.ZodDefault<z.ZodString>;
7
8
  domain: z.ZodDefault<z.ZodString>;
8
- }, z.core.$strip>>;
9
+ }, z.core.$strict>>;
9
10
  users: z.ZodDefault<z.ZodArray<z.ZodObject<{
10
11
  id: z.ZodOptional<z.ZodString>;
11
12
  name: z.ZodString;
@@ -15,7 +16,7 @@ export declare const seedSchema: z.ZodObject<{
15
16
  is_admin: z.ZodDefault<z.ZodBoolean>;
16
17
  tz: z.ZodDefault<z.ZodString>;
17
18
  profile: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
18
- }, z.core.$strip>>>;
19
+ }, z.core.$strict>>>;
19
20
  channels: z.ZodDefault<z.ZodArray<z.ZodObject<{
20
21
  id: z.ZodOptional<z.ZodString>;
21
22
  name: z.ZodString;
@@ -32,9 +33,9 @@ export declare const seedSchema: z.ZodObject<{
32
33
  reactions: z.ZodDefault<z.ZodArray<z.ZodObject<{
33
34
  name: z.ZodString;
34
35
  user: z.ZodString;
35
- }, z.core.$strip>>>;
36
- }, z.core.$strip>>>;
37
- }, z.core.$strip>>>;
36
+ }, z.core.$strict>>>;
37
+ }, z.core.$strict>>>;
38
+ }, z.core.$strict>>>;
38
39
  files: z.ZodDefault<z.ZodArray<z.ZodObject<{
39
40
  id: z.ZodOptional<z.ZodString>;
40
41
  name: z.ZodString;
@@ -43,13 +44,13 @@ export declare const seedSchema: z.ZodObject<{
43
44
  user: z.ZodOptional<z.ZodString>;
44
45
  channels: z.ZodDefault<z.ZodArray<z.ZodString>>;
45
46
  content: z.ZodOptional<z.ZodString>;
46
- }, z.core.$strip>>>;
47
+ }, z.core.$strict>>>;
47
48
  emoji: z.ZodDefault<z.ZodArray<z.ZodObject<{
48
49
  name: z.ZodString;
49
50
  url: z.ZodOptional<z.ZodString>;
50
51
  alias: z.ZodOptional<z.ZodString>;
51
- }, z.core.$strip>>>;
52
- }, z.core.$strip>;
52
+ }, z.core.$strict>>>;
53
+ }, z.core.$strict>;
53
54
  export declare function parseSeed(input: unknown): SlackStateSeed;
54
55
  /**
55
56
  * Boot-time seed loader: prefer `POME_SEED_JSON` env (set by the cloud
@@ -1,6 +1,5 @@
1
1
  import { z } from "zod";
2
- import { type FailureInjectionStore } from "../../sdk/failure-injection-rules.js";
3
- import type { SeedState, TwinStripeDatabase } from "./types.js";
2
+ import type { SeedState } from "./types.js";
4
3
  export type { SeedState } from "./types.js";
5
4
  export declare const DEFAULT_SID = "default";
6
5
  export declare const DEFAULT_API_KEY = "sk_test_pome_default";
@@ -31,7 +30,7 @@ declare const paymentIntentSeedSchema: z.ZodObject<{
31
30
  updated: z.ZodNumber;
32
31
  canceled_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
33
32
  captured_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
34
- }, z.core.$strip>;
33
+ }, z.core.$strict>;
35
34
  declare const chargeSeedSchema: z.ZodObject<{
36
35
  id: z.ZodString;
37
36
  account_id: z.ZodString;
@@ -48,7 +47,7 @@ declare const chargeSeedSchema: z.ZodObject<{
48
47
  captured: z.ZodDefault<z.ZodBoolean>;
49
48
  currency: z.ZodString;
50
49
  created: z.ZodNumber;
51
- }, z.core.$strip>;
50
+ }, z.core.$strict>;
52
51
  declare const refundSeedSchema: z.ZodObject<{
53
52
  id: z.ZodString;
54
53
  account_id: z.ZodString;
@@ -66,7 +65,7 @@ declare const refundSeedSchema: z.ZodObject<{
66
65
  balance_transaction_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
67
66
  idempotency_key: z.ZodOptional<z.ZodNullable<z.ZodString>>;
68
67
  created: z.ZodNumber;
69
- }, z.core.$strip>;
68
+ }, z.core.$strict>;
70
69
  declare const balanceTransactionSeedSchema: z.ZodObject<{
71
70
  id: z.ZodString;
72
71
  account_id: z.ZodString;
@@ -83,7 +82,7 @@ declare const balanceTransactionSeedSchema: z.ZodObject<{
83
82
  available: "available";
84
83
  }>>;
85
84
  created: z.ZodNumber;
86
- }, z.core.$strip>;
85
+ }, z.core.$strict>;
87
86
  export type PaymentIntentSeed = z.infer<typeof paymentIntentSeedSchema>;
88
87
  export type ChargeSeed = z.infer<typeof chargeSeedSchema>;
89
88
  export type RefundSeed = z.infer<typeof refundSeedSchema>;
@@ -93,7 +92,7 @@ export declare const seedSchema: z.ZodObject<{
93
92
  key: z.ZodString;
94
93
  sid: z.ZodString;
95
94
  account_id: z.ZodOptional<z.ZodString>;
96
- }, z.core.$strip>>>;
95
+ }, z.core.$strict>>>;
97
96
  failure_injection: z.ZodDefault<z.ZodArray<z.ZodObject<{
98
97
  method: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
99
98
  path: z.ZodString;
@@ -104,7 +103,7 @@ export declare const seedSchema: z.ZodObject<{
104
103
  }>>;
105
104
  status: z.ZodNumber;
106
105
  body: z.ZodUnknown;
107
- }, z.core.$strip>>>;
106
+ }, z.core.$strict>>>;
108
107
  payment_intents: z.ZodDefault<z.ZodArray<z.ZodObject<{
109
108
  id: z.ZodString;
110
109
  account_id: z.ZodString;
@@ -132,7 +131,7 @@ export declare const seedSchema: z.ZodObject<{
132
131
  updated: z.ZodNumber;
133
132
  canceled_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
134
133
  captured_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
135
- }, z.core.$strip>>>;
134
+ }, z.core.$strict>>>;
136
135
  charges: z.ZodDefault<z.ZodArray<z.ZodObject<{
137
136
  id: z.ZodString;
138
137
  account_id: z.ZodString;
@@ -149,7 +148,7 @@ export declare const seedSchema: z.ZodObject<{
149
148
  captured: z.ZodDefault<z.ZodBoolean>;
150
149
  currency: z.ZodString;
151
150
  created: z.ZodNumber;
152
- }, z.core.$strip>>>;
151
+ }, z.core.$strict>>>;
153
152
  refunds: z.ZodDefault<z.ZodArray<z.ZodObject<{
154
153
  id: z.ZodString;
155
154
  account_id: z.ZodString;
@@ -167,7 +166,7 @@ export declare const seedSchema: z.ZodObject<{
167
166
  balance_transaction_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
168
167
  idempotency_key: z.ZodOptional<z.ZodNullable<z.ZodString>>;
169
168
  created: z.ZodNumber;
170
- }, z.core.$strip>>>;
169
+ }, z.core.$strict>>>;
171
170
  balance_transactions: z.ZodDefault<z.ZodArray<z.ZodObject<{
172
171
  id: z.ZodString;
173
172
  account_id: z.ZodString;
@@ -184,8 +183,8 @@ export declare const seedSchema: z.ZodObject<{
184
183
  available: "available";
185
184
  }>>;
186
185
  created: z.ZodNumber;
187
- }, z.core.$strip>>>;
188
- }, z.core.$strip>;
186
+ }, z.core.$strict>>>;
187
+ }, z.core.$strict>;
189
188
  export declare function parseSeed(input: unknown): SeedState;
190
189
  /**
191
190
  * Boot-time seed loader: prefer `POME_SEED_JSON` env (set by the cloud
@@ -210,4 +209,3 @@ export declare function parseSeed(input: unknown): SeedState;
210
209
  */
211
210
  export declare function loadSeedFromEnv(env?: Record<string, string | undefined>): SeedState;
212
211
  export declare function defaultSeed(): SeedState;
213
- export declare function applySeed(db: TwinStripeDatabase, seed: SeedState, failureInjection?: FailureInjectionStore): void;
@@ -1051,8 +1051,16 @@ var gmailSeedSchema = z.object({
1051
1051
  }
1052
1052
  }
1053
1053
  });
1054
+ function withoutSidecarMeta(input) {
1055
+ if (!input || typeof input !== "object" || Array.isArray(input))
1056
+ return input;
1057
+ if (!("_meta" in input))
1058
+ return input;
1059
+ const { _meta, ...rest } = input;
1060
+ return rest;
1061
+ }
1054
1062
  function parseSeed(input) {
1055
- return gmailSeedSchema.parse(input);
1063
+ return gmailSeedSchema.parse(withoutSidecarMeta(input));
1056
1064
  }
1057
1065
  var DEFAULT_GMAIL_AGENT_EMAIL = "pome-agent@pome-twin.test";
1058
1066
  function agentPathInboxMailbox(email2 = DEFAULT_GMAIL_AGENT_EMAIL) {
@@ -699,7 +699,7 @@ var STRIPE_CHECKS = [
699
699
  x402FirstRequestChallenged,
700
700
  x402RetryIncludesPayment
701
701
  ];
702
- var failureInjectionRuleSchema = z.object({
702
+ var failureInjectionRuleSchema = z.strictObject({
703
703
  method: z.string().min(1).transform((s) => s.toUpperCase()),
704
704
  path: z.string().min(1),
705
705
  attempt: z.number().int().positive(),
@@ -723,7 +723,7 @@ var PI_STATUSES = [
723
723
  var CHARGE_STATUSES2 = ["pending", "succeeded", "failed"];
724
724
  var REFUND_STATUSES = ["succeeded", "pending", "failed", "canceled"];
725
725
  var BALANCE_TX_STATUSES = ["pending", "available"];
726
- var paymentIntentSeedSchema = z.object({
726
+ var paymentIntentSeedSchema = z.strictObject({
727
727
  id: z.string().min(1),
728
728
  account_id: z.string().min(1),
729
729
  amount: z.number().int(),
@@ -743,7 +743,7 @@ var paymentIntentSeedSchema = z.object({
743
743
  canceled_at: z.number().int().nullable().optional(),
744
744
  captured_at: z.number().int().nullable().optional()
745
745
  });
746
- var chargeSeedSchema = z.object({
746
+ var chargeSeedSchema = z.strictObject({
747
747
  id: z.string().min(1),
748
748
  account_id: z.string().min(1),
749
749
  payment_intent_id: z.string().min(1),
@@ -756,7 +756,7 @@ var chargeSeedSchema = z.object({
756
756
  currency: z.string().min(1),
757
757
  created: z.number().int()
758
758
  });
759
- var refundSeedSchema = z.object({
759
+ var refundSeedSchema = z.strictObject({
760
760
  id: z.string().min(1),
761
761
  account_id: z.string().min(1),
762
762
  charge_id: z.string().min(1),
@@ -769,7 +769,7 @@ var refundSeedSchema = z.object({
769
769
  idempotency_key: z.string().nullable().optional(),
770
770
  created: z.number().int()
771
771
  });
772
- var balanceTransactionSeedSchema = z.object({
772
+ var balanceTransactionSeedSchema = z.strictObject({
773
773
  id: z.string().min(1),
774
774
  account_id: z.string().min(1),
775
775
  type: z.string().min(1),
@@ -783,8 +783,8 @@ var balanceTransactionSeedSchema = z.object({
783
783
  status: z.enum(BALANCE_TX_STATUSES).default("available"),
784
784
  created: z.number().int()
785
785
  });
786
- var seedSchema = z.object({
787
- api_keys: z.array(z.object({
786
+ var seedSchema = z.strictObject({
787
+ api_keys: z.array(z.strictObject({
788
788
  key: z.string().min(1),
789
789
  sid: z.string().min(1),
790
790
  account_id: z.string().min(1).optional()
@@ -795,8 +795,16 @@ var seedSchema = z.object({
795
795
  refunds: z.array(refundSeedSchema).default([]),
796
796
  balance_transactions: z.array(balanceTransactionSeedSchema).default([])
797
797
  });
798
+ function withoutSidecarMeta(input) {
799
+ if (!input || typeof input !== "object" || Array.isArray(input))
800
+ return input;
801
+ if (!("_meta" in input))
802
+ return input;
803
+ const { _meta, ...rest } = input;
804
+ return rest;
805
+ }
798
806
  function parseSeed(input) {
799
- return seedSchema.parse(input);
807
+ return seedSchema.parse(withoutSidecarMeta(input));
800
808
  }
801
809
  function defaultSeed() {
802
810
  return {
@@ -808,8 +808,16 @@ var linearSeedSchema = z.object({
808
808
  }
809
809
  }
810
810
  });
811
+ function withoutSidecarMeta(input) {
812
+ if (!input || typeof input !== "object" || Array.isArray(input))
813
+ return input;
814
+ if (!("_meta" in input))
815
+ return input;
816
+ const { _meta, ...rest } = input;
817
+ return rest;
818
+ }
811
819
  function parseSeed(input) {
812
- return linearSeedSchema.parse(input);
820
+ return linearSeedSchema.parse(withoutSidecarMeta(input));
813
821
  }
814
822
  function defaultSeedState() {
815
823
  return {
@@ -919,20 +919,20 @@ var GITHUB_CHECKS = [
919
919
  // slotted in front so the existing listing order does not move.
920
920
  toolWasCalled
921
921
  ];
922
- var seedSchema = z.object({
923
- users: z.array(z.object({
922
+ var seedSchema = z.strictObject({
923
+ users: z.array(z.strictObject({
924
924
  login: z.string().min(1),
925
925
  type: z.enum(["User", "Organization"]).default("User"),
926
926
  name: z.string().default("")
927
927
  })).default([]),
928
- repositories: z.array(z.object({
928
+ repositories: z.array(z.strictObject({
929
929
  owner: z.string().min(1),
930
930
  name: z.string().min(1),
931
931
  description: z.string().default(""),
932
932
  private: z.boolean().default(false),
933
933
  default_branch: z.string().min(1).default("main"),
934
934
  collaborators: z.array(z.string().min(1)).default([]),
935
- labels: z.array(z.object({
935
+ labels: z.array(z.strictObject({
936
936
  name: z.string().min(1),
937
937
  color: z.string().default("ededed"),
938
938
  description: z.string().default("")
@@ -952,7 +952,7 @@ var seedSchema = z.object({
952
952
  // remove. Refusing it keeps "the seed asked for a rename" and "the twin
953
953
  // serves a rename" the same statement. The content comes from the source
954
954
  // path, which the domain resolves on the branch the move happens on.
955
- files: z.array(z.object({
955
+ files: z.array(z.strictObject({
956
956
  path: z.string().min(1),
957
957
  content: z.string().optional(),
958
958
  branch: z.string().optional(),
@@ -986,11 +986,13 @@ var seedSchema = z.object({
986
986
  // Milestones, tags and releases are repository-level entities the
987
987
  // twin already SERVES (`GET /milestones`, `/tags`, `/releases`,
988
988
  // `/releases/latest`, `/releases/tags/:tag`) and the seed could not
989
- // express. Zod strips unknown keys, so a seed naming one reached the
989
+ // express. Zod stripped unknown keys, so a seed naming one reached the
990
990
  // domain as nothing at all and those routes could only ever answer `[]`
991
991
  // — a shape of infidelity no shape-diff can see, because an empty array
992
- // on both sides compares zero elements.
993
- milestones: z.array(z.object({
992
+ // on both sides compares zero elements. That silence is what `strictObject`
993
+ // closes for the general case (F-1689); this entry is the instance that
994
+ // was found first.
995
+ milestones: z.array(z.strictObject({
994
996
  // Assigned sequentially from 1 in seed order when omitted, the way
995
997
  // `nextMilestoneNumber` hands them out. Honored when given, so a
996
998
  // seed that pins `PATCH /milestones/2` addresses the milestone it
@@ -1007,11 +1009,11 @@ var seedSchema = z.object({
1007
1009
  // name or a SHA — and defaults to the repository's default-branch head. A
1008
1010
  // release whose `tag_name` matches an entry here reuses that tag rather
1009
1011
  // than minting a second one: `createRelease` looks the tag up first.
1010
- tags: z.array(z.object({
1012
+ tags: z.array(z.strictObject({
1011
1013
  name: z.string().min(1),
1012
1014
  target: z.string().min(1).optional()
1013
1015
  })).default([]),
1014
- releases: z.array(z.object({
1016
+ releases: z.array(z.strictObject({
1015
1017
  tag_name: z.string().min(1),
1016
1018
  // Nullable upstream, so an absent `name` means `null` — not `""`.
1017
1019
  name: z.string().optional(),
@@ -1021,7 +1023,7 @@ var seedSchema = z.object({
1021
1023
  prerelease: z.boolean().default(false),
1022
1024
  author: z.string().min(1).optional()
1023
1025
  })).default([]),
1024
- issues: z.array(z.object({
1026
+ issues: z.array(z.strictObject({
1025
1027
  number: z.number().int().positive().optional(),
1026
1028
  title: z.string().min(1),
1027
1029
  body: z.string().default(""),
@@ -1034,12 +1036,12 @@ var seedSchema = z.object({
1034
1036
  // stamps every comment `pome-agent`: a world in which the agent
1035
1037
  // under test wrote every comment on the issue it is being asked to
1036
1038
  // read is not one worth testing against.
1037
- comments: z.array(z.object({
1039
+ comments: z.array(z.strictObject({
1038
1040
  body: z.string().min(1),
1039
1041
  author: z.string().min(1).optional()
1040
1042
  })).default([])
1041
1043
  })).default([]),
1042
- pull_requests: z.array(z.object({
1044
+ pull_requests: z.array(z.strictObject({
1043
1045
  number: z.number().int().positive().optional(),
1044
1046
  title: z.string().min(1),
1045
1047
  body: z.string().default(""),
@@ -1049,7 +1051,7 @@ var seedSchema = z.object({
1049
1051
  author: z.string().min(1).optional(),
1050
1052
  // Reviews seeded on this PR. `state` mirrors GitHub's review
1051
1053
  // state enum; `author` must exist in the user/collaborator set.
1052
- reviews: z.array(z.object({
1054
+ reviews: z.array(z.strictObject({
1053
1055
  author: z.string().min(1),
1054
1056
  state: z.enum(["APPROVED", "CHANGES_REQUESTED", "COMMENTED"]).default("APPROVED"),
1055
1057
  body: z.string().default("")
@@ -1057,7 +1059,7 @@ var seedSchema = z.object({
1057
1059
  // Commit statuses applied to this PR's head SHA. Wired into the
1058
1060
  // commit_statuses table so get_pull_request_status and the merge
1059
1061
  // path see them without needing a separate setup call.
1060
- statuses: z.array(z.object({
1062
+ statuses: z.array(z.strictObject({
1061
1063
  context: z.string().min(1).default("ci/build"),
1062
1064
  state: z.enum(["error", "failure", "pending", "success"]).default("success"),
1063
1065
  description: z.string().default("")
@@ -1069,7 +1071,7 @@ var seedSchema = z.object({
1069
1071
  // keeps all three apart: `reviews[].body` is the prose on a review
1070
1072
  // verdict, `review_comments[]` below is anchored to a file and
1071
1073
  // line, and THIS one is the timeline.
1072
- comments: z.array(z.object({
1074
+ comments: z.array(z.strictObject({
1073
1075
  body: z.string().min(1),
1074
1076
  author: z.string().min(1).optional()
1075
1077
  })).default([]),
@@ -1079,7 +1081,7 @@ var seedSchema = z.object({
1079
1081
  // `line` must exist in it: a seeded review comment is one
1080
1082
  // `POST /pulls/:n/comments` could have produced, not a row only the
1081
1083
  // seeder can make.
1082
- review_comments: z.array(z.object({
1084
+ review_comments: z.array(z.strictObject({
1083
1085
  body: z.string().min(1),
1084
1086
  path: z.string().min(1),
1085
1087
  line: z.number().int().positive().default(1),
@@ -1087,10 +1089,41 @@ var seedSchema = z.object({
1087
1089
  author: z.string().min(1).optional()
1088
1090
  })).default([])
1089
1091
  })).default([])
1092
+ }).superRefine((repo, ctx) => {
1093
+ const claimed = /* @__PURE__ */ new Map();
1094
+ const entries = [
1095
+ ["issues", repo.issues ?? []],
1096
+ ["pull_requests", repo.pull_requests ?? []]
1097
+ ];
1098
+ for (const [field, rows] of entries) {
1099
+ for (const [index, row] of rows.entries()) {
1100
+ if (row.number === void 0)
1101
+ continue;
1102
+ const where = `${field}[${index}]`;
1103
+ const first = claimed.get(row.number);
1104
+ if (first === void 0) {
1105
+ claimed.set(row.number, where);
1106
+ continue;
1107
+ }
1108
+ ctx.addIssue({
1109
+ code: "custom",
1110
+ path: [field, index, "number"],
1111
+ message: `number ${row.number} is claimed by both ${first} and ${where} in ${repo.owner}/${repo.name}. Issues and pull requests share one per-repo counter, so a number names one entity or the other.`
1112
+ });
1113
+ }
1114
+ }
1090
1115
  }))
1091
1116
  });
1117
+ function withoutSidecarMeta(input) {
1118
+ if (!input || typeof input !== "object" || Array.isArray(input))
1119
+ return input;
1120
+ if (!("_meta" in input))
1121
+ return input;
1122
+ const { _meta, ...rest } = input;
1123
+ return rest;
1124
+ }
1092
1125
  function parseSeed(input) {
1093
- const seed = seedSchema.parse(normalizeLegacyGitHubSeed(input));
1126
+ const seed = seedSchema.parse(normalizeLegacyGitHubSeed(withoutSidecarMeta(input)));
1094
1127
  if (seed.repositories.length === 0) {
1095
1128
  throw new Error("GitHub seed must contain at least one repository");
1096
1129
  }
@@ -348,13 +348,13 @@ var SLACK_CHECKS = [
348
348
  // that compares two worlds rather than reading one.
349
349
  noSecretNewlyExposed
350
350
  ];
351
- var seedSchema = z.object({
352
- team: z.object({
351
+ var seedSchema = z.strictObject({
352
+ team: z.strictObject({
353
353
  id: z.string().regex(/^T[A-Z0-9_]+$/).optional(),
354
354
  name: z.string().default("Pome Twin Workspace"),
355
355
  domain: z.string().default("pome-twin")
356
356
  }).prefault({}),
357
- users: z.array(z.object({
357
+ users: z.array(z.strictObject({
358
358
  id: z.string().regex(/^[UB][A-Z0-9_]+$/).optional(),
359
359
  name: z.string().min(1),
360
360
  real_name: z.string().default(""),
@@ -364,7 +364,7 @@ var seedSchema = z.object({
364
364
  tz: z.string().default("America/Los_Angeles"),
365
365
  profile: z.record(z.string(), z.unknown()).default({})
366
366
  })).default([]),
367
- channels: z.array(z.object({
367
+ channels: z.array(z.strictObject({
368
368
  id: z.string().regex(/^[CGDM][A-Z0-9_]+$/).optional(),
369
369
  name: z.string().regex(/^[a-z0-9_-]{1,80}$/),
370
370
  is_private: z.boolean().default(false),
@@ -372,18 +372,18 @@ var seedSchema = z.object({
372
372
  purpose: z.string().default(""),
373
373
  creator: z.string().optional(),
374
374
  members: z.array(z.string()).default([]),
375
- messages: z.array(z.object({
375
+ messages: z.array(z.strictObject({
376
376
  ts: z.string().optional(),
377
377
  user: z.string(),
378
378
  text: z.string(),
379
379
  thread_ts: z.string().optional(),
380
- reactions: z.array(z.object({ name: z.string(), user: z.string() })).default([])
380
+ reactions: z.array(z.strictObject({ name: z.string(), user: z.string() })).default([])
381
381
  })).default([])
382
382
  })).default([]),
383
383
  // Files present in the world before the agent runs. `user` and
384
384
  // `channels` are seed HANDLES (a user/channel `name`) or ids — the same
385
385
  // currency `channels[].members` and `channels[].messages[].user` already use.
386
- files: z.array(z.object({
386
+ files: z.array(z.strictObject({
387
387
  id: z.string().regex(/^F[A-Z0-9_]+$/).optional(),
388
388
  name: z.string().min(1),
389
389
  title: z.string().optional(),
@@ -392,14 +392,22 @@ var seedSchema = z.object({
392
392
  channels: z.array(z.string()).default([]),
393
393
  content: z.string().optional()
394
394
  })).default([]),
395
- emoji: z.array(z.object({
395
+ emoji: z.array(z.strictObject({
396
396
  name: z.string().regex(/^[a-z0-9_+-]{1,100}$/),
397
397
  url: z.string().url().optional(),
398
398
  alias: z.string().regex(/^[a-z0-9_+-]{1,100}$/).optional()
399
399
  })).default([])
400
400
  });
401
+ function withoutSidecarMeta(input) {
402
+ if (!input || typeof input !== "object" || Array.isArray(input))
403
+ return input;
404
+ if (!("_meta" in input))
405
+ return input;
406
+ const { _meta, ...rest } = input;
407
+ return rest;
408
+ }
401
409
  function parseSeed(input) {
402
- return seedSchema.parse(input);
410
+ return seedSchema.parse(withoutSidecarMeta(input));
403
411
  }
404
412
  function defaultSeedState() {
405
413
  return {
package/dist/github.js CHANGED
@@ -1,2 +1,2 @@
1
- export { GITHUB_CHECKS, defaultSeedState, parseSeed, seedSchema } from './chunk-6AXGU7BV.js';
1
+ export { GITHUB_CHECKS, defaultSeedState, parseSeed, seedSchema } from './chunk-PCHPCMZH.js';
2
2
  import './chunk-W2JNYULF.js';
package/dist/gmail.js CHANGED
@@ -1,2 +1,2 @@
1
- export { GMAIL_CHECKS, defaultSeedState, gmailSeedSchema, parseSeed } from './chunk-KTTJCEDH.js';
1
+ export { GMAIL_CHECKS, defaultSeedState, gmailSeedSchema, parseSeed } from './chunk-GL26LYWH.js';
2
2
  import './chunk-W2JNYULF.js';
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import './chunk-ZXE6LAM3.js';
2
- import { GITHUB_CHECKS } from './chunk-6AXGU7BV.js';
3
- export { GITHUB_CHECKS, defaultSeedState as defaultGitHubSeed, seedSchema as githubSeedSchema, parseSeed as parseGitHubSeed } from './chunk-6AXGU7BV.js';
4
- import { GMAIL_CHECKS } from './chunk-KTTJCEDH.js';
5
- export { GMAIL_CHECKS, defaultSeedState as defaultGmailSeed, gmailSeedSchema, parseSeed as parseGmailSeed } from './chunk-KTTJCEDH.js';
6
- import { LINEAR_CHECKS } from './chunk-CDY7HEPC.js';
7
- export { LINEAR_CHECKS, defaultSeedState as defaultLinearSeed, linearSeedSchema, parseSeed as parseLinearSeed } from './chunk-CDY7HEPC.js';
8
- import { SLACK_CHECKS } from './chunk-OEGRXQ6W.js';
9
- export { SLACK_CHECKS, defaultSeedState as defaultSlackSeed, parseSeed as parseSlackSeed, seedSchema as slackSeedSchema } from './chunk-OEGRXQ6W.js';
10
- import { STRIPE_CHECKS } from './chunk-XOUAZPNB.js';
11
- export { STRIPE_CHECKS, defaultSeed as defaultStripeSeed, parseSeed as parseStripeSeed, seedSchema as stripeSeedSchema } from './chunk-XOUAZPNB.js';
2
+ import { GITHUB_CHECKS } from './chunk-PCHPCMZH.js';
3
+ export { GITHUB_CHECKS, defaultSeedState as defaultGitHubSeed, seedSchema as githubSeedSchema, parseSeed as parseGitHubSeed } from './chunk-PCHPCMZH.js';
4
+ import { GMAIL_CHECKS } from './chunk-GL26LYWH.js';
5
+ export { GMAIL_CHECKS, defaultSeedState as defaultGmailSeed, gmailSeedSchema, parseSeed as parseGmailSeed } from './chunk-GL26LYWH.js';
6
+ import { LINEAR_CHECKS } from './chunk-NKD5TSUV.js';
7
+ export { LINEAR_CHECKS, defaultSeedState as defaultLinearSeed, linearSeedSchema, parseSeed as parseLinearSeed } from './chunk-NKD5TSUV.js';
8
+ import { SLACK_CHECKS } from './chunk-RU5YFU2O.js';
9
+ export { SLACK_CHECKS, defaultSeedState as defaultSlackSeed, parseSeed as parseSlackSeed, seedSchema as slackSeedSchema } from './chunk-RU5YFU2O.js';
10
+ import { STRIPE_CHECKS } from './chunk-JBKRUBMR.js';
11
+ export { STRIPE_CHECKS, defaultSeed as defaultStripeSeed, parseSeed as parseStripeSeed, seedSchema as stripeSeedSchema } from './chunk-JBKRUBMR.js';
12
12
  export { REDACTION_PLACEHOLDER, VACUITY_SENTINEL, VACUITY_SENTINEL_NUMBER, VACUITY_SENTINEL_SNAKE, checkNearMissPattern, checkPattern, checksDigest, childStatePath, defineCheck, isRedacted, oneOf, parseCheck, probeDiscrimination, probeRedactionSurvival, probeStateCitation, renderCheck, repoRef, resolveStatePath, statePath, templateSlots } from './chunk-W2JNYULF.js';
13
13
 
14
14
  // src/index.ts
package/dist/linear.js CHANGED
@@ -1,2 +1,2 @@
1
- export { LINEAR_CHECKS, defaultSeedState, linearSeedSchema, parseSeed } from './chunk-CDY7HEPC.js';
1
+ export { LINEAR_CHECKS, defaultSeedState, linearSeedSchema, parseSeed } from './chunk-NKD5TSUV.js';
2
2
  import './chunk-W2JNYULF.js';
package/dist/slack.js CHANGED
@@ -1,2 +1,2 @@
1
- export { SLACK_CHECKS, defaultSeedState, parseSeed, seedSchema } from './chunk-OEGRXQ6W.js';
1
+ export { SLACK_CHECKS, defaultSeedState, parseSeed, seedSchema } from './chunk-RU5YFU2O.js';
2
2
  import './chunk-W2JNYULF.js';
package/dist/stripe.js CHANGED
@@ -1,2 +1,2 @@
1
- export { STRIPE_CHECKS, defaultSeed, parseSeed, seedSchema } from './chunk-XOUAZPNB.js';
1
+ export { STRIPE_CHECKS, defaultSeed, parseSeed, seedSchema } from './chunk-JBKRUBMR.js';
2
2
  import './chunk-W2JNYULF.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pome-sh/checks",
3
- "version": "0.3.10",
3
+ "version": "0.4.1",
4
4
  "description": "Pome's grading vocabulary — the check declarations, seed schemas and default seeds of all five digital twins, plus the check DSL they are written in. Declarations only: no twin server, no database, no routes, no tools.",
5
5
  "private": false,
6
6
  "type": "module",