fix: types/type-spec.schema.yaml enforced against real type-spec frontmatter, doc-pull-through.md docs/-page count corrected (closes #105)
Files changed: - CHANGES.md - VERSION - instructions/dev/doc-pull-through.md - tools/CONTRACT.md - tools/chemenu/commands/docs_verify.py - tools/chemenu/tests/test_docs_verify.py - types/type-spec.md - types/type-spec.schema.yaml
This commit is contained in:
1 parent
6eb3f84256
commit
55f65c1ab1
8 files changed
+161
-7
No files matched your search
@@ -44,6 +44,15 @@ assume - is `instructions verify`'s job, not this one, since that module
|
||||
already owns the Skill/Instruction split (`skill_dirs()` vs
|
||||
`instruction_files()`).
|
||||
|
||||
An eighth checks the type layer against its own schema: every file under
|
||||
`types/` declaring `type: types/type-spec.md` must validate against
|
||||
`types/type-spec.schema.yaml`. Before this check existed the schema had
|
||||
already drifted behind two fields real type-specs carry (`root:`,
|
||||
`capture_fields:`) while `additionalProperties: false` sat there describing a
|
||||
contract nothing enforced - the exact "checked or absent" failure this file's
|
||||
opening paragraph names, just one level up, for the schema that describes the
|
||||
type layer instead of a copy the type layer's code produces (Gitea #105).
|
||||
|
||||
Everything here is a hard oracle: a set comparison or a regex, no judgment.
|
||||
Content quality of the contracts themselves stays with the LLM.
|
||||
"""
|
||||
@@ -422,6 +431,37 @@ def check_stack_required_types() -> list[str]:
|
||||
return issues
|
||||
|
||||
|
||||
def check_type_spec_frontmatter() -> list[str]:
|
||||
"""Every type-spec's own frontmatter must validate against
|
||||
`types/type-spec.schema.yaml` - the schema that describes the type layer
|
||||
gets the same enforcement any other type's schema gets (Gitea #105).
|
||||
|
||||
Before this check nothing ever called `validate_frontmatter` against a
|
||||
type-spec's own frontmatter, so the schema had quietly drifted behind two
|
||||
fields real type-specs actually carry (`root:`, `capture_fields:`)
|
||||
without anything failing - `additionalProperties: false` described a
|
||||
contract that bound nothing. `resolver.list_type_specs()` already reads
|
||||
every file's frontmatter once for `wikitool types list`; reusing it here
|
||||
means this check costs no second parse pass.
|
||||
"""
|
||||
from chemenu.type_resolver import resolver
|
||||
|
||||
issues: list[str] = []
|
||||
for type_path, frontmatter in resolver.list_type_specs():
|
||||
try:
|
||||
resolver.validate_frontmatter(
|
||||
frontmatter, "types/type-spec.md", source_file=config.ROOT / type_path
|
||||
)
|
||||
except ValueError as exc:
|
||||
# `validate_frontmatter`'s own message names the type path it
|
||||
# validated *against* (always `types/type-spec.md` here, since
|
||||
# every type-spec is validated against the same schema) rather
|
||||
# than the specific file that failed - prefix that file's own
|
||||
# path so two failures in one run stay distinguishable.
|
||||
issues.append(f"{type_path}: {exc}")
|
||||
return issues
|
||||
|
||||
|
||||
def check_legacy_type_blocks() -> list[str]:
|
||||
issues = []
|
||||
guarded = [
|
||||
@@ -857,11 +897,12 @@ def check_breaking_change_for_boundary() -> list[str]:
|
||||
|
||||
@app.command("verify")
|
||||
def verify():
|
||||
"""Check the CLI/README command tables, contract presence, type-form drift, ignore rules, version/changelog agreement, issue references, and link targets in shipped documents."""
|
||||
"""Check the CLI/README command tables, contract presence, type-form drift, every type-spec's frontmatter against its own schema, ignore rules, version/changelog agreement, issue references, and link targets in shipped documents."""
|
||||
issues = (
|
||||
check_cli_readme()
|
||||
+ check_readmes_have_no_command_table()
|
||||
+ check_collection_contracts()
|
||||
+ check_type_spec_frontmatter()
|
||||
+ check_legacy_type_blocks()
|
||||
+ check_ignored_content()
|
||||
+ check_version_changelog()
|
||||
@@ -875,10 +916,13 @@ def verify():
|
||||
if issues:
|
||||
fail("Documentation issues found:\n" + "\n".join(f"- {i}" for i in issues))
|
||||
|
||||
from chemenu.type_resolver import resolver
|
||||
|
||||
success(
|
||||
f"Docs verified: {len(registered_commands())} command(s) documented, "
|
||||
f"{len(kb_collections.iter_kb_collections())} collection(s) and "
|
||||
f"{len(STAGE_CONTRACTS)} stage contract(s) present, no legacy type blocks, "
|
||||
f"{len(resolver.list_type_specs())} type-spec(s) validating against their own schema, "
|
||||
f"{len(IGNORE_CANARIES)} ignore canaries clear, "
|
||||
f"no issue references in {len(shipped_prose())} shipped document(s), "
|
||||
f"tables of contents current and every link resolving on "
|
||||
|
||||
Reference in new issue
Block a user