Scheduled Librarian
playbooks/scheduled-librarianChecked by automation only
still a draft
Written 2026-10-27 by ktl-librarian (automation). Last checked 2026-10-27 by ktl-librarian (automation).
The full record
- Checks
- 2026-10-27 by
ktl-librarian(automation)
- 2026-10-27 by
- Sources
- Depends on
- Related to
- Pointed to by
- Knowledge registrar gate (related to)
- Graph
- Open this concept in the knowledge graph
- IRI
https://w3id.org/ktl/registrar/knowledge/playbooks/scheduled-librarian- Licence
- CC BY 4.0
- Files
- MarkdownJSON-LDSource on GitHubHistory on GitHub
Overview
Section titled “Overview”.github/workflows/knowledge-librarian.yaml runs the ktl-librarian skill on a schedule (Mondays 05:00 UTC) and on demand, to keep .lokf/knowledge/ in step with the repository. It opens a review pull request with whatever changed. It never pushes to the default branch and never auto-merges, opens no pull request when nothing changed, and is inert until the KNOWLEDGE_LIBRARIAN_ENABLED repository variable is true. It is a copy of the ktl-sidecar template, and SECURITY.md says the copy differs from the template only in the pin it names: TRUST_LADDER_SKILLS_REF, with the commit that tag names in TRUST_LADDER_SKILLS_SHA. The install step installs nothing when the tag no longer names that commit.
Three jobs, split by privilege
Section titled “Three jobs, split by privilege”-
earlierreads the pull requests this workflow opened before, under a token that can read pull requests and nothing else, and runs no agent. A scheduled run opens no second pull request while one is still open, and does not propose again what a person declined by closing one without merging, until the source moves or a reader asks again. A run a person starts does neither. -
refreshruns the agent, which is third-party code, undercontents: readwithpersist-credentials: false, so no git credential is on disk while it runs. The agent writes one file,.lokf/patch.yaml, which the wrapper applies withknowledge-apply.sh. The job validates the result and hands the change topublishas a patch artifact. -
publishruns no agent code and is the only job that holdscontents: writeandpull-requests: write. It applies the patch to a clean checkout, pushes the branch and opens the pull request.
When the agent runs
Section titled “When the agent runs”The workflow reads AGENT_CLI from a repository variable or, as a fallback, a secret. AGENT_PROMPT_FLAG, AGENT_API_KEY_ENV, AGENT_USE_JOB_TOKEN and the AGENT_API_KEY secret say how the prompt and the agent’s credential reach it, and KNOWLEDGE_RETRIEVAL turns on an optional retrieval score. A scheduled week skips the agent when knowledge-report.sh finds nothing waiting: no moved source, no note a person left since the librarian last looked, no concept without a stamp and no reader feedback. A scheduled run in a month’s first seven days, and a run a person starts, always go ahead.
Checks on the agent’s write scope
Section titled “Checks on the agent’s write scope”.lokf/scripts/knowledge-librarian.sh is the fixed wrapper the workflow runs, never a variable’s content as a shell command. It splits AGENT_CLI into an argument array with read -r -a, so shell metacharacters in it are inert. The agent call and the post-run check that it wrote nothing but .lokf/patch.yaml live inside main(), which the script calls only from its last line. The wrapper snapshots .git/config and .git/hooks before the agent runs and restores both from an EXIT trap, so a changed core.fsmonitor or core.hooksPath cannot defeat a later check.
While the agent runs, the wrapper exports KNOWLEDGE_PEN_DRY_RUN_ONLY=1. The pen then refuses any call but --dry-run and leaves .lokf/patch.yaml in place for the wrapper to apply. This guards against an agent that calls the pen itself: without the flag, the pen would apply the patch and delete the file, leaving the checks below nothing to re-derive the allow-list from.
The refresh job’s “Enforce the agent’s write scope” step repeats the boundary check in YAML. The check that matters is publish’s, on a checkout that never shared a workspace with the agent. It re-derives the allow-list (.lokf/knowledge/, knowledge_bundle/, .lokf/feedback.md and .lokf/questions.md) from the patch’s own git apply --numstat output, refuses a patch that adds a by: human: line, and after applying runs knowledge-provenance.sh --unattended to refuse a change to any person’s event or note.
The registrar gate does not run on this pull request
Section titled “The registrar gate does not run on this pull request”GitHub starts no pull_request workflow for a pull request opened with the default GITHUB_TOKEN, so knowledge-registrar.yaml’s jobs do not run on the librarian’s pull request, and publish’s checks are its backstop. What the gate checks on a person’s own pull request is in Knowledge registrar gate.
Governance
Section titled “Governance”SECURITY.md lists this workflow and its wrapper as one row of its Surface | What holds it table, and links the guard design in the skills repository’s threat model. The “Repository-Owned Agent Automation” section of AI_COVENANT.md sets the rules the workflow runs under: a bot identity, review always, least privilege enforced, and verdicts that only a person can record.