# PR#85: An AI Summary as the Description of a Werkjournal Entry Version: minor > **WARNING:** This document describes only the change applied in this PR. > It may already be outdated once the next PR is merged. > Historic PR documentation is not maintained along with new PRs; treat it as a snapshot. ## Related Links - [werkregie PR#84](https://git.javagil.de/mi/werkregie/pulls/84): `JournalProposer` at a Mutation-CRAP of at most 15, the prerequisite. ## Problem The description of a proposed Werkjournal entry is built by rules: the story, the pull requests, the tasks, the sessions and the Matrix rooms, joined by semicolons. It names what happened, but reads as a list, not as a description of the work. Werkjournal adds a changed entry as a new one, so the same data must give the same text. ## Non-Goals - No transcripts as input; the model gets the evidence of the entry only, as the rules do. - No change of the rule text. ## Specification ### Feature: an AI summary as the description of a Werkjournal entry #### Scenario#85.01: the switch takes the AI summary into the entries and the file … so that the human imports a readable description. - **Given** a day with an entry of the project Werkregie and a configured `journal.summary` - **When** the human selects "KI" in the tab Journal - **Then** the entry shows the AI summary of its evidence, and the copied or downloaded file holds it ##### Verified by - [JournalProposerTest "each entry of the file gets the AI summary of its evidence; the file keeps the rule text"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/journal/JournalProposerTest.kt) - [journal.test.js "the rules take the rule text, the AI its summary"](../../dashboard/src/test/js/journal.test.js) - [EntrySummariesTest "the chat model gets the instructions and the evidence with the key, and its text is the summary"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/journal/EntrySummariesTest.kt) - manual check in the browser, see "Solution" #### Scenario#85.02: the same data gives the same summary … so that a second import adds no entry to Werkjournal. - **Given** a day whose proposal was summarized once - **When** the human opens the proposal of that day again, also after a restart of the server - **Then** each entry shows the same summary, and the model is not asked again ##### Verified by - [EntrySummariesTest "the same input gives the same summary, after a restart too, and the model is asked once"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/journal/EntrySummariesTest.kt) - [EntrySummariesTest "a summary in use is kept beyond the time since it was written"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/journal/EntrySummariesTest.kt) - [EntrySummariesTest "the model gets the project, the story and the evidence of the entry, in the order of the proposal"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/journal/EntrySummariesTest.kt) #### Scenario#85.03: without a model the rules stay … so that a configuration without a model works as before. - **Given** no `journal.summary` in the configuration - **When** the human opens the tab Journal - **Then** the tab shows no switch, and each entry the rule text ##### Verified by - [EntrySummariesTest "no model configured is no summaries; a missing key is their problem; a key from the environment works"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/journal/EntrySummariesTest.kt) - [journal.test.js "an entry without summary keeps the rule text under the AI too"](../../dashboard/src/test/js/journal.test.js) #### Scenario#85.04: a failing model leaves the rule text and names the cause … so that the human can import the day all the same. - **Given** a configured `journal.summary` whose model fails - **When** the human selects "KI" - **Then** each entry keeps the rule text, and the tab names the cause ##### Verified by - [JournalProposerTest "a failing model leaves the entries without summary and names the cause"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/journal/JournalProposerTest.kt) - [EntrySummariesTest "without a model, or with an empty answer, there is no summary and the cause is named"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/journal/EntrySummariesTest.kt) - manual check in the browser, see "Solution" #### Scenario#85.05: the choice stays … so that the human does not select it for each day. - **Given** the tab Journal with "KI" selected - **When** the human picks another day or opens the page again - **Then** "KI" stays selected ##### Verified by - manual check in the browser, see "Solution" ## Solution - `journal.summary` configures the chat model, as `claude.summary` does; without it, nothing changes. - `EntrySummaries` asks the model for each entry of the file, in parallel, with the project, the story and the evidence; the instructions ask for one or two German sentences of at most 300 characters, without invented facts. It keeps each summary by the SHA-256 of its input in `/journal-summaries.json`, 400 days after its last use; one lock per input keeps two requests of the same day from two answers. - `ProposedEntry.summary` carries the summary; `Proposal.summaryError` the first failure, e.g. a missing key. The file of the server keeps the rule text; the page builds the imported file from the text the switch picks. - The tab Journal shows the switch "Regeln | KI" when an entry has a summary or the proposal an error; the page keeps the choice, and a correction of the human stays with the text it corrected. - `journalDescription` and `journalField` move into `static/journal.js`, tested by `jsTest` (ADR 0002). ### Manual Check On 2026-10-14, a local dashboard with the recorded day 2026-10-13 and `journal.summary` with Haiku through OpenRouter: - The first proposal took 6 s and gave, e.g. for the project Werk: "Werkjournal-Import pro Kalendertag, Kunden-, Projekt- und Gewohnheitsangaben aus importierten Einträgen (PR#6), …"; the second took 0.03 s and gave the same texts from `journal-summaries.json`. - "KI" showed the summaries in the entries, "Regeln" the rule texts; the choice stayed after a reload. - Without the key, the switch stayed, the entries kept the rule text, and the tab said "Keine KI-Zusammenfassung: kein Schlüssel in OPENROUTER_API_KEY". ## Release Notes The tab Journal offers an AI summary of each entry beside the rule text, with the switch "Regeln | KI"; the server needs `journal.summary` for it. ## Additional Changes - `dashboard.server.example.yml` names `journal.summary`. ## Open Questions None.