Install
$ agentstack add skill-shalintripathi-organic-os-hoo-daily ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Daily signal pull (Generator role - append only)
Resolve the brain: use registry.get_active() when running interactively; scheduled runs receive the brain path from the routine configuration.
- Run
core.contracts.check_schema(brain_path)first. If not compatible,
relay the action string and stop before any of the steps below.
- Read site-profile.yaml. Determine available sources: GSC connector, GA4
connector, tracked keywords in keywords/tracking.yaml, WordPress endpoint. The sessions and referral pulls read the analytics slot (ADR-0009) - GA4 is the adapter today; see CONTRIBUTING.md's "Contributing an analytics adapter" to add Clarity or Matomo.
- Pull, for yesterday (or since the last signal date - read the latest file in
signals/): GSC clicks/impressions/CTR/position for top and tracked queries; GA4 sessions; spot-check 3 tracked keywords in one AI engine, rotating. 2.5. AI-referral segmentation (runs only when GA4 is reachable): segment referral sessions whose source matches a known AI surface and record one ai_referrals: line in the daily signal - the session count plus the top landing pages (cap 3, each with its count). The known AI surfaces: chatgpt.com, perplexity.ai, gemini.google.com, copilot.microsoft.com, claude.ai. This list is maintained here, in this skill, and reviewed quarterly - hoo-weekly and hoo-monday-report quote it, never extend it (see docs/INFORMATION-MAP.md in the repo). Zero matching sessions is a real value - write ai_referrals: 0. GA4 unreachable means no ai_referrals: line at all, never a guessed one. 2.6. Headline metrics line: record what steps 2 and 2.5 actually pulled as ONE structured signal line so later runs can parse it - the exact tokens clicks: N, impressions: N, sessions: N on a single line (site-wide daily totals; a source that was not pulled omits its token, never writes 0). Together with step 2.5's ai_referrals: N these are the daily's structured metric forms; the anomaly check below and the CSV export (skills/hoo-export, core.export) parse exactly these tokens. 2.7. Anomaly check: for each headline metric this run actually has - GSC clicks, GSC impressions, GA4 sessions, ai_referrals - collect the same metric's values from the trailing 7 daily signal files (parse the structured lines from steps 2.5 and 2.6; days without the metric are gaps, never zeros) and compare today's value to the median of those trailing values.
- Baseline discipline: fewer than 4 prior daily signals carrying the
metric -> skip that metric with a one-line note in today's signal ("anomaly check: skipped , no baseline yet") - no baseline, no alert.
- Noise floor: a trailing median below 10 -> skip the metric; percent
swings on single-digit medians are noise, not signals.
- Threshold: today deviating from the median by more than 40 percent
in either direction flags the metric. The default is profile-configurable via the additive alerts: {threshold_pct: 40} key in site-profile.yaml (absence means 40; see docs/site-repo-contract.md). Each flagged metric -> one P1 signal in falsifiable form: the metric, today's value, the 7-day median, the direction, a one-line likely-cause hypothesis (a weekend, a deploy, a tracking change, a SERP feature shift - whichever the data points to), and the honest caveat stated in the signal itself: weekends and seasonality can trip this check. These P1 signals JOIN the daily alert below - never a separate message. Rationale: alerting is the retention feature of every commercial monitor; ours rides the existing channel taxonomy instead of adding a dashboard (ROADMAP, v0.4).
- Write one
append_signalline per notable observation (threshold: any WoW
move > 10% or position change > 2 or a new AI citation appearing/vanishing). Quiet days produce one line: "no notable movement (checked: )". If neither GSC nor GA4 was reachable this run (both connectors read anything other than verified in connectors:), write the literal line no-data: GSC/GA4 not reachable from this runtime (checked: none) instead
- this exact string is what step 3.5 below counts and greps for, so do
not paraphrase it. 3.5. No-data escalation. After writing today's signal, count consecutive daily signal files - today's plus however many immediately prior days' files also contain a no-data: line, walking backward by filename date and stopping at the first file that does not (a day with real data, or a missing file, breaks the streak). If that count reaches 3:
- Check the last 7 days of signal files for a
nudge-sent:line. If one
is already there, skip sending - do not repeat the nudge more than once per 7 days.
- Otherwise send one nudge through the configured approval channel. This
is a plain notification, not an approval item - send_item-style text delivered directly over the channel (telegram: one sendMessage; slack: one post; email: one send; in-session: print it; pr-merge: no live channel mid-cycle, so just log it to the signal and skip delivery), not a create_item/approve-reject proposal: "3 daily runs with no analytics data - GSC/GA4 are not reachable from this runtime. Fix: run /organic-os:setup and use the connector wizard for GSC/GA4, or connect directly - claude.ai Settings -> Connectors, or /mcp / claude mcp add in Claude Code."
- Mark the nudge sent by appending `nudge-sent: no-data escalation
(GSC/GA4) to today's signal file via append_signal` - this is the state marker; do not create a new state file for it.
- If an observation crosses P1 (drop > 30% on a money page), also
create_item(kind="onpage-fix"...) or kind="strategy" and notify per the approval channel. Only send items where is_notified(item) is false; call mark_notified(path) right after a successful send.
- Outcome follow-ups: for items in
outcomes/with a due measurement date of
today, run the measurement per skills/onsite-measure and record. 5.5. Applied-change re-verification: scan outcomes/ for records with a reverify: block whose until is still in the future (written by skills/onsite-apply after a successful verify; see site-repo-contract.md). For each with due <= now, fetch the live values via the CMS adapter - the same fields the apply verified (title, meta description, canonical) - and compare to what the outcome record says was applied. Match: note the passing re-check in the outcome record, nothing else. Mismatch: append one P1 signal - "applied change no longer live - external revert suspected; re-propose" - naming the item id, the field, the applied value, and the live value; it goes out in the daily alert below. Once until passes, stop re-checking: the drift watch owns the long horizon (the baseline was already refreshed at apply time). Records without a reverify: block are never re-checked this way.
- If brain mode is git: commit and push with message "signals: YYYY-MM-DD".
Missing sources are stated, never guessed. This skill NEVER writes skillbook.md. The no-data nudge in step 3.5 is a notification, never an approval item - it needs no decision, just a fix.
Run cost: wrapper-invoked runs land one row (date, duration, tokens where the CLI reports them) in ~/.config/organic-os/cost-ledger-YYYYMM.tsv; the wrapper writes it, this skill never does - the Monday report reads it.
Drift watch
Runs only when the profile's WordPress connector is verified - drift is WP-only, there is no page inventory to snapshot without it.
- Build the tracked-page set: the WordPress post id recorded in every
outcomes/*-rollback.json snapshot (already captured by onsite-apply's verify step), any proposals/ item's target page still in play, plus the homepage - deduped, capped at 20.
- First run for this brain (
onsite.drift.baseline_path(root)does not
exist yet): onsite.drift.snapshot_pages(wp, page_ids), then save_baseline. Append one signal noting the baseline was established and how many pages it covers.
- Every later run: snapshot the same tracked-page set again and
onsite.drift.compare(root, snap). Empty list: one quiet signal line, nothing else to do. Any diff: one P1 signal per changed page, naming the field, the old value, and the new value - "changed outside the loop: field, was, now - if this change was yours, refresh the baseline; if not, investigate theme or plugin updates."
- Refresh the baseline (
save_baseline) only AFTER the signal for that
run's diff has been written, so a given drift is reported exactly once and never silently re-baselined out from under a pending investigation.
No WordPress connection: skip silently, no note needed - unlike the GSC sections in the weekly routine, there is no page inventory to have skipped pulling.
Daily alert (actionable only)
After every section above has run, decide whether the operator needs to hear anything today. Actionable content is exactly:
- P1 signals created by this run (anomaly flags from step 2.7, drift
"changed outside the loop", money-page drops from step 4, failed re-verifications from step 5.5)
- the no-data nudge from step 3.5
If any exist, send ONE message through the configured approval channel, using the same channel-neutral delivery as the step 3.5 nudge (telegram: one sendMessage; slack: one post; email: one send; in-session: print it; pr-merge: log to the signal file and skip delivery). When the no-data nudge fires on the same day, it rides inside this one message instead of going out separately - never two messages per day. Quiet days send NOTHING: no "all quiet" spam. The signal file already records the quiet day; silence on the channel means no action needed, never that something was hidden.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: shalintripathi
- Source: shalintripathi/organic-os
- License: MIT
- Homepage: https://organicos.shivaatripathi.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.