@vxil/feature-configs 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.
@@ -166,11 +166,11 @@ export interface ApiStateResponseField extends ApiStateSummary {
166
166
  }
167
167
  /** The note every executor reports for a DISABLED feature whose block still
168
168
  * declares rows: the declaration is kept in the manifest and nothing is
169
- * converged (a parked feature is not a propagation window — review finding 2). */
169
+ * converged (a parked feature is not a propagation window). */
170
170
  export declare const API_STATE_DISABLED_NOTE = "feature disabled \u2014 declaration kept, not converged";
171
171
  /** `GET /v1/rate-limits/policies` is a 100-row HARD cap with no cursor. A list
172
172
  * AT the cap is not a complete live set, so planning creates against it would
173
- * re-POST every declared name the cap hid (review finding 5). The server's
173
+ * re-POST every declared name the cap hid. The server's
174
174
  * converge and the CLI's read-only plan refuse with this message instead. */
175
175
  export declare function rlPolicyListCapError(liveCount: number): string | null;
176
176
  export declare const RL_POLICY_LIST_CAP = 100;
package/dist/apiState.js CHANGED
@@ -161,11 +161,11 @@ export function emptyApiStateSummary(datum) {
161
161
  }
162
162
  /** The note every executor reports for a DISABLED feature whose block still
163
163
  * declares rows: the declaration is kept in the manifest and nothing is
164
- * converged (a parked feature is not a propagation window — review finding 2). */
164
+ * converged (a parked feature is not a propagation window). */
165
165
  export const API_STATE_DISABLED_NOTE = 'feature disabled — declaration kept, not converged';
166
166
  /** `GET /v1/rate-limits/policies` is a 100-row HARD cap with no cursor. A list
167
167
  * AT the cap is not a complete live set, so planning creates against it would
168
- * re-POST every declared name the cap hid (review finding 5). The server's
168
+ * re-POST every declared name the cap hid. The server's
169
169
  * converge and the CLI's read-only plan refuse with this message instead. */
170
170
  export function rlPolicyListCapError(liveCount) {
171
171
  if (liveCount < RL_POLICY_LIST_CAP)
package/dist/hooks.d.ts CHANGED
@@ -69,7 +69,7 @@ export declare function parseExpr(src: string): Node;
69
69
  /** Walk the AST and reject anything outside the allow-list, plus depth bounds.
70
70
  * Returns an array of human-readable errors (empty = safe). Pure, no eval. */
71
71
  export declare function validateAst(root: Node): string[];
72
- /** The VERIFIED caller/session context for read hooks (design §5.6). Read-only;
72
+ /** The VERIFIED caller/session context for read hooks (guide ch. 7). Read-only;
73
73
  * present only on the read path in end-user mode. In server mode / write path
74
74
  * the whole object is null. */
75
75
  export interface HookCaller {
@@ -142,7 +142,7 @@ export interface ReadHookResult {
142
142
  * HookEvalError (→ a clean 422, never a pinned isolate). Write events never
143
143
  * fire here, and read events never fire in runWriteHooks. */
144
144
  export declare function runReadHooks(hooks: Record<string, HookDef> | undefined, collection: string, rows: ReadonlyArray<Record<string, unknown>>, now: string,
145
- /** verified caller/session context (design §5.6) — read-only, exposed to
145
+ /** verified caller/session context (guide ch. 7) — read-only, exposed to
146
146
  * expressions as `caller.endUserId` / `caller.principal`. Omitted ⇒ null
147
147
  * (server-caller mode). */
148
148
  caller?: HookCaller | null): ReadHookResult;
package/dist/hooks.js CHANGED
@@ -699,7 +699,7 @@ export function runWriteHooks(hooks, collection, phase, data, before, now) {
699
699
  * HookEvalError (→ a clean 422, never a pinned isolate). Write events never
700
700
  * fire here, and read events never fire in runWriteHooks. */
701
701
  export function runReadHooks(hooks, collection, rows, now,
702
- /** verified caller/session context (design §5.6) — read-only, exposed to
702
+ /** verified caller/session context (guide ch. 7) — read-only, exposed to
703
703
  * expressions as `caller.endUserId` / `caller.principal`. Omitted ⇒ null
704
704
  * (server-caller mode). */
705
705
  caller) {
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export * from './readmodels.js';
4
4
  export * from './apiState.js';
5
5
  export * from './canonicalJson.js';
6
6
  export declare const RESERVED_CREDIT_TYPES: ReadonlySet<string>;
7
- /** F33 (2026-09-25): a function binding's `retry.maxAttempts` ceiling, and the
7
+ /** A function binding's `retry.maxAttempts` ceiling, and the
8
8
  * binding kinds that may carry `retry` — the platform-delivered event lanes
9
9
  * (an http invoke returns its own status; a cron tick's retry would overlap
10
10
  * the next tick). Read by the schema, the deploy clamp and the CLI. */
@@ -20,14 +20,14 @@ export declare const NOTIFICATION_TEMPLATE_PLACEHOLDERS: Readonly<Record<string,
20
20
  * exist and renders EMPTY. Rejected in `subject` for exactly the reason the
21
21
  * whole allow-list exists: a silent empty render in a live email. */
22
22
  export declare const NOTIFICATION_TEMPLATE_SLOT_PLACEHOLDERS: Readonly<Record<string, readonly string[]>>;
23
- /** Per-override caps (D4). Bodies are emails, not documents. */
23
+ /** Per-override caps. Bodies are emails, not documents. */
24
24
  export declare const NOTIF_OVERRIDE_SUBJECT_MAX = 500;
25
25
  export declare const NOTIF_OVERRIDE_BODY_MAX = 20000;
26
26
  /** Whole-map caps: keeps one manifest (and the KV row every send reads) small. */
27
27
  export declare const NOTIF_OVERRIDE_MAX_LOCALES_PER_TEMPLATE = 20;
28
28
  export declare const NOTIF_OVERRIDE_MAX_BYTES: number;
29
29
  /**
30
- * D4 — validate `templates.overrides` at CONFIG-WRITE time. Returns [] when the
30
+ * Validate `templates.overrides` at CONFIG-WRITE time. Returns [] when the
31
31
  * bag is absent or clean. Every rule fails LOUD rather than shipping something
32
32
  * that silently renders wrong in a customer's inbox:
33
33
  * • overrides present with `allowOverride:false` → rejected (never inert);
@@ -91,10 +91,10 @@ export declare const NotificationsConfigSchema: import("@sinclair/typebox").TObj
91
91
  }>>;
92
92
  /** in-app inbox channel (send with channel: 'inbox' | 'both') */
93
93
  inboxEnabled: import("@sinclair/typebox").TBoolean;
94
- /** §11b.5 broadcast campaigns channel. Optional bag (= 1 leaf): absent means
94
+ /** Broadcast campaigns channel. Optional bag (= 1 leaf): absent means
95
95
  * disabled; per-campaign quiet_hours / freq_cap overrides live on the
96
96
  * notifications.campaigns ROW (tenant data), not here. Folded into the
97
- * canonical schema 2026-07-18 (M21/#4 — Value.Clean previously STRIPPED the
97
+ * canonical schema 2026-07-18 (Value.Clean previously STRIPPED the
98
98
  * worker-local extension, so campaigns 403'd via the real config path). */
99
99
  broadcast: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
100
100
  enabled: import("@sinclair/typebox").TBoolean;
@@ -114,9 +114,9 @@ export declare const NotificationsConfigSchema: import("@sinclair/typebox").TObj
114
114
  }>>;
115
115
  }>;
116
116
  export type NotificationsConfig = Static<typeof NotificationsConfigSchema>;
117
- /** The §11b.5 broadcast bag as persisted (present ⇒ leaf defaults applied). */
117
+ /** The broadcast bag as persisted (present ⇒ leaf defaults applied). */
118
118
  export type BroadcastConfig = NonNullable<NotificationsConfig['broadcast']>;
119
- /** Generation-lifecycle config defaults (jobs.md §11 / §5 ≤15-flag budget). */
119
+ /** Generation-lifecycle config defaults (guide ch. 6, jobs). */
120
120
  export declare const GENERATION_DEFAULTS: {
121
121
  /** per-tenant in-flight generation cap (separate budget from queue jobs) */
122
122
  readonly maxConcurrent: 20;
@@ -189,14 +189,14 @@ export declare const JobsConfigSchema: import("@sinclair/typebox").TObject<{
189
189
  maxTimeoutMs: import("@sinclair/typebox").TInteger;
190
190
  /** poll-mode: how many poll cycles before giving up (→ terminal-fail) */
191
191
  pollMaxAttempts: import("@sinclair/typebox").TInteger;
192
- /** MANDATORY per-hold cap on a generation `reserve_credits.amount` (jobs.md
193
- * §11.8). Every requested amount is CLAMPED to this (never rejected) — a
192
+ /** MANDATORY per-hold cap on a generation `reserve_credits.amount`
193
+ * (guide ch. 6, jobs). Every requested amount is CLAMPED to this (never rejected) — a
194
194
  * conservative default so an untrusted deployed function that carries a
195
195
  * reserve block can never hold more than a bounded amount per run without
196
196
  * any tenant action. */
197
197
  maxReserveCredits: import("@sinclair/typebox").TInteger;
198
198
  /** MANDATORY per-tenant ceiling on the SUM of un-settled provisional
199
- * reserve holds across all in-flight generation runs (jobs.md §11.8): a
199
+ * reserve holds across all in-flight generation runs (guide ch. 6, jobs): a
200
200
  * reserve whose amount would push the tenant's outstanding-holds total over
201
201
  * this is rejected 429, so a runaway function cannot hold every user at
202
202
  * once. Defaulted so no tenant action is required to be safe. */
@@ -318,7 +318,7 @@ export declare const AuthConfigSchema: import("@sinclair/typebox").TObject<{
318
318
  }>;
319
319
  /** The security bag as persisted (present ⇒ leaf defaults applied). */
320
320
  export type AuthSecurityConfig = NonNullable<Static<typeof AuthConfigSchema>['security']>;
321
- /** The RB-2 generic OIDC / SSO issuer block (`providers.oidc`). */
321
+ /** The generic OIDC / SSO issuer block (`providers.oidc`). */
322
322
  export type AuthOidcConfig = Static<typeof OidcProviderSchema>;
323
323
  export type AuthConfig = Static<typeof AuthConfigSchema>;
324
324
  export declare const RL_POLICY_NAME_PATTERN = "^[a-zA-Z0-9_.:-]+$";
@@ -656,6 +656,7 @@ export declare const PaymentsConfigSchema: import("@sinclair/typebox").TObject<{
656
656
  secretApiKeyRef: import("@sinclair/typebox").TString;
657
657
  webhookSecretRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
658
658
  acceptSandbox: import("@sinclair/typebox").TBoolean;
659
+ sandboxUsers: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
659
660
  }>>;
660
661
  paypal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
661
662
  clientIdRef: import("@sinclair/typebox").TString;
@@ -685,6 +686,7 @@ export declare const PaymentsConfigSchema: import("@sinclair/typebox").TObject<{
685
686
  creditType: import("@sinclair/typebox").TString;
686
687
  amount: import("@sinclair/typebox").TInteger;
687
688
  period: import("@sinclair/typebox").TString;
689
+ mode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"add">, import("@sinclair/typebox").TLiteral<"reset">]>>;
688
690
  }>>>;
689
691
  }>>;
690
692
  priceMap: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TString>>;
@@ -718,11 +720,17 @@ export declare const FunctionsConfigSchema: import("@sinclair/typebox").TObject<
718
720
  retry: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
719
721
  maxAttempts: import("@sinclair/typebox").TInteger;
720
722
  }>>;
723
+ overlap: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"allow">, import("@sinclair/typebox").TLiteral<"skip">]>>;
721
724
  }>>>;
722
725
  scriptRef: import("@sinclair/typebox").TString;
723
726
  scopes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
724
727
  secrets: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
725
728
  egressAllow: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
729
+ runtime: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
730
+ compatibilityDate: import("@sinclair/typebox").TString;
731
+ compatibilityFlags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
732
+ cpuMs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
733
+ }>>;
726
734
  limits: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
727
735
  cpuMs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
728
736
  timeoutMs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
@@ -781,16 +789,29 @@ export declare const CopilotConfigSchema: import("@sinclair/typebox").TObject<{
781
789
  export type CopilotConfig = Static<typeof CopilotConfigSchema>;
782
790
  export declare const FEATURE_SCHEMAS: Record<string, TSchema>;
783
791
  export declare const CONFIG_FLAG_CAP = 15;
784
- /** Counts leaf flags in a TypeBox object schema (architecture §6).
785
- * Per features/auth.md §4: an OPTIONAL object (e.g. a provider credential
792
+ /** Counts leaf flags in a TypeBox object schema.
793
+ * Per guide ch. 6, auth: an OPTIONAL object (e.g. a provider credential
786
794
  * block) counts as ONE flag — the tenant's decision is "configure it or
787
795
  * not", not each inner ref. */
788
- /** The auth lifecycle events an `authHook` binding may name (F4-30) — the
796
+ /** The auth lifecycle events an `authHook` binding may name — the
789
797
  * closed union `packages/config` types as AuthHookEvent; the control-plane
790
798
  * reconciler maps each to its `auth.<event>` audit-event prefix. */
791
799
  export declare const AUTH_HOOK_EVENTS: readonly ["user.created", "session.created", "session.revoked", "signin.failure"];
792
800
  export type AuthHookEvent = (typeof AUTH_HOOK_EVENTS)[number];
793
- /** F4-29 test-recipient entry grammar (shared by the validator and auth-v1's
801
+ /** The events a `cmsHook` function binding may name — the closed union
802
+ * `packages/config` types on the `cmsHook` trigger, and the keys of the
803
+ * functions-v1 receiver's CMS_HOOK_EVENTS_FOR (beforeCreate → created,
804
+ * beforeUpdate → updated, beforeWrite → both). Omitted = beforeWrite. Anything
805
+ * else is refused at config write (E-CMSHOOK, 2026-10-01): an unknown name used
806
+ * to fall back to beforeWrite at delivery, so a typo like 'afterCreate' or
807
+ * 'beforeDelete' silently subscribed the function to creates AND updates.
808
+ * A CI gate pins every copy to this list. */
809
+ export declare const CMS_HOOK_EVENTS: readonly ["beforeCreate", "beforeUpdate", "beforeWrite"];
810
+ export type CmsHookEvent = (typeof CMS_HOOK_EVENTS)[number];
811
+ /** The ONE refusal text for an unknown cmsHook binding event (the config
812
+ * validator and the deploy route's early 422 both use it). */
813
+ export declare function cmsHookEventError(event: unknown): string | null;
814
+ /** The OTP test-recipient entry grammar (shared by the validator and auth-v1's
794
815
  * matcher): an exact email, a `*@domain` glob, or a +E.164 phone number. */
795
816
  export declare const TEST_RECIPIENT_EMAIL_RE: RegExp;
796
817
  export declare const TEST_RECIPIENT_GLOB_RE: RegExp;