Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .claude/skills/report/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ Structure, in order:
6. **Open items** — split by who acts: owner (dashboard/env/merge),
orchestrator (cross-repo), this repo's next pass.

Where the pass consumed a sync spec, per-item dispositions use
exactly these five words: `applied` / `ported-as-contract` /
`already-present` / `not-applicable-because` / `open`. `open` means
the detect fires but the item is deliberately out of this session's
scope — name it under Open items with who acts. Do not invent a
sixth word; the orchestrator's tooling reads these five.

Anti-patterns, all observed in the fleet and all rejected on
receipt: "should work" (test it or mark it unverified); summary
claims without artifacts; green CI presented as deploy proof when
Expand Down
51 changes: 51 additions & 0 deletions tests/test_auth_demos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Every auth-gate demo entry resolves — on THIS site, loudly.

`build_demo` swallows import failures BY DESIGN (a broken example must never
take down the sign-in funnel), and its warning only fires when that
endpoint's card actually renders — which never happens when the endpoint is
not a page here at all. That combination made a dead entry perfectly silent:
every fork inherited the template's entry, it resolved on none of them, and
their gate cards rendered demo-less from fork time without a line of log
(batch-1 finding, excalidraw, 2026-08-25). This file is the one surface
where a dead entry is loud.

Byte-verbatim across the fleet: it sweeps THIS repo's DEMOS table against
THIS repo's page registry, so the same bytes hold everywhere. The entries
themselves are site judgment (swap in your own hero example) — an EMPTY
table passes; a dead entry never does.
"""

from __future__ import annotations

import importlib

from lib.auth_demos import DEMOS


def test_every_demo_endpoint_is_a_registered_page(app_module):
import dash

registered = {entry["path"] for entry in dash.page_registry.values()}
dead = sorted(set(DEMOS) - registered)
assert dead == [], (
f"DEMOS endpoints that are not pages on this site: {dead} — "
"a card that never renders can never surface its own broken demo"
)


def test_every_demo_module_imports_and_exposes_component(app_module):
# import_module is exactly what build_demo does in production; app_module
# first, because the example modules assume the app (and the docs pass
# that imports them at startup) already exists.
problems = []
for path, spec in sorted(DEMOS.items()):
try:
module = importlib.import_module(spec["module"])
except Exception as e:
problems.append(f"{path}: {spec['module']} failed to import ({e})")
continue
if not hasattr(module, "component"):
problems.append(
f"{path}: {spec['module']} has no module-level `component`"
)
assert problems == [], "; ".join(problems)
69 changes: 63 additions & 6 deletions tests/test_claude_kit.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,30 @@ def _ignored(path: str) -> bool:
)


def _in_repo(rel: str) -> bool:
return ".." not in rel and not rel.startswith("/")


def _machine_fence(kind: str, text: str, where: str) -> None:
"""The shared pin for machine fences (```yaml sync-verbatim in specs,
```yaml byte-owned in DIVERGENCES.md): exactly one block, `- path`
lines with `#` comments, every path repo-relative and real at HEAD.
Empty is valid — an empty block is a statement, a missing one is an
omission. `# requires: <path>` lines (the fan-out's adoption gate,
1.6.23) are validated like paths — a typo'd gate gates nothing."""
omission. Gate lines (the fan-out's adoption gates) are validated
like paths — a typo'd gate gates nothing:

`# requires: <path>` (1.6.23) — the block applies only where
<path> exists. For paths no pre-existing file can occupy;
where one can, the gate must name a contract instead
(sync/README.md — flows' pre-existing CLAUDE.md, 1.6.28).
`# requires-contract: <path> :: <clause>` (1.6.28) — the block
applies only where <path> exists AND contains <clause>. The
clause must be real in THIS repo's copy at HEAD too.
`- <path> # requires: <other>` (1.6.28) — per-file gate: the
fan-out skips this one copy where <other> is absent, instead
of gating the whole block (clerkhook: a lockdown fork has no
lib/auth_demos.py, legitimately, and must still receive the
rest)."""
fences = re.findall(
r"^```yaml " + kind + r"[ \t]*\n(.*?)^```[ \t]*$", text, re.M | re.S
)
Expand All @@ -52,31 +69,71 @@ def _machine_fence(kind: str, text: str, where: str) -> None:
f"found {len(fences)}"
)
for raw in fences[0].splitlines():
required = re.match(r"#\s*requires:\s*(.+)$", raw.strip())
stripped = raw.strip()
if re.match(r"#\s*requires-contract:", stripped):
gate = re.match(
r"#\s*requires-contract:\s*(.+?)\s*::\s*(.+)$", stripped
)
assert gate, (
f"{where} {kind}: {raw!r} — `# requires-contract:` takes "
"`<path> :: <clause>`; a malformed gate gates nothing"
)
req, clause = gate.group(1).strip(), gate.group(2).strip()
assert _in_repo(req), (
f"{where} {kind}: `# requires-contract:` path {req!r} "
"escapes the repo"
)
assert (REPO / req).is_file(), (
f"{where} {kind}: `# requires-contract:` names {req!r} "
"which does not exist at HEAD — a typo'd gate gates nothing"
)
assert clause in (REPO / req).read_text(), (
f"{where} {kind}: `# requires-contract:` clause {clause!r} "
f"is not in this repo's own {req} — a typo'd clause gates "
"nothing"
)
continue
required = re.match(r"#\s*requires:\s*(.+)$", stripped)
if required:
req = required.group(1).strip()
assert ".." not in req and not req.startswith("/"), (
assert _in_repo(req), (
f"{where} {kind}: `# requires:` path {req!r} escapes the repo"
)
assert (REPO / req).is_file(), (
f"{where} {kind}: `# requires:` names {req!r} which does "
"not exist at HEAD — a typo'd gate gates nothing"
)
continue
entry = raw.split("#", 1)[0].strip()
entry, _, comment = raw.partition("#")
entry = entry.strip()
if not entry:
continue
assert entry.startswith("- "), (
f"{where} {kind}: {raw!r} is not a `- path` line"
)
path = entry[2:].strip()
assert ".." not in path and not path.startswith("/"), (
assert _in_repo(path), (
f"{where} {kind}: {path!r} escapes the repo"
)
assert (REPO / path).is_file(), (
f"{where} {kind}: {path!r} does not exist at HEAD "
"— the machine would act on nothing or the wrong thing"
)
# A per-file gate is the WHOLE trailing comment, `requires: <path>`
# from its first character; prose comments that merely mention the
# word stay prose.
per_file = re.match(r"\s*requires:\s*(.+)$", comment)
if per_file:
gate_path = per_file.group(1).strip()
assert _in_repo(gate_path), (
f"{where} {kind}: per-file gate on {path!r} escapes the "
f"repo: {gate_path!r}"
)
assert (REPO / gate_path).is_file(), (
f"{where} {kind}: per-file gate on {path!r} names "
f"{gate_path!r} which does not exist at HEAD — a typo'd "
"gate gates nothing"
)


def test_kit_files_exist_and_are_not_ignored():
Expand Down
Loading