Coverage for src/keel/workblock.py: 100%
12 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-16 18:07 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-16 18:07 +0000
1"""Shared work-block contract for daytime and overnight queue runs."""
3from __future__ import annotations
5from typing import Any
7from . import checkpoint, ledger
8from . import config as cfg
10WORK_BLOCK_SCHEMA_VERSION = "keel.work-block.v1"
11OUTCOME_BUCKETS = (
12 "shipped",
13 "pr_open_not_merged",
14 "deferred",
15 "blocked",
16 "skipped",
17 "needs_input",
18)
19STOP_CONDITIONS = (
20 "queue-exhausted",
21 "max-items-reached",
22 "time-budget-exhausted",
23 "operator-pause",
24 "consent-gap",
25 "needs-input",
26 "blocked-finding",
27 "merge-window-close",
28 "three-consecutive-unresolved-ci-failures",
29 "user-cancelled",
30)
33def contract_as_dict(
34 *,
35 config: cfg.ProjectConfig,
36 mode: str,
37 transport: dict[str, Any] | None = None,
38) -> dict[str, Any]:
39 """Return the consumer-neutral queue/work-block primitive contract."""
40 if mode not in {"daytime", "overnight"}:
41 raise ValueError("work-block mode must be daytime or overnight")
42 github = transport or {}
43 return {
44 "schema_version": WORK_BLOCK_SCHEMA_VERSION,
45 "mode": mode,
46 "base_branch": config.base_branch,
47 "timezone": config.timezone,
48 "merge_window": config.merge_window,
49 "merge_window_mode": config.merge_window_mode,
50 "github_transport": github,
51 "queue": {
52 "accepted_inputs": ["explicit_issue_numbers", "queue_selector"],
53 "explicit_issue_order": "as-provided",
54 "selector_order": [
55 "priority",
56 "issue_number",
57 ],
58 "snapshot_once_per_session": True,
59 "refresh_readiness_between_issues": True,
60 },
61 "per_issue": {
62 "handoff_command": "ship",
63 "isolated_branch_worktree": True,
64 "child_inherits_operator_consent_scope": True,
65 "child_honors_capture_contract": True,
66 "child_appends_run_ledger": True,
67 "child_uses_merge_lock": True,
68 "child_rechecks_merge_window": True,
69 },
70 "failure_policy": {
71 "branch_contamination_policy": "one issue cannot reuse another issue worktree",
72 "non_ready_policy": "skip-or-stop-by-mode-policy",
73 "continue_after_blocked": mode == "overnight",
74 "daytime_operator_can_redirect_between_items": mode == "daytime",
75 },
76 "checkpoint": checkpoint.checkpoint_contract_as_dict(config),
77 "run_ledger": ledger.ledger_contract_as_dict(config),
78 "final_report": {
79 "required": True,
80 "outcome_buckets": list(OUTCOME_BUCKETS),
81 "source": "child ship results + run ledger + checkpoint",
82 },
83 "stop_conditions": list(STOP_CONDITIONS),
84 "shared_with": ["overnight"] if mode == "daytime" else ["work-block"],
85 }