logsayer
Spec-kit tells you what to build. logsayer tells you where you stand, how you got there, and whether what you built is still what you said you would build.
A Python CLI that scaffolds and coordinates a 5-layer documentary system for AI-agent projects: Specification, State, Logbook, Verification (mechanical + semantic), and Process.
Everything the agent needs to know about a project is written down by the same system that uses it — each layer answers one question, each document lives in exactly one layer, and every judgment lives in the CLI, not in the generated files.
Disclaimer (Dune homage)
This project uses names and concepts from Frank Herbert's Dune saga exclusively as a thematic reference and role metaphor. It is not affiliated with, sponsored by, or officially associated with Herbert Properties LLC, Legendary Entertainment, or any rights holders of the franchise. No art, logos, or protected material is reproduced — only concept/role names as a design analogy.
Why logsayer
The spec-driven pattern (as popularized by GitHub Spec Kit) governs the first generation of code. After that, its authority over the code is by convention, not verification. logsayer closes the loop that pattern leaves open:
- State continuity between sessions — an anchor snapshot the agent reads (and only that) at session start.
- A partitioned, append-only logbook for the "why" of past decisions.
- A mechanical + semantic verification loop that checks whether the code still matches the spec — both structurally and in meaning.
- Multi-agent coordination through the standard
AGENTS.mdconvention, with thin native adapters per tool (opencode and Claude Code today).
The 5 layers
| # | Layer | Question it answers | Dune role |
|---|---|---|---|
| 1 | Specification (normative) | What must be built? | Mentat |
| 2 | State (anchor) | Where is the project right now? | Guild Navigator |
| 3 | Logbook (historical) | How did we get here, and why? | Reverend Mother |
| 4 | Verification | Does what was built still match the spec? | Suk Doctor (mechanical) + Truthsayer (semantic) |
| 5 | Process (operational) | How do we work here? | Fremen |
Every layer has a plain-English alias, so you can use logsayer without knowing any of the lore.
Installation
Requires Python 3.11+.
uv tool install logsayer
# or
pipx install logsayer
Quick start
# 1. Scaffold a new project
logsayer init my-project
cd my-project
# 2. Write the spec for a user story
logsayer spec new HU-01
# 3. Add an agent adapter (opencode, claude)
logsayer agent add opencode
# 4. Start a session: check state, work the story
logsayer state show
# ... implement HU-01 ...
# 5. Close the session: log it, audit when threshold is hit
logsayer log add "HU-01 done: API + tests"
logsayer check # mechanical: structure, no mixed layers
logsayer audit run # semantic: spec vs real code report
For an existing project:
logsayer init --here
Commands
| Command | Dune alias | Layer | Purpose |
|---|---|---|---|
logsayer init [name] |
— | scaffold | Creates docs/ + AGENTS.md + logsayer.toml |
logsayer init --here |
— | scaffold | Scaffolds into the current directory |
logsayer agent add <opencode|claude> |
— | coordination | Generates per-role subagents for a tool |
logsayer spec new <hu> |
logsayer mentat spec new |
1 | Creates a minimal HU template |
logsayer state show |
logsayer navigator state show |
2 | Prints the project snapshot |
logsayer log add "…" |
logsayer reverend-mother log add |
3 | Appends a logbook entry (auto-partition) |
logsayer log index |
logsayer reverend-mother log index |
3 | Rebuilds 00_index.md from real files |
logsayer check |
logsayer suk doctor |
4 | Mechanical checks: structure, no layer mixing |
logsayer audit run |
logsayer truthsayer audit run |
4 | Generates the audit report + semantic prompt |
logsayer audit status |
logsayer truthsayer audit status |
4 | Shows HU counter vs threshold, last report |
logsayer process check |
logsayer fremen verify |
5 | Process checks: Dor, coordination agreement |
Configuration (logsayer.toml)
Generated by logsayer init, tuned in a single file:
[logsayer]
session_close_context_threshold = 0.70 # % context used → propose session close
bitacora_max_lines = 400 # lines/logbook file before partitioning
audit_threshold_hus = 3 # HUs closed since last audit → trigger audit
How a session flows
- Session start — the agent reads only the state layer (
docs/project_state.md). Cheap in tokens, enough to orient. - Audit check — if the closed-HUs counter meets the threshold, the agent proactively proposes an audit (semantic verification).
- Work — the agent works a HU reading only its folder under
docs/04_user_stories/, and only opens a logbook entry when it needs the "why" of a past decision. - Close / commit — with your prior approval, the agent overwrites the state snapshot and appends to the active logbook.
- Auto-partition — when the active logbook exceeds the line limit, the next file is created and the master index updated.
Example session
A full, real transcript — run against a freshly scaffolded project — lives in examples/hello-logsayer/. It walks through scaffold, story creation, logbook entries, verification, and agent adapters, with the actual output of every command.
Multi-agent design
A single engine (logsayer/core/) plus one thin adapter per agent (logsayer/adapters/<agent>/) that only translates each tool's native file convention and calls the CLI. Adding a new agent means a new adapter, not new logic. See docs/ of this repo (master spec) for the full architecture.
Roadmap
- 0–4 (done): naming & manifest,
init, core commands (spec,state,log,audit), opencode/Claude adapters, mechanical validation (check,process check). - 5 (current): documentation & publishing — README, PyPI, MIT, examples. You are here.
- 6: community presets, more agents on demand (copilot, cursor, gemini, hermes).
Acknowledgment & license
- MIT — see LICENSE.
- Built around the 5-layer documentary system described in the master spec.
- Names and concepts from Dune are used as a thematic role metaphor only (full disclaimer at the top of this document).
Release files for logsayer 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| logsayer-0.6.0.tar.gz | 44.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| logsayer-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 79.0 kB
Release files / logsayer-0.6.0.tar.gz
| Download URL | logsayer-0.6.0.tar.gz |
|---|---|
| Size | 44.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f594d3d1e76b96e572da29178e2d9dbc1e2545cf14558a50206e4d39a357f8d2
|
|
BLAKE2b-256 checksum How to use checksums |
1d765e85487d094323608666f61d0c61d53df6c07d3f1204b44c32e2f9b86b0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / logsayer-0.6.0-py3-none-any.whl
| Download URL | logsayer-0.6.0-py3-none-any.whl |
|---|---|
| Size | 34.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0dce7e6e9529e6627553cc801096cc6e015fa5df6afefb44dc43bd1dbfa05f01
|
|
BLAKE2b-256 checksum How to use checksums |
0d4c31ca102e384cce1a1a94c242871567e44cee61e0d9a0dc5aaec5073cc966
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|