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>
This commit is contained in:
@@ -88,6 +88,22 @@ kaizen-agentic memory init tdd-workflow --no-metrics # memory only
|
||||
|
||||
Session-close template: `docs/templates/session-close-protocol.md`
|
||||
|
||||
### Scheduled Agent Execution (ADR-005)
|
||||
```bash
|
||||
# Opt this repo into fleet scheduling
|
||||
kaizen-agentic schedule init # coach + optimization weekly
|
||||
kaizen-agentic schedule init --timezone UTC # override timezone
|
||||
kaizen-agentic schedule validate # schema + agent-name checks
|
||||
kaizen-agentic schedule list # enabled entries (--all incl. disabled)
|
||||
|
||||
# Prepare orientation for a scheduled run (offline; no State Hub needed)
|
||||
kaizen-agentic schedule prepare coach # markdown bundle
|
||||
kaizen-agentic schedule prepare optimization --format json
|
||||
```
|
||||
|
||||
activity-core fires the schedule and creates a task per (repo, agent); the task
|
||||
runs `schedule prepare`. kaizen-agentic does not run cron or invoke Claude.
|
||||
|
||||
### Information
|
||||
```bash
|
||||
# List templates
|
||||
|
||||
@@ -73,6 +73,45 @@ test -f .kaizen/metrics/optimizer/analysis.json && echo OK
|
||||
|
||||
**Boundary:** kaizen-agentic does not run Temporal schedules.
|
||||
|
||||
### Scheduled agent execution (WP-0006, ADR-005)
|
||||
|
||||
Beyond the metrics-only definitions above, agents themselves run on a cadence
|
||||
against a **preselected repo roster**. The roster combines three sources:
|
||||
|
||||
| Source | Purpose |
|
||||
|--------|---------|
|
||||
| State Hub `GET /repos/` | Canonical slug list + `host_paths` |
|
||||
| Repo opt-in: `.kaizen/schedule.yml` exists with `version` set | Per-repo enablement |
|
||||
| Optional hub flag `kaizen_schedule_enabled: true` (future) | Operator override |
|
||||
|
||||
A repo is **schedule-eligible** when it is registered with reachable
|
||||
`host_paths` **and** carries a valid `.kaizen/schedule.yml`. The activity-core
|
||||
resolver `discover_kaizen_scheduled_repos` intersects these and emits
|
||||
`context.scheduled_runs` (one entry per `(repo, agent)`); definitions `for_each`
|
||||
over that output.
|
||||
|
||||
| Definition | Trigger | Agent | Prepare command |
|
||||
|------------|---------|-------|-----------------|
|
||||
| [weekly-coach-orientation](integrations/activity-definitions/weekly-coach-orientation.md) | Cron Mon 09:00 | `coach` | `schedule prepare coach` |
|
||||
| [weekly-optimization-review](integrations/activity-definitions/weekly-optimization-review.md) | Cron Mon 10:00 | `optimization` | `schedule prepare optimization` |
|
||||
|
||||
**Listing schedule-eligible repos** (operator, no activity-core code):
|
||||
|
||||
```bash
|
||||
# In each candidate repo on a host listed in state-hub host_paths:
|
||||
kaizen-agentic schedule validate && kaizen-agentic schedule list
|
||||
```
|
||||
|
||||
**Design docs (no state-hub / activity-core code in this repo):**
|
||||
|
||||
- [schedule-schema.md](integrations/schedule-schema.md) — `.kaizen/schedule.yml`
|
||||
- [state-hub-roster-fields.md](integrations/state-hub-roster-fields.md) — hub fields/filters
|
||||
- [discover-kaizen-scheduled-repos.md](integrations/discover-kaizen-scheduled-repos.md) — resolver spec
|
||||
- [kaizen-schedule-prepared-event.md](integrations/kaizen-schedule-prepared-event.md) — event payload
|
||||
|
||||
**Boundary:** kaizen-agentic declares and prepares; activity-core schedules;
|
||||
state-hub owns the roster.
|
||||
|
||||
---
|
||||
|
||||
## Pattern 3 — artifact-store evidence retention
|
||||
|
||||
@@ -128,3 +128,27 @@ token with `TWINE_USERNAME=__token__`):
|
||||
make release-publish
|
||||
python -m twine upload dist/*
|
||||
```
|
||||
|
||||
## Scheduled-run runner prerequisites (WP-0006)
|
||||
|
||||
A runner that executes a scheduled kaizen agent task (fired by activity-core)
|
||||
needs:
|
||||
|
||||
- **`kaizen-agentic` on PATH** — `pip install kaizen-agentic` (or `pipx install
|
||||
kaizen-agentic`) using the Gitea PyPI extra index when installing from the
|
||||
internal registry:
|
||||
```bash
|
||||
pip install kaizen-agentic \
|
||||
--extra-index-url https://gitea.coulomb.social/api/packages/coulomb/pypi/simple/
|
||||
```
|
||||
- **Repo checkout reachable** at the `host_paths[<host>]` registered in State
|
||||
Hub, with a valid `.kaizen/schedule.yml` (`kaizen-agentic schedule validate`).
|
||||
- **No State Hub required for `prepare`** — `schedule prepare` reads local
|
||||
`.kaizen/` state only. The hub is needed by the *resolver* (activity-core),
|
||||
not by the prepared session.
|
||||
|
||||
**Enabling a definition** (activity-core operator): keep the kaizen definitions
|
||||
at `enabled: false` until a manual smoke test passes (see
|
||||
[INTEGRATION_PATTERNS.md Pattern 2](INTEGRATION_PATTERNS.md) and the
|
||||
[activity-core handoff checklist](integrations/activity-core-handoff-wp0006.md)),
|
||||
then flip one definition to `enabled: true` in staging before fleet-wide enable.
|
||||
|
||||
149
docs/adr/ADR-005-scheduled-agent-execution.md
Normal file
149
docs/adr/ADR-005-scheduled-agent-execution.md
Normal file
@@ -0,0 +1,149 @@
|
||||
---
|
||||
id: ADR-005
|
||||
title: Scheduled Agent Execution Convention
|
||||
status: accepted
|
||||
date: "2026-06-17"
|
||||
---
|
||||
|
||||
# ADR-005 — Scheduled Agent Execution Convention
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Kaizen agents are markdown instruction sets invoked in coding-agent sessions.
|
||||
ADR-004 added project-scoped metrics; WP-0004 committed three metrics-focused
|
||||
`ActivityDefinition` drafts (`enabled: false`). What is still missing is a way to
|
||||
run **agents themselves** — not just the metrics optimizer — on a **regular
|
||||
cadence** against a **preselected set of repos**, without kaizen-agentic owning
|
||||
Temporal workers, cron, or an LLM runtime.
|
||||
|
||||
The ecosystem already separates concerns:
|
||||
|
||||
- **activity-core** owns scheduling (cron/event → task creation).
|
||||
- **state-hub** owns the canonical repo roster and `host_paths`.
|
||||
- **kaizen-agentic** owns the agents, project memory, and metrics.
|
||||
|
||||
A scheduled agent run therefore needs a contract that crosses these repos
|
||||
without merging them.
|
||||
|
||||
## Decision
|
||||
|
||||
Introduce a **repo-local schedule manifest** and a **prepare** step. The
|
||||
end-to-end flow:
|
||||
|
||||
```
|
||||
activity-core cron
|
||||
→ context resolver (roster ∩ repos with schedule.yml)
|
||||
→ task per (repo, agent)
|
||||
→ coding-agent session runs `kaizen-agentic schedule prepare <agent>`
|
||||
→ session executes the agent instructions in that repo
|
||||
```
|
||||
|
||||
kaizen-agentic's responsibilities are exactly two: **declare** the schedule
|
||||
(`.kaizen/schedule.yml`) and **prepare** an orientation bundle for a run. It
|
||||
does **not** fire cron, create tasks, or invoke Claude.
|
||||
|
||||
### 1. Schedule manifest — `.kaizen/schedule.yml`
|
||||
|
||||
A repo opts into fleet scheduling by committing this file:
|
||||
|
||||
```yaml
|
||||
version: "1"
|
||||
timezone: Europe/Berlin
|
||||
agents:
|
||||
coach:
|
||||
cadence: weekly
|
||||
cron: "0 9 * * 1" # optional override; default from ActivityDefinition
|
||||
enabled: true
|
||||
optimization:
|
||||
cadence: weekly
|
||||
cron: "0 10 * * 1"
|
||||
enabled: true
|
||||
tdd-workflow:
|
||||
cadence: monthly
|
||||
enabled: false
|
||||
```
|
||||
|
||||
**Schema:**
|
||||
|
||||
| Key | Required | Type | Notes |
|
||||
|-----|----------|------|-------|
|
||||
| `version` | yes | string | Must be `"1"` |
|
||||
| `timezone` | no | string | IANA tz; default supplied by ActivityDefinition |
|
||||
| `agents` | yes | mapping | `agent-name → settings` |
|
||||
| `agents.<name>.cadence` | yes | enum | `daily` \| `weekly` \| `monthly` |
|
||||
| `agents.<name>.cron` | no | string | 5-field cron; overrides cadence default |
|
||||
| `agents.<name>.enabled` | no | bool | Default `true` |
|
||||
|
||||
**Validation rules** (`kaizen-agentic schedule validate`):
|
||||
|
||||
- `version` must equal `"1"`.
|
||||
- Every agent key must be an installed or packaged agent name.
|
||||
- `cadence` must be one of the allowed values.
|
||||
- Duplicate agent entries are rejected.
|
||||
|
||||
### 2. Roster (preselected repos)
|
||||
|
||||
A repo is **schedule-eligible** when **all** of:
|
||||
|
||||
1. It is a registered repo in state-hub (`GET /repos/`) with reachable
|
||||
`host_paths`.
|
||||
2. It contains a valid `.kaizen/schedule.yml`.
|
||||
3. (Optional, future) it carries a `kaizen_schedule_enabled: true` hub flag.
|
||||
|
||||
The resolver `discover_kaizen_scheduled_repos` (specified in
|
||||
`docs/integrations/discover-kaizen-scheduled-repos.md`, implemented in
|
||||
activity-core) intersects these sources and emits `context.scheduled_runs`.
|
||||
|
||||
### 3. Prepare bundle — `schedule prepare <agent>`
|
||||
|
||||
Assembles, from **local `.kaizen/` state only** (offline-safe):
|
||||
|
||||
- The agent prompt (`agents/agent-<name>.md`, installed or packaged).
|
||||
- Project memory (`.kaizen/agents/<name>/memory.md`) when present.
|
||||
- Metrics summary (`.kaizen/metrics/<name>/summary.json`) when present.
|
||||
- Repo pointers (`SCOPE.md`, `TODO.md`) when present.
|
||||
- Suggested session-close commands (`metrics record`, memory update).
|
||||
|
||||
Output is `markdown` (default) or `json` (`--format json`) so activity-core can
|
||||
embed it in a task `description` or a runner can parse it.
|
||||
|
||||
### CLI interface
|
||||
|
||||
```
|
||||
kaizen-agentic schedule init [--target PATH] [--timezone TZ] [--force]
|
||||
kaizen-agentic schedule validate [--target PATH]
|
||||
kaizen-agentic schedule list [--target PATH] [--all]
|
||||
kaizen-agentic schedule prepare <agent> [--target PATH] [--format markdown|json]
|
||||
```
|
||||
|
||||
## Boundaries
|
||||
|
||||
- **No scheduling code** in kaizen-agentic. Cron and task creation belong to
|
||||
activity-core; the roster query belongs to state-hub.
|
||||
- **No LLM invocation.** `prepare` produces a runner-agnostic bundle; a human or
|
||||
automated coding-agent session executes it.
|
||||
- **State-hub schema changes** (roster opt-in flag) are designed here but
|
||||
implemented in `the-custodian` (repo boundary).
|
||||
|
||||
## Consequences
|
||||
|
||||
- Operators declare per-repo schedules and a fleet roster without tribal
|
||||
knowledge.
|
||||
- activity-core can fire recurring tasks referencing `schedule prepare`.
|
||||
- A scheduled session opens with full orientation (prompt + memory + metrics).
|
||||
- The existing `weekly-metrics-optimize` definition (ADR-004 / WP-0004) remains
|
||||
complementary; an `optimization` agent run may chain `schedule prepare
|
||||
optimization` then `metrics optimize`.
|
||||
|
||||
## Related Documents
|
||||
|
||||
- [ADR-002: Project Memory Convention](ADR-002-project-memory-convention.md)
|
||||
- [ADR-004: Project Metrics Convention](ADR-004-project-metrics-convention.md)
|
||||
- [docs/integrations/schedule-schema.md](../integrations/schedule-schema.md)
|
||||
- [docs/integrations/discover-kaizen-scheduled-repos.md](../integrations/discover-kaizen-scheduled-repos.md)
|
||||
- [docs/agency-framework.md](../agency-framework.md)
|
||||
- [KAIZEN-WP-0006](../../workplans/kaizen-agentic-WP-0006-scheduled-agent-execution.md)
|
||||
@@ -299,12 +299,35 @@ Manifest: [integrations/optimizer-artifact-manifest.md](integrations/optimizer-a
|
||||
|
||||
---
|
||||
|
||||
## Scheduled Agent Execution
|
||||
|
||||
Agents can run on a **regular cadence** against **preselected repos**, fired by
|
||||
**activity-core** and prepared by kaizen-agentic (ADR-005). A repo opts in by
|
||||
committing `.kaizen/schedule.yml`:
|
||||
|
||||
```bash
|
||||
kaizen-agentic schedule init # scaffold (coach + optimization weekly)
|
||||
kaizen-agentic schedule validate # check schema + agent names
|
||||
kaizen-agentic schedule list # show enabled entries
|
||||
kaizen-agentic schedule prepare coach # orientation bundle for a scheduled run
|
||||
```
|
||||
|
||||
`schedule prepare <agent>` bundles the agent prompt, project memory, metrics
|
||||
summary, and repo pointers — offline, no State Hub required. kaizen-agentic does
|
||||
**not** run cron or invoke Claude; activity-core fires the schedule and a
|
||||
coding-agent session executes the prepared bundle.
|
||||
|
||||
Schema: [integrations/schedule-schema.md](integrations/schedule-schema.md).
|
||||
|
||||
---
|
||||
|
||||
## Related Documents
|
||||
|
||||
- [ADR-001: Workplan Convention](adr/ADR-001-workplan-convention.md)
|
||||
- [ADR-002: Project Memory Convention](adr/ADR-002-project-memory-convention.md)
|
||||
- [ADR-003: Protocols Artifact Convention](adr/ADR-003-protocols-artifact-convention.md)
|
||||
- [ADR-004: Project Metrics Convention](adr/ADR-004-project-metrics-convention.md)
|
||||
- [ADR-005: Scheduled Agent Execution](adr/ADR-005-scheduled-agent-execution.md)
|
||||
- [wiki/EcosystemIntegration.md](../wiki/EcosystemIntegration.md) — two-layer measurement model
|
||||
- [WP-0002: Agency Framework](../workplans/kaizen-agentic-WP-0002-agency-framework.md)
|
||||
- [WP-0003: Measurement Loop](../workplans/kaizen-agentic-WP-0003-measurement-loop.md)
|
||||
|
||||
17
docs/examples/.kaizen/schedule.yml
Normal file
17
docs/examples/.kaizen/schedule.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
# Kaizen scheduled agent execution manifest (ADR-005)
|
||||
# Declares which agents run on what cadence in this repo.
|
||||
# Validate with: kaizen-agentic schedule validate
|
||||
version: "1"
|
||||
timezone: Europe/Berlin
|
||||
agents:
|
||||
coach:
|
||||
cadence: weekly
|
||||
cron: "0 9 * * 1" # Monday 09:00 — cross-agent orientation brief
|
||||
enabled: true
|
||||
optimization:
|
||||
cadence: weekly
|
||||
cron: "0 10 * * 1" # Monday 10:00 — agent performance review
|
||||
enabled: true
|
||||
tdd-workflow:
|
||||
cadence: monthly
|
||||
enabled: false # declared but paused; operator opts in deliberately
|
||||
69
docs/integrations/activity-core-handoff-wp0006.md
Normal file
69
docs/integrations/activity-core-handoff-wp0006.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# activity-core Handoff — Scheduled Agent Execution (WP-0006)
|
||||
|
||||
Coordination checklist for the **activity-core** team to enable kaizen scheduled
|
||||
agent runs. kaizen-agentic owns the schedule contract, the prepare CLI, and the
|
||||
ActivityDefinition **drafts**; activity-core owns the resolver, the schedule
|
||||
firing, and task creation (repo boundary, ADR-005).
|
||||
|
||||
Open this as an activity-core issue/PR titled *"Enable kaizen scheduled agent
|
||||
execution (WP-0006)"* and track the boxes there.
|
||||
|
||||
## What kaizen-agentic ships (done in this repo)
|
||||
|
||||
- [x] `.kaizen/schedule.yml` schema + `schedule validate|init|list|prepare` CLI
|
||||
- [x] ADR-005 contract
|
||||
- [x] Resolver spec: [discover-kaizen-scheduled-repos.md](discover-kaizen-scheduled-repos.md)
|
||||
- [x] State Hub roster fields design: [state-hub-roster-fields.md](state-hub-roster-fields.md)
|
||||
- [x] Draft definitions (`enabled: false`):
|
||||
[weekly-coach-orientation](activity-definitions/weekly-coach-orientation.md),
|
||||
[weekly-optimization-review](activity-definitions/weekly-optimization-review.md)
|
||||
- [x] Event payload spec: [kaizen-schedule-prepared-event.md](kaizen-schedule-prepared-event.md)
|
||||
|
||||
## What activity-core must do
|
||||
|
||||
- [ ] **Implement resolver** `discover_kaizen_scheduled_repos` per the spec
|
||||
(hub roster ∩ repos with valid `.kaizen/schedule.yml`).
|
||||
- [ ] **Add resolver unit tests** using the four fixtures in the spec.
|
||||
- [ ] **Copy definitions** from `docs/integrations/activity-definitions/`
|
||||
(`weekly-coach-orientation.md`, `weekly-optimization-review.md`) into the
|
||||
activity-core catalog path (per ACT-ADR-002).
|
||||
- [ ] **Register** each definition slug in the activity-core index.
|
||||
- [ ] **Run** `make sync-activity-definitions` in activity-core.
|
||||
- [ ] **Wire cron** triggers (Mon 09:00 / 10:00 Europe/Berlin) to the resolver.
|
||||
- [ ] **Smoke test** against a pilot repo (see below) with the definition still
|
||||
`enabled: false` (dry-run task creation).
|
||||
- [ ] **Enable gradually** — flip one definition to `enabled: true` in staging
|
||||
after the smoke test passes.
|
||||
- [ ] **Verify runner prerequisites** — `kaizen-agentic` on PATH and the Gitea
|
||||
PyPI extra index if the runner installs from registry (see
|
||||
[PACKAGE_RELEASE.md](../PACKAGE_RELEASE.md)).
|
||||
|
||||
## State Hub team (the-custodian)
|
||||
|
||||
- [ ] Optional: add `kaizen_schedule_enabled` repo flag + `GET /repos/` filter
|
||||
(v2 pre-filter; the repo file remains the source of truth).
|
||||
|
||||
## Smoke test (manual, runner-agnostic)
|
||||
|
||||
```bash
|
||||
cd /path/to/pilot-repo
|
||||
kaizen-agentic schedule init # if not already present
|
||||
kaizen-agentic schedule validate # exit 0
|
||||
kaizen-agentic schedule list # shows coach + optimization enabled
|
||||
kaizen-agentic schedule prepare coach # non-empty orientation bundle
|
||||
```
|
||||
|
||||
Then in activity-core: run the resolver (dry-run) and confirm one
|
||||
`scheduled_run` per enabled `(repo, agent)` with a correct `prepare_command`.
|
||||
|
||||
## Pilot roster
|
||||
|
||||
- `kaizen-agentic` (dogfood)
|
||||
- `the-custodian` (hub operator)
|
||||
- one additional custodian-domain repo with `.kaizen/` state (TBD at pilot time)
|
||||
|
||||
## Related
|
||||
|
||||
- [ADR-005](../adr/ADR-005-scheduled-agent-execution.md)
|
||||
- [INTEGRATION_PATTERNS.md Pattern 2](../INTEGRATION_PATTERNS.md)
|
||||
- [KAIZEN-WP-0006](../../workplans/kaizen-agentic-WP-0006-scheduled-agent-execution.md)
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
id: kaizen-weekly-coach-orientation
|
||||
name: Weekly Kaizen Coach Orientation
|
||||
enabled: false
|
||||
owner: kaizen-agentic
|
||||
governance: custodian
|
||||
status: proposed
|
||||
trigger:
|
||||
type: cron
|
||||
cron_expression: "0 9 * * 1"
|
||||
timezone: Europe/Berlin
|
||||
misfire_policy: skip
|
||||
context_sources:
|
||||
- type: resolver
|
||||
query: discover_kaizen_scheduled_repos
|
||||
params:
|
||||
domain: custodian
|
||||
cadence: weekly
|
||||
bind_to: context.scheduled_runs
|
||||
---
|
||||
|
||||
# Weekly Kaizen Coach Orientation
|
||||
|
||||
Every Monday 09:00 Berlin time, opens a coach orientation task for each
|
||||
schedule-eligible repo whose `.kaizen/schedule.yml` enables the `coach` agent.
|
||||
|
||||
The resolver `discover_kaizen_scheduled_repos` (see
|
||||
[discover-kaizen-scheduled-repos.md](../discover-kaizen-scheduled-repos.md))
|
||||
returns one `scheduled_run` per `(repo, agent)`; this definition selects the
|
||||
`coach` runs.
|
||||
|
||||
```rule
|
||||
id: run-weekly-coach
|
||||
for_each: context.scheduled_runs
|
||||
bind_as: r
|
||||
condition: 'r.agent == "coach" and r.enabled == true'
|
||||
action:
|
||||
task_template: "Weekly coach orientation: {{r.repo}}"
|
||||
description: |
|
||||
{{r.prepare_command}}
|
||||
Then load agents/agent-coach.md in a coding-agent session, paste the
|
||||
prepared bundle, and follow the coach synthesis. At session close:
|
||||
kaizen-agentic metrics record coach --success --time <s> --quality <0-1>
|
||||
target_repo: "{{r.repo}}"
|
||||
priority: medium
|
||||
labels: ["kaizen", "agent-run", "coach", "scheduled", "automated"]
|
||||
```
|
||||
|
||||
**CLI mapping:** `kaizen-agentic schedule prepare coach` (offline-safe; reads
|
||||
local `.kaizen/` state).
|
||||
|
||||
**Activation:** sync into activity-core via `make sync-activity-definitions`
|
||||
after the `discover_kaizen_scheduled_repos` resolver is enabled. Keep
|
||||
`enabled: false` until a manual smoke test passes on a pilot repo. See
|
||||
[INTEGRATION_PATTERNS.md Pattern 2](../../INTEGRATION_PATTERNS.md).
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
id: kaizen-weekly-optimization-review
|
||||
name: Weekly Kaizen Optimization Review
|
||||
enabled: false
|
||||
owner: kaizen-agentic
|
||||
governance: custodian
|
||||
status: proposed
|
||||
trigger:
|
||||
type: cron
|
||||
cron_expression: "0 10 * * 1"
|
||||
timezone: Europe/Berlin
|
||||
misfire_policy: skip
|
||||
context_sources:
|
||||
- type: resolver
|
||||
query: discover_kaizen_scheduled_repos
|
||||
params:
|
||||
domain: custodian
|
||||
cadence: weekly
|
||||
bind_to: context.scheduled_runs
|
||||
---
|
||||
|
||||
# Weekly Kaizen Optimization Review
|
||||
|
||||
Every Monday 10:00 Berlin time, opens an optimization-agent review task for each
|
||||
schedule-eligible repo whose `.kaizen/schedule.yml` enables the `optimization`
|
||||
agent. Chains the agent orientation with the existing metrics optimizer so the
|
||||
review is evidence-backed.
|
||||
|
||||
```rule
|
||||
id: run-weekly-optimization
|
||||
for_each: context.scheduled_runs
|
||||
bind_as: r
|
||||
condition: 'r.agent == "optimization" and r.enabled == true'
|
||||
action:
|
||||
task_template: "Weekly optimization review: {{r.repo}}"
|
||||
description: |
|
||||
{{r.prepare_command}}
|
||||
kaizen-agentic metrics optimize # refresh evidence
|
||||
Then load agents/agent-optimization.md, paste the prepared bundle plus the
|
||||
optimizer report, and act on recommendations. At session close:
|
||||
kaizen-agentic metrics record optimization --success --time <s> --quality <0-1>
|
||||
target_repo: "{{r.repo}}"
|
||||
priority: medium
|
||||
labels: ["kaizen", "agent-run", "optimization", "scheduled", "automated"]
|
||||
```
|
||||
|
||||
**CLI mapping:** `kaizen-agentic schedule prepare optimization` then
|
||||
`kaizen-agentic metrics optimize`.
|
||||
|
||||
**Complementarity:** this generalizes the metrics-only
|
||||
[weekly-metrics-optimize](weekly-metrics-optimize.md) definition into a full
|
||||
agent run. Repos may run either; running both duplicates the optimizer step.
|
||||
|
||||
**Activation:** sync into activity-core via `make sync-activity-definitions`
|
||||
after the resolver is enabled; hold at `enabled: false` until smoke-tested.
|
||||
109
docs/integrations/discover-kaizen-scheduled-repos.md
Normal file
109
docs/integrations/discover-kaizen-scheduled-repos.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# 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:
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
## Related
|
||||
|
||||
- [state-hub-roster-fields.md](state-hub-roster-fields.md)
|
||||
- [schedule-schema.md](schedule-schema.md)
|
||||
- [activity-definitions/weekly-coach-orientation.md](activity-definitions/weekly-coach-orientation.md)
|
||||
- [ADR-005](../adr/ADR-005-scheduled-agent-execution.md)
|
||||
90
docs/integrations/kaizen-schedule-prepared-event.md
Normal file
90
docs/integrations/kaizen-schedule-prepared-event.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Event Payload: `kaizen.schedule.prepared`
|
||||
|
||||
**Status:** design — for **future event-driven runs**. v1 of WP-0006 is
|
||||
cron-driven (activity-core fires the schedule). This event lets a runner or
|
||||
activity-core react when a `schedule prepare` bundle has been assembled, without
|
||||
polling.
|
||||
|
||||
kaizen-agentic does **not** publish this event today; the `prepare` command
|
||||
writes to stdout. This spec fixes the contract so an emitter (a runner wrapper
|
||||
or a thin `--emit` flag in a later iteration) and consumers agree on the shape.
|
||||
|
||||
## Subject
|
||||
|
||||
```
|
||||
kaizen.schedule.prepared
|
||||
```
|
||||
|
||||
NATS/event-bus subject, sibling to the existing `kaizen.metrics.recorded` and
|
||||
`kaizen.agent.installed` subjects (Pattern 2).
|
||||
|
||||
## Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "kaizen.schedule.prepared",
|
||||
"version": "1",
|
||||
"occurred_at": "2026-06-17T09:00:12Z",
|
||||
"repo": "kaizen-agentic",
|
||||
"root": "/home/worsch/kaizen-agentic",
|
||||
"agent": "coach",
|
||||
"cadence": "weekly",
|
||||
"prepare_command": "kaizen-agentic schedule prepare coach --target /home/worsch/kaizen-agentic",
|
||||
"bundle": {
|
||||
"format": "markdown",
|
||||
"agent_prompt_found": true,
|
||||
"has_memory": true,
|
||||
"has_metrics": true,
|
||||
"pointers": ["scope", "todo"],
|
||||
"bytes": 8421
|
||||
},
|
||||
"session_close": [
|
||||
"kaizen-agentic metrics record coach --success --time <s> --quality <0-1>"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Type | Notes |
|
||||
|-------|------|-------|
|
||||
| `event` | string | Always `kaizen.schedule.prepared` |
|
||||
| `version` | string | Payload schema version |
|
||||
| `occurred_at` | RFC3339 | When the bundle was assembled |
|
||||
| `repo` | string | State Hub slug |
|
||||
| `root` | string | Absolute checkout path |
|
||||
| `agent` | string | Agent the bundle orients |
|
||||
| `cadence` | string | `daily` \| `weekly` \| `monthly` |
|
||||
| `prepare_command` | string | Exact CLI that produced the bundle |
|
||||
| `bundle.format` | string | `markdown` \| `json` |
|
||||
| `bundle.agent_prompt_found` | bool | Mirrors `schedule prepare --format json` |
|
||||
| `bundle.has_memory` | bool | Memory file present |
|
||||
| `bundle.has_metrics` | bool | Metrics summary present |
|
||||
| `bundle.pointers` | string[] | Repo pointer labels found (`scope`, `todo`) |
|
||||
| `bundle.bytes` | int | Rendered bundle size |
|
||||
| `session_close` | string[] | Suggested close commands |
|
||||
|
||||
The `bundle.*` flags map 1:1 to the JSON output of
|
||||
`kaizen-agentic schedule prepare <agent> --format json`, so an emitter can build
|
||||
this payload from the existing command without new computation.
|
||||
|
||||
## Consumers (illustrative)
|
||||
|
||||
- **activity-core** — close the loop: mark the scheduled task `in_progress` when
|
||||
a bundle is prepared.
|
||||
- **artifact-store** — archive large bundles by reference.
|
||||
- **dashboards** — fleet view of which scheduled runs have been prepared vs.
|
||||
executed.
|
||||
|
||||
## Boundary
|
||||
|
||||
- The payload carries **metadata and a command**, never secrets or full repo
|
||||
contents.
|
||||
- kaizen-agentic owns the schema; emission wiring (NATS publish) is a future
|
||||
iteration and belongs to the runner / activity-core integration.
|
||||
|
||||
## Related
|
||||
|
||||
- [discover-kaizen-scheduled-repos.md](discover-kaizen-scheduled-repos.md)
|
||||
- [INTEGRATION_PATTERNS.md Pattern 2](../INTEGRATION_PATTERNS.md)
|
||||
- [ADR-005](../adr/ADR-005-scheduled-agent-execution.md)
|
||||
93
docs/integrations/schedule-schema.md
Normal file
93
docs/integrations/schedule-schema.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# `.kaizen/schedule.yml` Schema
|
||||
|
||||
The schedule manifest declares which kaizen agents run on what cadence in an
|
||||
opted-in repo. It is the repo-local half of the scheduled-agent-execution
|
||||
contract (ADR-005). activity-core reads it (via the roster resolver) to fire
|
||||
recurring tasks; `kaizen-agentic schedule prepare` reads it indirectly by
|
||||
preparing per-agent orientation.
|
||||
|
||||
Canonical example: [`docs/examples/.kaizen/schedule.yml`](../examples/.kaizen/schedule.yml).
|
||||
|
||||
## Location
|
||||
|
||||
```
|
||||
<project-root>/.kaizen/schedule.yml
|
||||
```
|
||||
|
||||
Lives alongside `.kaizen/agents/` (memory) and `.kaizen/metrics/`. Like those,
|
||||
its presence is the **opt-in signal** for fleet scheduling.
|
||||
|
||||
## Fields
|
||||
|
||||
| Key | Required | Type | Default | Notes |
|
||||
|-----|----------|------|---------|-------|
|
||||
| `version` | yes | string | — | Must be `"1"` |
|
||||
| `timezone` | no | string | from ActivityDefinition | IANA tz, e.g. `Europe/Berlin` |
|
||||
| `agents` | yes | mapping | — | `agent-name → settings` |
|
||||
| `agents.<name>.cadence` | yes | enum | — | `daily` \| `weekly` \| `monthly` |
|
||||
| `agents.<name>.cron` | no | string | cadence default | 5-field cron expression |
|
||||
| `agents.<name>.enabled` | no | bool | `true` | Set `false` to declare but pause |
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
version: "1"
|
||||
timezone: Europe/Berlin
|
||||
agents:
|
||||
coach:
|
||||
cadence: weekly
|
||||
cron: "0 9 * * 1"
|
||||
enabled: true
|
||||
optimization:
|
||||
cadence: weekly
|
||||
cron: "0 10 * * 1"
|
||||
enabled: true
|
||||
tdd-workflow:
|
||||
cadence: monthly
|
||||
enabled: false
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
```bash
|
||||
kaizen-agentic schedule validate
|
||||
```
|
||||
|
||||
Errors are emitted with actionable messages and a non-zero exit code:
|
||||
|
||||
- Missing or non-`"1"` `version`.
|
||||
- `agents` not a mapping, or no agents declared.
|
||||
- An agent name that is **not** installed or packaged (typo guard).
|
||||
- A `cadence` outside `daily` / `weekly` / `monthly`.
|
||||
- Duplicate agent entries.
|
||||
|
||||
Only agents available to the project (installed under `agents/` or packaged in
|
||||
the distribution) may appear in a schedule.
|
||||
|
||||
## Scaffolding
|
||||
|
||||
```bash
|
||||
kaizen-agentic schedule init # defaults: coach + optimization weekly
|
||||
kaizen-agentic schedule init --timezone UTC # override timezone
|
||||
kaizen-agentic schedule init --force # overwrite existing
|
||||
```
|
||||
|
||||
The default scaffold enables `coach` and `optimization` weekly and declares
|
||||
`tdd-workflow` monthly but **disabled** (operator opts in deliberately).
|
||||
|
||||
## Listing
|
||||
|
||||
```bash
|
||||
kaizen-agentic schedule list # enabled entries only
|
||||
kaizen-agentic schedule list --all # include disabled
|
||||
```
|
||||
|
||||
## Relationship to activity-core
|
||||
|
||||
The `cron` field is an **optional per-repo override**. When omitted, the cadence
|
||||
maps to the default cron declared in the matching ActivityDefinition (e.g.
|
||||
`weekly-coach-orientation` fires Mon 09:00). This keeps fleet-wide timing in one
|
||||
place while letting individual repos shift their slot.
|
||||
|
||||
See [ADR-005](../adr/ADR-005-scheduled-agent-execution.md) and
|
||||
[INTEGRATION_PATTERNS.md Pattern 2](../INTEGRATION_PATTERNS.md).
|
||||
64
docs/integrations/state-hub-roster-fields.md
Normal file
64
docs/integrations/state-hub-roster-fields.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# State Hub Roster Fields for Kaizen Scheduling (Design)
|
||||
|
||||
**Status:** design only — implemented in `the-custodian/state-hub`, not here
|
||||
(repo boundary). This document specifies what kaizen-agentic and activity-core
|
||||
need from the hub so the State Hub team can add the fields and filter.
|
||||
|
||||
## Problem
|
||||
|
||||
activity-core's resolver needs to answer: *which registered repos participate in
|
||||
kaizen fleet scheduling, and where do they live on disk?* Today state-hub knows
|
||||
the canonical repo list and `host_paths` but has no notion of schedule opt-in.
|
||||
|
||||
## Existing hub data (sufficient for v1)
|
||||
|
||||
`GET /repos/` already returns, per repo:
|
||||
|
||||
| Field | Use |
|
||||
|-------|-----|
|
||||
| `slug` | Canonical repo identifier (`target_repo` in tasks) |
|
||||
| `host_paths[hostname] → local_path` | Where the repo is checked out on a runner |
|
||||
| `domain` | Scope filter (e.g. `custodian`) |
|
||||
|
||||
For **v1**, opt-in is detected **in the repo** (`.kaizen/schedule.yml` exists and
|
||||
validates). The resolver clones/reads each candidate path and checks for the
|
||||
file. No hub schema change is strictly required to ship the pilot.
|
||||
|
||||
## Proposed hub fields (v2, optional)
|
||||
|
||||
To let operators query eligibility **without touching every checkout**, add an
|
||||
optional repo-metadata flag:
|
||||
|
||||
| Field | Type | Default | Meaning |
|
||||
|-------|------|---------|---------|
|
||||
| `kaizen_schedule_enabled` | bool | `false` | Operator-confirmed fleet participation |
|
||||
| `kaizen_schedule_updated_at` | timestamp | null | Last time schedule.yml was synced/seen |
|
||||
|
||||
### Suggested filter
|
||||
|
||||
```
|
||||
GET /repos/?kaizen_schedule_enabled=true&domain=custodian
|
||||
```
|
||||
|
||||
Returns only schedule-eligible repos with their `host_paths`, so the resolver
|
||||
skips repos that have not opted in — cheaper than scanning every checkout.
|
||||
|
||||
### Write path
|
||||
|
||||
The flag is set by an operator (or a future `kaizen-agentic schedule register`
|
||||
that calls the hub). It is **advisory**: the authoritative opt-in remains the
|
||||
presence of a valid `.kaizen/schedule.yml` in the repo, re-checked by the
|
||||
resolver at run time. The flag is an index, not a source of truth.
|
||||
|
||||
## Boundary
|
||||
|
||||
- kaizen-agentic does **not** write these fields in WP-0006.
|
||||
- state-hub schema migration is tracked in `the-custodian`.
|
||||
- The resolver (activity-core) treats the hub flag as a pre-filter and the repo
|
||||
file as the decision.
|
||||
|
||||
## Related
|
||||
|
||||
- [discover-kaizen-scheduled-repos.md](discover-kaizen-scheduled-repos.md)
|
||||
- [schedule-schema.md](schedule-schema.md)
|
||||
- [ADR-005](../adr/ADR-005-scheduled-agent-execution.md)
|
||||
Reference in New Issue
Block a user