@klok-integration/cli 0.4.0 → 0.6.203

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,8 +22,12 @@ klok # opens the terminal UI
22
22
 
23
23
  Configuration lives in `~/.config/klok/config.json`. Every value can be overridden by an environment
24
24
  variable: `KLOK_AGENT_URL`, `KLOK_TENANT`, `KLOK_DOMAIN`, `KLOK_DEV_URL`, `KLOK_KEYCLOAK_ISSUER`,
25
- `KLOK_KEYCLOAK_CLIENT_ID`, `KLOK_GIT_URL`, `KLOK_GIT_LOCAL_WORKSPACE`. Run `klok config list` to see
26
- what is set and where it comes from.
25
+ `KLOK_KEYCLOAK_CLIENT_ID`, `KLOK_GIT_URL`, `KLOK_GIT_LOCAL_WORKSPACE`, `KLOK_GIT_APIKEY`. Run
26
+ `klok config list` to see what is set and where it comes from.
27
+
28
+ The GitLab token can be stored with `klok config set klokApiKey` (a hidden prompt, so it stays out of the shell
29
+ history). It is shown as `****` everywhere unless you run `klok config get klokApiKey --reveal`, and the file
30
+ is kept at mode 0600.
27
31
 
28
32
  Credentials are written to `~/.config/klok/credentials.json` with mode 0600.
29
33
 
@@ -40,8 +44,12 @@ Credentials are written to `~/.config/klok/credentials.json` with mode 0600.
40
44
  | `klok agent tasks`, `klok agent open <taskId>`, `klok agent cancel <taskId>` | Work with tasks. |
41
45
  | `klok agent answer <taskId> --question <qid> --text "..."` | Answer a clarification and continue. |
42
46
  | `klok agent serve [--port 3091]` | Loopback MCP and A2A proxy for IDEs and other agents. |
43
- | `klok agents init` | Write the Klok agent instructions and skills into a repository. |
47
+ | `klok agents init` | Write the Klok agent instructions, the platform skills and your tenant's skills into a repository, with a Claude Code hook that keeps them fresh. |
48
+ | `klok agents update [--check] [--global]` | Fetch what moved in the platform and tenant catalogs; `--check` writes nothing and exits 5 when something is outdated. |
49
+ | `klok agents status` | Per file and per catalog: current, outdated, missing or unreachable. |
44
50
  | `klok bead list\|show\|report` | Progress beads in the current repository. |
51
+ | `klok docs read <doc-id>` | Print a documentation project's `llm.txt` from docs.klok.dev, read with your GitLab token and cached. |
52
+ | `klok docs id [path]` | The doc id of a repository path. |
45
53
  | `klok docs publish` | Build this repository's znai documentation and upload it to the docs portal. |
46
54
  | `klok docs build` | Build this repository's `klok-docs/` with znai the way its documentation project will, uploading nothing. |
47
55
  | `klok solutions validate` | Check the descriptors of an integration solution registry against the descriptor contract. |
@@ -101,7 +109,12 @@ Cursor (`.cursor/mcp.json`):
101
109
  Klok skills. `KLOK-AGENTS.md`, the klok rule files and the `klok-*` skills belong to Klok and are
102
110
  replaced wholesale; every other file keeps its content and only has its single row created or replaced,
103
111
  so an update can never duplicate text. Klok skills the CLI no longer ships are removed.
104
- `klok agents status` shows whether a repository is up to date with the CLI version you have installed.
112
+ Your tenant's skills (`<tenant>-context` and one skill per documented repository) come from the tenant's private
113
+ catalog with your GitLab token (`KLOK_GIT_APIKEY`); they are installed, kept out of git, and refreshed by
114
+ `klok agents update`. `klok agents status` shows whether a repository is up to date with the catalogs.
115
+ After you install or update the CLI, the first interactive run tells you when the instructions you installed
116
+ with `klok agents init --global` or `--workspace` are older than the CLI, and prints the commands that update
117
+ them.
105
118
 
106
119
  ## Licence and support
107
120
 
@@ -53,6 +53,18 @@ The above copyright notice and this permission notice shall be included in all c
53
53
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
54
54
  ```
55
55
 
56
+ ## @klok-integration/brokerclient@0.3.114
57
+
58
+ Licence: Apache-2.0 — https://git.klok.dev/klok/framework/klok-brokerclient-java/-/tree/main/typescript/klok-brokerclient-typescript
59
+
60
+ _No licence file shipped with the package; see the project homepage._
61
+
62
+ ## @klok-integration/datamodel-klok-project-documentation-v1@1.0.0-build.260930043552
63
+
64
+ Licence: Apache-2.0 — https://git.klok.dev/klok/datamodel/public/klok-project-documentation-v1
65
+
66
+ _No licence file shipped with the package; see the project homepage._
67
+
56
68
  ## @modelcontextprotocol/sdk@1.30.0
57
69
 
58
70
  Licence: MIT — https://modelcontextprotocol.io
@@ -201,6 +213,32 @@ The above copyright notice and this permission notice shall be included in all c
201
213
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
202
214
  ```
203
215
 
216
+ ## avsc@5.7.9
217
+
218
+ Licence: MIT — https://github.com/mtth/avsc
219
+
220
+ ```
221
+ Copyright (c) 2015-2017, Matthieu Monsch.
222
+
223
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
224
+ this software and associated documentation files (the "Software"), to deal in
225
+ the Software without restriction, including without limitation the rights to
226
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
227
+ of the Software, and to permit persons to whom the Software is furnished to do
228
+ so, subject to the following conditions:
229
+
230
+ The above copyright notice and this permission notice shall be included in all
231
+ copies or substantial portions of the Software.
232
+
233
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
234
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
235
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
236
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
237
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
238
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
239
+ SOFTWARE.
240
+ ```
241
+
204
242
  ## bundle-name@4.1.0
205
243
 
206
244
  Licence: MIT
@@ -2,7 +2,7 @@
2
2
 
3
3
  A Klok application (portal, docs portal, agent service or another container) that is built and deployed with the
4
4
  platform pipelines: image to `repo.klok.dev`, deployment manifest in the manifests repository, secrets through
5
- Vault. Read https://docs.klok.dev/klok-environment-build-ci-templates/llm.txt for the release process and the
5
+ Vault. Read `klok docs read klok-environment-build-ci-templates` for the release process and the
6
6
  repository's own `README.md` and `docs/` for its architecture.
7
7
 
8
8
  ### Rules
@@ -2,8 +2,8 @@
2
2
 
3
3
  A Klok datamodel: an XSD (or JSON schema) under `schema-definition-xsd/`, converted by the pipeline to Avro and to
4
4
  a generated Java project that is published as `dev.klok.<tenant>.datamodel:<name>-v<n>` and written into the
5
- dependency catalog. Read https://docs.klok.dev/klok-framework-klok-common/llm.txt for naming and
6
- https://docs.klok.dev/klok-environment-build-ci-templates/llm.txt for the pipeline.
5
+ dependency catalog. Read `klok docs read klok-framework-klok-common` for naming and
6
+ `klok docs read klok-environment-build-ci-templates` for the pipeline.
7
7
 
8
8
  ### Rules
9
9
 
@@ -1,14 +1,15 @@
1
1
  ## This repository: documentation project
2
2
 
3
3
  A znai documentation project published to https://docs.klok.dev under the doc id in `klok-docs-sync.json`. Read
4
- https://docs.klok.dev/klok-environment-build-ci-templates/llm.txt (documentation from a source repository) for how
4
+ `klok docs read klok-environment-build-ci-templates` (documentation from a source repository) for how
5
5
  content arrives here. There are two kinds, and they are edited differently:
6
6
 
7
7
  * **The documentation project of a source repository** (`<tenant>/documentation/<group>/.../<repo>`, mirroring the
8
8
  source path) is output. KlokDocumentationEgress (`klok/integration/klok-documentation-egress`, KLK007) builds it
9
9
  from the `KlokProjectDocumentationV1` payload the source repository's `main` pipeline publishes, replaces
10
- everything under `docs/` on every run and commits the AI sections under `docs/_ai/`. Never edit it: a change made
11
- here is overwritten by the next run. There are exactly two places to change it:
10
+ everything under `docs/` on every run and commits the AI sections under `docs/_ai/`. It reads only tenant klok's
11
+ payloads today (klok/integration/klok-documentation-egress#2). Never edit it: a change made here is overwritten by
12
+ the next run. There are exactly two places to change it:
12
13
  * `klok-docs/` in the source repository, in a merge request there: the hand written pages, their order and
13
14
  chapter titles (`toc-manifest.json`), and where an AI section appears (`<!-- KLOK:GENERATED:START <id> -->` …
14
15
  `<!-- KLOK:GENERATED:END <id> -->`);
@@ -2,7 +2,7 @@
2
2
 
3
3
  Part of the Klok framework (klok-common, the broker client, the Quarkus extension, the gradle plugin or the CI
4
4
  templates). Changes here reach every tenant, so read the library's `klok-docs/` and its published documentation
5
- (`https://docs.klok.dev/klok-framework-<repo>/llm.txt`) before changing behaviour.
5
+ (`klok docs read klok-framework-<repo>`) before changing behaviour.
6
6
 
7
7
  ### Rules
8
8
 
@@ -3,7 +3,7 @@
3
3
  A Klok integration on the Quarkus extension 2.0: one Camel route per class, each extending a framework pattern
4
4
  (`KlokOnrampRoute`, `KlokProcessingRoute`, `KlokOfframpRoute`, their `Sync` variants, `KlokRestApi` and
5
5
  `KlokRestApiHandlerRoute`, `KlokAsyncTaskWorkerRoute`, `KlokCustomRoute`) and implementing the capabilities it
6
- needs. Read https://docs.klok.dev/klok-framework-klok-quarkus-extension/llm.txt before writing a route.
6
+ needs. Read `klok docs read klok-framework-klok-quarkus-extension` before writing a route.
7
7
 
8
8
  ### Commands
9
9
 
@@ -20,6 +20,11 @@ needs. Read https://docs.klok.dev/klok-framework-klok-quarkus-extension/llm.txt
20
20
  Configuration keys are `<RouteId>.<key>` with fallback to `<SolutionId>.<key>` and `klok.route-defaults.<key>`.
21
21
  * Datamodels are the type parameters of the pattern class and come from the catalog bundles; never hand write DTOs
22
22
  for something a datamodel project should own.
23
+ * A datamodel used in more than one flow gets a **topic purpose** per flow (`<Model>_<purpose>`, set with
24
+ `topicPurpose()` or `<RouteId>.topic.purpose`). The publisher sets it as the solution requires, the consumer
25
+ matches it, and both projects' `klok-docs/` write it down. A topic has at most one purpose; a reader is its
26
+ subscription (its route id), never a suffix. Never consume a shared topic and discard the other flows' messages.
27
+ The `klok-route` skill has the details.
23
28
  * Errors: throw `Klok4XXException` for caller errors (no retry) and `Klok5XXException` or plain exceptions for
24
29
  retryable failures; the framework retries, republishes to `_DLQ` and emits the failure event. Do not add
25
30
  `onException` blocks unless the route owns the failure (`failureHandled()`).
@@ -28,10 +33,12 @@ needs. Read https://docs.klok.dev/klok-framework-klok-quarkus-extension/llm.txt
28
33
  * Tests: `@QuarkusTest` with the recording broker client factory; assert routes started and published messages,
29
34
  never talk to a real broker or OpenSearch in unit tests.
30
35
  * A route that serves several tenants (a shared platform service) consumes each tenant's own request topic,
31
- `<tenant>[_<env>]/common/<Model>`, from the subscription list klok.dev keeps in the klok ODL; it takes the tenant
32
- from the namespace it received on and rejects a message whose payload or properties name another tenant. It never
33
- picks an index, repository or account from a field in the message, and what it writes back for a tenant goes to
34
- klok's namespace, one topic per tenant.
36
+ `<tenant>[_<env>]/common/<Model>`; it takes the tenant from the namespace it received on and rejects a message
37
+ whose payload or properties name another tenant. It never picks an index, repository or account from a field in
38
+ the message, and what it writes back for a tenant goes to klok's namespace, one topic per tenant. Today every
39
+ platform service is configured for tenant klok only, and the broker client has no topic list that can grow while
40
+ a service runs (klok/framework/klok-brokerclient-java#31, klok/application/frontend-klok-dev#53); say so in the
41
+ design instead of assuming one.
35
42
  * The service connects to the broker with a client of its own (`KLOK_BROKER_AUTH_CLIENT_ID`), granted `publish` and
36
43
  `consume` on its own tenant's namespaces only; a topic of another tenant is a `consume` grant on that one topic,
37
44
  reached with `<RouteId>.topic.tenant-override`. Never reuse another service's credentials.
@@ -8,23 +8,82 @@ otherwise yours. Do not copy rules into them.
8
8
 
9
9
  ## Read the documentation before guessing
10
10
 
11
- The platform documentation is published at https://docs.klok.dev. Every documentation project exposes its full
12
- content as one markdown file at `https://docs.klok.dev/<doc-id>/llm.txt`; fetch it instead of relying on memory.
11
+ Before anything else, run `klok agents update --check`. Exit 5 means the installed skills are behind a catalog:
12
+ run `klok agents update` and read the refreshed files. Exit 0 means they are current, and any other code names
13
+ what went wrong (no token, no network); say so instead of guessing.
14
+
15
+ The platform documentation is published at https://docs.klok.dev, one documentation project per repository, each
16
+ exposing its whole content as one markdown file. Read it with klok-cli, which sends your GitLab token and caches
17
+ the answer:
18
+
19
+ ```
20
+ klok docs read <doc-id> # the markdown on stdout, one status line on stderr; --json adds fetchedAt
21
+ klok docs id [tenant/group/.../repo] # the doc id of a repository, this one by default
22
+ ```
13
23
 
14
24
  | Topic | Read |
15
25
  |---|---|
16
- | Platform principles, event driven design, naming, onboarding | https://docs.klok.dev/klok-integration-strategy-and-tactics/llm.txt |
17
- | Route framework (patterns, config, logging, errors, topics, tasks) | https://docs.klok.dev/klok-framework-klok-quarkus-extension/llm.txt |
18
- | Naming conventions, message properties, CloudEvents | https://docs.klok.dev/klok-framework-klok-common/llm.txt |
19
- | Broker client | https://docs.klok.dev/klok-framework-klok-brokerclient-java/llm.txt |
20
- | Gradle plugin, versions, catalog | https://docs.klok.dev/klok-framework-klok-gradle-plugin/llm.txt |
21
- | CI templates, release process, Vault roles | https://docs.klok.dev/klok-environment-build-ci-templates/llm.txt |
22
- | Developer rules: identity and access, Keycloak, Vault paths, certificates, infrastructure as code | https://docs.klok.dev/klok-framework-development-guide/llm.txt |
23
- | How people use the platform: concepts, roles and access, workflow, operations | https://docs.klok.dev/klok-user-guide/llm.txt |
24
- | Infrastructure: stateful services, certificates, Ansible, Keycloak clients | https://docs.klok.dev/klok-environment-klok-environment-setup/llm.txt |
25
-
26
- A 404 means the documentation project is not published yet; read the repository's `klok-docs/` folder instead.
27
- The `klok-docs` skill describes the lookup in detail.
26
+ | Platform principles, event driven design, naming | `klok docs read klok-integration-strategy-and-tactics` |
27
+ | Route framework (patterns, config, logging, errors, topics, tasks) | `klok docs read klok-framework-klok-quarkus-extension` |
28
+ | Naming conventions, message properties, CloudEvents | `klok docs read klok-framework-klok-common` |
29
+ | Broker client | `klok docs read klok-framework-klok-brokerclient-java` |
30
+ | Gradle plugin, versions, catalog | `klok docs read klok-framework-klok-gradle-plugin` |
31
+ | CI templates, release process, Vault roles | `klok docs read klok-environment-build-ci-templates` |
32
+ | Developer rules: identity and access, Keycloak, Vault paths, certificates, infrastructure as code; onboarding a tenant | `klok docs read klok-framework-development-guide` |
33
+ | How people use the platform: concepts, roles and access, workflow, operations | `klok docs read klok-user-guide` |
34
+ | Infrastructure: stateful services, certificates, Ansible, Keycloak clients | `klok docs read klok-environment-klok-environment-setup` |
35
+
36
+ What the answers mean:
37
+
38
+ * **404**: the project is not published yet. Its hand written pages are in the repository's `klok-docs/` on
39
+ `main`, the source of the same site: `git -C <repo> fetch origin && git show origin/main:klok-docs/<page>.md`
40
+ (`toc-manifest.json` lists the pages). Read them there; nothing else is a substitute.
41
+ * **401 or 403** (no token, or your GitLab account is not a member of the tenant or domain): say so and ask for a
42
+ token or for access. Never guess what the page says, and never try another way in.
43
+
44
+ The `klok-docs` skill describes the lookup in detail. Cite the doc id you relied on, and the `fetchedAt` from
45
+ `klok docs read --json`, in your answer or merge request description.
46
+
47
+ ## Tenant skills
48
+
49
+ Next to the platform skills (`klok-docs`, `klok-solution`, `klok-route`, `klok-datamodel`, `klok-release`,
50
+ `klok-worktree`) the skill directories hold your tenant's own skills, generated by KlokDocumentationEgress from the
51
+ tenant's documentation publishes and served from the tenant's private catalog. The egress reads only tenant klok's
52
+ publishes today, so another tenant has no tenant skills yet:
53
+
54
+ * `<tenant>-context` is the router: what exists in the tenant (repositories, systems, datamodels, topics,
55
+ solutions), where it lives, and which skill to open for it. Start there. Its `data/` holds `projects.jsonl`,
56
+ `routes.jsonl`, `datamodels.jsonl`, `topics.jsonl` and `solutions.jsonl`.
57
+ * `<tenant>-<group>-…-<repo>` is one skill per documented repository (the name is its doc id): what the project
58
+ does, its routes, datamodels, topics, solution and configuration keys, with every fact as one JSON row in
59
+ `data/facts.jsonl` (`kind` first: `project`, `route`, `topic`, `datamodel`, `solution`, `config-key`, `doc-page`,
60
+ `component`).
61
+ * Search the facts instead of reading everything: `grep -i <term> .claude/skills/<skill>/data/facts.jsonl`, or
62
+ `jq -c 'select(.kind=="route")' .claude/skills/<skill>/data/facts.jsonl` (`.agents/skills/` for Codex, OpenCode
63
+ and Antigravity).
64
+ * They are installed, never committed: `klok agents update` refreshes them from the catalog and keeps them out of
65
+ git through `info/exclude`. Never edit them; a wrong fact is fixed in the repository's `klok-docs/` or code, and
66
+ the next documentation publish regenerates the skill.
67
+
68
+ ## Klok knowledge
69
+
70
+ The folder `knowledge/` next to this file holds the platform knowledge that Klok's models and agents share. Read
71
+ it when a task touches the platform:
72
+
73
+ | File | Holds |
74
+ |---|---|
75
+ | `knowledge/platform-rules.md` | the current platform rules: principles, naming, route ids and legs, topics, datamodel classes, write narrow and consume wide, claim check, tasks, the ODL |
76
+ | `knowledge/glossary.md` | the Klok terms and what they mean |
77
+ | `knowledge/kloker-identity.md` | Kloker's identity and writing style |
78
+ | `knowledge/roles/` | the role handbooks of the Kloker role models |
79
+ | `knowledge/retired-patterns.txt` | conventions the platform no longer has, one pattern per line with the reason |
80
+
81
+ * Klok knowledge is edited **only** in klok-integration-agent, `packages/cli/assets/agents/knowledge/`. Every other
82
+ copy is generated and never edited: `knowledge/` next to an installed `KLOK-AGENTS.md`, the catalog's
83
+ `agents/knowledge/`, `build/generated/klok-knowledge/` and the copies in images.
84
+ * A prompt, persona or agent instruction that needs the glossary or the platform rules loads the knowledge block.
85
+ It never restates it.
86
+ * Text that matches a line of `retired-patterns.txt` teaches a rule the platform no longer has; fix it at its source.
28
87
 
29
88
  ## Git is the truth, everything must work by hand
30
89
 
@@ -86,6 +145,32 @@ step by step procedure; the contract every agent follows is:
86
145
  * Repository discovery and sync (`klok sync`, workspace generators) exclude `<root>/worktrees`; a task tree is
87
146
  never a canonical repository.
88
147
 
148
+ ## Commits follow Conventional Commits
149
+
150
+ Every commit in a Klok repository follows [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/),
151
+ and so does every merge request title. The type says what kind of change it is, and the pipelines act on it: the
152
+ Klok templates choose which jobs run from the type of the change.
153
+
154
+ * The header is `<type>[(<scope>)][!]: <description>`: a lower case type, an optional scope naming the part that
155
+ changed, `!` for a breaking change, and a short imperative description (`feat(odl): add a scheduled query leg`,
156
+ `fix: take the tenant from the topic`, `docs(ci): explain the docs lane`). The body follows a blank line and says
157
+ why. Footers follow another blank line: `BREAKING CHANGE: <what breaks>`, `Refs: #12`, `Closes #7`.
158
+ * Types: `feat` a new capability, `fix` a bug fix, `docs` documentation only, `refactor`, `perf`, `test`, `build`
159
+ (build system and dependencies, the catalog copy included), `ci` (pipeline configuration), `style`, `revert`, and
160
+ `chore` for anything else that changes no behaviour.
161
+ * The merge request title is what `main` sees. Merge requests land as merge commits, and GitLab's default merge
162
+ commit message carries the title on its third line, where the template rules look. Give the merge request the
163
+ type of its whole change, not of its last commit.
164
+ * `docs` must be true. It covers `klok-docs/`, the Markdown files at the repository root and the bead files under
165
+ `.beads/`, nothing else. A `docs` merge request in a project built from a Klok template skips the build, the
166
+ image, the release and the deployment and only builds and publishes the documentation; `klok ci docs-only` fails
167
+ its pipeline when any other file changed. A merge request that mixes documentation with anything else takes the
168
+ type of the other change.
169
+ * A commit with no type, such as one made in the GitLab web editor, gets the full pipeline. So does a pipeline
170
+ started by hand (*Run pipeline*), by a schedule or through the API: that is how a change is built in full when it
171
+ was typed `docs` by mistake. The templates and the check are described on the *Change types* page of
172
+ `klok docs read klok-environment-build-ci-templates`.
173
+
89
174
  ## Versions come from the dependency catalog
90
175
 
91
176
  * Framework libraries, the gradle plugin and datamodels are released with timestamped versions from `main`
@@ -98,7 +183,7 @@ step by step procedure; the contract every agent follows is:
98
183
 
99
184
  ## Pipelines, secrets and infrastructure
100
185
 
101
- * After every push to git.klok.dev, check the pipeline (`glab api "projects/<id>/pipelines?per_page=3"`, job traces)
186
+ * After every push to git.klok.dev, check the pipeline (`glab api --hostname git.klok.dev "projects/<id>/pipelines?per_page=3"`, job traces)
102
187
  and fix failures before moving on. Publishing, image pushes, manifest updates and catalog updates only happen on
103
188
  `main`; merge request pipelines build and test.
104
189
  * Container images are built without privileges, always. Every image job extends `.klok_image_build` from
@@ -106,21 +191,81 @@ step by step procedure; the contract every agent follows is:
106
191
  layers, no layer cache, push from `main` only. Never use or propose a privileged runner, `docker:dind`, or a
107
192
  relaxed seccomp or AppArmor profile. A Dockerfile copies dependencies, assets and application code as separate
108
193
  `COPY` layers and sets owners with `COPY --chown`, never `RUN chown -R`, so that a build stores only what
109
- changed. Read the *Container images* page of https://docs.klok.dev/klok-environment-build-ci-templates/llm.txt
194
+ changed. Read the *Container images* page of `klok docs read klok-environment-build-ci-templates`
110
195
  before changing a Dockerfile or an image job.
111
- * Vault (`vault.ipaas.se`) is changed by a human only. Agents may read to diagnose and must then propose the exact
112
- command, including every existing field of the object.
113
- * New projects are created through klok.dev, or through the agent at https://agent.klok.dev authenticated as the
114
- tenant with the right to create projects in the domain. That is the supported path and it provisions what the
115
- project needs to build. Creating a project by hand is a legitimate fallback under *Git är sanningen*, but it is
116
- not the normal path: say up front what a human will still have to do, rather than letting it surface as a red
117
- pipeline. Vault needs nothing per project: the tenant CI role `<tenant>-ci` accepts every project under the
118
- tenant's root group. A tenant without it fails every job at `auth/jwt/login` with
119
- `role "<tenant>-ci" could not be found`; setting a tenant up is described in `klok-docs/ci/tenant-onboarding.md`
120
- of `klok/environment/build-ci-templates`.
196
+ * **Agents never write to Vault** (`vault.ipaas.se`). People write it, by hand or with the playbooks they run. The
197
+ only automated writer allowed is klok.dev's own provisioning identity, within its policy, and that identity does
198
+ not exist yet (klok/environment/klok-environment-setup#34). An agent may read to diagnose, and then proposes the
199
+ exact command, including every existing field of the object.
200
+ * New projects are created through klok.dev (the agent at https://agent.klok.dev asks klok.dev), or by hand, which
201
+ is a legitimate fallback under *Git är sanningen*. Neither path provisions a pipeline schedule, a deployment
202
+ manifest, a Vault Kubernetes role, a Keycloak client or broker grants yet: say up front what a human still has to
203
+ do (the `klok-release` skill lists it), rather than letting it surface as a red pipeline (tracked in
204
+ klok/application/frontend-klok-dev#41). Vault CI needs nothing
205
+ per project: the tenant CI role `<tenant>-ci` accepts every project under the tenant's root group. A tenant
206
+ without it fails every job at `auth/jwt/login` with `role "<tenant>-ci" could not be found`; setting a tenant up
207
+ is the *Onboarding a tenant* runbook in `klok docs read klok-framework-development-guide`.
121
208
  * Never push to `main` of an existing repository, never force push, never merge. Work on a branch and open a
122
209
  merge request that is ready for review; only a brand new repository gets its first commit on `main`. A draft
123
210
  merge request is not the default, it is what you open when the work is knowingly unfinished, and you say why.
211
+ * **Never cancel a running job without a human's yes.** Cancelling, stopping, killing, deleting or force-restarting
212
+ anything that runs is never done on an agent's own judgement: a CI job or pipeline, a release, a deployment
213
+ rollout, a pod, a container, a broker consumer, a scheduled task. Describe what you see (job id, how long it has
214
+ run by the current time from `date -u`, never an assumed time, the last log lines with their timestamps, what
215
+ waits behind it), say what you propose and what it would break, and wait for an explicit yes. "It looks hung",
216
+ "it blocks the `main` lane" and "it can be retried" are reasons to ask at once, not to act: a release that waits
217
+ for Maven Central or npm can legitimately take half an hour. On 2026-09-29 an agent cancelled the Gradle
218
+ plugin's release while it correctly waited for Maven Central, because it misread the time.
219
+
220
+ ## Manual steps are handed over as a guide
221
+
222
+ Whatever a task leaves for a human (merging merge requests, a Vault write, an Ansible run, a Keycloak or cluster
223
+ change, a decision) is handed over as a numbered step-by-step guide at the end of every answer that has such steps.
224
+ Someone who did not follow the work must be able to carry it out without working anything out:
225
+
226
+ * **What, why and how.** Each step says what to do and why, gives the exact commands in copyable code blocks (one
227
+ command per block, a dry run first where there is one, such as `ansible-playbook … --check --diff`), and says what
228
+ "done" looks like before the next step. Repeat the whole guide in the final answer, even when the steps were
229
+ mentioned earlier.
230
+ * **Commands run as pasted, from any directory.** The person pastes a command into a terminal that is not in your
231
+ worktree, so a command never relies on the working directory to tell it where it is: `glab` takes its host from
232
+ the git remote of the current directory and otherwise falls back to gitlab.com, where every Klok project is a 404,
233
+ so every `glab api` command carries `--hostname git.klok.dev`. Run a command from a neutral directory such as
234
+ `/tmp` before you hand it over.
235
+ * **Merging is a manual step.** List every merge request with its link and say whether the merge order matters and
236
+ why (the catalog before its consumers; klok-common, then the broker client, then the Quarkus extension; a
237
+ datamodel before the code that uses it), or say plainly that it does not.
238
+ * **Wait for the result, not for the merge.** Pipelines on `main` may run in parallel, so never assume that one job
239
+ runs at a time or that a merge means a release. When a step needs what an earlier pipeline produces (a datamodel
240
+ or framework version in the dependency catalog, an image in the deploy manifest, the agent files in the catalog, a
241
+ staged npm package, a published documentation project), the guide says to wait for that result and gives the
242
+ command that shows it. The catalog records every release as a commit on its `main`
243
+ (`chore(catalog): update <name> to the version published by <repository>@<sha>`,
244
+ `chore(catalog): update klok-agents to <version>`; releases before 2026-10-01 have the same titles without the
245
+ `chore(catalog): ` prefix and with a capital `Update`):
246
+
247
+ ```
248
+ glab api --hostname git.klok.dev "projects/klok%2Fframework%2Fklok-gradle-dependency-catalog/repository/commits?ref_name=main&per_page=10" | jq -r '.[].title'
249
+ ```
250
+ * **Hold points.** A plan that mixes agent work with such steps stops at numbered hold points, says exactly what the
251
+ human does there, and continues when they say so.
252
+
253
+ ## Design and maintenance start from the solution
254
+
255
+ Every task that designs, builds, changes or fixes a service, an integration, an API or a route starts from the
256
+ solution it belongs to, and new development and maintenance follow the same process (the `klok-solution` skill):
257
+
258
+ * Find the solution from the route id prefix and read its document in `<tenant>/integration-solutions` on `main`;
259
+ `klok solutions check` says whether the document still matches the code. A new solution gets its id and its
260
+ document before its first route.
261
+ * The document classifies every service (new project, new routes in an existing project, reused with a change,
262
+ reused as is, client change) and maps the legs: route ids, patterns, topics with purpose, datamodels.
263
+ * Integration logic is Java Klok routes. Doing integration work with the Python or TypeScript broker clients, or
264
+ inside an application or an external engine, is a `[TACTICAL]` choice whose motivation, cost and removal condition
265
+ the solution document states. An external engine (a GPU model server, a vendor service) stays a simple REST
266
+ service; priority, retries, claim checks and task state live in a Java leg.
267
+ * Every merge request that adds, changes or removes a leg brings the solution document to the new steady state, so
268
+ the registry describes the landscape that is built and deployed.
124
269
 
125
270
  ## Logic lives in the Klok tools, not in the pipelines
126
271
 
@@ -146,7 +291,10 @@ step by step procedure; the contract every agent follows is:
146
291
  and the solution key.
147
292
  * Topics: `persistent://<tenant>[_<env>]/<domain>/<Model>[_<purpose>]`, request/reply
148
293
  `ReqRes_<Req>_<Res>_Request|_Response`, dead letters `<topic>_DLQ`. The datamodel major version is in the class
149
- name (`CustomerV1`).
294
+ name (`CustomerV1`). The purpose is optional and the publisher's: the solution requires it so that one datamodel
295
+ serves several flows, and each consumer reads only the purpose of its flow. A topic has at most one purpose, and
296
+ the purpose never contains `_`. A reader is identified by its subscription, named after its route id, and never
297
+ appears in the topic name.
150
298
  * Context properties: `klok-correlation-id`, `klok-invocation-id`, `klok-parent-invocation-id`, `klok-task-id`,
151
299
  `klok-solution-id`, `klok-route-id`, `klok-tenant`, `klok-domain`, `klok-environment`; same spelling as HTTP
152
300
  header, Pulsar property and CloudEvents extension, `klok.`-prefixed as MDC key.
@@ -159,7 +307,7 @@ step by step procedure; the contract every agent follows is:
159
307
  ## Broker access and tenant isolation
160
308
 
161
309
  Read the *Broker Access And Tenant Isolation* page of
162
- https://docs.klok.dev/klok-framework-development-guide/llm.txt before designing anything that touches broker
310
+ `klok docs read klok-framework-development-guide` before designing anything that touches broker
163
311
  access, Keycloak broker clients or a service that serves several tenants.
164
312
 
165
313
  * **The topic decides the tenant, never the message.** Pulsar does not tell a consumer who published; a `tenant`
@@ -167,32 +315,45 @@ access, Keycloak broker clients or a service that serves several tenants.
167
315
  name and rejects a payload that claims another one.
168
316
  * **Write narrow, consume wide.** A tenant publishes only in its own namespace, `<tenant>[_<env>]/<domain>`; nobody
169
317
  holds `publish` in another tenant's namespace, not even on one topic. Reading elsewhere is a `consume` grant on a
170
- named topic, approved by the owner and recorded in Git in the owning tenant. A topic read across tenants carries
171
- its reader as the last purpose segment (`persistent://konvoj/hr/PersonnelScheduleExportV1_degerfors`).
172
- * **Platform services** (logs, the ODL, AI, mail, SMS, documentation) are shared klok workers that follow the same
173
- rule: a tenant's requests live in the tenant's namespace (`persistent://<tenant>[_<env>]/common/KlokLogEventV5`)
174
- and the worker is granted `consume` on exactly those topics, taking the tenant from the namespace; what the
175
- platform writes back lives in klok's namespace, one topic per tenant (`klok[_<env>]/<domain>/<Model>_<tenant>`).
176
- The worker subscribes to a list of topics kept in the klok ODL, never to a pattern. The ODL runs as one instance
177
- per tenant.
318
+ named topic, approved by the owner and recorded in Git in the owning tenant. The topic keeps its own name; the
319
+ reader is known by its subscription (its route id, `DEG012E1_...`). When the content belongs to one reader, the
320
+ publisher may choose that reader's tenant slug as the purpose
321
+ (`persistent://konvoj/hr/PersonnelScheduleExportV1_degerfors`); that is the publisher's choice, not a condition
322
+ for reading across tenants.
323
+ * **Platform services** (logs, the ODL, tasks, AI, documentation) are klok services, and today each one is
324
+ configured for tenant klok only (`klok.tenant=klok`; other tenants: klok/application/frontend-klok-dev#51). A
325
+ platform service that serves several tenants follows the same rule: a tenant's requests live in the tenant's
326
+ namespace (`persistent://<tenant>[_<env>]/common/KlokProjectDocumentationV1_prepared`), the service is granted
327
+ `consume` on exactly those topics and takes the tenant from the namespace, and what it writes back lives in klok's
328
+ namespace, one topic per tenant (`klok[_<env>]/<domain>/<Model>_<tenant>`).
178
329
  * **Identities:** one Keycloak client per running deployment, never shared, never used by a person; its Pulsar role
179
330
  is `service-account-<client id>`; one CI broker client per tenant; every broker client attaches the client scope
180
331
  `pulsar` (audience and the `nbf` claim Pulsar requires) instead of copying mappers.
181
332
  * **Grants:** `publish` and `consume` on the service's own domain and its tenant's `common`, as namespace grants;
182
333
  anything in another domain or tenant is `consume` on one topic, never `publish`, approved by its owner and
183
334
  recorded in Git in the owning tenant. Pulsar's `produce`/`consume` appear only inside a grant command.
184
- * **Who applies it:** Ansible (`klok/environment/klok-environment-setup`) for the platform and tenant klok's
185
- services, klok.dev for tenant projects. A grant made only in the broker's admin API is drift.
335
+ * **Who applies it:** Ansible (`klok/environment/klok-environment-setup`, `keycloak.yml` and `pulsar.yml`) applies
336
+ what those files declare: today the platform and tenant klok's services, plus any entries a person adds there for
337
+ another tenant's service (a playbook per tenant: klok/environment/klok-environment-setup#35). Broker access (a
338
+ tenant, a namespace, a topic created in advance, a grant) changes only through a merge request to those Pulsar
339
+ files, applied by Ansible run by a person. klok.dev provisions no broker clients or grants yet
340
+ (klok/application/frontend-klok-dev#51). A grant made only in the broker's admin API is drift.
186
341
 
187
342
  ## Documentation is part of every change
188
343
 
189
344
  Klok documentation has three levels, and a change is finished only when all three have been considered:
190
345
 
191
- * **The repository's own `klok-docs/`** (znai markdown, `toc-manifest.json`). On every `main` pipeline
192
- `./gradlew publishKlokDocs` publishes it, together with the scan of the code, as `KlokProjectDocumentationV1` on
193
- `persistent://<tenant>[_<env>]/common/KlokProjectDocumentationV1_prepared`. KlokDocumentationEgress
346
+ * **The repository's own `klok-docs/`** (znai markdown, `toc-manifest.json`). On every `main` pipeline it is
347
+ published as `KlokProjectDocumentationV1` on
348
+ `persistent://<tenant>[_<env>]/common/KlokProjectDocumentationV1_prepared`: by `./gradlew publishKlokDocs`, with
349
+ the scan of the code, in a Gradle project, and by `klok docs send` in any other (the Klok templates do this; a
350
+ project outside them includes `klok/environment/build-ci-templates:/klok-docs-send.yml`).
351
+ `klok docs send --dry-run` shows what would be sent. KlokDocumentationEgress
194
352
  (`klok/integration/klok-documentation-egress`, KLK007) builds the repository's documentation project from it. That
195
- documentation project is output, and nobody edits it. There are two places to change a project's documentation:
353
+ documentation project is output, and nobody edits it. This runs for tenant klok only: another tenant has no
354
+ documentation broker client, so its `klok_docs_publish` job fails and, being `allow_failure`, only warns
355
+ (klok/environment/klok-environment-setup#33), and the egress reads only klok's topic
356
+ (klok/integration/klok-documentation-egress#2). There are two places to change a project's documentation:
196
357
  `klok-docs/` in the source repository (including the `KLOK:GENERATED` markers that place AI sections in a page),
197
358
  and the documentation generation settings in klok.dev, which tenant admins own. A change that adds or alters a
198
359
  route, a datamodel, a configuration key, a CI job, a command or a decision updates `klok-docs/` in the same merge
@@ -223,6 +384,21 @@ Klok documentation has three levels, and a change is finished only when all thre
223
384
  sections that fill `KLOK:GENERATED` regions. They are never edited by hand. A wrong generated page is fixed in
224
385
  the egress or in the documentation generation settings in klok.dev.
225
386
 
387
+ **Documentation describes only what exists, in one place.** A cross-cutting topic lives in the framework
388
+ documentation projects under `klok/documentation/`, everything else in the owning project's `klok-docs/`; other
389
+ places link there instead of repeating it. A wrong statement is removed or corrected, never marked as outdated. A
390
+ wanted feature written as if it existed becomes an issue in the repository that would build it, and the text is
391
+ removed. Never use the present tense for something that is not built.
392
+
393
+ **Prompts and agent instructions carry the same knowledge.** System prompts, section prompts, personas, tool
394
+ descriptions, these agent instructions and the skills teach platform rules to a model, and they load the shared
395
+ blocks from *Klok knowledge* above instead of restating them. The *Prompt Catalogue* in
396
+ the framework development guide (`klok docs read klok-framework-development-guide`) lists every place.
397
+ A change to a platform rule, the strategy, naming, the datamodel classes or the glossary checks the catalogue. It
398
+ updates every prompt that restates the change, or files an issue in the owning repository for each one it leaves. A
399
+ new prompt, persona, tool description or agent instruction is added to the catalogue in the same merge request.
400
+ Prompts never carry `/think` or `/no_think` tokens; the model name (`Kloker-nothink`, `Kloker`) is the only switch.
401
+
226
402
  ### Before the merge request
227
403
 
228
404
  1. Update the repository's `klok-docs/` in the same merge request as the change — ideally in the same commit as
@@ -233,7 +409,7 @@ Klok documentation has three levels, and a change is finished only when all thre
233
409
  cannot parse fails now instead of stopping the documentation project from publishing after the merge, where
234
410
  nobody in this repository sees it.
235
411
  3. Ask what a reader of the platform documentation would now find wrong: a renamed command, a new rule, a changed
236
- default, a workflow with one more step. Read the affected pages (`https://docs.klok.dev/<doc-id>/llm.txt`)
412
+ default, a workflow with one more step. Read the affected pages (`klok docs read <doc-id>`)
237
413
  instead of guessing what they say.
238
414
  4. Correct what you can judge yourself. A central page that is now plainly wrong is fixed in its own small merge
239
415
  request against that documentation project, linked from the change. What you cannot judge is written down
@@ -248,8 +424,9 @@ The pipeline on `main` publishes the project's documentation payload (`KlokProje
248
424
  sources, configuration keys and the whole `klok-docs/` folder with a hash per file). KlokDocumentationEgress
249
425
  (`klok/integration/klok-documentation-egress`) turns it into the project's published documentation: your
250
426
  `klok-docs/` pages as written, with `KLOK:GENERATED` regions filled, next to generated pages for routes,
251
- datamodels and configuration. Nothing behind you updates the central platform documentation, so the steps above
252
- are the ones that matter.
427
+ datamodels and configuration. The egress reads only tenant klok's topic today
428
+ (klok/integration/klok-documentation-egress#2), so another tenant's projects get no generated documentation yet.
429
+ Nothing behind you updates the central platform documentation, so the steps above are the ones that matter.
253
430
 
254
431
  ## How to work
255
432
 
@@ -257,9 +434,12 @@ are the ones that matter.
257
434
  2. Create the task worktree and branch before the first edit (see *One task, one worktree, one branch*) and say
258
435
  which repository, worktree and branch you work in.
259
436
  3. Build and test locally with the repository's standard commands before pushing; keep every commit green.
260
- 4. Small, reviewable merge requests with a description that states what changed, why, and which documentation
261
- it affects.
437
+ 4. Small, reviewable merge requests with a Conventional Commits title (see *Commits follow Conventional Commits*)
438
+ and a description that states what changed, why, and which documentation it affects.
262
439
  5. A new project cloned from a template refreshes the catalog copy and the agent instructions before the first
263
- push: `./gradlew updateKlokLibsToml updateKlokAgents`. klok.dev does the same HTTP fetch when it creates the
264
- project. Re-run the tasks later to pick up a new catalog or a new skill set.
440
+ push: `./gradlew updateKlokLibsToml updateKlokAgents`. klok.dev fetches only the versions catalog when it creates
441
+ a project; the agent instructions come as committed in the template. Re-run the tasks later to pick up a new
442
+ catalog or a new skill set.
265
443
  6. Report outcomes faithfully: failing tests, skipped steps and open questions are stated, not hidden.
444
+ 7. End with the step-by-step guide of everything left for a human, merges included (see *Manual steps are handed
445
+ over as a guide*).