Repository navigation
Add isolated TUI device control with native ask inspection and revoke - #6294
Conversation
|
Source review at
Please compare normalized optional item IDs for equality, including missing/null, before any navigation/signature; a bound lifecycle requires the identical bound command item. Keep legitimate fully unbound cases consistent with the product contract. Add real shipped-reducer/UI refusal tests for bound lifecycle A plus absent/null command item and target B, asserting unchanged navigation and no result/signature, as well as matching A positive coverage. Existing tests only mutate wrong-item when BOTH lifecycle and command grant contain an item, so they do not cover this cut. This is a static source counterexample, not an observed live access violation; daemon admission is a separate authority and must remain checked. Please have the source owner correct/rerun at the final head under the existing admitted/isolated-job rules (do not mutate a checkout while its job is queued/running). No live fixture/device action requested. |
Problem
The terminal client has no device-command consumer, run indicator or enrollment revoke control. An isolated client needs to consume the shared bounded-command protocol without gaining message or answer authority.
Goal
Implement client-side grant/run/device/session/actor/verb/screen/window/budget checks; sign renderer-visible state with the paired P-256 key and shared canonical form; show the active run and a global enrollment-revoke binding.
Decisions
Seed
The shared seed is an open native ask: attention_kind=person-step, presentation.kind=request, from the fixture agent to the fixture person. request.question carries the seeded body. The journey is NowRoot → the ask's existing Attention screen → inspect. No Conversation navigation is part of the journey, and normal inbox policy is unchanged.
Source checks of the shipped UI:
Title/question are each printable ASCII, at most 60 characters, one paragraph, with no Markdown syntax, JSON, leading/trailing/repeated whitespace. Digest is lowercase hex SHA-256 of exact question bytes. Added a shipped-card terminal-render test including the 60-character boundary.
Forbidden during journeys: Yes/No, named answers, Nothing to do, answer/close/dismiss/Mark read/send controls, TUI answer keys y/n/a/x/c and Enter while answering, and all confirmation actions. Inspection/navigation never invokes these controls.
Verification
gate-slot --lane build --max-wait 1800 -- nix develop --no-write-lock-file --command cargo test --locked -p fractal-tui client_control. The request recorded prerequisite source b6c0d55 before the final commits; no check ran against any source head. Define canonical client command result contract #6274's generated canonical/result sources are also not available yet. No Rust compilation/test success is claimed.Complexity
One bounded adapter module, one existing-UI status/render integration, and a separate-process terminal-capture verifier. Uses the existing private SDK profile and generated canonical form.
Concerns
Draft dependency stack: #6293 and #6274's generator output/daemon integration must land before this is build-ready. The local Rust gate is not evidence until admitted and completed. Enrollment/bootstrap, independent fixture manifest/canary checks and live journey acceptance remain separately gated.
Friction & bottlenecks
Generated dependencies are waiting for shared build admission. Managed dependent-base PR creation was correctly refused; this side chain was submitted through gh stack. The release-note validator is a Python function, not a validate CLI subcommand.
Follow-ups
Integrate the generated canonical head and record admitted Rust test evidence. No deployment or enrollment is authorized by this source PR.
References
Depends on #6293; canonical source in #6274. No FPL-held source paths changed.
Published source
TUI head:
a4107410bbac9dcfe1a484632844282c421a0e9b. SDK prerequisite head:62adcce869fbbbf6f21eccbdf19fd5cd997277b5. Both are signed source commits. Source-only; not enrolled or activated.Read-only identity observer
Signed append-only head
1f8c81a51bd06e8df914b07eb783bd16b792354daddsfractal tui client-control identity --profile PATH --json. It loads exactly one fixture command pairing with Profile::load, refuses the normal profile (including symlink aliases), and emits canonical P-256 public key, SHA-256 fingerprint of its uncompressed 65-byte SEC1 point, device id, session actor, and the full raw profile snapshot. Only pkcs8 and credential are replaced by{redacted: "[REDACTED]", sha256: ...}over the original UTF-8 string. No pairing, network request, or save occurs. Tests cover exact output fields, preservation of other fields, no secret output, changed-secret hashes, normal/symlink and multiple-pairing refusal, and unchanged profile mtime and content hash.Rust checks for this head have been requested on dev5 in one gate ticket (
--lane build --profile disk=cargo-warm --max-wait 10800); no success is claimed while admission is pending.Generated dependency integration
Signed append-only merge integrates canonical generated head
36592f7090093ae6fe94a87706e319fca78fca17; current head3d51f91ce34502fb9ef262404c4675104a071222. No generated file was hand-edited. One exact-head dev5 gate ticket requests the relevant Rust checks with--lane build --profile disk=cargo-warm --max-wait 10800; result pending. The prior pre-generation identity ticket was canceled, not executed.Final generated lifecycle cutover
Current signed head
54adebdd168f53d7d88d3fa43492c4cfd36c04f0integrates final canonical generated head7cafdf138efbea937cbefa83323d5d2fc8dda15cappend-only. Supersedes earlier generated-integration and pending-head notes. Both intermediate gate tickets were canceled before admission, so no Rust execution is claimed for them.The temporary lifecycle field adapter is removed: the reducer decodes/stores the generated ClientControlGrantLifecycle type. Lifecycle drives the indicator and terminal latch; each command must match active lifecycle context and checks its embedded control_grant policy. The shipped reducer consumes shared fixtures/clients/client-control-lifecycle-v1.json traces, including stale/duplicate starts, item mismatch, terminal finality and missing lifecycle refusal. Independent identity helper source and sanitized profile snapshot remain included.
One final-head dev5 gate ticket now requests
cargo test --locked -p fractal-tui client_controlthroughgate-slot --lane build --profile disk=cargo-warm --max-wait 10800 -- nix develop --no-write-lock-file --command .... Receipt pending; no success claimed.Final sequence and item-binding revision
Current head
e9f65833172818c8c93a34b24d22f726b4223cb9includes signed merge of regenerated canonical head6fb398ccf5f0b7c08ea0cd1892aa26fdb7a2c006. Previous bg318 (TUI) and bg319 (SDK) ended queue-only without payload or exit-code receipts: both NOT RUN. These are not passing or failing Rust executions.An independent source counterexample exposed missing/null command item binding under a bound lifecycle. Fixed with exact normalized optional-item equality before navigation/signing. Attention additionally requires a nonempty item, while fully unbound NowRoot remains supported. Shipped reducer plus native-ask UI tests cover absent/null/explicit-B commands targeting B under lifecycle A, unchanged navigation/no result/signature, positive A, and unbound Attention refusal. Shared traces include the final invalid-sequence expectation. Daemon admission was not changed.
One new exact-head dev5 ticket is pending with the current xvrpad67 gate-slot helper and
--lane build --profile disk=cargo-warm --max-wait10800. No Rust success claimed until its receipt.Current source and exact-head checks
Current signed head
b0a77fa0ee62eee39a3b8ecb61ec1938279a659bintegrates corrected canonical972b65b7c4cf8e3612ffdd4d756e11d0b7b011f2. Superseded tickets bg419/bg420 were withdrawn while queued with SIGUSR2 and both exited94: NOT RUN, no payload. New exact-head dev5 ticket requests the same crate test command through xvrpad67 gate-slot. Receipt pending.FPL accepted the item-binding counterexample fix at f994aa1. The requested P3 hardening is also included: non-null/non-string item_id is refused before navigation/signing; item_id:5 is covered through shipped UI and result path.
Admission receipt
The first current-head dev5 ticket expired before admission after10800seconds with exit94: Rust tests NOT RUN, no nix/cargo payload executed. The single authorized replacement requests the identical command at the unchanged current head; pending. This is an admission constraint, not a passing or failing test result.
Posted on behalf of @schickling
agent_identitysessionagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimeagent_modelworktree