System impact and risk routing
How a card gets a blast radius — LOW, MEDIUM, HIGH or CRITICAL, with the reasons — from the System Map, how a person overrides it, and how a station's routes can depend on the level so critical work takes a longer path through the factory.
CodeBook understands your system and uses that understanding to decide how work should move through the factory. This page is the two halves of that sentence: impact analysis, which reads the System Map and writes a level with its reasons on a card, and risk routing, which lets a station's routes depend on that level.
Both are rules the platform enforces. The level comes from written thresholds over counted rows, the route comes from the station's settings, and a model chooses neither.
Impact is computed only for workflows whose repository has a System Map. Risk routing changes nothing until a factory's policy switches it on; see implementation status.
What a change touches
Impact starts with the affected set: the nodes in the map a card is about, read only from the repositories attached to the card's workflow. Before any code exists it is found from the card's title and description, matched against the names, keys and paths of files, modules, services, endpoints, data entities, symbols, queues and outside systems. Once a pull request is linked to the card, the files it changed replace the guesses, and the impact is recomputed from what actually changed.
From the affected set the analysis walks the map and counts what it finds. The result is a list of reasons, each a count and a sentence, each pointing at the nodes behind it.
| Reason | What is counted |
|---|---|
| Dependents | Nodes that import, depend on or read the affected ones, transitively, up to three edges away along certain edges. Nodes reached only through a possible edge are a second row and do not count toward the level |
| Downstream services | Services (or modules with no service) that hold a dependent and none of the affected files |
| Endpoints | API endpoints handled by an affected file or symbol, or by a certain dependent |
| Data | Data entities the affected files contain or read; a second row counts the other services that read those same entities |
| Personal data | Those entities with a field flagged personal data (pii) |
| Outside systems | External systems and queues the affected files, or their services, use — naming any flagged payment or authentication |
| Tests | Test files that reach the affected files, and how many reach them directly — or that none does |
| Incidents | Production issues and reverts, not retracted, in the last 180 days on other cards whose pull requests touched the affected or dependent files; and production incidents a monitoring source reported in the last 180 days on the affected and dependent nodes, their modules and services, and the runtimes that run them — with how many are open and how many critical |
| No match | Nothing on the map matched: no repository is attached, its map is not built yet, the pull request's files are not on the map, or the card's words named nothing |
The levels
The level is read off the counts with thresholds written in the code, in this order; the first that applies wins.
| Level | Threshold |
|---|---|
| CRITICAL | An entity with personal data is touched; or a payment or authentication outside system is used; or there was an incident in the last 90 days and there are five or more dependents |
| HIGH | Ten or more dependents; or any outside system; or three or more endpoints |
| MEDIUM | Three or more dependents; or no test covers the path |
| LOW | Everything else |
| unknown | Nothing in the map matched. Shown as unknown, and treated as MEDIUM by routing and approval |
The thresholds are constants, not tuned weights. Two cards with the same counts get the same level. Ask your system uses the same thresholds when it is asked what a change to some nodes would touch.
When it is computed
- When a card is created into a station of a workflow with an attached repository — flagged at once, and computed on the scheduler's next tick, so creating a card never waits on the map.
- When a story arrives from OpenBook, or is updated.
- When a line is added to a work order's plan — by the planner or by a person — or edited, per line, so a person reviewing the plan sees each line's level before any card exists; and again when a line is turned into a card.
- When a pull request is linked to the card, by convention, by hand or by an agent, and each time its file list is synced.
- When the map moves to a new version. Impacts are marked stale, and open cards and proposed plan lines are recomputed a few per tick.
- On demand, with Recompute on the card.
Each computation emits an impact.computed event, so a system outside CodeBook can react to a critical card the moment it is scored. Setting or clearing an override emits impact.overridden.
On the card and the work order
A card's System impact panel sits beside its security scans. It shows the effective level — marked Stale when the map has moved on — the rule's level with when and why it was computed and the map version it read, the reasons with their counts, and the nodes by role: affected, dependents and downstream, tests, incidents and outside systems. Below them is the projected route: from the station the card is at, where each outcome — passes, fails, blocked — goes at the card's level, the handoffs an agent may choose, whether a person approves the next run, and which routes and branches declared for another level it will not take, and why. Then the override, if any, and Recompute for people who may change the card.
A work order's plan shows each line's level as a chip beside the planner's own risk — the level only; the reasons and the route are on the card once the line becomes one. The planner's risk stays what it always was, the planner's opinion; the computed level sits beside it and is the one routing reads.
Overriding the level
A person who may change the card can set its level, with a reason. The effective level is the override when there is one and the computed level otherwise, and the panel shows both, with when and why it was overridden. The override is carried onto every later computation until someone clears it. It needs a signed-in person with write access to the card; no agent, model or peer message can make one.
An override changes the level, not the person's freedom: a person can still hand the card to any station, as always. It changes which routes the platform takes when a worker's verdict moves the card, and whether a run needs approval.
Risk routing
A station's routes — when it passes, when it fails, when it is blocked, and the handoffs to other workflows an agent may choose — and the parallel branches a passing card fans out to can each carry a risk level. They are set in the station's settings, under Triggers: Route differently at one impact level for an outcome, a level per branch, and Offered to on each handoff.
- A route with a level replaces the unconditioned route for the same outcome or handoff, for a card at that level only.
- A branch with a level opens beside the unconditioned branches, for a card at that level only. A station may fan out at one level and keep its ordinary pass target for every other card.
- Routes and branches without a level are the default, and a station with none is exactly the station it was.
When a worker finishes, the platform picks the variant for the card's effective level. An unknown level, or a card whose impact was never computed, counts as MEDIUM. The verdict is the worker's; the route is the station's. The same rule narrows what an agent and the supervisor can choose: the handoffs offered to either are only those that apply at the card's level, so neither can send a LOW card down the CRITICAL path or the reverse.
Two policy settings, under Factory settings → Policies & budgets → Risk-adaptive routing:
- Route work by its impact level — turns level-conditioned routes and branches on for the factory. While it is off, every card takes the unconditioned path, whatever the stations declare.
- A person approves runs from this impact level up — a level at or above which a run waits for a person's approval before it starts, even where the autonomy setting would have let it start on its own; autonomy levels that already ask for more are unchanged. It applies on its own, with or without risk routing, and extends the approval rule that already exists rather than adding a new kind of station.
The levels on routes and branches and both settings are part of the factory's definition. They are carried by versions and rollback, blueprints, reviewed changes and environment promotion; a route that gains a level is a new version, and the comparison says so in a sentence. Test factory walks the happy path once more at each level a workflow's routes vary by, and warns when a station declares levels while risk routing is switched off.
The critical path, worked
The Idea to App Factory blueprint is the reference. Its policy turns risk routing on and asks a person to approve runs from critical up. In its build workflow:
- A story at any level below CRITICAL takes the default path: Design → Development → QA → Human review → Done.
- A CRITICAL story is declared like this. Design's pass route at level critical sends the story, and waits, to the Architecture station of a separate Architecture review workflow; when the architecture is written, the story resumes at Development. QA's branches at level critical fan the story out to Security review and Regression, joined at Review gate, which sends it on to Human review or back to Development. And because the policy approves from critical, a person approves each agent run on the story before it starts.
No station type was added. Architecture, Security review and Regression are ordinary stations with ordinary workers, the gate is the existing join gate, the crossing is an ordinary send and wait, and the approval is the existing approval. What the level adds is which of them a card visits.
What does not change
- Evaluators and contracts judge the work as before; the level does not lower a contract or skip an evaluator.
- Supervisors are asked when the rules run out, as before, and choose from a list the level has already narrowed.
- MadeBook governance of a governed run is untouched. A MadeBook decision may be a node in the map; it is not overruled by a level.
- Autonomy — at execute low-risk work, a card whose effective level is HIGH or CRITICAL is not low risk; the planner's opinion is read only when no level was computed. A bad outcome still steps autonomy down, and only a person raises it. See policies.
- Handoffs a person makes are never blocked by a level.
Limits
The level is as good as the map. A repository whose analysis is limited scores only what was indexed. A card whose words match no node is unknown, not LOW, and a card with no pull request yet is scored on its title and description, not the diff. A card on a workflow with no attached repository is not flagged when it is created. Incidents count only when production has been connected to report them — through inbound triggers or a monitoring source — and a production incident counts only once it is linked to the map; a system nobody connected has no incidents, and its cards will score lower than the truth. MadeBook policy violations are not counted as incidents. Dependents are counted along certain edges — a dependency through a dynamic import is shown as possible and does not raise the level — and any outside system on the path, including a database client, makes a card at least HIGH.