docs: remediate stable control runtime ADR review findings (#615)
Address review 443 on PR #616: mandatory operator-guide/runbook cross-links, LLM vs operator restart/relaunch split, and sanctioned post-merge parity staleness response (stop, report, operator reload, re-verify). Add docs tests enforcing F1–F3. Refs: #615
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
"""Documentation acceptance for the stable control runtime ADR (#615 / PR #616).
|
||||
|
||||
Enforces review 443 remediation:
|
||||
|
||||
* F1 — operator guide / runbooks cross-link the ADR (issue #615 AC2).
|
||||
* F2 — LLM sessions are not instructed to kill/restart/relaunch MCP; process
|
||||
restart is operator-owned; ADR is the authoritative split.
|
||||
* F3 — routine post-merge master-parity staleness has a sanctioned response
|
||||
(stop → report → operator reload → re-verify parity) and is not a full
|
||||
promotion ledger requirement.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
ADR = (
|
||||
REPO_ROOT
|
||||
/ "docs"
|
||||
/ "architecture"
|
||||
/ "mcp-stable-control-runtime-policy-adr.md"
|
||||
)
|
||||
ADR_REL = "architecture/mcp-stable-control-runtime-policy-adr.md"
|
||||
ADR_BASENAME = "mcp-stable-control-runtime-policy-adr.md"
|
||||
|
||||
CROSS_LINK_DOCS = (
|
||||
REPO_ROOT / "docs" / "wiki" / "Operator-Guide.md",
|
||||
REPO_ROOT / "docs" / "wiki" / "Runbooks.md",
|
||||
REPO_ROOT / "docs" / "llm-workflow-runbooks.md",
|
||||
)
|
||||
|
||||
|
||||
def _read(path: Path) -> str:
|
||||
assert path.is_file(), f"missing {path.relative_to(REPO_ROOT)}"
|
||||
return path.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_adr_exists_with_policy_core():
|
||||
text = _read(ADR)
|
||||
assert text.lstrip().startswith("#"), "ADR lacks a title"
|
||||
assert "#615" in text
|
||||
assert "stable control runtime" in text.lower()
|
||||
assert "2.3" in text and "2.4" in text and "2.5" in text and "2.6" in text
|
||||
|
||||
|
||||
def test_f1_operator_docs_cross_link_adr():
|
||||
for path in CROSS_LINK_DOCS:
|
||||
text = _read(path)
|
||||
assert ADR_BASENAME in text, (
|
||||
f"{path.relative_to(REPO_ROOT)} must cross-link {ADR_BASENAME} "
|
||||
f"(issue #615 acceptance criterion 2)"
|
||||
)
|
||||
|
||||
|
||||
def test_f1_adr_lists_cross_links_as_acceptance_not_optional_tooling():
|
||||
text = _read(ADR)
|
||||
# Acceptance section must require guide/runbook cross-links.
|
||||
assert "Operator guide / runbooks cross-link" in text or (
|
||||
"operator guide" in text.lower() and "cross-link" in text.lower()
|
||||
and "Acceptance" in text
|
||||
)
|
||||
# Cross-link must not remain only as optional tooling item #4.
|
||||
optional = text.split("## 5. Implementation follow-ups", 1)[-1].split(
|
||||
"## 6. Acceptance", 1
|
||||
)[0]
|
||||
assert "Operator Guide wiki cross-link to this ADR" not in optional, (
|
||||
"ADR §5 must not list operator-guide cross-link as optional tooling"
|
||||
)
|
||||
assert "Not optional" in text or "must** cross-link" in text.lower() or (
|
||||
"must cross-link" in text.lower()
|
||||
)
|
||||
|
||||
|
||||
def test_f2_runbook_fallback_is_operator_owned_not_llm_restart():
|
||||
runbooks = _read(REPO_ROOT / "docs" / "llm-workflow-runbooks.md")
|
||||
# Forbidden historical self-service instruction.
|
||||
forbidden = (
|
||||
"the LLM must relaunch or restart the client/MCP with the correct "
|
||||
"profile environment variable before claiming or working on any tasks"
|
||||
)
|
||||
assert forbidden not in runbooks, (
|
||||
"llm-workflow-runbooks must not instruct the LLM to relaunch/restart MCP"
|
||||
)
|
||||
assert "operator-owned" in runbooks.lower() or "Operator-owned" in runbooks
|
||||
assert ADR_BASENAME in runbooks
|
||||
|
||||
|
||||
def test_f2_workspace_rebind_does_not_require_llm_process_relaunch():
|
||||
runbooks = _read(REPO_ROOT / "docs" / "llm-workflow-runbooks.md")
|
||||
section = runbooks.split("### Safe reconnect / rebind procedure", 1)[-1]
|
||||
section = section.split("## Safety notes", 1)[0]
|
||||
# Must not tell the LLM alone to relaunch the MCP process as step 2.
|
||||
assert "Reconnect or relaunch the correct namespace MCP server from the intended" not in section
|
||||
assert "Operator-owned" in section or "operator" in section.lower()
|
||||
assert "worktree_path" in section
|
||||
collapsed = " ".join(section.lower().split())
|
||||
assert "client reconnect" in collapsed
|
||||
|
||||
|
||||
def test_f2_adr_forbids_llm_restart_and_supersedes_self_service_relaunch():
|
||||
text = _read(ADR)
|
||||
lower = text.lower()
|
||||
assert "must not" in lower and "restart" in lower
|
||||
assert "operator" in lower and "reload" in lower
|
||||
assert "supersedes" in lower
|
||||
assert "llm" in lower
|
||||
|
||||
|
||||
def test_f3_adr_defines_post_merge_parity_staleness_response():
|
||||
text = _read(ADR)
|
||||
lower = text.lower()
|
||||
assert "2.6" in text
|
||||
assert "post-merge" in lower or "post merge" in lower
|
||||
assert "parity" in lower and "stale" in lower
|
||||
# Sanctioned steps: stop, report, operator reload, re-verify.
|
||||
assert "stop" in lower
|
||||
assert "report" in lower
|
||||
assert "operator" in lower
|
||||
assert "parity is verified" in lower or "re-verif" in lower or (
|
||||
"startup/current-head" in lower
|
||||
)
|
||||
# Not a full promotion ledger for routine reload.
|
||||
assert "not a §2.4 promotion" in lower or "not a section 2.4 promotion" in lower or (
|
||||
"not a §2.4" in text or "Not a §2.4 promotion" in text
|
||||
)
|
||||
# Stale parity listed among unhealthy triggers.
|
||||
assert "master parity is stale" in lower or "stale master parity" in lower
|
||||
|
||||
|
||||
def test_f3_adr_forbids_llm_bypass_of_parity_gate():
|
||||
text = _read(ADR)
|
||||
lower = text.lower()
|
||||
assert "bypass" in lower or "self-reset" in lower or "self-service" in lower
|
||||
assert "parity" in lower
|
||||
|
||||
|
||||
def test_cross_links_do_not_embed_secrets_or_raw_hosts_in_wiki_snippets():
|
||||
for path in CROSS_LINK_DOCS:
|
||||
text = _read(path)
|
||||
for marker in ("ghp_", "BEGIN PRIVATE KEY", "Authorization: Bearer"):
|
||||
assert marker not in text, f"{path} contains {marker!r}"
|
||||
Reference in New Issue
Block a user