mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
feat(x-engine): smart spotlight cadence — daily when there's news, quiet when there isn't (#374)
CEO verdict on the blind 3-day timer: 'It should default to 1 day and be more like... smart.' Now: interval defaults to 1 day; the cycle skips (with logged reasons) while a spotlight draft is still awaiting the CEO, and stretches to 3x the interval when nothing has shipped (CHANGELOG sections via the read clone) since the last spotlight activity — where activity is a materialized draft's seen_at or a completed exploration's updated_at, deliberately excluding the stale- cycle janitor's cancels. The HoM gains an explicit skip exit (propose_feature_spotlight skip=true + reason: completes the exploration, no draft, no seen-slug, still counts as activity), and its spawn prompt now carries the seen ledger WITH dates, what shipped since the last spotlight, and recently rejected drafts with the CEO's reasons — fresh-but-unspotlighted first. Fail-open on changelog read errors so a signal outage never starves the engine. Co-authored-by: Renn F <rennf93@users.noreply.github.com>
This commit is contained in:
+24
-6
@@ -586,27 +586,43 @@ def propose_roadmap(cycle_goal: str, items: list[dict[str, Any]]) -> dict[str, A
|
||||
|
||||
|
||||
def propose_feature_spotlight(
|
||||
feature_slug: str,
|
||||
feature_title: str,
|
||||
body: str,
|
||||
feature_slug: str = "",
|
||||
feature_title: str = "",
|
||||
body: str = "",
|
||||
wants_video: bool = False,
|
||||
video_script: str = "",
|
||||
skip: bool = False,
|
||||
skip_reason: str = "",
|
||||
) -> dict[str, Any]:
|
||||
"""Head of Marketing: draft ONE feature-spotlight marketing post.
|
||||
"""Head of Marketing: draft ONE feature-spotlight marketing post, or skip.
|
||||
|
||||
Call this exactly ONCE per exploration cycle, after investigating the
|
||||
CHANGELOG, feature-flags ledger, docs/map, charter, and KB to pick a real,
|
||||
under-publicized capability. The draft is held in the X post queue for the
|
||||
CEO to edit/approve — nothing auto-posts.
|
||||
|
||||
If nothing shipped is genuinely worth spotlighting this cycle, pass
|
||||
skip=True with a substantive skip_reason instead of forcing a weak post —
|
||||
a forced spotlight is worse than skipping. A skip still completes the
|
||||
exploration task (no draft materialized, no feature marked seen) and
|
||||
counts as this cycle's activity for the engine's cadence, so it won't just
|
||||
re-fire daily into the same quiet period.
|
||||
|
||||
Args:
|
||||
feature_slug: Stable slug identifying the feature (the dedup key).
|
||||
feature_title: Short human title of the feature.
|
||||
body: The tweet text (plain, <=280 chars, no invented facts).
|
||||
Ignored when skip=True.
|
||||
feature_title: Short human title of the feature. Ignored when
|
||||
skip=True.
|
||||
body: The tweet text (plain, <=280 chars, no invented facts). Ignored
|
||||
when skip=True.
|
||||
wants_video: Also request a companion video (held separately for CEO
|
||||
approval, when the video engine is armed for spotlights).
|
||||
video_script: Optional script for that video; falls back to the
|
||||
feature title/body when omitted.
|
||||
skip: True to declare "nothing worth spotlighting this cycle" instead
|
||||
of authoring a draft.
|
||||
skip_reason: Required (non-empty, >=8 chars) explanation when
|
||||
skip=True.
|
||||
"""
|
||||
return _post(
|
||||
"/api/v1/do/propose_feature_spotlight",
|
||||
@@ -616,6 +632,8 @@ def propose_feature_spotlight(
|
||||
"body": body,
|
||||
"wants_video": wants_video,
|
||||
"video_script": video_script,
|
||||
"skip": skip,
|
||||
"skip_reason": skip_reason,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user