Enable kaizen agents to run on a regular cadence against a preselected repo roster, orchestrated by activity-core and prepared by kaizen-agentic — without this repo owning cron, Temporal workers, or an LLM runtime. CLI + module: - src/kaizen_agentic/schedule.py — .kaizen/schedule.yml parse/validate/scaffold - `kaizen-agentic schedule` group: init, validate, list, prepare <agent> (prepare bundles agent prompt + memory + metrics + repo pointers, offline) - tests/test_schedule_cli.py — 15 tests Contract & design: - ADR-005 scheduled agent execution; schema doc + example manifest - discover_kaizen_scheduled_repos resolver spec, state-hub roster fields, kaizen.schedule.prepared event payload, activity-core handoff checklist - INTEGRATION_PATTERNS Pattern 2 extended with roster model ActivityDefinition drafts (enabled: false): - weekly-coach-orientation, weekly-optimization-review Docs: agency-framework, CLI cheat sheet, PACKAGE_RELEASE runner prereqs, EcosystemIntegration, CHANGELOG, TODO. Workplan closed (status: done). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.7 KiB
3.7 KiB
Resolver Spec: discover_kaizen_scheduled_repos
Status: specification — implemented in activity-core, not here. This doc is the contract an activity-core implementer needs to add the context resolver that feeds the scheduled-agent ActivityDefinitions (ADR-005).
Purpose
Given the fleet roster and per-repo schedule manifests, emit one entry per
(repo, agent) that is due to run, so ActivityDefinitions can for_each over
the result.
Signature
discover_kaizen_scheduled_repos(
domain: str | None = None, # optional scope filter, e.g. "custodian"
cadence: str | None = None, # optional: "daily" | "weekly" | "monthly"
now: datetime | None = None, # injection point for testing
) -> { "scheduled_runs": list[ScheduledRun] }
Bound in a definition as:
context_sources:
- type: resolver
query: discover_kaizen_scheduled_repos
params:
domain: custodian
cadence: weekly
bind_to: context.scheduled_runs
Inputs (sources, in order)
- State Hub
GET /repos/(optionally filtered bydomainand, when the v2 flag lands,kaizen_schedule_enabled=true). Yieldsslug,host_paths,domain. - Repo checkout at
host_paths[<runner-host>]: read.kaizen/schedule.yml. Skip repos without the file. - Validation: run the equivalent of
kaizen-agentic schedule validate. Skip (and log) repos whose schedule is invalid — never emit a bad entry.
Output shape
{
"scheduled_runs": [
{
"repo": "kaizen-agentic",
"root": "/home/worsch/kaizen-agentic",
"agent": "coach",
"cadence": "weekly",
"cron": "0 9 * * 1",
"timezone": "Europe/Berlin",
"enabled": true,
"prepare_command": "kaizen-agentic schedule prepare coach --target /home/worsch/kaizen-agentic"
}
]
}
ScheduledRun fields
| Field | Source | Notes |
|---|---|---|
repo |
hub slug |
becomes target_repo on the created task |
root |
host_paths[<host>] |
absolute checkout path on the runner |
agent |
schedule.yml key | |
cadence |
schedule.yml | |
cron |
schedule.yml or definition default | per-repo override when present |
timezone |
schedule.yml or definition default | |
enabled |
schedule.yml (true only emitted) |
disabled entries are filtered out |
prepare_command |
derived | exact CLI the task should run |
Filtering rules
- Emit only entries with
enabled: true. - When
cadenceparam is set, emit only matching entries (lets each cron-bound definition select its own cadence slice). - When
cronis present on the entry, it is the authoritative per-repo time; otherwise the definition's cron applies.
Errors
| Condition | Behavior |
|---|---|
| Repo unreachable / path missing on host | Skip + log repo_unreachable |
.kaizen/schedule.yml absent |
Skip silently (not opted in) |
| schedule.yml invalid | Skip + log schedule_invalid with validation errors |
| Hub unreachable | Fail the resolver run (no roster = no safe output) |
The resolver must be idempotent and side-effect free: it reads, it does not write. Task creation happens in the ActivityDefinition rule, not here.
Test fixtures
- A repo with valid
.kaizen/schedule.yml(coach enabled) → one entry. - A repo with the file but coach
enabled: false→ no entry. - A repo without the file → no entry.
- A repo with an invalid schedule → no entry + logged error.