Episode 04Research and requirement

The stages that ran late

Seven weeks after this site went live, its research and requirement stages ran. The research found a limit that would soon break the published record. The record was already broken.

Published

Episode 02 said this site’s research and requirement stages never ran. That was true on 13 October. On 26 October, both ran.

What ran

The estate has a skill that moves a product through the stages before a build: brief, research, requirement, decision and spec. Each stage opens a pull request against a records repository and writes one line to an audit ledger. Two lines from 26 October belong to this site:

Time (UTC) Stage Record Tier Result
14:19 research where-the-published-record-comes-from 1 merged
16:34 requirement the-record-is-complete-and-names-its-source, status proposed 1 merged

Both were Tier 1, so the gate let the agent merge them without me. The forge records the agent as the account that opened and merged each one. The first deploy was on 8 September. The research ran 48 days later.

The question the research asked

The brief asks what the published record is derived from. The research compared three sources: the site’s pull request history, the audit ledger, and the delivery records in this repository. It recommended the pull request history, which the record page already reads. The ledger is a file on one machine, outside version control, so a build cannot read it. Its lines name no actor, and every pull request link in it points at a private address.

The research also listed a risk:

The page reads at most 100 closed pull requests. The repo is at #67. At the current rate the cap is reached within weeks, and the page then omits changes with no error.

The requirement turned that risk into something a test can check: “the record lists every merged change to the site repository, in merge order, and none is missing.”

The risk had already happened

On 29 October I checked the research against the forge.

The record page asked the forge for 100 pull requests. The forge returns at most 50 items in any list, whatever a request asks for. That limit is a forge setting, and the code did not read it. So each build received 50 closed pull requests and dropped the rest. On 29 October it received #18 to #67.

Source Merged changes Unprovable
The forge 66 10
The live record page 49 0

The page was missing changes #1 to #17. Those include the 10 from before the agent had its own identity, which the page exists to show as unprovable. Its heading still said “Every change that built this site”.

The research had the right risk and the wrong number. It read the limit in the request, not the limit in the response. The cap was not weeks away. It was passed on 12 October, when the 51st pull request closed. The next deploy was on 13 October, the day the series launched with episodes 01 to 03. Every build from that day was incomplete.

Why nothing objected

The record page fails closed. If the forge cannot be reached, the build fails rather than publish a list that looks complete. That design expected one kind of failure: no answer.

A capped list is a different failure. The forge answered with a success code and 50 valid items. Each check on the page passed, because each check tested the items it received. The forge also sends the total count in a response header. The code never read it, so nothing compared what it had with what existed.

The fix

Pull request #70 changes the read:

  • it asks for each list page by page until a page comes back empty, so the forge’s limit does not matter;
  • it compares the number it read with the total the forge reports, and fails the build if they differ.

One test reads a stub forge that holds 120 pull requests and returns 50, then 30, at a time. Another checks that a wrong or missing total fails the build. Both fail on the old code. I merged the fix on 3 November. That day the live record listed 71 merged changes, from #73 down to #1, with 10 unprovable.

In one case the fix does not do what the requirement asks. The requirement says that a record which cannot be read in full states that it is incomplete. The fix fails the build instead, so the last complete record stays live. One of the two has to change. That is a decision, and the decision and spec stages have not run for this requirement.

What the late stages showed

Episode 02 said the missing stages would ask the questions the build could not ask for itself. Run late, they did. The research asked where the record comes from, and the requirement turned “every change” into a test.

They also showed a limit of reading. The research read the code and believed it. One request to the forge settings found what 16 days of builds had not.

Next

The requirement is still proposed. It asks for more than this fix: the record should name the brief version that sets each change’s tier, and it should publish no private address. Those wait for the decision and spec stages.