Architecture
Data Flow
Section titled “Data Flow”Source repo workflow → Builds structured submission (JSON) → Emits via repository_dispatch to dogfood-labs
dogfood-labs ingestion pipeline → Schema validation (AJV against JSON Schema) → Provenance check (GitHub API — verify run actually happened) → Policy evaluation (enforcement tier, required scenarios, freshness) → Verdict computation (source proposes, verifier confirms or downgrades)
→ Accepted: records/<org>/<repo>/YYYY/MM/DD/<run-id>.json → Rejected: records/_rejected/<org>/<repo>/YYYY/MM/DD/<run-id>.json
→ Index rebuild: indexes/latest-by-repo.json, failing.json, stale.jsonKey Design Decisions
Section titled “Key Design Decisions”Central Ingestion
Section titled “Central Ingestion”Source repos never write records directly. They emit structured payloads via repository_dispatch, and only the dogfood-labs bot writes to the records directory. This prevents source repos from fabricating evidence.
Verdict Ownership
Section titled “Verdict Ownership”The source repo proposes a verdict (overall_verdict in the submission). The verifier can confirm or downgrade — never upgrade. A source claiming “pass” that fails schema or policy validation becomes “fail.”
Sharded Persistence
Section titled “Sharded Persistence”Records are stored at records/<org>/<repo>/YYYY/MM/DD/<run-id>.json. This provides natural time-sharding, easy browsing, and clean git history without merge conflicts.
Generated Indexes
Section titled “Generated Indexes”latest-by-repo.json is rebuilt from accepted records after every ingestion. Consumers read indexes, not the raw record tree. This keeps reads fast without scanning git history.
Components
Section titled “Components”| Component | Location | Purpose |
|---|---|---|
| Verifier | tools/verify/ | Schema, provenance, policy, verdict validation |
| Ingestion | tools/ingest/ | Pipeline orchestration, atomic persistence, index rebuild |
| Submission builder | tools/report/ | Canonical submission assembly for source repos |
| Portfolio | tools/portfolio/ | Org-level summary generation |
Verifier Pipeline (7 steps)
Section titled “Verifier Pipeline (7 steps)”The verifier (tools/verify/index.js) processes each submission through seven stages in order:
- Schema validation — validates the submission against
dogfood-record-submission.schema.jsonusing AJV. - Verifier-owned field guard — rejects submissions that include fields only the verifier may set (
policy_version,verification, oroverall_verdictas an object). - Provenance check — confirms the source workflow run actually exists via the GitHub Actions API (or a stub adapter in tests).
- Step results validation — checks that each scenario’s required steps have matching results and that verdicts are internally consistent.
- Policy evaluation — evaluates enforcement tier, required scenarios, freshness, and execution-mode constraints from the repo or global policy.
- Verdict computation — computes the final verdict. The source proposes a verdict string; the verifier may confirm or downgrade, never upgrade. Verdict severity from highest to lowest: fail, blocked, partial, pass.
- Record assembly — builds the persisted record with verifier-owned fields (
verification.status,verification.verified_at,overall_verdict.verified,overall_verdict.downgraded).
Generated Indexes
Section titled “Generated Indexes”The index generator (tools/ingest/rebuild-indexes.js) produces three files after every ingestion:
| Index | Content |
|---|---|
indexes/latest-by-repo.json | Latest accepted record per repo and surface — the primary read model for consumers |
indexes/failing.json | Records where the verified verdict is not pass |
indexes/stale.json | Repo/surface pairs with no accepted record within the staleness threshold (default 30 days) |
Atomic Persistence
Section titled “Atomic Persistence”Records are written atomically: the persist layer writes to a temporary file, then renames it to the final path. Duplicate detection by run_id prevents double-writes. Accepted records go to records/<org>/<repo>/YYYY/MM/DD/, rejected records to records/_rejected/<org>/<repo>/YYYY/MM/DD/.
Enforcement Tiers
Section titled “Enforcement Tiers”| Mode | Behavior | Default |
|---|---|---|
required | Blocks on violation | Yes — all repos start here |
warn-only | Warns but doesn’t block | Must have documented reason + review date |
exempt | Skips evaluation entirely | Must have documented reason + review date |
Missing policy defaults to required — the safe default.