sennight

n., archaic. seven nights; a week.

Your week is a git repo. You text a bot what happened; every six hours an agent reads your messages, replans the rest of the week, admits what will not fit, and commits. No app, no database, no service.

The whole system is a few hundred lines: a markdown file of standing instructions, two YAML files, one validator, one cron, one HTML page. Small enough to read in one sitting, and made to be copied, the way micrograd is a model you can read, this is a life planner you can read.

How a run works

  1. Fetch. Pull whatever is new on Telegram and in the bot's Discord DM, save it verbatim to inbox/. That file is also the read cursor; there is no other state.
  2. Interpret. "did 2h dsa yesterday" is a log entry. "report due Friday, ~5h" is a task. "no gym this week" is an override that dies with the week. Only "permanently" touches the base config. Anything unclear goes to questions.md; hours are never guessed.
  3. Replan. Free windows = waking hours minus fixed anchors. Fill at most 80% of any window with ordered blocks, deadline tasks first, then activities by priority. Durations, never clock times.
  4. Validate. check_plan.py audits the arithmetic: every quota accounted for, every constraint honored, every miss declared. A failing plan is never committed.
  5. Digest. One plain message back on every transport you wired: what was understood, what changed, today's remaining blocks, where the week is at risk.
  6. Commit. The repo is the memory. Every run is a diff you can read.

Telegram and Discord both ship wired up; set up either one, or both, and the agent uses whatever it has secrets for. Neither is a dependency. Any other HTTP messaging API (Slack, email, a webhook) is a bullet in CLAUDE.md and two repo secrets away, with no code to change.

The whole thing

CLAUDE.mdthe brain: standing instructions the agent follows each run97 lines
config.yamlyour life: waking span, anchors, weekly quotas, priorities78 lines
overrides.yamlthis week's deviations; they expire with the weeka few
activities/<id>.jsonoptional: a locked long-running program the agent may tick but not rewritea few
scripts/check_plan.pythe auditor: deterministic checks the agent cannot argue with237 lines
schema/plan.schema.jsonthe frozen contract between agent and page93 lines
.github/workflows/plan.ymlthe heartbeat: cron, agent, commit53 lines
index.htmlthe board: renders plan.json, no build step218 lines

Counts are for the starting template. A copy that has been lived in for a while runs about half as long again, as house rules accumulate in the brain and the auditor learns your constraints by name. That is the config doing its job, not rot.

The rules that make it work

Copy it

This is a concept, not a service. Nothing on this page runs for you. You copy the template, wire it to your own bot and your own repo, and it becomes yours.
gh repo create my-sennight --private \
  --template agentlab-in/sennight
# then, in your copy:
# 1. move template/* to the repo root, delete the rest
# 2. rewrite config.yaml with your real week
# 3. add secrets: CLAUDE_CODE_OAUTH_TOKEN, then
#    TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID and/or
#    DISCORD_BOT_TOKEN + DISCORD_CHANNEL_ID
# 4. enable Actions, enable Pages, text your bot
Read the code on GitHub See the board it produces

That board is this repo's template/ directory running on its fictional week, rendered straight from plan.json with no build step.