feat(realism): scaffold decnet/realism/ library
Empty subpackage skeleton for the realism migration: ContentClass enum (file/email/canary content categories), Plan dataclass (frozen, with edit-action invariant), in_work_hours window check (wrap-around supported, fail-open on parse error), and sample_mtime for backdated file timestamps that snap into a persona's active hours. Stage 1 of the orchestrator+canary realism unification — no production caller wired yet; planner.pick is a stub returning None until stage 3.
This commit is contained in:
53
decnet/realism/planner.py
Normal file
53
decnet/realism/planner.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""Realism planner — picks the next ``(decky, persona, class, action)`` tuple.
|
||||
|
||||
Stage-1 stub: the public signature is in place so the orchestrator
|
||||
worker (stage 3) can import it, but the body returns ``None`` ("nothing
|
||||
to do this tick") until stage 3 wires the synthetic_files table and
|
||||
naming/body generators.
|
||||
|
||||
The eventual policy lives entirely in :func:`pick`; downstream
|
||||
consumers should not branch on ``ContentClass`` themselves — let the
|
||||
planner decide weights and rate-limits in one place.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import secrets
|
||||
from datetime import datetime
|
||||
from typing import Any, Optional, Sequence
|
||||
|
||||
from decnet.realism.taxonomy import Plan
|
||||
|
||||
|
||||
def pick(
|
||||
deckies: Sequence[dict[str, Any]],
|
||||
now: datetime,
|
||||
*,
|
||||
repo: Any = None,
|
||||
rand: Optional[secrets.SystemRandom] = None,
|
||||
) -> Optional[Plan]:
|
||||
"""Return the next :class:`Plan` for the orchestrator's tick.
|
||||
|
||||
Stage-1 stub returns ``None`` unconditionally so the orchestrator
|
||||
can import this function before the real implementation lands. The
|
||||
full policy (diurnal gate, action distribution 60/30/10
|
||||
create/edit/leave, content-class weights, canary rate-limit) lands
|
||||
in stage 3 of the realism migration.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
deckies :
|
||||
Output of :meth:`BaseRepository.list_running_deckies`. Each
|
||||
entry must carry ``uuid``, ``name``, ``services``,
|
||||
``email_personas`` (topology-pool JSON or list).
|
||||
now :
|
||||
Tick timestamp. Injected so tests don't need to monkey-patch
|
||||
:func:`datetime.utcnow`.
|
||||
repo :
|
||||
:class:`BaseRepository` for synthetic_files lookup (edit
|
||||
action). Optional in stage 1; required from stage 3 onward.
|
||||
rand :
|
||||
RNG for sampling. Defaults to a fresh
|
||||
:class:`secrets.SystemRandom`.
|
||||
"""
|
||||
_ = (deckies, now, repo, rand) # silence unused-arg until stage 3
|
||||
return None
|
||||
Reference in New Issue
Block a user