You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem — A shared peer (a different operator's machine) can't be controlled: there is no request→approve flow routed to the peer's lifecycle-admin authority, and no pending-request surface. Self-owned control (the #1540 fast-path) doesn't cover the cross-operator case. Approach — A control-request that routes to wherever the target's lifecycle-admin authority is held; a pending-request surface on that authority machine; approve → issueLifecycleGrant("control") + deliver the token. The requester side reuses slice 4's Request-control affordance; enforcement reuses slice 1's grant model. A headless shared target is approved from its authority holder's UI. Scope — in: request routing + pending-request surface + approve/deny → control grant issuance for shared peers. · out: the self-owned path (slice 1); the write plane (slice 2). Assumptions — #1541 provides the lifecycle-admin authority + grant issuance; #1544 provides the Request-control affordance + a pending-requests view in Fleet Manager.
Warning
Deliberate-review corrections (2026-09-24) — these BIND over any stale text below.
Approval is a NEW evaluateControlBootstrap (shared arm), not an extension.evaluateObserveBootstrap refuses a control outcome; re-establish the "shared never borrows the self-owned fast-path (no privilege bleed)" invariant in the new control-scoped decision.
Split AC1 into (a) routing/addressing (needs the named endpoint + resolvable authority) and (b) fail-closed denial-until-approved. Restate AC4 "the target renders nothing" as the backend-testable enforcement invariant (a headless target only runs enforceScopeForRequest; "renders nothing" is a Fleet Studio B2b · slice 4 — Control UI: enable, driving banner, fail-closed affordances #1544 UI property).
Full record: ADR 0034 D3.
Acceptance Criteria
A shared peer's control request routes to that peer's lifecycle-admin holder and is denied until approved.
The authority machine sees a pending request and can approve or deny it.
Approval mints a control grant + delivers the token; the requester can then Enable control.
A headless shared target's request is approvable from its lifecycle-admin holder's UI — the target renders nothing.
Deny (or no response) leaves the requester without control — fail-closed.
Testing Decisions
Extend fleet_two_peer_e2e with a shared (non-self-owned) path. Reuse the grant-issuance unit suite (fleet_control_lifecycle). Add request-routing and approve/deny tests. Extends #1541's grant model and #1544's Request-control surface — the cross-slice edges.
Key Decisions
The request routes to the lifecycle-admin authority, not the target when the target is headless — this is what makes headless shared control possible.
Approval is the explicit target-side authority act (the evaluateObserveBootstrapshared path extended to control), never automatic.
Constraints & Invariants
The shared path never borrows the self-owned fast-path (no privilege bleed).
Headless target enforces only — approval renders on the authority machine.
Fail-closed — no approval, no control.
Prior Art
Read first (modules): fleet_observe_bootstrap (the shared-path decision to extend to control), fleet_control_lifecycle (issueLifecycleGrant / readmitPeer), and the outputs of slice 1 (authority seeding) + slice 4 (Request-control affordance + pending-requests view).
Important
Problem — A shared peer (a different operator's machine) can't be controlled: there is no request→approve flow routed to the peer's
lifecycle-adminauthority, and no pending-request surface. Self-owned control (the #1540 fast-path) doesn't cover the cross-operator case.Approach — A control-request that routes to wherever the target's
lifecycle-adminauthority is held; a pending-request surface on that authority machine; approve →issueLifecycleGrant("control")+ deliver the token. The requester side reuses slice 4's Request-control affordance; enforcement reuses slice 1's grant model. A headless shared target is approved from its authority holder's UI.Scope — in: request routing + pending-request surface + approve/deny →
controlgrant issuance for shared peers. · out: the self-owned path (slice 1); the write plane (slice 2).Assumptions — #1541 provides the
lifecycle-adminauthority + grant issuance; #1544 provides the Request-control affordance + a pending-requests view in Fleet Manager.Warning
Deliberate-review corrections (2026-09-24) — these BIND over any stale text below.
grep "control-request"→ nothing). Specify, as data contracts: (a) the request endpoint (e.g.POST /amicode/fleet/control-request), its payload + auth + the requester→authority-machine addressing hop; (b) the pending-request store (file/shape/state machine: pending → approved|denied → consumed). Neither Fleet Studio B2b · slice 1 — Grant foundation: Enroll seeds lifecycle-admin + self-owned control issuance #1541 (grant foundation, no UI) nor Fleet Studio B2b · slice 4 — Control UI: enable, driving banner, fail-closed affordances #1544 (UI view) provides these.lifecycle-adminholder" presupposes the persisted authority record + resolver that Fleet Studio B2b · slice 1 — Grant foundation: Enroll seeds lifecycle-admin + self-owned control issuance #1541 defines (todayauthorityIdentityKeyis only an injected predicate param — not resolvable). Make the Fleet Studio B2b · slice 1 — Grant foundation: Enroll seeds lifecycle-admin + self-owned control issuance #1541 dependency explicit for the resolver, not just for grant issuance.evaluateControlBootstrap(shared arm), not an extension.evaluateObserveBootstraprefuses a control outcome; re-establish the "shared never borrows the self-owned fast-path (no privilege bleed)" invariant in the new control-scoped decision.enforceScopeForRequest; "renders nothing" is a Fleet Studio B2b · slice 4 — Control UI: enable, driving banner, fail-closed affordances #1544 UI property).Full record: ADR 0034 D3.
Acceptance Criteria
lifecycle-adminholder and is denied until approved.controlgrant + delivers the token; the requester can then Enable control.lifecycle-adminholder's UI — the target renders nothing.Testing Decisions
Extend
fleet_two_peer_e2ewith a shared (non-self-owned) path. Reuse the grant-issuance unit suite (fleet_control_lifecycle). Add request-routing and approve/deny tests. Extends #1541's grant model and #1544's Request-control surface — the cross-slice edges.Key Decisions
lifecycle-adminauthority, not the target when the target is headless — this is what makes headless shared control possible.evaluateObserveBootstrapshared path extended tocontrol), never automatic.Constraints & Invariants
Prior Art
Read first (modules):
fleet_observe_bootstrap(the shared-path decision to extend to control),fleet_control_lifecycle(issueLifecycleGrant/readmitPeer), and the outputs of slice 1 (authority seeding) + slice 4 (Request-control affordance + pending-requests view).Source
docs/adr/0034-base-peer-studio-control.md), decision D3 (shared).Notes
Cross-operator authority → HITL. The deferrable slice — self-owned control (#1541→slice 2→slice 4) is fully usable without it.