Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e6a6fbb
docs(architecture): write chapter 7 as the distribution view (#2410)
braboj Oct 30, 2026
5afa06b
docs(architecture): route the hooks path around the project in chapte…
braboj Oct 30, 2026
385e864
docs(architecture): name the vendored copy pinned templates in chapte…
braboj Oct 30, 2026
48dbc26
docs(architecture): label the pinned templates templates@v3.0.0 in ch…
braboj Oct 30, 2026
228244b
docs(architecture): say the CI fetches the commit in chapter 7's diag…
braboj Oct 30, 2026
791d297
docs(architecture): label the CI path fetch commit, like its neighbou…
braboj Oct 30, 2026
71b3d14
docs(architecture): label the CI path checkout in chapter 7's diagram…
braboj Oct 30, 2026
dad13f5
docs(architecture): label the CI path checkout <ref> in chapter 7's d…
braboj Oct 30, 2026
5c9e604
docs(architecture): show pre-commit on the developer's machine and in…
braboj Oct 30, 2026
164f3db
docs(architecture): give chapter 7's sections neutral technical names…
braboj Oct 30, 2026
fa49ed9
docs(architecture): name chapter 4 and 6 sections and diagrams neutra…
braboj Oct 30, 2026
958c15e
docs(architecture): state the move to a fork in one sentence in chapt…
braboj Oct 30, 2026
75d3ca5
docs(architecture): fold the move to a fork into chapter 7.2's table …
braboj Oct 30, 2026
f46e875
docs(architecture): name chapter 7.3 Integration models (#2410)
braboj Oct 30, 2026
cdd0cec
docs(architecture): separate hooks only from the template models in c…
braboj Oct 30, 2026
8761f8c
docs(architecture): move 7.3's lead-in into a Brings column (#2410)
braboj Oct 30, 2026
4194e5e
docs(architecture): cite requirements, not the playbook, in chapters …
braboj Oct 30, 2026
d0c4371
docs(architecture): explain the hooks-only opt-out in 7.3's lead-in, …
braboj Oct 30, 2026
6a0eadf
docs(architecture): add generated files only to 7.3, qualify the fork…
braboj Oct 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/architecture/04-solution-strategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ catch it, copied into its context; any other rule may stay a reference.
| A mechanically checkable rule names its command and pass condition. This repository gives every such check a disposition, and runs each one that applies here | A rule upstream ships is one upstream obeys, and a skip states its reason | ADR-030, ADR-031, FR-07-01, QG-01-01 |
| The 3.x line freezes its contract, and a removal waits for the next major, except for a security fix | A project pins a release and moves the pin without rework | ADR-051, FR-09-01, FR-09-02, QG-03-02 |

## 4.2 Delivery
## 4.2 Delivery model

![How one rule is placed: if breaking it is silent and no test, linter or CI step enforces it, it is inlined; if it fails visibly or a tool enforces it, it may be referenced. Inline and hybrid remain; pure reference is deprecated](../diagrams/delivery-model.png)

Expand Down
23 changes: 11 additions & 12 deletions docs/architecture/06-runtime-view.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ not wait. A frame marks a choice (`alt`) or a repeat (`loop`), with its
condition in brackets. The numbers on the messages are the steps of each
table.

## 6.1 Generating a project's context
## 6.1 Context generation

The agent writes the project's context files from the chain the resolver
orders, placing each rule where the output contract says.

![Generating a project's context. The team asks the coding agent to generate the context for a root. The agent reads the fork's interview questions and asks the team each one, getting the answers and the adopted rules. It runs the resolver, which seeds the core tier and walks depends_on, and gets the ordered file list. For an inline or hybrid file, it reads each template in order, applies overrides then extensions, places each rule, writes AGENTS.md and CLAUDE.md, and runs the self-check. For a root file with skills, it runs the emitter with the declined list, which places each section by its load and returns the root file and task skills with fact slots, and the agent fills the facts. The agent hands the files to the team for review](../diagrams/runtime-generate.png)
![Context generation. The team asks the coding agent to generate the context for a root. The agent reads the fork's interview questions and asks the team each one, getting the answers and the adopted rules. It runs the resolver, which seeds the core tier and walks depends_on, and gets the ordered file list. For an inline or hybrid file, it reads each template in order, applies overrides then extensions, places each rule, writes AGENTS.md and CLAUDE.md, and runs the self-check. For a root file with skills, it runs the emitter with the declined list, which places each section by its load and returns the root file and task skills with fact slots, and the agent fills the facts. The agent hands the files to the team for review](../diagrams/runtime-generate.png)

| Step | What happens | Source |
|------|--------------|--------|
Expand All @@ -36,12 +36,12 @@ list, then the root's file and every file its dependency lines name,
transitively. Skipping either list loses rules with no error, because no
template declares those files.

## 6.2 A task skill loads
## 6.2 Task skill loading

The root file holds the rules for every turn; a procedure for one kind of
task loads only when that task starts.

![A task skill loads. At the start of the session the coding agent reads the root file and gets the rules for every turn and the trigger table. The team gives it a task, such as a release, and the agent matches the task to a trigger. If one matches, it loads that skill's SKILL.md and gets the task's procedures; otherwise it works from the root file alone. It applies the rules, does the task, and returns the change with its evidence](../diagrams/runtime-skill.png)
![Task skill loading. At the start of the session the coding agent reads the root file and gets the rules for every turn and the trigger table. The team gives it a task, such as a release, and the agent matches the task to a trigger. If one matches, it loads that skill's SKILL.md and gets the task's procedures; otherwise it works from the root file alone. It applies the rules, does the task, and returns the change with its evidence](../diagrams/runtime-skill.png)

| Step | What happens | Source |
|------|--------------|--------|
Expand All @@ -50,25 +50,25 @@ task loads only when that task starts.
| 4 | A skill is one folder under `.agents/skills/`, copied where an agent reads only its own folder | ADR-058, proposed |
| 5 | An agent that cannot load skills gets them inlined in the root file | ADR-058, proposed |

## 6.3 A shipped hook runs in a project's CI
## 6.3 Hook execution in CI

A check too long for a fence ships as a hook, which pre-commit runs at the
revision the project pinned.

![A shipped hook runs in a project's CI. The project's CI runs pre-commit for a hook. pre-commit fetches upstream at the pinned revision and installs the solid-ai-checks command, then runs it with the hook ID. The hook reads the project's tracked files. If the check passes, it exits 0 with the inspected counts; if it finds a breach, it exits 1 with the findings; if it does not apply, it prints a line and exits 0. pre-commit reports pass or fail to CI](../diagrams/runtime-hook.png)
![Hook execution in CI. The project's CI runs pre-commit for a hook. pre-commit fetches upstream at the pinned revision and installs the solid-ai-checks command, then runs it with the hook ID. The hook reads the project's tracked files. If the check passes, it exits 0 with the inspected counts; if it finds a breach, it exits 1 with the findings; if it does not apply, it prints a line and exits 0. pre-commit reports pass or fail to CI](../diagrams/runtime-hook.png)

| Step | What happens | Source |
|------|--------------|--------|
| 1-2 | The project's pre-commit configuration names upstream, a revision and the hook IDs, which `.pre-commit-hooks.yaml` lists | FR-07-02, ADR-055 |
| 3-4 | Every hook reads the tracked tree itself, so pre-commit passes it no file names | ADR-055 |
| 5-7 | A check exits 0 on a pass, 1 on a breach and 3 when it does not apply. Under pre-commit, 3 becomes a printed line and exit 0 | FR-07-03 |

## 6.4 A fork takes an upstream change
## 6.4 Upstream synchronisation

A fork stays current by merging upstream, never by copying files. A commit
that removes what forks carry is marked `Fork-merge: ours`.

![A fork takes an upstream change. The fork maintainer fetches upstream and lists the commits carrying Fork-merge: ours, oldest first. For each, the maintainer merges its parent, merges the commit with -s ours, keeping the fork's files, then moves the fork's templates to its own keys and restores upstream's text. The maintainer then merges upstream/main and pushes, and the fork's CI runs smoke against upstream/main](../diagrams/runtime-fork-sync.png)
![Upstream synchronisation. The fork maintainer fetches upstream and lists the commits carrying Fork-merge: ours, oldest first. For each, the maintainer merges its parent, merges the commit with -s ours, keeping the fork's files, then moves the fork's templates to its own keys and restores upstream's text. The maintainer then merges upstream/main and pushes, and the fork's CI runs smoke against upstream/main](../diagrams/runtime-fork-sync.png)

| Step | What happens | Source |
|------|--------------|--------|
Expand All @@ -79,15 +79,14 @@ that removes what forks carry is marked `Fork-merge: ours`.

`py tests/run.py fork_sync` runs the same merge on every pull request
upstream, in a simulated fork that appends a stack and edits its own files
(FR-10-02). The playbook, "Sync with upstream as a fork", gives the
commands.
(FR-10-02).

## 6.5 A project adopts a release
## 6.5 Release adoption

A newer tag adopts nothing by itself. The team decides what the project
takes, and only a regeneration or an edit changes its context files.

![A project adopts a release. The team asks the coding agent to assess the release. The agent reads the changelog between the pin and the tag and returns the candidates, with what each addresses. The team names the ones to adopt, and the agent moves the pin to the tag, then regenerates or adopts each rule by hand, and returns the change for review](../diagrams/runtime-adopt.png)
![Release adoption. The team asks the coding agent to assess the release. The agent reads the changelog between the pin and the tag and returns the candidates, with what each addresses. The team names the ones to adopt, and the agent moves the pin to the tag, then regenerates or adopts each rule by hand, and returns the change for review](../diagrams/runtime-adopt.png)

| Step | What happens | Source |
|------|--------------|--------|
Expand Down
60 changes: 60 additions & 0 deletions docs/architecture/07-deployment-view.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 7. Deployment view

How the rules reach a project and where they run. Nothing of upstream runs
as a service. The templates travel as files at a released tag, the coding
agent reads them on a developer's machine, and pre-commit runs the shipped
hooks on that machine and again in the project's CI. A project chooses
the source it takes the rules from, how it holds them, and who moves its
pin.

The diagram is a UML deployment diagram. A 3D box is a node, such
as a repository, a machine or an execution environment. An element drawn
inside a node is deployed on it. A line is a communication path, and its
arrow points from the side that opens it.

## 7.1 Deployment overview

![Deployment overview. Upstream, solid-ai-templates, holds the templates and tools and the shipped hooks. A fork, such as imbra-ai-templates, fetches and merges upstream, and adds its stacks and platforms and, optionally, an updater. The project repository pins the templates to a release tag, by submodule, clone or copy, from upstream or from a fork, and holds AGENTS.md and CLAUDE.md, the task skills under .agents/skills, and the pre-commit configuration. The updater opens a pull request with a pin bump to the project. The developer's machine runs the coding agent, which clones the project and commits to it, and pre-commit on each commit. The project's CI checks out the pushed commit and runs pre-commit on each push. Both pre-commit runs fetch the shipped hooks from upstream at the pinned revision](../diagrams/deployment-distribution.png)

| Node | What it holds | Source |
|------|---------------|--------|
| Upstream | The templates, the tools and the shipped hooks, released as tags | FR-09-01 |
| A fork | Upstream's history, merged, with its own stacks, platforms and process | FR-08-01, ADR-050 |
| Project | The pinned templates, its context files, its task skills and its pre-commit configuration | FR-08-04, FR-05-04 |
| Developer's machine | The coding agent, which generates the context files from the project's copy of the templates, and pre-commit, which git's hook runs on each commit for early feedback | FR-05-01, ADR-055 |
| Project's CI | pre-commit, on each push, the gate every change passes, since a local hook is optional and can be skipped. Both runs fetch the shipped hooks at the revision the project pinned | FR-07-02, ADR-055 |

## 7.2 Distribution sources

| Source | What a project gets | Fits | Source |
|--------|---------------------|------|--------|
| Upstream | The core tier, the opt-in base templates and the layers, each of them a root; no stack | A project that wants the shared rules only | ADR-050 |
| A fork, such as imbra-ai-templates | Upstream unchanged, plus the fork's stacks, platforms, process and interview | A team with stacks of its own. A project on upstream moves to it without regenerating its context files, if it pins a fork tag that contains its upstream tag. An older fork tag can lack files or sections its context files name | ADR-049, ADR-050, FR-08-02, FR-09-01 |

## 7.3 Integration models

A project holds the templates by submodule, clone or copy, and its coding
agent generates the context files from them. A project whose context file
copies in every rule may keep that file alone, without the templates. A
project may also opt out of the templates and take only the shipped
checks, with hooks only.

| Model | Brings | The pin | Update | Trade-off | Source |
|-------|--------|---------|--------|-----------|--------|
| Submodule | The templates | A released tag, in the project's history | Move the submodule to a newer tag | Each commit records the rules that governed it | FR-08-04 |
| Clone | The templates | A released tag, outside the project's history | Check out a newer tag | Simple, but no commit records which rules governed it | FR-08-04 |
| Copy | The templates | A released tag, in the project's history as files | Replace the copy with a newer tag's files | No submodule to initialise, but a local edit to the copy is lost on update | - |
| Generated files only | The inline context files, generated once from the templates at a released tag | None in the repository; the tag is the one the files were generated from | Regenerate from a newer tag | Nothing to hold but the context files. A hybrid file cannot do this, since its references point into the templates | FR-05-04, ADR-052 |
| Hooks only | The shipped checks, run by pre-commit | A released tag, as `rev:` in `.pre-commit-config.yaml` | Move `rev:` to a newer tag | The checks, without the rules | ADR-055 |

## 7.4 Version updates

The team moves the pin, by hand, when a release holds a rule it wants
(chapter 6.5). A fork may add an updater, a bot that watches releases and
proposes the move to its projects. Any updater follows these rules.

| Rule | Source |
|------|--------|
| It moves the pin to a released tag, never a branch | FR-08-04 |
| It proposes the move as a pull request, listing the changelog entries between the two tags as candidates | FR-09-03 |
| It never rewrites a context file. Moving the pin changes nothing, and adopting a rule stays the team's decision | FR-09-03 |
2 changes: 1 addition & 1 deletion docs/diagrams/delivery-model.drawio
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="t1" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontFamily=Segoe UI;fontSize=26;fontColor=#0F172A;fontStyle=1;" value="How a generated file delivers a rule" vertex="1"><mxGeometry x="30" y="18" width="1380" height="36" as="geometry" /></mxCell>
<mxCell id="t1" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontFamily=Segoe UI;fontSize=26;fontColor=#0F172A;fontStyle=1;" value="Delivery model" vertex="1"><mxGeometry x="30" y="18" width="1380" height="36" as="geometry" /></mxCell>
<mxCell id="t2" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontFamily=Segoe UI;fontSize=13;fontColor=#64748B;" value="A rule must be inlined only when its breaking is silent and no tool enforces it; pure reference is no longer generated." vertex="1"><mxGeometry x="30" y="54" width="1380" height="24" as="geometry" /></mxCell>
<mxCell id="g1" parent="1" style="rounded=1;arcSize=2;whiteSpace=wrap;html=1;fillColor=#F8FAFC;strokeColor=#CBD5E1;strokeWidth=1.5;align=left;verticalAlign=top;spacingLeft=16;spacingTop=10;fontFamily=Segoe UI;fontSize=14;fontColor=#334155;fontStyle=1;" value="Placing one rule" vertex="1"><mxGeometry x="30" y="100" width="1380" height="230" as="geometry" /></mxCell>
<mxCell id="q" parent="1" style="rounded=1;arcSize=8;whiteSpace=wrap;html=1;fillColor=#F1F5F9;gradientColor=#FFFFFF;gradientDirection=north;strokeColor=#475569;strokeWidth=1.6;shadow=1;align=center;fontFamily=Segoe UI;fontColor=#0F172A;spacing=6;" value="&lt;b style=&#x27;font-size:14px;color:#0F172A&#x27;&gt;One rule&lt;/b&gt;&lt;br&gt;&lt;span style=&#x27;font-size:11px;color:#475569&#x27;&gt;from the template chain&lt;/span&gt;" vertex="1"><mxGeometry x="60" y="175" width="220" height="80" as="geometry" /></mxCell>
Expand Down
Binary file modified docs/diagrams/delivery-model.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading