@dogfood-lab/schemas 1.4.0 → 1.5.0

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.
package/README.md CHANGED
@@ -75,6 +75,24 @@ import recordSchema from '@dogfood-lab/schemas/json/dogfood-record.schema.json'
75
75
 
76
76
  `$id` is a contract field. Changes that consumers should treat as contract changes bump the monorepo's lockstep version.
77
77
 
78
+ ## Schema versioning
79
+
80
+ Payloads that carry a `schema_version` are gated by **MAJOR range**, not exact match. The accepted ranges live in one place — `SUPPORTED_SCHEMA_VERSIONS` (`src/schema-versions.ts`), which `@dogfood-lab/verify` imports to drive the gate and to stamp the persisted record's `schema_version`:
81
+
82
+ | Field | Meaning |
83
+ |---|---|
84
+ | `current` | the version this build emits for the contract |
85
+ | `minMajor` | lowest MAJOR accepted (inclusive) |
86
+ | `maxMajor` | highest MAJOR accepted (inclusive) |
87
+
88
+ The gate compares the payload's MAJOR against `[minMajor, maxMajor]`:
89
+
90
+ - **MAJOR inside the range** (any patch/minor) → **accepted**.
91
+ - **MAJOR above `maxMajor`** → rejected `CONTRACT_SCHEMA_TOO_NEW` — the payload was emitted against a newer contract than this build understands. **Operator action: upgrade testing-os.**
92
+ - **MAJOR below `minMajor`** → rejected `CONTRACT_SCHEMA_TOO_OLD` — the payload predates the supported contract. **Operator action: re-emit against the current contract.**
93
+
94
+ The contracts that carry `schema_version` are `record`, `recordSubmission`, `finding`, `pattern`, `recommendation`, `doctrine`, and the `agentOutput` swarm envelope. **`policy` and `scenario` deliberately carry no `schema_version`** and are exempt from the gate — the gate only fires on payloads that declare one. See the [error code reference](https://dogfood-lab.github.io/testing-os/handbook/error-codes/) for how the `CONTRACT_SCHEMA_TOO_*` rejections surface to a consumer.
95
+
78
96
  ## Docs
79
97
 
80
98
  📖 Full handbook: **<https://dogfood-lab.github.io/testing-os/handbook/>**
package/dist/index.d.ts CHANGED
@@ -43,4 +43,5 @@ export declare function _loadSchemaForTests(filename: string, dirOverride?: stri
43
43
  export { compileSchema, validatePayload, createAjv, _resetValidatorCacheForTests, _schemasModuleInstanceCount, type ValidationError, type ValidationResult, } from './validate.js';
44
44
  export { SUPPORTED_SCHEMA_VERSIONS, type SupportedSchemaVersion, type SupportedSchemaContract, } from './schema-versions.js';
45
45
  export { PRODUCT_SURFACES, EXECUTION_MODES, EVIDENCE_KINDS, type ProductSurface, type ExecutionMode, type EvidenceKind, } from './enums.js';
46
+ export { EXAMPLE_PAYLOADS, type Submission, type Record, type Finding, type ScenarioResult, type StepResult, type ScenarioEvidence, type Ref, type Source, type Timing, type CiCheck, type CiCheckKind, type CiCheckStatus, type Verdict, type StepStatus, type RecordOverallVerdict, type Verification, type ProvenanceRemediation, type FindingStatus, type JourneyStage, type IssueKind, type RootCauseKind, type RemediationKind, type TransferScope, type FindingEvidence, type FindingEvidenceKind, type FixRef, type FixRefKind, type FindingDerived, type FindingReview, type ReviewAction, type RejectReason, type FindingLineage, type FindingInvalidation, } from './payload-types.js';
46
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA6DA,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,EAAE,UAA+C,CAAC;AAC3E,eAAO,MAAM,sBAAsB,EAAE,UAA0D,CAAC;AAChG,eAAO,MAAM,aAAa,EAAE,UAAgD,CAAC;AAC7E,eAAO,MAAM,aAAa,EAAE,UAAgD,CAAC;AAC7E,eAAO,MAAM,oBAAoB,EAAE,UAAuD,CAAC;AAC3F,eAAO,MAAM,cAAc,EAAE,UAAiD,CAAC;AAC/E,eAAO,MAAM,YAAY,EAAE,UAAuC,CAAC;AACnE,eAAO,MAAM,cAAc,EAAE,UAAyC,CAAC;AAEvE,eAAO,MAAM,UAAU;;;;;;;;;CASb,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,UAAU,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CAEtF;AAED,OAAO,EACL,aAAa,EACb,eAAe,EACf,SAAS,EACT,4BAA4B,EAC5B,2BAA2B,EAC3B,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA6DA,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,EAAE,UAA+C,CAAC;AAC3E,eAAO,MAAM,sBAAsB,EAAE,UAA0D,CAAC;AAChG,eAAO,MAAM,aAAa,EAAE,UAAgD,CAAC;AAC7E,eAAO,MAAM,aAAa,EAAE,UAAgD,CAAC;AAC7E,eAAO,MAAM,oBAAoB,EAAE,UAAuD,CAAC;AAC3F,eAAO,MAAM,cAAc,EAAE,UAAiD,CAAC;AAC/E,eAAO,MAAM,YAAY,EAAE,UAAuC,CAAC;AACnE,eAAO,MAAM,cAAc,EAAE,UAAyC,CAAC;AAEvE,eAAO,MAAM,UAAU;;;;;;;;;CASb,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,UAAU,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CAEtF;AAED,OAAO,EACL,aAAa,EACb,eAAe,EACf,SAAS,EACT,4BAA4B,EAC5B,2BAA2B,EAC3B,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC;AAMpB,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,GAAG,EACR,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,MAAM,EACX,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -85,4 +85,9 @@ export function _loadSchemaForTests(filename, dirOverride) {
85
85
  export { compileSchema, validatePayload, createAjv, _resetValidatorCacheForTests, _schemasModuleInstanceCount, } from './validate.js';
86
86
  export { SUPPORTED_SCHEMA_VERSIONS, } from './schema-versions.js';
87
87
  export { PRODUCT_SURFACES, EXECUTION_MODES, EVIDENCE_KINDS, } from './enums.js';
88
+ // FT-h — hand-authored TypeScript interfaces for the contract payload SHAPES,
89
+ // so TS consumers get compile-time safety on the envelope (the schema OBJECTS
90
+ // + validatePayload only catch shape errors at runtime). Kept in sync with the
91
+ // JSON schemas; each interface carries a `Mirrors:` pointer to its source.
92
+ export { EXAMPLE_PAYLOADS, } from './payload-types.js';
88
93
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,SAAS,IAAI,CAAC,QAAgB,EAAE,WAAoB;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,uDAAuD,QAAQ,QAAQ,IAAI,MACxE,CAAW,CAAC,OACf,EAAE,CACH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;IACvC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,wDAAwD,QAAQ,QAAQ,IAAI,iEACzE,CAAW,CAAC,OACf,EAAE,CACH,CAAC;IACJ,CAAC;AACH,CAAC;AAcD,MAAM,CAAC,MAAM,YAAY,GAAe,IAAI,CAAC,4BAA4B,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,sBAAsB,GAAe,IAAI,CAAC,uCAAuC,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,aAAa,GAAe,IAAI,CAAC,6BAA6B,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,aAAa,GAAe,IAAI,CAAC,6BAA6B,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAe,IAAI,CAAC,oCAAoC,CAAC,CAAC;AAC3F,MAAM,CAAC,MAAM,cAAc,GAAe,IAAI,CAAC,8BAA8B,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAe,IAAI,CAAC,oBAAoB,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,cAAc,GAAe,IAAI,CAAC,sBAAsB,CAAC,CAAC;AAEvE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,MAAM,EAAE,YAAY;IACpB,gBAAgB,EAAE,sBAAsB;IACxC,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,aAAa;IACtB,cAAc,EAAE,oBAAoB;IACpC,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,cAAc;CAChB,CAAC;AAIX;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,WAAoB;IACxE,OAAO,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACrC,CAAC;AAED,OAAO,EACL,aAAa,EACb,eAAe,EACf,SAAS,EACT,4BAA4B,EAC5B,2BAA2B,GAG5B,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,yBAAyB,GAG1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,cAAc,GAIf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,SAAS,IAAI,CAAC,QAAgB,EAAE,WAAoB;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,uDAAuD,QAAQ,QAAQ,IAAI,MACxE,CAAW,CAAC,OACf,EAAE,CACH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;IACvC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,wDAAwD,QAAQ,QAAQ,IAAI,iEACzE,CAAW,CAAC,OACf,EAAE,CACH,CAAC;IACJ,CAAC;AACH,CAAC;AAcD,MAAM,CAAC,MAAM,YAAY,GAAe,IAAI,CAAC,4BAA4B,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,sBAAsB,GAAe,IAAI,CAAC,uCAAuC,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,aAAa,GAAe,IAAI,CAAC,6BAA6B,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,aAAa,GAAe,IAAI,CAAC,6BAA6B,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAe,IAAI,CAAC,oCAAoC,CAAC,CAAC;AAC3F,MAAM,CAAC,MAAM,cAAc,GAAe,IAAI,CAAC,8BAA8B,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAe,IAAI,CAAC,oBAAoB,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,cAAc,GAAe,IAAI,CAAC,sBAAsB,CAAC,CAAC;AAEvE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,MAAM,EAAE,YAAY;IACpB,gBAAgB,EAAE,sBAAsB;IACxC,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,aAAa;IACtB,cAAc,EAAE,oBAAoB;IACpC,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,cAAc;CAChB,CAAC;AAIX;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,WAAoB;IACxE,OAAO,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACrC,CAAC;AAED,OAAO,EACL,aAAa,EACb,eAAe,EACf,SAAS,EACT,4BAA4B,EAC5B,2BAA2B,GAG5B,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,yBAAyB,GAG1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,cAAc,GAIf,MAAM,YAAY,CAAC;AAEpB,8EAA8E;AAC9E,8EAA8E;AAC9E,+EAA+E;AAC/E,2EAA2E;AAC3E,OAAO,EACL,gBAAgB,GAkCjB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,401 @@
1
+ /**
2
+ * Hand-authored TypeScript interfaces for the contract payload shapes.
3
+ *
4
+ * FT-h (Wave, HIGH, consumability). The package exports the JSON-schema
5
+ * OBJECTS, the three full-set enum unions, and `validatePayload`, but no
6
+ * TypeScript interface for the actual payload SHAPES. A TS consumer that
7
+ * builds a submission, reads a persisted record, or constructs a finding got
8
+ * zero compile-time safety on the envelope — `validatePayload` only catches
9
+ * the mistake at runtime, after the bad object already flowed through typed
10
+ * code as `unknown`/`any`.
11
+ *
12
+ * These interfaces give consumers a typed shape to assert against at author
13
+ * time. They are HAND-MAINTAINED to mirror the JSON schemas — there is no
14
+ * codegen step — so each interface and nested type carries a `Mirrors:`
15
+ * pointer to its source schema, and the {@link EXAMPLE_PAYLOADS} consts at the
16
+ * bottom are `satisfies`-checked so `tsc --build` (which CI runs via
17
+ * `npm run verify` → `npm run build`) goes RED the moment an interface drifts
18
+ * from a representative payload. The companion vitest
19
+ * (`test/payload-types.test.ts`) closes the other half of the loop: it pushes
20
+ * those same examples through `validatePayload` and asserts the JSON schema
21
+ * AGREES they are valid. Interface drift in EITHER direction is caught.
22
+ *
23
+ * Reused enum unions: enum-typed fields reference the exported
24
+ * {@link ProductSurface} / {@link ExecutionMode} / {@link EvidenceKind} unions
25
+ * rather than re-typing the literals, so those fields stay sealed to the same
26
+ * single source the cross-contract enum seal enforces on the JSON side.
27
+ *
28
+ * SCOPE — the four payloads FT-h names: {@link Submission},
29
+ * {@link ScenarioResult}, {@link Record}, {@link Finding}. The other four
30
+ * contract schemas (pattern, recommendation, doctrine, policy) are out of
31
+ * scope for this slice and intentionally not modelled here; add them the same
32
+ * way (interface + `Mirrors:` pointer + a `satisfies` example) when a consumer
33
+ * needs them.
34
+ */
35
+ import type { ProductSurface, ExecutionMode, EvidenceKind } from './enums.js';
36
+ /** Scenario- and run-level verdict. Mirrors the `verdict` / `overall_verdict` enum. */
37
+ export type Verdict = 'pass' | 'fail' | 'blocked' | 'partial';
38
+ /** Per-step status. Mirrors `scenario_results[].step_results[].status`. */
39
+ export type StepStatus = 'pass' | 'fail' | 'blocked' | 'skip' | 'partial';
40
+ /** Machine CI check kind. Mirrors `ci_checks[].kind`. */
41
+ export type CiCheckKind = 'test' | 'coverage' | 'lint' | 'security' | 'build' | 'other';
42
+ /** Machine CI check status. Mirrors `ci_checks[].status`. */
43
+ export type CiCheckStatus = 'pass' | 'fail' | 'skip';
44
+ /** Git ref of the work under test. Mirrors the `ref` object. */
45
+ export interface Ref {
46
+ /** Branch name, if applicable. */
47
+ branch?: string;
48
+ /** 40-char lowercase-hex commit SHA. Schema pattern: `^[0-9a-f]{40}$`. */
49
+ commit_sha: string;
50
+ /** Release version tag if applicable. */
51
+ version?: string;
52
+ }
53
+ /** SCM provider that ran the workflow. Mirrors the `source.provider` enum. */
54
+ export type SourceProvider = 'github' | 'gitlab';
55
+ /** SCM provenance of the run. Mirrors the `source` object. */
56
+ export interface Source {
57
+ /** SCM provider — 'github' (GitHub Actions) or 'gitlab' (GitLab CI). */
58
+ provider: SourceProvider;
59
+ /** Workflow filename that produced the submission (e.g. a GitHub Actions YAML or '.gitlab-ci.yml'). */
60
+ workflow: string;
61
+ /** Provider-native run ID: a GitHub Actions run ID or a GitLab pipeline/job ID. */
62
+ provider_run_id: string;
63
+ /** Run attempt number. Schema default is 1. */
64
+ attempt?: number;
65
+ /** URL to the provider run. Schema format: uri. */
66
+ run_url: string;
67
+ /** Username that triggered the workflow. */
68
+ actor?: string;
69
+ }
70
+ /** Wall-clock timing of the run. Mirrors the `timing` object. */
71
+ export interface Timing {
72
+ /** ISO-8601 date-time the run started. */
73
+ started_at: string;
74
+ /** ISO-8601 date-time the run finished. */
75
+ finished_at: string;
76
+ /** Duration in milliseconds. */
77
+ duration_ms?: number;
78
+ }
79
+ /** A machine-evaluated CI result. Mirrors a `ci_checks[]` element. */
80
+ export interface CiCheck {
81
+ id: string;
82
+ kind: CiCheckKind;
83
+ status: CiCheckStatus;
84
+ /** Numeric result (test count, coverage %, etc.). */
85
+ value?: number;
86
+ /** Policy threshold if applicable. */
87
+ threshold?: number;
88
+ }
89
+ /** A single per-step execution result. Mirrors `scenario_results[].step_results[]`. */
90
+ export interface StepResult {
91
+ /** Must match a step.id from the scenario definition. Pattern: `^[a-z0-9][a-z0-9-]*$`. */
92
+ step_id: string;
93
+ status: StepStatus;
94
+ notes?: string;
95
+ }
96
+ /** A piece of evidence attached to a scenario result. Mirrors `scenario_results[].evidence[]`. */
97
+ export interface ScenarioEvidence {
98
+ /** Evidence kind — reuses the sealed full-set {@link EvidenceKind} union. */
99
+ kind: EvidenceKind;
100
+ /** Evidence URL. Schema format: uri. */
101
+ url: string;
102
+ description?: string;
103
+ /** ISO-8601 date-time when this evidence URL becomes unavailable. */
104
+ expires_at?: string;
105
+ }
106
+ /**
107
+ * One scenario's dogfood evidence.
108
+ *
109
+ * Mirrors the `scenario_results[]` item shape shared by the submission and the
110
+ * persisted record. `product_surface` / `execution_mode` reuse the sealed
111
+ * full-set enum unions.
112
+ */
113
+ export interface ScenarioResult {
114
+ /** Stable ID matching a scenario definition in the source repo. */
115
+ scenario_id: string;
116
+ scenario_name?: string;
117
+ /** Semver. Schema pattern: `^\d+\.\d+\.\d+$`. */
118
+ scenario_version?: string;
119
+ product_surface: ProductSurface;
120
+ execution_mode: ExecutionMode;
121
+ /** Human attester ID. Verifier enforces presence when execution_mode is human or mixed. */
122
+ attested_by?: string;
123
+ verdict: Verdict;
124
+ /** Required when verdict is blocked. Verifier enforces. */
125
+ blocking_reason?: string;
126
+ /** Per-step execution results. Schema minItems: 1. */
127
+ step_results: StepResult[];
128
+ evidence?: ScenarioEvidence[];
129
+ notes?: string;
130
+ }
131
+ /**
132
+ * Source-authored dogfood submission payload — what a consumer repo emits via
133
+ * `repository_dispatch`. Carries NO verifier-owned fields (no `verification`,
134
+ * no `policy_version`); `overall_verdict` is a flat {@link Verdict} the source
135
+ * PROPOSES (the verifier may confirm or downgrade, never upgrade).
136
+ *
137
+ * Mirrors: dogfood-record-submission.schema.json.
138
+ */
139
+ export interface Submission {
140
+ /** Semver of the submission schema. Schema pattern: `^\d+\.\d+\.\d+$`. */
141
+ schema_version: string;
142
+ /** Unique run identifier. Schema pattern: `^[A-Za-z0-9_-]+$` (filesystem-path-safe). */
143
+ run_id: string;
144
+ /** Full org/repo name. Schema pattern: `^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$`. */
145
+ repo: string;
146
+ ref: Ref;
147
+ source: Source;
148
+ timing: Timing;
149
+ /** Optional — not all dogfood runs include CI. */
150
+ ci_checks?: CiCheck[];
151
+ /** Dogfood evidence. Schema minItems: 1. */
152
+ scenario_results: ScenarioResult[];
153
+ /** Source-proposed verdict (flat). */
154
+ overall_verdict: Verdict;
155
+ notes?: string;
156
+ }
157
+ /**
158
+ * The persisted record's `overall_verdict` object. Unlike the submission's
159
+ * flat verdict, the record nests proposed-vs-verified to record the verifier's
160
+ * decision. Mirrors `overall_verdict` in dogfood-record.schema.json.
161
+ */
162
+ export interface RecordOverallVerdict {
163
+ /** Verdict as proposed by the source repo. */
164
+ proposed: Verdict;
165
+ /** Final verdict after central verification. */
166
+ verified: Verdict;
167
+ /** True if verifier downgraded the proposed verdict. Schema default: false. */
168
+ downgraded?: boolean;
169
+ /** Machine-readable reasons if verifier downgraded. */
170
+ downgrade_reasons?: string[];
171
+ }
172
+ /**
173
+ * Provenance-remediation metadata — present when a record's provenance could
174
+ * not be auto-confirmed but was manually stub-verified. Mirrors
175
+ * `verification.provenance_remediation` in dogfood-record.schema.json.
176
+ */
177
+ export interface ProvenanceRemediation {
178
+ status?: 'stub_verified';
179
+ /** Schema maxLength: 500. */
180
+ note?: string;
181
+ remediated_at: string;
182
+ /** Tri-state: the original boolean, or null when it was never evaluated. */
183
+ original_provenance_confirmed?: boolean | null;
184
+ }
185
+ /**
186
+ * Tamper-evident hash-chain metadata stamped by the persist layer when a record
187
+ * is written. Mirrors the OPTIONAL `integrity` object in
188
+ * dogfood-record.schema.json — records persisted before the integrity chain
189
+ * existed have no integrity block, so the field is optional on {@link Record}.
190
+ * The digest is computed over the record with this block removed (you cannot
191
+ * hash the digest into itself).
192
+ */
193
+ export interface RecordIntegrity {
194
+ /** Lowercase sha256 hex (64 chars) of the canonicalized record without the integrity block. Schema pattern: `^[0-9a-f]{64}$`. */
195
+ submission_digest: string;
196
+ /** The previous entry's submission_digest, or 64 zeros (genesis) for the first entry. Schema pattern: `^[0-9a-f]{64}$`. */
197
+ prev_digest: string;
198
+ /** Monotonic chain position, starting at 0. Schema minimum: 0. */
199
+ seq: number;
200
+ }
201
+ /**
202
+ * Verifier-owned verification block. Mirrors `verification` in
203
+ * dogfood-record.schema.json. Never authored by source repos.
204
+ */
205
+ export interface Verification {
206
+ /** Final outcome. No pending state in persisted records. */
207
+ status: 'accepted' | 'rejected';
208
+ verified_at: string;
209
+ /** True if the provider API (GitHub Actions or GitLab CI, per source.provider) confirmed the source run exists and matches claims. */
210
+ provenance_confirmed: boolean;
211
+ /** True if submission passed JSON Schema validation. */
212
+ schema_valid: boolean;
213
+ /** True if record satisfies all applicable policy rules. */
214
+ policy_valid: boolean;
215
+ /** Machine-readable rejection reasons. Empty/absent if accepted. */
216
+ rejection_reasons?: string[];
217
+ provenance_remediation?: ProvenanceRemediation;
218
+ }
219
+ /**
220
+ * Canonical persisted record written by the central verifier — all
221
+ * source-authored fields plus verifier-owned ones (`policy_version`,
222
+ * `verification`, and the nested {@link RecordOverallVerdict}). Never authored
223
+ * by source repos.
224
+ *
225
+ * Mirrors: dogfood-record.schema.json.
226
+ *
227
+ * Named `Record` to match the schema title; this shadows the TS global
228
+ * `Record<K, V>` utility type WITHIN modules that import it, which is the
229
+ * intended contract-first naming. Modules needing the utility can alias on
230
+ * import (`import type { Record as DogfoodRecord }`).
231
+ */
232
+ export interface Record {
233
+ /** Semver of the persisted record schema. */
234
+ schema_version: string;
235
+ /** Semver of the policy this record was evaluated against. Set by verifier. */
236
+ policy_version: string;
237
+ run_id: string;
238
+ repo: string;
239
+ ref: Ref;
240
+ source: Source;
241
+ timing: Timing;
242
+ ci_checks?: CiCheck[];
243
+ scenario_results: ScenarioResult[];
244
+ overall_verdict: RecordOverallVerdict;
245
+ verification: Verification;
246
+ notes?: string;
247
+ /** Tamper-evident hash-chain metadata stamped at persist. Optional — absent on pre-chain records. */
248
+ integrity?: RecordIntegrity;
249
+ }
250
+ /** Finding lifecycle status. Mirrors `status`. */
251
+ export type FindingStatus = 'candidate' | 'reviewed' | 'accepted' | 'rejected';
252
+ /** Where in the product experience the lesson was observed. Mirrors `journey_stage`. */
253
+ export type JourneyStage = 'install' | 'setup' | 'first_run' | 'core_loop' | 'export' | 'publish' | 'recovery' | 'integration' | 'verification' | 'rollout';
254
+ /** What visibly went wrong. Mirrors `issue_kind`. */
255
+ export type IssueKind = 'entrypoint_truth' | 'interface_assumption' | 'docs_drift' | 'schema_mismatch' | 'build_output_mismatch' | 'flag_contract_mismatch' | 'evidence_insufficiency' | 'evidence_overconstraint' | 'policy_mismatch' | 'freshness_miscalibration' | 'read_after_write_timing' | 'provenance_gap' | 'execution_mode_mismatch' | 'surface_misclassification' | 'ux_discoverability' | 'verification_gap' | 'dispatch_format' | 'concurrency_conflict' | 'process_lifecycle';
256
+ /** Why it actually happened. Mirrors `root_cause_kind`. */
257
+ export type RootCauseKind = 'contract_drift' | 'docs_code_drift' | 'surface_misclassification' | 'missing_precondition' | 'policy_overconstraint' | 'policy_underconstraint' | 'build_config_error' | 'interface_assumption_error' | 'timing_race' | 'tooling_gap' | 'human_process_gap' | 'schema_alignment_failure' | 'dispatch_encoding_error' | 'process_model_mismatch';
258
+ /** What kind of fix resolved it. Mirrors `remediation_kind`. */
259
+ export type RemediationKind = 'docs_change' | 'scenario_change' | 'policy_calibration' | 'schema_fix' | 'build_config_fix' | 'entrypoint_fix' | 'verification_fix' | 'classification_fix' | 'retry_logic' | 'evidence_requirement_change' | 'workflow_change' | 'dispatch_fix' | 'process_fix';
260
+ /**
261
+ * How far the lesson should travel. Mirrors the finding `transfer_scope` enum
262
+ * (the FULL 5-value set — NOT the deliberate 3-value doctrine subset).
263
+ */
264
+ export type TransferScope = 'repo_local' | 'surface_local' | 'surface_archetype' | 'execution_mode' | 'org_wide';
265
+ /** Type of evidence supporting a finding. Mirrors `evidence[].evidence_kind`. */
266
+ export type FindingEvidenceKind = 'record' | 'scenario_result' | 'ci_check' | 'policy' | 'artifact' | 'doc' | 'rejection';
267
+ /** A structured evidence binding on a finding. Mirrors `evidence[]`. */
268
+ export interface FindingEvidence {
269
+ evidence_kind: FindingEvidenceKind;
270
+ /** Run ID of the source record. */
271
+ record_id?: string;
272
+ /** Scenario ID if evidence is from a scenario result. */
273
+ scenario_id?: string;
274
+ /** Path or URL to an artifact. */
275
+ artifact_ref?: string;
276
+ /** Path to the policy file. */
277
+ policy_ref?: string;
278
+ /** Path to a documentation file. */
279
+ doc_ref?: string;
280
+ /** Schema maxLength: 500. */
281
+ note?: string;
282
+ }
283
+ /** Type of fix reference. Mirrors `fix_refs[].ref_kind`. */
284
+ export type FixRefKind = 'commit' | 'pr' | 'doc' | 'policy_change' | 'scenario_change' | 'workflow_change';
285
+ /** A link to a concrete repair action. Mirrors `fix_refs[]`. */
286
+ export interface FixRef {
287
+ ref_kind: FixRefKind;
288
+ /** Commit SHA, PR URL, file path, etc. */
289
+ ref: string;
290
+ /** Schema maxLength: 500. */
291
+ note?: string;
292
+ }
293
+ /** Derivation metadata — present when a finding was machine-generated. Mirrors `derived`. */
294
+ export interface FindingDerived {
295
+ method: 'deterministic_rule';
296
+ /** Pattern: `^rule-[a-z0-9][a-z0-9-]*$`. */
297
+ rule_id: string;
298
+ derived_at: string;
299
+ /** Schema minLength: 10, maxLength: 1000. */
300
+ rationale: string;
301
+ }
302
+ /** The most recent review action taken on a finding. Mirrors `review.last_action`. */
303
+ export type ReviewAction = 'review' | 'accept' | 'reject' | 'edit' | 'merge' | 'reopen' | 'invalidate' | 'supersede';
304
+ /** Structured reject reason. Mirrors `review.reject_reason`. */
305
+ export type RejectReason = 'insufficient_evidence' | 'duplicate' | 'classification_error' | 'not_portable' | 'noise' | 'source_truth_changed' | 'merged_into_canonical';
306
+ /** Current state of the most recent review action. Mirrors `review`. */
307
+ export interface FindingReview {
308
+ reviewed_by?: string;
309
+ reviewed_at?: string;
310
+ /** Schema maxLength: 1000. */
311
+ decision_reason?: string;
312
+ /** Schema maxLength: 2000. */
313
+ review_notes?: string;
314
+ last_action?: ReviewAction;
315
+ /**
316
+ * Structured reject reason. The schema's `allOf` makes this REQUIRED when
317
+ * `status` is `rejected` — that conditional cannot be expressed in a plain
318
+ * interface, so callers building a rejected finding must populate it (the
319
+ * runtime `validatePayload` check is what enforces the conditional).
320
+ */
321
+ reject_reason?: RejectReason;
322
+ }
323
+ /** Merge and supersession lineage. Mirrors `lineage`. */
324
+ export interface FindingLineage {
325
+ /** Finding IDs merged into this canonical finding. */
326
+ merged_from?: string[];
327
+ /** Finding ID that supersedes this one. */
328
+ superseded_by?: string;
329
+ }
330
+ /** Invalidation metadata — present when an accepted finding is no longer trustworthy. Mirrors `invalidation`. */
331
+ export interface FindingInvalidation {
332
+ is_invalidated: boolean;
333
+ invalidated_at: string;
334
+ /** Review event ID that triggered the invalidation. */
335
+ invalidated_by?: string;
336
+ /** Schema minLength: 5, maxLength: 1000. */
337
+ reason: string;
338
+ }
339
+ /**
340
+ * A reviewed, evidence-backed lesson extracted from one or more dogfood runs —
341
+ * the smallest durable unit of reusable learning. `product_surface` /
342
+ * `execution_mode` reuse the sealed full-set enum unions.
343
+ *
344
+ * Mirrors: dogfood-finding.schema.json. The schema additionally enforces an
345
+ * `allOf` conditional (status `rejected` ⇒ `review.reject_reason` required)
346
+ * that is not expressible here; rely on `validatePayload('finding', …)` for it.
347
+ */
348
+ export interface Finding {
349
+ /** Semver of the finding schema. */
350
+ schema_version: string;
351
+ /** Stable slug. Pattern: `^dfind-[a-z0-9][a-z0-9-]*$`. */
352
+ finding_id: string;
353
+ /** Schema minLength: 10, maxLength: 200. */
354
+ title: string;
355
+ status: FindingStatus;
356
+ /** Full org/repo. Pattern: `^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$`. */
357
+ repo: string;
358
+ product_surface: ProductSurface;
359
+ execution_mode?: ExecutionMode;
360
+ journey_stage: JourneyStage;
361
+ issue_kind: IssueKind;
362
+ root_cause_kind: RootCauseKind;
363
+ remediation_kind: RemediationKind;
364
+ transfer_scope: TransferScope;
365
+ /** Schema minLength: 20, maxLength: 1000. */
366
+ summary: string;
367
+ /** Portable rule derived from this finding. Schema maxLength: 500. */
368
+ doctrine_statement?: string;
369
+ /** Schema maxLength: 2000. */
370
+ notes?: string;
371
+ /** Run IDs of the source records. Schema minItems: 1. */
372
+ source_record_ids: string[];
373
+ /** Scenario IDs relevant to this finding. */
374
+ scenario_ids?: string[];
375
+ /** Structured evidence binding. Schema minItems: 1 — a finding with no evidence is invalid. */
376
+ evidence: FindingEvidence[];
377
+ fix_refs?: FixRef[];
378
+ created_at?: string;
379
+ updated_at?: string;
380
+ derived?: FindingDerived;
381
+ review?: FindingReview;
382
+ lineage?: FindingLineage;
383
+ invalidation?: FindingInvalidation;
384
+ }
385
+ /**
386
+ * Representative valid payloads, one per modelled interface. Exported so the
387
+ * companion vitest can push them through `validatePayload` and assert the JSON
388
+ * schema agrees — the runtime half of the FT-h drift seal. Consumers may also
389
+ * import these as ready-made fixtures.
390
+ *
391
+ * The `as const` example bodies above are `satisfies`-checked against their
392
+ * interfaces; here we widen to the interface types so the exported shape is the
393
+ * interface (not a frozen literal) for downstream reuse.
394
+ */
395
+ export declare const EXAMPLE_PAYLOADS: {
396
+ submission: Submission;
397
+ scenarioResult: ScenarioResult;
398
+ record: Record;
399
+ finding: Finding;
400
+ };
401
+ //# sourceMappingURL=payload-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload-types.d.ts","sourceRoot":"","sources":["../src/payload-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Hand-authored TypeScript interfaces for the contract payload shapes.
3
+ *
4
+ * FT-h (Wave, HIGH, consumability). The package exports the JSON-schema
5
+ * OBJECTS, the three full-set enum unions, and `validatePayload`, but no
6
+ * TypeScript interface for the actual payload SHAPES. A TS consumer that
7
+ * builds a submission, reads a persisted record, or constructs a finding got
8
+ * zero compile-time safety on the envelope — `validatePayload` only catches
9
+ * the mistake at runtime, after the bad object already flowed through typed
10
+ * code as `unknown`/`any`.
11
+ *
12
+ * These interfaces give consumers a typed shape to assert against at author
13
+ * time. They are HAND-MAINTAINED to mirror the JSON schemas — there is no
14
+ * codegen step — so each interface and nested type carries a `Mirrors:`
15
+ * pointer to its source schema, and the {@link EXAMPLE_PAYLOADS} consts at the
16
+ * bottom are `satisfies`-checked so `tsc --build` (which CI runs via
17
+ * `npm run verify` → `npm run build`) goes RED the moment an interface drifts
18
+ * from a representative payload. The companion vitest
19
+ * (`test/payload-types.test.ts`) closes the other half of the loop: it pushes
20
+ * those same examples through `validatePayload` and asserts the JSON schema
21
+ * AGREES they are valid. Interface drift in EITHER direction is caught.
22
+ *
23
+ * Reused enum unions: enum-typed fields reference the exported
24
+ * {@link ProductSurface} / {@link ExecutionMode} / {@link EvidenceKind} unions
25
+ * rather than re-typing the literals, so those fields stay sealed to the same
26
+ * single source the cross-contract enum seal enforces on the JSON side.
27
+ *
28
+ * SCOPE — the four payloads FT-h names: {@link Submission},
29
+ * {@link ScenarioResult}, {@link Record}, {@link Finding}. The other four
30
+ * contract schemas (pattern, recommendation, doctrine, policy) are out of
31
+ * scope for this slice and intentionally not modelled here; add them the same
32
+ * way (interface + `Mirrors:` pointer + a `satisfies` example) when a consumer
33
+ * needs them.
34
+ */
35
+ // ---------------------------------------------------------------------------
36
+ // Representative example payloads — the load-bearing compile-time seal.
37
+ //
38
+ // Each const is `satisfies`-checked against its interface. `tsc --build` (run
39
+ // by CI via `npm run verify` → `npm run build`) compiles this `src/` file, so
40
+ // any field that an interface declares but a representative payload cannot fill
41
+ // — or any interface field that drifts in type from the JSON schema's intent —
42
+ // turns the build RED here, at author time, not at a downstream consumer.
43
+ //
44
+ // `satisfies` (not a type annotation) keeps each const's literal type narrow
45
+ // AND asserts assignability to the interface, so an EXTRA property that the
46
+ // interface forbids is also a compile error. The companion vitest pushes these
47
+ // same values through `validatePayload` so the JSON schema independently agrees
48
+ // they are valid — drift on either side is caught.
49
+ //
50
+ // Values mirror the representative payloads already proven valid in
51
+ // test/validate.test.ts, so they share that file's known-good provenance.
52
+ // ---------------------------------------------------------------------------
53
+ const EXAMPLE_SUBMISSION = {
54
+ schema_version: '1.0.0',
55
+ run_id: 'run-01H8Y4ZC9XJWQ5N6',
56
+ repo: 'dogfood-lab/testing-os',
57
+ ref: { commit_sha: 'a'.repeat(40), branch: 'main' },
58
+ source: {
59
+ provider: 'github',
60
+ workflow: 'dogfood.yml',
61
+ provider_run_id: '12345',
62
+ run_url: 'https://github.com/dogfood-lab/testing-os/actions/runs/12345',
63
+ },
64
+ timing: {
65
+ started_at: '2026-04-26T18:00:00Z',
66
+ finished_at: '2026-04-26T18:05:00Z',
67
+ },
68
+ scenario_results: [
69
+ {
70
+ scenario_id: 'cli-resolve-and-list',
71
+ product_surface: 'cli',
72
+ execution_mode: 'bot',
73
+ verdict: 'pass',
74
+ step_results: [{ step_id: 'install', status: 'pass' }],
75
+ },
76
+ ],
77
+ overall_verdict: 'pass',
78
+ };
79
+ const EXAMPLE_SCENARIO_RESULT = {
80
+ scenario_id: 'cli-resolve-and-list',
81
+ scenario_name: 'Resolve loadout and list its packages',
82
+ scenario_version: '1.0.0',
83
+ product_surface: 'cli',
84
+ execution_mode: 'mixed',
85
+ attested_by: 'human-attester-01',
86
+ verdict: 'partial',
87
+ step_results: [
88
+ { step_id: 'install', status: 'pass' },
89
+ { step_id: 'resolve', status: 'partial', notes: 'slow but completed' },
90
+ ],
91
+ evidence: [
92
+ { kind: 'log', url: 'https://example.com/run.log' },
93
+ ],
94
+ };
95
+ const EXAMPLE_RECORD = {
96
+ schema_version: '1.0.0',
97
+ policy_version: '1.0.0',
98
+ run_id: 'run-01H8Y4ZC9XJWQ5N6',
99
+ repo: 'dogfood-lab/testing-os',
100
+ ref: { commit_sha: 'b'.repeat(40) },
101
+ source: {
102
+ provider: 'github',
103
+ workflow: 'dogfood.yml',
104
+ provider_run_id: '12345',
105
+ run_url: 'https://github.com/dogfood-lab/testing-os/actions/runs/12345',
106
+ },
107
+ timing: {
108
+ started_at: '2026-04-26T18:00:00Z',
109
+ finished_at: '2026-04-26T18:05:00Z',
110
+ },
111
+ scenario_results: [
112
+ {
113
+ scenario_id: 'cli-resolve-and-list',
114
+ product_surface: 'cli',
115
+ execution_mode: 'bot',
116
+ verdict: 'pass',
117
+ step_results: [{ step_id: 'install', status: 'pass' }],
118
+ },
119
+ ],
120
+ overall_verdict: { proposed: 'pass', verified: 'pass' },
121
+ verification: {
122
+ status: 'accepted',
123
+ verified_at: '2026-04-26T18:06:00Z',
124
+ provenance_confirmed: true,
125
+ schema_valid: true,
126
+ policy_valid: true,
127
+ },
128
+ };
129
+ const EXAMPLE_FINDING = {
130
+ schema_version: '1.0.0',
131
+ finding_id: 'dfind-testing-os-schemas-payload-types',
132
+ title: 'Schemas package shipped no payload interfaces',
133
+ status: 'accepted',
134
+ repo: 'dogfood-lab/testing-os',
135
+ product_surface: 'npm-package',
136
+ journey_stage: 'verification',
137
+ issue_kind: 'schema_mismatch',
138
+ root_cause_kind: 'tooling_gap',
139
+ remediation_kind: 'schema_fix',
140
+ transfer_scope: 'org_wide',
141
+ summary: 'TS consumers of @dogfood-lab/schemas got no compile-time safety on the payload envelope; only validatePayload caught shape errors, at runtime.',
142
+ source_record_ids: ['testing-os-fth-001'],
143
+ evidence: [{ evidence_kind: 'doc', doc_ref: 'packages/schemas/src/payload-types.ts' }],
144
+ };
145
+ /**
146
+ * Representative valid payloads, one per modelled interface. Exported so the
147
+ * companion vitest can push them through `validatePayload` and assert the JSON
148
+ * schema agrees — the runtime half of the FT-h drift seal. Consumers may also
149
+ * import these as ready-made fixtures.
150
+ *
151
+ * The `as const` example bodies above are `satisfies`-checked against their
152
+ * interfaces; here we widen to the interface types so the exported shape is the
153
+ * interface (not a frozen literal) for downstream reuse.
154
+ */
155
+ export const EXAMPLE_PAYLOADS = {
156
+ submission: EXAMPLE_SUBMISSION,
157
+ scenarioResult: EXAMPLE_SCENARIO_RESULT,
158
+ record: EXAMPLE_RECORD,
159
+ finding: EXAMPLE_FINDING,
160
+ };
161
+ //# sourceMappingURL=payload-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload-types.js","sourceRoot":"","sources":["../src/payload-types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dogfood-lab/schemas",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "JSON schemas for the testing-os contract spine — record, finding, pattern, recommendation, doctrine, policy, scenario, submission.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,7 +26,8 @@
26
26
  "run_id": {
27
27
  "type": "string",
28
28
  "minLength": 1,
29
- "description": "Unique dogfood run identifier. ULID recommended for sortability."
29
+ "pattern": "^[A-Za-z0-9_-]+$",
30
+ "description": "Unique dogfood run identifier. ULID recommended for sortability. Charset is constrained because run_id becomes a filesystem path segment in the persisted record path; this mirrors the persist-time guard."
30
31
  },
31
32
 
32
33
  "repo": {
@@ -59,16 +60,16 @@
59
60
  "properties": {
60
61
  "provider": {
61
62
  "type": "string",
62
- "enum": ["github"],
63
- "description": "SCM provider. GitHub-only for now."
63
+ "enum": ["github", "gitlab"],
64
+ "description": "SCM provider that ran the workflow. 'github' (GitHub Actions) or 'gitlab' (GitLab CI). The verifier selects a provider-specific provenance adapter to confirm the run."
64
65
  },
65
66
  "workflow": {
66
67
  "type": "string",
67
- "description": "Workflow filename that produced this submission."
68
+ "description": "Workflow filename that produced this submission (e.g. a GitHub Actions workflow YAML or '.gitlab-ci.yml')."
68
69
  },
69
70
  "provider_run_id": {
70
71
  "type": "string",
71
- "description": "GitHub Actions run ID (provider-native)."
72
+ "description": "Provider-native run identifier. For 'github' this is the GitHub Actions run ID; for 'gitlab' this is the GitLab pipeline ID (or job ID when run_url points at a job)."
72
73
  },
73
74
  "attempt": {
74
75
  "type": "integer",
@@ -34,7 +34,8 @@
34
34
  "run_id": {
35
35
  "type": "string",
36
36
  "minLength": 1,
37
- "description": "Unique dogfood run identifier. Carried from submission."
37
+ "pattern": "^[A-Za-z0-9_-]+$",
38
+ "description": "Unique dogfood run identifier. Carried from submission. Charset is constrained because run_id becomes a filesystem path segment in the persisted record path; this mirrors the persist-time guard."
38
39
  },
39
40
 
40
41
  "repo": {
@@ -67,16 +68,16 @@
67
68
  "properties": {
68
69
  "provider": {
69
70
  "type": "string",
70
- "enum": ["github"],
71
- "description": "SCM provider. GitHub-only for now."
71
+ "enum": ["github", "gitlab"],
72
+ "description": "SCM provider that ran the workflow. 'github' (GitHub Actions) or 'gitlab' (GitLab CI). Carried verbatim from the submission."
72
73
  },
73
74
  "workflow": {
74
75
  "type": "string",
75
- "description": "Workflow filename that produced the submission."
76
+ "description": "Workflow filename that produced the submission (e.g. a GitHub Actions workflow YAML or '.gitlab-ci.yml')."
76
77
  },
77
78
  "provider_run_id": {
78
79
  "type": "string",
79
- "description": "GitHub Actions run ID (provider-native)."
80
+ "description": "Provider-native run identifier. For 'github' this is the GitHub Actions run ID; for 'gitlab' this is the GitLab pipeline ID (or job ID when run_url points at a job)."
80
81
  },
81
82
  "attempt": {
82
83
  "type": "integer",
@@ -266,7 +267,7 @@
266
267
  },
267
268
  "provenance_confirmed": {
268
269
  "type": "boolean",
269
- "description": "True if GitHub API confirmed the source run exists and matches claims."
270
+ "description": "True if the provider API (GitHub Actions or GitLab CI, selected by source.provider) confirmed the source run exists and matches the claimed repo, commit, and finished state."
270
271
  },
271
272
  "schema_valid": {
272
273
  "type": "boolean",
@@ -298,6 +299,34 @@
298
299
  "notes": {
299
300
  "type": "string",
300
301
  "description": "Freeform summary from the source."
302
+ },
303
+
304
+ "integrity": {
305
+ "type": "object",
306
+ "title": "Integrity Chain Entry",
307
+ "description": "Tamper-evident hash-chain metadata stamped by the persist layer when this record is written. Optional and backward-compatible: records persisted before the integrity chain existed have no integrity block and remain valid. The digest is computed over the record WITH this block removed (you cannot hash the digest into itself), so it is stable regardless of the integrity block's contents.",
308
+ "additionalProperties": false,
309
+ "required": ["submission_digest", "prev_digest", "seq"],
310
+ "properties": {
311
+ "submission_digest": {
312
+ "type": "string",
313
+ "title": "Submission Digest",
314
+ "description": "Lowercase sha256 hex (64 chars) of the canonicalized record with the integrity block removed. Recomputed by the chain verifier to detect tampering.",
315
+ "pattern": "^[0-9a-f]{64}$"
316
+ },
317
+ "prev_digest": {
318
+ "type": "string",
319
+ "title": "Previous Digest",
320
+ "description": "The submission_digest of the previous record in the append-only chain, or 64 zeros (the genesis digest) for the first entry. Links this record to its predecessor.",
321
+ "pattern": "^[0-9a-f]{64}$"
322
+ },
323
+ "seq": {
324
+ "type": "integer",
325
+ "title": "Chain Sequence Number",
326
+ "description": "Monotonic position of this record in the append-only chain, starting at 0 for the genesis entry.",
327
+ "minimum": 0
328
+ }
329
+ }
301
330
  }
302
331
  }
303
332
  }