Timing intelligence and evidence-aware calendar planning
Read this when asked: best time or day to post, schedule 5–100 posts, batch publishing, content calendar, automatic posting, engagement timing, platform-specific posting patterns. Also consult platform-algorithms.md, publishing.md, and the dated research report when available in the full repository. In a copied standalone skill, links outside this folder may not exist; use these references directly.
Never confuse three separate actions
Section titled “Never confuse three separate actions”- Propose is analysis only: produce a calendar and evidence/confidence for human review, with
status=proposed. No network request. - Native scheduled is a user-confirmed entry in LinkedIn, Meta Business Suite/Instagram, TikTok, YouTube Studio, X, Threads, Pinterest or other platform after user logs in, grants access and confirms that platform’s own queue accepted it. Without receipt, say
native_handoff_pending, NOTscheduled. - ReachWeaver scheduled is a locally approved draft with a UTC due timestamp. It is not remotely published. Auto-send requires a trusted persistent scheduler, real account authorization,
--live,REACHWEAVER_ALLOW_LIVE=1andREACHWEAVER_ENV=prod, no emergency pause, and supported adapter. Only Bluesky/Mastodon/Telegram/LinkedIn-member have mock-tested text send adapters; none have live account verification. Unsupported platforms remain manual.
Low-confidence 2026 population priors
Section titled “Low-confidence 2026 population priors”One provider analysis covered 52M+ posts across its own customer population and observed engagement, not randomized experiments on the operator’s accounts: Buffer, 2026-03-05. Time suggestions are audience-local and candidate windows, not promises or universal algorithm weights.
| Platform | Candidate time windows | Baseline label |
|---|---|---|
| Weekdays 15:00–20:00; sample Wed 16:00 | industry_observational |
|
| Weekdays 18:00–21:00; separately test Thu 09:00 | industry_observational |
|
| Weekdays 08:00–11:00; sample Thu 09:00 | industry_observational |
|
| X | Weekdays 06:00–11:00; sample Tue 09:00 | industry_observational |
| Threads | Weekdays 06:00–11:00; sample Thu 09:00 | industry_observational |
| TikTok | Weekends 08:00–11:00; sample Sun 09:00 | industry_observational |
| Bluesky | Weekend afternoons/evenings 16:00–19:00; test weekday evenings | industry_observational; see updated Bluesky study |
| YouTube | Use own Audience heatmap; consider staff availability for live/Premieres | first_party_preferred; official FAQ says long-term performance not known to depend on publish time |
| Mastodon, Telegram, Pinterest, Reddit | Platform/subscriber/community-specific audience data; do not fabricate a globally best clock hour | unknown_prior |
| Product Hunt | Pacific-time launch-day cycle, user/staff launch availability | platform_fixed_cycle |
| Hacker News | Human-written, human-submitted only; never automate | automation_disallowed |
These windows will change with sample mix, platform features and audience. More current own-account evidence overrides all third-party population summaries.
Inputs for each recommendation
Section titled “Inputs for each recommendation”Require only available information, make unknown fields explicit. Use:
brand_id,account_id,platform,post_idorvariant_id, contentformat, audience segment, goal, due-after/deadline/embargo, human reviewer;- audience IANA timezone (e.g.
Europe/Rome,America/New_York) or justified multiple cohort zones; content language; excluded days and practical response coverage; - permitted native scheduler formats, upload/auth status, account eligibility, desired weekly cadence, queue horizon, already scheduled posts and spacing constraints;
- owned native audience activity, post metadata, native metric snapshots, first-party website conversion/GitHub downstream metrics, their metric definitions, observation age and data coverage.
Do not scrape personal analytics or personal audience information from a platform without approved permission. Do not store authorization tokens in Git; no third-party analytics is proof of first-party outcomes.
Owner-exported audience activity (calendar-plan --audience-activity FILE)
Section titled “Owner-exported audience activity (calendar-plan --audience-activity FILE)”When the owner can see hour-of-week audience activity in a native dashboard (for example “followers online” or “most active times”), ask them to copy it into ReachWeaver’s audience-activity CSV. The columns are account_id,timezone,weekday,hour,activity,source,as_of, with optional consent,notes. This layout is ReachWeaver’s own interchange format: no real platform export has been verified against it, so never say a platform exports this file. The bundled example examples/audience-activity.example.csv is synthetic and is never evidence for a real account.
- The owner fills in the file. Do not scrape dashboards or ask for credentials to fetch the numbers.
- Leave hours the dashboard does not show out of the file, or set them to
unknown. Never fill them with 0. - The output tags each slot
evidence=first_party_audience_activity,confidence=unverified, withprovenance(source,as_of, rank,stale, DST status). Pass these labels on to the user unchanged. Activity is presence, not outcome, so it is not proof that a time performs better. - When
stale: true(as_ofolder than 90 days by default; change with--audience-max-age-days N), ask for a fresh export before relying on the slots.--audience-top-hours N(1-24, default 5) sets how many top hours become slots. - Use either
--audience-activityor--slot, not both. The planner stays advisory, and approval,--applyand publishing gates are unchanged.
Selection method (transparent baseline, not a trained prediction model)
Section titled “Selection method (transparent baseline, not a trained prediction model)”- Eligibility first. Check account ownership, official native/API capability, format, user authorization, moderation/community policy and embargo. Set
delivery=native_manual,delivery=reachweaver_workerordelivery=reminder_only. Reject automatic HN and ordinary Reddit bot promotion. No secret key or browser session scraping. - Create candidates from own-account follower activity, prior account/format post times or the low-confidence table above. When data absent, rotate two or three reasonable audience-local windows, and state no empirical optimum established.
- Normalize clock. Resolve an actual date in an IANA zone, convert to ISO8601 explicit offset and UTC, and preserve zone in the plan. Validate daylight-saving gaps/folds; never interpret
09:00as operator-local unless confirmed. - Prioritize goals and fairness. Prefer proven audience presence, relevant format, creative utility and staffing. Avoid back-to-back posts or aggressive duplication. Do not put a large launch on a national holiday without explicit review. Respect provider maximum advance scheduling horizon.
- If comparable history exists: segment same account, platform, format, content purpose and metric definition; compare median/robust rate at matched post ages (+24h, +7d). Do not compare raw views to impressions, different follower sizes, bought promotion to organic or absent metrics to zero. Require meaningful post counts across slots before making an account-specific inference; otherwise output
insufficient_evidence. - Continue exploring: Reserve, as a policy suggestion, ~20% of future noncritical posts for another allowed time slot. This 20% is a heuristic not a platform ranking factor or statistically optimal exploration rate. For high-value launches, favor staff/community availability and human editorial judgment.
- Produce a reason + confidence.
account_observedmay support a measured recommendation but not causal certainty;industry_observationalis low;editorial_hypothesisis tentative;unknownis explicitly unknown. - Separate schedule from approval. Present the exact per-account content and publication time for review; only call
reachweaver approve/scheduleonce the human has explicitly approved the item. Do not auto-edit an approved post; cancel/unapprove and recreate if content changed. Native UI scheduling needs separate human confirmation/receipt. - Measure and revisit. At the same post ages collect native metrics and downstream goal; show source, missingness and sample sizes. Weekly evaluate slots; monthly refresh platform docs/prior assumptions. Report confounders such as holiday, format, topic, link and audience composition. Never claim causal uplift solely from observational before/after.
Calendar deliverable schema
Section titled “Calendar deliverable schema”Return a visible scheduling table, plus CSV/JSON on request, with at least:
| Field | Meaning |
|---|---|
brand_id, account_id |
Authorized identity / precise destination |
platform, post_id, format |
Channel, immutable draft link and asset type |
audience_zone, scheduled_local, scheduled_utc |
Zoned exact date/time; DST-safe |
time_evidence, evidence_checked_at, confidence |
First-party/industry/editorial source and uncertainty |
delivery |
native_manual / reachweaver_worker / reminder_only |
schedule_status |
proposed / awaiting_approval / native_handoff_pending / locally_scheduled / remote_confirmed |
receipt, next_measure_at |
Real remote queue receipt when supported; next matched-age metrics checkpoint |
Example illustrative row (NOT proof of user account, a published post, or validated optimal time):
YazSes | personal-linkedin | linkedin | YS-202610 | text | Europe/Rome | 2026-10-14T16:00:00+02:00 | 2026-10-14T14:00:00Z | industry_observational | 2026-10-08 | low | native_manual | native_handoff_pending | none | +24h/+7d
Never fabricate IDs, upload URLs, queue receipts or evidence. If YazSes is not an authorized brand profile, use an explicitly illustrative example instead of a real saved campaign.
Batch draft → review → schedule → publish → measure
Section titled “Batch draft → review → schedule → publish → measure”For a user who writes 10 posts today, keep all 10 drafts; adapt them to each platform, build a collision-aware calendar, show a single review table, then submit each human-approved exact variant to its allowed transport.
For native-only platforms, the skill can prepare copy and instructions and open a human handoff, but it must not report scheduled until there is evidence from the platform UI/provider. For the three ReachWeaver mock-tested text adapters, queue locally with reachweaver schedule POST_ID --at 2026-10-15T09:00:00+02:00. This is never proof a worker will run. Show reachweaver publish dry-run; live publishing remains disabled without explicit authorization, host, credentials and tested adapter.
For YouTube, prefer title/thumbnail/retention and audience interest; an exact time may help early viewers but does not establish long-term algorithm advantage per official guidance. For Hacker News, do not auto-submit or place model-written submission content.
Executable offline planner (current implementation)
Section titled “Executable offline planner (current implementation)”The portable skill includes the same reachweaver calendar-plan command as the main repository. First reachweaver show ID and approve each exact platform/account variant. Use calendar-plan --account ACCOUNT --timezone IANA_ZONE --start YYYY-MM-DD --days 14 to get evidence-labeled, collision-aware proposals, not remote schedules. Add --slot 'Wed@16:00' to supply your account’s observed or hypothesized audience windows; the CLI labels them operator_supplied/unverified. Optional --blackout YYYY-MM-DD avoids dates; --spacing-hours 20 sets account-specific spacing. For previewing drafts, add --include-drafts (never combinable with --apply). To reserve a capped share of the batch for testing new times, add --explore-share 0.25 --explore-slot 'Sat@11:00' (share above 0, at most 0.5; default 0 = off): floor(share x posts) posts, evenly interleaved by post order, go to the explore slots and are labelled role: explore, evidence: operator_explore_hypothesis, confidence: unverified; the rest stay role: exploit on the evidence-backed slots. The split is fixed, never randomized, so say “exploration”, not “experiment”; spacing, blackouts and --apply gating are unchanged. The exploration.baseline_eval_slots list gives the matching baseline-eval --slot roles.
Only after human approvals and review, --apply queues times in local SQLite for the four existing text-only Bluesky/Mastodon/Telegram/LinkedIn-member adapters. The method rechecks approval and collisions atomically, uses explicit IANA zones/UTC and rejects ambiguous/nonexistent DST times. LinkedIn organization pages, DEV.to, Hashnode, TikTok, Instagram, Facebook, YouTube, X, Threads, Reddit and Pinterest do not gain authorized publishing from this change; present a native/manual handoff instead. No cron worker or analytics-trained prediction is activated. The full repository has implementation details in docs/CALENDAR-PLANNER.md.
Evaluate actual imported account outcomes, safely
Section titled “Evaluate actual imported account outcomes, safely”Run reachweaver timing-evaluate --account ACCOUNT --timezone IANA_ZONE --source NATIVE_EXPORT_LABEL --metric clicks --denominator impressions --age-hours 168 --tolerance-hours 24 --min-posts-per-slot 3 only when real, owner-permitted native metric snapshots have already been imported. This read-only evaluation groups posts by weekday/weekend six-hour windows at matched age, and compares robust median rates within ONE account and declared source. Missing snapshots are unknown, not zero. An exploratory candidate requires at least two sample-qualified slots; it remains an observation with uncontrolled topic/format/follower and selection biases. Add --stratify format (text/image/video from the stored attachment) or --stratify campaign to get the same readout per stratum; a stratum with too few matched posts is insufficient_data with no candidate and a cold_start pointer to calendar-plan’s generic baseline slots (or none_available where the planner has no prior). Report that pointer as a low-confidence starting point, never as a winner. Never infer a precise clock-minute from a six-hour median. Never trigger calendar-plan --apply or publishing from this result. In the full repo, see docs/TIMING-EVALUATION.md; in copied standalone skills use this reference and references/experimental-learning.md.
Compare against the non-personalized baseline
Section titled “Compare against the non-personalized baseline”Run reachweaver baseline-eval --account ACCOUNT --timezone IANA_ZONE --source NATIVE_EXPORT_LABEL --metric clicks --denominator impressions --since YYYY-MM-DD --until YYYY-MM-DD --slot exploit:Tue@09:00 [--slot explore:Sat@11:00] [--campaign-arm explore:CAMPAIGN] [--readout READOUT.json] to ask whether the account’s own slots did better than calendar-plan’s generic slot (the one it proposes without --slot). Fix the period before looking at results. Each arm is one comparison with a seeded percentile bootstrap interval of the median rate difference and a permutation p-value; Holm–Bonferroni corrects across all comparisons in the run. Status is insufficient_data (fewer than --min-posts, default 5, rates in either group; estimates are null, not 0), no_clear_difference, or separated_after_holm (interval excludes zero and adjusted p ≤ 1 − confidence). Every arm-versus-baseline result is correlational. Report the role (explore/exploit), the exploration share and the excluded counts. Small organic samples usually give insufficient_data or no_clear_difference; say so plainly. The command is read-only and never changes the planner, a queue or a post. Platforms without a generic slot (e.g. Mastodon, Telegram) have no baseline. To compare website or repository outcomes instead of a platform rate, save reachweaver attribution-report --analytics CSV --json > attribution.json and replace --source/--metric/--denominator with --attribution attribution.json --outcome docs_visits (attributed sessions) or --outcome repo_stars_utm (attributed conversions); a post without an attributed count is excluded, never 0. Add --attribution-source ga4 to use the GA4 section of a report made with --ga4-csv (GA4 sessions, key events as conversions). In the full repo, see docs/TIMING-EVALUATION.md.
Upstream source cadence
Section titled “Upstream source cadence”Review official scheduling help and the dated full-repo report before each new integration; monthly thereafter. Revalidate horizon, eligible account type, native post types, third-party API permissions, media support and ranking guidance. Store last-reviewed date, not an implication that algorithmic factors are frozen.
