# Schemas define the boundary

> For agents: start with the [agent guide](https://ratstack.sh/llms.txt). Every page is Markdown by default; add `Accept: text/html` for HTML.

Free workshop: [how to burn a trillion tokens and get good results](/tokenmaxx#interested).

Schema-driven development starts with accepted values and declared outcomes. In this repo, schemas are executable boundaries. They are not separate descriptions of TypeScript interfaces.

[`packages/core/src/join-interest-contract.ts`](https://github.com/joelhooks/rat-stack/blob/main/packages/core/src/join-interest-contract.ts) defines `joinInterest`:

- Contact consent is `Schema.Literal(true)`.
- Answers are optional bounded strings.
- The ticket and agent reference are bounded nonempty strings.
- Sharing consent is optional.

Contact consent does not imply sharing consent.

[`AbuseVerdictSchema`](https://github.com/joelhooks/rat-stack/blob/main/packages/core/src/abuse-score.ts) defines:

- A boolean hold.
- A finite score between 0 and 1.
- An array of signal names.

The TypeScript `AbuseVerdict` type comes from `typeof AbuseVerdictSchema.Type`.

## Decode before dispatch

Effect's [`Schema.decodeUnknownEffect`](https://github.com/Effect-TS/effect/blob/effect%404.0.0/packages/effect/src/Schema.ts) decodes unknown input or fails with a schema error. Our [code-mode invoker](https://github.com/joelhooks/rat-stack/blob/main/packages/capability/src/to-code-mode.ts) decodes input before calling the handler. It then encodes the declared output or failure.

A domain refusal is typed too. [`MaskedInterestReplay`](https://github.com/joelhooks/rat-stack/blob/main/packages/core/src/masked-interest-replay.ts) is a Schema tagged error. The [handler](https://github.com/joelhooks/rat-stack/blob/main/packages/core/src/join-interest.ts) returns it when someone tries to replay a redacted card.

That refusal differs from a malformed request's [empty HTTP 400](/lore/openapi-describes-the-refusal-too).

## Generate cases, then state the rule

The [intake property tests](https://github.com/joelhooks/rat-stack/blob/main/packages/core/test/join-interest.test.ts) use `Arbitrary.schema(Scenario)`. Cases combine availability, sharing consent, ticket validity, and holds. Another property generates response histories.

The schema supplies cases. The tests still state the behavior those cases must satisfy.

See [property-based testing](/lore/property-based-testing) and [model-based testing](/lore/model-based-testing).

See [how we do it with Effect](/lore/how-we-do-it-with-effect) for the whole path.

## Sources

1. [packages/core/src/join-interest-contract.ts](https://github.com/joelhooks/rat-stack/blob/main/packages/core/src/join-interest-contract.ts)
   GitHub. packages/core/src/join-interest-contract.ts Accessed 2026-10-02.

2. [packages/core/src/abuse-score.ts](https://github.com/joelhooks/rat-stack/blob/main/packages/core/src/abuse-score.ts)
   GitHub. packages/core/src/abuse-score.ts Accessed 2026-10-02.

3. [packages/core/src/masked-interest-replay.ts](https://github.com/joelhooks/rat-stack/blob/main/packages/core/src/masked-interest-replay.ts)
   GitHub. packages/core/src/masked-interest-replay.ts Accessed 2026-10-02.

4. [packages/core/src/join-interest.ts](https://github.com/joelhooks/rat-stack/blob/main/packages/core/src/join-interest.ts)
   GitHub. packages/core/src/join-interest.ts Accessed 2026-10-02.

5. [packages/core/test/join-interest.test.ts](https://github.com/joelhooks/rat-stack/blob/main/packages/core/test/join-interest.test.ts)
   GitHub. packages/core/test/join-interest.test.ts Accessed 2026-10-02.

6. [packages/capability/src/to-code-mode.ts](https://github.com/joelhooks/rat-stack/blob/main/packages/capability/src/to-code-mode.ts)
   GitHub. packages/capability/src/to-code-mode.ts Accessed 2026-10-02.

7. [Effect 4 Schema](https://github.com/Effect-TS/effect/blob/effect%404.0.0/packages/effect/src/Schema.ts)
   GitHub. Effect 4 Schema Accessed 2026-10-02.

8. [Effect 4 Arbitrary](https://github.com/Effect-TS/effect/blob/effect%404.0.0/packages/effect/src/Arbitrary.ts)
   GitHub. Effect 4 Arbitrary Accessed 2026-10-02.

## Linked from

- Agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms.txt)

- Change log → What changed in the files served here, newest first. → [Read page](https://ratstack.sh/log)

- Code snippets quote a pinned source → Design brief for a build-only code pipeline: pinned Git objects, typed diagnostics, and one snippet model for both views. → [Read page](https://ratstack.sh/lore/code-snippets)

- Effect keeps the surfaces on one contract → Schema owns values, projections build interfaces, and Layers supply implementations. → [Read page](https://ratstack.sh/lore/how-we-do-it-with-effect)

- Errors are part of the interface → An author error needs a location, the rejected input, and a repair. → [Read page](https://ratstack.sh/lore/errors-are-part-of-the-interface)

- Full agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms-full.txt)

- log.md → The generated change log as Markdown. → [Read page](https://ratstack.sh/log.md)

- One capability, every surface → A schema-typed contract and one handler feed every interface rat-stack keeps. → [Read page](https://ratstack.sh/lore/one-capability-every-surface)

- One schema, three surfaces → A capability contract feeds CLI, HTTP, and MCP; OpenAPI is generated output, not their input. → [Read page](https://ratstack.sh/lore/one-schema-three-surfaces)

- OpenAPI describes the refusal too → The generated HTTP contract declares inputs, outputs, and the bodyless 400 returned when decoding fails. → [Read page](https://ratstack.sh/lore/openapi-describes-the-refusal-too)

- Rat Stack lore | rat-stack → Short, source-grounded notes on the ideas and decisions behind rat-stack. → [Read page](https://ratstack.sh/lore)
