docs(review): 2026-06-11 repo audit — fix build-wave doc drift
/review-repo run at 67f2aba. Auto-fixed 5 safe doc-drift items left by the
base(firewall)+dev_env build wave: README/playbook/role notes that still called
the roles "empty/not built", plus README tree gaps and the reciprocal ADR-021
cross-links in ADR-016/020.
18 open findings reported (not fixed). Headline: `make lint` is red on `main`
(site.yml imports the non-existent docker_host role) and an ADR-004 <-> ADR-022
backup-scope contradiction. Deferral checklist clean (0 stale-deferred); 7 of
12 prior findings confirmed resolved. See docs/reviews/2026-06-11-review.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
67f2aba9d8
commit
1da117d65b
9 changed files with 384 additions and 79 deletions
|
|
@ -60,6 +60,8 @@ See `Makefile` for the full list of targets.
|
|||
│ ├── runbooks/ # Step-by-step operational procedures
|
||||
│ ├── security/ # Per-service security checklist + templates + accepted risks
|
||||
│ ├── testing/ # VERIFY.md template + service-UI verification reports
|
||||
│ ├── access/ # ACCESS.md template (ADR-021)
|
||||
│ ├── backup/ # BACKUP.md template (ADR-022)
|
||||
│ ├── hardware/ # Physical capacity reference + reviews
|
||||
│ └── reviews/ # /review-repo reports
|
||||
│
|
||||
|
|
@ -69,10 +71,12 @@ See `Makefile` for the full list of targets.
|
|||
│
|
||||
├── playbooks/ # Orchestration playbooks
|
||||
│ ├── site.yml # Full standard state
|
||||
│ ├── workstation.yml # Developer environment (control group)
|
||||
│ └── bootstrap.yml # First-run new host setup
|
||||
│
|
||||
├── roles/ # Ansible roles
|
||||
│ ├── base/ # OS baseline applied to all hosts
|
||||
│ ├── dev_env/ # Interactive developer environment
|
||||
│ └── docker_host/ # Docker runtime setup
|
||||
│
|
||||
├── terraform/ # VM provisioning only — no DNS (see ADR-006/009)
|
||||
|
|
|
|||
|
|
@ -107,7 +107,8 @@ Accepted (2026-06-05). Designed, not built — depends on the unbuilt `base` rol
|
|||
|
||||
See also: ADR-007 (network — amended), ADR-015 (control host), ADR-002 (security),
|
||||
ADR-011 (version pinning), ADR-004 (one service = one role), ADR-009 (TF↔Ansible
|
||||
handoff), ADR-013 (heritage — V4 ran WireGuard; NetBird is translated, not transplanted).
|
||||
handoff), ADR-013 (heritage — V4 ran WireGuard; NetBird is translated, not transplanted),
|
||||
ADR-021 (operational access; SSH ladder reconciling `wt0` + `ubongo`'s LAN address).
|
||||
|
||||
## Consequences
|
||||
|
||||
|
|
|
|||
|
|
@ -132,4 +132,5 @@ symbolic sources; each layer renders its own slice; the no-ad-hoc-ports guardrai
|
|||
|
||||
ADR-002 (security baseline: nftables default-deny, fail2ban, blast radius),
|
||||
ADR-004 (Docker model: `iptables:false`), ADR-007 (network topology, VLANs, OPNsense,
|
||||
per-VLAN egress), ADR-016 (NetBird mesh: SSH on `wt0` only), ADR-019 (`firewall` tag).
|
||||
per-VLAN egress), ADR-016 (NetBird mesh: SSH on `wt0` only), ADR-019 (`firewall` tag),
|
||||
ADR-021 (operational access doctrine; `ssh-from-control` management-plane source).
|
||||
|
|
|
|||
65
docs/reviews/2026-06-11-findings.json
Normal file
65
docs/reviews/2026-06-11-findings.json
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"date": "2026-06-11",
|
||||
"reviewed_commit": "67f2aba",
|
||||
"fixes_commit": null,
|
||||
"mode": "on-demand",
|
||||
"counts": {
|
||||
"auto_fixed": 5,
|
||||
"open": 18,
|
||||
"scan": {
|
||||
"broken-adr-ref": 4,
|
||||
"broken-path-ref": 1,
|
||||
"marker": 14,
|
||||
"open-deferred-item": 5,
|
||||
"stale-deferred": 0
|
||||
}
|
||||
},
|
||||
"deferral_checklist": {
|
||||
"adr-011-open-items": "all 5 (snapshot driver, cadences, health-check harness home, classification home, staging-first) confirmed genuinely still open; cross-checked against later ADRs + TODO 16. No stale-deferred.",
|
||||
"adr-015-deferred": "deferred #1 (mesh VPN) #2 (service-UI) #3 (build) all confirmed marked RESOLVED in place. No stale-deferred.",
|
||||
"stale_deferred_found": 0
|
||||
},
|
||||
"scan_false_positives": [
|
||||
{"check": "broken-path-ref", "location": "STATUS.md:38", "why": "STATUS legitimately documents roles/docker_host/ as 'Not in git.' — intentional reference to an unbuilt role."},
|
||||
{"check": "broken-adr-ref", "location": "tests/test_repo_scan.py:10,43; docs/superpowers/plans/2026-06-10-adr-structure.md:50,83", "why": "ADR-099/ADR-100 are intentional test fixtures exercising the scanner's bad-ref detection."},
|
||||
{"check": "marker", "location": "docs/superpowers/plans/*, docs/superpowers/specs/*, docs/decisions/019-tagging.md:14", "why": "All 14 markers are in historical planning artifacts (commit-message TODOs, plan steps) or prose discussing 'over-tagging' as a concept — not actionable cruft."}
|
||||
],
|
||||
"auto_fixed": [
|
||||
{"id": "AF1", "dimension": "drift", "severity": "high", "location": "roles/README.md:11-13", "description": "'base and docker_host not built yet — empty, untracked dirs, so site.yml would fail on a clean clone' contradicts STATUS.md: base is partially built (firewall concern, tracked), docker_host does not exist, dev_env is built+applied.", "fix": "rewrote Current-state paragraph: base partially built (firewall), docker_host not yet created, dev_env built+applied.", "tag": "new"},
|
||||
{"id": "AF2", "dimension": "drift", "severity": "medium", "location": "playbooks/site.yml:4-5", "description": "NOTE claimed base + docker_host 'not built yet ... fails on a clean clone'; base's firewall concern is built+applied per STATUS.md.", "fix": "NOTE now states base is partially built (firewall) and only docker_host is missing.", "tag": "new"},
|
||||
{"id": "AF3", "dimension": "drift", "severity": "medium", "location": "playbooks/README.md:6-8", "description": "site.yml described as 'currently a no-op' (roles empty); base's firewall now applies real nftables state. workstation.yml (applies dev_env) was unlisted.", "fix": "reworded the no-op claim and added a workstation.yml bullet.", "tag": "new"},
|
||||
{"id": "AF4", "dimension": "drift", "severity": "low", "location": "README.md:58-76", "description": "project-structure tree omitted docs/access/, docs/backup/, roles/dev_env/, and playbooks/workstation.yml — all present on disk.", "fix": "added the four missing tree entries.", "tag": "recurring"},
|
||||
{"id": "AF5", "dimension": "consistency", "severity": "low", "location": "docs/decisions/016-mesh-vpn.md:110; docs/decisions/020-firewall.md:135", "description": "ADR-021 states it amends ADR-016 and ADR-020 to cross-reference the SSH ladder, but neither listed ADR-021 back in its See-also/Related section.", "fix": "added the reciprocal ADR-021 cross-reference to both.", "tag": "new"}
|
||||
],
|
||||
"open": [
|
||||
{"id": "O1", "dimension": "conformance", "severity": "high", "location": "playbooks/site.yml:18", "description": "`make lint` is RED on `main`: site.yml imports the `docker_host` role which does not exist, so ansible-lint syntax-check fails on a clean checkout. Violates CLAUDE.md 'main must always work' and 'Never skip lint' (pre-commit would block every commit unless bypassed).", "suggested_fix": "Decide an interim posture: guard the docker_host play (e.g. skip until the role exists), stub the role via `make new-role NAME=docker_host`, or exclude site.yml from syntax-check until built — and record it. Judgement call.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O2", "dimension": "consistency", "severity": "high", "location": "docs/decisions/004-docker-model.md:105 ↔ docs/decisions/022-backup.md", "description": "ADR-004 'Persistent data' says 'Backup strategy is defined separately (not in scope of this repo).' ADR-022 defines a full in-repo backup strategy (backup role, fisi pull node, per-service backup__* + BACKUP.md). Direct ADR↔ADR contradiction on scope.", "suggested_fix": "Update ADR-004's line to point at ADR-022 (backup is now in-repo scope) and cross-link, per ADR-023's no-silent-reversal rule. Design decision — report only.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O3", "dimension": "consistency", "severity": "medium", "location": "docs/decisions/004-docker-model.md:48-49", "description": "ADR-004's service-role file table (the canonical standard) lists only SECURITY.md + VERIFY.md, but CLAUDE.md + ADR-021/ADR-022 now mandate ACCESS.md (every service role) and BACKUP.md (stateful service roles).", "suggested_fix": "Add ACCESS.md (ADR-021) and BACKUP.md (ADR-022) rows to ADR-004's service-role file table. (Prior O1 'missing VERIFY.md' is now resolved — this is the next evolution.)", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O4", "dimension": "consistency", "severity": "medium", "location": "docs/CAPABILITIES.md:149-154 ↔ STATUS.md:29", "description": "CAPABILITIES lists nvim/tmux/shell config as a CONFIRMED EXCLUSION ('boma is server-only, so these are correctly absent'), but the dev_env role (built+applied to ubongo) installs exactly zsh+oh-my-zsh+tmux+neovim.", "suggested_fix": "Carve out an exception for the control-node developer/AI-worker environment (ubongo, ADR-015) rather than flatly excluding nvim/tmux; distinguish infra worker-host config from personal desktops.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O5", "dimension": "drift", "severity": "medium", "location": "docs/decisions/002-security.md:82", "description": "References `make deploy PLAYBOOK=upgrade` as the deliberate full-upgrade mechanism, but no upgrade.yml playbook exists (only bootstrap/site/workstation) and ADR-011 update-management is still Proposed/unbuilt — stated without the '(planned)' caveat ADR-002 uses for its other unbuilt controls.", "suggested_fix": "Add a '(planned — ADR-011, not yet built)' caveat to the upgrade line.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O6", "dimension": "drift", "severity": "medium", "location": "inventories/production/hosts.yml:7-16; inventories/staging/hosts.yml:7-14", "description": "Committed hosts.yml stubs omit the offsite_hosts group, but it is one of the four VALID_GROUPS in tf_to_inventory.py and in ADR-009/ADR-016/CLAUDE.md; the next `make tf-inventory` would add it, so the hand-stubs have drifted. (Prior O4 'askari group unnamed' is resolved — naming is now consistent; this is the residual stub gap.)", "suggested_fix": "Regenerate via `make tf-inventory TF_ENV=production` and `TF_ENV=staging` (do NOT hand-edit hosts.yml — CLAUDE.md), or accept the stubs lag until TF runs.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O7", "dimension": "drift", "severity": "medium", "location": "docs/runbooks/new-host.md:81-130", "description": "Part E (control node ubongo) instructs creating an 'ansible' user and 'ssh ansible@<IP>', but STATUS.md records ubongo is deliberately managed as the operator account sjat (group_vars/control ansible_user: sjat) with the ansible-user bootstrap listed as Pending.", "suggested_fix": "Update Part E to reflect ubongo managed as sjat (no ansible user yet), ansible-user bootstrap a pending item per STATUS.md.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O8", "dimension": "conformance", "severity": "medium", "location": "roles/dev_env/tasks/per_user.yml:2-9", "description": "The getent + `set_fact: dev_env__home` preflight is untagged, but downstream tasks that consume dev_env__home carry concern tags (users, config). A partial `--tags users` or `--tags config` run skips the set_fact, leaving dev_env__home undefined and failing the tagged tasks — against ADR-019's concern-runnable-in-isolation intent.", "suggested_fix": "Tag the preflight with the union of dependent concerns ([users, config]) or `always`.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O9", "dimension": "consistency", "severity": "medium", "location": "STATUS.md:31 ↔ docs/decisions/007-network.md", "description": "STATUS places ubongo at 10.20.10.151; ADR-007 defines srv as 10.20.0.0/24 and mgmt as 10.10.0.0/24 — 10.20.10.151 is in neither. base__firewall_control_addr (ADR-021 recovery path) depends on this address being correct. Already a tracked follow-up in the ubongo-build plan (line 147).", "suggested_fix": "Either correct ubongo's recorded address to a valid ADR-007 subnet, or amend ADR-007 to document the actual VLAN/subnet ubongo's physical port lives on, before base__firewall_control_addr is populated.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O10", "dimension": "drift", "severity": "low", "location": "README.md:104-106", "description": "README's Documentation ADR list stops at 017; ADRs 018 (logging), 019 (tagging), 020 (firewall), 021 (access), 022 (backup), 023 (ADR structure) exist and are in CLAUDE.md's full table. Partial enumeration is now stale. (Evolved from prior O3, which is otherwise resolved — the docs/ tree omissions were fixed in AF4.)", "suggested_fix": "Extend the list through 023, or trim it to a pointer at CLAUDE.md's full table to avoid a stale partial list.", "tag": "recurring", "auto_fixable": false},
|
||||
{"id": "O11", "dimension": "conformance", "severity": "low", "location": "docs/decisions/008-testing.md:3; 014-knowledge-sourcing.md:98; 016-mesh-vpn.md:91; 017-service-ui-verification.md:66; 018-logging.md:73", "description": "ADR-023 §2 mandates section order Status→Context→Decision→Consequences. ADR-008 injects a gotchas blockquote before ## Status; ADR-014's ## Decision is a late summary after six topical sections; ADR-016/017/018 place ## Status mid-document. The scan checks presence, not order, so all pass lint — but they don't match the stated standard.", "suggested_fix": "Presentational restructure per ADR-023 §6 (move Status first; pull Decision up). No decision substance changes. Judgement call — report.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O12", "dimension": "consistency", "severity": "low", "location": "docs/decisions/007-network.md:160", "description": "The naming-scheme table states the public FQDN convention is `<service>.baobab.band`, but its own example is `forgejo.nyumbani.baobab.band` (extra nyumbani label). The nyumbani split-horizon sub-label is still OPEN (TODO 4); convention and example disagree.", "suggested_fix": "Change the example to forgejo.baobab.band, or note nyumbani is an unresolved split-horizon sub-label (TODO 4). Ties to an open decision — report.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O13", "dimension": "consistency", "severity": "low", "location": "roles/dev_env/files/dotfiles/zsh/.zshrc:28,55", "description": "Shipped .zshrc hard-codes `alias rclone=\"/usr/bin/rclone\"` (rclone is not installed by dev_env) and `eval \"$(direnv hook zsh)\"` unguarded (unlike the guarded oh-my-posh block) — heritage fisi/V4 carryovers. If direnv is dropped from dev_env__packages every shell startup errors.", "suggested_fix": "Drop the rclone alias (role doesn't install it) and guard the direnv hook with `command -v direnv`, or document direnv as a hard dependency of the shipped .zshrc.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O14", "dimension": "consistency", "severity": "low", "location": "roles/dev_env/tasks/oh_my_posh.yml:15-26", "description": "The zen.toml theme-directory + deploy tasks render config to disk but carry no `config` tag, while analogous dotfile tasks in per_user.yml are tagged `config` — inconsistent concern tagging within the role.", "suggested_fix": "Add tags: [config] to the zen.toml directory + deploy tasks.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O15", "dimension": "consistency", "severity": "low", "location": "terraform/environments/production/terraform.tfvars.example:9-11; staging/terraform.tfvars.example", "description": "proxmox_node/endpoint examples use pve01 / pve01.baobab.band, but ADR-007 defines Proxmox node names as pve0/pve1/pve2 (single digit, no leading zero). Example contradicts the naming convention.", "suggested_fix": "Change example values to pve0 / pve0.baobab.band (both envs). Verify the actual node name first — report rather than auto-fix.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O16", "dimension": "consistency", "severity": "low", "location": "docs/decisions/013-heritage-v4.md:77; docs/decisions/015-control-host.md", "description": "ADR-013 and ADR-015 close with an inline 'See also:' prose line, whereas ADRs 014/019/020/021/022 and the adr-template use a dedicated `## Related` section. Stylistic inconsistency (## Related is optional per ADR-023 §3).", "suggested_fix": "Convert the 'See also:' prose in ADR-013/015 into ## Related sections for uniformity. Cosmetic.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O17", "dimension": "cruft", "severity": "low", "location": "roles/dev_env/handlers/main.yml; roles/base/handlers/main.yml", "description": "Both roles ship an empty handlers/main.yml (only `---`); neither defines or uses handlers (base's firewall apply/rollback is deliberately in tasks). Scaffold artifacts from make new-role.", "suggested_fix": "Confirm whether empty scaffold files are an intentional convention; if not, delete. Low priority.", "tag": "new", "auto_fixable": false},
|
||||
{"id": "O18", "dimension": "consistency", "severity": "low", "location": "docs/README.md:5-8; inventories/README.md:1-12", "description": "docs/README.md lists only decisions/ + runbooks/ (omits security/testing/access/backup/hardware/reviews/superpowers); inventories/README.md omits the offsite_hosts group documented in CLAUDE.md. Both are narrower than current reality.", "suggested_fix": "Add the missing subdir rows / note offsite_hosts, or explicitly defer to the canonical list. Low priority.", "tag": "new", "auto_fixable": false}
|
||||
],
|
||||
"prior_resolved": [
|
||||
{"id": "O1@2026-06-05", "description": "ADR-004 service-role table missing VERIFY.md row", "status": "resolved — table now lists SECURITY.md + VERIFY.md (next gap ACCESS/BACKUP tracked as O3)"},
|
||||
{"id": "O2@2026-06-05", "description": "new-role runbook missing VERIFY.md step", "status": "resolved — step 10 present"},
|
||||
{"id": "O3@2026-06-05", "description": "README ADR list + docs/ tree omissions", "status": "partial — docs tree security/testing/hardware now present; access/backup fixed in AF4; ADR-list staleness carried as O10"},
|
||||
{"id": "O4@2026-06-05", "description": "askari inventory group unnamed", "status": "resolved — offsite_hosts named consistently (residual stub gap = O6)"},
|
||||
{"id": "O5@2026-06-05", "description": "backend.tf mislabelled Forgejo state backend", "status": "resolved — now labelled local state"},
|
||||
{"id": "O6@2026-06-05", "description": "ADR-014 plugin reproducibility described open but TODO done", "status": "resolved"},
|
||||
{"id": "O11@2026-06-05", "description": "CAPABILITIES missing /verify-service Level-4 row", "status": "resolved — present (§10)"},
|
||||
{"id": "O12@2026-06-05", "description": "TODO 3.10 garbled", "status": "resolved — readable"},
|
||||
{"id": "O7-O10@2026-06-05", "description": "ADR-011 digest-pinning row; act_runner ambiguity; WireGuard Molecule row; ADR-011 scheduled_jobs cross-ref", "status": "not re-detected this run (ADR-011 still Proposed) — verify on next run"}
|
||||
]
|
||||
}
|
||||
161
docs/reviews/2026-06-11-review.md
Normal file
161
docs/reviews/2026-06-11-review.md
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# Repo review — 2026-06-11
|
||||
|
||||
- **Reviewed commit:** `67f2aba` (main)
|
||||
- **Mode:** on-demand (interactive)
|
||||
- **Previous run:** `2026-06-05` (commit `f566fd1`)
|
||||
- **Process:** Phase 0 deterministic scan → 5 parallel shard reviewers + 1 cross-cutting
|
||||
reviewer → synthesis, deferral-checklist resolution, prior-run diff → safe auto-fixes.
|
||||
|
||||
## Summary
|
||||
|
||||
| | High | Medium | Low | Total |
|
||||
|---|---|---|---|---|
|
||||
| **Auto-fixed** | 1 | 2 | 2 | 5 |
|
||||
| **Open (report-only)** | 2 | 7 | 9 | 18 |
|
||||
|
||||
By dimension (open): conformance 3 · consistency 8 · drift 6 · cruft 1.
|
||||
|
||||
**Headline:** `make lint` is currently **red on `main`** — `playbooks/site.yml` imports the
|
||||
not-yet-existent `docker_host` role (confirmed at clean HEAD, unrelated to this run's
|
||||
edits). That breaks CLAUDE.md's "main must always work" / "Never skip lint" contract and
|
||||
is the top open finding (O1). The bulk of the rest is documentation drift created by the
|
||||
recent `base` (firewall) + `dev_env` build wave: several READMEs/playbook notes still
|
||||
described the roles as "empty / not built." Those were the safe auto-fixes.
|
||||
|
||||
**Good news:** 7 of the 12 open findings from the 2026-06-05 run are confirmed resolved
|
||||
(VERIFY.md row + runbook step, backend.tf relabel, askari group naming, ADR-014
|
||||
reproducibility, CAPABILITIES Level-4 row, TODO 3.10). The deferral checklist is clean —
|
||||
**0 stale-deferred** this run (the recurring miss logged in FRICTION.md did not recur).
|
||||
|
||||
## Auto-fixes applied
|
||||
|
||||
Markdown / YAML-comment only; no runtime behaviour, logic, vars, or task order touched.
|
||||
|
||||
| ID | Sev | File(s) | What |
|
||||
|---|---|---|---|
|
||||
| AF1 | high | `roles/README.md` | Rewrote stale "base & docker_host are empty untracked dirs, site.yml would fail on a clean clone" → base partially built (firewall), docker_host not yet created, dev_env built+applied. |
|
||||
| AF2 | med | `playbooks/site.yml` | NOTE no longer claims base is unbuilt / "fails on a clean clone"; now reflects firewall-only base + missing docker_host. |
|
||||
| AF3 | med | `playbooks/README.md` | Dropped the "currently a no-op" claim; added a `workstation.yml` bullet. |
|
||||
| AF4 | low | `README.md` | Added `docs/access/`, `docs/backup/`, `roles/dev_env/`, `playbooks/workstation.yml` to the project-structure tree. |
|
||||
| AF5 | low | `docs/decisions/016-mesh-vpn.md`, `docs/decisions/020-firewall.md` | Added the reciprocal `ADR-021` cross-reference that ADR-021 says it amended in. |
|
||||
|
||||
> `make lint` was re-run after the fixes: it fails **only** on the pre-existing
|
||||
> `docker_host` syntax-check (O1), identical to clean HEAD. No auto-fix introduced or
|
||||
> changed any lint result, so none were reverted.
|
||||
|
||||
## Open findings (prioritised)
|
||||
|
||||
### High
|
||||
|
||||
- **O1 — `make lint` is red on `main`** · `playbooks/site.yml:18` · *conformance*
|
||||
site.yml imports the `docker_host` role, which does not exist, so ansible-lint's
|
||||
syntax-check fails on a clean checkout. Violates "main must always work" + "Never skip
|
||||
lint" (pre-commit would block every commit unless bypassed).
|
||||
*Fix (judgement):* guard/skip the docker_host play until the role exists, scaffold a
|
||||
stub via `make new-role NAME=docker_host`, or exclude site.yml from syntax-check until
|
||||
built — and record the choice. **new**
|
||||
|
||||
- **O2 — ADR-004 ↔ ADR-022 backup-scope contradiction** ·
|
||||
`docs/decisions/004-docker-model.md:105` · *consistency*
|
||||
ADR-004 says "Backup strategy is defined separately (not in scope of this repo)";
|
||||
ADR-022 defines a full in-repo backup strategy. Per ADR-023 (no silent reversals),
|
||||
update ADR-004's line to defer to ADR-022 and cross-link. Design decision — report. **new**
|
||||
|
||||
### Medium
|
||||
|
||||
- **O3 — ADR-004 service-role file table missing ACCESS.md + BACKUP.md** ·
|
||||
`docs/decisions/004-docker-model.md:48` · *consistency* — CLAUDE.md + ADR-021/022 now
|
||||
mandate both for service roles; the canonical table lists only SECURITY.md + VERIFY.md.
|
||||
(Prior "missing VERIFY.md" is resolved; this is the next evolution.) **new**
|
||||
- **O4 — CAPABILITIES nvim/tmux exclusion ↔ dev_env built** ·
|
||||
`docs/CAPABILITIES.md:149` · *consistency* — listed as a confirmed exclusion
|
||||
("server-only"), but `dev_env` (built+applied to ubongo) installs exactly that. Carve
|
||||
out the control-node/AI-worker exception (ADR-015). **new**
|
||||
- **O5 — phantom `make deploy PLAYBOOK=upgrade`** · `docs/decisions/002-security.md:82` ·
|
||||
*drift* — no `upgrade.yml` exists; ADR-011 is unbuilt. Add a "(planned)" caveat. **new**
|
||||
- **O6 — hosts.yml stubs missing `offsite_hosts` group** ·
|
||||
`inventories/{production,staging}/hosts.yml` · *drift* — the generator emits it (one of
|
||||
four VALID_GROUPS); the hand-stubs predate the standard. Regenerate via
|
||||
`make tf-inventory` (don't hand-edit). (Prior "askari group unnamed" is resolved.) **new**
|
||||
- **O7 — new-host runbook Part E vs ubongo reality** · `docs/runbooks/new-host.md:81-130`
|
||||
· *drift* — instructs creating an `ansible` user / `ssh ansible@`; STATUS records ubongo
|
||||
is managed as `sjat`, ansible-user bootstrap pending. **new**
|
||||
- **O8 — dev_env untagged `set_fact` under tagged consumers** ·
|
||||
`roles/dev_env/tasks/per_user.yml:2-9` · *conformance* — partial `--tags users|config`
|
||||
runs skip the `dev_env__home` set_fact and fail. Tag the preflight `[users, config]` or
|
||||
`always`. **new**
|
||||
- **O9 — ubongo address outside ADR-007 subnets** · `STATUS.md:31 ↔ 007-network.md` ·
|
||||
*drift* — 10.20.10.151 is in neither srv (10.20.0.0/24) nor mgmt (10.10.0.0/24);
|
||||
`base__firewall_control_addr` depends on it. Already a tracked follow-up in the
|
||||
ubongo-build plan. Reconcile address or ADR-007. **new**
|
||||
|
||||
### Low
|
||||
|
||||
- **O10 — README ADR list stops at 017** · `README.md:104` · *drift* — 018–023 exist;
|
||||
extend or trim to a pointer. **recurring** (evolved from prior O3)
|
||||
- **O11 — ADR section-order vs ADR-023 §2** · `008:3, 014:98, 016:91, 017:66, 018:73` ·
|
||||
*conformance* — Status-not-first / Decision-late; passes lint (order not gated) but not
|
||||
the standard. Presentational restructure. **new**
|
||||
- **O12 — ADR-007 FQDN convention vs its own example** · `007-network.md:160` ·
|
||||
*consistency* — `<service>.baobab.band` vs `forgejo.nyumbani.baobab.band`; ties to open
|
||||
TODO 4 (split-horizon). **new**
|
||||
- **O13 — dev_env `.zshrc` heritage carryovers** ·
|
||||
`roles/dev_env/files/dotfiles/zsh/.zshrc:28,55` · *consistency* — hard-coded
|
||||
`/usr/bin/rclone` alias (not installed by the role) + unguarded `direnv` hook. **new**
|
||||
- **O14 — oh_my_posh config tasks untagged** · `roles/dev_env/tasks/oh_my_posh.yml:15-26`
|
||||
· *consistency* — inconsistent `config` tagging vs per_user.yml. **new**
|
||||
- **O15 — tfvars.example `pve01` vs ADR-007 `pve0`** ·
|
||||
`terraform/environments/*/terraform.tfvars.example:9` · *consistency* — verify the real
|
||||
node name, then align. **new**
|
||||
- **O16 — ADR-013/015 "See also:" vs `## Related`** · *consistency* — stylistic; convert
|
||||
for uniformity. **new**
|
||||
- **O17 — empty scaffold `handlers/main.yml`** · `roles/{dev_env,base}/handlers/main.yml`
|
||||
· *cruft* — confirm convention or delete. **new**
|
||||
- **O18 — docs/README.md + inventories/README.md narrower than reality** · *consistency*
|
||||
— omit several real subdirs / the offsite_hosts group. **new**
|
||||
|
||||
## Deferral checklist (Phase 2)
|
||||
|
||||
| Source | Items | Verdict |
|
||||
|---|---|---|
|
||||
| ADR-011 Deferred/Open | 5 (snapshot driver, cadences, health-check harness home, classification home, staging-first) | **All genuinely still open** — cross-checked against later ADRs + TODO 16. None silently resolved. |
|
||||
| ADR-015 Deferred | #1 mesh VPN, #2 service-UI, #3 build | **All marked RESOLVED in place** (ADR-016 / ADR-017 / 2026-06-11 build). |
|
||||
|
||||
**Stale-deferred found: 0.** The recurring FRICTION.md miss did not recur this run.
|
||||
|
||||
## Scan false positives (folded in, not actionable)
|
||||
|
||||
- `broken-path-ref STATUS.md:38` — STATUS legitimately documents `roles/docker_host/` as
|
||||
"Not in git." (intentional reference to an unbuilt role).
|
||||
- `broken-adr-ref` ×4 — `ADR-099`/`ADR-100` in `tests/test_repo_scan.py` and the
|
||||
adr-structure plan are intentional **test fixtures** for the scanner's bad-ref check.
|
||||
- `marker` ×14 — all in `docs/superpowers/{plans,specs}/*` (historical commit-message
|
||||
TODOs / plan steps) or prose discussing "over-tagging" as a concept. Not cruft.
|
||||
|
||||
## Prior-run diff (vs 2026-06-05)
|
||||
|
||||
**Resolved (7):** O1 VERIFY.md row · O2 new-role VERIFY step · O4 askari group naming ·
|
||||
O5 backend.tf relabel · O6 ADR-014 reproducibility · O11 CAPABILITIES Level-4 row ·
|
||||
O12 TODO 3.10. **Partial:** O3 (docs tree fixed in AF4; ADR-list carried as O10).
|
||||
**Not re-detected (verify next run):** O7–O10 (ADR-011 still Proposed).
|
||||
|
||||
## Follow-up prompt (copy-paste)
|
||||
|
||||
> Act on the open findings from `docs/reviews/2026-06-11-review.md`. Priority order:
|
||||
> 1. **O1 (high):** `make lint` is red on `main` — `playbooks/site.yml` imports the
|
||||
> non-existent `docker_host` role. Pick an interim posture (guard/skip the play, or
|
||||
> `make new-role NAME=docker_host` to scaffold a stub, or exclude from syntax-check
|
||||
> until built) so the trunk lints clean again, and record the choice in STATUS.md.
|
||||
> 2. **O2 (high):** Resolve the ADR-004 ↔ ADR-022 backup-scope contradiction —
|
||||
> update ADR-004's "not in scope of this repo" line to defer to ADR-022 (per ADR-023's
|
||||
> no-silent-reversal rule) and cross-link.
|
||||
> 3. **O3:** Add ACCESS.md + BACKUP.md rows to ADR-004's service-role file table.
|
||||
> 4. **O4:** Reconcile CAPABILITIES' nvim/tmux exclusion with the built `dev_env` role
|
||||
> (carve out the ubongo control-node exception).
|
||||
> 5. **O8 (conformance):** Tag the `dev_env__home` preflight `set_fact` so partial
|
||||
> `--tags users|config` runs don't fail.
|
||||
> 6. **O6 / O9:** Regenerate the inventory stubs to include `offsite_hosts`; reconcile
|
||||
> ubongo's 10.20.10.151 against ADR-007's subnets (or amend ADR-007).
|
||||
> 7. Sweep the low-severity doc items (O5 caveat, O7 runbook, O10 ADR list, O11 ADR
|
||||
> section order, O12–O18) as a single docs-hygiene batch.
|
||||
> Run `make lint` before committing; commit per CLAUDE.md git conventions.
|
||||
|
|
@ -1,93 +1,161 @@
|
|||
# Repo review — 2026-06-05
|
||||
# Repo review — 2026-06-11
|
||||
|
||||
- **Reviewed commit:** `f566fd1` (scan); auto-fixes landed in `666ad42`
|
||||
- **Reviewed commit:** `67f2aba` (main)
|
||||
- **Mode:** on-demand (interactive)
|
||||
- **Scope:** whole repo — 2 roles, 17 ADRs, 4 runbooks, 7 scripts; doc-heavy
|
||||
- **Prior run:** 2026-05-30 (`de38d1c`) — 7 auto-fixed, 17 open
|
||||
- **Previous run:** `2026-06-05` (commit `f566fd1`)
|
||||
- **Process:** Phase 0 deterministic scan → 5 parallel shard reviewers + 1 cross-cutting
|
||||
reviewer → synthesis, deferral-checklist resolution, prior-run diff → safe auto-fixes.
|
||||
|
||||
## Summary
|
||||
|
||||
| | high | medium | low | total |
|
||||
| | High | Medium | Low | Total |
|
||||
|---|---|---|---|---|
|
||||
| Auto-fixed | 2 | 0 | 2 | 4 |
|
||||
| Open (report-only) | 0 | 5 | 7 | 12 |
|
||||
| **Auto-fixed** | 1 | 2 | 2 | 5 |
|
||||
| **Open (report-only)** | 2 | 7 | 9 | 18 |
|
||||
|
||||
This review followed a session of heavy documentation work (ADR-015 `ubongo`,
|
||||
ADR-016 NetBird mesh, ADR-017 Level-4 verification). Most findings are **propagation
|
||||
gaps** — a new decision landed but an older doc still reflects the prior design.
|
||||
By dimension (open): conformance 3 · consistency 8 · drift 6 · cruft 1.
|
||||
|
||||
**New deferral check exercised.** `repo-scan.py` now enumerates open ADR "Deferred/
|
||||
Open" items and flags any another file calls resolved-but-unmarked. This run: 6
|
||||
open-deferred-items surfaced, **all confirmed genuinely open** by the cross-cutting
|
||||
reviewer (ADR-011 #1–5, ADR-015 #3), **0 stale-deferred**. The check produced no false
|
||||
resolutions and the judgement layer agreed — working as designed.
|
||||
**Headline:** `make lint` is currently **red on `main`** — `playbooks/site.yml` imports the
|
||||
not-yet-existent `docker_host` role (confirmed at clean HEAD, unrelated to this run's
|
||||
edits). That breaks CLAUDE.md's "main must always work" / "Never skip lint" contract and
|
||||
is the top open finding (O1). The bulk of the rest is documentation drift created by the
|
||||
recent `base` (firewall) + `dev_env` build wave: several READMEs/playbook notes still
|
||||
described the roles as "empty / not built." Those were the safe auto-fixes.
|
||||
|
||||
## Auto-fixes applied (`666ad42`)
|
||||
**Good news:** 7 of the 12 open findings from the 2026-06-05 run are confirmed resolved
|
||||
(VERIFY.md row + runbook step, backend.tf relabel, askari group naming, ADR-014
|
||||
reproducibility, CAPABILITIES Level-4 row, TODO 3.10). The deferral checklist is clean —
|
||||
**0 stale-deferred** this run (the recurring miss logged in FRICTION.md did not recur).
|
||||
|
||||
| id | dim | sev | location | fix |
|
||||
|---|---|---|---|---|
|
||||
| AF1 | consistency | high | `docs/decisions/005-bootstrapping.md:36`, `docs/runbooks/new-host.md:62,71` | Removed "Terraform writes the host's DNS A record" — contradicts ADR-009 (the `dns` role owns the zone). **Recurring**: the 2026-05-30 run fixed the same contradiction in README/ADR-003; it reappeared in two more files. |
|
||||
| AF2 | consistency | high | `docs/decisions/005-bootstrapping.md:8` | Control node described as cloned from the cloud-init template; ADR-015 makes `ubongo` a physical box installed directly. Corrected. |
|
||||
| AF3 | consistency | low | `CLAUDE.md:197` | Added the missing `docs/testing/service-verify-template.md` row to Further reading (parallels the security-template row). |
|
||||
| AF4 | cruft | low | `docs/TODO.md:79` | Typos: "we we" → "we"; "seperate" → "separate". |
|
||||
## Auto-fixes applied
|
||||
|
||||
## Open findings (report-only)
|
||||
Markdown / YAML-comment only; no runtime behaviour, logic, vars, or task order touched.
|
||||
|
||||
### VERIFY.md propagation cluster (ADR-017 not fully threaded through)
|
||||
| ID | Sev | File(s) | What |
|
||||
|---|---|---|---|
|
||||
| AF1 | high | `roles/README.md` | Rewrote stale "base & docker_host are empty untracked dirs, site.yml would fail on a clean clone" → base partially built (firewall), docker_host not yet created, dev_env built+applied. |
|
||||
| AF2 | med | `playbooks/site.yml` | NOTE no longer claims base is unbuilt / "fails on a clean clone"; now reflects firewall-only base + missing docker_host. |
|
||||
| AF3 | med | `playbooks/README.md` | Dropped the "currently a no-op" claim; added a `workstation.yml` bullet. |
|
||||
| AF4 | low | `README.md` | Added `docs/access/`, `docs/backup/`, `roles/dev_env/`, `playbooks/workstation.yml` to the project-structure tree. |
|
||||
| AF5 | low | `docs/decisions/016-mesh-vpn.md`, `docs/decisions/020-firewall.md` | Added the reciprocal `ADR-021` cross-reference that ADR-021 says it amended in. |
|
||||
|
||||
| id | sev | location | finding | suggested fix |
|
||||
|---|---|---|---|---|
|
||||
| O1 | medium | `docs/decisions/004-docker-model.md` (file table) | The service-role standard lists `SECURITY.md` but not `VERIFY.md`, though ADR-017 + CLAUDE.md:85 now mandate it. | Add a `VERIFY.md` row to ADR-004's file table. |
|
||||
| O2 | medium | `docs/runbooks/new-role.md` (step 9 → Commit) | No step to write `VERIFY.md` for service roles (only `SECURITY.md`). Makes `STATUS.md:17` ("runbooks current and mutually reconciled") slightly overstated. | Add a "write the per-service verification spec" step mirroring the SECURITY.md step. |
|
||||
| O3 | low | `README.md:58-60, 94` | ADR list stops at 001–009 (010–017 absent); the `docs/` tree omits `security/`, `testing/`, `hardware/`. | Extend the ADR list (or point to `docs/decisions/` + CLAUDE.md's table); expand the `docs/` subtree. |
|
||||
> `make lint` was re-run after the fixes: it fails **only** on the pre-existing
|
||||
> `docker_host` syntax-check (O1), identical to clean HEAD. No auto-fix introduced or
|
||||
> changed any lint result, so none were reverted.
|
||||
|
||||
### Design gaps from the recent ADRs
|
||||
## Open findings (prioritised)
|
||||
|
||||
| id | sev | location | finding | suggested fix |
|
||||
|---|---|---|---|---|
|
||||
| O4 | medium | `CLAUDE.md:106`, `docs/decisions/009-provisioning-handoff.md:78`, `scripts/tf_to_inventory.py:24` | ADR-016 says "`askari` is Ansible-managed — its own inventory group", but no group is named anywhere; host-groups list + valid-groups set don't include it. | Decide the group name (e.g. `edge_hosts`/`hetzner_hosts`), add to CLAUDE.md host groups + ADR-009 valid groups. (`askari` is manual like the control node, so `tf_to_inventory.py` need not generate it, but the group must be valid.) |
|
||||
| O5 | medium | `docs/decisions/006-terraform.md:78` | `backend.tf` labelled "Forgejo state backend", contradicting ADR-006's own State-backend section (local state on `ubongo`; Forgejo's API is read-only). | Relabel to "local state backend (no remote backend)". |
|
||||
| O6 | medium | `docs/decisions/014-knowledge-sourcing.md:88` | Plugin-reproducibility described as open ("tracked in `docs/TODO.md`"), but TODO 10.7 is marked DONE (settings.json declares the plugin set; claude-code-setup.md covers bootstrap). | Update to reflect the resolved state; drop the forward-pointer. |
|
||||
### High
|
||||
|
||||
### Clarity / lower-priority consistency
|
||||
- **O1 — `make lint` is red on `main`** · `playbooks/site.yml:18` · *conformance*
|
||||
site.yml imports the `docker_host` role, which does not exist, so ansible-lint's
|
||||
syntax-check fails on a clean checkout. Violates "main must always work" + "Never skip
|
||||
lint" (pre-commit would block every commit unless bypassed).
|
||||
*Fix (judgement):* guard/skip the docker_host play until the role exists, scaffold a
|
||||
stub via `make new-role NAME=docker_host`, or exclude site.yml from syntax-check until
|
||||
built — and record the choice. **new**
|
||||
|
||||
| id | sev | location | finding | suggested fix |
|
||||
|---|---|---|---|---|
|
||||
| O7 | low | `docs/decisions/011-update-management.md:128` | "Digest-pinning the stateful tier" sits in the ruled-out table, but Decision #2 *adopts* `tag@digest` for stateful (TODO 16 confirms). ADR-011 is still **Proposed/draft**. | Remove/replace the ruled-out row when accepting ADR-011 (TODO 16). |
|
||||
| O8 | low | `docs/decisions/003-toolchain.md:85`, `docs/decisions/010-forgejo-ci.md:66` | "act_runner on the control node **or a dedicated runner VM**" reads ambiguously against ADR-015 (no cluster control VM). Not wrong (a runner VM is a separate option) but worth disambiguating. | Name `ubongo` as the runner host; cross-ref ADR-015; keep "dedicated runner VM" as an explicit future option. |
|
||||
| O9 | low | `docs/decisions/008-testing.md:148` | The "WireGuard tunnel establishment" Molecule-exclusion row is framed for the retired OPNsense VLAN-99 WireGuard; NetBird still uses WireGuard (`wt0`) as its data plane. | Reframe the row to the NetBird `wt0` data-plane (ADR-016). |
|
||||
| O10 | low | `docs/decisions/011-update-management.md:67` | Cross-references "the `scheduled_jobs` plan and ADR-010"; ADR-010 is Forgejo CI, not scheduled jobs (that's TODO 8.3, unbuilt). | Point to TODO 8.3 instead. |
|
||||
| O11 | low | `docs/CAPABILITIES.md` §10 | No row for the `/verify-service` (Level 4) capability though ADR-017 decided it. | Add an Operations row for `/verify-service`. |
|
||||
| O12 | low | `docs/TODO.md:30` (item 3.10) | Garbled text ("maybe something in the improvements of the methods in boma moods the point?") — unfollowable. | Rewrite the question clearly or strike it. |
|
||||
- **O2 — ADR-004 ↔ ADR-022 backup-scope contradiction** ·
|
||||
`docs/decisions/004-docker-model.md:105` · *consistency*
|
||||
ADR-004 says "Backup strategy is defined separately (not in scope of this repo)";
|
||||
ADR-022 defines a full in-repo backup strategy. Per ADR-023 (no silent reversals),
|
||||
update ADR-004's line to defer to ADR-022 and cross-link. Design decision — report. **new**
|
||||
|
||||
### Deterministic-scan noise (not fixed — known limitations)
|
||||
### Medium
|
||||
|
||||
- **`broken-path-ref` ×14** — all illustrative/future paths: report-name templates
|
||||
(`docs/testing/reviews/YYYY-MM-DD-<service>.md`) and `latest.md` files not yet
|
||||
created. The path-ref check stops at the `<placeholder>` boundary, so a templated
|
||||
path registers as a partial broken ref. *Potential scanner improvement: skip a path
|
||||
ref immediately followed by a placeholder char or a `YYYY-MM-DD` token.*
|
||||
- **`marker` ×35** — mostly prose references to `TODO.md` items, not code markers.
|
||||
Known noise; the regex already excludes `TODO.md`/alternations but not "TODO 8.2"
|
||||
prose.
|
||||
- **`open-deferred-item` ×6** — all confirmed genuinely open (see above). `0`
|
||||
stale-deferred. New check healthy.
|
||||
- **O3 — ADR-004 service-role file table missing ACCESS.md + BACKUP.md** ·
|
||||
`docs/decisions/004-docker-model.md:48` · *consistency* — CLAUDE.md + ADR-021/022 now
|
||||
mandate both for service roles; the canonical table lists only SECURITY.md + VERIFY.md.
|
||||
(Prior "missing VERIFY.md" is resolved; this is the next evolution.) **new**
|
||||
- **O4 — CAPABILITIES nvim/tmux exclusion ↔ dev_env built** ·
|
||||
`docs/CAPABILITIES.md:149` · *consistency* — listed as a confirmed exclusion
|
||||
("server-only"), but `dev_env` (built+applied to ubongo) installs exactly that. Carve
|
||||
out the control-node/AI-worker exception (ADR-015). **new**
|
||||
- **O5 — phantom `make deploy PLAYBOOK=upgrade`** · `docs/decisions/002-security.md:82` ·
|
||||
*drift* — no `upgrade.yml` exists; ADR-011 is unbuilt. Add a "(planned)" caveat. **new**
|
||||
- **O6 — hosts.yml stubs missing `offsite_hosts` group** ·
|
||||
`inventories/{production,staging}/hosts.yml` · *drift* — the generator emits it (one of
|
||||
four VALID_GROUPS); the hand-stubs predate the standard. Regenerate via
|
||||
`make tf-inventory` (don't hand-edit). (Prior "askari group unnamed" is resolved.) **new**
|
||||
- **O7 — new-host runbook Part E vs ubongo reality** · `docs/runbooks/new-host.md:81-130`
|
||||
· *drift* — instructs creating an `ansible` user / `ssh ansible@`; STATUS records ubongo
|
||||
is managed as `sjat`, ansible-user bootstrap pending. **new**
|
||||
- **O8 — dev_env untagged `set_fact` under tagged consumers** ·
|
||||
`roles/dev_env/tasks/per_user.yml:2-9` · *conformance* — partial `--tags users|config`
|
||||
runs skip the `dev_env__home` set_fact and fail. Tag the preflight `[users, config]` or
|
||||
`always`. **new**
|
||||
- **O9 — ubongo address outside ADR-007 subnets** · `STATUS.md:31 ↔ 007-network.md` ·
|
||||
*drift* — 10.20.10.151 is in neither srv (10.20.0.0/24) nor mgmt (10.10.0.0/24);
|
||||
`base__firewall_control_addr` depends on it. Already a tracked follow-up in the
|
||||
ubongo-build plan. Reconcile address or ADR-007. **new**
|
||||
|
||||
## Diff vs prior run (2026-05-30)
|
||||
### Low
|
||||
|
||||
- **Recurring:** the Terraform-writes-DNS contradiction (AF1) — fixed in README/ADR-003
|
||||
last run, reappeared in ADR-005/new-host.md. Signal that this phrasing keeps being
|
||||
copied; worth a `/review-repo`-time grep for "writes … DNS A record".
|
||||
- **New:** everything else — the repo gained ADR-010…017 and the `ubongo`/NetBird/
|
||||
Level-4 work since the prior run, so most findings are fresh propagation gaps.
|
||||
- **Resolved:** prior-run open items were largely addressed during the intervening
|
||||
doc work (control-node-as-VM, WireGuard framing, etc., now mostly reconciled).
|
||||
- **O10 — README ADR list stops at 017** · `README.md:104` · *drift* — 018–023 exist;
|
||||
extend or trim to a pointer. **recurring** (evolved from prior O3)
|
||||
- **O11 — ADR section-order vs ADR-023 §2** · `008:3, 014:98, 016:91, 017:66, 018:73` ·
|
||||
*conformance* — Status-not-first / Decision-late; passes lint (order not gated) but not
|
||||
the standard. Presentational restructure. **new**
|
||||
- **O12 — ADR-007 FQDN convention vs its own example** · `007-network.md:160` ·
|
||||
*consistency* — `<service>.baobab.band` vs `forgejo.nyumbani.baobab.band`; ties to open
|
||||
TODO 4 (split-horizon). **new**
|
||||
- **O13 — dev_env `.zshrc` heritage carryovers** ·
|
||||
`roles/dev_env/files/dotfiles/zsh/.zshrc:28,55` · *consistency* — hard-coded
|
||||
`/usr/bin/rclone` alias (not installed by the role) + unguarded `direnv` hook. **new**
|
||||
- **O14 — oh_my_posh config tasks untagged** · `roles/dev_env/tasks/oh_my_posh.yml:15-26`
|
||||
· *consistency* — inconsistent `config` tagging vs per_user.yml. **new**
|
||||
- **O15 — tfvars.example `pve01` vs ADR-007 `pve0`** ·
|
||||
`terraform/environments/*/terraform.tfvars.example:9` · *consistency* — verify the real
|
||||
node name, then align. **new**
|
||||
- **O16 — ADR-013/015 "See also:" vs `## Related`** · *consistency* — stylistic; convert
|
||||
for uniformity. **new**
|
||||
- **O17 — empty scaffold `handlers/main.yml`** · `roles/{dev_env,base}/handlers/main.yml`
|
||||
· *cruft* — confirm convention or delete. **new**
|
||||
- **O18 — docs/README.md + inventories/README.md narrower than reality** · *consistency*
|
||||
— omit several real subdirs / the offsite_hosts group. **new**
|
||||
|
||||
## Follow-up prompt
|
||||
## Deferral checklist (Phase 2)
|
||||
|
||||
> Thread the ADR-017 `VERIFY.md` convention through the remaining docs (O1–O3): add a
|
||||
> `VERIFY.md` row to ADR-004's service-role file table, a VERIFY.md step to
|
||||
> `new-role.md` (and reconcile STATUS.md:17), and refresh `README.md`'s ADR list +
|
||||
> `docs/` tree. Then settle the `askari` inventory group name (O4) and propagate it to
|
||||
> CLAUDE.md host-groups + ADR-009 valid-groups. Finally clear the stale labels O5
|
||||
> (ADR-006 backend.tf) and O6 (ADR-014 plugin reproducibility = DONE).
|
||||
| Source | Items | Verdict |
|
||||
|---|---|---|
|
||||
| ADR-011 Deferred/Open | 5 (snapshot driver, cadences, health-check harness home, classification home, staging-first) | **All genuinely still open** — cross-checked against later ADRs + TODO 16. None silently resolved. |
|
||||
| ADR-015 Deferred | #1 mesh VPN, #2 service-UI, #3 build | **All marked RESOLVED in place** (ADR-016 / ADR-017 / 2026-06-11 build). |
|
||||
|
||||
**Stale-deferred found: 0.** The recurring FRICTION.md miss did not recur this run.
|
||||
|
||||
## Scan false positives (folded in, not actionable)
|
||||
|
||||
- `broken-path-ref STATUS.md:38` — STATUS legitimately documents `roles/docker_host/` as
|
||||
"Not in git." (intentional reference to an unbuilt role).
|
||||
- `broken-adr-ref` ×4 — `ADR-099`/`ADR-100` in `tests/test_repo_scan.py` and the
|
||||
adr-structure plan are intentional **test fixtures** for the scanner's bad-ref check.
|
||||
- `marker` ×14 — all in `docs/superpowers/{plans,specs}/*` (historical commit-message
|
||||
TODOs / plan steps) or prose discussing "over-tagging" as a concept. Not cruft.
|
||||
|
||||
## Prior-run diff (vs 2026-06-05)
|
||||
|
||||
**Resolved (7):** O1 VERIFY.md row · O2 new-role VERIFY step · O4 askari group naming ·
|
||||
O5 backend.tf relabel · O6 ADR-014 reproducibility · O11 CAPABILITIES Level-4 row ·
|
||||
O12 TODO 3.10. **Partial:** O3 (docs tree fixed in AF4; ADR-list carried as O10).
|
||||
**Not re-detected (verify next run):** O7–O10 (ADR-011 still Proposed).
|
||||
|
||||
## Follow-up prompt (copy-paste)
|
||||
|
||||
> Act on the open findings from `docs/reviews/2026-06-11-review.md`. Priority order:
|
||||
> 1. **O1 (high):** `make lint` is red on `main` — `playbooks/site.yml` imports the
|
||||
> non-existent `docker_host` role. Pick an interim posture (guard/skip the play, or
|
||||
> `make new-role NAME=docker_host` to scaffold a stub, or exclude from syntax-check
|
||||
> until built) so the trunk lints clean again, and record the choice in STATUS.md.
|
||||
> 2. **O2 (high):** Resolve the ADR-004 ↔ ADR-022 backup-scope contradiction —
|
||||
> update ADR-004's "not in scope of this repo" line to defer to ADR-022 (per ADR-023's
|
||||
> no-silent-reversal rule) and cross-link.
|
||||
> 3. **O3:** Add ACCESS.md + BACKUP.md rows to ADR-004's service-role file table.
|
||||
> 4. **O4:** Reconcile CAPABILITIES' nvim/tmux exclusion with the built `dev_env` role
|
||||
> (carve out the ubongo control-node exception).
|
||||
> 5. **O8 (conformance):** Tag the `dev_env__home` preflight `set_fact` so partial
|
||||
> `--tags users|config` runs don't fail.
|
||||
> 6. **O6 / O9:** Regenerate the inventory stubs to include `offsite_hosts`; reconcile
|
||||
> ubongo's 10.20.10.151 against ADR-007's subnets (or amend ADR-007).
|
||||
> 7. Sweep the low-severity doc items (O5 caveat, O7 runbook, O10 ADR list, O11 ADR
|
||||
> section order, O12–O18) as a single docs-hygiene batch.
|
||||
> Run `make lint` before committing; commit per CLAUDE.md git conventions.
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@ Top-level orchestration playbooks. No inline vars — configuration comes from
|
|||
`group_vars/` / `host_vars/` (see CLAUDE.md).
|
||||
|
||||
- `site.yml` — full standard state: applies `base` to all hosts and `docker_host`
|
||||
to docker hosts. **Note:** those roles are empty today, so this is currently a
|
||||
no-op — see `STATUS.md`.
|
||||
to docker hosts. **Note:** `base` is only partially built (its `firewall` concern)
|
||||
and `docker_host` does not exist yet, so this is incomplete — see `STATUS.md`.
|
||||
- `workstation.yml` — applies the `dev_env` role (interactive developer environment)
|
||||
to the `control` group; built and applied to `ubongo` (see `STATUS.md`).
|
||||
- `bootstrap.yml` — first-run setup for a host that may not have Python yet;
|
||||
self-contained (does not depend on the roles).
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
# site.yml — apply full standard state to all hosts
|
||||
# Run via: make deploy PLAYBOOK=site
|
||||
# NOTE: the `base` and `docker_host` roles are not built yet (see STATUS.md), so this
|
||||
# playbook fails on a clean clone until they exist.
|
||||
# NOTE: `base` is only partially built (its `firewall` concern; see STATUS.md) and the
|
||||
# `docker_host` role does not exist yet, so this playbook applies base's firewall but is
|
||||
# incomplete until `docker_host` is created.
|
||||
|
||||
- name: Apply base configuration to all hosts
|
||||
hosts: all
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ Each role must have: a `molecule/default/` scenario (Debian 13), a populated
|
|||
`README.md`, and a filled-in `meta/main.yml`. Conventions: CLAUDE.md and
|
||||
`docs/runbooks/new-role.md`.
|
||||
|
||||
Current state: `base` and `docker_host` are **not built yet** — they exist only as
|
||||
empty, untracked dirs, so `site.yml` would fail on a clean clone. Build them with
|
||||
`make new-role` when defining the baseline. See `STATUS.md`.
|
||||
Current state: `base` is **partially built** — its `firewall` concern (nftables) is
|
||||
implemented and tested; the other concerns (SSH hardening, fail2ban, auditd, packages,
|
||||
users) are not yet built. `docker_host` does **not exist yet**. `dev_env` (interactive
|
||||
developer environment) is built and applied. See `STATUS.md` for the authoritative
|
||||
breakdown.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue