first commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-06
|
||||
@@ -0,0 +1,58 @@
|
||||
## Context
|
||||
|
||||
Run has typed clients for control/job/log/artifact channels and local spool packages, but its executable behavior is still a smoke summary plus bounded lifecycle executor that immediately returns success metadata. Platform-side job leasing is already available, so the missing piece is a persistent run worker that consumes jobs safely.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Add hello/heartbeat and job polling loops.
|
||||
- Execute install/start/stop lifecycle jobs using scoped process supervision.
|
||||
- Emit progress and terminal results through the job channel.
|
||||
- Connect stdout/stderr to log spool and lifecycle artifacts to artifact queue hooks.
|
||||
- Enforce path, credential, command, and socket safety.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- No arbitrary plugin code execution or unbounded shell access.
|
||||
- No game client bridge implementation.
|
||||
- No cloud host provisioning or billing.
|
||||
- No external artifact/log storage backend implementation.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Worker owns channel scheduling
|
||||
|
||||
The run worker keeps control heartbeat high priority, job claim/result next, logs durable/batched, and artifacts lower priority. Long transfers must not block heartbeat or job result submission.
|
||||
|
||||
### Decision 2: Lifecycle actions use scoped command templates
|
||||
|
||||
Plugin lifecycle action references resolve to bounded command templates under a configured server workspace. Absolute paths, parent traversal, raw credentials, and socket exposure are rejected.
|
||||
|
||||
### Decision 3: Process supervisor is an abstraction
|
||||
|
||||
Process management sits behind a supervisor interface so tests can use fake processes and later game-specific process handling can be added without rewriting the worker loop.
|
||||
|
||||
### Decision 4: Smoke mode remains
|
||||
|
||||
Smoke mode stays available for local diagnostics. Worker mode is enabled through explicit config.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] Real process orchestration can hang. Mitigation: bounded timeouts, cancellation, progress heartbeat, and supervisor tests.
|
||||
- [Risk] Command templates can become unsafe. Mitigation: validation rejects shell metacharacter abuse, absolute paths, direct sockets, and secret env leaks.
|
||||
- [Risk] Worker loops can starve logs/artifacts. Mitigation: separate scheduling and priority rules.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Add worker config and session state.
|
||||
2. Implement control heartbeat and job loop.
|
||||
3. Add process supervisor and lifecycle executor.
|
||||
4. Wire logs/artifacts to existing queues.
|
||||
5. Update command entrypoint and docs.
|
||||
6. Add unit and integration-style tests.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Whether future plugin action runtimes should interpret JSON action schemas directly or compile them into lifecycle command templates.
|
||||
- Whether server process state should be persisted in a journal file or a small local database.
|
||||
@@ -0,0 +1,28 @@
|
||||
## Why
|
||||
|
||||
The run executor currently returns metadata-only success for lifecycle assignments. The platform can queue and claim jobs, but no daemon loop performs hello, heartbeat, claim, ack, progress, result, cancel, reconcile, process supervision, log collection, or artifact worker coordination. Operators need real local execution before server management can be considered operational.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a run worker loop for registration, heartbeat, job polling, acknowledgement, progress, results, cancel polling, and reconcile.
|
||||
- Replace metadata-only lifecycle execution with scoped install/start/stop process orchestration.
|
||||
- Enforce workspace scoping, command allowlists, redaction, and channel separation.
|
||||
- Connect process output to log spool and lifecycle result refs to artifact upload hooks.
|
||||
- Add configuration, tests, and integration-style verification with a platform test server.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `run-worker-real-execution`: Real run-side worker loop and scoped lifecycle process execution.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `server-management-workflows`: Lifecycle jobs become executable by run instead of metadata-only.
|
||||
- `run-job-channel`: The run client is used by a persistent worker loop.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affects `run/` config, command, runtime, protocol usage, spool integration, artifact hooks, docs, and tests.
|
||||
- Affects `platform/` tests where integration-style job flow coverage is needed.
|
||||
- Does not expose host paths, raw credentials, direct sockets, unrestricted shell execution, billing, or cloud host workflows.
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Run worker maintains platform session
|
||||
The run executable SHALL support a worker mode that registers with platform and maintains heartbeat state.
|
||||
|
||||
#### Scenario: Worker registers and heartbeats
|
||||
- **WHEN** run starts in worker mode with valid platform configuration
|
||||
- **THEN** it MUST send hello, store the active session token, and continue sending heartbeat metadata
|
||||
|
||||
#### Scenario: Heartbeat does not carry heavy channels
|
||||
- **WHEN** run sends heartbeat
|
||||
- **THEN** it MUST NOT include logs, artifact chunks, job result bodies, host paths, raw credentials, or direct sockets
|
||||
|
||||
### Requirement: Run worker processes job lifecycle
|
||||
The run worker SHALL claim, acknowledge, report progress, complete, cancel, and reconcile jobs through the platform job channel.
|
||||
|
||||
#### Scenario: Job assignment completes
|
||||
- **WHEN** platform assigns a supported lifecycle job
|
||||
- **THEN** run MUST ack the job, report bounded progress, execute scoped lifecycle work, and submit a terminal result
|
||||
|
||||
#### Scenario: Cancel request handled
|
||||
- **WHEN** platform reports cancellation for an active job lease
|
||||
- **THEN** run MUST attempt cancellation and submit a bounded cancelled or failed result
|
||||
|
||||
### Requirement: Lifecycle execution is scoped
|
||||
The run worker SHALL execute install, start, and stop lifecycle commands only inside configured server workspaces with validated command templates.
|
||||
|
||||
#### Scenario: Scoped lifecycle command accepted
|
||||
- **WHEN** a lifecycle job resolves to a safe command template and workspace
|
||||
- **THEN** run MUST execute it through the process supervisor and redact unsafe output before platform reporting
|
||||
|
||||
#### Scenario: Unsafe lifecycle command rejected
|
||||
- **WHEN** a lifecycle job requests absolute paths, parent traversal, raw credentials, direct sockets, or unrestricted shell execution
|
||||
- **THEN** run MUST reject the job with a bounded failure result
|
||||
|
||||
### Requirement: Run channels remain prioritized
|
||||
The run worker SHALL keep control, job, log, and artifact work channelized so large transfer work cannot block heartbeat or job result submission.
|
||||
|
||||
#### Scenario: Artifact work pending during heartbeat
|
||||
- **WHEN** artifact uploads are pending and a heartbeat is due
|
||||
- **THEN** run MUST prioritize heartbeat over artifact transfer work
|
||||
|
||||
#### Scenario: Process logs are spooled
|
||||
- **WHEN** a managed process writes stdout or stderr
|
||||
- **THEN** run MUST write bounded log entries to local spool for platform ingest
|
||||
@@ -0,0 +1,56 @@
|
||||
## 1. Run Worker Loop
|
||||
|
||||
- [x] 1.1 Add run worker service that performs hello registration and stores active session state.
|
||||
- [x] 1.2 Add heartbeat loop with capability refresh and capacity reporting.
|
||||
- [x] 1.3 Add job claim loop with ack, progress, result, cancel polling, and reconcile.
|
||||
- [x] 1.4 Add bounded retry/backoff behavior without blocking heartbeat.
|
||||
|
||||
## 2. Process Lifecycle Execution
|
||||
|
||||
- [x] 2.1 Replace metadata-only lifecycle executor with scoped install/start/stop execution.
|
||||
- [x] 2.2 Add process supervisor abstraction for server working directory, command templates, env allowlist, and lifecycle state.
|
||||
- [x] 2.3 Add safe command resolution from plugin lifecycle action schemas without unrestricted shell execution.
|
||||
- [x] 2.4 Add local state/journal for active server processes and in-flight jobs.
|
||||
- [x] 2.5 Add cancellation behavior for running lifecycle jobs.
|
||||
|
||||
## 3. Security Boundaries
|
||||
|
||||
- [x] 3.1 Enforce scoped server workspace roots and never expose raw host paths to platform_web or plugins.
|
||||
- [x] 3.2 Reject plugin action payloads requesting raw credentials, direct sockets, absolute paths, or unrestricted commands.
|
||||
- [x] 3.3 Redact command output and metadata before sending progress/result.
|
||||
- [x] 3.4 Keep control, job, log, and artifact channels independent.
|
||||
|
||||
## 4. Log And Artifact Worker Hooks
|
||||
|
||||
- [x] 4.1 Connect process stdout/stderr to the existing log spool.
|
||||
- [x] 4.2 Add artifact upload hook for lifecycle result refs.
|
||||
- [x] 4.3 Ensure large artifact work cannot block control heartbeat or job result submission.
|
||||
|
||||
## 5. CLI And Config
|
||||
|
||||
- [x] 5.1 Add run config for platform URL, run endpoint ID, registration token, workspace root, poll intervals, and capacity.
|
||||
- [x] 5.2 Update `run/cmd/run` to start the worker in local mode.
|
||||
- [x] 5.3 Keep smoke mode available for tests and local diagnostics.
|
||||
|
||||
## 6. Verification
|
||||
|
||||
- [x] 6.1 Add unit tests for worker state transitions, retry behavior, and cancel/reconcile.
|
||||
- [x] 6.2 Add run tests for scoped lifecycle command execution using temp workspaces.
|
||||
- [x] 6.3 Add integration-style test with a platform test server: hello → heartbeat → claim → ack → progress → result.
|
||||
- [x] 6.4 Run `cd run && go test ./...` and record evidence.
|
||||
- [x] 6.5 Run `cd platform && go test ./...` and record evidence.
|
||||
- [x] 6.6 Run `scripts/check-structure.sh` and record evidence.
|
||||
- [x] 6.7 Run `openspec validate implement-run-worker-real-execution --strict` and record evidence.
|
||||
|
||||
## Evidence
|
||||
|
||||
- 2026-07-06: Added `run/runtime.Worker` with hello session registration, heartbeat, claim, ack, progress, cancel polling, terminal result, reconcile, bounded retry ticker reset, and an in-memory active job journal.
|
||||
- 2026-07-06: Replaced metadata-only lifecycle execution with scoped command-template execution through `ProcessSupervisor`, per-server workspace resolution, command/env validation, cancellation, redaction, log sink, and lifecycle artifact hook.
|
||||
- 2026-07-06: Added `run/config` worker settings for endpoint identity, registration token, workspace/spool roots, max jobs, heartbeat/poll intervals, and retry backoff; updated `run/cmd/run` to preserve smoke mode and start worker mode when `RUN_MODE=worker`.
|
||||
- 2026-07-06: Updated `run/README.md`, `run/protocol/job.md`, and `run/protocol/control.md` to document real worker mode, scoped lifecycle command templates, and channel boundaries.
|
||||
- 2026-07-06: `cd run && GOCACHE=/private/tmp/browser-go-build-cache go test ./runtime` passed after adding lifecycle tests for scoped command execution, unsafe template rejection, workspace escape rejection, cancellation, log sink, artifact hook, worker registration, heartbeat, claim/ack/progress/result, cancel/reconcile, spool token propagation, bounded retry, and HTTP platform-like worker flow.
|
||||
- 2026-07-06: Updated `platform/api/job_channel_handlers_test.go` so the platform router workflow covers `hello -> heartbeat -> claim -> ack -> progress -> cancel -> result -> reconcile`.
|
||||
- 2026-07-06: `cd run && GOCACHE=/private/tmp/browser-go-build-cache go test ./...` passed with escalated loopback permission because existing API/worker `httptest` suites bind local ports.
|
||||
- 2026-07-06: `cd platform && GOCACHE=/private/tmp/browser-go-build-cache go test ./...` passed.
|
||||
- 2026-07-06: `scripts/check-structure.sh` passed.
|
||||
- 2026-07-06: `openspec validate implement-run-worker-real-execution --strict` reported `Change 'implement-run-worker-real-execution' is valid`; PostHog telemetry flush failed due restricted DNS and did not affect validation.
|
||||
Reference in New Issue
Block a user