CB-WP-0036 done: the pace flag and the first ornament declarations
Some checks failed
ci / check (push) Failing after 4s
Some checks failed
ci / check (push) Failing after 4s
--pace speed|interactive, defaulting to Speed. Nothing reads it yet, and that is the point: it is the seam clay-animate attaches to, and a seam is cheap now where a retrofit would not be. A misspelt pace is refused rather than defaulting, because quietly falling back to Speed would look exactly like the renderer being broken. I3 is asserted rather than intended: the same scripted game at both paces must produce a byte-identical serialised recording and the same end state hash. Mutation-proven — leak the pace into the seed and it fails with "the recording differs by pace, so a renderer has become mechanism". specs/OrnamentRegister.md carries four declarations. This reverses the reasoning written in T03 earlier, which said the first declarations would come from F18's unvendored files: instances already existed. Hand order is what prompted the category, and "who deals" was the maintainer's own example. O3 is the interesting one — seat ORDER is mechanism because GR-R08 rotates Lead, while where a seat is drawn is not. I5 is executable: check_ornament_falsifier fails any row still declared that names no falsifier, mutation-proven red on O1. Presence, never adequacy, and the finding text says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
b231c1b5e2
commit
bd9e168af5
7 changed files with 315 additions and 9 deletions
|
|
@ -306,6 +306,51 @@ def check_gate_registry(root=REPO):
|
|||
return out
|
||||
|
||||
|
||||
def check_ornament_falsifier(root=REPO):
|
||||
"""Ornamentation I5 — an open declaration names what would refute it.
|
||||
|
||||
**A declaration is a claim that something does not matter**, and this
|
||||
project's finding register is largely a list of times that claim was
|
||||
wrong. One that cannot be wrong is not a claim, it is a preference
|
||||
with a table row.
|
||||
|
||||
Presence, never adequacy -- the same split as ADR-0018 D5.
|
||||
"""
|
||||
out = []
|
||||
reg = os.path.join(root, "specs", "OrnamentRegister.md")
|
||||
if not os.path.exists(reg):
|
||||
return out
|
||||
with open(reg) as fh:
|
||||
text = fh.read()
|
||||
m = re.search(r"<!-- ornament-register:begin -->(.*?)"
|
||||
r"<!-- ornament-register:end -->", text, re.S)
|
||||
if not m:
|
||||
return out
|
||||
for line in m.group(1).splitlines():
|
||||
line = line.strip()
|
||||
if not line.startswith("|") or line.startswith("|---"):
|
||||
continue
|
||||
cells = [c.strip() for c in line.strip("|").split("|")]
|
||||
if len(cells) != 5 or cells[0] == "id":
|
||||
continue
|
||||
oid, state = cells[0], cells[3]
|
||||
# A refuted or withdrawn row is history; the rule binds a claim
|
||||
# that is still being made.
|
||||
if state != "declared":
|
||||
continue
|
||||
body = re.search(rf"^- \*\*{re.escape(oid)} [^\n]*(?:\n(?!- \*\*O\d).*)*",
|
||||
text, re.M)
|
||||
if not body or "Falsifier:" not in body.group(0):
|
||||
out.append(Finding(
|
||||
"ornament",
|
||||
"specs/OrnamentRegister.md",
|
||||
f"{oid} is declared ornamentation and names no falsifier "
|
||||
f"(Ornamentation.md I5). Say what would make it mechanism. "
|
||||
f"NOTE: this checks presence, not adequacy.",
|
||||
))
|
||||
return out
|
||||
|
||||
|
||||
def check_sensitivity_stated(root=REPO):
|
||||
"""GameDesign §1.4 / ADR-0018 — a finding whose claim is arithmetic
|
||||
must name the variable it depends on.
|
||||
|
|
@ -384,6 +429,7 @@ CHECKS = (
|
|||
check_reporting_tools_self_test,
|
||||
check_gate_registry,
|
||||
check_sensitivity_stated,
|
||||
check_ornament_falsifier,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -473,6 +519,29 @@ def self_test():
|
|||
check("sensitivity: a note has no measurement to be sensitive about",
|
||||
not check_sensitivity_stated(tmp), "GameDesign §3.1")
|
||||
|
||||
# Ornamentation I5. Same shape: it must say NO and it must say YES.
|
||||
def orn(state, prose):
|
||||
body = ("<!-- ornament-register:begin -->\n\n"
|
||||
"| id | ornaments | grounded | state | raised |\n"
|
||||
"|---|---|---|---|---|\n"
|
||||
f"| O9 | a thing | provisional | {state} | 2026-01-01 |\n"
|
||||
"\n<!-- ornament-register:end -->\n\n"
|
||||
f"- **O9 — a thing.** {prose}\n")
|
||||
with open(os.path.join(tmp, "specs", "OrnamentRegister.md"), "w") as fh:
|
||||
fh.write(body)
|
||||
|
||||
orn("declared", "It does not matter.")
|
||||
check("ornament: a declaration with no falsifier is caught",
|
||||
len(check_ornament_falsifier(tmp)) == 1,
|
||||
"a claim that cannot be wrong is not a claim")
|
||||
orn("declared", "It does not matter. **Falsifier:** a rule naming it.")
|
||||
check("ornament: naming a falsifier clears it",
|
||||
not check_ornament_falsifier(tmp),
|
||||
"without this it would fire on everything")
|
||||
orn("refuted", "It does not matter.")
|
||||
check("ornament: a refuted row is history, not a live claim",
|
||||
not check_ornament_falsifier(tmp))
|
||||
|
||||
wp("ready", ["done", "todo"])
|
||||
f = check_workplan_lifecycle(tmp)
|
||||
check("lifecycle detects `ready` after work has started",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue