also looking at this
feat: coordinate modeled two-carrier cargo handover
#103
25 files
+1654
-13
| @@ -0,0 +1,117 @@ | ||
| 1 | # Two-carrier modeled cargo handover | |
| 2 | ||
| 3 | `simulateCargoFleet()` in `resources/functions/drone/cargo/fleet.ts` runs two actual | |
| 4 | retained vehicle sessions on the same 4 ms clock. One source point parcel falls onto | |
| 5 | a station, follows a finite powered rail, enters an initially empty receiving body, | |
| 6 | and then flies the receiver's own delivery and return route. | |
| 7 | ||
| 8 | This is a bounded fictional simulation, with physical outputs inhibited. It does not | |
| 9 | qualify an aircraft, station, recipient identity, electrical endurance or BVLOS service. | |
| 10 | The [single-carrier guide](cargo-delivery.md) retains the wider operations evidence case. | |
| 11 | ||
| 12 | ## Native command and exit status | |
| 13 | ||
| 14 | ```sh | |
| 15 | ./buddy cargo:fleet | |
| 16 | ./buddy cargo:fleet --scenario receiver-primary-link-loss | |
| 17 | ./buddy cargo:fleet --scenario receiver-both-links-loss | |
| 18 | ./buddy cargo:fleet --scenario receiver-host-loss-before-intake | |
| 19 | ./buddy cargo:fleet --scenario intake-receipt-loss | |
| 20 | ./buddy cargo:fleet --scenario receiver-joint-shift-before-intake | |
| 21 | ``` | |
| 22 | ||
| 23 | The command emits one JSON line, at most 16 KiB. Exit 0 means the modeled routes and | |
| 24 | captured custody completed. Exit 2 retains an incomplete modeled outcome. Exit 1 means | |
| 25 | invalid input, execution or output failure. The standalone `drone cargo:fleet` command | |
| 26 | uses the same native Stacks definition. `cargoFleetSummary(run)` projects observed | |
| 27 | results without serializing the full runtime journals. | |
| 28 | ||
| 29 | The library accepts only an optional own-data `scenario` declaration from this finite | |
| 30 | set. It does not yet accept arbitrary fleet geometry, vehicle count or hardware transports. | |
| 31 | ||
| 32 | ## One world, two authority owners | |
| 33 | ||
| 34 | Carrier A uses raw boot 101 and authority session 201. Carrier B uses raw boot 102 and | |
| 35 | session 202. Both use the fixed synthetic WGS84 origin 0, 0, 100 and LOCAL_NED, with down | |
| 36 | positive. These are distinct model identities, not authenticated identities or distributed | |
| 37 | clock qualification. Each retains its own raw IMU/GNSS pipeline, estimator, mission, | |
| 38 | controller, output watchdog and primary/backup radio observer. | |
| 39 | ||
| 40 | A begins at [0, 0, -0.1] m with a 0.1 kg body-forward point at 0.08 m. B begins at | |
| 41 | [3, 2, -0.1] m with a declared empty joint. The first site is [3, 0, 0] m and the final | |
| 42 | recipient site is [6, 2, 0] m, each with a 0.35 m horizontal acceptance disc. Both bodies | |
| 43 | use the declared flat -0.1 m ground datum; the parcel capture plane is down 0. No landing | |
| 44 | gear, collision/contact geometry, wind/weather envelope or surveyed field is inferred. | |
| 45 | ||
| 46 | The receiving task holds its declared pad with neutral motor commands from its first | |
| 47 | frame. It does not preload mass. Flight policy consumes the owned estimator and modeled | |
| 48 | sensor captures. Physical joint geometry is used only inside the modeled mechanism's | |
| 49 | contact operation; it is not supplied as a flight-controller positioning oracle. | |
| 50 | ||
| 51 | ## Transfer and custody | |
| 52 | ||
| 53 | 1. A's existing release coordinator requires current observed site/recipient/load evidence | |
| 54 | and its own mission scope. The world checks actual same-epoch host availability, | |
| 55 | supervisor boot/session, current lease, recent policy and pending command before separation. | |
| 56 | 2. The actual separation event supplies the point to the [station actor](cargo-station.md). | |
| 57 | Free fall retains the within-step impact epoch, impulse and mechanical loss. Only after | |
| 58 | A confirms station custody does the rail start toward B's declared current joint. | |
| 59 | 3. B's intake coordinator requires 26 distinct qualified captures spanning at least 500 ms, | |
| 60 | its boot/reference, healthy estimator/gyro, conservative pad uncertainty, contact, stopped | |
| 61 | motors, a clear site and the captured ready-station parcel/source event. It issues one | |
| 62 | modeled grant, valid for at most 40 ms and within the pending task deadline. | |
| 63 | 4. On a later 4 ms epoch the mechanism independently checks B's actual host availability, | |
| 64 | current supervisor boot/session/lease, recent policy, exact pending command and neutral | |
| 65 | outputs. It consumes the station's departure once and calls actual `attachParcel` at | |
| 66 | B's current joint. A refused point enters the world's separate loose-parcel actor and continues | |
| 67 | ballistic motion to the declared capture plane. It is not copied back, repositioned | |
| 68 | onto the joint or silently retried. | |
| 69 | 5. A later B sensor capture must report that actual intake event, source event, mass and | |
| 70 | mechanism epoch. Its capture pose and command scope produce the receipt ACK. Requesting | |
| 71 | or granting intake is not confirmation. Only then does B take off with changed mass/CG, | |
| 72 | release the point at the final site and complete captured recipient custody and landing. | |
| 73 | ||
| 74 | The grant's session declaration alone cannot establish authority. The physical-world | |
| 75 | check uses the live retained runtime at the actual operation epoch. Host loss can leave | |
| 76 | an old supervisor snapshot saying `autonomous`; it still blocks the intake mechanism. | |
| 77 | ||
| 78 | Physical ownership and captured custody are separate records. The world mass ledger reads | |
| 79 | the actual body/actor masses after transitions and at 20 ms intervals. It retains one | |
| 80 | 0.1 kg point and 3.1 kg total mass, with reported maximum numerical error. Historical | |
| 81 | separation/departure records are evidence copies, not additional physical owners. The | |
| 82 | station reports mechanical work; each vehicle's reserve remains the shared longest-path | |
| 83 | **declared power budget**, not measured Wh or an electrical model. | |
| 84 | ||
| 85 | ## Bounded model cases | |
| 86 | ||
| 87 | | Scenario | Expected result | Parcel and authority outcome | | |
| 88 | | --- | --- | --- | | |
| 89 | | `nominal` | Completed | A to station to B to final parcel, with three separate captured custody stages | | |
| 90 | | `receiver-primary-link-loss` | Completed | Receiver primary stops during station handling; its independently captured backup preserves authority | | |
| 91 | | `receiver-both-links-loss` | Incomplete | Receiver link freshness expires and authority fails; finite station braking retains the parcel while A continues | | |
| 92 | | `receiver-host-loss-before-intake` | Incomplete | Host stops 4 ms after the actual grant; no physical intake, independent board expiry and station retention | | |
| 93 | | `receiver-joint-shift-before-intake` | Incomplete | A 0.4 N force for one 4 ms step shifts the actual joint before intake; strict coincidence refuses it, the loose point falls, and B lands its counted alternate empty | | |
| 94 | | `intake-receipt-loss` | Incomplete | Actual intake occurs but its receipt fields are withheld; B retains the mass and lands its counted alternate without claiming custody or making a second delivery | | |
| 95 | ||
| 96 | Radio observations retain capture, receipt, sequence and scope, with 1 ms clock uncertainty | |
| 97 | and 20/40 ms primary/backup delays. Failure stops new packets rather than restamping a | |
| 98 | connected fixture. Link loss takes effect through the declared freshness contract. | |
| 99 | Vehicle host termination retains a 1,000 ms independent board/plant tail. The other peer | |
| 100 | continues its own mission. Both routes and their failure alternatives count toward the | |
| 101 | native finite graph/reserve budget; the world is bounded by the 180 s host limit and tails. | |
| 102 | ||
| 103 | ## Evidence and remaining work | |
| 104 | ||
| 105 | `tests/unit/cargo-fleet.test.ts` exercises actual two-session physics, intake mass changes, | |
| 106 | source/receiver scopes, same-epoch admission, captured receipt ordering, retained mass, | |
| 107 | backup continuation, both-link braking, the host/grant gap and uncertain loaded diversion. | |
| 108 | `tests/unit/cargo-fleet-cli.test.ts` executes the native Buddy command and its bounded wire. | |
| 109 | `scripts/qualify-cargo-fleet-cli.ts` exercises all six cases through a copied standalone | |
| 110 | binary outside the checkout and retains output hashes and factual outcomes. | |
| 111 | ||
| 112 | These cases do not cover a complete fleet fault envelope. Receiver/source kill or manual | |
| 113 | intervention at every phase, navigation degradation and containment across the transfer, | |
| 114 | late/foreign/replayed receipt campaigns, explicit operator cancellation/recovery, durable | |
| 115 | whole-world checkpoints, general rendezvous, collision avoidance and richer fleet planning | |
| 116 | remain open under [#25](https://github.com/stacksjs/drone/issues/25) and its dependencies. | |
| 117 | The wider measured hardware, endurance and operational evidence requirements remain open. | |