Typed, dated, defaulted waits — and cut the four-hop chain

The register had nine waits in four days, one four hops deep: F-0003's
embargo waited on F-0009, which waited on railiance-platform, which
waited on live OpenBao verification, which waited on a credential nobody
has. No single link was wrong, which is why it needed a rule.

docs/method/dependencies.md: the register never waits to decide, it
decides and revises. Every wait carries who, what, since, what it would
change, what happens if nobody answers, and the date that default
applies. Depth one — a record never waits on a record that is itself
waiting. Defaults are dates and are pessimistic: silence costs the grade
the evidence supports rather than buying a softer one, and owners are
told the default in advance because a default nobody was warned about is
an ambush.

Applied: F-0009's embargo now lifts on railiance-platform reporting
coverage, with live verification as a refinement rather than a condition,
cutting the F-0003 chain from four hops to two. All eight open waits are
typed with defaults. make check reports them with age, owner and default
date, flags defaults come due, and catches depth-two violations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-20 22:34:56 +02:00
parent 56b8d61583
commit d5147bfaea
11 changed files with 220 additions and 7 deletions

View file

@ -121,6 +121,29 @@ def main() -> int:
]
section("Stalled — escalation trigger 5", bottom, "none")
# Waits: typed, dated, and defaulted (docs/method/dependencies.md).
waiting, due_defaults, deep = [], [], []
waiting_ids = {f["id"] for f in fs if f.get("waiting_on")}
for f in fs:
for w in (f.get("waiting_on") or []):
since = lib.moment(w.get("since"))
age = f"{(NOW - since).days}d" if since else "?"
when = lib.moment(w.get("default_at"))
waiting.append(f"{f['id']}{w.get('who')}: {str(w.get('what'))[:64]} ({age} old, defaults {w.get('default_at')})")
if when and NOW >= when:
due_defaults.append(
f"{f['id']}{w.get('who')} did not answer by {w.get('default_at')}; apply: {w.get('default')}"
)
# depth-two check: a record waiting on a record that is itself waiting
for ref in ([f.get("constraint_on")] if f.get("constraint_on") else []):
if ref in waiting_ids and f.get("waiting_on"):
deep.append(f"{f['id']} waits, and points at {ref} which also waits — depth two, cut one")
section("Waiting on someone", waiting, "nothing is waiting on anyone")
if due_defaults:
section("Defaults now due — apply them", due_defaults, "none")
if deep:
section("Dependency depth violations", deep, "none")
embargo = [
f"{f['id']} — lifts when: {f.get('embargo_condition')}"
for f in fs

View file

@ -96,6 +96,18 @@ def render() -> str:
id=f["id"], on=f.get("constraint_on", ""),
sev=f.get("constraint_severity", ""), text=f["constraint"]))
waits = [(f, w) for f in fs for w in (f.get("waiting_on") or [])]
if waits:
out += ["", "## Waiting on someone", "",
"Every wait resolves on its default date whether or not anyone answers.",
"Silence never buys a softer grade — see `docs/method/dependencies.md`.",
"", "| Finding | Who | What would change | Default if silent | On |",
"| --- | --- | --- | --- | --- |"]
for f, w in waits:
out.append("| {id} | {who} | {chg} | {dflt} | {at} |".format(
id=f["id"], who=w.get("who", ""), chg=w.get("would_change", ""),
dflt=w.get("default", ""), at=w.get("default_at", "")))
embargoed = [f for f in fs if f.get("disclosure") == "embargoed"]
if embargoed:
out += ["", "## Embargoes", "",