idle-draft: add sample_override config flag to bypass cold-start throttle
Optional config key (default false). When true, research candidates are offered even at max_unreviewed_research_per_dossier; research_sampled bookkeeping, mark sampled, and status flags are unchanged so unsampled items stay visible for later human verification. Claude-Session: https://claude.ai/code/session_01Lgv4Qn82boNFC1jn8QXSNw
This commit is contained in:
@@ -683,6 +683,7 @@ def count_open_topic_proposals(repo: Path, dossier: str) -> int:
|
||||
def build_ready_queue(repo: Path, config: dict, state: dict, in_flight: set) -> list[dict]:
|
||||
candidates: list[dict] = []
|
||||
dossiers = config["dossiers"]
|
||||
sample_override = bool(config.get("sample_override", False))
|
||||
for idx, dossier in enumerate(dossiers):
|
||||
unreviewed = count_unreviewed_research(repo, dossier, state)
|
||||
max_unreviewed = config["max_unreviewed_research_per_dossier"]
|
||||
@@ -693,7 +694,7 @@ def build_ready_queue(repo: Path, config: dict, state: dict, in_flight: set) ->
|
||||
files = item_files(repo, dossier, f"{nn}-{slug}")
|
||||
entry = get_item_state(state, key)
|
||||
wtype, reason = next_work_type_for_item(files, entry)
|
||||
if wtype == "research" and unreviewed >= max_unreviewed:
|
||||
if wtype == "research" and unreviewed >= max_unreviewed and not sample_override:
|
||||
continue
|
||||
if wtype is None:
|
||||
continue
|
||||
|
||||
@@ -86,6 +86,12 @@ Parse `--config` as JSON. Required top-level keys: `parallel`, `providers`, `wor
|
||||
verbatim. Missing required keys or malformed structure → log loudly, exit **2**.
|
||||
`--parallel` on the CLI overrides the config value.
|
||||
|
||||
Optional key `sample_override` (bool, default `false`): when `true`, the cold-start
|
||||
throttle (§ dispatch, below) is bypassed — `research` candidates are offered even when
|
||||
the dossier is at `max_unreviewed_research_per_dossier`. Nothing else changes:
|
||||
`research_sampled` bookkeeping, `mark … sampled`, and the `status` flags are unaffected,
|
||||
so unsampled research remains visible and awaiting human verification.
|
||||
|
||||
### 4. State load and validation
|
||||
|
||||
Read `<repo>/idle-draft.state.json`. Missing file is not an error — treat as
|
||||
@@ -184,6 +190,8 @@ from consideration for further dispatch until the in-flight task completes.
|
||||
whose state entry does **not** have `research_sampled: true`. Once that count reaches
|
||||
`max_unreviewed_research_per_dossier`, no further `research` candidates are offered for
|
||||
that dossier this cycle (draft/review candidates in that dossier are unaffected).
|
||||
If config `sample_override` is `true`, this throttle is skipped entirely; the unsampled
|
||||
counts and `research_sampled` state are still maintained exactly as above.
|
||||
|
||||
**`topic_ideas`:** dossier-level (not tied to an `NN-slug`), considered only when the
|
||||
combined candidate list above (across all dossiers) is empty. For each dossier, eligible
|
||||
|
||||
@@ -570,6 +570,17 @@ draft_candidates = [c["slug"] for c in tqueue if c["work_type"] == "draft"]
|
||||
check("cold-start throttle: draft candidates for 01/02 unaffected by the research throttle",
|
||||
set(draft_candidates) == {"01-a", "02-b"}, draft_candidates)
|
||||
|
||||
# sample_override: throttle bypassed, sampling state untouched
|
||||
override_config = dict(throttle_config)
|
||||
override_config["sample_override"] = True
|
||||
oqueue = m.build_ready_queue(throttle_repo, override_config, throttle_state, set())
|
||||
override_research = [c["slug"] for c in oqueue if c["work_type"] == "research"]
|
||||
check("sample_override: item 03's research is offered despite the dossier being at the cap",
|
||||
"03-c" in override_research, override_research)
|
||||
check("sample_override: research_sampled state is not mutated by queue building",
|
||||
not any(m.get_item_state(throttle_state, f"ai/{s}")["research_sampled"]
|
||||
for s in ("01-a", "02-b", "03-c")), throttle_state)
|
||||
|
||||
# topic_ideas: only offered when nothing else is eligible
|
||||
idle_repo = tmpdir / "idle-repo"
|
||||
(idle_repo / "ai").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
Reference in New Issue
Block a user