Azure / Azure/azure-functions-host
[Compute Separation][HT13] Freeze the M1 Host, appserver, and nginx contract
- Dominant language
- C#
- Stars
- 2k
- Forks
- 482
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 38
Description
## Roadmap mapping
| Field | Value |
|---|---|
| Roadmap ID | `HT13` |
| Lane | Host contract/decision |
| BYOC milestone | M1 |
| Parent | #11965 |
| Depends on | None; ready now |
| Merge contract gate for | `HT9`, `HT10-M1+HT13B-M1`, `HP3+HP5A-M1`, `HP4`; parallel development may begin |
| Pull request | None; decision record |
## Goal
Freeze the exact M1 contract between compute Host, Go appserver, nginx, and WorkerProxy: route ownership, payloads, status semantics, and error ownership. The implementation issues encode this contract, so this issue must close before they merge.
## Source material
- `Functions-NoPlaceholders@brettsam/ga_plan`: `docs/host/ga/roadmap.md`, rows `HT13`/`HT13B`.
- `docs/host/platform-control-apis.md` and `docs/host/containerization-details.md`.
- [internal BYOC #219](https://github.com/serverless-paas-balam/FlexConsumption-BYOC/issues/219), [internal BYOC #117](https://github.com/serverless-paas-balam/FlexConsumption-BYOC/issues/117), and [internal BYOC #123](https://github.com/serverless-paas-balam/FlexConsumption-BYOC/issues/123).
- Appserver implementation under `AAPT-Antares-Functions-Docker/images/flexconsumption/components/appserver/cv2/`.
## M1 ownership decisions to ratify
1. **Go appserver owns Frontend request-slot allocation.** It handles `POST /admin/apiserver/acquireHttpRequestSlots` and `POST /admin/apiserver/releaseHttpRequestSlots` and owns per-Frontend allocations. The Host does not add `/admin/request-slots/leases`; the prototype `RequestSlotsController` is not ported.
2. **Host owns linked-worker eligibility and revisioned capacity/health publication.** Appserver converts that snapshot into Frontend-visible capacity.
3. **WorkerProxy owns worker-pod assignment/readiness state** observed by NNA.
4. **The Host link route is Host-owned and nginx-bypassed.** `/admin/workers` reaches the compute Host on 9091, not appserver on 6060.
5. **M1 uses the [internal BYOC #219](https://github.com/serverless-paas-balam/FlexConsumption-BYOC/issues/219) beta plaintext exception.** No M1 route claims to satisfy production transport security.
## Route table to freeze
| Route | Owner | Caller | M1 behavior |
|---|---|---|---|
| `GET /admin/worker/ready` | WorkerProxy | NNA | Ready after worker gRPC connection; polled before assignment. |
| `POST /admin/worker/assign` | WorkerProxy | NNA | Applies the M1 specialization payload; idempotent, conflicting reassignment fails. |
| `POST /admin/infra/instanceState` | WorkerProxy | NNA | Long-polled monotonic unassigned -> assigned -> ready state. |
| `PUT /admin/workers` | Compute Host | Platform chain | Links one worker; absent from standard Host. |
| `POST /` on appserver 6060 with `operation=publish-runtime-state` | Host publishes, appserver receives | Host -> co-located appserver | Revisioned capacity/health after worker state changes. |
| `/admin/apiserver/acquireHttpRequestSlots` and `/releaseHttpRequestSlots` | Appserver | Frontend | Explicitly outside Host M1 implementation. |
### Host link payload and outcomes
Initial shape:
```json
{
"workerPodName": "worker-pod-abc123",
"workerHttpEndpoint": "http://100.64.1.12:48801",
"workerGrpcEndpoint": "http://100.64.1.12:48802",
"workerContainerEncryptionKey": "base64-encoded-key"
}
```
- `workerPodName` is the registry key.
- HTTP and gRPC endpoints are platform-derived.
- The encryption key is accepted/carried but not enforced under the beta exception.
- `200`: outbound connect, `StartStream`, init handshake, and channel registration complete; ScriptHost/capacity may still be pending.
- `400`: malformed/missing fields or invalid endpoints.
- `409`: duplicate/conflicting/stale/terminal admission.
- `503`: proxy/network/handshake unavailable.
- Exact replay is idempotent; stale or conflicting operation/epoch input mutates nothing.
### Capacity publish shape
| Field | M1 rule |
|---|---|
| `linkedWorkerCount` | 0 before link, 1 after eligibility. |
| `maxLinkedWorkers` | 1 for M1. |
| `totalRequestSlots` | 0 when ineligible; otherwise worker-reported concurrency. |
| `totalAvailableRequestSlots` | Same as total for M1 because appserver owns leasing. |
| revision | Host-assigned, immutable, strictly monotonic; appserver ignores lower revisions. |
Positive capacity is published only after link/init eligibility. Worker loss produces a higher revision with zero capacity.
### nginx routing
- `/admin/apiserver/*`, `/admin/infra/*`, `/admin/proxy/*` -> appserver 6060.
- `/admin/workers` and other Host admin paths -> Functions Host 9091.
- Confirm both placeholder and assigned beta configurations bypass appserver for `/admin/workers`.
## Acceptance criteria
- Host, appserver, Legion/NNA, and image owners confirm every route and status owner.
- Link payload/status/replay semantics are ratified.
- Capacity fields and monotonic revision handling are ratified.
- Appserver slot ownership and the no-Host-`RequestSlotsController` decision are explicit.
- nginx bypass is confirmed for beta stamp configurations.
- Plaintext is recorded as a non-production M1 exception.
- [internal BYOC #219](https://github.com/serverless-paas-balam/FlexConsumption-BYOC/issues/219), [internal BYOC #117](https://github.com/serverless-paas-balam/FlexConsumption-BYOC/issues/117), and [internal BYOC #123](https://github.com/serverless-paas-balam/FlexConsumption-BYOC/issues/123) remain linked as inputs.
## Dependencies
Blocks HT9, M1 capacity publication, WorkerProxy assignment APIs, and HTTP routing contract implementation.
## Explicit exclusions
Multi-worker, Host slot leases, drain/stop/eviction/reconnect, auth/certificates, host.json, billing, extension gRPC, assembly streaming, full [internal BYOC #123](https://github.com/serverless-paas-balam/FlexConsumption-BYOC/issues/123) hardening, and GA contracts.
## Standard-product protection
No code is created here. Frozen compute routes must be absent from standard Host; HT9 proves route absence and no runtime topology flag.
## Close condition
Close after all owning teams record agreement, the route/payload/revision table matches `platform-control-apis.md` or is updated there, and the decision lands before HT9 or HT13B-M1 merges.
Contributor guide
Assessment
This issue has not been assessed yet.