ADR 0081: a decision nothing cites is not yet in the chain
Decisions were the one link the cycle checks skipped, and measuring found 19 of 70 records orphaned — the credential flow and the module-runtime cluster among them, which is how a stale premise about a settled decision survived in working memory. cycle.py now refuses an accepted record nothing cites; the 19 got true homes (design frontmatter, the playbook that implements 0021, META for the process records). The overview names the practice: spec-driven development with provenance. https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
@@ -17,6 +17,10 @@ What is enforced:
|
||||
"nothing, the capability existed" is an answer).
|
||||
research a known `status:`; a `graduated` overview says what it `became:`, and every
|
||||
target it names exists.
|
||||
decisions every accepted record is REACHABLE from the cycle: cited by a design doc's
|
||||
frontmatter, a research overview, an issue report, a 00-META document, or another
|
||||
record's extends/supersedes chain. A decision nothing points at is one nobody will
|
||||
find by following pointers -- which is how records go stale in people's heads.
|
||||
|
||||
Deliberately NOT enforced: `resolved` issues may leave `located-in` empty (a symptom that
|
||||
turned out not to be a defect has no owner), and as-is docs need no decisions (they
|
||||
@@ -135,10 +139,42 @@ def main():
|
||||
if not os.path.exists(os.path.join(ROOT, target)):
|
||||
bad(path, "became names %s, which does not exist" % target)
|
||||
|
||||
# ---- decisions -------------------------------------------------------------------
|
||||
records = {}
|
||||
for path in sorted(glob.glob(os.path.join(ROOT, "02-DECISIONS", "[0-9]*.md"))):
|
||||
front = frontmatter(path)
|
||||
records[os.path.basename(path)] = (path, (front or {}).get("status"))
|
||||
|
||||
cited = set()
|
||||
sources = (glob.glob(os.path.join(ROOT, "03-DESIGN", "*", "*.md"))
|
||||
+ glob.glob(os.path.join(ROOT, "01-RESEARCH", "*", "00-overview.md"))
|
||||
+ glob.glob(os.path.join(ROOT, "04-ISSUES", "*", "00-report.md"))
|
||||
+ glob.glob(os.path.join(ROOT, "00-META", "**", "*.md"), recursive=True))
|
||||
for path in sources:
|
||||
text = open(path, encoding="utf-8").read()
|
||||
if os.sep + "03-DESIGN" + os.sep in path:
|
||||
# A design doc's governing citations live in frontmatter; a prose mention is
|
||||
# commentary, not a home.
|
||||
m = re.match(r"^---\n(.*?)\n---", text, re.S)
|
||||
text = m.group(1) if m else ""
|
||||
for m in re.finditer(r"([0-9]{4}-[^\s\)\],#]+\.md)", text):
|
||||
cited.add(os.path.basename(m.group(1)))
|
||||
for name in records:
|
||||
front = frontmatter(records[name][0]) or {}
|
||||
for key in ("extends", "supersedes", "superseded-by"):
|
||||
v = front.get(key)
|
||||
if isinstance(v, str) and v:
|
||||
cited.add(os.path.basename(v))
|
||||
for name, (path, status) in records.items():
|
||||
if status == "accepted" and name not in cited:
|
||||
bad(path, "an accepted decision nothing in the cycle cites -- give it a home in a "
|
||||
"design doc's decisions:, a research became:, an issue, or 00-META")
|
||||
|
||||
checked = (
|
||||
len(glob.glob(os.path.join(ROOT, "03-DESIGN", "0*", "*.md")))
|
||||
+ len(glob.glob(os.path.join(ROOT, "04-ISSUES", "*", "00-report.md")))
|
||||
+ len(glob.glob(os.path.join(ROOT, "01-RESEARCH", "*", "00-overview.md")))
|
||||
+ len(records)
|
||||
)
|
||||
if failures:
|
||||
print("cycle: %d document(s) break the development cycle:" % len(failures))
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Process — overview
|
||||
|
||||
How work moves through HQ, and who may do what. Every other document in this folder is a
|
||||
How work moves through HQ, and who may do what. In industry terms this is **spec-driven
|
||||
development, with provenance**: the decision is the why, the design doc is the spec, `code:`
|
||||
names the implementation, and the lab beds are the conformance tests — and unlike the common
|
||||
form, the chain itself is checked ([ADR 0080](../../02-DECISIONS/0080-the-development-cycle-is-checked.md),
|
||||
[0081](../../02-DECISIONS/0081-a-decision-nothing-cites-is-not-yet-in-the-chain.md)). Every other document in this folder is a
|
||||
playbook: trigger, who runs it, steps, outputs. Engineers and agents follow the same
|
||||
playbooks; agents must not act outside them.
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Playbook 05 — Constitution sync
|
||||
|
||||
Implements [ADR 0021](../../02-DECISIONS/0021-hq-is-the-source-of-the-constitution.md): HQ is
|
||||
the source of the constitution, and the knowledge-base page is derived, never edited.
|
||||
|
||||
**Trigger.** [`how-we-build.md`](../how-we-build.md) changed a rule that the mesh enforces at
|
||||
runtime.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user