Skip to content

T3 — logbook pipeline: writer/reader, tier routing, salient push#29

Open
cyber-ayi wants to merge 1 commit into
mainfrom
ops/t3-logbook
Open

T3 — logbook pipeline: writer/reader, tier routing, salient push#29
cyber-ayi wants to merge 1 commit into
mainfrom
ops/t3-logbook

Conversation

@cyber-ayi

Copy link
Copy Markdown
Collaborator

Closes #26.

Summary

The logbook capture-layer mechanism (not its judgment). Python — the pipeline touches the private record, so it runs local at runtime (AGENTS.md rule 6) and co-locates with the Python L3 (ADR-0006); the TS harness stays on the world-facing side of the bridge seam.

  • writer/reader validating against logbook/schema/entry.schema.yaml (the schema's own DSL is parsed into a typed spec, so validation binds to the file, not a hand-copied field list).
  • tier routing: private default → an out-of-repo store (~/.commonplace/logbook, env-overridable to an Obsidian vault). shareable/narrative get their own dirs.
  • redaction gate: refuses to emit shareable/narrative without redaction_checked: true (RedactionRequiredError) — even on dry-run. Validation and the gate are separate concerns: a shareable entry with the flag unset is well formed but not emittable.
  • salient-push hook → AstrBot/Discord, transport-not-brain (exploration/gateway-selection.md): the sinks carry an already-chosen entry to the operator's channel; no salience logic, LLM, or filtering lives here (that's the drive layer, T4/T5). Default NullSink → no network. Discord-webhook is the documented thin fallback.
  • thin CLI (validate / route / emit) and a logbook-ci workflow (a signal, not a hard gate, per adr-0001).

Acceptance (issue #26 DoD)

  • Round-trips the synthetic sample.redacted.md — semantic equality, idempotent serialization, body verbatim.
  • Refuses shareable/narrative without redaction_checked: true.
  • Creates NO real entries in the repo — store defaults outside the working tree; a test asserts the repo tree holds no *.entry.md.

Language sub-decision

Resolved to Python (was open in #26). Forced by AGENTS.md rule 6 + ADR-0006 (record-touching → local → co-located with L3). No new ADR — ADR-0006 already covers it; recorded in the pipeline README rationale.

Test plan

  • pytest — 89 passed, 100% line+branch coverage of the pipeline surface.
  • Editable install (pip install -e ".[dev]") + console script smoke green in a clean venv (matches CI, which upgrades pip first).
  • Reviewer: confirm the out-of-repo store default and gate semantics match the intended discipline.

Notes

  • Salient push targets the operator's own dyad channel (not publication), so the redaction gate — a publication control — deliberately does not apply there; a private entry may be surfaced to the operator, never published.
  • Adds *.egg-info/ to .gitignore so editable installs don't surface build artifacts.
  • ROADMAP/TASKS status flip for T3 left for a separate docs PR to keep this focused.

Per the worktree workflow; one task → one PR; stopping here for operator review.

🤖 Generated with Claude Code

The record's capture-layer mechanism (not its judgment): validate entries
against logbook/schema/entry.schema.yaml, route by visibility tier, enforce the
redaction gate, and push salient entries transport-not-brain. Closes the T3
acceptance in TASKS.md / issue #26.

Language: Python — the pipeline touches the private record so it runs local at
runtime (AGENTS.md rule 6) and co-locates with the Python L3 (ADR-0006). The TS
harness stays on the world-facing side of the bridge seam.

- schema.py: parse the entry.schema.yaml DSL into a typed SchemaSpec, so the
  validator binds to the file rather than a hand-copied field list.
- entry.py / reader.py: Entry model + YAML-frontmatter parse/serialize; the
  synthetic sample round-trips (semantic + idempotent; body verbatim).
- validate.py: structural validation, schema defaults applied (visibility ->
  private, redaction_checked -> false); tz-aware datetime required.
- store.py: visibility tier -> on-disk path. Defaults OUTSIDE the repo
  (~/.commonplace/logbook), env-overridable (Obsidian vault); a stray entry can
  never be committed (AGENTS.md rule 2 / ADR-0005).
- writer.py: validate -> redaction gate -> tier-routed write. Refuses to emit
  shareable/narrative without redaction_checked: true (RedactionRequiredError),
  even on dry-run. Content-addressed filenames -> idempotent re-emit.
- salient.py: transport-not-brain push sinks (AstrBot / Discord-webhook
  fallback / Null default). No salience logic, LLM, or filtering here — that is
  the drive layer (T4/T5). Channel per exploration/gateway-selection.md.
- cli.py: validate / route / emit.
- logbook-ci.yml: a signal (not a hard gate, per adr-0001), 100% pipeline
  surface. A test asserts the repo tree holds NO real *.entry.md.

Verified: pytest 89 passed, 100% line+branch coverage; editable install + console
script smoke green; sample round-trips; no entries created in the repo.

Session-Id: 019e909f-788f-7c38-bce3-26c9decd24ec
Agent: cc-rc-bot

Co-authored-by: cyber-ayi <259769279+cyber-ayi@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[task] T3 — logbook pipeline (writer/reader, tiers, salient push)

1 participant