fix(worker): harden control-plane lifecycle
Все проверки выполнены успешно
CI / test (push) Successful in 2m32s
Docker / Build and publish worker image (push) Successful in 18m17s

- reconnect safely after token rotation and retry leased results
- reject malformed tasks and remove production cluster debug mutation
- validate environment files and require immutable container images

BREAKING CHANGE: Docker install, deploy, and Compose now require an
immutable repository@sha256 image reference.
Этот коммит содержится в:
Gleb Tv
2026-07-19 23:11:43 +03:00
родитель 6937674449
Коммит e987f24903
38 изменённых файлов: 2203 добавлений и 674 удалений

Просмотреть файл

@@ -35,11 +35,11 @@ branch.
| Server to worker | diagnostic task | new task-envelope variant | Planned |
The legacy top-level `task` and `notification_task` branches are accepted for
rollout compatibility. If a frame includes both a valid current
`task_envelope` and a legacy branch, the worker executes only
`task_envelope`. The current runner ignores malformed or unsupported task
branches and does not yet compare the envelope job ID with the inner job ID;
strict rejection and reporting are P1 work below.
rollout compatibility. A current `task_envelope` must activate exactly one
matching branch with a non-empty, matching inner and outer job ID and lease
token. Unsupported check kinds and attributable malformed envelopes produce
terminal reports; malformed envelopes without a usable identity are rejected
without execution or reporting.
## Initialization And Refresh
@@ -86,9 +86,10 @@ selection remains the primary isolation boundary.
}
```
`type=notification` activates `notification` instead. Job IDs in the envelope
and active branch must match once P1 validation lands. Today a task without a
recognized populated branch is ignored without execution.
`type=notification` activates `notification` instead. The worker enforces the
matching job IDs and non-empty lease token before dispatch. A task without one
recognized populated branch is rejected without execution; it is reported only
when the active branch provides attributable job and lease identity.
## Result Invariants
@@ -117,20 +118,26 @@ Files:
- `internal/wire/types_test.go`
- `internal/distworker/runner_protocol_test.go`
Tests:
Implemented:
- decode every current frame branch;
- prefer the current envelope over duplicate legacy branches;
- reject mismatched envelope and inner job IDs;
- preserve unknown optional fields during compatible rollout;
- reject missing lease tokens before execution result submission;
- atomically replace config and credentials.
- strict single-branch envelope selection with matching job-ID and lease
validation;
- unsupported-kind and attributable malformed-task terminal reporting;
- atomic config and credential replacement.
Still required:
- decode conformance coverage for every current frame branch and unknown
optional fields;
- explicit drain behavior and stale-lease acknowledgement coverage.
### P2: Safe Token Rotation
Current `Runner.RotateToken` closes the runner stop channel. Replace this with a
connection-scoped cancellation path that stores the new token, closes only the
active WebSocket, and reconnects without terminating worker services.
`Runner.RotateToken` replaces the token in memory, closes only the active
control-plane WebSocket, and reconnects without terminating worker services.
The replacement is not persisted: a process restart still uses its configured
startup token. The control plane must tolerate connection-scoped result resend
using the leased job and lease token for idempotency.
Acceptance: rotating from the web console produces a reconnect using the new
token while the HTTP listener, collectors, and optional cluster stay running.