From 058c92e5d0802c9328d32f976b606e93af311470 Mon Sep 17 00:00:00 2001 From: Red Queen Date: Fri, 28 Aug 2026 11:27:31 +0000 Subject: [PATCH] CP1.1: PRE_HERMES Control Plane SOT closure - 5-control scope (trading_execution removed), RED_QUEEN_TRADING_AUTHORITY=NEVER, reproducible deployment --- .../control-plane/README.md | 119 +++++++++++++----- .../control-plane/README_CP1OS_SCOPE.md | 73 +++++++++++ .../control-plane/control_reader.py | 16 +-- .../control-plane/test_control_reader.py | 34 +---- 4 files changed, 176 insertions(+), 66 deletions(-) create mode 100644 red-queen-architecture/control-plane/README_CP1OS_SCOPE.md diff --git a/red-queen-architecture/control-plane/README.md b/red-queen-architecture/control-plane/README.md index fcb66fa..bf44423 100644 --- a/red-queen-architecture/control-plane/README.md +++ b/red-queen-architecture/control-plane/README.md @@ -1,4 +1,4 @@ -# PRE_HERMES Control Plane — Betriebsvertrag (CP1) +# PRE_HERMES Control Plane — Betriebsvertrag (CP1 / CP1.1) Autoritative SoT für die produktive PRE_HERMES Autonomy Control Plane. Dieses Verzeichnis ist die **einzige** Quelle für den produktiven Control-Plane-Code. @@ -9,18 +9,52 @@ Produktiver Deploy-Pfad: `red-queen-architecture/control-plane/` → `/opt/contr Minimale, fail-closed Sicherheitsgrundlage für zukünftige Red-Queen/Hermes-Autonomie. **CP1 ist KEINE Autonomie-Aktivierung.** Nach CP1 ist das System mindestens so restriktiv wie vorher. -## 2. Komponenten +## 2. Architektur-Boundary (CP1.0S, permanent) + +**RED_QUEEN_TRADING_AUTHORITY = NEVER** + +Trading ist NICHT Bestandteil der Hermes Control Plane. Red Queen ist ein +**autonomes Arbeits-, Wissens-, Planungs-, Prüfungs- und Orchestrierungssystem** — kein Trading-System. +Hermes Autonomy und Trading Authority sind **zwei getrennte Sicherheitsdomänen**. + +**Hermes Control Plane besteht ausschließlich aus:** +``` +global_autonomy +productive_mutations +save_execution +delete_execution +emergency_stop +``` + +**KEIN** `trading_execution`, Trading-Gate, Broker-Gate, Broker-Credential oder +Trading-Execution-Control darf Bestandteil dieser Control Plane sein. Das bestehende +Trading-System ist eine separate Security-Domain (eigene Architektur, Execution, +Credentials, Risk Control, Kill-Switch, Freigabelogik). + +`PRODUCTIVE_MUTATIONS` innerhalb der Hermes Control Plane bedeutet Hermes-/Knowledge-/ +Mission-Domain-Mutationen — NICHT Order/Trade/Broker/Position-Mutation oder Trading-Execution. + +**Red-Queen-Autonomie-Level (Arbeitsautonomie, KEIN Trading-Level):** +- L0 = Disabled / Manual +- L1 = Read-only Observation +- L2 = Autonomous Planning / Preparation +- L3 = bounded authorized SAVE / productive knowledge work +- L4 = human-authorized DELETE / höhere Arbeitsautonomie + +## 3. Komponenten | Datei | Zweck | |---|---| | `control_reader.py` | Fail-closed, deterministischer Control-State-Reader (produktiver Code) | -| `test_control_reader.py` | Statische + adversariale Tests (A–J, 25 Fälle) | +| `test_control_reader.py` | Statische + adversariale Tests (A–J, 22 Fälle) | | `deploy_control_plane.sh` | Reproduzierbarer Deployment-Pfad (root, idempotent) | +| `README_CP1OS_SCOPE.md` | CP1.0S Domain-Boundary + Level-Model | | `README.md` | Dieser Betriebsvertrag | -## 3. Control State (Source of Truth) +## 4. Control State (Source of Truth) Produktiver Pfad: `/opt/control-plane/state/` (root:root, 0700, Dateien 0600). +**Runtime State ist NICHT Teil der SoT** (nie committen). | Datei | Typ | Erlaubte RAW-Werte | |---|---|---| @@ -28,7 +62,6 @@ Produktiver Pfad: `/opt/control-plane/state/` (root:root, 0700, Dateien 0600). | `productive_mutations` | positiv | `ON` / `OFF` (+ `boot_id=`) | | `save_execution` | positiv | `ON` / `OFF` (+ `boot_id=`) | | `delete_execution` | positiv | `ON` / `OFF` (+ `boot_id=`) | -| `trading_execution` | positiv | `ON` / `OFF` (+ `boot_id=`) | | `emergency_stop` | negativ | `ON` / `OFF` | **Positives ON-Grant-Format:** @@ -37,48 +70,61 @@ ON boot_id= ``` -## 4. Gate-Semantik (fail-closed) +## 5. Gate-Semantik (fail-closed) - **Positives Gate:** `EFFECTIVE=ON` nur wenn `RAW==ON` UND `grant_boot_id == current_boot_id` UND `EMERGENCY_EFFECTIVE==OFF`. Sonst `OFF`. - **Emergency Stop (negativ):** `EFFECTIVE=ON` wenn `RAW==ON` ODER Datei fehlt ODER malformed. `OFF` nur bei explizitem `RAW==OFF`. - **UNKNOWN = MORE RESTRICTIVE.** Fehlende/unlesbare/malformed Datei → positives Gate `OFF`, Emergency `ON`. -- **Hierarchie:** `SAVE/DELETE/TRADING_EFFECTIVE` benötigen `GLOBAL_AUTONOMY_EFFECTIVE==ON` UND `MUTATIONS_EFFECTIVE==ON` UND eigenen Grant gültig UND `EMERGENCY_EFFECTIVE==OFF`. Kein spezifischer Execution-Switch umgeht den globalen Mutation-Gate. +- **Fail-closed:** Positive missing→OFF, malformed→OFF, raw!=ON→OFF, ON+wrong boot_id→OFF. Emergency missing→ON, malformed→ON, raw ON→ON, raw OFF→OFF. -## 5. Boot-ID-Validierung +## 6. Effective-State-Hierarchie -- Quelle: `/proc/sys/kernel/random/boot_id` (Kernel-Boot-ID, ändert sich bei jedem Host-Boot). -- Positiver Grant ist nur gültig, wenn `grant_boot_id == current_boot_id`. +- **GLOBAL effective** erfordert: global_autonomy raw ON + gültige boot_id + emergency OFF +- **MUTATIONS effective** erfordert: GLOBAL ON + productive_mutations raw ON + gültige boot_id + emergency OFF +- **SAVE effective** erfordert: GLOBAL ON + MUTATIONS ON + save_execution raw ON + gültige boot_id + emergency OFF +- **DELETE effective** erfordert: GLOBAL ON + MUTATIONS ON + delete_execution raw ON + gültige boot_id + emergency OFF + +**IMPORTANT:** DELETE effective ON allein autorisiert NIEMALS einen DELETE. +**AUTH.4D + Human Authorization bleiben zusätzliche, unabhängige Pflichtbedingungen.** +**COMMAND != AUTHORIZATION.** + +## 7. Boot-ID-Validierung + +- Quelle: `/proc/sys/kernel/random/boot_id` (Kernel-Boot-ID). +- Positiver Grant gültig nur wenn `grant_boot_id == current_boot_id`. - `missing boot_id` → `EFFECTIVE=OFF`. `malformed boot_id` → `EFFECTIVE=OFF`. - **Keine manuell gepflegte Epoch, kein persistenter Alt-Grant.** -## 6. Restart-Semantik (korrekt dokumentiert) +## 8. Boot-Semantik (KORREKT dokumentiert) -- **HOST REBOOT:** `current_boot_id` ändert sich → alle alten positiven Grants ungültig → `EFFECTIVE=OFF`. Operator muss erneut autorisieren. -- **CONTAINER RESTART OHNE HOST REBOOT:** `current_boot_id` bleibt gleich → ein gültiger positiver Grant kann weiterhin gültig bleiben (kein neuer Boot, keine neue Autorisierung nötig). -- **Negative/Deny-States** (`emergency_stop=ON`, `*_execution=OFF`) persistieren über Restart hinweg (fail-closed). +- **HOST REBOOT:** Kernel `boot_id` ändert sich → alte positive Grants ungültig → positive effective Gates fallen fail-closed auf **OFF**. Operator muss erneut autorisieren. +- **CONTAINER RESTART:** Host `boot_id` ändert sich normalerweise NICHT → ein gültiger positiver Grant kann weiterhin gültig bleiben. +- **NICHT dokumentieren:** "jeder Container-Neustart setzt Grants zurück" (das wäre falsch). +- Negative/Deny-States (`emergency_stop=ON`, `*_execution=OFF`) persistieren über Restart (fail-closed). -## 7. Status Projection Contract +## 9. Status Projection Contract - Produktiver Pfad: `/opt/control-plane/status/latest.txt` (root:root, 0444, read-only). - **STATUS PROJECTION != AUTHORITY.** -- **Authority ist ausschließlich:** Control State + aktuelle Kernel-Boot-ID + fail-closed effective-state evaluation. +- **Authority ist ausschließlich:** Runtime State + aktuelle Kernel-Boot-ID + fail-closed Evaluator. - `latest.txt` dient **ausschließlich der Observability**. -- Wenn die Projection fehlt/stale/malformed ist, darf das **niemals eine positive Freigabe erzeugen** (die Authority-Evaluation ist davon unabhängig). +- Fehlende/stale/malformed Projection darf **niemals eine Capability aktivieren**. -## 8. Ownership / Permissions +## 10. Ownership / Permissions - Control State: root:root, 0700 (dir), 0600 (Dateien). - Status Projection: root:root, 0444. - Audit: root:root, `chattr +a` (append-only). - **Red Queen:** kein Host-Root, kein Docker-Socket, kein Schreibzugriff auf `/opt/control-plane`. RQ kann State nicht lesen (0700) und nicht schreiben. RQ erhält später nur read-only Status-Projection (Observability). -## 9. Audit-Foundation +## 11. Audit-Foundation - Pfad: `/opt/control-plane/audit/control_audit.log` (root:root, append-only `+a`). - Format: `WHEN | WHO | WHAT | OLD | NEW | WHY | BOOT_ID`. - RQ kann Audit nicht überschreiben (root-owned, append-only). +- **Runtime Audit Log ist NICHT Teil der SoT** (nie committen). -## 10. Deployment (reproduzierbar) +## 12. Deployment (reproduzierbar) ```bash # Als root auf dem Host, aus frischem Forgejo-Checkout: @@ -88,23 +134,40 @@ cd red-queen-architecture/control-plane - Reproduziert ausschließlich die CP1-Artefakte. - **Überschreibt KEINE bestehenden State-Dateien** (Runtime-State bleibt unangetastet). -- Rollback: `rm -rf /opt/control-plane`. +- Ein Redeploy darf NICHT `/opt/control-plane/state/` überschreiben/neu initialisieren, wenn produktiver State existiert. +- Audit bleibt erhalten. -## 11. NICHT in Git +## 13. Rollback-Semantik -- Aktuelle produktive State-Werte als Authority (State ist Runtime, nicht SoT). -- Aktuelle `boot_id` als persistente Authority. -- Secrets, Tokens, private Keys. -- Runtime Audit Log. +`rm -rf /opt/control-plane` ist NICHT der langfristige Sicherheits-Rollback. +Für CP1.1 existiert ein versionsgebundener Code-Rollback, der: +- Runtime State erhält +- Audit erhält +- keine positiven Gates aktiviert +- Emergency State nicht abschwächt +- auf einen bekannten SoT-Commit zurückgeht -## 12. Sicherheitszustand (CP1 initial) +**Code-Rollback:** Aus dem gewünschten bekannten SoT-Commit den `control_reader.py` extrahieren und per `deploy_control_plane.sh` neu deployen (State bleibt unangetastet). Kein komplexer Rollback-Manager nötig. + +## 14. NICHT in Git (Runtime Authority) + +Forgejo ersetzt NICHT die produktive Laufzeit-Autorität. Nicht committen: +- Aktuelle produktive Gate-Werte, produktive Grant-Dateien +- Aktuelle `boot_id` als Authority +- Produktive Audit-Logs +- Secrets, Tokens, private Keys, Credentials +- SAVE/DELETE-Tokens, Human Authorization Private Key +- Runtime SQLite DBs + +Forgejo enthält: **CODE, SCHEMA, TESTS, DEPLOYMENT LOGIC, DOCUMENTATION** — aber NICHT den aktuellen produktiven Sicherheitszustand. + +## 15. Sicherheitszustand (CP1 initial) ``` GLOBAL_AUTONOMY_EFFECTIVE=OFF MUTATIONS_EFFECTIVE=OFF SAVE_EFFECTIVE=OFF DELETE_EFFECTIVE=OFF -TRADING_EFFECTIVE=OFF EMERGENCY_EFFECTIVE=ON A2-A5=NOT_PRESENT HEARTBEAT=NOT_PRESENT SCHEDULER=NOT_PRESENT AUTH.4D=FROZEN P15=FALSE DELETE_CANARY=FALSE diff --git a/red-queen-architecture/control-plane/README_CP1OS_SCOPE.md b/red-queen-architecture/control-plane/README_CP1OS_SCOPE.md new file mode 100644 index 0000000..9e7236c --- /dev/null +++ b/red-queen-architecture/control-plane/README_CP1OS_SCOPE.md @@ -0,0 +1,73 @@ +# PRE_HERMES Control Plane — CP1.0S Scope-Korrektur & Permanente Domain-Boundary + +Scope-Korrektur der produktiven PRE_HERMES Control Plane (CP1.0S, 28.08.). +Wird in CP1.1 in die SoT/README übernommen. + +## PERMANENT INVARIANT + +``` +RED_QUEEN_TRADING_AUTHORITY = NEVER +``` + +Red Queen ist ein **autonomes Arbeits-, Wissens-, Planungs-, Prüfungs- und +Orchestrierungssystem** — NICHT ein Trading-System. + +Red Queen darf insbesondere **niemals** allein aufgrund ihrer Hermes-Autonomie erhalten: +- Broker Credentials +- Broker API Execution +- Order Execution +- Trading Execution Tokens +- Trading Kill-Switch Authority +- Trading Enable Authority + +**Hermes Autonomy und Trading Authority sind zwei getrennte Sicherheitsdomänen.** + +## Domain Boundary + +### RED QUEEN = AUTONOMOUS WORK SYSTEM — RED QUEEN MAY: +- observe +- research +- plan +- orchestrate +- delegate +- verify +- document +- maintain mission state +- use authorized knowledge SAVE paths +- use separately human-authorized DELETE paths + +### RED QUEEN MUST NOT: +- receive Trading Execution Authority + +### TRADING SYSTEM = SEPARATE SECURITY DOMAIN +Eigene: Architektur, Security Boundary, Execution, Broker-Anbindung, +Credentials, Risk Control, Kill-Switch-Logik, Freigabelogik. + +**PRODUCTIVE_MUTATIONS in der Hermes Control Plane bedeutet NICHT Trading/Orders/Broker-Mutationen.** + +## Hermes Control Plane (nach CP1.0S) — 5 Controls + +| Control | Bedeutung | +|---|---| +| `global_autonomy` | autonome Arbeit von Red Queen | +| `productive_mutations` | produktive Mutationen innerhalb der Hermes-/Knowledge-Domäne | +| `save_execution` | SAVE-Pfad der Hermes-/Knowledge-Domäne | +| `delete_execution` | DELETE-Pfad der Hermes-/Knowledge-Domäne (zusätzlich AUTH.4D + Human Authorization) | +| `emergency_stop` | stoppt Red-Queen/Hermes-Autonomie | + +**KEIN Switch dieser Control Plane kontrolliert das Trading-System.** +`trading_execution` wurde entfernt (irrtümlicher Control aus korrigierter Architekturannahme). + +## Level Model Correction (Red-Queen-Autonomie-Level) + +Autonomie-Level beziehen sich ausschließlich auf **Arbeitsautonomie**. KEIN Trading-Level. + +| Level | Bedeutung | +|---|---| +| L0 | Disabled / Manual | +| L1 | Read-only Observation | +| L2 | Autonomous Planning / Preparation | +| L3 | bounded authorized SAVE / productive knowledge work | +| L4 | human-authorized DELETE / höhere Arbeitsautonomie | + +Weitere Arbeitsautonomie-Level können später separat definiert werden. KEIN Trading-Level. diff --git a/red-queen-architecture/control-plane/control_reader.py b/red-queen-architecture/control-plane/control_reader.py index 0e0a5c4..b9ad721 100755 --- a/red-queen-architecture/control-plane/control_reader.py +++ b/red-queen-architecture/control-plane/control_reader.py @@ -32,13 +32,12 @@ ON = "ON" OFF = "OFF" _ALLOWED = {ON, OFF} -# Die sechs Controls +# Die fünf Controls (Hermes/Red-Queen-Domäne; Trading ist eine separate Security-Domain) POSITIVE_GATES = ( "global_autonomy", "productive_mutations", "save_execution", "delete_execution", - "trading_execution", ) EMERGENCY = "emergency_stop" @@ -124,7 +123,7 @@ def _positive_effective(raw, grant_boot_id, current_boot_id, emergency_effective def read_control_state(): """ - Berechnet den vollständigen Control-State (RAW + EFFECTIVE für alle 6 Controls). + Berechnet den vollständigen Control-State (RAW + EFFECTIVE für alle 5 Controls). Rückgabe: dict mit allen Feldern für die Status-Projection. """ current_boot_id = read_boot_id() @@ -146,19 +145,18 @@ def read_control_state(): "productive_mutations": "productive_mutations", "save_execution": "save", "delete_execution": "delete", - "trading_execution": "trading", } # 2) Positive Gates (Boot-gebunden, hierarchisch) for gate in POSITIVE_GATES: raw, grant_boot = _parse_raw(os.path.join(STATE_DIR, gate)) short = _short[gate] - # Abhängigkeit: SAVE/DELETE/TRADING brauchen zusätzlich die Master-Gates (siehe unten). + # Abhängigkeit: SAVE/DELETE brauchen zusätzlich die Master-Gates (siehe unten). eff = _positive_effective(raw, grant_boot, current_boot_id, emergency_effective) result[f"{short}_raw"] = raw if raw is not None else "MISSING" result[f"{short}_effective"] = eff - # 3) Hierarchische Berechnung (MISSIONS: Mutationen, SAVE, DELETE, TRADING) + # 3) Hierarchische Berechnung (MISSIONS: Mutationen, SAVE, DELETE) global_eff = result["global_autonomy_effective"] mutations_eff = result["productive_mutations_effective"] @@ -166,8 +164,8 @@ def read_control_state(): if mutations_eff == ON and global_eff == OFF: result["productive_mutations_effective"] = OFF - # SAVE / DELETE / TRADING brauchen: GLOBAL=ON AND MUTATIONS=ON AND eigener Grant gültig - for gate in ("save_execution", "delete_execution", "trading_execution"): + # SAVE / DELETE brauchen: GLOBAL=ON AND MUTATIONS=ON AND eigener Grant gültig + for gate in ("save_execution", "delete_execution"): short = _short[gate] raw = result[f"{short}_raw"] grant_boot = _parse_raw(os.path.join(STATE_DIR, gate))[1] @@ -191,8 +189,6 @@ def format_projection(state): "save_effective", "delete_raw", "delete_effective", - "trading_raw", - "trading_effective", "emergency_raw", "emergency_effective", ] diff --git a/red-queen-architecture/control-plane/test_control_reader.py b/red-queen-architecture/control-plane/test_control_reader.py index ead6570..c9a7363 100644 --- a/red-queen-architecture/control-plane/test_control_reader.py +++ b/red-queen-architecture/control-plane/test_control_reader.py @@ -1,5 +1,10 @@ #!/usr/bin/env python3 -"""CP1 statische + adversariale Tests (A-J) für control_reader.py.""" +"""CP1 statische + adversariale Tests (A-J) für control_reader.py. + +CP1.0S: trading_execution aus der Hermes Control Plane entfernt (separate +Security-Domain). Test E (trading-Gate) wurde entfernt, da der Gate nicht mehr +existiert. Alle übrigen Tests prüfen die 5 Hermes-Controls. +""" import os import shutil import sys @@ -53,14 +58,12 @@ e.write("global_autonomy", "OFF") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "ON") s = read() check("initial global=OFF", s["global_autonomy_effective"] == "OFF") check("initial mutations=OFF", s["productive_mutations_effective"] == "OFF") check("initial save=OFF", s["save_effective"] == "OFF") check("initial delete=OFF", s["delete_effective"] == "OFF") -check("initial trading=OFF", s["trading_effective"] == "OFF") check("initial emergency=ON", s["emergency_effective"] == "ON") # ---------- TEST A: positive ON mit falscher Boot-ID -> OFF ---------- @@ -70,7 +73,6 @@ e.write("global_autonomy", "ON\nboot_id=other-boot\n") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "OFF") s = read() check("A global OFF bei falscher boot_id", s["global_autonomy_effective"] == "OFF") @@ -82,7 +84,6 @@ e.write("global_autonomy", f"ON\nboot_id={e.cur_boot}\n") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "ON") s = read() check("B global OFF bei emergency ON", s["global_autonomy_effective"] == "OFF") @@ -95,7 +96,6 @@ e.write("global_autonomy", f"ON\nboot_id={e.cur_boot}\n") e.write("productive_mutations", "OFF") e.write("save_execution", f"ON\nboot_id={e.cur_boot}\n") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "OFF") s = read() check("C save OFF bei mutations OFF", s["save_effective"] == "OFF") @@ -108,25 +108,11 @@ e.write("global_autonomy", "OFF") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", f"ON\nboot_id={e.cur_boot}\n") -e.write("trading_execution", "OFF") e.write("emergency_stop", "OFF") s = read() check("D delete OFF bei global OFF", s["delete_effective"] == "OFF") check("D global OFF", s["global_autonomy_effective"] == "OFF") -# ---------- TEST E: trading ON aber emergency ON -> TRADING OFF ---------- -print("== TEST E: trading ON, emergency ON -> TRADING OFF ==") -e = Env() -e.write("global_autonomy", "OFF") -e.write("productive_mutations", "OFF") -e.write("save_execution", "OFF") -e.write("delete_execution", "OFF") -e.write("trading_execution", f"ON\nboot_id={e.cur_boot}\n") -e.write("emergency_stop", "ON") -s = read() -check("E trading OFF bei emergency ON", s["trading_effective"] == "OFF") -check("E emergency ON", s["emergency_effective"] == "ON") - # ---------- TEST F: fehlende emergency_stop -> EMERGENCY ON ---------- print("== TEST F: missing emergency_stop -> ON ==") e = Env() @@ -134,7 +120,6 @@ e.write("global_autonomy", "OFF") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") # KEIN emergency_stop schreiben s = read() check("F emergency ON bei fehlender Datei", s["emergency_effective"] == "ON") @@ -146,7 +131,6 @@ e.write("global_autonomy", "OFF") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "MAYBE\n") s = read() check("G emergency ON bei malformed", s["emergency_effective"] == "ON") @@ -158,7 +142,6 @@ e.write("global_autonomy", f"ON\nboot_id={e.cur_boot}\n") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "OFF") s = read() check("H vor Reboot global ON", s["global_autonomy_effective"] == "ON") @@ -175,7 +158,6 @@ e.write("global_autonomy", f"ON\nboot_id={e.cur_boot}\n") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "OFF") e.missing_boot() s = read() @@ -188,7 +170,6 @@ e.write("global_autonomy", "ON") # no boot_id -> invalid anyway e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "ON") os.chmod(os.path.join(e.state_dir, "emergency_stop"), 0o000) s = read() @@ -202,7 +183,6 @@ e.write("global_autonomy", "ON\n") # no boot_id line e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "OFF") s = read() check("ON ohne boot_id -> global OFF", s["global_autonomy_effective"] == "OFF") @@ -214,7 +194,6 @@ e.write("global_autonomy", "") # empty e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "OFF") s = read() check("empty positive -> global OFF", s["global_autonomy_effective"] == "OFF") @@ -227,7 +206,6 @@ e.write("global_autonomy", "ON\nfoo=bar\nboot_id=xyz\n") e.write("productive_mutations", "OFF") e.write("save_execution", "OFF") e.write("delete_execution", "OFF") -e.write("trading_execution", "OFF") e.write("emergency_stop", "OFF") s = read() check("unknown field -> global OFF", s["global_autonomy_effective"] == "OFF")