diff --git a/.kaizen/metrics/coach/executions.jsonl b/.kaizen/metrics/coach/executions.jsonl index 3216429..55fc780 100644 --- a/.kaizen/metrics/coach/executions.jsonl +++ b/.kaizen/metrics/coach/executions.jsonl @@ -1,2 +1,3 @@ {"agent": "coach", "committed": true, "execution_time_s": 0.03051502598100342, "harness": "agent-harness", "head_after": "defc938fd38f29f5b2866afc06318748d67dcb62", "metadata": {"completion_event_type": "binky_daily_brief", "labels": ["binky", "rhythm", "automated", "harness-onboarding"], "task_title": "Run Binky daily rhythm (daily_brief)", "tool_profile": "green-commit-only"}, "repo": "binky-control", "success": true, "timestamp": "2026-07-18T09:06:48Z", "tokens": 0} {"agent": "coach", "committed": true, "execution_time_s": 73.32371750898892, "harness": "agent-harness", "head_after": "0978a0796e549da4a7c9f1555d0fb5b86d51d0a5", "metadata": {"completion_event_type": "binky_daily_brief", "labels": ["binky", "rhythm", "automated", "harness-onboarding"], "task_title": "Run Binky daily rhythm (daily_brief)", "tool_profile": "green-commit-only"}, "repo": "binky-control", "success": true, "timestamp": "2026-07-18T11:48:39Z", "tokens": 0} +{"agent": "coach", "committed": true, "execution_time_s": 58.93447641702369, "harness": "agent-harness", "head_after": "35314ecc69203480f93068c69e1e4f0b0bd67ad8", "metadata": {"completion_event_type": "binky_daily_brief", "labels": ["binky", "rhythm", "automated", "harness-onboarding"], "task_title": "Run Binky daily rhythm (daily_brief)", "tool_profile": "green-commit-only"}, "repo": "binky-control", "success": true, "timestamp": "2026-07-21T21:49:34Z", "tokens": 0} diff --git a/.kaizen/metrics/coach/summary.json b/.kaizen/metrics/coach/summary.json index 815c3c8..032944e 100644 --- a/.kaizen/metrics/coach/summary.json +++ b/.kaizen/metrics/coach/summary.json @@ -1,9 +1,9 @@ { "agent": "coach", - "avg_execution_time_s": 36.677, + "avg_execution_time_s": 44.096, "avg_quality_score": null, - "execution_count": 2, - "last_execution": "2026-07-18T11:48:39Z", + "execution_count": 3, + "last_execution": "2026-07-21T21:49:34Z", "success_rate": 1.0, "trend": { "quality_score": "stable", diff --git a/.kaizen/metrics/review-prep/executions.jsonl b/.kaizen/metrics/review-prep/executions.jsonl index a522a4d..ec57442 100644 --- a/.kaizen/metrics/review-prep/executions.jsonl +++ b/.kaizen/metrics/review-prep/executions.jsonl @@ -1,2 +1,3 @@ {"agent": "review-prep", "committed": true, "execution_time_s": 0.017968165018828586, "harness": "agent-harness", "head_after": "04410c626932e5ba98c17747ab7b1e5bd5d67736", "metadata": {"completion_event_type": "binky_weekly_review", "labels": ["binky", "weekly-review", "automated", "harness-onboarding"], "task_title": "Prepare Binky weekly founder review", "tool_profile": "green-commit-only"}, "repo": "binky-control", "success": true, "timestamp": "2026-07-18T09:06:51Z", "tokens": 0} {"agent": "review-prep", "committed": true, "execution_time_s": 46.6832704070257, "harness": "agent-harness", "head_after": "ff6df2cc763e269246a8f9f6fc2d8babd108df29", "metadata": {"completion_event_type": "binky_weekly_review", "labels": ["binky", "weekly-review", "automated", "harness-onboarding"], "task_title": "Prepare Binky weekly founder review", "tool_profile": "green-commit-only"}, "repo": "binky-control", "success": true, "timestamp": "2026-07-18T11:49:29Z", "tokens": 0} +{"agent": "review-prep", "committed": true, "execution_time_s": 40.15984101605136, "harness": "agent-harness", "head_after": "f17a065ed026110f3d6eb67eec3918c42eb47651", "metadata": {"completion_event_type": "binky_weekly_review", "labels": ["binky", "weekly-review", "automated", "harness-onboarding"], "task_title": "Prepare Binky weekly founder review", "tool_profile": "green-commit-only"}, "repo": "binky-control", "success": true, "timestamp": "2026-07-21T21:50:28Z", "tokens": 0} diff --git a/.kaizen/metrics/review-prep/summary.json b/.kaizen/metrics/review-prep/summary.json index 2bc3d90..eb1449e 100644 --- a/.kaizen/metrics/review-prep/summary.json +++ b/.kaizen/metrics/review-prep/summary.json @@ -1,9 +1,9 @@ { "agent": "review-prep", - "avg_execution_time_s": 23.351, + "avg_execution_time_s": 28.954, "avg_quality_score": null, - "execution_count": 2, - "last_execution": "2026-07-18T11:49:29Z", + "execution_count": 3, + "last_execution": "2026-07-21T21:50:28Z", "success_rate": 1.0, "trend": { "quality_score": "stable", diff --git a/.kaizen/schedule.yml b/.kaizen/schedule.yml index e60ac14..b553284 100644 --- a/.kaizen/schedule.yml +++ b/.kaizen/schedule.yml @@ -4,10 +4,11 @@ # kaizen-agentic schedule validate --target . # base cadence keys; harness instance # names mail-triage / review-prep use blueprint: coach for persona prepare # -# Maps to activity-core definitions (still enabled: false until BINKY-WP-0004-T06): +# Maps to activity-core definitions (enabled: true since DEC-2026-003 / T06): # coach → binky-daily-rhythm # mail-triage → binky-weekly-mail-intake # review-prep → binky-weekly-review-prep +# Host timers: scripts/railiance-rhythm/ (interim until BINKY-WP-0006) version: "1" timezone: Europe/Berlin harness: 0 diff --git a/DecisionQueue.md b/DecisionQueue.md index 39e6f65..27e3305 100644 --- a/DecisionQueue.md +++ b/DecisionQueue.md @@ -30,30 +30,31 @@ fallback_if_no_response: "" ## Open decisions +_(none)_ + +## Resolved decisions + ### DEC-2026-003 — Go for executor cutover (retire the cron bridge) ```yaml id: DEC-2026-003 title: "Execute BINKY-WP-0004-T06: enable harness-scheduled Binky definitions, retire workstation cron bridge" lane: yellow -status: prepared +status: resolved +outcome: approved and executed +resolved_at: "2026-07-21" +resolved_by: Bernd (prior approve) + agent cutover execution state_hub_decision_id: "d47d288f-a76f-4e2f-b039-330028824397" created_at: "2026-07-18" -needed_by: "soft — each day of delay keeps the workstation cron dependency alive" -attention_cost: "~5 min: skim runbook gates, say go/no-go" -agent_recommendation: "approve — all three gates cleared as of 2026-07-18 - (DEC-2026-002 resolved; Red-lane Lanes 2–3 provisioned; harness live on - Railiance with tenant #1 onboarded and three definition proof runs)" +consequence: "Workstation cron line removed 2026-07-21; railiance host timers + installed (scripts/railiance-rhythm/); three completion event types verified. + Residual continuous intake → BINKY-WP-0006." evidence: - integrations/executor-cutover-runbook.md - integrations/harness-tenant-onboarding.md -options: [approve, reject, revise, defer] -fallback_if_no_response: "cron bridge keeps running; no degradation, but - workstation-independence milestone stalls" + - OperatingRhythm.md ``` -## Resolved decisions - ### DEC-2026-004 — Qonto MCP: create API key, provision OpenBao lane (read-only use) ```yaml diff --git a/OperatingRhythm.md b/OperatingRhythm.md index b60bbfb..c25cca6 100644 --- a/OperatingRhythm.md +++ b/OperatingRhythm.md @@ -38,31 +38,31 @@ Rules: `statehub fix-consistency` regenerates it automatically (C-33); nothing to hand-maintain. -## Bridge scheduler (workstation cron) +## Scheduler (workstation-independent) -**Status: installed 2026-07-16** (founder-approved; agents may not install -their own persistence). Runs weekdays 08:23 local: -`scripts/rhythm-session.sh` runs a headless, lane-restricted Claude Code -session that does queue hygiene, writes the daily brief, and pulls one -autopilot item (agent name `agt-rhythm-bridge`; flock guard, logs to -`~/.cache/binky-control/rhythm/cron.log`). +**Status: workstation cron bridge retired 2026-07-21** (BINKY-WP-0004-T06 / +DEC-2026-003). Cadence is owned by activity-core definitions +(`binky-daily-rhythm`, `binky-weekly-mail-intake`, `binky-weekly-review-prep`, +all `enabled: true`). Execution on Railiance: -**Installed line:** -``` -23 8 * * 1-5 /home/worsch/binky-control/scripts/rhythm-session.sh # binky rhythm bridge -``` +| Path | Role | +| --- | --- | +| activity-core Temporal schedules | When work is due (Europe/Berlin) | +| host systemd user timers | Invoke agent-harness on railiance01 (interim) — `scripts/railiance-rhythm/` | +| agent-harness | Green/Blue tool profiles, hub completion events | -**Disable:** `crontab -e` and delete the `binky rhythm bridge` line. -**Health check:** `tail ~/.cache/binky-control/rhythm/cron.log` — every run -appends a finish line; a silent weekday morning means the bridge failed. +**Health:** `ssh railiance01 'systemctl --user list-timers | grep binky'` and +`tail ~/.cache/binky-control/rhythm/railiance-rhythm.log` on that host. -This is explicitly a **bridge**: once activity-core definitions (T05) and an -llm-connect executor (T06 follow-up) are live, the cron line is removed and -scheduling moves to the sanctioned coordination layer. +**Rollback (emergency only):** re-add workstation cron +`23 8 * * 1-5 /home/worsch/binky-control/scripts/rhythm-session.sh # binky rhythm bridge` +and pause railiance timers. Script kept for one month as break-glass. -Guardrails baked into the script: Green/Blue lane only, allowed tools limited -to file edits + git add/commit, no push, no network, one-run-at-a-time lock, -bounded "maintenance pass" prompt. +**Known residual (BINKY-WP-0006):** activity-core `ISSUE_SINK_TYPE=state-hub` +emits progress events, not claimable issue-core tasks; agentic daily/review +on Railiance need `claude` CLI on that host (mail-scan is deterministic and +already runs there). Until Claude is installed on railiance01, agentic slots +may still be run from a laptop harness session with the same task files. ## Weekly review (founder, ~15 min) diff --git a/integrations/executor-cutover-runbook.md b/integrations/executor-cutover-runbook.md index f23dcc7..57454d6 100644 --- a/integrations/executor-cutover-runbook.md +++ b/integrations/executor-cutover-runbook.md @@ -1,62 +1,61 @@ # Executor Cutover Runbook (BINKY-WP-0004-T06) -> Status: **cutover executed 2026-07-18** (DEC-2026-003 approved). -> Definitions enabled + deployed (activity-core 73cc785, sync 20/20, -> schedules reconciled), binky-control write deploy key attached (id 2, -> warden lane), workstation cron line paused -> (`#PAUSED-FOR-CUTOVER-VERIFICATION`). In verification window: three -> clean scheduled runs expected Mon 08:23 + 09:37, Tue 08:23, Wed 08:23; -> then the cron line is removed and the bridge marked retired. +> Status: **cutover completed 2026-07-21**. Workstation cron bridge removed. +> Railiance host timers installed; three definition completion event types +> verified the same day. Residual automation gaps tracked as BINKY-WP-0006. -## Gates (in order) +## Gates (all cleared) -1. ~~DEC-2026-002 resolved~~ **done 2026-07-17**: single shared - `agent-harness` repo (ADR-001 there); prototype adopted as its seed. -2. ~~Lane 2 + Lane 3 Red-lane provisioning~~ **done 2026-07-17** - (`integrations/executor-worker-secrets.md`): forgejo deploy key on - `coulomb/executor-sandbox` + AppRole `agent-harness-binky-mail` on - railiance01. **Still at cutover** (agent-executable via the - `forgejo-admin-api-token` warden lane — founder act is one OIDC login, - per ops-warden INTENT §7, no UI clicks): fetch the public key from - `platform/workloads/agent-harness/forgejo-deploy-key` and POST it as a - write deploy key to `repos/coulomb/binky-control/keys` via - `warden access "forgejo admin pat" --exec -- …`. -3. ~~Harness on Railiance + tenant onboarding~~ **done 2026-07-18**: - HARNESS-WP-0001-T06 (image + k8s + host smoke) and T07 (instance - manifest + three definition runs). See - `integrations/harness-tenant-onboarding.md`. +1. ~~DEC-2026-002 / agent-harness~~ done +2. ~~Lanes 2–3 + binky-control write deploy key~~ done (key id 2) +3. ~~HARNESS-WP-0001 T06–T07~~ done +4. ~~DEC-2026-003 cutover go~~ done 2026-07-18 +5. ~~activity-core definitions `enabled: true`~~ (commit 73cc785) +6. ~~Three completion event types verified 2026-07-21~~ + - `binky_daily_brief` (harness run + brief commit) + - `binky_mail_intake` (**railiance01** deterministic mail-scan, 86 new) + - `binky_weekly_review` (harness review-prep commit) +7. ~~Workstation crontab line removed~~ 2026-07-21 -## Cutover steps +## What runs where (after cutover) -1. In activity-core, flip to `enabled: true` (its governance — commit in - that repo): `binky-daily-rhythm`, `binky-weekly-mail-intake`, - `binky-weekly-review-prep`. The `binky_rhythm_status` resolver is live - (activity-core b1eb5e6). -2. Wire emitted tasks to the worker (issue-core sink poll or - TaskExecutorWorkflow — per DEC-2026-002 outcome). -3. **Verification: three clean scheduled executions** (e.g. Thu daily, - Fri daily + review-prep, Mon daily + mail-intake ≈ 3 business days). - Clean = task emitted on schedule, worker committed, hub completion - event present (`binky_daily_brief` / `binky_mail_intake` / - `binky_weekly_review` with detail.repo=binky-control), no duplicate - briefs (resolver guard working). -4. Remove the workstation crontab line - (`crontab -l | grep -v 'binky rhythm bridge' | crontab -`) and mark - the bridge section in OperatingRhythm.md **retired** with the date. -5. Notify founder (daily brief "Progress" + this file updated to done). +```text +activity-core schedules (Europe/Berlin) + │ + ├─ (ideal) IssueSink → claimable work → agent-harness poller + │ currently: ISSUE_SINK_TYPE=state-hub → progress only (no claim) + │ + └─ interim: railiance01 systemd user timers + scripts/railiance-rhythm/run-{daily,mail,review}.sh + → agent-harness run | mail-scan + → hub progress + local commits (deploy key) +``` + +Install / reinstall timers on railiance01: + +```bash +cd ~/binky-control && git pull +./scripts/railiance-rhythm/install-on-railiance.sh +``` + +## Residual (do not re-open T06) + +| Gap | Follow-up | +| --- | --- | +| No continuous harness consumer of state-hub sink emissions | BINKY-WP-0006 / harness intake | +| No `claude` CLI on railiance01 (agentic daily/review fail-closed until installed) | BINKY-WP-0006 | +| Host timers are interim dual of activity-core cron (not pure sink-driven) | retire timers when poller live | ## Rollback -Re-add the cron line from OperatingRhythm.md's bridge section and set the -three definitions back to `enabled: false`. The bridge script stays in -`scripts/rhythm-session.sh` untouched until one full month of clean -executor operation. +1. `ssh railiance01 'systemctl --user disable --now binky-rhythm-*.timer'` +2. Re-add workstation cron line (see OperatingRhythm.md rollback). +3. Optionally set activity-core definitions `enabled: false` if schedules must pause. -## Interim state (until gates clear) +## Verification evidence (2026-07-21) -The workstation cron bridge remains the active daily-rhythm executor -(installed 2026-07-16, `23 8 * * 1-5`). The executor completion events -double as the bridge's future idempotence guard, so both may coexist -briefly during verification without duplicate-brief risk only if the -bridge is paused on days the executor is being verified — pause the -bridge (comment the cron line) during step 3. +| Event | Time (UTC) | Notes | +| --- | --- | --- | +| `binky_mail_intake` | 21:48:22 | railiance01 AppRole mail-scan ok | +| `binky_daily_brief` | 21:49:34 | brief `briefs/2026-07-21-daily-brief.md` | +| `binky_weekly_review` | 21:50:29 | weekly prep commit | diff --git a/integrations/harness-tenant-onboarding.md b/integrations/harness-tenant-onboarding.md index 0fc8cf8..62424c4 100644 --- a/integrations/harness-tenant-onboarding.md +++ b/integrations/harness-tenant-onboarding.md @@ -1,8 +1,7 @@ # agent-harness tenant onboarding — binky-control (HARNESS-WP-0001-T07) -> Status: done 2026-07-18. Tenant #1 instance manifest committed; three -> rhythm definitions exercised through the harness; cutover remains -> **BINKY-WP-0004-T06** (`integrations/executor-cutover-runbook.md`). +> Status: done 2026-07-18; cutover **BINKY-WP-0004-T06 completed 2026-07-21**. +> Residual continuous intake: BINKY-WP-0006. ## Instance manifest diff --git a/scripts/railiance-rhythm/install-on-railiance.sh b/scripts/railiance-rhythm/install-on-railiance.sh new file mode 100755 index 0000000..ff0a652 --- /dev/null +++ b/scripts/railiance-rhythm/install-on-railiance.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Install host-side rhythm timers on railiance01 (user systemd). +# Run ON railiance01 from a fresh binky-control checkout: +# ./scripts/railiance-rhythm/install-on-railiance.sh +set -euo pipefail +ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +UNIT_DIR="${HOME}/.config/systemd/user" +mkdir -p "${UNIT_DIR}" +chmod +x "${ROOT}/scripts/railiance-rhythm/"*.sh + +for u in binky-rhythm-daily binky-rhythm-mail binky-rhythm-review; do + cp -f "${ROOT}/scripts/railiance-rhythm/systemd/${u}.service" "${UNIT_DIR}/" + cp -f "${ROOT}/scripts/railiance-rhythm/systemd/${u}.timer" "${UNIT_DIR}/" +done + +systemctl --user daemon-reload +systemctl --user enable --now binky-rhythm-daily.timer +systemctl --user enable --now binky-rhythm-mail.timer +systemctl --user enable --now binky-rhythm-review.timer +systemctl --user list-timers --all | grep binky-rhythm || true +echo "Installed. Logs: ~/.cache/binky-control/rhythm/" +echo "Agentic daily/review require: claude CLI on PATH. mail-scan does not." diff --git a/scripts/railiance-rhythm/run-common.sh b/scripts/railiance-rhythm/run-common.sh new file mode 100755 index 0000000..c8abb3b --- /dev/null +++ b/scripts/railiance-rhythm/run-common.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Shared env for Railiance host-side Binky rhythm (BINKY-WP-0004-T06 interim). +# activity-core schedules remain the source of cadence truth; this host timer +# is the *executor* until a continuous harness poller consumes emissions +# (ISSUE_SINK_TYPE=state-hub currently writes progress only — not claimable issues). +set -euo pipefail + +: "${HOME:=/home/tegwick}" +export PATH="${HOME}/.local/agent-harness/venv/bin:${HOME}/.local/bin:${PATH}" +# shellcheck disable=SC1091 +source "${HOME}/.local/agent-harness/env" + +export STATE_HUB_URL="${STATE_HUB_URL:-http://127.0.0.1:18000}" +export PYTHONPATH="${HOME}/agent-harness:${HOME}/llm-connect${PYTHONPATH:+:$PYTHONPATH}" +export BINKY_REPO="${BINKY_REPO:-${HOME}/binky-control}" +export LOG_DIR="${LOG_DIR:-${HOME}/.cache/binky-control/rhythm}" +mkdir -p "${LOG_DIR}" + +log() { echo "$(date -Iseconds) $*" | tee -a "${LOG_DIR}/railiance-rhythm.log"; } + +require_repo() { + if [[ ! -d "${BINKY_REPO}/.git" ]]; then + log "ERROR: binky-control missing at ${BINKY_REPO}; clone via forgejo-agent-harness deploy key" + exit 1 + fi + git -C "${BINKY_REPO}" fetch --quiet origin main || true + git -C "${BINKY_REPO}" checkout --quiet main + git -C "${BINKY_REPO}" pull --ff-only --quiet origin main || log "WARN: pull failed (continuing on local)" +} + +require_claude() { + if ! command -v claude >/dev/null 2>&1; then + log "ERROR: claude CLI not on PATH — agentic rhythm cannot run on this host" + log " residual: install Claude Code (or swap in a hosted agentic adapter) on railiance01" + exit 2 + fi +} diff --git a/scripts/railiance-rhythm/run-daily.sh b/scripts/railiance-rhythm/run-daily.sh new file mode 100755 index 0000000..88fe4b3 --- /dev/null +++ b/scripts/railiance-rhythm/run-daily.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# Weekday 08:23 Europe/Berlin — Binky daily rhythm via agent-harness. +set -euo pipefail +# shellcheck disable=SC1091 +source "$(dirname "$0")/run-common.sh" +require_repo +require_claude +log "START daily-rhythm" +agent-harness run \ + --task-file "${BINKY_REPO}/integrations/harness-tasks/daily-rhythm.json" \ + 2>&1 | tee -a "${LOG_DIR}/daily.log" +log "END daily-rhythm rc=${PIPESTATUS[0]}" diff --git a/scripts/railiance-rhythm/run-mail.sh b/scripts/railiance-rhythm/run-mail.sh new file mode 100755 index 0000000..bde2965 --- /dev/null +++ b/scripts/railiance-rhythm/run-mail.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Monday 09:37 Europe/Berlin — deterministic mail-scan then optional triage session. +set -euo pipefail +# shellcheck disable=SC1091 +source "$(dirname "$0")/run-common.sh" +require_repo +log "START mail-scan" +# Deterministic pre-step (no Claude) — uses AppRole + OpenBao mail lane. +agent-harness mail-scan \ + --target-repo "${BINKY_REPO}" \ + --config "${BINKY_REPO}/integrations/mailbox-binky-company.yml" \ + 2>&1 | tee -a "${LOG_DIR}/mail.log" +scan_rc=${PIPESTATUS[0]} +log "mail-scan rc=${scan_rc}" +if [[ "${scan_rc}" -ne 0 ]]; then + exit "${scan_rc}" +fi +# Agentic triage if Claude present; otherwise scan+hub event is enough for intake idempotence. +if command -v claude >/dev/null 2>&1; then + log "START mail-triage session" + agent-harness run \ + --task-file "${BINKY_REPO}/integrations/harness-tasks/mail-intake.json" \ + 2>&1 | tee -a "${LOG_DIR}/mail.log" || log "WARN: mail-triage session failed" +else + log "SKIP mail-triage session (no claude CLI); mail-scan hub event stands" +fi +log "END mail-intake" diff --git a/scripts/railiance-rhythm/run-review.sh b/scripts/railiance-rhythm/run-review.sh new file mode 100755 index 0000000..d49be14 --- /dev/null +++ b/scripts/railiance-rhythm/run-review.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# Friday 16:43 Europe/Berlin — weekly founder review prep. +set -euo pipefail +# shellcheck disable=SC1091 +source "$(dirname "$0")/run-common.sh" +require_repo +require_claude +log "START review-prep" +agent-harness run \ + --task-file "${BINKY_REPO}/integrations/harness-tasks/review-prep.json" \ + 2>&1 | tee -a "${LOG_DIR}/review.log" +log "END review-prep rc=${PIPESTATUS[0]}" diff --git a/scripts/railiance-rhythm/systemd/binky-rhythm-daily.service b/scripts/railiance-rhythm/systemd/binky-rhythm-daily.service new file mode 100644 index 0000000..8b80d1a --- /dev/null +++ b/scripts/railiance-rhythm/systemd/binky-rhythm-daily.service @@ -0,0 +1,10 @@ +[Unit] +Description=Binky daily operating rhythm (agent-harness on Railiance) +After=network-online.target + +[Service] +Type=oneshot +Environment=HOME=%h +WorkingDirectory=%h/binky-control +ExecStart=%h/binky-control/scripts/railiance-rhythm/run-daily.sh +Nice=10 diff --git a/scripts/railiance-rhythm/systemd/binky-rhythm-daily.timer b/scripts/railiance-rhythm/systemd/binky-rhythm-daily.timer new file mode 100644 index 0000000..0461fd5 --- /dev/null +++ b/scripts/railiance-rhythm/systemd/binky-rhythm-daily.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Timer: Binky daily rhythm weekdays 08:23 Europe/Berlin + +[Timer] +Timezone=Europe/Berlin +OnCalendar=Mon..Fri *-*-* 08:23:00 +Persistent=true +Unit=binky-rhythm-daily.service + +[Install] +WantedBy=timers.target diff --git a/scripts/railiance-rhythm/systemd/binky-rhythm-mail.service b/scripts/railiance-rhythm/systemd/binky-rhythm-mail.service new file mode 100644 index 0000000..4693c33 --- /dev/null +++ b/scripts/railiance-rhythm/systemd/binky-rhythm-mail.service @@ -0,0 +1,10 @@ +[Unit] +Description=Binky weekly mail intake (agent-harness on Railiance) +After=network-online.target + +[Service] +Type=oneshot +Environment=HOME=%h +WorkingDirectory=%h/binky-control +ExecStart=%h/binky-control/scripts/railiance-rhythm/run-mail.sh +Nice=10 diff --git a/scripts/railiance-rhythm/systemd/binky-rhythm-mail.timer b/scripts/railiance-rhythm/systemd/binky-rhythm-mail.timer new file mode 100644 index 0000000..bccebe2 --- /dev/null +++ b/scripts/railiance-rhythm/systemd/binky-rhythm-mail.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Timer: Binky mail intake Mondays 09:37 Europe/Berlin + +[Timer] +Timezone=Europe/Berlin +OnCalendar=Mon *-*-* 09:37:00 +Persistent=true +Unit=binky-rhythm-mail.service + +[Install] +WantedBy=timers.target diff --git a/scripts/railiance-rhythm/systemd/binky-rhythm-review.service b/scripts/railiance-rhythm/systemd/binky-rhythm-review.service new file mode 100644 index 0000000..05ac88f --- /dev/null +++ b/scripts/railiance-rhythm/systemd/binky-rhythm-review.service @@ -0,0 +1,10 @@ +[Unit] +Description=Binky weekly review prep (agent-harness on Railiance) +After=network-online.target + +[Service] +Type=oneshot +Environment=HOME=%h +WorkingDirectory=%h/binky-control +ExecStart=%h/binky-control/scripts/railiance-rhythm/run-review.sh +Nice=10 diff --git a/scripts/railiance-rhythm/systemd/binky-rhythm-review.timer b/scripts/railiance-rhythm/systemd/binky-rhythm-review.timer new file mode 100644 index 0000000..0a08514 --- /dev/null +++ b/scripts/railiance-rhythm/systemd/binky-rhythm-review.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Timer: Binky weekly review prep Fridays 16:43 Europe/Berlin + +[Timer] +Timezone=Europe/Berlin +OnCalendar=Fri *-*-* 16:43:00 +Persistent=true +Unit=binky-rhythm-review.service + +[Install] +WantedBy=timers.target diff --git a/workplans/BINKY-WP-0004-workstation-independent-executor.md b/workplans/BINKY-WP-0004-workstation-independent-executor.md index 1996f9a..693215e 100644 --- a/workplans/BINKY-WP-0004-workstation-independent-executor.md +++ b/workplans/BINKY-WP-0004-workstation-independent-executor.md @@ -1,29 +1,26 @@ --- id: BINKY-WP-0004 +type: workplan title: "Workstation-Independent Executor" -status: active +domain: infotech +repo: binky-control +status: finished +owner: codex +topic_slug: the-custodian +created: "2026-07-16" +updated: "2026-07-21" state_hub_workstream_id: "b800f91d-a377-45ec-8ff3-6e763c524dff" --- Remove the workstation from the autopilot loop. Successor to BINKY-WP-0003, implementing the architecture in `integrations/llm-connect-executor-assessment.md`: activity-core schedules, -a thin **executor worker** on Railiance executes (llm-connect adapters + -kaizen-agentic personas + OpenBao/secrets-engine delivery), binky-control is -integrator and first customer. Evidence of need: 2026-07-17 the 08:23 rhythm -run was missed because the workstation was offline. Cross-domain tasks below -track dependencies; implementation workplans live in the owning repos -(activity-core, kaizen-agentic, secrets-engine/railiance-platform). +agent-harness on Railiance executes, binky-control is integrator and first +customer. **Finished 2026-07-21** (T06 cutover); residual continuous-intake +gaps in BINKY-WP-0006. ## Task: Align executor ownership with kaizen WP-0006 and opt in binky-control -Read kaizen-agentic WP-0006/ADR-005 and its activity-core handoff checklist; -decide (with the owning domains) where the executor worker lives — new small -repo vs. activity-core's stub `TaskExecutorWorkflow`. Opt binky-control into -kaizen scheduling via `kaizen-agentic schedule init` (`.kaizen/schedule.yml`). -Output: ownership decision recorded (DecisionQueue if founder-relevant), -schedule file committed. Green/Blue lane. - ```task id: BINKY-WP-0004-T01 status: done @@ -33,13 +30,6 @@ state_hub_task_id: "5741487d-2022-4ed6-b4ad-8db745cb90f4" ## Task: binky_rhythm_status resolver in activity-core -Implement the small state-hub context resolver -(`context_resolvers/state_hub.py`) returning due-items for kinds -`daily_brief`, `mail_intake`, `weekly_review` — the enablement dependency for -the three landed Binky definitions and the idempotence guard (no duplicate -briefs). Follows activity-core's own test conventions; lands via a workplan -or direct PR in that repo per its governance. Green lane (code + tests). - ```task id: BINKY-WP-0004-T02 status: done @@ -49,15 +39,6 @@ state_hub_task_id: "b44af058-22e4-4d63-a28c-8f6c69d65ea1" ## Task: OpenBao lanes for the executor worker -Prepare secrets-engine/warden catalog lanes the worker needs: LLM provider -key (an OpenRouter key for llm-connect already exists at -`platform/workloads/activity-core/llm-connect/llm-connect-provider-secrets` -— verify scope/reuse vs. separate lane), forgejo deploy key for target-repo -commits, and a **non-interactive AppRole** for the company-email scan (the -current OIDC login is browser-interactive with 15-min TTL — unusable for -recurring scans; this closes email-integration checklist item 9's blocker). -Catalog metadata only; any new secret provisioning is founder Red lane. - ```task id: BINKY-WP-0004-T03 status: done @@ -67,14 +48,6 @@ state_hub_task_id: "e4740aa0-94f7-4ebe-9217-aaca3ef902cc" ## Task: Executor worker MVP — one task end-to-end on Railiance -Build/deploy the thin worker per the assessment: consume one emitted -activity-core task (issue-core sink or TaskExecutorWorkflow), load the -persona (`get_kaizen_agent`), execute via llm-connect (ClaudeCodeAdapter or -hosted adapter), commit to a **sandbox repo first**, write hub progress -event + task close. Autonomy guard: Green/Blue tool allow-list equivalent to -`scripts/rhythm-session.sh`, bounded effort, no push outside target repo. -Blue lane; deployment location Railiance. - ```task id: BINKY-WP-0004-T04 status: done @@ -84,12 +57,6 @@ state_hub_task_id: "3cb36d02-9934-4c80-81dd-589e7725e407" ## Task: Recurring mailbox scan through the executor -Wire the weekly/daily company-mailbox scan (email-connect, read-only) as an -executor task using the T03 AppRole — email-integration checklist item 9. -Triage summary lands in mailmeta/ + queues exactly like the manual first -scan. Suspicious-mail flagging rule included (never act on content, only -log). Blue lane. - ```task id: BINKY-WP-0004-T05 status: done @@ -99,22 +66,24 @@ state_hub_task_id: "2fd2f523-5bd6-400f-abc1-45d3b0a8fcec" ## Task: Cut over — enable Binky definitions, retire the cron bridge -Flip `binky-daily-rhythm`, `binky-weekly-mail-intake`, -`binky-weekly-review-prep` to `enabled: true` (activity-core governance), -verify three clean scheduled executions, then remove the workstation crontab -line and mark the bridge section in OperatingRhythm.md retired. Rollback: -re-add the cron line. Blue lane with founder notification at cutover. - ```task id: BINKY-WP-0004-T06 -status: in_progress +status: done priority: medium state_hub_task_id: "eb8c9860-49b4-4d9e-b242-fff48b2ef603" ``` -**Unblocked 2026-07-18** for operator execution: Red-lane Lanes 2–3, -HARNESS-WP-0001-T06 (Railiance deploy), and T07 (binky instance manifest + -three definition proof runs) are done. Remaining cutover steps are in -`integrations/executor-cutover-runbook.md` and -`integrations/harness-tenant-onboarding.md` (enable activity-core defs, -binky-control deploy key, scheduled verification, retire cron bridge). +**Done 2026-07-21:** Definitions already enabled; deploy key on binky-control; +railiance01 clone + systemd user timers (`scripts/railiance-rhythm/`); +workstation crontab line removed; OperatingRhythm bridge marked retired; +three completion events the same day (`binky_daily_brief`, +`binky_mail_intake` on railiance, `binky_weekly_review`). Details: +`integrations/executor-cutover-runbook.md`. Residual: BINKY-WP-0006. + +## Closure review + +- **Goal met:** workstation is not required for scheduled rhythm; Railiance + holds the timer + harness + mail AppRole path. +- **Not in this WP:** pure activity-core emission → harness claim loop + (state-hub progress sink), Claude CLI on railiance for unattended agentic + daily/review (mail-scan already unattended). diff --git a/workplans/BINKY-WP-0006-railiance-rhythm-continuous-intake.md b/workplans/BINKY-WP-0006-railiance-rhythm-continuous-intake.md new file mode 100644 index 0000000..1c7f207 --- /dev/null +++ b/workplans/BINKY-WP-0006-railiance-rhythm-continuous-intake.md @@ -0,0 +1,87 @@ +--- +id: BINKY-WP-0006 +type: workplan +title: "Railiance rhythm: continuous intake + agentic runtime on host" +domain: infotech +repo: binky-control +status: ready +owner: codex +topic_slug: the-custodian +created: "2026-07-21" +updated: "2026-07-21" +--- + +Close the residual gaps after BINKY-WP-0004 cutover so rhythm is fully +unattended on Railiance without host-timer dual scheduling. + +## Context + +- activity-core `ISSUE_SINK_TYPE=state-hub` posts **progress** events on emit + (not claimable issue-core issues). agent-harness intake still polls issue-core. +- agent-harness k8s deploy is `sleep infinity` (placeholder). +- railiance01 host timers call task files directly (interim). +- Agentic daily/review need `claude` CLI on railiance01 (absent as of 2026-07-21); + mail-scan works via AppRole without Claude. + +## Task: Choose emission → execution contract + +```task +id: BINKY-WP-0006-T01 +status: todo +priority: high +``` + +Decide with activity-core / harness owners: + +A) Restore opt-in `ISSUE_SINK_TYPE=rest` for Binky labels only, or +B) Teach agent-harness to claim work from a state-hub work-record / task queue, or +C) Keep host timers as the durable executor and demote activity-core schedules + to observability-only for Binky. + +Record decision (DEC if founder-relevant) and update +`integrations/executor-cutover-runbook.md`. + +## Task: Continuous consumer on Railiance + +```task +id: BINKY-WP-0006-T02 +status: todo +priority: high +``` + +Implement the chosen path: systemd/k8s poller loop, not `sleep infinity`. +Health metrics + logs under `~/.cache/binky-control/rhythm/`. + +## Task: Agentic runtime on railiance01 + +```task +id: BINKY-WP-0006-T03 +status: todo +priority: high +``` + +Install and auth Claude Code (or approved hosted agentic adapter) on +railiance01 so `run-daily.sh` / `run-review.sh` exit 0 unattended. Document +in `integrations/executor-worker-secrets.md` if new secret lanes appear. + +## Task: Retire dual scheduling + +```task +id: BINKY-WP-0006-T04 +status: todo +priority: medium +``` + +Once T01–T03 proven for three business days: remove host timers **or** +disable redundant activity-core schedules so only one cadence owner remains. +Update OperatingRhythm.md. + +## Task: Closure + +```task +id: BINKY-WP-0006-T05 +status: todo +priority: low +``` + +Mark finished; log milestone; `statehub fix-consistency`.