Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e28ff1e5b | ||
|
|
d8ab6bb72c |
No files matched your search
@@ -208,7 +208,10 @@ Switches: `досуг: выкл` as the first line of the file for every day, an
|
|||||||
|
|
||||||
An agreement with a foreign agent on someone else's home server: both print
|
An agreement with a foreign agent on someone else's home server: both print
|
||||||
one line a day into a vibegram room of their own, and both watch the other's
|
one line a day into a vibegram room of their own, and both watch the other's
|
||||||
silence. If the neighbour goes quiet past the threshold, *their* human is the
|
silence. The two rates are deliberately different: the beat is daily because
|
||||||
|
that is the period we promise the neighbour, while the check runs every six
|
||||||
|
hours, because a watchdog stepping once a day against a 36 h threshold would
|
||||||
|
only notice silence some 60 h in - it would be measuring the wrong thing. If the neighbour goes quiet past the threshold, *their* human is the
|
||||||
one who needs to hear about it, so the alarm goes to the master thread as a
|
one who needs to hear about it, so the alarm goes to the master thread as a
|
||||||
spawned triage job and the dispatcher decides whether to wake the owner.
|
spawned triage job and the dispatcher decides whether to wake the owner.
|
||||||
|
|
||||||
@@ -226,7 +229,7 @@ are no defaults anywhere in it.
|
|||||||
period is not a constant: it is derived from that job's own registered cron
|
period is not a constant: it is derived from that job's own registered cron
|
||||||
(`run.job.cron`). A schedule that does not reduce to "every N hours" gets
|
(`run.job.cron`). A schedule that does not reduce to "every N hours" gets
|
||||||
`every=unknown src=none` - lying with a number is worse than refusing.
|
`every=unknown src=none` - lying with a number is worse than refusing.
|
||||||
- `сторож` (17:42 local) asks for an explicit window (`pending(limit=25)`),
|
- `сторож` (`:42` every six hours) asks for an explicit window (`pending(limit=25)`),
|
||||||
finds the newest `hb claude-kai …`, and compares its age against
|
finds the newest `hb claude-kai …`, and compares its age against
|
||||||
`every * 1.5` where `every` comes **from the neighbour's own line**. The
|
`every * 1.5` where `every` comes **from the neighbour's own line**. The
|
||||||
clock it trusts is `seen` - when *we* saw the line - not the `at=` inside it,
|
clock it trusts is `seen` - when *we* saw the line - not the `at=` inside it,
|
||||||
|
|||||||
@@ -31,10 +31,12 @@ jobs = [
|
|||||||
# Сторожевое кольцо с чужим агентом. Кроны читаются в локальной зоне, а
|
# Сторожевое кольцо с чужим агентом. Кроны читаются в локальной зоне, а
|
||||||
# сосед печатает свою отметку в 05:00 UTC - вечер по Варшаве разводит нас
|
# сосед печатает свою отметку в 05:00 UTC - вечер по Варшаве разводит нас
|
||||||
# на полсуток, и его строка лежит в комнате задолго до нашего прогона.
|
# на полсуток, и его строка лежит в комнате задолго до нашего прогона.
|
||||||
# Сторож идёт через полчаса после своей отметки: так «моя запись в комнату
|
# Частоты тут две, и они разные: отметка суточная (её период мы обещаем
|
||||||
# проходит» - свежий факт этих же суток, а не вчерашний.
|
# соседу), а проверка - вчетверо чаще. Сторож с шагом в сутки при пороге
|
||||||
|
# 36 ч обнаруживал бы молчание только через ~60 ч, то есть мерил бы не то,
|
||||||
|
# ради чего заведён; чтение 25 событий стоит копейки.
|
||||||
Job("отметка", beat, cron="12 17 * * *", critical=False),
|
Job("отметка", beat, cron="12 17 * * *", critical=False),
|
||||||
Job("сторож", watch, cron="42 17 * * *", critical=False),
|
Job("сторож", watch, cron="42 */6 * * *", critical=False),
|
||||||
Job("память", memory, cron="30 4 * * 0", critical=False),
|
Job("память", memory, cron="30 4 * * 0", critical=False),
|
||||||
Job("голосовой", rotate_voice, cron="5 4 * * *", critical=False),
|
Job("голосовой", rotate_voice, cron="5 4 * * *", critical=False),
|
||||||
Job("куратор", curate, cron="0 2,8,12,16,20 * * *", critical=False),
|
Job("куратор", curate, cron="0 2,8,12,16,20 * * *", critical=False),
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import urllib.request
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
ENV = Path(__file__).resolve().parent.parent / ".env"
|
ENV = Path(__file__).resolve().parent.parent / ".env"
|
||||||
|
USER_AGENT = "beaver-agent/0.1 (+vibegram)"
|
||||||
|
|
||||||
|
|
||||||
def hub_from_env() -> str | None:
|
def hub_from_env() -> str | None:
|
||||||
@@ -56,7 +57,9 @@ def main() -> int:
|
|||||||
request = urllib.request.Request( # noqa: S310 - адрес хаба задаёт оператор
|
request = urllib.request.Request( # noqa: S310 - адрес хаба задаёт оператор
|
||||||
f"{args.hub.rstrip('/')}/api/rooms/join",
|
f"{args.hub.rstrip('/')}/api/rooms/join",
|
||||||
data=json.dumps(body).encode(),
|
data=json.dumps(body).encode(),
|
||||||
headers={"content-type": "application/json"},
|
# Перед хабом Cloudflare: безымянный `Python-urllib` он отбивает 1010.
|
||||||
|
# Тот же user-agent, что у клиента в `beaver_agent/hands/vibegram.py`.
|
||||||
|
headers={"content-type": "application/json", "user-agent": USER_AGENT},
|
||||||
method="POST",
|
method="POST",
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ class FakeRoom:
|
|||||||
|
|
||||||
|
|
||||||
class FakeRun:
|
class FakeRun:
|
||||||
def __init__(self, cron="42 17 * * *"):
|
def __init__(self, cron="42 */6 * * *"):
|
||||||
self.job = SimpleNamespace(cron=cron, name="сторож")
|
self.job = SimpleNamespace(cron=cron, name="сторож")
|
||||||
self.scheduler = SimpleNamespace(tz=WARSAW)
|
self.scheduler = SimpleNamespace(tz=WARSAW)
|
||||||
self.spawned = []
|
self.spawned = []
|
||||||
@@ -280,7 +280,7 @@ async def test_watch_job_prints_ack_and_spawns_alarm(tmp_path, monkeypatch):
|
|||||||
|
|
||||||
assert room.limit == 25 # окно запрошено явным размером
|
assert room.limit == 25 # окно запрошено явным размером
|
||||||
assert room.said and room.said[0].startswith(f"ack {PEER} ")
|
assert room.said and room.said[0].startswith(f"ack {PEER} ")
|
||||||
assert "res=24h" in room.said[0]
|
assert "res=6h" in room.said[0]
|
||||||
assert len(run.spawned) == 1
|
assert len(run.spawned) == 1
|
||||||
agent, title, text = run.spawned[0]
|
agent, title, text = run.spawned[0]
|
||||||
assert agent == "beaver-triage" and title == "сторож"
|
assert agent == "beaver-triage" and title == "сторож"
|
||||||
|
|||||||
Reference in new issue
Block a user