feat(grade): incomplete becomes the floor with a per-grade roadmap [skip Codex]#32
Conversation
- Make incomplete the conformance floor: a record with identity but no source documents is valid, grades incomplete, and validate, build-index, and from-sheet all exit 0. Remove the below-floor none state. - Emit a per-grade roadmap to full. Each grade reports as satisfied, an outstanding delta, or gated (its own requirements met but blocked by a lower grade, naming the grade to reach). Add the grade-satisfied and grade-gated info findings. - Make the cutsheet a graded core requirement instead of a schema requirement, so an unattached cutsheet grades incomplete with a roadmap entry rather than failing schema validation. - Loosen the schema additively: shrink the index and product_family required sets and allow an empty source_files array. - Always stamp conformance_level; the index may be sparse for an incomplete record; bump the builder version to 0.5.0. - Re-stamp the example records to 0.8.0; grades are unchanged. - Reframe the docs and schema descriptions to three grades above an incomplete floor.
Codex Automated Code ReviewCode Review SummaryPR: v0.8.0 conformance model: P0 - Critical Issues (Must Fix)None found. P1 - High Priority Issues (Should Fix)
P2 - Medium Priority Issues (Consider Fixing)
P3 - Low Priority Issues (Optional)
Positive Observations
I could not run Automated review by OpenAI Codex |
|
| Filename | Overview |
|---|---|
| tools/validator/internal/grade/grade.go | Core grading logic rewritten correctly: LevelNone removed, LevelIncomplete becomes the zero-value floor, AchievedLevel no longer requires photometric anchors, hasCutsheet added as a core rubric rule, per-grade roadmap emission with satisfied/gap/gated states is logically sound. |
| tools/validator/internal/index/builder.go | Builder always stamps conformance_level; RequiredKeys shrunk to identity + always-generated keys; Index.required and RequiredKeys are now in sync. BuilderVersion bumped to 0.5.0. |
| tools/validator/cmd/ulc/main.go | All three subcommands correctly treat incomplete as a non-failure exit; the old 'none' fallback removed; from-sheet prints a notice for incomplete records without suppressing the write. |
| tools/validator/internal/sheet/convert.go | Empty cutsheet_file gracefully accepted; nil cutsheetRef is never dereferenced because assembleSourceFiles guards on cutsheetFilename. ulc_version default bumped to 0.8.0. |
| schema/ulc.schema.json | Three additive loosenings: minItems 1 to 0 on source_files, cutsheet removed from ProductFamily.required, three photometric projection keys removed from Index.required. No existing record becomes invalid. |
| schema/taxonomy.schema.json | ConformanceLevel description reframed to three grades above an incomplete floor; enum values unchanged; no breaking change. |
| tools/validator/internal/findings/findings.go | Two new INFO codes added (grade-satisfied, grade-gated); existing codes and Finding struct unchanged, so current JSON consumers are unaffected. |
| tools/validator/internal/grade/grade_test.go | Extensive new test coverage: zero-document floor, cutsheet as core rule, satisfied/gap/gated per-grade states, blocker-naming cases, and per-tier decomposition to full. |
| tools/validator/cmd/ulc/main_test.go | New CLI integration tests pin the floor contract end-to-end: identity-only record exits 0, missing catalog_model is rejected, from-sheet writes incomplete records with the correct conformance_level. |
| CHANGELOG.md | 0.8.0 entry is accurate and complete: behavior change for consumers clearly called out, all schema loosenings listed, grading, builder, and CLI changes covered. |
Reviews (5): Last reviewed commit: "docs(schema): state that source_files is..." | Re-trigger Greptile
- Make ulc from-sheet accept a workbook record with an empty cutsheet_file: it converts the record (omitting product_family.cutsheet and the synthesized datasheet source-file entry) so the record grades incomplete with a roadmap, instead of failing during conversion. - Default the from-sheet ulc_version to 0.8.0. - Add the cutsheet to the methodology core-requirements table. - Reframe the PIM mapping guides: omitting the cutsheet grades incomplete, not schema-invalid, since the cutsheet is a graded core requirement. - Clarify the schema and CLI text (the schema envelope versus identity; the per-grade roadmap to full). - Add tests: cutsheet-optional conversion, the malformed-versus-incomplete identity boundary, and the from-sheet incomplete write path.
- When an incomplete record has gaps at more than one lower grade, a gated higher grade (its own requirements met) now names the highest of those grades as the one to reach. Reaching a lower grade alone does not unlock it while an intermediate grade still has a gap. - Add a test for the core-plus-standard dual-gap case.
Codex Automated Code ReviewCode Review SummaryPR: v0.8.0 conformance-floor change: P0 - Critical Issues (Must Fix)None found. P1 - High Priority Issues (Should Fix)None found. P2 - Medium Priority Issues (Consider Fixing)
P3 - Low Priority Issues (Optional)None found. Positive Observations
Could not run Automated review by OpenAI Codex |
Bump the PIM emitter examples and the from-sheet design note to declare ulc_version 0.8.0, matching the converter default and every shipped example so a copied integration emits a current-spec record. Clarify the identity boundary: a record missing identity is malformed rather than incomplete, naming the schema-required authored fields (product_family.manufacturer.slug, product_family.family_id, product_family.catalog_model) and noting it fails JSON Schema validation and the builder cannot derive its required index keys (MissingRequiredKeys), a rejection distinct from the incomplete grade. Correct the changelog exit-code note: build-index runs no JSON Schema validation and gates on the builder's required index keys, while validate and from-sheet additionally fail on schema invalidity.
Codex Automated Code ReviewCode Review SummaryPR: v0.8.0 release update making P0 - Critical Issues (Must Fix)None found. P1 - High Priority Issues (Should Fix)
P2 - Medium Priority Issues (Consider Fixing)None found. P3 - Low Priority Issues (Optional)None found. Positive Observations
Automated review by OpenAI Codex |
The ConformanceLevel description previously claimed JSON Schema required fields are limited to record identity; the schema also requires the record envelope (version, identifiers, status, the generated index container, configuration, and source_files). Reword it to say required covers the record envelope plus product-family identity, matching the record schema description. Complete the identity set in the conformance description and the methodology and how-it-works incomplete sections by adding product_family.manufacturer.display_name, which is schema-required. Scope the builder's MissingRequiredKeys check to the two index keys it projects from identity (manufacturer_slug, catalog_model) and attribute the rest of the identity set to JSON Schema validation, so the two rejection mechanisms are no longer conflated.
Codex Automated Code ReviewCode Review SummaryPR: v0.8.0 conformance-floor change: P0 - Critical Issues (Must Fix)None found. P1 - High Priority Issues (Should Fix)None found. P2 - Medium Priority Issues (Consider Fixing)
P3 - Low Priority Issues (Optional)
Positive Observations
Automated review by OpenAI Codex |
…ADMEs [skip Codex] Replace the one-step roadmap wording in the validator README (guidance to reach the next level) with the per-grade roadmap through full, including the conformance/grade-satisfied and conformance/grade-gated INFO codes, so CLI consumers implement against the current output contract. Rename the examples README section from Conformance levels to Conformance grades for terminology consistency with the three-grades above-an-incomplete-floor model.
Codex Automated Code ReviewCode Review SummaryPR: v0.8.0 conformance model: P0 - Critical Issues (Must Fix)None found. P1 - High Priority Issues (Should Fix)
P2 - Medium Priority Issues (Consider Fixing)
P3 - Low Priority Issues (Optional)
Positive Observations
Validation note: I could not run Automated review by OpenAI Codex |
…t pointer The source_files description claimed source files are graded core items. The grader gates the core cutsheet on the family-level pointer product_family.cutsheet and does not grade the source_files array at all. Reword the description so it states the array is neither schema-required nor graded, and that product_family.cutsheet is the graded core cutsheet item while source_files carries integrity-tracked provenance.
Summary
Makes
incompletethe true floor of the conformance model and decomposes the roadmap per grade all the way to full. The model is now three grades (core,standard,full) above anincompletefloor.incomplete, andvalidate/build-index/from-sheetall exit 0. The below-floornonestate is removed.Behavior change for consumers
Records that previously failed
validate/build-index/from-sheetbecause they were anchorless or missing required index keys now succeed and gradeincompletewith a roadmap. Any tooling that treated a nonzero exit as "unacceptable" must treatincompleteas a valid, expected, below-core state. Nonzero exits remain only for schema-invalidity, malformed input, source-file integrity failures, or stored-vs-recomputed drift.Changes
schema/ulc.schema.json,schema/taxonomy.schema.json- loosen threerequiredsites andsource_files.minItems(1 to 0); reframe the descriptions. All additive: no existing record becomes invalid.tools/validator/internal/grade/grade.go- removeLevelNone; floorAchievedLevelatincomplete; add the cutsheet core rule; emit the per-grade roadmap with satisfied / gap / gated states.tools/validator/internal/findings/findings.go- addconformance/grade-satisfiedandconformance/grade-gatedinfo codes.tools/validator/internal/index/builder.go- always stampconformance_level; shrinkRequiredKeys; bumpBuilderVersionto0.5.0.tools/validator/cmd/ulc/main.go-incompleteis a success in all three subcommands.ulc_version0.8.0 /builder_version0.5.0; grades unchanged (four standard, Vode core).Test plan
go test ./...andgo test -race ./...passgo vet ./...clean;go build ./...cleanulc validate examples/*exits 0 for all five recordsTestZeroDocumentRecordGradesIncomplete,TestCLIFloorExitsZero), gated cascade (TestGatedGradesReported,TestGatedNamesIntermediateBlocker), per-grade roadmap, cutsheet core rule, builder always-stampCallouts for reviewers
grade.goReportper-grade loop: the three-state emission (satisfied / gap / gated) and theblockernaming.builder.goalways-stamp plus the shrunkRequiredKeys(identity only).