Stage 03b · Information architecture, detail layer
Structure
The launcher for every node of the product. Each chip is one node of the map: what it contains, which states it has to survive, who may open it and what its address is. Chips with a solid border have their page written; dashed ones are on the map and not yet specified.
- Nodes on the map
- 45 forty in the MVP
- Specified so far
- 0 of 45
- Source of truth
ia/docs/sitemap.md- Block bank
- 7 of 7 types done
The map is complete before the pages are. Every node is registered here from the moment it exists on the map, so a dashed chip is a declared piece of work rather than a hole someone forgot. The tree that produced these chips is on Sitemap; the routes through them are on Flows.
01 · Nodes
Global elements first, because every page inherits them
02 · Block bank, by page type
Where the composition of a page comes from, so it is not taken from the air
Every other artefact in this pipeline has a rule of origin. The composition of a page did not: a template that says "blocks: 1, 2, 3" and does not say where they came from returns the median of everything the model has seen, and that median only becomes visible at stage 04, when the structure is already rolled out. So the source is fixed here, per page type rather than per node. Full bank in ia/docs/blocks.md.
| Type | Nodes | MVP | Round one |
|---|---|---|---|
| A. List in a split pane | 3.1–3.4, 5.1–5.3, 5.6 | 8 | done |
| B. Record detail with an AI narrative | 4.1–4.3, 4.5, 4.7–4.10, 5.4, 5.5 | 10 | done |
| C. Shift digest | 2.1–2.5 | 5 | done |
| D. Fleet and filters | 3.5, 3.6 | 2 | done |
| E. Dialog | 1.2, 4.4, 4.6, 7.3 | 3 | done |
| F. Sign in | 1.1 | 1 | done |
| G. Systemic state | 8.1–8.3 | 2 | done |
| H. Grant grid | 7.1, 7.2 | 0 | no, all LATER |
| I. Client summary composer | 6.1, 6.2 | 0 | no, all LATER |
At the gate I said no competitor publishes a page of this type outside a login, so the domain half of the bank would have to be our own research. That was wrong in a useful way: vendor documentation publishes screenshots of the real product, and those are public pages of exactly the right type. PagerDuty documents its Operations Console and Microsoft documents the Defender incident queue, both with the split pane visible. The domain half of this bank is real, not a substitute.
Type A, what the four sources gave
| Block | Source | Verdict | Why |
|---|---|---|---|
| AI assessment as named factors with counts, each expandable | Defender | TAKE | The best thing on the reference. Cheapest correct thing first, depth one key away, every factor carries a count |
| Inline source chip attached to the claim | Rox, Intercom | TAKE | Citation at the claim rather than a bibliography at the end. What makes a narrative checkable in seconds |
| Prev and next in the panel header | Defender | TAKE | The mouse equivalent of the keyboard grid model already in 0.1 |
| Panel width draggable and remembered | PagerDuty | TAKE | Not an improvement on them, a correction to us: it closes an open question 0.1 was carrying to stage 04 |
Summary cards, 71% last 30 days | Defender | DIFFERENT | A window with no absolute count, which design principle 2 forbids in its own words |
Row with a bare priority score 100 and a truncating generated name | Defender | DIFFERENT | The widest column carries the least decidable content. Our row carries what Clerk concluded and what checking it costs |
Thought for 20s above the AI output | Rox | DIFFERENT | Effort is right, time alone is thin. Ours names sources, how many, over what window |
The panel ends in Open incident page | Defender | LEAVE, and it is the differentiator | Their panel previews, ours decides. The list has to survive the decision |
| Chat composer at the foot of the panel | Rox | LEAVE | The most tempting block on the reference. The foot of our panel belongs to the verdict |
| Bulk actions on checked rows | PagerDuty | LEAVE | Bulk accept is the fastest way to destroy the audit trail this product exists to produce |
| Saved views, column builder, density toggle | Defender, PagerDuty | LEAVE | No job, and configurability is what ships when a product cannot decide what the row should say |
Three of our advantages are the same advantage: the references show numbers without their claim, their scope, their window or their count. 71%, 100, Thought for 20s. Each is legible and none is checkable. That is one differentiator, and calling it three would be inflating the count. The one structural difference is the panel: theirs previews and ours decides, and no bulk actions, no chat composer and verdict controls at the foot all follow from it.
Six blocks that all four references ship and we do not: summary cards, saved views, a column builder, a density toggle, bulk actions, a chat composer. Each with a reason in blocks.md. A composition that matched one source one to one would be a copy, and this one matches none.
Type B, what the five sources gave
The type the product exists for. 4.1 is where the analyst rules on Clerk, and it is the second screen that goes to full colour. Four sources opened live: Defender's Copilot incident summary and guided response, PagerDuty Incidents for the timeline and for redaction, and Parallel Deep Research from Refero for the craft half.
| Block | Source | Verdict | Why |
|---|---|---|---|
| Permission limited actions shown greyed out with their reason, not hidden | Defender | TAKE, the find of the type | The answer to a question 0.3 has carried since it was written. A hidden control teaches nothing; a disabled one teaches the ceiling. This is per tenant autonomy made legible on the case |
| Banner when the machine already acted, naming the action | Defender | TAKE | Our rule "a case that left the analyst's hands must not look identical to one that did not", shipped by someone else. Ours adds the class from 0.6 and whether it can be undone |
| Chip on the sentence opening source, schema field and reasoning | Parallel | TAKE | Deeper than the inline chip taken in type A: it explains what kind of claim it is, not only where it came from |
| Redaction leaves who redacted and when, and cannot be undone | PagerDuty | TAKE | The tombstone pattern. 4.7 and 5.5 are the same shape: the evidence is gone, the record of it being gone is not |
| Timeline rows as sentences naming actor and channel, machine actions in the same stream | PagerDuty | TAKE | The channel answers "considered decision or thumb on a phone at 03:00", which is exactly 4.10. One log, both actors, so the two histories cannot disagree |
Narrative as prose lead then dated bullets, entities linked inline; Last updated stamped on the summary | Defender | TAKE | For them a courtesy, for us load bearing: 5.4 addresses a snapshot by time, so a narrative with no time cannot be addressed |
AI-generated content may be incorrect on every card | Defender | DIFFERENT | The same sentence whether Clerk is on firm ground or guessing, so it carries no information. Ours puts uncertainty on the claim, and 4.8 is a state rather than a footer |
| Thumbs up and thumbs down under each card | Defender | DIFFERENT | A thumb cannot tune a detection. Ours is the structured rejection reason from 0.7, on the same keystroke as the override |
Basis 69 chip with a bare number | Parallel | DIFFERENT | Reading the page you cannot tell whether 69 is a citation index or a score, and that ambiguity is the finding |
Classification: Not set as an ordinary optional field | Defender | DIFFERENT | For them the ruling is metadata that defaults to unset. For us it is why the record exists, and unrecorded is a visible state, which is 4.10 |
| Summary cached for a week and expiring quietly | Defender | DIFFERENT | A published retention window, and the third time this layer has hit the retention question research.md still carries open |
Regenerate the summary | Defender | LEAVE, the most consequential here | Regenerating a verdict before ruling on it means the thing accepted is not the thing filed, and the log cannot say which. If Clerk is wrong the path is 4.4, which teaches |
| The incident graph as the default tab | Defender | LEAVE | The largest object on the screen, and it does not answer "does the verdict hold". Also the most portfolio friendly thing in this bank, which is why leaving it out has to be a decision |
See prompts, Open in Security Copilot, task pane, cost per severity | Defender | LEAVE | Three of these are one instinct: keep talking to the agent instead of ruling on it |
One block was worth the whole type: the greyed out action with its reason. Defender uses it for role based access; we use it for latitude. The analyst sees, on this case, what Clerk could have done here and could not, which is the differentiator doing work on the screen rather than on a settings page.
Basis 69 joins 100, 71% and Thought for 20s. Four references, four numbers, none naming its claim. Type A called this one differentiator and type B does not make it two; it makes it better evidenced.
Seven blocks the references ship in 4.1 and we do not: the incident graph, suggested prompts, Regenerate, the task pane, Open in Security Copilot, thumbs up and down, and the blanket AI disclaimer. The ten block composition for 4.1 is in blocks.md and matches no single source.
Types C to G, one finding each
Five smaller types, closed in one pass. Sources opened live: Defender multitenant management, PagerDuty identity, Microsoft Entra sign in, a live PagerDuty 404, plus five Refero screens. Full tables in ia/docs/blocks.md.
| Type | The finding | What it changes |
|---|---|---|
| C Shift digest | No reference exists. Three Refero searches returned calendars and changelogs; PagerDuty's on call handoff article is gone from the live knowledge base (404, checked this session) | The bank is built by transfer from types A and B plus our own stage 01 handover research, and it is labelled as such. Nothing in type C may be claimed as better than the market, because we did not find the market |
| D Fleet | Microsoft ships cross tenant already: "a single, unified view of all the tenants you manage", "single pane of glass". But their tenant list lives at Configuration > Settings, described as a page to "view and manage your tenants" | Single pane of glass is not our claim and never presented as one. What survives is exactly what stage 02 narrowed to: their fleet is an administration surface, ours is the resting state of the working pane at zero taps, showing latitude and the accepted count rather than device inventory. This page is the strongest evidence we have for the differentiator |
| E Dialog | YouTube Music's report dialog ends in Cancel and Next, because picking a reason is step 3 of 6 | Design principle 3 says override is one key and it teaches. Rejecting Clerk must cost less than accepting it, not more. Our reason dialog is the action, not a step towards it. Also left: OK as a confirm label, and every warning illustration |
| F Sign in | PagerDuty and Entra both do identifier first: one email field, no password, button reads Next. Neither reference has our problem | The block that is ours: the deep link survives authentication. An on call analyst opens a case from a pager at 03:00 and must land on that case, not on the queue. Left behind: consumer identity buttons and the signup link, since seats are provisioned by the provider |
| G Systemic | PagerDuty's 404 is a plain sentence with two named exits and no illustration. Defender answers permission at the control, greyed out with a reason | 8.3 is therefore rarely reached, and if it turns out unreachable that is a finding rather than a page. The block that is ours: 8.1 must render no such case and not your tenant identically, or the 404 enumerates other providers' clients. A security requirement written as a copy rule, and it goes to stage 05 |
Seven types, nineteen sources, all opened in session. Two entries are worth more than the takes. Type C has no reference at all and says so instead of inventing one. Type D found our differentiator half shipped by Microsoft and narrowed the claim to the half that survives, which is where it lives in the product rather than whether it exists. A bank that only ever confirmed us would not have been worth building.
03 · How to read a chip
Three things carried by every node
| Carried | Why it is on the chip |
|---|---|
| Number | Cluster and position. The number is the address used by every later stage, so a node renamed without renumbering breaks references rather than labels |
| Type | Page, section, state, dialog, loading, empty, error. Twenty five of the forty six are not pages, which is the entire reason this layer exists |
| Border | Solid means the node has a written specification. Dashed means it is on the map and the work is declared. Grey background means LATER |
It is not the sidebar. The roadmap on the left tracks stages of the pipeline; this tracks nodes of the product. Forty six nodes and twelve pipeline stages are two different registries, and this hub owns neither panel: the stage panel on the left is rendered from ia/_nav.js, the same record these chips come from.
04 · Settled before stage 04
Seventy seven open questions across twenty three nodes, every one given a verdict rather than carried forward as a list
Twenty three node specifications ended with open questions, and nobody had ever counted them together. Seventy seven. Read as one set rather than one node at a time, most of them were not open at all: the answer already followed from something the product had decided, and nobody had written it down.
| Verdict | Count | What it means |
|---|---|---|
| Settled | 52 | The answer follows from a decision the product already made, so it is taken here and written into the node that owns it |
| Stage 04 draws it | 7 | Genuinely undecidable in prose. Drawing is the instrument, and arguing would be pretending |
| Still open | 18 | Needs a person we do not have, or a business decision that is not ours. Each one says who can answer and what it blocks |
Four decisions that closed more than one question each
| Decision | Closed | Why it is the answer |
|---|---|---|
| Harrier reads the rota, it does not own it | 4.6 and 2.1 | Providers already run on call tooling, and a second rota is a second truth. When the rota is unreachable the recipient is 8.2’s declared fallback contact, a value both nodes already shared |
| An escalation is delivered out of band, and Harrier records that it was sent | 4.6, and it unblocks the [?] on P2 | Harrier is not the delivery mechanism, so whether the secondary persona uses the console stops blocking a mechanism. If they do, 4.2’s permalink is what they open |
| Clerk down is 0.4’s fourth state, not a new node | 8.2, and it disarms 2.3 | It is a freshness condition, which is what the strip is for. The distinction it draws is the useful part: under a lost connection an empty queue is ambiguous; with Clerk stopped, the queue is complete and she can work through it |
| Retention is two windows, and the entry says how long its own snapshot lasts | 0.6, 5.4, 5.1, and 4.7 keeps its reason | The number is a contract term and stays [?]. What removes the blocker is the rule rather than the figure: the analyst learns the window from the entry, never from a failure |
Three answers that changed a drawing rather than a paragraph
| Question | Answer | What it changed |
|---|---|---|
| What does a fleet row do on click, when 7.1 is LATER? | It narrows the queue to that tenant | The most likely dead end in the product becomes an entry. A record that moved down is one click from the cases behind it, and 3.6 already owns the mechanism |
| Does a second analyst picking up a case change the row for the first? | Yes, and it must | 0.8’s chip set gained a sixth value, taken, and a fourth pair. A collision is recorded by 5.1’s superseded machinery rather than prevented by a lock |
| Is the queue a grid or a list? | A grid, one tab stop | The row is columnar and she reads across it, so cells must be addressable. A list would turn the state chip and the cost into run-on text |
Per node
| Node | Questions | Settled | Drawn | Open | What stays open |
|---|---|---|---|---|---|
| 0.1 | 3 | 3 | 0 | 0 | none |
| 0.2 | 3 | 3 | 0 | 0 | none |
| 0.3 | 3 | 2 | 0 | 1 | Is 30 days the right window |
| 0.4 | 3 | 2 | 0 | 1 | Is the transport actually server-sent events |
| 0.5 | 3 | 2 | 0 | 1 | Where does the disable setting live once a settings surface exists |
| 0.6 | 3 | 2 | 0 | 1 | Who owns the taxonomy, the provider or the product |
| 0.7 | 3 | 0 | 0 | 3 | Does the analyst ever learn what happened to the reason; Who maintains the list; Is `Real, called benign` even reachable |
| 0.8 | 4 | 0 | 2 | 2 | How does a source tool's severity map onto three levels; Who owns these conventions after the MVP |
| 1.1 | 4 | 4 | 0 | 0 | none |
| 2.1 | 4 | 4 | 0 | 0 | none |
| 3.1 | 4 | 3 | 1 | 0 | none |
| 3.5 | 4 | 2 | 1 | 1 | Does the ordering in section 6 match what an analyst asks at shift start |
| 3.6 | 4 | 2 | 0 | 2 | Does persistent scope surprise people; Is sort as a chip discoverable |
| 4.1 | 4 | 2 | 2 | 0 | none |
| 4.2 | 3 | 3 | 0 | 0 | none |
| 4.4 | 4 | 1 | 1 | 2 | Is `Real, called benign` reachable often enough to matter; Does the consequence line get read |
| 4.6 | 3 | 3 | 0 | 0 | none |
| 5.1 | 4 | 3 | 0 | 1 | Is the resting pane in section 5 read, or is it furniture |
| 5.4 | 3 | 3 | 0 | 0 | none |
| 8.1 | 2 | 2 | 0 | 0 | none |
| 8.2 | 3 | 1 | 0 | 2 | Is the fallback contact the right thing to show unauthenticated; Does planned maintenance ever happen during a shift |
| 8.3 | 3 | 2 | 0 | 1 | Does block 3 grow a request path |
| 8.4 | 3 | 3 | 0 | 0 | none |
They fall into three piles and none of them is a gap in the design. Four point at one hole: 0.6, 0.7, 0.8 and 0.5 all end on the missing settings surface, and four nodes naming one absence is a stronger statement than any of them alone. Six need a person in front of the screen, which is the honest answer for whether a line gets read. The rest belong to somebody else: a contract term, an ingestion mapping, an engineer’s choice of transport.
And one of them got worse rather than better. 0.7 asks whether the analyst ever learns what happened to a rejection reason. Step 9 counted that R3 is carried by two nodes out of forty six and neither closes the loop. A rejection that never visibly changes anything stops being filled in honestly, so the thinnest job in the product is the one design principle 3 depends on.
05 · Audit before wireframes, before and after
Four instruments, run independently, deduplicated after
| Instrument | Radius | Raised | Held |
|---|---|---|---|
Codex, --sandbox read-only | The source: contradictions between files, unresolved references, scope drift, registry mismatch, facts without a citation | 9 | 3 |
| Claude with a browser | The output: real 360 on every page, live link resolution, backlink hashes, em dash, class collisions with the shared sheet | 4 | 3 |
| The stage contract as a checklist | Steps that never happened, which neither of the other two can see | 3 | 3 |
| A reader with clean context, given stage 04's real task | Whether the specification is sufficient to draw from. Not defects: insufficiencies | 44 | 4 contradictions, 11 missing rules, and one new node |
What was fixed
| # | Who found it | Was | Is |
|---|---|---|---|
| 1 | Claude | Three files routed an out of scope tenant to 8.3. sitemap.md, 0.1's state matrix and 0.3's scope note. 0.1 argued for it explicitly: "an empty result is indistinguishable from a quiet client" | All three render 8.1. If out of scope rendered differently from not found, the address bar would distinguish "this client is somebody's" from "no such client", a disclosure across providers. Five nodes already required this and three contradicted it |
| 2 | Claude, corroborated by Codex | 8.3 marked MVP with no reachable route | LATER. Fixing finding 1 removed its last three routes, all of which were themselves defects. Counts updated: 39 MVP, six LATER, and 0.8 later took it to forty |
| 3 | Codex | sitemap.md listed the toast stack as "Filed, escalated, connection recovered". 8.4 rules No for filed and No for escalated | The map row now says what 8.4 says: only what happened off screen. The map was not corrected upward when 8.4 refined the policy |
| 4 | Codex | Node 3.5 carried three different names across the registry, its h1 and its md | One name. The registry was the odd one out |
| 5 | Claude, browser | case-queue.html defined a local .q, colliding with the reserved [?] marker in research/_page.css, which injected white-space:nowrap into the whole wireframe | Renamed. This was the real cause of a column collision fixed earlier by widening the frame, so the fix was right and the diagnosis was wrong |
| 6 | Claude, browser | Two pages overflowed at a real 360: 1.1 and 4.2. Both from a flex column sizing to max-content | Fixed. The 4.2 check had never been run, which is worse than a check that failed |
| 7 | The stage contract, reread | Every IA page rendered the pipeline roadmap, not a stage panel. Moving from one node to another meant going back to the hub for a chip, and two registries were loaded on the hub at once | The panel is rebuilt. ia/_nav.js now does both jobs from one record: it renders the stage panel on all 26 IA pages, grouped Base layer, Detail layer, then cluster by cluster with every X.Y, and the chips on the hub. Node to node is one click. The root registry is not loaded on IA pages at all, and the first panel item is the way back out |
Raised and dismissed, with the reason
| Who | Claim | Why it does not hold |
|---|---|---|
| Codex | Registry mismatch on 0.3, 0.4, 4.1, 4.2, 5.4: the registry label differs from NAV_ACTIVE_LABEL | Two fields, two jobs at the time it was raised. Overtaken by the panel rebuild below: NAV_ACTIVE_LABEL no longer exists on any IA page, so there is one name per node and nothing left to diverge |
| Claude | reject.md references node 4.11, which does not exist | Rhetorical: "it is a dialog rather than node 4.11". The sentence exists to say the node was never created |
Held open, and why
| Who | Finding | Why it is not fixed here |
|---|---|---|
| Codex | CLAUDE.md says global navigation has four items. 0.2 found three in the MVP | Real, and known since 0.2. CLAUDE.md is a rules file with its own owner: the closing ritual at Step 9, which is also where the reserved class rule lands |
| Contract | Two accepted deviations from the pack: node pages were registered from Step 1 rather than incrementally, and types C to G of the block bank were closed in one pass | Both were shown and agreed at the time. Recorded so the deviation is visible rather than invisible |
Second pass, on the nodes the fixes touched
Both instruments again, on the six fixes only. Three came back incomplete, and all three were a fix that moved a neighbour.
| Fix | Verdict | What the second pass found |
|---|---|---|
| 1, out of scope renders 8.1 | complete | Every remaining mention of 8.3 describes the corrected past state |
| 2, 8.3 becomes LATER | incomplete | blocks.md still called the systemic type "three nodes, all MVP" and still described 8.3 as reachable by a deep link into another tenant, which is the route the audit had just deleted. sitemap.html still said "Forty MVP nodes". 8.3's own section 03 still spoke in the present tense. All three corrected |
| 3, the toast row | incomplete | The best find of the second pass. The map row was fixed, but 4.4 and 4.6 both still referenced "the toast that follows". Under 8.4 neither produces one: a filed verdict has none because the row changes to decided in place, and an escalation has none because the row stays and changes state visibly. Both nodes now say so and say why |
| 4, 3.5's name | complete | Registry, h1 and md agree |
| 5, the class collision | complete | No local .q, .note, .node or .lede anywhere under ia/ |
| 6, the 360 overflows | complete | No flex:0 0 auto anywhere; the 22 page sweep is clean |
Three of six fixes were incomplete, and none of the three was incomplete in the file that was edited. Every one had moved a neighbour instead: a bank entry describing a route that no longer exists, a count in a sibling page, and two dialogs promising a notification a third node had already ruled out. A single pass would have shipped all three.
Third instrument: the stage contract, read as a checklist
Neither of the other two can see a step that never happened, because a step that never happened is in no file. This is that pass, kept separate from the defect table above on purpose.
| Contract line | Answer | Evidence, or the reason |
|---|---|---|
| Full node map with type, group, scope, includes, transitions | done | sitemap.md, nine clusters, 46 nodes |
| Sitemap tree and Structure hub, both synchronised | done | Ten Mermaid blocks, 45 chips from one registry |
| Estimate shown and the round agreed before rollout | done | The Step 4 gate, option B |
| Every node in the agreed round has md, html, desktop and 360 | done | 22 of 22, and the 360 sweep is above |
| Deferred nodes collected as a list, not forgotten | was not done | Found by this pass. Scope labels existed; a list of what round one did not build did not. Added to sitemap.md: 23 deferred nodes, each with the parent matrix that already specifies it |
| Structural nodes carry a state matrix, anatomy, transitions, a11y | done | 0.1 to 0.7. Footer consciously skipped: an authenticated console has none, and nothing in the map promised one |
| A to E block on every indexed page | consciously skipped | Nothing is indexed. 1.1 is the only public URL and closes the question explicitly with a no |
| Cookie handled by law | was not done | Found by this pass. GDPR is in the compliance line and no node mentioned cookies. Now a section on 1.1: one strictly necessary session cookie, no banner, and the two conditions that would change that |
| Systemic nodes present and none a dead end | done | 8.1, 8.2, 8.3, 8.4. Each has a named exit |
| Canonical components defined once and propagated | done | The row at 3.1, redefined explicitly at 5.1. The evidence block, provenance strip and verdict record at 4.1, referenced by 4.2 and 5.4 |
Real structure grounded in sources, uncertain left as [?] | done | Nineteen sources opened in session. The retention window and the session length are still [?] and named in four nodes |
| Block bank real, both halves, missing half named out loud | done | Seven types. Type C says plainly that no page of that type could be opened |
| Every node's composition comes from the bank | done | Every block row on every node names its origin |
| Audit before wireframes, with the result visible on the page | done | This section |
| Every node registered once and rendered from that entry | done | 45 of 45 registered in ia/_nav.js, and that one record now renders both the panel item and the chip. The Step 1 deviation, two registries on IA pages, is closed by the panel rebuild below |
concept-map.html does not freeze | partly, and it was stale | Found by this pass. The expansion line was there and said "forty three nodes". Corrected to forty five, thirty nine MVP, twenty two written, and again to forty six when 0.8 arrived from the reader. The matrix and the navigation model on that page are rebuilt at Step 9, which is where the contract puts them |
| Closing ritual | not done | Step 9. Two items are already queued for it: the four item navigation line in CLAUDE.md, and the reserved class rule |
Three lines came back "was not done", and none of them was visible to the other two instruments. A deferred list that does not exist leaves no trace in any file; a cookie decision nobody made leaves no trace either; a stale count on a page from the previous stage is not a contradiction, because nothing else asserts the number. All three were omissions rather than errors, which is exactly the class a checklist finds and a reader does not.
Fourth instrument: a reader with clean context, given the next stage's real task
Not "find defects". A subagent that had never seen this conversation was told to prepare to wireframe 0.1, 3.1 and 4.1, and to return two lists: what it understood, and what it could not work out. It was allowed the repository, CLAUDE.md and AGENTS.md, and explicitly denied this chat and the audit section above.
Codex reads statements and compares them. The browser reads what rendered. The contract looks for steps that never happened. The reader tries to use the artefact, and breaks where the specification looks complete. It returned 44 items it could not determine, and roughly twenty of those were correctly recorded open questions, which is the system working. The rest were not.
| # | Was | Is |
|---|---|---|
| 8 | Three vocabularies for one value. 0.3 said Read-only / Dry-run / Guided / Autopilot, 3.5 listed action classes, 4.1 said Acts alone / Asks first / Never. 0.6 forbids exactly this in its own words: "one vocabulary, five places". Worse, it made the hard constraint in 3.5 undrawable: reading B counted levels while the fleet listed classes, so the two could not be compared even in principle | Two axes that compose. The class from 0.6, and one of three levels: Acts alone, Asks first, Never. Simbian's four go back to being a quotation. Every surface now says acts alone up to a class, and the constraint is something a person can check on screen |
| 9 | The frame after a verdict is filed did not exist. 3.1 promised the selection is held "including after a verdict is filed"; 8.4 said "the row leaves the queue, that is the feedback". Both cannot be drawn, and neither said what the pane does. The single most important moment in the product | Specified at 3.1 section 02b. The row stays in place and changes to decided; it leaves only when the selection moves off it; the pane holds the case and states the outcome and does not advance on its own. Still no toast, and now for a better reason |
| 10 | Two models of one interaction. 3.1: arrows move and "the pane follows". 0.1: "Enter opens the selected row into Z5" | They divide the work. Arrows read, Enter decides: the pane follows the selection, and Enter moves focus into it, which is exactly what makes the verdict keys live under SC 2.1.4 |
| 11 | 0.1's wireframe had never been corrected upward. Its prose had, three times. The drawing still showed four navigation items where 0.2 settled three, verdict controls in the pane header where 4.1 puts them in the foot, no Z2 at 360 where 0.4 requires it in the same place, and a superseded latitude level | All four redrawn. The rule this produced: a container node is redrawn whenever a node inside it settles something, prose and drawing together. Prose alone is how a frame goes stale while reading as current |
The eleven missing rules, and the node they turned into
Alongside the four contradictions, the reader named eleven things it needed and could not find. Five of them were the same kind of thing, so they became a node: 0.8 Reading conventions, sibling to 0.6 and 0.7 and arriving the same way, discover-as-you-go. The other six belonged to a node that already existed and had not written them down.
| What was missing | Where it went | The decision |
|---|---|---|
| The severity scale | 0.8 | Three levels, glyph plus word. A fourth would be a distinction she reads and then resolves the same way |
Time grammar, 27m against 04:12:38 | 0.8 | Two grammars because there are two questions. She decides on elapsed, she defends on absolute, and the log is UTC because one analyst covers two continents |
The unit of effort | 0.8 | Two numbers were wearing one word. signals is what checking costs her, sources is what Clerk spent, and the row’s signal count is bound to the line count of the pane’s evidence block |
| Whether a row can carry two state chips | 0.8 | At most two, highest first, and only three pairs can occur. That is a claim about the taxonomy rather than a truncation rule, and stage 04 can falsify it |
| Canonical fixtures, and whether mockup numbers are approved | 0.8 | Counted first: twelve tenant names across fourteen mockups, five of them second names for a client already in the set. Now seven tenants and one canonical case, plus one paragraph binding every later stage: numbers in a wireframe are fixtures, not findings |
| Default queue ordering | 3.1, section 02c | unrecorded, then blocked on her, then severity, then age. Rank 2 comes from 0.6 and no reference in the bank orders a queue that way |
| Where an escalated or unrecorded case sits afterwards | 3.1, section 02c | The queue is a narrowing like any other. escalated leaves it and is one chip away; unrecorded does not leave until the write lands, because the console is the only place that decision exists |
| A matrix column for 4.5 amend | 4.1 | Added, seven columns. And amend carries no reason code: the amended text is the reason, and a code would ask her to classify her own writing |
| What the evidence chip opens | 4.1, section 04b | Principle 5 had already forbidden three of the four options. It expands in place, more than one at a time, because comparing two claims is the job |
| New evidence during a connection gap | 4.1, section 04c | 0.4 named 4.1 as the owner and 4.1 had never picked it up. It lands marked, never silently, and filing writes the snapshot she actually saw, which is the compliance requirement rather than a compromise |
| Where the responsible chip is named on an empty result | 3.6, already | Dismissed at verification. 3.6 section 4 specified it in full. What was missing was the cross reference from 3.1, and that is what was added |
Fixing the drift meant measuring it, and the measurement found more than the reader had. Twelve tenant names, not the nine visible at a glance. A selected row in 3.1’s wireframe while the caption said nothing was selected and the pane held the fleet. 1h 03m, two units and a leading zero, in both renderings. as of 6m ago, which says the same thing twice. One claim in the canon did not survive its own verification and is kept as a line rather than deleted: two ISO timestamps that looked like one entry under two dates are two different records.
Every one of these four had been read past by Codex, by the browser and by the contract checklist. They are not contradictions between statements, they are insufficiencies: each file is internally consistent and the set does not add up to something a person can draw. Only a reader trying to do the next stage's work finds that, and the rule is right that a run returning nothing was run formally.
The overlap was one finding out of thirteen. Codex reads the source and found a map row never corrected upward and a name carried three ways. The browser reads the output and found a stylesheet collision and two real overflows. Neither could have found the other's list, and the biggest finding, three files routing an out of scope tenant to the wrong page, came from reading what the nodes require of each other rather than from either instrument's radius.
The contract checklist, run once more at the close
The third instrument reads the stage’s own "Готово, коли" as a checklist, because a step that never happened is in no file. Run against the closed stage:
| Line of the contract | Verdict | Evidence |
|---|---|---|
| Node map complete, every node carries scope | done | 46 parsed from sitemap.md and matched field by field against the registry. 40 MVP, 6 LATER, zero in one and not the other |
| Both estimates shown and agreed | done | Page types at step 4, clusters at step 6, each with a gate |
| Every node in the agreed scope has md, html and a chip | done | 23 of 46, tallied by the hub itself. 23 links, zero broken |
| Deferred collected as a list rather than forgotten | done | 23 nodes, each with the parent matrix that specifies it |
| Structural nodes carry a state matrix | done, and one deliberate absence | Found by this pass: 0.8 had none and did not say why. It renders nowhere, so section 06b now states that rather than leaving the gap to be re-found |
Indexed pages carry A to E, private ones are noindex | done, and it was stated in the wrong place | Found by this pass: seven nodes spelled out noindex and sixteen did not, which read as though the seven were special. It is a property of the product, so sitemap.md now settles it once for all forty six, and 1.1 keeps its own answer because it is the only public URL |
| Systemic nodes exist and none is a dead end | done | 8.1 routes back, 8.2 carries retry and the provider’s fallback contact, 8.3 is LATER with no reachable route in the MVP and says so |
| Canonical components defined once | done | The row at 3.1, three components at 4.1, three canonical lists at 0.6, 0.7 and 0.8 |
| The block bank works as a source and its faults are named | done | Nine page types, 19 pages opened in session, and type C carries the barrier instead of a comparison |
concept-map.html does not freeze | done at step 9 | Navigation and traceability both rebuilt from the tree. The base layer matrix stays as the honest reading at its own level, with the node level check beside it |
| Closing ritual | done | Four deletions, four corrections, four rules added. CLAUDE.md 107 to 108 lines against a 200 ceiling |
A checklist that never returns "not done" is being performed rather than run. This one returned two, and both are the same shape: a decision that had been taken correctly and recorded in the wrong place, so the absence read as an omission. Neither was visible to Codex, to the browser or to the reader, because in every file that mentions them they are right.
Every one of the 22 built pages, loaded in a 360 wide frame and measured: clientWidth 360, scrollWidth 360, zero overflowing. Every local link on every page fetched: zero broken. Em dash: zero. Backlink present on all 22. One pass, and it should run again at stage 04.