@substrat-run/contract-tests 0.122.1 → 0.125.0

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 (37) hide show
  1. package/dist/capability-suite.d.ts.map +1 -1
  2. package/dist/capability-suite.js +21 -0
  3. package/dist/capability-suite.js.map +1 -1
  4. package/dist/emitted-suite.d.ts +3 -0
  5. package/dist/emitted-suite.d.ts.map +1 -0
  6. package/dist/emitted-suite.js +102 -0
  7. package/dist/emitted-suite.js.map +1 -0
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/module-log-suite.d.ts +6 -0
  13. package/dist/module-log-suite.d.ts.map +1 -0
  14. package/dist/module-log-suite.js +80 -0
  15. package/dist/module-log-suite.js.map +1 -0
  16. package/dist/modules.d.ts +395 -0
  17. package/dist/modules.d.ts.map +1 -1
  18. package/dist/modules.js +202 -3
  19. package/dist/modules.js.map +1 -1
  20. package/dist/permission-suite.d.ts +1 -1
  21. package/dist/permission-suite.d.ts.map +1 -1
  22. package/dist/permission-suite.js +230 -0
  23. package/dist/permission-suite.js.map +1 -1
  24. package/dist/schedule-suite.d.ts.map +1 -1
  25. package/dist/schedule-suite.js +131 -6
  26. package/dist/schedule-suite.js.map +1 -1
  27. package/dist/scope-host-suite.d.ts +23 -0
  28. package/dist/scope-host-suite.d.ts.map +1 -1
  29. package/dist/scope-host-suite.js +104 -5
  30. package/dist/scope-host-suite.js.map +1 -1
  31. package/dist/sql-limits-suite.d.ts.map +1 -1
  32. package/dist/sql-limits-suite.js +29 -2
  33. package/dist/sql-limits-suite.js.map +1 -1
  34. package/dist/system-switch-suite.d.ts.map +1 -1
  35. package/dist/system-switch-suite.js +226 -20
  36. package/dist/system-switch-suite.js.map +1 -1
  37. package/package.json +3 -3
package/dist/modules.d.ts CHANGED
@@ -1907,6 +1907,141 @@ export declare const contractTestBareOps: Record<string, OperationHandler<never,
1907
1907
  export declare const testMod: ModuleRegistration;
1908
1908
  export declare const atomicMod: ModuleRegistration;
1909
1909
  export declare const scheduleMod: ModuleRegistration;
1910
+ /**
1911
+ * #1525: the failure twin of `scheduleMod` itself — a SEPARATE module so registering
1912
+ * it never changes `scheduleMod`'s own schedule count, which `system-switch-suite.ts`
1913
+ * (its `SCHEDULES` constant) and every `scheduleContractSuite` test above this fixture
1914
+ * already pin exactly. Its one schedule declares the permission it is GIVEN
1915
+ * (`sched-denied:tick`) but the handler checks a DIFFERENT one (`sched-denied:admin`),
1916
+ * so provisioning never grants what the handler needs: due, invoked, and denied, every
1917
+ * pass, forever. `entitlementKey` reuses `scheduleMod`'s own SKU so no suite needs a
1918
+ * second `grantEntitlement` call to use it.
1919
+ */
1920
+ export declare const deniedScheduleModManifest: {
1921
+ id: string & z.$brand<"ModuleId">;
1922
+ version: string;
1923
+ kernelContract: string;
1924
+ permissions: {
1925
+ key: string & z.$brand<"PermissionKey">;
1926
+ description: string;
1927
+ }[];
1928
+ events: {
1929
+ emits: {
1930
+ type: string;
1931
+ schemaVersion: number;
1932
+ }[];
1933
+ consumes: {
1934
+ type: string;
1935
+ schemaVersion: number;
1936
+ from?: string | undefined;
1937
+ }[];
1938
+ exports?: {
1939
+ type: string;
1940
+ schemaVersion: number;
1941
+ readPermission: string & z.$brand<"PermissionKey">;
1942
+ }[] | undefined;
1943
+ };
1944
+ migrations: {
1945
+ journalDir: string;
1946
+ compatibleFrom: string;
1947
+ };
1948
+ attachmentTargets: {
1949
+ entityType: string;
1950
+ readPermission: string & z.$brand<"PermissionKey">;
1951
+ writePermission?: (string & z.$brand<"PermissionKey">) | undefined;
1952
+ }[];
1953
+ liveTargets?: {
1954
+ entityType: string;
1955
+ readPermission: string & z.$brand<"PermissionKey">;
1956
+ }[] | undefined;
1957
+ entityRelations?: {
1958
+ entityType: string;
1959
+ parentType: string;
1960
+ }[] | undefined;
1961
+ guards?: {
1962
+ before: string;
1963
+ predicate: string;
1964
+ config: Record<string, unknown>;
1965
+ }[] | undefined;
1966
+ schedules?: {
1967
+ operation: string;
1968
+ cadence: {
1969
+ everyMinutes: number;
1970
+ };
1971
+ input?: Record<string, unknown> | undefined;
1972
+ permissions: (string & z.$brand<"PermissionKey">)[];
1973
+ }[] | undefined;
1974
+ peers?: {
1975
+ vertical: string;
1976
+ operations: string[];
1977
+ permissions: (string & z.$brand<"PermissionKey">)[];
1978
+ }[] | undefined;
1979
+ freshness?: {
1980
+ eventType: string;
1981
+ within: {
1982
+ hours: number;
1983
+ };
1984
+ }[] | undefined;
1985
+ withdraws?: string[] | undefined;
1986
+ entitlementKey: string;
1987
+ envSpec?: {
1988
+ key: string;
1989
+ label?: string | undefined;
1990
+ description: string;
1991
+ placeholder?: string | undefined;
1992
+ required: boolean;
1993
+ secret: boolean;
1994
+ default?: string | undefined;
1995
+ group?: string | undefined;
1996
+ }[] | undefined;
1997
+ ownerGrants?: (string & z.$brand<"PermissionKey">)[] | undefined;
1998
+ entitlements?: string[] | undefined;
1999
+ provides?: string[] | undefined;
2000
+ requires?: string[] | undefined;
2001
+ api?: string | undefined;
2002
+ searchables?: {
2003
+ entityType: string;
2004
+ fields: string[];
2005
+ table?: string | undefined;
2006
+ idColumn?: string | undefined;
2007
+ tokenizer?: "prefix" | "substring" | undefined;
2008
+ }[] | undefined;
2009
+ lists?: {
2010
+ entityType: string;
2011
+ sortable: string[];
2012
+ filterable?: string[] | undefined;
2013
+ table?: string | undefined;
2014
+ idColumn?: string | undefined;
2015
+ }[] | undefined;
2016
+ ui?: {
2017
+ routes?: {
2018
+ path: string;
2019
+ screen: string;
2020
+ permission: string & z.$brand<"PermissionKey">;
2021
+ }[] | undefined;
2022
+ nav?: {
2023
+ label: string;
2024
+ icon?: string | undefined;
2025
+ to: string;
2026
+ permission: string & z.$brand<"PermissionKey">;
2027
+ }[] | undefined;
2028
+ entityViews?: {
2029
+ entityType: string;
2030
+ view: string;
2031
+ }[] | undefined;
2032
+ widgets?: {
2033
+ slot: string;
2034
+ component: string;
2035
+ permission: string & z.$brand<"PermissionKey">;
2036
+ }[] | undefined;
2037
+ settingsPanels?: {
2038
+ label: string;
2039
+ component: string;
2040
+ permission: string & z.$brand<"PermissionKey">;
2041
+ }[] | undefined;
2042
+ } | undefined;
2043
+ };
2044
+ export declare const deniedScheduleMod: ModuleRegistration;
1910
2045
  export declare const flowMod: ModuleRegistration;
1911
2046
  export declare const guardedMod: ModuleRegistration;
1912
2047
  export declare const gateMod: ModuleRegistration;
@@ -2970,6 +3105,266 @@ export declare const peerModManifest: {
2970
3105
  } | undefined;
2971
3106
  };
2972
3107
  export declare const peerMod: ModuleRegistration;
3108
+ export declare const emittedModManifest: {
3109
+ id: string & z.$brand<"ModuleId">;
3110
+ version: string;
3111
+ kernelContract: string;
3112
+ permissions: {
3113
+ key: string & z.$brand<"PermissionKey">;
3114
+ description: string;
3115
+ }[];
3116
+ events: {
3117
+ emits: {
3118
+ type: string;
3119
+ schemaVersion: number;
3120
+ }[];
3121
+ consumes: {
3122
+ type: string;
3123
+ schemaVersion: number;
3124
+ from?: string | undefined;
3125
+ }[];
3126
+ exports?: {
3127
+ type: string;
3128
+ schemaVersion: number;
3129
+ readPermission: string & z.$brand<"PermissionKey">;
3130
+ }[] | undefined;
3131
+ };
3132
+ migrations: {
3133
+ journalDir: string;
3134
+ compatibleFrom: string;
3135
+ };
3136
+ attachmentTargets: {
3137
+ entityType: string;
3138
+ readPermission: string & z.$brand<"PermissionKey">;
3139
+ writePermission?: (string & z.$brand<"PermissionKey">) | undefined;
3140
+ }[];
3141
+ liveTargets?: {
3142
+ entityType: string;
3143
+ readPermission: string & z.$brand<"PermissionKey">;
3144
+ }[] | undefined;
3145
+ entityRelations?: {
3146
+ entityType: string;
3147
+ parentType: string;
3148
+ }[] | undefined;
3149
+ guards?: {
3150
+ before: string;
3151
+ predicate: string;
3152
+ config: Record<string, unknown>;
3153
+ }[] | undefined;
3154
+ schedules?: {
3155
+ operation: string;
3156
+ cadence: {
3157
+ everyMinutes: number;
3158
+ };
3159
+ input?: Record<string, unknown> | undefined;
3160
+ permissions: (string & z.$brand<"PermissionKey">)[];
3161
+ }[] | undefined;
3162
+ peers?: {
3163
+ vertical: string;
3164
+ operations: string[];
3165
+ permissions: (string & z.$brand<"PermissionKey">)[];
3166
+ }[] | undefined;
3167
+ freshness?: {
3168
+ eventType: string;
3169
+ within: {
3170
+ hours: number;
3171
+ };
3172
+ }[] | undefined;
3173
+ withdraws?: string[] | undefined;
3174
+ entitlementKey: string;
3175
+ envSpec?: {
3176
+ key: string;
3177
+ label?: string | undefined;
3178
+ description: string;
3179
+ placeholder?: string | undefined;
3180
+ required: boolean;
3181
+ secret: boolean;
3182
+ default?: string | undefined;
3183
+ group?: string | undefined;
3184
+ }[] | undefined;
3185
+ ownerGrants?: (string & z.$brand<"PermissionKey">)[] | undefined;
3186
+ entitlements?: string[] | undefined;
3187
+ provides?: string[] | undefined;
3188
+ requires?: string[] | undefined;
3189
+ api?: string | undefined;
3190
+ searchables?: {
3191
+ entityType: string;
3192
+ fields: string[];
3193
+ table?: string | undefined;
3194
+ idColumn?: string | undefined;
3195
+ tokenizer?: "prefix" | "substring" | undefined;
3196
+ }[] | undefined;
3197
+ lists?: {
3198
+ entityType: string;
3199
+ sortable: string[];
3200
+ filterable?: string[] | undefined;
3201
+ table?: string | undefined;
3202
+ idColumn?: string | undefined;
3203
+ }[] | undefined;
3204
+ ui?: {
3205
+ routes?: {
3206
+ path: string;
3207
+ screen: string;
3208
+ permission: string & z.$brand<"PermissionKey">;
3209
+ }[] | undefined;
3210
+ nav?: {
3211
+ label: string;
3212
+ icon?: string | undefined;
3213
+ to: string;
3214
+ permission: string & z.$brand<"PermissionKey">;
3215
+ }[] | undefined;
3216
+ entityViews?: {
3217
+ entityType: string;
3218
+ view: string;
3219
+ }[] | undefined;
3220
+ widgets?: {
3221
+ slot: string;
3222
+ component: string;
3223
+ permission: string & z.$brand<"PermissionKey">;
3224
+ }[] | undefined;
3225
+ settingsPanels?: {
3226
+ label: string;
3227
+ component: string;
3228
+ permission: string & z.$brand<"PermissionKey">;
3229
+ }[] | undefined;
3230
+ } | undefined;
3231
+ };
3232
+ /**
3233
+ * The module the #1746 suite drives. Its consumer answers every `emitted.touched` with an
3234
+ * `emitted.echoed` in the same invocation, which is what lets the suite show the report
3235
+ * names the operation's own events and none of its consumers'.
3236
+ */
3237
+ export declare const emittedMod: ModuleRegistration;
3238
+ export declare const loggedModManifest: {
3239
+ id: string & z.$brand<"ModuleId">;
3240
+ version: string;
3241
+ kernelContract: string;
3242
+ permissions: {
3243
+ key: string & z.$brand<"PermissionKey">;
3244
+ description: string;
3245
+ }[];
3246
+ events: {
3247
+ emits: {
3248
+ type: string;
3249
+ schemaVersion: number;
3250
+ }[];
3251
+ consumes: {
3252
+ type: string;
3253
+ schemaVersion: number;
3254
+ from?: string | undefined;
3255
+ }[];
3256
+ exports?: {
3257
+ type: string;
3258
+ schemaVersion: number;
3259
+ readPermission: string & z.$brand<"PermissionKey">;
3260
+ }[] | undefined;
3261
+ };
3262
+ migrations: {
3263
+ journalDir: string;
3264
+ compatibleFrom: string;
3265
+ };
3266
+ attachmentTargets: {
3267
+ entityType: string;
3268
+ readPermission: string & z.$brand<"PermissionKey">;
3269
+ writePermission?: (string & z.$brand<"PermissionKey">) | undefined;
3270
+ }[];
3271
+ liveTargets?: {
3272
+ entityType: string;
3273
+ readPermission: string & z.$brand<"PermissionKey">;
3274
+ }[] | undefined;
3275
+ entityRelations?: {
3276
+ entityType: string;
3277
+ parentType: string;
3278
+ }[] | undefined;
3279
+ guards?: {
3280
+ before: string;
3281
+ predicate: string;
3282
+ config: Record<string, unknown>;
3283
+ }[] | undefined;
3284
+ schedules?: {
3285
+ operation: string;
3286
+ cadence: {
3287
+ everyMinutes: number;
3288
+ };
3289
+ input?: Record<string, unknown> | undefined;
3290
+ permissions: (string & z.$brand<"PermissionKey">)[];
3291
+ }[] | undefined;
3292
+ peers?: {
3293
+ vertical: string;
3294
+ operations: string[];
3295
+ permissions: (string & z.$brand<"PermissionKey">)[];
3296
+ }[] | undefined;
3297
+ freshness?: {
3298
+ eventType: string;
3299
+ within: {
3300
+ hours: number;
3301
+ };
3302
+ }[] | undefined;
3303
+ withdraws?: string[] | undefined;
3304
+ entitlementKey: string;
3305
+ envSpec?: {
3306
+ key: string;
3307
+ label?: string | undefined;
3308
+ description: string;
3309
+ placeholder?: string | undefined;
3310
+ required: boolean;
3311
+ secret: boolean;
3312
+ default?: string | undefined;
3313
+ group?: string | undefined;
3314
+ }[] | undefined;
3315
+ ownerGrants?: (string & z.$brand<"PermissionKey">)[] | undefined;
3316
+ entitlements?: string[] | undefined;
3317
+ provides?: string[] | undefined;
3318
+ requires?: string[] | undefined;
3319
+ api?: string | undefined;
3320
+ searchables?: {
3321
+ entityType: string;
3322
+ fields: string[];
3323
+ table?: string | undefined;
3324
+ idColumn?: string | undefined;
3325
+ tokenizer?: "prefix" | "substring" | undefined;
3326
+ }[] | undefined;
3327
+ lists?: {
3328
+ entityType: string;
3329
+ sortable: string[];
3330
+ filterable?: string[] | undefined;
3331
+ table?: string | undefined;
3332
+ idColumn?: string | undefined;
3333
+ }[] | undefined;
3334
+ ui?: {
3335
+ routes?: {
3336
+ path: string;
3337
+ screen: string;
3338
+ permission: string & z.$brand<"PermissionKey">;
3339
+ }[] | undefined;
3340
+ nav?: {
3341
+ label: string;
3342
+ icon?: string | undefined;
3343
+ to: string;
3344
+ permission: string & z.$brand<"PermissionKey">;
3345
+ }[] | undefined;
3346
+ entityViews?: {
3347
+ entityType: string;
3348
+ view: string;
3349
+ }[] | undefined;
3350
+ widgets?: {
3351
+ slot: string;
3352
+ component: string;
3353
+ permission: string & z.$brand<"PermissionKey">;
3354
+ }[] | undefined;
3355
+ settingsPanels?: {
3356
+ label: string;
3357
+ component: string;
3358
+ permission: string & z.$brand<"PermissionKey">;
3359
+ }[] | undefined;
3360
+ } | undefined;
3361
+ };
3362
+ /**
3363
+ * The module the `ctx.log` suite drives. `logged/act` logs, emits, and its consumer logs
3364
+ * again in the same invocation; `logged/fail` logs and then throws, so the suite can show
3365
+ * the line survives the rollback.
3366
+ */
3367
+ export declare const loggedMod: ModuleRegistration;
2973
3368
  export declare const contractTestModules: ModuleRegistration[];
2974
3369
  /**
2975
3370
  * A module for the live-read fan-out, with two entity types that differ in exactly
@@ -1 +1 @@
1
- {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EASL,CAAC,EAIF,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAML,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAI9B,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAU1B,CAAC;AAMH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiC9B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAU/B,CAAC;AAEH,eAAO,MAAM,YAAY,EAAE,kBAI1B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS1B,CAAC;AAEH,eAAO,MAAM,OAAO,EAAE,kBAkBrB,CAAC;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkB1B,CAAC;AAMH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmB5B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS1B,CAAC;AAKH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS5B,CAAC;AAOH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAe7B,CAAC;AAIH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAUhC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS5B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAU/B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS1B,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYpC,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuC1B,CAAC;AA6BH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CA+OhF,CAAC;AA4cF,eAAO,MAAM,OAAO,EAAE,kBA0CrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,kBAkBvB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,kBAyDzB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAepC,CAAC;AAEH,eAAO,MAAM,iBAAiB,EAAE,kBAO/B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,kBAoDrB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,kBAwBxB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,kBAYrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,kBAAwD,CAAC;AAExF,eAAO,MAAM,SAAS,EAAE,kBAOvB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,kBAAuD,CAAC;AAEtF,eAAO,MAAM,OAAO,EAAE,kBAQrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,kBAWvB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,kBAwBlC,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,kBA+DrB,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmB/B,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,kBA0E1B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,kBAAkB,EAS1D,CAAC;AAEF;;;;;GAKG;AAGH;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoB1B,CAAC;AAEH,eAAO,MAAM,OAAO,EAAE,kBAqDrB,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAe5B,CAAC;AAEH,eAAO,MAAM,SAAS,EAAE,kBAmDvB,CAAC;AAIF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS3B,CAAC;AA+CH,eAAO,MAAM,QAAQ,EAAE,kBAQtB,CAAC;AAIF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYjC,CAAC;AAmGH,eAAO,MAAM,cAAc,EAAE,kBAY5B,CAAC;AAIF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASjC,CAAC;AAwFH,eAAO,MAAM,cAAc,EAAE,kBAa5B,CAAC;AAIF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCzB,CAAC;AAOH,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,YAAI,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAU,CAAC;AAGtG,eAAO,MAAM,MAAM,EAAE,kBAkJpB,CAAC;AAIF;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAC7C,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqB1B,CAAC;AAMH,eAAO,MAAM,OAAO,EAAE,kBAiDrB,CAAC;AAIF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAe7B,CAAC;AAeH;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,kBAqCxB,CAAC;AAIF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAY5B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,kBA0BvB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,kBAAkB,EAsCnD,CAAC;AAIF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiC1B,CAAC;AAsDH,eAAO,MAAM,OAAO,EAAE,kBAQrB,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS5B,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,EAAE,kBASvB,CAAC"}
package/dist/modules.js CHANGED
@@ -307,7 +307,16 @@ export const permModManifest = moduleManifest.parse({
307
307
  // #473: an attachment target on `item`, gated read=perm:read / write=perm:use — reusing
308
308
  // the permission model the suite already sets up, so both adapters exercise attachments.
309
309
  attachmentTargets: [{ entityType: 'item', readPermission: 'perm:read', writePermission: 'perm:use' }],
310
- entityRelations: [{ entityType: 'item', parentType: 'box' }],
310
+ // #1856: camelCase entity types, the way a module names them, so the walk is proven
311
+ // over the spelling `ctx.link` writes — a camelCase child under a lower-case parent,
312
+ // and a camelCase child under a camelCase parent.
313
+ entityRelations: [
314
+ { entityType: 'item', parentType: 'box' },
315
+ { entityType: 'aiTurn', parentType: 'box' },
316
+ { entityType: 'aiTurn', parentType: 'chatThread' },
317
+ // #1856: a type that only CONTAINS a kernel namespace is an ordinary entity type.
318
+ { entityType: 'scopeItem', parentType: 'box' },
319
+ ],
311
320
  entitlementKey: 'perm',
312
321
  });
313
322
  // Shared across test/stash + test/read-stash. Module scope so the value survives
@@ -369,6 +378,21 @@ export const contractTestBareOps = {
369
378
  payload: input.omit ? undefined : { code: input.code },
370
379
  });
371
380
  }),
381
+ /**
382
+ * One event of a chosen PII class carrying an `email` (#1762), so the suite can put
383
+ * the same payload field under every class and assert a payload facet groups only
384
+ * the `'none'` ones. A classified event needs a data subject, so one is minted.
385
+ */
386
+ 'test/emit-classified': ((ctx, input) => {
387
+ ctx.emit({
388
+ type: 'test.classified',
389
+ schemaVersion: 1,
390
+ entity: { entityType: 'test-thing', entityId: 'classified' },
391
+ piiClass: input.pii,
392
+ ...(input.pii === 'none' ? {} : { subjectId: dataSubjectId.parse(input.subject ?? ulid()) }),
393
+ payload: { email: input.email },
394
+ });
395
+ }),
372
396
  'test/emit-unclassified-pii': ((ctx) => {
373
397
  // piiClass 'direct' without subjectId — must be rejected at emit (§6.1)
374
398
  ctx.emit({
@@ -965,12 +989,55 @@ export const scheduleMod = {
965
989
  assertAllowed(await ctx.check('sched:admin'));
966
990
  }),
967
991
  'sched/count': ((ctx) => ctx.sql.query('SELECT COUNT(*) AS n FROM sched_ticks')[0].n),
968
- 'sched/read-outbox': ((ctx) => ctx.sql.query('SELECT type, actor, operation FROM _substrat_outbox ORDER BY id')),
992
+ // #1525: `invocation_id` selected alongside — a schedule contract assertion joins
993
+ // this to the same column on `sched/schedule-state` to prove they carry ONE id.
994
+ 'sched/read-outbox': ((ctx) => ctx.sql.query('SELECT type, actor, operation, invocation_id FROM _substrat_outbox ORDER BY id')),
969
995
  // #1288: `kind` is selected, and the order leads with it — two rows may now share
970
996
  // a `schedule_op`, so ordering by that alone leaves the pair's order to the query
971
997
  // planner and an assertion on the array would be flaky rather than wrong.
972
- 'sched/schedule-state': ((ctx) => ctx.sql.query(`SELECT kind, schedule_op, last_status FROM _substrat_schedule_state
998
+ // #1525: `invocation_id` selected alongside — null for a 'freshness' row (nothing
999
+ // ran) and for a legacy row predating the column; a fired 'schedule' row carries
1000
+ // the id its own invoke ran under.
1001
+ 'sched/schedule-state': ((ctx) => ctx.sql.query(`SELECT kind, schedule_op, last_status, invocation_id FROM _substrat_schedule_state
973
1002
  ORDER BY kind, schedule_op`)),
1003
+ // #1525: a denied schedule's own denial row, joined by eye against the same column
1004
+ // on `sched/schedule-state` — proving a FAILED run carries the identical id, not
1005
+ // just a fired one.
1006
+ 'sched/read-denials': readDenialsOp,
1007
+ },
1008
+ };
1009
+ /**
1010
+ * #1525: the failure twin of `scheduleMod` itself — a SEPARATE module so registering
1011
+ * it never changes `scheduleMod`'s own schedule count, which `system-switch-suite.ts`
1012
+ * (its `SCHEDULES` constant) and every `scheduleContractSuite` test above this fixture
1013
+ * already pin exactly. Its one schedule declares the permission it is GIVEN
1014
+ * (`sched-denied:tick`) but the handler checks a DIFFERENT one (`sched-denied:admin`),
1015
+ * so provisioning never grants what the handler needs: due, invoked, and denied, every
1016
+ * pass, forever. `entitlementKey` reuses `scheduleMod`'s own SKU so no suite needs a
1017
+ * second `grantEntitlement` call to use it.
1018
+ */
1019
+ export const deniedScheduleModManifest = moduleManifest.parse({
1020
+ id: '@test/sched-denied',
1021
+ version: '1.0.0',
1022
+ kernelContract: '^0.0.1',
1023
+ permissions: [
1024
+ { key: 'sched-denied:tick', description: 'the only permission this module ever grants' },
1025
+ { key: 'sched-denied:admin', description: 'required by the handler; no schedule declares it' },
1026
+ ],
1027
+ events: { emits: [], consumes: [] },
1028
+ migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
1029
+ attachmentTargets: [],
1030
+ entitlementKey: 'sched',
1031
+ schedules: [
1032
+ { operation: 'sched-denied/tick', cadence: { everyMinutes: 60 }, permissions: ['sched-denied:tick'] },
1033
+ ],
1034
+ });
1035
+ export const deniedScheduleMod = {
1036
+ manifest: deniedScheduleModManifest,
1037
+ operations: {
1038
+ 'sched-denied/tick': (async (ctx) => {
1039
+ assertAllowed(await ctx.check('sched-denied:admin'));
1040
+ }),
974
1041
  },
975
1042
  };
976
1043
  export const flowMod = {
@@ -1953,6 +2020,125 @@ export const peerMod = {
1953
2020
  'peer/tuples': ((ctx) => ctx.sql.query("SELECT subject, relation, object, revoked_at FROM _substrat_tuples WHERE substr(subject, 1, 9) = 'vertical:' ORDER BY subject, relation")),
1954
2021
  },
1955
2022
  };
2023
+ // -- #1746: what an invocation emitted ----------------------------------------
2024
+ export const emittedModManifest = moduleManifest.parse({
2025
+ id: '@test/emitted',
2026
+ version: '1.0.0',
2027
+ kernelContract: '^0.0.1',
2028
+ permissions: [{ key: 'emitted:use', description: 'the emitted-report fixture permission' }],
2029
+ events: {
2030
+ emits: [
2031
+ { type: 'emitted.touched', schemaVersion: 1 },
2032
+ { type: 'emitted.echoed', schemaVersion: 1 },
2033
+ ],
2034
+ consumes: [{ type: 'emitted.touched', schemaVersion: 1 }],
2035
+ },
2036
+ migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
2037
+ attachmentTargets: [],
2038
+ entitlementKey: 'emitted',
2039
+ });
2040
+ /** One `emitted.touched` per id, in order — the rows `onEmitted` should name. */
2041
+ const touchAll = (ctx, ids) => {
2042
+ for (const id of ids) {
2043
+ ctx.emit({
2044
+ type: 'emitted.touched',
2045
+ schemaVersion: 1,
2046
+ entity: { entityType: 'emitted-thing', entityId: id },
2047
+ piiClass: 'none',
2048
+ payload: {},
2049
+ });
2050
+ }
2051
+ };
2052
+ /**
2053
+ * The module the #1746 suite drives. Its consumer answers every `emitted.touched` with an
2054
+ * `emitted.echoed` in the same invocation, which is what lets the suite show the report
2055
+ * names the operation's own events and none of its consumers'.
2056
+ */
2057
+ export const emittedMod = {
2058
+ manifest: emittedModManifest,
2059
+ operations: {
2060
+ 'emitted/touch': ((ctx, input) => {
2061
+ touchAll(ctx, input.ids);
2062
+ return { touched: input.ids.length };
2063
+ }),
2064
+ 'emitted/read': (() => ({ ok: true })),
2065
+ 'emitted/fail': ((ctx, input) => {
2066
+ touchAll(ctx, input.ids);
2067
+ throw new Error('emitted/fail: refused after emitting');
2068
+ }),
2069
+ // A sub-transaction that rolled back takes its emit with it; the outer one commits.
2070
+ 'emitted/partial': (async (ctx, input) => {
2071
+ touchAll(ctx, [input.kept]);
2072
+ try {
2073
+ await ctx.atomic(() => {
2074
+ touchAll(ctx, [input.dropped]);
2075
+ throw new Error('rolled back');
2076
+ });
2077
+ }
2078
+ catch {
2079
+ // The point of the fixture: the dropped emit is gone, the kept one stays.
2080
+ }
2081
+ return { ok: true };
2082
+ }),
2083
+ },
2084
+ consumers: {
2085
+ 'emitted.touched': ((ctx, event) => {
2086
+ ctx.emit({
2087
+ type: 'emitted.echoed',
2088
+ schemaVersion: 1,
2089
+ entity: event.entity,
2090
+ piiClass: 'none',
2091
+ payload: {},
2092
+ });
2093
+ }),
2094
+ },
2095
+ };
2096
+ // -- #1746/#1747: ctx.log ------------------------------------------------------
2097
+ export const loggedModManifest = moduleManifest.parse({
2098
+ id: '@test/logged',
2099
+ version: '1.0.0',
2100
+ kernelContract: '^0.0.1',
2101
+ permissions: [{ key: 'logged:use', description: 'the ctx.log fixture permission' }],
2102
+ events: {
2103
+ emits: [{ type: 'logged.acted', schemaVersion: 1 }],
2104
+ consumes: [{ type: 'logged.acted', schemaVersion: 1 }],
2105
+ },
2106
+ migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
2107
+ attachmentTargets: [],
2108
+ entitlementKey: 'logged',
2109
+ });
2110
+ /**
2111
+ * The module the `ctx.log` suite drives. `logged/act` logs, emits, and its consumer logs
2112
+ * again in the same invocation; `logged/fail` logs and then throws, so the suite can show
2113
+ * the line survives the rollback.
2114
+ */
2115
+ export const loggedMod = {
2116
+ manifest: loggedModManifest,
2117
+ operations: {
2118
+ 'logged/act': ((ctx, input) => {
2119
+ // `tenantId` and `operation` in the fields are the caller's own values: they stay
2120
+ // fields and never replace what the host stamps.
2121
+ ctx.log.info('reply to {ticketId} sent', { ticketId: input.ticketId, tenantId: 'forged', operation: 'forged' });
2122
+ ctx.emit({
2123
+ type: 'logged.acted',
2124
+ schemaVersion: 1,
2125
+ entity: { entityType: 'logged-thing', entityId: input.ticketId },
2126
+ piiClass: 'none',
2127
+ payload: {},
2128
+ });
2129
+ return { ok: true };
2130
+ }),
2131
+ 'logged/fail': ((ctx, input) => {
2132
+ ctx.log.error('could not reach {ticketId}', { ticketId: input.ticketId });
2133
+ throw new Error('logged/fail: refused after logging');
2134
+ }),
2135
+ },
2136
+ consumers: {
2137
+ 'logged.acted': ((ctx, event) => {
2138
+ ctx.log.warn('saw {type}', { type: event.type });
2139
+ }),
2140
+ },
2141
+ };
1956
2142
  export const contractTestModules = [
1957
2143
  ...contractTestInitialModules,
1958
2144
  lateMod,
@@ -1964,6 +2150,13 @@ export const contractTestModules = [
1964
2150
  impersonationEchoMod,
1965
2151
  connectorMod,
1966
2152
  scheduleMod,
2153
+ // #1525: the failed-schedule fixture. A Durable Object bakes its operations in at
2154
+ // define time (this array), so registering it on a coordinator mid-test is not
2155
+ // enough for the CLOUDFLARE adapter to know the operation exists — it has to be
2156
+ // here too, or `stub.invoke('sched-denied/tick', …)` throws `not_found` before
2157
+ // `ctx.check` ever runs, which still counts as a failed schedule but records no
2158
+ // denial. Inert for every other suite — nothing else invokes `sched-denied/tick`.
2159
+ deniedScheduleMod,
1967
2160
  // #1577: the operation a resumable run's steps write through. Inert for every
1968
2161
  // other suite — nothing else reads `job_items`.
1969
2162
  jobsMod,
@@ -1978,6 +2171,12 @@ export const contractTestModules = [
1978
2171
  capMod,
1979
2172
  // #1706: the peer suite's target. Inert for every other suite beyond the peers' seats.
1980
2173
  peerMod,
2174
+ // #1746: the emitted-report suite's module. Its consumer reacts only to its own
2175
+ // `emitted.touched`, so it is inert for every other suite.
2176
+ emittedMod,
2177
+ // #1746/#1747: the ctx.log suite's module. Its consumer reacts only to its own
2178
+ // `logged.acted`, so it is inert for every other suite.
2179
+ loggedMod,
1981
2180
  ];
1982
2181
  // -- live reads (#938) -------------------------------------------------------
1983
2182
  /**