---
id: 01-subject-linkage-types
epic: dsr-consent-and-cookie-banner
title: Subject-linkage types in core-shared
type: technical-story
status: done
feature: core-shared
depends-on: []
blocks: [02-audit-enum-amendment]
created: 2026-05-19T12:00:00Z
updated: 2026-05-19T10:13:17.502Z
---

## Goal

Add the subject-linkage type definitions to `@repo/core-shared` and apply the first instance of the `custom.subject` declaration to the `auth.users` collection, establishing the pattern every downstream consumer will follow.

## Why

The DSR cascade (Epic B's `core-dsr`) walks `custom.subject` fields to discover which rows belong to a given subject. Before any DSR or consent implementation can begin, the TypeScript types and Payload ambient declaration must exist in `core-shared` (must-have package) so all other packages can reference them without an optional-core dependency.

## Done when

- `packages/core-shared/src/payload/subject-linkage-types.ts` exports `SubjectLinkKind`, `SubjectLink`, and `CollectionSubject`.
- An ambient module declaration extends Payload's `CollectionConfig.custom?` with `subject?: CollectionSubject | CollectionSubject[]`.
- `PAYLOAD_AUTH_PII_DEFAULTS` (Epic A's auth-managed exclusions list) gains `processingRestrictedAt` and `consentState` as excluded fields.
- `packages/auth/` sets `custom.subject = { kind: "self", field: "id" }` on the `users` collection config (canonical usage example).
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass.

## In scope

- `packages/core-shared/src/payload/subject-linkage-types.ts` — `SubjectLinkKind` (`"self" | "owner" | "reference"`), `SubjectLink` (field, kind, optional target + role), `CollectionSubject` (single or array form).
- Ambient declaration extending `CollectionConfig.custom?` in `core-shared` (parallel to `custom.pii` from Epic A).
- `PAYLOAD_AUTH_PII_DEFAULTS` extension with `processingRestrictedAt` and `consentState`.
- Export of new types from the `core-shared` payload barrel.
- `auth.users` collection: explicit `custom.subject = { kind: "self", field: "id" }` declaration for documentation clarity.

## Out of scope

- Payload impl walking `custom.subject` (Story 06 — core-dsr).
- All other existing collections (`blog.articles`, `media.media`, etc.) — no subject linkage needed per Epic A's PII backfill.
- `docs/compliance/subject-linkage.example.md` — Story 11.

## Tasks

- [x] Add `SubjectLink`, `SubjectLinkKind`, `CollectionSubject` types in `packages/core-shared/src/payload/subject-linkage-types.ts` + ambient declaration extending Payload `CollectionConfig.custom?` with `subject?: CollectionSubject | CollectionSubject[]` + extend `PAYLOAD_AUTH_PII_DEFAULTS` with `processingRestrictedAt` and `consentState` as excluded fields + export from `core-shared` payload barrel + add `custom.subject = { kind: "self", field: "id" }` to `packages/auth/`'s `users` collection config; all gates pass.
