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

1"""Shared work-block contract for daytime and overnight queue runs.""" 

2 

3from __future__ import annotations 

4 

5from typing import Any 

6 

7from . import checkpoint, ledger 

8from . import config as cfg 

9 

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) 

31 

32 

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 }