feat(LinuxTentacleE2E): Phase 12.M.L.C.3 — register Polling flavor E2E
Summary
Section C breadth: Polling flavor exercises a different code path than Listening, with operator-meaningful differences.
| Aspect | Listening (C1.h) | Polling (this PR) |
|---|---|---|
| Mode resolution | no --comms-url
|
--comms-url set |
| Endpoint | /api/machines/register/tentacle-listening |
/api/machines/register/tentacle-polling |
| Registrar |
TentacleListeningRegistrar (bespoke HTTP) |
TentaclePollingRegistrar wraps TentacleRegistrationClient
|
| Payload field |
uri (listening URL) |
subscriptionId |
| Response validation | (none — gap caught by J.M.L.C.2) | EnsureRegistrationPayloadComplete |
Why ship-blocking
Without this pin, regressions in polling-specific code ship silently:
- Mode resolution flips →
--comms-urlignored, operator gets Listening flow when they wanted Polling - Endpoint path drift (
/tentacle-polling→/poll) → server returns 404 -
subscriptionIdfield renamed → server can't correlate dispatches to the agent
Pairs with C1.h to pin BOTH flavor branches
- C1.h: Listening +
/tentacle-listening+urifield - C2.h (this PR): Polling +
/tentacle-polling+subscriptionIdfield
Assertions
| Assertion | Pins |
|---|---|
exitCode == 0 |
Polling registrar succeeds with valid response |
Stub path = /api/machines/register/tentacle-polling
|
Endpoint contract |
X-API-KEY header propagation |
Auth contract (parity with Listening) |
Payload contains subscriptionId (Polling-specific) |
Field-presence positive |
Payload does NOT contain uri (Listening-specific) |
Field-presence reverse-assert (no flavor confusion) |
Config persisted with stub's ServerThumbprint
|
TLS pinning material round-trip |
Fidelity tier
--comms-url arg + expected endpoint + payload field assertions.
Expected runtime: ~1-2s.
Test plan
-
Linux E2E workflow runs (manual workflow_dispatchafter merge) -
C2h_RegisterPolling_HitsPollingEndpointAndPersistsConfigpasses within ~3s -
No regression on existing 35 Linux E2E tests