Files
kaizen-agentic/docs/integrations/discover-kaizen-scheduled-repos.md
tegwick 3b2edd4a9e feat: scheduled agent execution via activity-core (WP-0006, v1.3.0)
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>
2026-06-17 08:19:51 +02:00

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)

  1. State Hub GET /repos/ (optionally filtered by domain and, when the v2 flag lands, kaizen_schedule_enabled=true). Yields slug, host_paths, domain.
  2. Repo checkout at host_paths[<runner-host>]: read .kaizen/schedule.yml. Skip repos without the file.
  3. 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 cadence param is set, emit only matching entries (lets each cron-bound definition select its own cadence slice).
  • When cron is 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.