types/: Seiten-Type-Spec-Anleitungsprosa in stackeigene guidance-Datei ausgelagert (schliesst #104)
Files changed: - AGENTS.md - CHANGES.md - VERSION - docs/ownership-and-templates.md - instructions/migrations/6.0.0-type-guidance-split.md - instructions/setup-instance.md - tools/CONTRACT.md - tools/chemenu/commands/dist_cmd.py - tools/chemenu/commands/types_cmd.py - tools/chemenu/tests/test_dist_cmd.py - tools/chemenu/tests/test_dist_upgrade.py - tools/chemenu/tests/test_type_resolver.py - tools/chemenu/tests/test_types_cmd.py - tools/chemenu/type_resolver.py - tools/chemenu/types_core.py - types/comparison.guidance.md - types/comparison.md - types/concept.guidance.md - types/concept.md - types/entity.guidance.md - types/entity.md - types/source.guidance.md - types/source.md - types/type-guidance.md - types/type-guidance.schema.yaml - types/type-spec.md
This commit is contained in:
1 parent
90ce41964f
commit
d49513bda6
26 files changed
+789
-238
No files matched your search
@@ -338,6 +338,32 @@ def instance_owned_type_stems() -> set[str]:
|
||||
return stems
|
||||
|
||||
|
||||
# The suffix a type-spec's own two files carry - `<stem>.md` and
|
||||
# `<stem>.schema.yaml` - as opposed to a sibling file that merely starts with
|
||||
# the same stem, such as `<stem>.guidance.md` (Gitea #104). Checked as an
|
||||
# exact suffix rather than by splitting on the first `.`, which is what let
|
||||
# `entity.guidance.md` be mistaken for the `entity` type-spec's own file
|
||||
# before this existed - a stack-owned file re-keyed as though it were the
|
||||
# instance's `.template` to adopt, and flagged as a leak by the other call
|
||||
# site for not being one.
|
||||
_TYPE_SCHEMA_SUFFIX = ".schema.yaml"
|
||||
|
||||
|
||||
def _owned_type_stem(relative: str) -> Optional[str]:
|
||||
"""The type stem `relative` (a path under `types/`, no `.template`
|
||||
suffix) names, if it is exactly that type-spec's own `<stem>.md` or
|
||||
`<stem>.schema.yaml` - `None` for anything else under `types/`,
|
||||
including a `<stem>.guidance.md` file. `_plan_types()` and `find_leaks()`
|
||||
both ask this instead of computing their own stem, so the two answer the
|
||||
same question about the same path (AGENTS.md invariant 8)."""
|
||||
name = relative.rsplit("/", 1)[-1]
|
||||
if name.endswith(_TYPE_SCHEMA_SUFFIX):
|
||||
return name[: -len(_TYPE_SCHEMA_SUFFIX)]
|
||||
if name.endswith(".md") and not name.endswith(".guidance.md"):
|
||||
return name[: -len(".md")]
|
||||
return None
|
||||
|
||||
|
||||
def _plan_types() -> dict[str, PlannedFile]:
|
||||
"""`types/`, with the page type-specs re-keyed as templates.
|
||||
|
||||
@@ -347,6 +373,11 @@ def _plan_types() -> dict[str, PlannedFile]:
|
||||
to be adopted before it counts. A type-spec's `.schema.yaml` travels with
|
||||
it, because the two are one type (see types/type-spec.md § Anatomy) and
|
||||
adopting half of it would leave a spec validated by a file it does not own.
|
||||
|
||||
A type-spec's optional `<name>.guidance.md` (Gitea #104) is the opposite:
|
||||
stack-owned even where the type-spec itself is instance-owned, and ships
|
||||
verbatim beside the `.template` - `_owned_type_stem` is what keeps it out
|
||||
of this re-keying despite sharing the type-spec's own stem.
|
||||
"""
|
||||
plan = _copy_tree(config.TYPES_DIR, "types", frozenset())
|
||||
stems = instance_owned_type_stems()
|
||||
@@ -355,9 +386,8 @@ def _plan_types() -> dict[str, PlannedFile]:
|
||||
|
||||
rekeyed: dict[str, PlannedFile] = {}
|
||||
for relative, planned in plan.items():
|
||||
name = relative.rsplit("/", 1)[-1]
|
||||
stem = name.split(".", 1)[0]
|
||||
if stem in stems:
|
||||
stem = _owned_type_stem(relative)
|
||||
if stem is not None and stem in stems:
|
||||
rekeyed[f"{relative}.template"] = planned
|
||||
else:
|
||||
rekeyed[relative] = planned
|
||||
@@ -512,7 +542,8 @@ def find_leaks(plan: dict[str, PlannedFile]) -> list[str]:
|
||||
elif (
|
||||
relative.startswith("types/")
|
||||
and not relative.endswith(".template")
|
||||
and name.split(".", 1)[0] in owned_types
|
||||
and (owned_stem := _owned_type_stem(relative)) is not None
|
||||
and owned_stem in owned_types
|
||||
):
|
||||
leaks.append(f"{relative} (this instance's page type-spec; ship the .template)")
|
||||
elif relative.startswith("instructions/dev/"):
|
||||
|
||||
@@ -55,7 +55,10 @@ def describe_type_command(
|
||||
"""Print one type's full contract: frontmatter fields (required/optional,
|
||||
with enums where declared), its subtype field if any, and its authoring
|
||||
body - the same information an LLM would otherwise gather by reading the
|
||||
raw type-spec and `.schema.yaml` files directly."""
|
||||
raw type-spec and `.schema.yaml` files directly. Where the type-spec
|
||||
declares `guidance:`, that stack-owned file's prose is composed in ahead
|
||||
of the type-spec's own body, so a `root: kb` type's contract still reads
|
||||
as one answer even though it lives in two files (Gitea #104)."""
|
||||
try:
|
||||
described = describe_type(name)
|
||||
except UnknownType as exc:
|
||||
@@ -89,9 +92,13 @@ def describe_type_command(
|
||||
typer.echo("")
|
||||
|
||||
typer.echo("## Authoring guidance")
|
||||
# A type-spec over 100 lines carries a generated table-of-contents region
|
||||
# (`chemenu/toc.py`), which serves whoever opens the file. Here it would be
|
||||
# noise: this command already hands over the whole body, so there is
|
||||
# nothing left for a navigation aid to navigate - only markers and a list
|
||||
# of headings the reader is about to see anyway.
|
||||
# A type-spec (and its guidance file) over 100 lines carries a generated
|
||||
# table-of-contents region (`chemenu/toc.py`), which serves whoever opens
|
||||
# the file directly. Here it would be noise: this command already hands
|
||||
# over the whole body, so there is nothing left for a navigation aid to
|
||||
# navigate - only markers and a list of headings the reader is about to
|
||||
# see anyway.
|
||||
if described["guidance"]:
|
||||
typer.echo(toc.strip_region(described["guidance"]))
|
||||
typer.echo("")
|
||||
typer.echo(toc.strip_region(described["body"]))
|
||||
Reference in new issue
Block a user