Skip to content

feat: kernel constraints pipeline enforcement#409

Merged
jithinraj merged 5 commits intomainfrom
feat/kernel-constraints-pipeline
Feb 23, 2026
Merged

feat: kernel constraints pipeline enforcement#409
jithinraj merged 5 commits intomainfrom
feat/kernel-constraints-pipeline

Conversation

@jithinraj
Copy link
Copy Markdown
Member

@jithinraj jithinraj commented Feb 22, 2026

Summary

  • Wire validateKernelConstraints() into issue() and verifyLocal()/verifyReceipt() pipelines (DD-121)
  • Fail-closed enforcement: violations reject before signing (issuance) or before schema validation (verification)
  • New error code E_CONSTRAINT_VIOLATION with factory function
  • Normative specification published at docs/specs/KERNEL-CONSTRAINTS.md

Enforcement points

Pipeline Location On violation
issue() After claims build, before Zod parse Throws IssueError with E_CONSTRAINT_VIOLATION
verifyLocal() After signature verify, before parseReceiptClaims() Returns VerifyLocalFailure with code E_CONSTRAINT_VIOLATION
verifyReceipt() After JWS decode, before ReceiptClaims.parse() Returns VerifyFailure with reason constraint_violation

Zero impact on valid receipts

Constraints match existing JSON_EVIDENCE_LIMITS values. No valid receipt that currently passes will be rejected.

Changes

  • packages/schema/src/errors.ts: Added E_CONSTRAINT_VIOLATION to ERROR_CODES, added createConstraintViolationError() factory
  • packages/protocol/src/issue.ts: Constraint check inserted after claims object build (line 295)
  • packages/protocol/src/verify-local.ts: Constraint check after signature verification, E_CONSTRAINT_VIOLATION added to VerifyLocalErrorCode
  • packages/protocol/src/verify.ts: Constraint check after decode, constraint_violation reason added to VerifyFailure
  • docs/specs/KERNEL-CONSTRAINTS.md: Normative specification with constraint values, enforcement semantics, types, and cross-references

Test plan

  • All 225 existing protocol tests pass unchanged
  • 6 new issue constraint tests (valid, oversized array, oversized keys, oversized string, error code details, boundary value)
  • 5 new verify constraint tests (oversized array, oversized keys, oversized string, valid receipt, ordering precedence)
  • Build: 76/76 targets pass
  • Lint, typecheck, format: clean
  • guard.sh + check-planning-leak.sh: clean

Non-goals (explicitly deferred)

  • UTF-8 byte-length caps: future tightening of string length constraints to enforce byte-level limits (currently character-level).
  • Custom constraint profiles: deployer-configurable constraint overrides are not supported; kernel constraints are fixed.
  • Wire 0.2 constraint extensions: additional constraint types for Wire 0.2 kinds are deferred to v0.12.0.

Spec deltas

Constraint Value Enforcement
MAX_KEYS 64 issue() pre-sign, verify() post-decode
MAX_DEPTH 8 issue() pre-sign, verify() post-decode
MAX_STRING_LENGTH 4096 chars issue() pre-sign, verify() post-decode
MAX_EVIDENCE_BYTES 65536 bytes issue() pre-sign, verify() post-decode
Failure mode fail-closed IssueError (issue), VerifyFailure reason=constraint_violation (verify)
Error code E_CONSTRAINT_VIOLATION Added to specs/kernel/errors.json (canonical registry)

Round 2 hardening

Ordering precedence (normative)

Added to docs/specs/KERNEL-CONSTRAINTS.md:

  • Constraint validation runs before expensive JWKS fetch and signature verify (DoS resistance)
  • Pipeline order: decode -> constraint check -> schema parse -> expiry -> JWKS fetch -> signature verify
  • Constraint failures do not mask downstream signature failures (structurally valid payloads with invalid signatures report the signature failure)

Migrate all 9 packages from Zod 3.22.x to Zod 4.3.6. This is a
breaking change for downstream TypeScript consumers who compile
against exported @peac/schema types (z.infer<> types are not
assignment-compatible across Zod majors).

Schema changes:
- z.record() single-arg form removed in Zod 4: add explicit
  z.string() key schema in 5 locations (schema, control, mcp-server)
- .default({}) on object schemas requires output-type-compatible
  values in Zod 4: use .prefault({}) for input-type defaults (policy.ts)
- ZodError.errors alias removed: use .issues in test assertions
- issue.path typed as PropertyKey[] (was (string | number)[]): add
  casts at 2 call sites (protocol/issue.ts, cli/validators.ts)

No behavioral changes to schema validation, receipt issuance, or
verification. All 4138 tests pass across 167 test files.

Workspace enforcement:
- pnpm.overrides forces zod@^4.3.6 across all workspace packages
- Prevents mixed Zod 3/4 which causes runtime TypeError
Wire validateKernelConstraints() into issue() and verify pipelines.
Fail-closed: violations reject before signing (issue) or before
schema validation (verify).

Changes:
- issue.ts: constraint check after claims build, before Zod parse
- verify-local.ts: constraint check after signature, before schema
- verify.ts: constraint check after decode, before Zod parse
- errors.ts: E_CONSTRAINT_VIOLATION error code + factory function
- verify-local.ts: E_CONSTRAINT_VIOLATION added to VerifyLocalErrorCode
- verify.ts: 'constraint_violation' added to VerifyFailure reasons

New: docs/specs/KERNEL-CONSTRAINTS.md normative specification
Tests: 11 new (issue + verify constraint boundary tests)
@jithinraj jithinraj changed the base branch from feat/zod4-schema to main February 22, 2026 20:58
Rename test to clarify intent and use items directly instead of
unused exactArray + smallArray indirection.
@jithinraj jithinraj changed the title feat: kernel constraints pipeline enforcement (DD-121) feat: kernel constraints pipeline enforcement Feb 23, 2026
@jithinraj jithinraj merged commit fbb7cd8 into main Feb 23, 2026
8 checks passed
@jithinraj jithinraj deleted the feat/kernel-constraints-pipeline branch February 24, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant