feat(core-shared): add rate-limit type primitives and manifest field

Adds IRateLimit, RateLimitBudget, RateLimitDecision to a new
rate-limit sub-module; adds RateLimited<F> brand and isRateLimited
predicate following the Captured/ConsentChecked pattern; extends
UseCaseManifest with rateLimit?: readonly RateLimitBudget[] so
features can declare rate-limit gates in their manifests.

Exports new types from @repo/core-shared/rate-limit and
@repo/core-shared/conformance. Blocks stories 02, 03, and 04.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 08:21:42 +00:00
parent a633561c82
commit c62de6fce9
12 changed files with 154 additions and 23 deletions

View File

@@ -1,18 +1,18 @@
{
"generatedAt": "2026-05-19T21:51:40.371Z",
"commit": "5151454",
"generatedAt": "2026-05-20T08:21:18.294Z",
"commit": "a633561",
"repo": {
"statements": 97.38,
"branches": 92.19,
"functions": 97.1,
"branches": 92.2,
"functions": 97.11,
"lines": 97.38,
"counts": {
"lf": 5801,
"lh": 5649,
"brf": 1165,
"brh": 1074,
"fnf": 345,
"fnh": 335
"lf": 5807,
"lh": 5655,
"brf": 1166,
"brh": 1075,
"fnf": 346,
"fnh": 336
}
},
"byPackage": {
@@ -101,17 +101,17 @@
}
},
"@repo/core-shared": {
"statements": 98.03,
"branches": 95.89,
"functions": 92.08,
"lines": 98.03,
"statements": 98.04,
"branches": 95.9,
"functions": 92.16,
"lines": 98.04,
"counts": {
"lf": 1067,
"lh": 1046,
"brf": 316,
"brh": 303,
"fnf": 101,
"fnh": 93
"lf": 1073,
"lh": 1052,
"brf": 317,
"brh": 304,
"fnf": 102,
"fnh": 94
}
},
"@repo/core-ui": {

View File

@@ -6,6 +6,7 @@
"exports": {
".": "./src/index.ts",
"./audit": "./src/audit/index.ts",
"./rate-limit": "./src/rate-limit/index.ts",
"./conformance": "./src/conformance/index.ts",
"./conformance/coverage": "./src/conformance/coverage.ts",
"./di": "./src/di/index.ts",

View File

@@ -5,6 +5,7 @@ import {
isCaptured,
isAudited,
isAnalyzed,
isRateLimited,
} from "@/conformance/brand-runtime";
describe("brand-runtime", () => {
@@ -23,6 +24,7 @@ describe("brand-runtime", () => {
expect(isCaptured(fn)).toBe(false);
expect(isAudited(fn)).toBe(false);
expect(isAnalyzed(fn)).toBe(false);
expect(isRateLimited(fn)).toBe(false);
});
it("predicates discriminate between brands", () => {
@@ -45,6 +47,11 @@ describe("brand-runtime", () => {
const analyzed = () => {};
attachBrand(analyzed, "__analyzed");
expect(isAnalyzed(analyzed)).toBe(true);
const rateLimited = () => {};
attachBrand(rateLimited, "__rateLimited");
expect(isRateLimited(rateLimited)).toBe(true);
expect(isInstrumented(rateLimited)).toBe(false);
});
it("composing brands stacks them on the same function", () => {
@@ -53,10 +60,12 @@ describe("brand-runtime", () => {
attachBrand(fn, "__captured");
attachBrand(fn, "__audited");
attachBrand(fn, "__analyzed");
attachBrand(fn, "__rateLimited");
expect(isInstrumented(fn)).toBe(true);
expect(isCaptured(fn)).toBe(true);
expect(isAudited(fn)).toBe(true);
expect(isAnalyzed(fn)).toBe(true);
expect(isRateLimited(fn)).toBe(true);
});
it("attached brands are non-writable and non-configurable", () => {

View File

@@ -13,14 +13,15 @@
* commitment, not a mutable flag.
*/
import type { Analyzed, ConsentChecked } from "./brands";
import type { Analyzed, ConsentChecked, RateLimited } from "./brands";
type Brand =
| "__instrumented"
| "__captured"
| "__audited"
| "__analyzed"
| "__consentChecked";
| "__consentChecked"
| "__rateLimited";
/**
* Attaches the brand as a non-enumerable property on the given function.
@@ -68,3 +69,9 @@ export function isConsentChecked<F extends object>(
): fn is ConsentChecked<F> {
return hasBrand(fn, "__consentChecked");
}
export function isRateLimited<F extends object>(
fn: unknown,
): fn is RateLimited<F> {
return hasBrand(fn, "__rateLimited");
}

View File

@@ -1,5 +1,5 @@
import { describe, it, expectTypeOf } from "vitest";
import type { Instrumented, Captured } from "@/conformance/brands";
import type { Instrumented, Captured, RateLimited } from "@/conformance/brands";
describe("brand types", () => {
it("Instrumented<F> is structurally F plus a phantom flag", () => {
@@ -16,6 +16,12 @@ describe("brand types", () => {
expectTypeOf<Captured<Fn>["__captured"]>().toEqualTypeOf<true>();
});
it("RateLimited<F> is structurally F plus a phantom flag", () => {
type Fn = (n: number) => Promise<string>;
expectTypeOf<RateLimited<Fn>>().toBeCallableWith(1);
expectTypeOf<RateLimited<Fn>["__rateLimited"]>().toEqualTypeOf<true>();
});
it("brands compose without conflict", () => {
type Fn = (n: number) => Promise<string>;
type Both = Instrumented<Fn> & Captured<Fn>;

View File

@@ -11,3 +11,4 @@ export type Instrumented<F> = F & { readonly __instrumented: true };
export type Captured<F> = F & { readonly __captured: true };
export type Analyzed<F> = F & { readonly __analyzed: true };
export type ConsentChecked<F> = F & { readonly __consentChecked: true };
export type RateLimited<F> = F & { readonly __rateLimited: true };

View File

@@ -2,7 +2,9 @@ import { describe, it, expect, expectTypeOf } from "vitest";
import {
defineFeature,
type FeatureManifest,
type UseCaseManifest,
} from "@/conformance/define-feature";
import type { RateLimitBudget } from "@/rate-limit/rate-limit.interface";
import {
DEFAULT_COVERAGE_BANDS,
DEFAULT_MUTATION_SCORE,
@@ -58,6 +60,41 @@ describe("defineFeature", () => {
expectTypeOf(manifest).toMatchTypeOf<FeatureManifest>();
});
it("accepts an optional rateLimit array on a use case", () => {
const manifest = defineFeature({
name: "auth",
requiredCores: [],
useCases: {
signIn: {
mutates: false,
audits: [],
publishes: [],
consumes: [],
rateLimit: [{ name: "login", window: "1m", budget: 5 }],
},
},
realtimeChannels: [],
jobs: [],
} as const);
expectTypeOf(manifest).toMatchTypeOf<FeatureManifest>();
expectTypeOf(manifest.useCases.signIn.rateLimit).toMatchTypeOf<
readonly RateLimitBudget[] | undefined
>();
});
it("use case without rateLimit satisfies UseCaseManifest", () => {
const uc: UseCaseManifest = {
mutates: false,
audits: [],
publishes: [],
consumes: [],
};
expectTypeOf(uc.rateLimit).toEqualTypeOf<
readonly RateLimitBudget[] | undefined
>();
});
it("accepts an optional coverage section", () => {
const manifest = defineFeature({
name: "auth",

View File

@@ -1,4 +1,5 @@
import type { CoverageManifest } from "./coverage";
import type { RateLimitBudget } from "../rate-limit/rate-limit.interface";
/**
* Per-use-case manifest entry. Declares what the use case does at the contract
@@ -12,6 +13,7 @@ export type UseCaseManifest = {
readonly publishes: readonly string[];
readonly consumes: readonly string[];
readonly analyticsEvents?: readonly string[];
readonly rateLimit?: readonly RateLimitBudget[];
};
/**

View File

@@ -3,6 +3,7 @@ export type {
Captured,
Analyzed,
ConsentChecked,
RateLimited,
} from "./brands";
export type { FeatureManifest, UseCaseManifest } from "./define-feature";
export { defineFeature } from "./define-feature";
@@ -29,6 +30,7 @@ export {
isAudited,
isAnalyzed,
isConsentChecked,
isRateLimited,
} from "./brand-runtime";
export { ConformanceError } from "./conformance-error";
export { assertFeatureConformance } from "./assert-bindings";

View File

@@ -0,0 +1,5 @@
export type {
IRateLimit,
RateLimitBudget,
RateLimitDecision,
} from "./rate-limit.interface";

View File

@@ -0,0 +1,41 @@
import { describe, it, expectTypeOf } from "vitest";
import type {
IRateLimit,
RateLimitBudget,
RateLimitDecision,
} from "@/rate-limit/rate-limit.interface";
describe("rate-limit types", () => {
it("RateLimitBudget has the expected shape", () => {
expectTypeOf<RateLimitBudget>().toMatchTypeOf<{
name: string;
window: string;
budget: number;
}>();
});
it("RateLimitDecision has the expected shape", () => {
expectTypeOf<RateLimitDecision>().toMatchTypeOf<{
allowed: boolean;
remaining: number;
resetAt: Date;
}>();
});
it("IRateLimit.consume returns Promise<RateLimitDecision>", () => {
expectTypeOf<
IRateLimit["consume"]
>().returns.resolves.toEqualTypeOf<RateLimitDecision>();
});
it("IRateLimit.consume accepts optional weight", () => {
type ConsumeParams = Parameters<IRateLimit["consume"]>;
expectTypeOf<ConsumeParams[0]>().toEqualTypeOf<string>();
expectTypeOf<ConsumeParams[1]>().toEqualTypeOf<string>();
expectTypeOf<ConsumeParams[2]>().toEqualTypeOf<number | undefined>();
});
it("IRateLimit.reset returns Promise<void>", () => {
expectTypeOf<IRateLimit["reset"]>().returns.resolves.toEqualTypeOf<void>();
});
});

View File

@@ -0,0 +1,20 @@
export type RateLimitBudget = {
name: string;
window: string;
budget: number;
};
export type RateLimitDecision = {
allowed: boolean;
remaining: number;
resetAt: Date;
};
export interface IRateLimit {
consume(
budgetName: string,
key: string,
weight?: number,
): Promise<RateLimitDecision>;
reset(budgetName: string, key: string): Promise<void>;
}