feat: schedule init --engagement for customer bootstrap presets
Some checks failed
ci / test (push) Has been cancelled
Some checks failed
ci / test (push) Has been cancelled
Add --engagement, --agents, and --bootstrap-cadence flags to scaffold hourly/daily/weekly engagement schedules. Hourly bootstrap keeps cadence: daily with hourly cron overrides per coulomb-loop ADR-003. Document activity-core requirements in activity-core-handoff-engagement.md. Closes KAIZEN-WP-0008 T02 and T04.
This commit is contained in:
@@ -6,11 +6,13 @@ import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
from click.testing import CliRunner
|
||||
|
||||
from kaizen_agentic.cli import cli
|
||||
from kaizen_agentic.schedule import (
|
||||
ScheduleError,
|
||||
engagement_schedule_yaml,
|
||||
parse_schedule,
|
||||
schedule_path,
|
||||
validate_schedule,
|
||||
@@ -30,6 +32,20 @@ def project_dir(tmp_path: Path) -> Path:
|
||||
|
||||
|
||||
class TestScheduleModule:
|
||||
def test_engagement_schedule_yaml_hourly_preset(self):
|
||||
text = engagement_schedule_yaml(
|
||||
"coulomb-loop",
|
||||
agents=["coach", "optimization"],
|
||||
bootstrap_cadence="hourly",
|
||||
)
|
||||
assert "Engagement: coulomb-loop bootstrap" in text
|
||||
body = "\n".join(line for line in text.splitlines() if not line.startswith("#"))
|
||||
schedule = parse_schedule(yaml.safe_load(body))
|
||||
coach = schedule.entry_for("coach")
|
||||
assert coach is not None
|
||||
assert coach.cadence == "daily"
|
||||
assert coach.cron == "15 * * * *"
|
||||
|
||||
def test_parse_requires_version(self):
|
||||
with pytest.raises(ScheduleError):
|
||||
parse_schedule({"agents": {}})
|
||||
@@ -67,6 +83,67 @@ class TestScheduleCli:
|
||||
assert path.exists()
|
||||
assert "coach" in path.read_text()
|
||||
|
||||
def test_engagement_init_hourly_bootstrap(
|
||||
self, runner: CliRunner, project_dir: Path
|
||||
):
|
||||
result = runner.invoke(
|
||||
cli,
|
||||
[
|
||||
"schedule",
|
||||
"init",
|
||||
"--target",
|
||||
str(project_dir),
|
||||
"--engagement",
|
||||
"coulomb-loop",
|
||||
"--agents",
|
||||
"coach,optimization",
|
||||
"--bootstrap-cadence",
|
||||
"hourly",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0, result.output
|
||||
text = schedule_path(project_dir).read_text()
|
||||
assert "Engagement: coulomb-loop bootstrap" in text
|
||||
assert "cron: 15 * * * *" in text
|
||||
assert "cadence: daily" in text
|
||||
assert "Engagement: coulomb-loop" in result.output
|
||||
|
||||
def test_engagement_init_validates_unknown_agent(
|
||||
self, runner: CliRunner, project_dir: Path
|
||||
):
|
||||
result = runner.invoke(
|
||||
cli,
|
||||
[
|
||||
"schedule",
|
||||
"init",
|
||||
"--target",
|
||||
str(project_dir),
|
||||
"--engagement",
|
||||
"demo",
|
||||
"--agents",
|
||||
"not-a-real-agent",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 1
|
||||
assert "unknown agent" in result.output
|
||||
|
||||
def test_engagement_flags_require_engagement_slug(
|
||||
self, runner: CliRunner, project_dir: Path
|
||||
):
|
||||
result = runner.invoke(
|
||||
cli,
|
||||
[
|
||||
"schedule",
|
||||
"init",
|
||||
"--target",
|
||||
str(project_dir),
|
||||
"--agents",
|
||||
"coach",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 1
|
||||
assert "--engagement" in result.output
|
||||
|
||||
def test_init_no_overwrite_without_force(
|
||||
self, runner: CliRunner, project_dir: Path
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user