feat(queen-doctor): autonomous Queen↔Doctor loop over canonical bus#506
Open
feat(queen-doctor): autonomous Queen↔Doctor loop over canonical bus#506
Conversation
Closes the human-out-of-the-loop circuit between the Queen daemon and
the Doctor daemon by extending the existing trios-server WS bus with two
new BusEvent variants and a small pair of long-running clients.
Loop:
Queen --queen/order--> trios-server --BusEvent::QueenOrder--> Doctor
Doctor --doctor/report--> trios-server --BusEvent::DoctorReport--> Queen
Server (`crates/trios-server/src/ws_handler.rs`)
• +BusEvent::QueenOrder { order_id, action, target_agent, params, ts }
• +BusEvent::DoctorReport { order_id, agent_id, status, summary,
diagnosis, ts }
• +RPC methods "queen/order", "doctor/report"
• +helpers queen_order_publish, doctor_report_publish
• +4 unit tests (broadcast roundtrip, missing-field rejection)
Doctor (`crates/trios-doctor/src/doctor_loop.rs`, new bin trios-doctor-loop)
• Subscribes to /ws, filters QueenOrder where target_agent="doctor".
• For "doctor scan" / "doctor quick" / "doctor heal" calls the real
`Doctor::run_all()` and maps Red/Yellow/Green to the report status.
• Auto-reconnect with TRIOS_DOCTOR_RECONNECT_SECS (default 5).
Queen (`crates/trios-queen-loop`, new crate)
• Connects to /operator with $TRIOS_OPERATOR_TOKEN.
• Reads `.trinity/queen/{policy,actions}.json` from workspace root.
• Filters actions level <= policy.max_auto_level (default 3) and
starting with "doctor ".
• Picks deterministically: (epoch_secs / tick) % candidates.len().
• Sends queen/order, tracks order_id in VecDeque<64>, correlates the
matching DoctorReport.
• Tick interval TRIOS_QUEEN_TICK_SECS (default 60s).
Verification (`crates/trios-queen-loop/tests-e2e/smoke_queen_doctor_loop.py`)
Live end-to-end smoke against a running trios-server confirms both
halves of the loop close — order_id correlates exactly between the
outgoing Queen frame and the incoming Doctor report:
[doctor] queen_order=f1b7991e-… → sent doctor/report
[queen] DoctorReport: status=green, order_id=f1b7991e-…
RESULT: GREEN — Queen↔Doctor loop closed end-to-end via real WS bus
Test runs:
• cargo check -p trios-server -p trios-doctor -p trios-queen-loop → green
• cargo build --bins (all three) → green
• cargo test -p trios-server --bins ws_handler → 16/16
• cargo test -p trios-doctor --lib → 9/9
• python3 smoke_queen_doctor_loop.py → GREEN
Constitutional anchors: φ² + φ⁻² = 3
L1 no .sh files (pure Rust)
L11 every order carries a soul field, default "SCARABS"
L14 Agent trailer present
L21 broadcast bus is append-only
L24 agents speak only via the canonical bus
Soul: Scarab Smith
Agent: SCARABS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Что это
Реальная автономная петля Королева ↔ Доктор через канонический bus
trios-server. Без человека-толкача между приказом и отчётом.Изменения
crates/trios-server/src/ws_handler.rscrates/trios-doctor/src/doctor_loop.rs(new bintrios-doctor-loop)crates/trios-queen-loop/(new crate)crates/trios-queen-loop/tests-e2e/smoke_queen_doctor_loop.pyServer (
ws_handler.rs)+BusEvent::QueenOrder { order_id, action, target_agent, params, ts }+BusEvent::DoctorReport { order_id, agent_id, status, summary, diagnosis, ts }+RPC methods—"queen/order","doctor/report"+pub async fn queen_order_publish/doctor_report_publish— broadcast helpersDoctor (
crates/trios-doctor)Новый бинарь
trios-doctor-loop:/ws, фильтруетQueenOrderгдеtarget_agent="doctor"doctor scan|quick|healзовёт настоящийDoctor::run_all()→WorkspaceDiagnosis, мапит Red/Yellow/Green в статус отчётаdoctor/reportобратно с тем жеorder_idTRIOS_DOCTOR_RECONNECT_SECS(default 5s)Queen (
crates/trios-queen-loop)Новый крейт-демон (workspace member):
ws://127.0.0.1:9005/operator?token=$TRIOS_OPERATOR_TOKEN.trinity/queen/{policy,actions}.jsonиз рабочей директорииlevel ≤ policy.max_auto_level(default 3) иначинающиеся с
doctor(epoch_secs / tick) % candidates.len()— безперсистентного состояния
order_idвVecDeque<64>, коррелирует входящиеDoctorReportTRIOS_QUEEN_TICK_SECS(default 60s)Verification (всё зелёное)
E2E smoke против работающего сервера на 9005:
order_idкорректно коррелирует между исходящим приказом Королевы ивходящим отчётом Доктора.
Constitutional compliance · φ² + φ⁻² = 3
.shsoul(defaultSCARABS)Agent: SCARABStrailer присутствует/wsи/operator,никаких sibling-сокетов
Как поднять
С этого момента петля автономна: Королева раз в минуту шлёт
doctor scan,Доктор отчитывается, Королева логирует и шлёт следующий приказ.
Soul: Scarab Smith
Agent: SCARABS