|
| 1 | +# HelixFlow — Constitution |
| 2 | + |
| 3 | +> **Status:** Active. This document is the project's authoritative |
| 4 | +> rule set. When a rule here conflicts with `CLAUDE.md`, `AGENTS.md`, |
| 5 | +> or any guide, the Constitution wins. |
| 6 | +
|
| 7 | +## Mission |
| 8 | + |
| 9 | +See README.md. |
| 10 | + |
| 11 | +## Mandatory Standards |
| 12 | + |
| 13 | +1. **Reproducibility:** every change is reproducible from a clean |
| 14 | + clone (`git clone <repo> && <project bootstrap>`); no hidden steps. |
| 15 | +2. **Tests track behavior, not code:** test what the user-visible |
| 16 | + behavior is, not what the implementation looks like. |
| 17 | +3. **No silent skips, no silent mocks above unit tests.** |
| 18 | +4. **Conventional Commits** for all commits. |
| 19 | +5. **SSH-only for git operations** (`git@…`); HTTPS prohibited. |
| 20 | + |
| 21 | +## Numbered Rules |
| 22 | + |
| 23 | +<!-- Rules are numbered CONST-NNN. New rules append. Removed rules |
| 24 | + keep their number with a "**Retired:** …" line. --> |
| 25 | + |
| 26 | +<!-- BEGIN host-power-management addendum (CONST-033) --> |
| 27 | + |
| 28 | +### CONST-033 — Host Power Management is Forbidden |
| 29 | + |
| 30 | +**Status:** Mandatory. Non-negotiable. Applies to every project, |
| 31 | +submodule, container entry point, build script, test, challenge, and |
| 32 | +systemd unit shipped from this repository. |
| 33 | + |
| 34 | +**Rule:** No code in this repository may invoke a host-level power- |
| 35 | +state transition (suspend, hibernate, hybrid-sleep, suspend-then- |
| 36 | +hibernate, poweroff, halt, reboot, kexec) on the host machine. This |
| 37 | +includes — but is not limited to: |
| 38 | + |
| 39 | +- `systemctl {suspend,hibernate,hybrid-sleep,suspend-then-hibernate,poweroff,halt,reboot,kexec}` |
| 40 | +- `loginctl {suspend,hibernate,hybrid-sleep,suspend-then-hibernate,poweroff,halt,reboot}` |
| 41 | +- `pm-{suspend,hibernate,suspend-hybrid}` |
| 42 | +- `shutdown {-h,-r,-P,-H,now,--halt,--poweroff,--reboot}` |
| 43 | +- DBus calls to `org.freedesktop.login1.Manager.{Suspend,Hibernate,HybridSleep,SuspendThenHibernate,PowerOff,Reboot}` |
| 44 | +- DBus calls to `org.freedesktop.UPower.{Suspend,Hibernate,HybridSleep}` |
| 45 | +- `gsettings set ... sleep-inactive-{ac,battery}-type` to any value other than `'nothing'` or `'blank'` |
| 46 | + |
| 47 | +**Why:** The host runs mission-critical parallel CLI-agent and |
| 48 | +container workloads. On 2026-04-26 18:23:43 the host was auto- |
| 49 | +suspended by the GDM greeter's idle policy mid-session, killing |
| 50 | +HelixAgent and 41 dependent services. Recurring memory-pressure |
| 51 | +SIGKILLs of `user@1000.service` (perceived as "logged out") have the |
| 52 | +same outcome. Auto-suspend, hibernate, and any power-state transition |
| 53 | +are unsafe for this host. |
| 54 | + |
| 55 | +**Defence in depth (mandatory artifacts in every project):** |
| 56 | +1. `scripts/host-power-management/install-host-suspend-guard.sh` — |
| 57 | + privileged installer, manual prereq, run once per host with sudo. |
| 58 | + Masks `sleep.target`, `suspend.target`, `hibernate.target`, |
| 59 | + `hybrid-sleep.target`; writes `AllowSuspend=no` drop-in; sets |
| 60 | + logind `IdleAction=ignore` and `HandleLidSwitch=ignore`. |
| 61 | +2. `scripts/host-power-management/user_session_no_suspend_bootstrap.sh` — |
| 62 | + per-user, no-sudo defensive layer. Idempotent. Safe to source from |
| 63 | + `start.sh` / `setup.sh` / `bootstrap.sh`. |
| 64 | +3. `scripts/host-power-management/check-no-suspend-calls.sh` — |
| 65 | + static scanner. Exits non-zero on any forbidden invocation. |
| 66 | +4. `challenges/scripts/host_no_auto_suspend_challenge.sh` — asserts |
| 67 | + the running host's state matches layer-1 masking. |
| 68 | +5. `challenges/scripts/no_suspend_calls_challenge.sh` — wraps the |
| 69 | + scanner as a challenge that runs in CI / `run_all_challenges.sh`. |
| 70 | + |
| 71 | +**Enforcement:** Every project's CI / `run_all_challenges.sh` |
| 72 | +equivalent MUST run both challenges (host state + source tree). A |
| 73 | +violation in either channel blocks merge. Adding files to the |
| 74 | +scanner's `EXCLUDE_PATHS` requires an explicit justification comment |
| 75 | +identifying the non-host context. |
| 76 | + |
| 77 | +**See also:** `docs/HOST_POWER_MANAGEMENT.md` for full background and |
| 78 | +runbook. |
| 79 | + |
| 80 | +<!-- END host-power-management addendum (CONST-033) --> |
| 81 | + |
| 82 | +## Definition of Done |
| 83 | + |
| 84 | +A change is done when: |
| 85 | + |
| 86 | +1. The code change is committed. |
| 87 | +2. All project-level tests pass on a clean clone. |
| 88 | +3. All challenges in `challenges/scripts/` pass on the running host. |
| 89 | +4. Governance docs (`CONSTITUTION.md`, `AGENTS.md`, `CLAUDE.md`) are |
| 90 | + coherent with the change. |
| 91 | + |
| 92 | +## See also |
| 93 | + |
| 94 | +- `README.md` — project overview, quickstart. |
| 95 | +- `AGENTS.md` — guidance for AI coding agents (Codex, Cursor, etc.). |
| 96 | +- `CLAUDE.md` — guidance specifically for Claude Code. |
| 97 | +- `docs/HOST_POWER_MANAGEMENT.md` — CONST-033 background and runbook. |
0 commit comments