seam: add polaris worker CLI subcommand (cli/worker.py) #52

Closed
opened 2026-09-11 10:35:06 +00:00 by bart · 1 comment
Collaborator

Why

infra/compose/docker-compose.yml (PH0.1) already wires the worker service to run command: ["polaris", "worker"], and backend/Dockerfile (PH0.2)'s own header comment says the same image "also runs the worker (polaris worker, PH0.3)". But backend/src/polaris/cli/** is owned/sealed to PH0.2's branch, and PH0.3 (#6, worker skeleton)'s brief explicitly says not to touch anything under backend/src/polaris/{core,api,db,cli}. So right now there is no cli/worker.py, and polaris worker is not a valid subcommand — docker compose up would fail to start the worker service, even though #6 ships a working worker process at polaris.worker.main:main() (also runnable directly as python -m polaris.worker).

What's needed

One small new file, following the exact shape of the existing cli/api.py:

# backend/src/polaris/cli/worker.py
from __future__ import annotations

import argparse

NAME = "worker"


def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
    parser = subparsers.add_parser(NAME, help="Run the worker process (claim loop + scheduler)")
    parser.set_defaults(handler=run)


def run(args: argparse.Namespace) -> int:
    from polaris.worker.main import main

    return main()

This is a new file under a discovery seam (polaris/cli/<command>.py, auto-discovered by polaris.cli's pkgutil.iter_modules walk per docs/12-implementation-plan.md) — it doesn't edit any existing file, so it shouldn't conflict with anything else in flight. It is not in the "Sealed after PH1" list in docs/12-implementation-plan.md (only api/main.py is named there for the api/cli family).

Blocks

#6 (PH0.3 worker skeleton) for its first acceptance criterion ("Worker starts against the compose stack and logs a heartbeat on schedule") to be true end-to-end against the real compose stack. #6's own unit tests and the rest of its acceptance criteria do not depend on this — they exercise polaris.worker.main.main()/run_claim_loop/discovery directly.

Flagged per CLAUDE.md: "If a ticket turns out to need a change outside its scope, open a seam request issue that blocks it, instead of widening the ticket."

## Why `infra/compose/docker-compose.yml` (PH0.1) already wires the `worker` service to run `command: ["polaris", "worker"]`, and `backend/Dockerfile` (PH0.2)'s own header comment says the same image "also runs the worker (`polaris worker`, PH0.3)". But `backend/src/polaris/cli/**` is owned/sealed to PH0.2's branch, and PH0.3 (#6, worker skeleton)'s brief explicitly says not to touch anything under `backend/src/polaris/{core,api,db,cli}`. So right now there is no `cli/worker.py`, and `polaris worker` is not a valid subcommand — `docker compose up` would fail to start the `worker` service, even though #6 ships a working worker process at `polaris.worker.main:main()` (also runnable directly as `python -m polaris.worker`). ## What's needed One small new file, following the exact shape of the existing `cli/api.py`: ```python # backend/src/polaris/cli/worker.py from __future__ import annotations import argparse NAME = "worker" def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None: parser = subparsers.add_parser(NAME, help="Run the worker process (claim loop + scheduler)") parser.set_defaults(handler=run) def run(args: argparse.Namespace) -> int: from polaris.worker.main import main return main() ``` This is a new file under a discovery seam (`polaris/cli/<command>.py`, auto-discovered by `polaris.cli`'s `pkgutil.iter_modules` walk per docs/12-implementation-plan.md) — it doesn't edit any existing file, so it shouldn't conflict with anything else in flight. It is **not** in the "Sealed after PH1" list in `docs/12-implementation-plan.md` (only `api/main.py` is named there for the `api`/`cli` family). ## Blocks #6 (PH0.3 worker skeleton) for its first acceptance criterion ("Worker starts against the compose stack and logs a heartbeat on schedule") to be true end-to-end against the real compose stack. #6's own unit tests and the rest of its acceptance criteria do not depend on this — they exercise `polaris.worker.main.main()`/`run_claim_loop`/discovery directly. Flagged per `CLAUDE.md`: "If a ticket turns out to need a change outside its scope, open a seam request issue that blocks it, instead of widening the ticket."
Author
Collaborator

Fix drafted on feature/cli-worker-command (local, not pushed yet): backend/src/polaris/cli/worker.py exactly as specified above, plus worker added to test_known_commands_are_discovered. Holding off on pushing/opening the PR: mypy --strict correctly fails right now because polaris.worker does not exist on main yet (PR #53 is still open, not merged) — the lazy from polaris.worker.main import main inside run() cannot be typechecked against a module that is not there. I will rebase this branch and open the PR once #53 merges, then verify AC1 end-to-end against the real compose stack.

Fix drafted on `feature/cli-worker-command` (local, not pushed yet): `backend/src/polaris/cli/worker.py` exactly as specified above, plus `worker` added to `test_known_commands_are_discovered`. Holding off on pushing/opening the PR: `mypy --strict` correctly fails right now because `polaris.worker` does not exist on `main` yet (PR #53 is still open, not merged) — the lazy `from polaris.worker.main import main` inside `run()` cannot be typechecked against a module that is not there. I will rebase this branch and open the PR once #53 merges, then verify AC1 end-to-end against the real compose stack.
bart closed this issue 2026-09-11 11:15:49 +00:00
Sign in to join this conversation.
No labels
ready-for-agent
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
patrick/Polaris#52
No description provided.