Canon logo
DF Canon
Product database handbook — confidential, internal use

AGENTS.md — df-product-db (Damn Filters Product Database)

Pipeline is Python-stdlib-only (3.10+), SQLite-backed product-data project for the Damn Filters Shopify catalog. Builds a normalized DB from Matrixify exports and classifies products into dimensional "classes" (seeds for DF house part numbers). Optional read-only / dev tools (ruff, duckdb, openpyxl) are declared in requirements-optional.txt — the pipeline itself stays stdlib-only.

A class = same OD × ID × length × shape × media × top endcap × bottom endcap × build configuration (8 attributes), matched at nominal dimension. Media is part of the class, not a variant suffix. Dimensions, both endcaps, and build are product-level; media is the only variant-level attribute — non-primary variants need a media-specific class ID, never "inherit". The old "gate" term is retired — say "endcap". The dimension-merge allowance is the tolerance window — never "band" (a material dust-collector construction term) or "slack" (the DF comms app).

Reserved words

One meaning each — keep them out of other contexts so they don't confuse:

Known traps

Read first

Names. "Canon" = this repo/pipeline (df-product-db). "DFI" and "EFI" are the same vendor-confidential reference dataset (dfi/, legacy name EFI — the files still say efi_*); it is authoritative — among the highest-authority sources we have, much more authoritative than our own data. We trust it.

All docs/ (one line each): domain-model.md (canonical rules) · column-map.md (offsets) · grade-pricing.md (grades + pricing) · media-taxonomy.md (media catalog) · open-questions.md (live backlog) · metafield-definitions.md (Shopify metafields) · final-export-fields.md (final-export plan) · n8n-metafield-contract.md (n8n order MANIFEST) · donaldson-media-mapping.md (Donaldson substrate mapping) · duckdb-analysis.md (read-only SQL) · architecture.md (schema + model) · HANDOFF-2026-09-02-competitor-study.md (competitor-study runbook) · HANDOFF-2026-09-05-dims-drift-codex.md (external dims-drift handoff).

Counts are DERIVED — never written in prose

Class counts, in-stock counts, and the dcf-default backlog are derived — run python3 src/classification_report.py and python3 src/invariants.py for the current numbers. If a number must be cited, write date + source (e.g. "N,NNN classes (report YYYY-MM-DD)"). Enforced by docs.no_hardcoded_counts in src/invariants.py.

archive/ is historical — do not cite

archive/ (incl. archive/hermes-skill-notes/) holds superseded docs and old pass notes. It is a record, not a source: never import rules, counts, or terminology from it into live docs or code. Current truth = docs/domain-model.md (rules) + CHANGELOG.md (decisions) + imports/class-overrides.csv (data).

Locked rules (Viktor — do not override)

Data files

Pitfalls