feat(ceo): pull GSC on-demand into the digest, keyed on agent.json .seo.domain #299
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
2 participants
Notifications
Total time spent: 1 minute 21 seconds
Due date
igor
1 minute 21 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!299
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/ceo-gsc-ondemand"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
PR 2 of the agent-ification work. Makes the CEO read its own scoreboard — directly answers the CEO's board question #37 ("zero GSC metrics, I can't assess delta").
What
The CEO digest read live numbers only from
agent.json .ceo.metrics_url. A GSC-scoreboard repo like vps-showdown (mandate names impressions/clicks/CTR/position as the scoreboard) has no metrics_url, so the digest came up empty and the CEO filed #37 asking for the data.Now the CEO reads Google Search Console itself, keyed on the
.seo.domainfield PR #298 established — and it does not wait for the monthly SEO pass. It's the boss; it reads the scoreboard whenever it runs.ceo_read_gsc(repo):agent.json .seo.domain(no domain → clean no-op, non-SEO repos unchanged);seo_window+ the existing GSC client), so the trend is self-contained — no persisted state;Unconfigured or failed GSC fetch → a "scoreboard dark, do NOT guess" note, never a crash. Wired into
do_ceo_tickahead ofceo_read_metrics.Tests
New
ceo_read_gscsection intest-ceo.sh: no-domain no-op, unconfigured note, aggregated totals + weighted position, token-fail note.make testgreen (check-sync + all units).Activation
This goes live for a repo once it carries
agent.json .seo.domain— which is PR 3 (vps-showdown first). After that merges, the next vps-showdown CEO digest leads with real GSC numbers, and you can answer #37.🤖 Review —
COMMENT(automated)CI for
8f8bc99b: successAdds
ceo_read_gsc(+ helper_ceo_gsc_totals) to pull Google Search Console on-demand into the CEO digest, keyed onagent.json .seo.domain, and wires it ahead ofceo_read_metricsindo_ceo_tick. Focused (~90 lines incl. tests), CI green, no CI-config or out-of-scope changes. Tests trace cleanly to the code. One behavioral gap and one thing I can't verify from the diff keep me off APPROVE.Findings
lib/ceo.sh(ceo_read_gsc, query step) — failed fetch falls through to a false-zero table, contradicting the description's contract. The PR claims "Unconfigured or failed GSC fetch → a scoreboard dark, do NOT guess note." That's true for the unconfigured and token-refresh paths, but a query failure is handled bygsc_query ... || printf '{"rows":[]}', which yields empty rows →_ceo_gsc_totalsreturns all zeros → the digest prints a real-lookingclicks 0 / impressions 0table with a delta. For a feature whose entire purpose is the CEO assessing delta, a transient API/HTTP failure surfacing as "traffic crashed to zero" is exactly the false signal the dark-note framing exists to prevent. Consider: if the current-windowgsc_queryfails (or returns no.rows), emit the same "scoreboard dark, do NOT guess" note instead of a zeros table. Note this path is also untested (only the token-refresh failure is covered).Runtime availability of
seo_window/gsc_query/gsc_access_token— can't confirm from the diff.ceo_read_gsccalls these three functions, which the description says are "existing" (presumably in another lib). The tests mock all three, so green CI does not prove they're actually sourced into thedo_ceo_tickruntime context. Iflib/ceo.sh/tick.shdoesn't already source whatever defines them, this is a production-only failure the tests can't catch. Worth a quick confirmation they're in scope wheredo_ceo_tickruns.Smaller notes (non-blocking)
read -r start end pstart pend <<<"$(seo_window)"assumesseo_windowalways emits exactly four space-separated tokens; an empty/short return would print a malformed** -> **window line and pass empty dates togsc_query. Mirrors the failure mode above._ceo_gsc_totalsmath and rounding check out: test rows give clicks 15, impressions 200, CTR 7.5%, impression-weighted position 10, and the jqadd // 0/ weighted-average logic handles empty and null fields without erroring. No correctness objection there.Nothing here is a hard blocker, but the false-zero-on-fetch-failure gap is a reservation I'd want a human to weigh before merge — flagging rather than rubber-stamping.
Independent review by the harness on
claude-opus-4-8. The human reviewer is requested once Igor has reviewed; a human still merges.