feat: CEO Phase 1 — weekly board digest (convention opt-in via .agent/ceo.md) #246

Merged
joshtronic merged 5 commits from feat/ceo into master 2026-06-25 04:24:16 +00:00
Collaborator

What this is

CEO Phase 1 — a weekly harness pass that, for each repo carrying a root .agent/ceo.md mandate, reads the mandate + gathers that repo's week and emails a strategic board digest assessing progress against the mandate's ranked priorities. Convention opt-in: the mandate's mere presence opts a repo in (like logwatch's systemd/ and the review's merge), and the mandate itself is the model's system prompt. Read-only — it reports, it does not act. The agency (issue-filing, steering, mandate redlines) is the mandate's own roadmap for later phases ("start tight, loosen as trust earns it").

Phased on this trunk

  • P1 (0805f3b) — lib/ceo.sh read side: .agent/ceo.md opt-in detection + the weekly activity gather (PRs merged / issues opened+closed / open Agent queue). Proven live against porksicle.
  • P2 (c665806) — the pass: bin/lib/ceo-digest-directive.md (the CEO-persona prompt) + do_ceo_tick (model call → parse → email, per-repo .ceo weekly slot), cascade-wired after sports, below the health gate.
  • P3 (e45d584) — CLAUDE.md docs.

Live-validated — the actual digest it produced

Ran the full pipeline against porksicle.com (gather → mandate → claude_call → parse). Real output:

[CEO] Porksicle — week of Jun 18: foundations solid, SEO queue empty

The one thing that matters: SEO is Priority #1 and the Agent queue has zero SEO issues — only bug #51. That's the miss. SEO foundations shipped, but foundations aren't a strategy.

The real win: npm run verify (Playwright smoke, #46) — turns "play-test before merge" from a manual promise into an enforced gate. The seed of Priority #2's regression harness.

Next week's theme: SEO — foundations → content depth. One SEO issue/day into the queue: structured-data richness, hub-page content, internal-linking audit, indexing health.

Asks for the board: (1) GSC access confirmed? Can't track indexing without it. (2) Feedback triage — is anything actionable in the form→sheet loop yet?

(full digest in the PR thread / reproducible via the pipeline)

It found the real miss on its own, flagged the right win, set a priority-derived theme, and made board-level asks — a CEO digest, not a changelog.

Notes

  • No OUTCOME label (email-only, like sports) → check-sync green; bash -n clean.
  • CEO_RECIPIENTS (optional, falls back to SEO_PRIMARY_EMAIL); needs SMTP2GO. No recipient or no .agent/ceo.md repo → clean no-op. The HTML email reuses the proven sports renderer.
  • Leaves the shadow-review bullet's "analysis set" text alone — #244 rewrites that (different hunk, no conflict).

Phase 2+ (the CEO's actual authority) lands as deliberate, human-gated follow-ups.

## What this is **CEO Phase 1** — a weekly harness pass that, for each repo carrying a root `.agent/ceo.md` mandate, reads the mandate + gathers that repo's week and emails a strategic **board digest** assessing progress against the mandate's ranked priorities. Convention opt-in: the mandate's mere presence opts a repo in (like logwatch's `systemd/` and the review's merge), and the mandate itself is the model's system prompt. **Read-only** — it reports, it does not act. The agency (issue-filing, steering, mandate redlines) is the mandate's own roadmap for later phases ("start tight, loosen as trust earns it"). ## Phased on this trunk - **P1** (`0805f3b`) — `lib/ceo.sh` read side: `.agent/ceo.md` opt-in detection + the weekly activity gather (PRs merged / issues opened+closed / open Agent queue). Proven live against porksicle. - **P2** (`c665806`) — the pass: `bin/lib/ceo-digest-directive.md` (the CEO-persona prompt) + `do_ceo_tick` (model call → parse → email, per-repo `.ceo` weekly slot), cascade-wired after sports, below the health gate. - **P3** (`e45d584`) — CLAUDE.md docs. ## Live-validated — the actual digest it produced Ran the full pipeline against `porksicle.com` (gather → mandate → `claude_call` → parse). Real output: > **[CEO] Porksicle — week of Jun 18: foundations solid, SEO queue empty** > > **The one thing that matters:** SEO is Priority #1 and the `Agent` queue has **zero SEO issues** — only bug #51. That's the miss. SEO foundations shipped, but foundations aren't a strategy. > > **The real win:** `npm run verify` (Playwright smoke, #46) — turns "play-test before merge" from a manual promise into an enforced gate. The seed of Priority #2's regression harness. > > **Next week's theme: SEO — foundations → content depth.** One SEO issue/day into the queue: structured-data richness, hub-page content, internal-linking audit, indexing health. > > **Asks for the board:** (1) GSC access confirmed? Can't track indexing without it. (2) Feedback triage — is anything actionable in the form→sheet loop yet? > > *(full digest in the PR thread / reproducible via the pipeline)* It found the real miss on its own, flagged the right win, set a priority-derived theme, and made board-level asks — a CEO digest, not a changelog. ## Notes - No `OUTCOME` label (email-only, like sports) → `check-sync` green; `bash -n` clean. - `CEO_RECIPIENTS` (optional, falls back to `SEO_PRIMARY_EMAIL`); needs SMTP2GO. No recipient or no `.agent/ceo.md` repo → clean no-op. The HTML email reuses the proven sports renderer. - Leaves the shadow-review bullet's "analysis set" text alone — **#244** rewrites that (different hunk, no conflict). Phase 2+ (the CEO's actual authority) lands as deliberate, human-gated follow-ups.
lib/ceo.sh: the CEO pass's read side.
- Convention opt-in: ceo_repo_has_mandate keys off .agent/ceo.md presence
  (like logwatch's systemd/ dir), no env knob or hardcoded repo.
- ceo_read_mandate: fetch the board mandate.
- ceo_gather_week: PRs merged / issues opened+closed / open Agent queue since
  a date -- the evidence base for the board digest, at PR-level granularity
  (porksicle is PR-to-master only, per its charter).

Proven live against porksicle.com: opt-in detected, mandate read, week
gathered (the merged_at window verified correct -- the repo is 5 days old, so
week 1 is the whole 100-game grind).

Phase 1 of the feat/ceo trunk. No cascade wiring yet (P2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011KXPafSYJPY6XkWHHk1Lfs
- bin/lib/ceo-digest-directive.md: the CEO-persona system prompt (be the
  CEO, read the mandate, write the board digest; SUBJECT:/===BODY=== contract).
- lib/ceo.sh: ceo_build_prompt + ceo_parse_response + ceo_render_html (the
  sports renderer) + per-repo .ceo weekly-slot state helpers.
- tick.sh: source lib/ceo.sh; do_ceo_tick (convention opt-in via .agent/ceo.md,
  one repo/tick, weekly slot, claude_call digest -> email); cascade call after
  sports, before logwatch. No OUTCOME label (email-only, like sports) so
  check-sync stays green.

Phase 2 of feat/ceo. Syntax + check-sync clean; live digest test + docs are P3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011KXPafSYJPY6XkWHHk1Lfs
feat(ceo): P3 -- document the CEO board-digest pass in CLAUDE.md
All checks were successful
Lint / check-sync (push) Successful in 4s
Lint / check-sync (pull_request) Successful in 4s
e45d584559
Cascade-order sentence + a Gotchas bullet: convention opt-in via .agent/ceo.md,
weekly per-repo, below the health gate, SUBJECT:/===BODY=== parse, Phase 1
read-only (agency deferred to later phases). Leaves the shadow-review bullet's
analysis-set text alone -- #244 rewrites that (different hunk).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011KXPafSYJPY6XkWHHk1Lfs
Author
Collaborator

🤖 Review — REQUEST_CHANGES (automated)

CI for e45d5845: pending

Summary: Adds a weekly, convention-opt-in (.agent/ceo.md) "CEO board digest" — a read-only model pass that gathers a repo's week and emails a strategic digest. Code is well-structured, scoped, and read-only with limited blast radius. But it ships ~200 lines of new parsing/rendering/state logic with zero tests, and CI is pending so I can't confirm the branch is green. Both block APPROVE.

Blocking

  • No tests added (contract violation). lib/ceo.sh introduces several pure, directly-testable functions — ceo_parse_response (sentinel parsing + blank-collapsing awk), ceo_render_html (markdown→HTML), ceo_week_done/ceo_mark_week_done (state round-trip), and the ceo_gather_week jq filters — and the diff adds no test for any of them. The author states these "mirror sports-digest.sh"; if that mirror has unit tests, this needs the parallel set, and if it doesn't, say so explicitly. "Live-validated against porksicle" is a one-shot manual run, not a regression guard. Add tests for at least ceo_parse_response (happy path, missing ===BODY===, empty body, missing SUBJECT:) and the state functions.
  • CI is pending. I cannot confirm bash -n / check-sync are actually green — the description asserts it but the objective signal isn't there yet. Hold until CI reports success; a failure here would be a hard block.

Correctness / robustness notes (worth fixing while reworking)

  • bin/tick.sh do_ceo_tick reads <<<"$ANALYSIS_REPOS_JSON" with a bare expansion (no ${...:-}). If this harness runs under set -u and that global is ever unset when the cascade reaches the CEO tick, the whole tick aborts. Confirm it's guaranteed-set by this point (sports presumably relies on the same global), or guard it.
  • lib/ceo.sh mandate double-fetch: ceo_repo_has_mandate does a GET, then ceo_read_mandate does a second identical GET, then you check [ -n "$mandate" ]. The existence check is redundant — reading and testing non-empty already covers opt-in. Minor, but it's an extra API round-trip per repo per tick.
  • ceo_mark_week_done: on jq failure the mktemp file is never cleaned up (&& mv short-circuits, temp leaks). Low impact but trivially fixed with a trap or rm -f fallback.
  • Week-boundary mismatch: the dedup stamp uses local date +%G-W%V while the gather window uses date -u -d '7 days ago'. Around week/timezone boundaries these can disagree. Cosmetic for a digest, but flagging.

Security

  • Prompt-injection surface: the entire .agent/ceo.md mandate is fetched from a repo and fed as the model's north-star prompt. A hostile/compromised repo could steer digest content. Phase 1 is read-only (email-only, no issue-filing/steering), so blast radius is bounded to email text — acceptable here, but this surface widens materially in the "later phases" the description previews, and should be re-reviewed then. Note for the human, not a block.
  • No CI-config changes, no secret leakage, no command/path injection beyond the forgejo-constrained repo name interpolated into _fj URLs.

Scope / checklist

Scope is clean and matches the three-phase framing (lib read-side, the pass + directive, CLAUDE.md docs). The narrative "checklist" items I can verify against the diff (P1/P2/P3 contents, cascade placement after sports/below health gate) all check out. The live-digest output and bash -n/check-sync green claims are unverifiable from here — the latter is exactly what pending CI needs to confirm.

Bottom line: add tests for the new functions and let CI go green; the rest are minor cleanups.


Independent review by the harness on claude-opus-4-8. The human reviewer is requested once Igor has reviewed; a human still merges.

### 🤖 Review — `REQUEST_CHANGES` _(automated)_ CI for `e45d5845`: **pending** **Summary:** Adds a weekly, convention-opt-in (`.agent/ceo.md`) "CEO board digest" — a read-only model pass that gathers a repo's week and emails a strategic digest. Code is well-structured, scoped, and read-only with limited blast radius. But it ships ~200 lines of new parsing/rendering/state logic with **zero tests**, and **CI is pending** so I can't confirm the branch is green. Both block APPROVE. ### Blocking - **No tests added (contract violation).** `lib/ceo.sh` introduces several pure, directly-testable functions — `ceo_parse_response` (sentinel parsing + blank-collapsing awk), `ceo_render_html` (markdown→HTML), `ceo_week_done`/`ceo_mark_week_done` (state round-trip), and the `ceo_gather_week` jq filters — and the diff adds no test for any of them. The author states these "mirror `sports-digest.sh`"; if that mirror has unit tests, this needs the parallel set, and if it doesn't, say so explicitly. "Live-validated against porksicle" is a one-shot manual run, not a regression guard. Add tests for at least `ceo_parse_response` (happy path, missing `===BODY===`, empty body, missing `SUBJECT:`) and the state functions. - **CI is `pending`.** I cannot confirm `bash -n` / `check-sync` are actually green — the description asserts it but the objective signal isn't there yet. Hold until CI reports `success`; a `failure` here would be a hard block. ### Correctness / robustness notes (worth fixing while reworking) - **`bin/tick.sh` `do_ceo_tick`** reads `<<<"$ANALYSIS_REPOS_JSON"` with a bare expansion (no `${...:-}`). If this harness runs under `set -u` and that global is ever unset when the cascade reaches the CEO tick, the whole tick aborts. Confirm it's guaranteed-set by this point (sports presumably relies on the same global), or guard it. - **`lib/ceo.sh` mandate double-fetch:** `ceo_repo_has_mandate` does a GET, then `ceo_read_mandate` does a second identical GET, then you check `[ -n "$mandate" ]`. The existence check is redundant — reading and testing non-empty already covers opt-in. Minor, but it's an extra API round-trip per repo per tick. - **`ceo_mark_week_done`:** on `jq` failure the `mktemp` file is never cleaned up (`&& mv` short-circuits, temp leaks). Low impact but trivially fixed with a trap or `rm -f` fallback. - **Week-boundary mismatch:** the dedup stamp uses local `date +%G-W%V` while the gather window uses `date -u -d '7 days ago'`. Around week/timezone boundaries these can disagree. Cosmetic for a digest, but flagging. ### Security - **Prompt-injection surface:** the entire `.agent/ceo.md` mandate is fetched from a repo and fed as the model's north-star prompt. A hostile/compromised repo could steer digest content. Phase 1 is read-only (email-only, no issue-filing/steering), so blast radius is bounded to email text — acceptable here, but this surface widens materially in the "later phases" the description previews, and should be re-reviewed then. Note for the human, not a block. - No CI-config changes, no secret leakage, no command/path injection beyond the forgejo-constrained `repo` name interpolated into `_fj` URLs. ### Scope / checklist Scope is clean and matches the three-phase framing (lib read-side, the pass + directive, CLAUDE.md docs). The narrative "checklist" items I can verify against the diff (P1/P2/P3 contents, cascade placement after sports/below health gate) all check out. The live-digest output and `bash -n`/`check-sync` green claims are unverifiable from here — the latter is exactly what pending CI needs to confirm. Bottom line: add tests for the new functions and let CI go green; the rest are minor cleanups. --- <sub>Independent review by the harness on `claude-opus-4-8`. The human reviewer is requested once Igor has reviewed; a human still merges.</sub> <!-- review sha=e45d584559cad1fb0d2047b7fd633237a3ffc58a verdict=REQUEST_CHANGES ci=pending -->
igor added spent time 2026-06-25 03:47:41 +00:00
1 minute 49 seconds
igor self-assigned this 2026-06-25 03:47:42 +00:00
igor removed their assignment 2026-06-25 04:01:48 +00:00
feat: add CEO unit tests and wire them into check-sync.sh CI gate
All checks were successful
Lint / check-sync (push) Successful in 5s
Lint / check-sync (pull_request) Successful in 4s
639d288975
igor added spent time 2026-06-25 04:01:49 +00:00
11 minutes 39 seconds
Author
Collaborator

🤖 Review — COMMENT (automated)

CI for 639d2889: success

Summary: Adds CEO Phase 1 — a weekly, read-only board digest for any repo carrying a root .agent/ceo.md (lib/ceo.sh + do_ceo_tick + directive + unit tests + docs). Well-structured, CI green, no workflow files touched, no OUTCOME label. The pure-function logic is genuinely tested. My reservation is that the integration path is unverifiable from the diff and untested, so I can't reach a confident APPROVE — handing to the human.

Why not APPROVE (unverifiable integration points):

  • do_ceo_tick itself has no test coveragetest-ceo.sh exercises only the pure helpers (ceo_parse_response, ceo_render_html, state round-trip, ceo_gather_week with a stubbed _fj). The orchestration — claude_call "$AGENT_MODEL" "ceo-digest" 8000 ... arg order, email_send "$subject" "$html" "$body" "$recipients" arg order, and the <<<"$ANALYSIS_REPOS_JSON" line-by-line jq -r '.full_name' (assumes JSON-lines, not a JSON array) — can't be confirmed from the diff. If ANALYSIS_REPOS_JSON is actually a JSON array, the per-line jq would silently produce nothing and the tick would no-op. Please confirm these match the sports/logwatch precedents they claim to mirror.
  • "Below the health gate" — the cascade snippet shows do_ceo_tick after do_sports_tick, but the health gate itself isn't in the diff. Trusting the claim; a human can eyeball placement.

Concrete findings (worth fixing, none hard-blocking):

  • lib/ceo.sh ceo_gather_week header comment claims it gathers "commits to the default branch" — the implementation gathers no commits (only PRs, issues, Agent queue). Misleading comment; trim it.
  • bin/tick.sh line . "$AGENT_HOME/lib/ceo.sh" is missing the # shellcheck source=lib/ceo.sh directive that the adjacent espn.sh/sports-digest.sh sources carry. Won't fail the check-sync CI step, but make lint (shellcheck) will likely emit SC1091. Add for consistency.
  • Diff is ~450 added lines, modestly over the ~400 guideline. It's a cohesive feature+tests+docs so I'm not blocking on it, just noting.

Minor / non-blocking:

  • ceo_render_html is a copy of the sports renderer rather than a shared function ("same renderer" per the comment) — link-substitution doesn't sanitize javascript: hrefs, but the audience is the operator's own inbox and the inputs are operator-controlled repos, so low risk. Same posture as the existing sports digest.
  • The mandate file is fed as the model's system prompt (ceo_read_mandateclaude_call). That's prompt-injection-by-design, but Phase 1 is strictly read-only (email only), so blast radius is a weird email. Acceptable for this phase; flag if Phase 2 grants write authority.

Honesty check: The phase breakdown (P1 read side, P2 pass+directive, P3 docs) all map to real hunks. check-sync.sh now discovering/running bin/test-*.sh is a sensible, in-scope addition to make the new tests gate in CI. No fabricated claims spotted; the live-validation output is plausible but unverifiable on my end.

Bottom line: No hard defect, CI green, scope is honest — but the untested do_ceo_tick integration and a couple of unverifiable call signatures keep me from APPROVE. A human should sanity-check the claude_call/email_send arg orders and the ANALYSIS_REPOS_JSON format against their existing tick conventions before merge.


Independent review by the harness on claude-opus-4-8. The human reviewer is requested once Igor has reviewed; a human still merges.

### 🤖 Review — `COMMENT` _(automated)_ CI for `639d2889`: **success** **Summary:** Adds CEO Phase 1 — a weekly, read-only board digest for any repo carrying a root `.agent/ceo.md` (`lib/ceo.sh` + `do_ceo_tick` + directive + unit tests + docs). Well-structured, CI green, no workflow files touched, no `OUTCOME` label. The pure-function logic is genuinely tested. My reservation is that the *integration* path is unverifiable from the diff and untested, so I can't reach a confident APPROVE — handing to the human. **Why not APPROVE (unverifiable integration points):** - `do_ceo_tick` itself has **no test coverage** — `test-ceo.sh` exercises only the pure helpers (`ceo_parse_response`, `ceo_render_html`, state round-trip, `ceo_gather_week` with a stubbed `_fj`). The orchestration — `claude_call "$AGENT_MODEL" "ceo-digest" 8000 ...` arg order, `email_send "$subject" "$html" "$body" "$recipients"` arg order, and the `<<<"$ANALYSIS_REPOS_JSON"` line-by-line `jq -r '.full_name'` (assumes JSON-lines, not a JSON array) — can't be confirmed from the diff. If `ANALYSIS_REPOS_JSON` is actually a JSON array, the per-line `jq` would silently produce nothing and the tick would no-op. Please confirm these match the sports/logwatch precedents they claim to mirror. - "Below the health gate" — the cascade snippet shows `do_ceo_tick` after `do_sports_tick`, but the health gate itself isn't in the diff. Trusting the claim; a human can eyeball placement. **Concrete findings (worth fixing, none hard-blocking):** - `lib/ceo.sh` `ceo_gather_week` header comment claims it gathers "**commits to the default branch**" — the implementation gathers no commits (only PRs, issues, Agent queue). Misleading comment; trim it. - `bin/tick.sh` line `. "$AGENT_HOME/lib/ceo.sh"` is missing the `# shellcheck source=lib/ceo.sh` directive that the adjacent `espn.sh`/`sports-digest.sh` sources carry. Won't fail the check-sync CI step, but `make lint` (shellcheck) will likely emit SC1091. Add for consistency. - Diff is ~450 added lines, modestly over the ~400 guideline. It's a cohesive feature+tests+docs so I'm not blocking on it, just noting. **Minor / non-blocking:** - `ceo_render_html` is a copy of the sports renderer rather than a shared function ("same renderer" per the comment) — link-substitution doesn't sanitize `javascript:` hrefs, but the audience is the operator's own inbox and the inputs are operator-controlled repos, so low risk. Same posture as the existing sports digest. - The mandate file is fed as the model's system prompt (`ceo_read_mandate` → `claude_call`). That's prompt-injection-by-design, but Phase 1 is strictly read-only (email only), so blast radius is a weird email. Acceptable for this phase; flag if Phase 2 grants write authority. **Honesty check:** The phase breakdown (P1 read side, P2 pass+directive, P3 docs) all map to real hunks. `check-sync.sh` now discovering/running `bin/test-*.sh` is a sensible, in-scope addition to make the new tests gate in CI. No fabricated claims spotted; the live-validation output is plausible but unverifiable on my end. **Bottom line:** No hard defect, CI green, scope is honest — but the untested `do_ceo_tick` integration and a couple of unverifiable call signatures keep me from APPROVE. A human should sanity-check the `claude_call`/`email_send` arg orders and the `ANALYSIS_REPOS_JSON` format against their existing tick conventions before merge. --- <sub>Independent review by the harness on `claude-opus-4-8`. The human reviewer is requested once Igor has reviewed; a human still merges.</sub> <!-- review sha=639d2889759987fd0eae9430807a71f87927f7c8 verdict=COMMENT ci=success -->
igor added spent time 2026-06-25 04:06:13 +00:00
2 minutes 9 seconds
igor self-assigned this 2026-06-25 04:10:27 +00:00
igor removed their assignment 2026-06-25 04:11:42 +00:00
igor added spent time 2026-06-25 04:13:11 +00:00
2 minutes 6 seconds
Merge remote-tracking branch 'origin/master' into feat/ceo
All checks were successful
Lint / check-sync (push) Successful in 4s
Lint / check-sync (pull_request) Successful in 4s
cfab8984d5
joshtronic deleted branch feat/ceo 2026-06-25 04:24:16 +00:00
joshtronic approved these changes 2026-06-25 16:59:05 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
2 participants
Notifications
Total time spent: 17 minutes 43 seconds
igor
17 minutes 43 seconds
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
joshtronic/igor!246
No description provided.