| Check | Soll | Ist | OK |
|---|---|---|---|
| master HEAD | cd37822 | cd37822 mh-4c: add managed asset lifecycle command service | ✓ |
git status | clean | empty output | ✓ |
| Bot in-container PID | 29984 | unverändert | ✓ |
| Worker Host PID | (egal) | 2486135 (pre-existing Watchdog-Respawn) | ⚠ |
| cmd 13 | cancelled | 13 | apply_baseline_holdings | cancelled | ✓ |
managed_proposals rows | 0 | 0 | ✓ |
managed_assets_history rows | 0 | 0 | ✓ |
BINANCE_TESTNET | true | BINANCE_TESTNET=true | ✓ |
runtime_config.json | absent | not present | ✓ |
baseline_holdings.json | absent | not present | ✓ |
managed_state.json | absent | not present | ✓ |
state/risk_proposals/ | absent | not present | ✓ |
| Tracebacks last 200 lines | 0 | 0 matches | ✓ |
| Komponente | Status | Konsumiert in MH-5 |
|---|---|---|
MH-1: 8 managed.* CommandTypes + Validators | ea11637 | Filament Actions rufen Service-Methoden, die ihrerseits Registry validieren |
MH-2: ManagedStateReader + ProposalReader (Bot-side dormant) | 50cc5c2 | nicht direkt — UI liest DB-Cache, nicht Bot-Files (Hybrid C) |
MH-3a: ProposalEngine | 26c8ab3 | UI sieht Output via managed_proposals.proposal_json |
MH-3b: ProposalWriter | 62a08f4 | UI sieht proposal_sha256 / proposal_file_path aus DB-Cache |
MH-4a: managed_proposals + managed_assets_history + Enum + Models | 83dafca | Hauptquelle für Filament Resource Tabellen + Detail-Views |
MH-4b-1/2/3: ProposalService request/approve/reject + buildHardConfirmString() | 3fd7846 / be9cab7 / 93f4026 | Action-Backend für request/approve/reject |
MH-4c: ManagedStateService pause/resume/release + buildReleaseHardConfirmString() | cd37822 | Action-Backend für pause/resume/release |
Worker-Handler _handle_* | MH-6 | kommt nach MH-5 — Commands sitzen in pending/failed bis MH-6 |
flag_managed_drift Bot-Self-Emit | MH-7 | nicht in MH-5 |
Pattern-Source: gui/app/Filament/Pages/BaselineHoldings.php (RECON-2.3 — Operator-Custom-Page mit Action-Buttons + Hard-Confirm-Modal).
| Variante | Bestandteile | Komplexität |
|---|---|---|
| A — Page-only | 1 Custom Page ManagedHoldings mit allen 6 Actions inline | LOW |
| B — Resource-only ← empfohlen | ManagedProposalResource (CRUD-style mit Custom Actions) | MEDIUM |
| C — Hybrid | Page ManagedHoldings (Overview + Request-Action) + Resource (Listing + Approve/Reject) + Page für Pause/Resume/Release | HIGH |
Empfehlung: Option B (Resource-only) — Standard-Filament-CRUD-UX (Tabelle, Filter, Sortierung, Search) ohne Custom-Page-Boilerplate.
Per G-DR-7 (master_boundaries.md):
Operator-Multi-Step-Wizard für Promote: kein One-Click-Transfer; mindestens 5 Schritte inklusive Risk-Summary + Hard-Confirm
Approve-Action ist der einzige Wizard-Worthy Flow:
proposal_json)overall_score < 0.50)<asset>:<variant>:<sha8>Filament 3 unterstützt Wizard Component. Reject / Pause / Resume / Release / Request brauchen keinen Wizard — Modal-Action mit Form genügt.
| Command | UI-Stelle | Form |
|---|---|---|
| request | Filament-Resource Header-Action "Analyze new asset" | TextInput(asset) + TextInput(intent) |
| approve | per-row Action auf Proposal (Wizard 5 Steps) | Wizard mit form/sections |
| reject | per-row Action auf Proposal | Textarea(reason) + TextInput(hard_confirm) |
| pause | per-row Action auf managed-asset | Confirm-Modal, kein Hard-Confirm |
| resume | per-row Action auf managed_paused-asset | Confirm-Modal |
| release | per-row Action auf managed-asset | Select(strategy) + TextInput(hard_confirm) |
| Option | Inhalt | Empfehlung |
|---|---|---|
| 1 | Alle 6 Actions ENABLED. Worker (pre-MH-6) marked unknown command_type als failed. Safe failure path — kein state-touch. | — |
| 2 | Alle 6 Actions DISABLED mit Tooltip "Worker-Handler aktiviert sich erst in MH-6". UI sichtbar aber nicht triggerbar. | EMPFOHLEN |
| 3 | Read-only Listing only — keine Action-Buttons. Actions kommen in MH-5-FU nach MH-6. | — |
Begründung Option 2: UI-Vollständigkeit für Operator-Review + Safety. MH-6 Closure-Phase entfernt das disabled=true Flag — minimal-invasiver Aktivierungs-Punkt.
ETH:recommended:a1b2c3d4"hard_confirm_input mit clientside required + serverside Service-ExceptionHardConfirmMismatchException → Filament catched → Notification::danger(...)Wizard Step 4 (nur sichtbar wenn score < 0.50):
ConfidenceOverrideRequiredException → Notificationreason (required, max 256 chars, mit Filament maxLength(256)-Validierung clientside + serverside via Service)hard_confirm <asset>:reject:<sha8>UI-Layer-Mainnet-Block (Layer 5 per master_boundaries §8):
environment='testnet' hardcoded (Service hardcoded auch)canAccess() zeigt UI nur an wenn Bot-Status environment='testnet'| Tabu | MH-5-Touch | Verdict |
|---|---|---|
| Kein command_worker | UI ruft NUR Service-Methoden | konform |
| Kein Bot-Code | trading/*.py bleibt unverändert | konform |
| Kein ProposalEngine/Writer-Aufruf aus GUI | Service hat das verboten; UI ruft Service | konform |
| Kein managed_state.json write | UI liest DB-Cache, Worker MH-6 schreibt JSON | konform |
| Kein baseline_holdings.json write | UI nicht beteiligt | konform |
| Kein runtime_config-touch | nicht im Scope | konform |
| Keine direkte Exchange/API-Aktion | UI nicht beteiligt | konform |
| Kein Mainnet | hardcoded testnet + Banner | konform |
| Kein Docker / Restart | reine PHP/Blade-Phase | konform |
| Komponente | Inhalt |
|---|---|
gui/app/Filament/Resources/ManagedProposalResource.php | List + View + Header-Action (Request) + per-row Actions (Approve/Reject) |
gui/app/Filament/Resources/ManagedProposalResource/Pages/ListManagedProposals.php | Tabelle mit state/asset/generated_at/expires_at columns + filters |
gui/app/Filament/Resources/ManagedProposalResource/Pages/ViewManagedProposal.php | Detail-View des proposal_json (Risk-Recommendation, Confidence, Market-Context) |
gui/app/Filament/Pages/ManagedAssets.php | Operator-Page für Asset-Level Actions (Pause/Resume/Release per Asset) |
gui/app/Filament/Resources/ManagedAssetHistoryResource.php (optional) | Read-only Audit-Trail-Listing |
| Action | Form | Hard-Confirm | Disabled bis MH-6? |
|---|---|---|---|
| Request (header) | asset + intent | NEIN | JA (Empfehlung) |
| Approve (per-row, Wizard) | asset/variant/overrides/confidence_override/hard_confirm | <asset>:<variant>:<sha8> | JA |
| Reject (per-row) | reason + hard_confirm | <asset>:reject:<sha8> | JA |
| Pause (per-asset) | confirm modal | NEIN | JA |
| Resume (per-asset) | confirm modal | NEIN | JA |
| Release (per-asset) | strategy + hard_confirm | <asset>:release:<strategy> | JA |
Flow A: Request a managed proposal
Operator → ManagedProposalResource Header-Action "Analyze new asset"
→ Modal: TextInput(asset) + TextInput(intent)
→ Submit → ProposalService::createRequestCommand
→ Notification "Command queued"
→ Resource Table refreshes (new row pending Worker fill)
Flow B: Approve a proposal (Wizard)
Operator → ProposalResource per-row Action "Approve"
→ Wizard Step 1: Risk Summary (read-only display)
→ Step 2: Variant Select
→ Step 3: Overrides (4 optional TextInputs)
→ Step 4: Confidence Display + Override Checkbox (if score<0.50)
→ Step 5: Hard-Confirm TextInput
→ Submit → ProposalService::createApproveCommand
→ Notification + redirect
Flow C: Pause/Resume/Release (per-asset)
Operator → ManagedAssets Page → per-row Action
→ Pause/Resume: Confirm-Modal, single submit
→ Release: Select(strategy) + Hard-Confirm
→ Submit → ManagedStateService::create*
→ Notification
// In Action callable: app(ProposalService::class)->createRequestCommand(...) app(ProposalService::class)->createApproveCommand(...) app(ProposalService::class)->createRejectCommand(...) app(ManagedStateService::class)->createPauseCommand(...) app(ManagedStateService::class)->createResumeCommand(...) app(ManagedStateService::class)->createReleaseCommand(...)
Erlaubt: nur Service-Methoden + Filament-Standards (Action/Notification/Form/Wizard).
Verboten: direct Eloquent-Mutation auf managed_proposals / managed_assets_history.
| Test-Klasse | Anzahl | Inhalt |
|---|---|---|
| ManagedProposalResourceCanAccessTest | 3 | Admin allowed · Operator denied · Anonymous denied |
| ManagedProposalResourceListingTest | 5 | Empty list · multiple proposals shown · state filter · asset filter · pagination |
| ManagedProposalResourceViewTest | 4 | Detail-View shows proposal_json fields · confidence · market_context · risk_recommendation |
| RequestActionTest | 6 | happy path triggers Service · invalid asset rejected · disabled-tooltip visible (MH-6-gate) · notification on success · empty input · trim |
| ApproveWizardTest | 10 | all 5 steps · variant select · overrides whitelist · confidence-override conditional display · hard-confirm validation · Service call · Notification on success · cancel returns to list |
| RejectActionTest | 6 | happy path · reason required · max-length · hard-confirm validation · Service call · Notification |
| PauseActionTest | 4 | confirm modal · Service call · notification · disabled-tooltip |
| ResumeActionTest | 4 | analog Pause |
| ReleaseActionTest | 6 | strategy select · hard-confirm validation · Service call · 2 strategies · disabled-tooltip · Notification |
| MainnetBannerTest | 2 | Banner visible · "testnet only" text |
| DisabledByMh6GateTest | 6 | all 6 actions show "Worker MH-6 not deployed" tooltip · disabled flag set |
| AuditEventVisibilityTest | 3 | managed.* audit events visible · subject_type filter · per-asset filter |
| Total | ~59 Tests | (Filament-UI-Tests sind heavier als pure Service-Tests) |
| Datei | Status |
|---|---|
gui/app/Filament/Resources/ManagedProposalResource.php | NEU |
gui/app/Filament/Resources/ManagedProposalResource/Pages/ListManagedProposals.php | NEU |
gui/app/Filament/Resources/ManagedProposalResource/Pages/ViewManagedProposal.php | NEU |
gui/app/Filament/Pages/ManagedAssets.php | NEU |
gui/app/Filament/Resources/ManagedAssetHistoryResource.php (optional) | NEU |
Tests in gui/tests/Feature/Filament/Managed* | NEU |
gui/app/Services/Managed/ProposalService.php (MH-4b komplett intact)gui/app/Services/Managed/ManagedStateService.php (MH-4c komplett intact)Erwartete LOC: ~600-900 Resource + Pages + Forms + ~1200-1500 Tests = ~2000-2400 LOC.
| ID | Stop wenn… |
|---|---|
| MH-5-SR-1 | Filament-Code ruft direkt ManagedProposal::create oder ManagedAssetHistory::create (muss über Service) |
| MH-5-SR-2 | Filament-Code touched managed_state.json / baseline_holdings.json / risk_proposals/ |
| MH-5-SR-3 | Filament-Code ruft Engine / Writer / Reader (Python-Bot-Side) |
| MH-5-SR-4 | Filament-Code ruft command_worker (Python-Subprocess) |
| MH-5-SR-5 | Action akzeptiert environment != 'testnet' |
| MH-5-SR-6 | Approve-Action ist Single-Click (muss Wizard mit ≥5 Steps sein, G-DR-7) |
| MH-5-SR-7 | Hard-Confirm Validierung ist case-insensitive |
| MH-5-SR-8 | Action ist für non-Admin sichtbar (UserRole::Admin gating) |
| MH-5-SR-9 | Mainnet-Banner fehlt |
| MH-5-SR-10 | Action-disabled-by-MH-6-Gate fehlt (Empfehlung Option 2) |
| MH-5-SR-11 | Wizard erlaubt strategy_group / variant Override (G-DR-3 Q-MH-3) |
| MH-5-SR-12 | Filament-Form-Validierung umgeht Service-Layer-Validierung |
| Aktion | Pflicht? | Begründung |
|---|---|---|
| pg_dump GUI-DB | NEIN | keine Migration; reine UI-Phase |
| State-Files snapshot | NEIN | kein State-Touch |
| DB Migration | NEIN | MH-4a Schema bleibt unverändert |
| Bot-Restart | NEIN | kein Bot-Code-Touch |
| Worker-Restart | NEIN | command_worker.py unverändert |
| docker cp | NEIN | PHP via Laravel Live-Volume mount |
| GUI Cache-Clear | JA | php artisan config:clear && php artisan route:clear && php artisan view:clear nach Filament-Resource-Add (Filament-Caching) |
→ MH-5 = Reine UI-Code+Test+Commit Phase + GUI-Container Cache-Clear.
| # | Risiko | Severity | Mitigation |
|---|---|---|---|
| R1 | Wizard ist UX-komplex — Filament Wizard-Component hat Edge-Cases | MEDIUM | Pattern-Source BaselineHoldings zeigt Modal-mit-Multi-Form-Sections; Wizard-Tests deck large surface |
| R2 | Hard-Confirm-String wird gecopy-pastet statt getippt → kein "Awareness-Check" | LOW | Akzeptable Default: TextInput + visual verify |
| R3 | Operator klickt Approve im Wizard, vergisst Step 4 (Confidence) | LOW | Wizard Step::completedIcon + disabled-bis-completed. Falls submit + Service throws ConfidenceOverrideRequiredException → Notification + zurück zu Step 4 |
| R4 | Worker pre-MH-6 marked Commands als failed/rejected → Operator-Verwirrung | MEDIUM | UI zeigt Tooltip "Worker handler activates in MH-6"; Empfehlung Option 2 (disabled until MH-6 closure) |
| R5 | Filament-Notification spam wenn Operator schnell klickt | LOW | Same-second idempotency in Service returnt existing — UI sieht "same command returned" und unterdrückt 2nd notification |
| R6 | Resource-Listing zeigt stale Daten weil Worker MH-6 nicht läuft | LOW | UI-Refresh-Button + Auto-Polling alle 10s |
| R7 | proposal_json Display-Drift wenn Engine V2 neue Fields hinzufügt | LOW | JsonInfolistEntry zeigt raw JSON; Wizard-Steps only read specific fields (graceful degradation) |
| R8 | UserRole::Admin canAccess()-Drift | LOW | Test pinned (existing pattern) |
| R9 | Filament Wizard erlaubt browser-back-navigation mit stale state | LOW | Filament 3 handles wizard-state per-form; akzeptabel |
| R10 | Tests sind UI-fragil (Filament-Internals changes) | MEDIUM | Use Filament Test-Macros (->assertActionExists, ->callAction); avoid DOM-snapshot tests |
| Variante | Inhalt | LOC | Tests | Risk |
|---|---|---|---|---|
| MH-5-monolithic | Resource + Pages + Wizard + alle 6 Actions + Tests | ~2400 | ~59 | MEDIUM |
| MH-5a ← empfohlen | Resource Listing + View (read-only, kein Action) | ~800 | ~20 | LOW |
| MH-5b (folgt) | Request + Reject Actions (einfach, kein Wizard) | ~500 | ~15 | LOW |
| MH-5c (folgt) | Approve Wizard (5 Steps, complex) | ~700 | ~15 | MEDIUM |
| MH-5d (folgt) | Pause/Resume/Release Actions (ManagedAssets Page) | ~600 | ~15 | LOW |
Begründung:
Alternative bei Operator-Wunsch nach Full-Phase → MH-5-monolithic mit allen 6 Actions disabled-bis-MH-6 via Tooltip + UI-Flag. Akzeptabel — keine Live-Trigger-Risk.
disabled=true Flag in Resource oder via Feature-Flag/env? ← Empfehlung hardcoded disabled + Tooltip (einfacher revert in MH-6)| Aspekt | Bewertung |
|---|---|
| LOC | ~500 Resource + ~300 Tests = ~800 |
| Tests | ~20 |
| Komplexität | LOW (Standard Filament-Resource ohne Actions) |
| Blast-Radius | NULL — read-only auf DB-Cache; keine Service-Aufrufe; 0 Commands |
| Roll-Back-Cost | minimal: git revert + 0 DB-Rows verändert |
| Dependencies-Klärung | UI-Architektur (Resource vs Page) |
| Backup-Pflicht | NEIN |
| Migration-Pflicht | NEIN |
| Restart-Pflicht | NEIN |
| Mainnet-Touch | NEIN |
| Cache-Clear | JA (Filament-Resource-Add) |
| docker cp | NEIN |