diff --git a/.claude/skills/run-a-platform-trial/SKILL.md b/.claude/skills/run-a-platform-trial/SKILL.md index 915b65ef..3bfc2eb6 100644 --- a/.claude/skills/run-a-platform-trial/SKILL.md +++ b/.claude/skills/run-a-platform-trial/SKILL.md @@ -21,12 +21,12 @@ everything a trial leaves in it: its runs, logs and artifacts. - **Only the canary.** A trial runs in combsmith/software-factory-canary. Set `GH_REPO=combsmith/software-factory-canary` for every command of the trial, and name no other repo. P-8 needs twelve repos, P-11 the control room and the hub, P-19 a separate public repo, - P-30 the Factory's own repo, and P-31 every repo an App is installed on: for these, stop and + P-30 and P-63 the Factory's own repo, and P-31 every repo an App is installed on: for these, stop and raise it with the Maintainer before anything runs. The fixture's schema accepts the canary, or the org `combsmith` for a trial about the org and its Apps alone, such as P-39 (decision 0035), or the Factory's own repo for a trial `tools/check_trials.py` names in - `TRIALS_OF_THE_FACTORY`, which is P-30 alone, or, for a vendor's CLI, no repo (decision 0033), so - any other trial outside the canary needs that decided first. + `TRIALS_OF_THE_FACTORY`, which is P-30 and P-63 alone, or, for a vendor's CLI, no repo + (decision 0033), so any other trial outside the canary needs that decided first. - **Nothing here reads the canary.** Only a document, a fixture, the fixture's example and its schema name it here, and so does `config/apps.json`, which declares where the Apps are installed and which nothing runs. `tools/check_trials.py` refuses any other file that names diff --git a/docs/architecture/software-factory-design.md b/docs/architecture/software-factory-design.md index af68f374..586cf5a1 100644 --- a/docs/architecture/software-factory-design.md +++ b/docs/architecture/software-factory-design.md @@ -2220,7 +2220,7 @@ it observed as a recorded fixture, which is what the simulator's fake GitHub is | P-31 | Does the Controller App's webhook reach a hosted function for every repo it is installed on, and can that function cause a nudge with no credential over the Factory? | Yes to both | | P-28 | Can the actor who last pushed a pull request's head be read as a fact? | Yes, or I-26 has to be met another way | | P-29 | Is the hash of a pull request's own diff stable when only the base moves, and how does a truncated diff present? | Stable; truncation is detectable | -| P-30 | Which identity can cut a Release and move a channel tag under a tag ruleset, from a workflow in the Factory repo? | One identity, through one path | +| P-30 | Which identity can cut a Release and move a channel tag under a tag ruleset, from a workflow in the Factory repo? | One identity, through one path. **Passed** on 2026-11-09 (`trials/P-30.json`), recorded from the release runs of v0.1.0: the release App, combsmith-sf-release, cut it and moved the channel tag from `release.yml` on `main`, and the re-cut wrote nothing. The tag ruleset's bypass list names that App and the admin role alone, and the admin role is the Maintainer's login alone, both read live. That read stands in for each other identity's refusal; none was exercised (decision 0173). Decision 0114 is why the App and not the poller's job token | | P-21 | How often may the control room's page be rebuilt, and can a page read the feed files directly from a browser? | The page reads the feed directly and rebuilds only when its own code changes | | P-23 | How many threads may one App resolve in an hour before GitHub's secondary limits apply? | Enough for about 22 threads a pull request at the Factory's merge rate. **Passed** on 2026-10-28 (`trials/P-23.json`), in the canary: an App with `contents: write` resolved 30 threads it had opened, one after another as fast as GitHub answered, each 200 with no error, in 40 seconds, the GraphQL count rising from 8 to 37 of 5,000, with no secondary limit met. An hour's rate was not measured: no limit was reached | | P-24 | With the Maintainer as the only code owner of a path, does the machine user's approval fail to satisfy code-owner review there? Not needed for the Factory's repo while its code owners follow the org's standard | It fails to satisfy it | @@ -2257,6 +2257,7 @@ it observed as a recorded fixture, which is what the simulator's fake GitHub is | P-60 | Does GitHub serve a commit's tarball as one redirect from api.github.com to codeload.github.com, which answers it with no Authorization header, and does codeload redirect again? | One redirect, so the transport may follow it to codeload alone and refuse any second (the Maintainer's "Tarball, allow codeload", 2026-11-04). **Passed** on 2026-11-04 (`trials/P-60.json`), on the canary, asked with no credential: the API answered 302 to `https://codeload.github.com///legacy.tar.gz/`, with no token in it, and codeload answered that with no Authorization header 200, a gzip with no `content-length`, whose tar opens with a pax global header naming the whole commit and holds one folder of directories and regular files. No address on codeload over HTTPS redirected; over plain HTTP it answered 301 to the same address over HTTPS. For a commit the canary does not hold the API still answered 302, and codeload 404. What codeload's Location holds for a private repo, read with an App's token, is not asked: it is owed before a live Run reads a private head. The same commit's tree, `GET /repos///git/trees/?recursive=1` asked with no credential on 2026-11-05 (`trials/P-60.tree.json`), answered 200 and not truncated, listing every folder and file with its mode, and each file with its size and a blob hash that matched the tarball's bytes, all 22; a commit the canary does not hold answered 422. The review's head is held to that tree (decision 0142) | | P-61 | Does an issue's timeline give each change of its type, and each link of a pull request by hand in its Development box and its unlinking, as an event of its own with its time to the second and who made it; and does the merge of a pull request linked by hand close the issue, naming it the closer? | Each as its own timed event, so that row 1 can read an issue's type and a link by hand as each stood at the merge ("Trial P-61: an issue's type changes and a pull request linked by hand, each timed on the issue's timeline", issue 551; decision 0141). **Not run yet**: `tools/trial_p61_timeline.sh` reads the timeline through the Maintainer's own login at each of eight steps he makes by hand in the canary, and keeps each answer redacted outside the repo; it waits on the eval replay | | P-62 | Does the contents API, asked with the raw media type, answer a file of more than 1 MiB with its bytes whole, in one answer and no redirect; and does the git blobs API answer the same blob as base64? | Whole, in one answer, so that the eval job reads a case's head and tree from the held-out home with the home's token alone ("A case's head is read from the private home, pinned by its hash, and the run is sharded", issue 611; the Factory Builder's ruling of 2026-11-08, (d)); the git blobs API is the fallback. **Passed** on 2026-11-09 (`trials/P-62.json`), by the Factory Builder's ruling of 2026-11-08 that "the raw media type" in its pass condition is answered by `application/vnd.github.raw`, the type the transport must ask for, and that `gh`'s failure on `application/vnd.github.raw+json` with the Maintainer's login is a fault of the client on a type the Factory will not use, not GitHub's answer; in the canary, on a file of 1,577,185 random bytes on a branch made for it and deleted after: asked with `application/vnd.github.raw+json` with no credential, or with `application/vnd.github.raw` with the Maintainer's login or none, the API answered 200 with a `content-length` of the file's and the file's bytes exactly, by their sha256, and no redirect. Asked as JSON it answered the file's size with `content` empty and `encoding` `none`. The git blobs API answered the blob as base64 that decoded to the same bytes, and with the raw media type as `application/octet-stream`. With the login, `application/vnd.github.raw+json` was answered 200 with a `content-length` of the file's, but `gh api` wrote no body, saying "transform: short source buffer", three times; and the transport reads any answer whose type ends in json as JSON, so every reader, the transport among them, asks for `application/vnd.github.raw`, whose answer's type does not. What the API answers for a private repo's file is not asked here. Should it answer the held-out home's otherwise, a redirect among them, the read fails closed: the transport follows no redirect for a file, and a head not read whole is `head_unreadable` | +| P-63 | Does the review Intent's eval job, run from `main`, read the private held-out home with its environment's secret and upload its `eval-report/1` by hashes alone, and is that environment refused to every other branch? | The job reads and uploads on `main`, and the environment admits `main` alone with no admin bypass. **Passed** on 2026-11-09 (`trials/P-63.json`), recorded from run 42347416962, the gate's run for `factory/v0.1.0`, by hashes, codes and run metadata alone: its fetch and upload succeeded, its report's set and cases are `evals/pr-review/cases.json`'s at the run's commit, and `factory-eval` deploys from `main` alone with no admin bypass, read live. No dispatch from another branch was exercised; the live read stands in for it (decision 0173). It runs in the Factory's own repo, as P-30 does (decision 0113) | ### 6.1 The order to run them in diff --git a/docs/decisions/0173-the-eval-jobs-trial-records-the-factorys-own-repo-beside-p-30-and-a-live-read-stands-for-a-refusal.md b/docs/decisions/0173-the-eval-jobs-trial-records-the-factorys-own-repo-beside-p-30-and-a-live-read-stands-for-a-refusal.md new file mode 100644 index 00000000..21479234 --- /dev/null +++ b/docs/decisions/0173-the-eval-jobs-trial-records-the-factorys-own-repo-beside-p-30-and-a-live-read-stands-for-a-refusal.md @@ -0,0 +1,25 @@ +# 0173. The eval job's trial records the Factory's own repo beside P-30, and a live read stands for a refusal + +Status: accepted. The Factory Builder's rulings of 2026-11-09 on the fixtures of "Epic: slice 1, first approval. A Release on next reviews a pull request to this repo, and the machine user's approval stands" (issue 182), for "Workflows: eval.yml runs the review Intent's held-out cases and writes eval-report/1" (issue 309) and "Trial P-30: one identity cuts a Release and moves a channel tag under the tag ruleset" (issue 189). Pre-approved by the Maintainer on 2026-11-08. It amends decision 0113's row "Which trials may", whose "P-30 alone" now reads "P-30 and P-63 alone", and changes nothing else of it. + +## Decision + +| What | Decided | Because | +|---|---|---| +| The eval job's trial | P-63, a new row of section 6: the job, run from `main`, reads the private held-out home with `factory-eval`'s secret and uploads its `eval-report/1` by hashes alone, and that environment is refused to every other branch. `trials/P-63.json` records run 42347416962, the gate's run for the Release v0.1.0 | The eval job's story asks a platform trial to record the job, and no row of section 6 asked it | +| Where it records it ran | `combsmith/software-factory`: `TRIALS_OF_THE_FACTORY` in `tools/check_trials.py` names P-63 beside P-30, and still no other | The job and its environment are this repo's, and the canary has neither, as with P-30's tag ruleset under 0113 | +| What it keeps of the report | The report's commit, Release, set, totals and one-word bars, and each case by its id and sha256 alone. Each case's verdict and reasons are left out, and the archive's own sha256 is the artifact's digest GitHub lists | A reason such as `finding_not_raised` tells a case's kind, and no count of a kind is written in this repo (decision 0120). The id and the hash are already `evals/pr-review/cases.json`'s | +| What stands for a refusal | P-63: `factory-eval`'s one deployment branch policy, `main`, with no admin bypass, read live, stands for a dispatch from another branch refused. P-30: tag ruleset 25183656's bypass list, the admin role and the release App alone, read live, stands for each other identity's refusal. Each fixture states its residual in its pass condition: no dispatch from another branch, and no other identity's refusal, was exercised | A rule GitHub enforces, read as it stands, says whom it refuses. Exercising each refusal needs a dispatch the Maintainer alone makes, or a credential for each identity, which no session holds | +| P-30 | `trials/P-30.json` records release runs 42348605675, which cut the Release v0.1.0 and moved the channel tag v0-next to it, its Deployment naming the release App as creator, and 42348650504, the same cut refused, with both tag rulesets and the repo's admins read live. Decision 0114 is why the release App and not the poller's job token | The first two boxes of P-30's story | +| When each pass condition was written | After the runs, from the story's own condition as the ruling of 2026-11-09 stands it in. This sets aside, for these two fixtures alone, the trial skill's step 1, that the condition comes before anything runs: the runs were the Maintainer's dispatches for the Release, made before any trial was asked of them, and each condition names its stand-in and residual rather than fitting the answer | A fixture of a run already made can only be written after it; saying so is better than a condition that reads as written first | + +## Why + +Both stories needed a fixture to close, and both runs had already happened. A fixture made from those runs, with the rule that refuses everyone else read beside it, says what happened and what it stands on, and names what it does not show. + +## Boundaries + +| Boundary | Check | +|---|---| +| P-63 recorded on this repo holds, and recorded on the canary is refused | `tests/test_tools.py::test_the_eval_jobs_trial_records_the_factorys_own_repo`, `tools/check_trials.py`, mutant: "the eval job's trial is no trial of the Factory" | +| No trial but P-30 and P-63 records this repo | `examples/invalid/trial.another-trial-in-the-factorys-repo.json`, `tests/test_tools.py::test_a_cost_measurements_exchanges_name_each_repo_they_span`, `tools/check_trials.py`, mutant: "any trial may record the Factory's own repo" | diff --git a/schemas/trial.schema.json b/schemas/trial.schema.json index b6d615e9..dacf4508 100644 --- a/schemas/trial.schema.json +++ b/schemas/trial.schema.json @@ -35,7 +35,7 @@ "minLength": 1 }, "repo": { - "description": "Where the trial ran: the canary repo; the org itself for a trial about the org and its Apps, such as P-39 (decision 0035); the Factory's own repo for a trial tools/check_trials.py names in TRIALS_OF_THE_FACTORY, such as P-30; or null for a trial that asks a vendor's CLI and not GitHub, such as P-13 (decision 0033). Nothing else.", + "description": "Where the trial ran: the canary repo; the org itself for a trial about the org and its Apps, such as P-39 (decision 0035); the Factory's own repo for a trial tools/check_trials.py names in TRIALS_OF_THE_FACTORY, P-30 and P-63; or null for a trial that asks a vendor's CLI and not GitHub, such as P-13 (decision 0033). Nothing else.", "enum": [ "combsmith/software-factory-canary", "combsmith", diff --git a/tests/test_tools.py b/tests/test_tools.py index 9c000f6a..0a32fb4d 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -5633,6 +5633,14 @@ def test_a_write_is_recorded_only_on_a_node_a_read_of_the_org_answered(self): outside["exchanges"][0]["request"]["call"] = "GET /repos/outside/x/pulls/7" self.assertTrue(any("on a node no read" in p for p in check_trials.fixture_problems(outside))) + def test_the_eval_jobs_trial_records_the_factorys_own_repo(self): # issue 309, decision 0173 + # P-63, the eval job's trial, ran in this repo from main: recorded there it holds, and on the canary it is refused. + data = json.loads((ROOT / "trials" / "P-63.json").read_text()) + self.assertEqual(check_trials.fixture_problems(data), []) + canary = check_trials.ORG + "/" + check_trials.CANARY + self.assertEqual(check_trials._of_the_factory(dict(data, repo=canary)), + [("repo", "is %s, and P-63 runs in %s; record where it ran" % (canary, check_trials.FACTORY))]) + def test_a_write_in_a_fixture_of_the_factory_is_held_to_a_node_of_the_factory(self): # What holds a canary fixture's writes holds this one's, with the Factory's id in the canary's. Each node id is # a prefix and base64url of msgpack [0, the repository's id, ...], as GitHub writes one. diff --git a/tools/check_trials.py b/tools/check_trials.py index 35258e26..3642e061 100644 --- a/tools/check_trials.py +++ b/tools/check_trials.py @@ -57,10 +57,11 @@ TRIALS_OF_FORKS = {"P-27"} TRIALS_OF_REACH = {"P-4"} # A trial that can only run in the Factory's own repo, and records it: P-30 cuts a Release under the tag ruleset of the -# repo that holds the Releases, which the canary is not. It is held to every rule of a fixture of the canary, with this -# repo in the canary's place, and no other trial records this repo. +# repo that holds the Releases, which the canary is not, and P-63 runs the eval job from its environment, which the +# canary has not either. Each is held to every rule of a fixture of the canary, with this repo in the canary's place, and +# no other trial records this repo. FACTORY = ORG + "/software-factory" -TRIALS_OF_THE_FACTORY = {"P-30"} +TRIALS_OF_THE_FACTORY = {"P-30", "P-63"} # A command-line read names a repo by --repo, -R or GH_REPO, with or without a space, an equals sign, quotes or the # site's address; by `gh repo owner/name`; or by a path or an address in its words. CLI_REPO = re.compile(r"(?:--repo|-R|GH_REPO)[ =]?[\"']?(?:https://github\.com/)?([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+)" diff --git a/tools/mutants.py b/tools/mutants.py index 2e555c39..ad2bfcd4 100644 --- a/tools/mutants.py +++ b/tools/mutants.py @@ -2656,11 +2656,15 @@ def moved_before(rel: str, block: str, anchor: str) -> tuple: " if not actions and rel is not None:\n", " if False:\n", ("tests.test_tools.Workflows.test_a_lens_run_by_actions_names_its_workflow_and_no_other_does",)), ("a Role may write through the release App", "tools/check_authority.py", 'if key in ("controller", "reader", "release")}', 'if key in ("controller", "reader")}', ("tests.test_tools.Authority.test_a_role_writes_through_no_app_that_is_no_roles",)), - # P-30 runs in the Factory's own repo, the one trial that records it, and is held as a canary fixture is. + # P-30 and P-63 run in the Factory's own repo, the only trials that record it, each held as a canary fixture is. ("any trial may record the Factory's own repo", "tools/check_trials.py", 'if repo == FACTORY and trial not in TRIALS_OF_THE_FACTORY:', 'if False:', ("tests.test_tools.Trials.test_a_cost_measurements_exchanges_name_each_repo_they_span",)), ("a trial of the Factory may record the canary", "tools/check_trials.py", 'if trial in TRIALS_OF_THE_FACTORY and repo != FACTORY:', 'if False:', ("tests.test_tools.Trials.test_a_cost_measurements_exchanges_name_each_repo_they_span",)), + # Issue 309, decision 0173: the eval job's trial records this repo, beside P-30. + ("the eval job's trial is no trial of the Factory", "tools/check_trials.py", + 'TRIALS_OF_THE_FACTORY = {"P-30", "P-63"}', 'TRIALS_OF_THE_FACTORY = {"P-30"}', + ("tests.test_tools.Trials.test_the_eval_jobs_trial_records_the_factorys_own_repo",)), ("a fixture of the Factory's repo is held to no repo it names", "tools/check_trials.py", 'data.get("repo") in ("%s/%s" % (ORG, CANARY), FACTORY):', 'data.get("repo") == "%s/%s" % (ORG, CANARY):', ("tests.test_tools.Trials.test_a_cost_measurements_exchanges_name_each_repo_they_span",)), ("an App in a fixture of the Factory's repo is held to no reach", "tools/check_trials.py", diff --git a/trials/AGENTS.md b/trials/AGENTS.md index 959f749e..33b4a1e6 100644 --- a/trials/AGENTS.md +++ b/trials/AGENTS.md @@ -1,7 +1,7 @@ # trials/ What GitHub was seen to do. Each file is the fixture of one platform trial from section 6 of the design: what was sent to GitHub in the canary repo, combsmith/software-factory-canary, of the -org itself for a trial about the org and its Apps (decision 0035), in the Factory's repo for P-30 (decision 0113), or, for a trial of a vendor's CLI, in no repo (decision 0033), and what came back, +org itself for a trial about the org and its Apps (decision 0035), in the Factory's repo for P-30 and P-63 (0113, 0173), or, for a trial of a vendor's CLI, in no repo (decision 0033), and what came back, with every credential removed. The fake GitHub in `sim/` is held to these (`sim/grounding.py`). How a trial is run is the skill `.claude/skills/run-a-platform-trial/SKILL.md`; P-13's script, `tools/trial_p13_cli.sh`, has its runbook beside it, `tools/trial_p13_runbook.md`; `tools/trial_p13_ended.sh` asks how a run ends. P-26's script, `tools/trial_p26_sandbox.sh`, holds its runbook and its pass condition at its top; so do P-50's and P-51's, `tools/trial_p50_linux_sandbox.sh` and `tools/trial_p51_sandbox_writes.sh`, @@ -11,7 +11,7 @@ which with P-50's stub, `tools/trial_p50_stub.py`, a trial runs only in the cana | Rule | Held by | |---|---| | A fixture is `.json` or `..json`, validates against `schemas/trial.schema.json`, and records the trial it is named for. Nothing else is kept here | `tests/test_tools.py::test_a_fixture_that_is_misnamed_or_invalid_is_caught` | -| It ran in the canary, the org `combsmith` (0035), the Factory's repo for P-30 alone, or no repo for a vendor's CLI (0033) | `examples/invalid/trial.another-trial-in-the-factorys-repo.json`, `examples/invalid/trial.neither-the-canary-nor-the-org.json` | +| It ran in the canary, the org `combsmith` (0035), the Factory's repo for P-30 and P-63 (0113, 0173), or none for a CLI (0033) | `examples/invalid/trial.another-trial-in-the-factorys-repo.json`, `examples/invalid/trial.neither-the-canary-nor-the-org.json` | | No credential: no field named for one at any depth, no string shaped like one, plainly or in base64. Delete it and list where in `removed` | `tests/test_tools.py::test_a_credential_in_a_fixture_is_caught` | | A header is kept only if `HEADERS` in `tools/check_trials.py` names it | `tests/test_tools.py::test_a_header_a_fixture_may_not_keep_is_caught` | | The examples of a fixture, counter-examples too, and this file hold no credential either | `tests/test_tools.py::test_every_example_of_a_fixture_and_the_folder_notes_are_scanned` | diff --git a/trials/P-30.json b/trials/P-30.json new file mode 100644 index 00000000..ae72c680 --- /dev/null +++ b/trials/P-30.json @@ -0,0 +1,1169 @@ +{ + "schema": "trial/1", + "trial": "P-30", + "question": "Which identity can cut a Release and move a channel tag under a tag ruleset, from a workflow in the Factory repo?", + "pass": "One identity, through one path (section 6). As the story, #189, states it, under the Factory Builder's ruling of 2026-11-09, pre-approved by the Maintainer on 2026-11-08: from release.yml on main, one identity created the immutable tag factory/v0.1.0 and moved the channel tag factory/v0-next to it, in run 42348605675, and the Deployment of factory-next that the same step recorded names that identity as its creator; a second cut of the same Release, run 42348650504, wrote nothing; the tag ruleset factory release tags (25183656), which refuses creating, updating, deleting or force-pushing any refs/tags/factory/* tag, names in its bypass list that identity and the admin role alone, the admin role being the Maintainer's own login (recovery, section 9.1), which the repo's admins, read live with every affiliation, show: don-petry alone; and the ruleset factory releases are immutable (25996980) lets no one move or delete a Release tag. The live read of 25183656's bypass list stands in for each other identity's refusal, the machine user's and each other Factory App's: an identity the list does not name is refused by the ruleset. Residual, stated: no other identity's refusal was exercised, and the admins are read as they stood on the day of the read. The identity is the App combsmith-sf-release, 5502359 (decision 0114). The poller's job token was not taken: GitHub grants a job token no workflows permission, which a tag on a commit that touches .github/workflows/ needs (decision 0114), and a bypass for it would name GitHub Actions, through which every workflow of this repo would pass the ruleset, not one path.", + "repo": "combsmith/software-factory", + "ran_at": "2026-11-09T02:44:03Z", + "exchanges": [ + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/actions/runs/42348605675 (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:04 GMT", + "etag": "W/\"1245ab3fa0ceda2743df24e95e676b2d56bfbbfd8b2236b7c26971e3b5453281\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5A1:C9190:26A6F92:800442B:6AF13373", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4682", + "x-ratelimit-reset": "1794192257", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "318" + }, + "body": { + "id": 42348605675, + "name": "sf-release", + "node_id": "WFR_kwLOVFBqVc8AAAAJ3Cxw6w", + "head_branch": "main", + "head_sha": "499835d5384ba81c466b17199edcde1848431630", + "path": ".github/workflows/release.yml", + "display_title": "sf-release", + "run_number": 15, + "event": "workflow_dispatch", + "status": "completed", + "conclusion": "success", + "workflow_id": 398755186, + "check_suite_id": 114738805087, + "check_suite_node_id": "CS_kwDOVFBqVc8AAAAatvc5Xw", + "url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348605675", + "html_url": "https://github.com/combsmith/software-factory/actions/runs/42348605675", + "pull_requests": [], + "created_at": "2026-11-07T06:48:28Z", + "updated_at": "2026-11-07T06:48:45Z", + "actor": { + "login": "don-petry", + "id": 36422719, + "node_id": "MDQ6VXNlcjM2NDIyNzE5", + "avatar_url": "https://avatars.githubusercontent.com/u/36422719?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/don-petry", + "html_url": "https://github.com/don-petry", + "followers_url": "https://api.github.com/users/don-petry/followers", + "following_url": "https://api.github.com/users/don-petry/following{/other_user}", + "gists_url": "https://api.github.com/users/don-petry/gists{/gist_id}", + "starred_url": "https://api.github.com/users/don-petry/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/don-petry/subscriptions", + "organizations_url": "https://api.github.com/users/don-petry/orgs", + "repos_url": "https://api.github.com/users/don-petry/repos", + "events_url": "https://api.github.com/users/don-petry/events{/privacy}", + "received_events_url": "https://api.github.com/users/don-petry/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "run_attempt": 1, + "referenced_workflows": [], + "run_started_at": "2026-11-07T06:48:28Z", + "triggering_actor": { + "login": "don-petry", + "id": 36422719, + "node_id": "MDQ6VXNlcjM2NDIyNzE5", + "avatar_url": "https://avatars.githubusercontent.com/u/36422719?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/don-petry", + "html_url": "https://github.com/don-petry", + "followers_url": "https://api.github.com/users/don-petry/followers", + "following_url": "https://api.github.com/users/don-petry/following{/other_user}", + "gists_url": "https://api.github.com/users/don-petry/gists{/gist_id}", + "starred_url": "https://api.github.com/users/don-petry/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/don-petry/subscriptions", + "organizations_url": "https://api.github.com/users/don-petry/orgs", + "repos_url": "https://api.github.com/users/don-petry/repos", + "events_url": "https://api.github.com/users/don-petry/events{/privacy}", + "received_events_url": "https://api.github.com/users/don-petry/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "jobs_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348605675/jobs", + "logs_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348605675/logs", + "check_suite_url": "https://api.github.com/repos/combsmith/software-factory/check-suites/114738805087", + "artifacts_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348605675/artifacts", + "cancel_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348605675/cancel", + "rerun_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348605675/rerun", + "previous_attempt_url": null, + "workflow_url": "https://api.github.com/repos/combsmith/software-factory/actions/workflows/398755186", + "head_commit": { + "id": "499835d5384ba81c466b17199edcde1848431630", + "tree_id": "fe2a466d35ef359b8cf55e1ea322d01e982ddcf2", + "message": "The artifact storage is any productionresults account numbered in one to three digits (record 0151) (#598)\n\n* The artifact storage is any productionresults account numbered in one to three digits (record NNNN)\n\nThe cut of factory/v0.1.0 was refused with eval_gate_closed: the eval\nreport's download redirected to productionresultssa32, which the\ntransport's STORAGE pattern, sa0 to sa19 by decision 0045, refused, so\nthe report was read as unanswered. By the Maintainer's ruling, the\nstorage is productionresultssa and one to three digits, with no leading\nzero; the rest of 0045's row stands.\n\n- STORAGE in adapters/github.py widened, and a boundary test: sa0 to\n sa999 accepted; sa1000, a leading zero, a letter or non-ASCII digit\n in the number, another account name and another host refused.\n- Mutants: a fourth digit, a stop at sa99 or sa19, a leading zero, a\n trailing letter, Unicode digits, and any account name.\n- Record NNNN replaces 0147, the one record in force of those that hold\n 0045's rows (0045, then 0138, then 0147), and overturns only the\n accounts 0045's row names. 0147's Status says it is replaced.\n\nEvery artifact read through the redirect, a Run's outcome, a Lens's\napplied/1, the pass records and the eval report, had the same latent\nfailure whenever GitHub served it past sa19.\n\nCo-Authored-By: Claude Opus 5.5 \n\n* Fix round 1 on record 0151: no mutant that no test can kill, and the record named\n\n- The mutant giving the storage's number any Unicode digit is dropped:\n storage() refuses a URL that is not ASCII before STORAGE is read, so\n no test can tell it from the code. The record's row no longer claims\n it (the security pass, the Claude review, Astra and Argon).\n- The record says that every account from sa0 to sa999 being GitHub's\n is assumed, not known, and what the ruling accepts in it (the\n security pass).\n- The record says a leading zero is refused, narrower than the ruling,\n since GitHub's names have none (the Factory Builder).\n- NNNN is 0151, the Factory Builder's number, everywhere (Argon).\n\nCo-Authored-By: Claude Opus 5.5 \n\n---------\n\nCo-authored-by: Claude Opus 5.5 ", + "timestamp": "2026-11-07T06:03:10Z", + "author": { + "name": "Don Petry", + "email": "36422719+don-petry@users.noreply.github.com" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com" + } + }, + "repository": { + "id": 1414556245, + "node_id": "R_kgDOVFBqVQ", + "name": "software-factory", + "full_name": "combsmith/software-factory", + "private": false, + "owner": { + "login": "combsmith", + "id": 258516906, + "node_id": "O_kgDOD2inqg", + "avatar_url": "https://avatars.githubusercontent.com/u/258516906?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/combsmith", + "html_url": "https://github.com/combsmith", + "followers_url": "https://api.github.com/users/combsmith/followers", + "following_url": "https://api.github.com/users/combsmith/following{/other_user}", + "gists_url": "https://api.github.com/users/combsmith/gists{/gist_id}", + "starred_url": "https://api.github.com/users/combsmith/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/combsmith/subscriptions", + "organizations_url": "https://api.github.com/users/combsmith/orgs", + "repos_url": "https://api.github.com/users/combsmith/repos", + "events_url": "https://api.github.com/users/combsmith/events{/privacy}", + "received_events_url": "https://api.github.com/users/combsmith/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/combsmith/software-factory", + "description": "The Factory's decision core: a pure, checkable Kernel over GitHub facts, with schemas, lifecycles and a simulator", + "fork": false, + "url": "https://api.github.com/repos/combsmith/software-factory", + "forks_url": "https://api.github.com/repos/combsmith/software-factory/forks", + "keys_url": "https://api.github.com/repos/combsmith/software-factory/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/combsmith/software-factory/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/combsmith/software-factory/teams", + "hooks_url": "https://api.github.com/repos/combsmith/software-factory/hooks", + "issue_events_url": "https://api.github.com/repos/combsmith/software-factory/issues/events{/number}", + "events_url": "https://api.github.com/repos/combsmith/software-factory/events", + "assignees_url": "https://api.github.com/repos/combsmith/software-factory/assignees{/user}", + "branches_url": "https://api.github.com/repos/combsmith/software-factory/branches{/branch}", + "tags_url": "https://api.github.com/repos/combsmith/software-factory/tags", + "blobs_url": "https://api.github.com/repos/combsmith/software-factory/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/combsmith/software-factory/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/combsmith/software-factory/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/combsmith/software-factory/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/combsmith/software-factory/statuses/{sha}", + "languages_url": "https://api.github.com/repos/combsmith/software-factory/languages", + "stargazers_url": "https://api.github.com/repos/combsmith/software-factory/stargazers", + "contributors_url": "https://api.github.com/repos/combsmith/software-factory/contributors", + "subscribers_url": "https://api.github.com/repos/combsmith/software-factory/subscribers", + "subscription_url": "https://api.github.com/repos/combsmith/software-factory/subscription", + "commits_url": "https://api.github.com/repos/combsmith/software-factory/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/combsmith/software-factory/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/combsmith/software-factory/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/combsmith/software-factory/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/combsmith/software-factory/contents/{+path}", + "compare_url": "https://api.github.com/repos/combsmith/software-factory/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/combsmith/software-factory/merges", + "archive_url": "https://api.github.com/repos/combsmith/software-factory/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/combsmith/software-factory/downloads", + "issues_url": "https://api.github.com/repos/combsmith/software-factory/issues{/number}", + "pulls_url": "https://api.github.com/repos/combsmith/software-factory/pulls{/number}", + "milestones_url": "https://api.github.com/repos/combsmith/software-factory/milestones{/number}", + "notifications_url": "https://api.github.com/repos/combsmith/software-factory/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/combsmith/software-factory/labels{/name}", + "releases_url": "https://api.github.com/repos/combsmith/software-factory/releases{/id}", + "deployments_url": "https://api.github.com/repos/combsmith/software-factory/deployments" + }, + "head_repository": { + "id": 1414556245, + "node_id": "R_kgDOVFBqVQ", + "name": "software-factory", + "full_name": "combsmith/software-factory", + "private": false, + "owner": { + "login": "combsmith", + "id": 258516906, + "node_id": "O_kgDOD2inqg", + "avatar_url": "https://avatars.githubusercontent.com/u/258516906?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/combsmith", + "html_url": "https://github.com/combsmith", + "followers_url": "https://api.github.com/users/combsmith/followers", + "following_url": "https://api.github.com/users/combsmith/following{/other_user}", + "gists_url": "https://api.github.com/users/combsmith/gists{/gist_id}", + "starred_url": "https://api.github.com/users/combsmith/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/combsmith/subscriptions", + "organizations_url": "https://api.github.com/users/combsmith/orgs", + "repos_url": "https://api.github.com/users/combsmith/repos", + "events_url": "https://api.github.com/users/combsmith/events{/privacy}", + "received_events_url": "https://api.github.com/users/combsmith/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/combsmith/software-factory", + "description": "The Factory's decision core: a pure, checkable Kernel over GitHub facts, with schemas, lifecycles and a simulator", + "fork": false, + "url": "https://api.github.com/repos/combsmith/software-factory", + "forks_url": "https://api.github.com/repos/combsmith/software-factory/forks", + "keys_url": "https://api.github.com/repos/combsmith/software-factory/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/combsmith/software-factory/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/combsmith/software-factory/teams", + "hooks_url": "https://api.github.com/repos/combsmith/software-factory/hooks", + "issue_events_url": "https://api.github.com/repos/combsmith/software-factory/issues/events{/number}", + "events_url": "https://api.github.com/repos/combsmith/software-factory/events", + "assignees_url": "https://api.github.com/repos/combsmith/software-factory/assignees{/user}", + "branches_url": "https://api.github.com/repos/combsmith/software-factory/branches{/branch}", + "tags_url": "https://api.github.com/repos/combsmith/software-factory/tags", + "blobs_url": "https://api.github.com/repos/combsmith/software-factory/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/combsmith/software-factory/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/combsmith/software-factory/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/combsmith/software-factory/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/combsmith/software-factory/statuses/{sha}", + "languages_url": "https://api.github.com/repos/combsmith/software-factory/languages", + "stargazers_url": "https://api.github.com/repos/combsmith/software-factory/stargazers", + "contributors_url": "https://api.github.com/repos/combsmith/software-factory/contributors", + "subscribers_url": "https://api.github.com/repos/combsmith/software-factory/subscribers", + "subscription_url": "https://api.github.com/repos/combsmith/software-factory/subscription", + "commits_url": "https://api.github.com/repos/combsmith/software-factory/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/combsmith/software-factory/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/combsmith/software-factory/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/combsmith/software-factory/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/combsmith/software-factory/contents/{+path}", + "compare_url": "https://api.github.com/repos/combsmith/software-factory/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/combsmith/software-factory/merges", + "archive_url": "https://api.github.com/repos/combsmith/software-factory/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/combsmith/software-factory/downloads", + "issues_url": "https://api.github.com/repos/combsmith/software-factory/issues{/number}", + "pulls_url": "https://api.github.com/repos/combsmith/software-factory/pulls{/number}", + "milestones_url": "https://api.github.com/repos/combsmith/software-factory/milestones{/number}", + "notifications_url": "https://api.github.com/repos/combsmith/software-factory/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/combsmith/software-factory/labels{/name}", + "releases_url": "https://api.github.com/repos/combsmith/software-factory/releases{/id}", + "deployments_url": "https://api.github.com/repos/combsmith/software-factory/deployments" + } + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/actions/runs/42348605675/jobs (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:04 GMT", + "etag": "W/\"7fe32c01a0a9ca3d824aae45766d7acf8e2897743fc1510de0c8d1e29c17a6da\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5A2:148802:1D6F978:616CF1F:6AF13374", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4864", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "136" + }, + "body": { + "total_count": 1, + "jobs": [ + { + "id": 128331696706, + "run_id": 42348605675, + "workflow_name": "sf-release", + "head_branch": "main", + "run_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348605675", + "run_attempt": 1, + "node_id": "CR_kwDOVFBqVc8AAAAd4SpKQg", + "head_sha": "499835d5384ba81c466b17199edcde1848431630", + "url": "https://api.github.com/repos/combsmith/software-factory/actions/jobs/128331696706", + "html_url": "https://github.com/combsmith/software-factory/actions/runs/42348605675/job/128331696706", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-07T06:48:30Z", + "started_at": "2026-11-07T06:48:33Z", + "completed_at": "2026-11-07T06:48:45Z", + "name": "release", + "steps": [ + { + "name": "Set up job", + "status": "completed", + "conclusion": "success", + "number": 1, + "started_at": "2026-11-07T06:48:33Z", + "completed_at": "2026-11-07T06:48:34Z" + }, + { + "status": "completed", + "conclusion": "success", + "number": 2, + "started_at": "2026-11-07T06:48:34Z", + "completed_at": "2026-11-07T06:48:35Z" + }, + { + "name": "Run actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1", + "status": "completed", + "conclusion": "success", + "number": 3, + "started_at": "2026-11-07T06:48:35Z", + "completed_at": "2026-11-07T06:48:36Z" + }, + { + "name": "Run python3 -m release.move", + "status": "completed", + "conclusion": "success", + "number": 4, + "started_at": "2026-11-07T06:48:36Z", + "completed_at": "2026-11-07T06:48:42Z" + }, + { + "name": "Post Run actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1", + "status": "completed", + "conclusion": "success", + "number": 7, + "started_at": "2026-11-07T06:48:42Z", + "completed_at": "2026-11-07T06:48:42Z" + }, + { + "status": "completed", + "conclusion": "success", + "number": 8, + "started_at": "2026-11-07T06:48:42Z", + "completed_at": "2026-11-07T06:48:43Z" + }, + { + "name": "Complete job", + "status": "completed", + "conclusion": "success", + "number": 9, + "started_at": "2026-11-07T06:48:43Z", + "completed_at": "2026-11-07T06:48:43Z" + } + ], + "check_run_url": "https://api.github.com/repos/combsmith/software-factory/check-runs/128331696706", + "labels": [ + "ubuntu-24.04" + ], + "runner_id": 1000861594, + "runner_name": "GitHub Actions 1000861594", + "runner_group_id": 0, + "runner_group_name": "GitHub Actions" + } + ] + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/deployments?environment=factory-next (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:05 GMT", + "etag": "W/\"4f1c9410d392ee0f3dbe78bd44738751f28301734bc5232941cde5921f479750\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "repo, repo_deployment", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5A3:1EE6F7:25877C8:7C4312F:6AF13375", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4863", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "137" + }, + "body": [ + { + "url": "https://api.github.com/repos/combsmith/software-factory/deployments/7617833539", + "id": 7617833539, + "node_id": "DE_kwDOVFBqVc8AAAABxg7qQw", + "task": "deploy", + "original_environment": "factory-next", + "environment": "factory-next", + "description": "factory/v0.1.0", + "created_at": "2026-11-07T06:48:42Z", + "updated_at": "2026-11-07T06:48:42Z", + "statuses_url": "https://api.github.com/repos/combsmith/software-factory/deployments/7617833539/statuses", + "repository_url": "https://api.github.com/repos/combsmith/software-factory", + "creator": { + "login": "combsmith-sf-release[bot]", + "id": 349046324, + "node_id": "BOT_kgDOFM4GNA", + "avatar_url": "https://avatars.githubusercontent.com/u/258516906?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D", + "html_url": "https://github.com/apps/combsmith-sf-release", + "followers_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/combsmith-sf-release%5Bbot%5D/received_events", + "type": "Bot", + "user_view_type": "public", + "site_admin": false + }, + "sha": "499835d5384ba81c466b17199edcde1848431630", + "ref": "499835d5384ba81c466b17199edcde1848431630", + "payload": {}, + "transient_environment": false, + "production_environment": false, + "performed_via_github_app": null + } + ] + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/git/ref/tags/factory/v0.1.0 (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:05 GMT", + "etag": "W/\"bfaa2d87e3b242338243c15de3a09ce284225ead593614579d0b02193209225c\"", + "last-modified": "Mon, 09 Nov 2026 01:43:23 GMT", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "repo", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5A6:29A68C:27E391F:83ED8ED:6AF13375", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4862", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "138" + }, + "body": { + "ref": "refs/tags/factory/v0.1.0", + "node_id": "REF_kwDOVFBqVbhyZWZzL3RhZ3MvZmFjdG9yeS92MC4xLjA", + "url": "https://api.github.com/repos/combsmith/software-factory/git/refs/tags/factory/v0.1.0", + "object": { + "sha": "499835d5384ba81c466b17199edcde1848431630", + "type": "commit", + "url": "https://api.github.com/repos/combsmith/software-factory/git/commits/499835d5384ba81c466b17199edcde1848431630" + } + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/git/ref/tags/factory/v0-next (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:06 GMT", + "etag": "W/\"e8d359ec6d3b4c1c18e27634199cc5ecbbc75be16199c1ac9b731394a5731a37\"", + "last-modified": "Mon, 09 Nov 2026 01:43:23 GMT", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "repo", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5AA:9B7E2:25ED172:7D79A25:6AF13376", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4861", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "139" + }, + "body": { + "ref": "refs/tags/factory/v0-next", + "node_id": "REF_kwDOVFBqVblyZWZzL3RhZ3MvZmFjdG9yeS92MC1uZXh0", + "url": "https://api.github.com/repos/combsmith/software-factory/git/refs/tags/factory/v0-next", + "object": { + "sha": "499835d5384ba81c466b17199edcde1848431630", + "type": "commit", + "url": "https://api.github.com/repos/combsmith/software-factory/git/commits/499835d5384ba81c466b17199edcde1848431630" + } + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/actions/runs/42348650504 (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:06 GMT", + "etag": "W/\"384b02884daa866e64cb3b9bd6a5cb4da0c4530684b45fe355ab32aab2b6b8ec\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5AC:21681:2602246:7DE4317:6AF13376", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4681", + "x-ratelimit-reset": "1794192257", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "319" + }, + "body": { + "id": 42348650504, + "name": "sf-release", + "node_id": "WFR_kwLOVFBqVc8AAAAJ3C0gCA", + "head_branch": "main", + "head_sha": "499835d5384ba81c466b17199edcde1848431630", + "path": ".github/workflows/release.yml", + "display_title": "sf-release", + "run_number": 16, + "event": "workflow_dispatch", + "status": "completed", + "conclusion": "failure", + "workflow_id": 398755186, + "check_suite_id": 114738919203, + "check_suite_node_id": "CS_kwDOVFBqVc8AAAAatvj3Iw", + "url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348650504", + "html_url": "https://github.com/combsmith/software-factory/actions/runs/42348650504", + "pull_requests": [], + "created_at": "2026-11-07T06:49:08Z", + "updated_at": "2026-11-07T06:49:23Z", + "actor": { + "login": "don-petry", + "id": 36422719, + "node_id": "MDQ6VXNlcjM2NDIyNzE5", + "avatar_url": "https://avatars.githubusercontent.com/u/36422719?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/don-petry", + "html_url": "https://github.com/don-petry", + "followers_url": "https://api.github.com/users/don-petry/followers", + "following_url": "https://api.github.com/users/don-petry/following{/other_user}", + "gists_url": "https://api.github.com/users/don-petry/gists{/gist_id}", + "starred_url": "https://api.github.com/users/don-petry/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/don-petry/subscriptions", + "organizations_url": "https://api.github.com/users/don-petry/orgs", + "repos_url": "https://api.github.com/users/don-petry/repos", + "events_url": "https://api.github.com/users/don-petry/events{/privacy}", + "received_events_url": "https://api.github.com/users/don-petry/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "run_attempt": 1, + "referenced_workflows": [], + "run_started_at": "2026-11-07T06:49:08Z", + "triggering_actor": { + "login": "don-petry", + "id": 36422719, + "node_id": "MDQ6VXNlcjM2NDIyNzE5", + "avatar_url": "https://avatars.githubusercontent.com/u/36422719?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/don-petry", + "html_url": "https://github.com/don-petry", + "followers_url": "https://api.github.com/users/don-petry/followers", + "following_url": "https://api.github.com/users/don-petry/following{/other_user}", + "gists_url": "https://api.github.com/users/don-petry/gists{/gist_id}", + "starred_url": "https://api.github.com/users/don-petry/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/don-petry/subscriptions", + "organizations_url": "https://api.github.com/users/don-petry/orgs", + "repos_url": "https://api.github.com/users/don-petry/repos", + "events_url": "https://api.github.com/users/don-petry/events{/privacy}", + "received_events_url": "https://api.github.com/users/don-petry/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "jobs_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348650504/jobs", + "logs_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348650504/logs", + "check_suite_url": "https://api.github.com/repos/combsmith/software-factory/check-suites/114738919203", + "artifacts_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348650504/artifacts", + "cancel_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348650504/cancel", + "rerun_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348650504/rerun", + "previous_attempt_url": null, + "workflow_url": "https://api.github.com/repos/combsmith/software-factory/actions/workflows/398755186", + "head_commit": { + "id": "499835d5384ba81c466b17199edcde1848431630", + "tree_id": "fe2a466d35ef359b8cf55e1ea322d01e982ddcf2", + "message": "The artifact storage is any productionresults account numbered in one to three digits (record 0151) (#598)\n\n* The artifact storage is any productionresults account numbered in one to three digits (record NNNN)\n\nThe cut of factory/v0.1.0 was refused with eval_gate_closed: the eval\nreport's download redirected to productionresultssa32, which the\ntransport's STORAGE pattern, sa0 to sa19 by decision 0045, refused, so\nthe report was read as unanswered. By the Maintainer's ruling, the\nstorage is productionresultssa and one to three digits, with no leading\nzero; the rest of 0045's row stands.\n\n- STORAGE in adapters/github.py widened, and a boundary test: sa0 to\n sa999 accepted; sa1000, a leading zero, a letter or non-ASCII digit\n in the number, another account name and another host refused.\n- Mutants: a fourth digit, a stop at sa99 or sa19, a leading zero, a\n trailing letter, Unicode digits, and any account name.\n- Record NNNN replaces 0147, the one record in force of those that hold\n 0045's rows (0045, then 0138, then 0147), and overturns only the\n accounts 0045's row names. 0147's Status says it is replaced.\n\nEvery artifact read through the redirect, a Run's outcome, a Lens's\napplied/1, the pass records and the eval report, had the same latent\nfailure whenever GitHub served it past sa19.\n\nCo-Authored-By: Claude Opus 5.5 \n\n* Fix round 1 on record 0151: no mutant that no test can kill, and the record named\n\n- The mutant giving the storage's number any Unicode digit is dropped:\n storage() refuses a URL that is not ASCII before STORAGE is read, so\n no test can tell it from the code. The record's row no longer claims\n it (the security pass, the Claude review, Astra and Argon).\n- The record says that every account from sa0 to sa999 being GitHub's\n is assumed, not known, and what the ruling accepts in it (the\n security pass).\n- The record says a leading zero is refused, narrower than the ruling,\n since GitHub's names have none (the Factory Builder).\n- NNNN is 0151, the Factory Builder's number, everywhere (Argon).\n\nCo-Authored-By: Claude Opus 5.5 \n\n---------\n\nCo-authored-by: Claude Opus 5.5 ", + "timestamp": "2026-11-07T06:03:10Z", + "author": { + "name": "Don Petry", + "email": "36422719+don-petry@users.noreply.github.com" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com" + } + }, + "repository": { + "id": 1414556245, + "node_id": "R_kgDOVFBqVQ", + "name": "software-factory", + "full_name": "combsmith/software-factory", + "private": false, + "owner": { + "login": "combsmith", + "id": 258516906, + "node_id": "O_kgDOD2inqg", + "avatar_url": "https://avatars.githubusercontent.com/u/258516906?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/combsmith", + "html_url": "https://github.com/combsmith", + "followers_url": "https://api.github.com/users/combsmith/followers", + "following_url": "https://api.github.com/users/combsmith/following{/other_user}", + "gists_url": "https://api.github.com/users/combsmith/gists{/gist_id}", + "starred_url": "https://api.github.com/users/combsmith/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/combsmith/subscriptions", + "organizations_url": "https://api.github.com/users/combsmith/orgs", + "repos_url": "https://api.github.com/users/combsmith/repos", + "events_url": "https://api.github.com/users/combsmith/events{/privacy}", + "received_events_url": "https://api.github.com/users/combsmith/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/combsmith/software-factory", + "description": "The Factory's decision core: a pure, checkable Kernel over GitHub facts, with schemas, lifecycles and a simulator", + "fork": false, + "url": "https://api.github.com/repos/combsmith/software-factory", + "forks_url": "https://api.github.com/repos/combsmith/software-factory/forks", + "keys_url": "https://api.github.com/repos/combsmith/software-factory/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/combsmith/software-factory/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/combsmith/software-factory/teams", + "hooks_url": "https://api.github.com/repos/combsmith/software-factory/hooks", + "issue_events_url": "https://api.github.com/repos/combsmith/software-factory/issues/events{/number}", + "events_url": "https://api.github.com/repos/combsmith/software-factory/events", + "assignees_url": "https://api.github.com/repos/combsmith/software-factory/assignees{/user}", + "branches_url": "https://api.github.com/repos/combsmith/software-factory/branches{/branch}", + "tags_url": "https://api.github.com/repos/combsmith/software-factory/tags", + "blobs_url": "https://api.github.com/repos/combsmith/software-factory/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/combsmith/software-factory/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/combsmith/software-factory/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/combsmith/software-factory/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/combsmith/software-factory/statuses/{sha}", + "languages_url": "https://api.github.com/repos/combsmith/software-factory/languages", + "stargazers_url": "https://api.github.com/repos/combsmith/software-factory/stargazers", + "contributors_url": "https://api.github.com/repos/combsmith/software-factory/contributors", + "subscribers_url": "https://api.github.com/repos/combsmith/software-factory/subscribers", + "subscription_url": "https://api.github.com/repos/combsmith/software-factory/subscription", + "commits_url": "https://api.github.com/repos/combsmith/software-factory/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/combsmith/software-factory/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/combsmith/software-factory/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/combsmith/software-factory/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/combsmith/software-factory/contents/{+path}", + "compare_url": "https://api.github.com/repos/combsmith/software-factory/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/combsmith/software-factory/merges", + "archive_url": "https://api.github.com/repos/combsmith/software-factory/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/combsmith/software-factory/downloads", + "issues_url": "https://api.github.com/repos/combsmith/software-factory/issues{/number}", + "pulls_url": "https://api.github.com/repos/combsmith/software-factory/pulls{/number}", + "milestones_url": "https://api.github.com/repos/combsmith/software-factory/milestones{/number}", + "notifications_url": "https://api.github.com/repos/combsmith/software-factory/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/combsmith/software-factory/labels{/name}", + "releases_url": "https://api.github.com/repos/combsmith/software-factory/releases{/id}", + "deployments_url": "https://api.github.com/repos/combsmith/software-factory/deployments" + }, + "head_repository": { + "id": 1414556245, + "node_id": "R_kgDOVFBqVQ", + "name": "software-factory", + "full_name": "combsmith/software-factory", + "private": false, + "owner": { + "login": "combsmith", + "id": 258516906, + "node_id": "O_kgDOD2inqg", + "avatar_url": "https://avatars.githubusercontent.com/u/258516906?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/combsmith", + "html_url": "https://github.com/combsmith", + "followers_url": "https://api.github.com/users/combsmith/followers", + "following_url": "https://api.github.com/users/combsmith/following{/other_user}", + "gists_url": "https://api.github.com/users/combsmith/gists{/gist_id}", + "starred_url": "https://api.github.com/users/combsmith/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/combsmith/subscriptions", + "organizations_url": "https://api.github.com/users/combsmith/orgs", + "repos_url": "https://api.github.com/users/combsmith/repos", + "events_url": "https://api.github.com/users/combsmith/events{/privacy}", + "received_events_url": "https://api.github.com/users/combsmith/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/combsmith/software-factory", + "description": "The Factory's decision core: a pure, checkable Kernel over GitHub facts, with schemas, lifecycles and a simulator", + "fork": false, + "url": "https://api.github.com/repos/combsmith/software-factory", + "forks_url": "https://api.github.com/repos/combsmith/software-factory/forks", + "keys_url": "https://api.github.com/repos/combsmith/software-factory/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/combsmith/software-factory/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/combsmith/software-factory/teams", + "hooks_url": "https://api.github.com/repos/combsmith/software-factory/hooks", + "issue_events_url": "https://api.github.com/repos/combsmith/software-factory/issues/events{/number}", + "events_url": "https://api.github.com/repos/combsmith/software-factory/events", + "assignees_url": "https://api.github.com/repos/combsmith/software-factory/assignees{/user}", + "branches_url": "https://api.github.com/repos/combsmith/software-factory/branches{/branch}", + "tags_url": "https://api.github.com/repos/combsmith/software-factory/tags", + "blobs_url": "https://api.github.com/repos/combsmith/software-factory/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/combsmith/software-factory/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/combsmith/software-factory/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/combsmith/software-factory/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/combsmith/software-factory/statuses/{sha}", + "languages_url": "https://api.github.com/repos/combsmith/software-factory/languages", + "stargazers_url": "https://api.github.com/repos/combsmith/software-factory/stargazers", + "contributors_url": "https://api.github.com/repos/combsmith/software-factory/contributors", + "subscribers_url": "https://api.github.com/repos/combsmith/software-factory/subscribers", + "subscription_url": "https://api.github.com/repos/combsmith/software-factory/subscription", + "commits_url": "https://api.github.com/repos/combsmith/software-factory/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/combsmith/software-factory/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/combsmith/software-factory/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/combsmith/software-factory/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/combsmith/software-factory/contents/{+path}", + "compare_url": "https://api.github.com/repos/combsmith/software-factory/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/combsmith/software-factory/merges", + "archive_url": "https://api.github.com/repos/combsmith/software-factory/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/combsmith/software-factory/downloads", + "issues_url": "https://api.github.com/repos/combsmith/software-factory/issues{/number}", + "pulls_url": "https://api.github.com/repos/combsmith/software-factory/pulls{/number}", + "milestones_url": "https://api.github.com/repos/combsmith/software-factory/milestones{/number}", + "notifications_url": "https://api.github.com/repos/combsmith/software-factory/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/combsmith/software-factory/labels{/name}", + "releases_url": "https://api.github.com/repos/combsmith/software-factory/releases{/id}", + "deployments_url": "https://api.github.com/repos/combsmith/software-factory/deployments" + } + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/actions/runs/42348650504/jobs (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:07 GMT", + "etag": "W/\"ec80e42eaf52ca953f72278be11525c19fc9eb23aca20ab21f568e1c0778523b\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5AD:69339:25CA145:7D108BA:6AF13377", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4860", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "140" + }, + "body": { + "total_count": 1, + "jobs": [ + { + "id": 128331834219, + "run_id": 42348650504, + "workflow_name": "sf-release", + "head_branch": "main", + "run_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42348650504", + "run_attempt": 1, + "node_id": "CR_kwDOVFBqVc8AAAAd4Sxjaw", + "head_sha": "499835d5384ba81c466b17199edcde1848431630", + "url": "https://api.github.com/repos/combsmith/software-factory/actions/jobs/128331834219", + "html_url": "https://github.com/combsmith/software-factory/actions/runs/42348650504/job/128331834219", + "status": "completed", + "conclusion": "failure", + "created_at": "2026-11-07T06:49:10Z", + "started_at": "2026-11-07T06:49:13Z", + "completed_at": "2026-11-07T06:49:22Z", + "name": "release", + "steps": [ + { + "name": "Set up job", + "status": "completed", + "conclusion": "success", + "number": 1, + "started_at": "2026-11-07T06:49:13Z", + "completed_at": "2026-11-07T06:49:14Z" + }, + { + "status": "completed", + "conclusion": "success", + "number": 2, + "started_at": "2026-11-07T06:49:14Z", + "completed_at": "2026-11-07T06:49:15Z" + }, + { + "name": "Run actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1", + "status": "completed", + "conclusion": "success", + "number": 3, + "started_at": "2026-11-07T06:49:15Z", + "completed_at": "2026-11-07T06:49:16Z" + }, + { + "name": "Run python3 -m release.move", + "status": "completed", + "conclusion": "failure", + "number": 4, + "started_at": "2026-11-07T06:49:16Z", + "completed_at": "2026-11-07T06:49:19Z" + }, + { + "name": "Post Run actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1", + "status": "completed", + "conclusion": "success", + "number": 7, + "started_at": "2026-11-07T06:49:19Z", + "completed_at": "2026-11-07T06:49:19Z" + }, + { + "status": "completed", + "conclusion": "success", + "number": 8, + "started_at": "2026-11-07T06:49:19Z", + "completed_at": "2026-11-07T06:49:20Z" + }, + { + "name": "Complete job", + "status": "completed", + "conclusion": "success", + "number": 9, + "started_at": "2026-11-07T06:49:20Z", + "completed_at": "2026-11-07T06:49:20Z" + } + ], + "check_run_url": "https://api.github.com/repos/combsmith/software-factory/check-runs/128331834219", + "labels": [ + "ubuntu-24.04" + ], + "runner_id": 1000861596, + "runner_name": "GitHub Actions 1000861596", + "runner_group_id": 0, + "runner_group_name": "GitHub Actions" + } + ] + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/rulesets/25183656 (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:08 GMT", + "etag": "W/\"648b56872769b3d31cd03bc67d1226118a310ea183199970a1e3ea9475240d86\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "repo", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5B4:74C48:28141FF:84C01EF:6AF13377", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4859", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "141" + }, + "body": { + "id": 25183656, + "name": "factory release tags", + "target": "tag", + "source_type": "Repository", + "source": "combsmith/software-factory", + "enforcement": "active", + "conditions": { + "ref_name": { + "exclude": [], + "include": [ + "refs/tags/factory/*" + ] + } + }, + "rules": [ + { + "type": "creation" + }, + { + "type": "update" + }, + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + } + ], + "node_id": "RRS_lACqUmVwb3NpdG9yec5UUGpVzgGARag", + "created_at": "2026-10-15T12:48:45.102-05:00", + "updated_at": "2026-10-27T17:20:14.827-05:00", + "bypass_actors": [ + { + "actor_id": 5, + "actor_type": "RepositoryRole", + "bypass_mode": "always" + }, + { + "actor_id": 5502359, + "actor_type": "Integration", + "bypass_mode": "always" + } + ], + "current_user_can_bypass": "always", + "_links": { + "self": { + "href": "https://api.github.com/repos/combsmith/software-factory/rulesets/25183656" + }, + "html": { + "href": "https://github.com/combsmith/software-factory/rules/25183656" + } + } + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/rulesets/25996980 (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:44:08 GMT", + "etag": "W/\"9cc6ab334e24bc81a2283fb85622d7822e59473e165511d80efbd8dec6dbecbd\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "repo", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "E5B7:C3AC6:2621094:7ED0390:6AF13378", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4858", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "142" + }, + "body": { + "id": 25996980, + "name": "factory releases are immutable", + "target": "tag", + "source_type": "Repository", + "source": "combsmith/software-factory", + "enforcement": "active", + "conditions": { + "ref_name": { + "exclude": [], + "include": [ + "refs/tags/factory/v*.*.*" + ] + } + }, + "rules": [ + { + "type": "update" + }, + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + } + ], + "node_id": "RRS_lACqUmVwb3NpdG9yec5UUGpVzgGMrrQ", + "created_at": "2026-10-27T17:20:20.158-05:00", + "updated_at": "2026-10-27T17:20:20.208-05:00", + "bypass_actors": [], + "current_user_can_bypass": "never", + "_links": { + "self": { + "href": "https://api.github.com/repos/combsmith/software-factory/rulesets/25996980" + }, + "html": { + "href": "https://github.com/combsmith/software-factory/rules/25996980" + } + } + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/collaborators?affiliation=all&permission=admin (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 03:05:02 GMT", + "etag": "W/\"2eafd7d3befe4f79f525e75874707475db861abcb583f949d7210b5959c70aae\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "F89E:3E6302:79BB66:18E704E:6AF1385D", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4769", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "231" + }, + "body": [ + { + "login": "don-petry", + "id": 36422719, + "node_id": "MDQ6VXNlcjM2NDIyNzE5", + "avatar_url": "https://avatars.githubusercontent.com/u/36422719?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/don-petry", + "html_url": "https://github.com/don-petry", + "followers_url": "https://api.github.com/users/don-petry/followers", + "following_url": "https://api.github.com/users/don-petry/following{/other_user}", + "gists_url": "https://api.github.com/users/don-petry/gists{/gist_id}", + "starred_url": "https://api.github.com/users/don-petry/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/don-petry/subscriptions", + "organizations_url": "https://api.github.com/users/don-petry/orgs", + "repos_url": "https://api.github.com/users/don-petry/repos", + "events_url": "https://api.github.com/users/don-petry/events{/privacy}", + "received_events_url": "https://api.github.com/users/don-petry/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false, + "permissions": { + "admin": true, + "maintain": true, + "push": true, + "triage": true, + "pull": true + }, + "role_name": "admin" + } + ] + } + } + ], + "removed": [ + "exchanges[0].request.headers.authorization", + "exchanges[1].request.headers.authorization", + "exchanges[2].request.headers.authorization", + "exchanges[3].request.headers.authorization", + "exchanges[4].request.headers.authorization", + "exchanges[5].request.headers.authorization", + "exchanges[6].request.headers.authorization", + "exchanges[7].request.headers.authorization", + "exchanges[8].request.headers.authorization", + "exchanges[9].request.headers.authorization", + "exchanges[*].response.headers: every header but those a trial's fixture keeps, as tools/redact_trial.py reported them", + "exchanges[1].response.body.jobs[0].steps[1].name", + "exchanges[1].response.body.jobs[0].steps[5].name", + "exchanges[6].response.body.jobs[0].steps[1].name", + "exchanges[6].response.body.jobs[0].steps[5].name" + ], + "verdict": "pass" +} diff --git a/trials/P-63.json b/trials/P-63.json new file mode 100644 index 00000000..25a0c007 --- /dev/null +++ b/trials/P-63.json @@ -0,0 +1,776 @@ +{ + "schema": "trial/1", + "trial": "P-63", + "question": "Does the review Intent's eval job, run from main, read the private held-out home with its environment's secret and upload its eval-report/1 by hashes alone, and is that environment refused to every other branch?", + "pass": "The job reads and uploads on main, and the environment admits main alone with no admin bypass (section 6). As the story, #309, states it, under the Factory Builder's ruling of 2026-11-09, pre-approved by the Maintainer on 2026-11-08: run 42347416962 of .github/workflows/eval.yml, dispatched on main at its head, concluded success; its fetch step, the one step that reads the home with factory-eval's secret, succeeded, and so did its upload; its artifact eval-report is listed unexpired, and its archive's sha256 is the digest GitHub lists for it; the report names that run's commit, and its set's sha256, count and every case's id and sha256 are those evals/pr-review/cases.json holds at that commit. The environment factory-eval has one deployment branch policy, main, with protected_branches false and can_admins_bypass false, read live: that read stands in for the refusal of a dispatch from another branch. Residual, stated: no dispatch from another branch was exercised. The fixture holds hashes, codes and run metadata alone: no case's content, no case's verdict or reasons, and no secret, nor the list of the environment's secrets, which was not read.", + "repo": "combsmith/software-factory", + "ran_at": "2026-11-09T02:47:49Z", + "exchanges": [ + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/actions/runs/42347416962 (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:47:50 GMT", + "etag": "W/\"d301377f0758a8c4503318fbd0062dd0600047464aa4bfb24f4312a1215e9b27\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "EFB6:2A684F:5C4E9F:130F846:6AF13455", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4968", + "x-ratelimit-reset": "1794195922", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "32" + }, + "body": { + "id": 42347416962, + "name": "factory", + "node_id": "WFR_kwLOVFBqVc8AAAAJ3BpNgg", + "head_branch": "main", + "head_sha": "499835d5384ba81c466b17199edcde1848431630", + "path": ".github/workflows/eval.yml", + "display_title": "factory", + "run_number": 11, + "event": "workflow_dispatch", + "status": "completed", + "conclusion": "success", + "workflow_id": 399025209, + "check_suite_id": 114735810554, + "check_suite_node_id": "CS_kwDOVFBqVc8AAAAatsmH-g", + "url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42347416962", + "html_url": "https://github.com/combsmith/software-factory/actions/runs/42347416962", + "pull_requests": [], + "created_at": "2026-11-07T06:31:47Z", + "updated_at": "2026-11-07T06:47:45Z", + "actor": { + "login": "don-petry", + "id": 36422719, + "node_id": "MDQ6VXNlcjM2NDIyNzE5", + "avatar_url": "https://avatars.githubusercontent.com/u/36422719?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/don-petry", + "html_url": "https://github.com/don-petry", + "followers_url": "https://api.github.com/users/don-petry/followers", + "following_url": "https://api.github.com/users/don-petry/following{/other_user}", + "gists_url": "https://api.github.com/users/don-petry/gists{/gist_id}", + "starred_url": "https://api.github.com/users/don-petry/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/don-petry/subscriptions", + "organizations_url": "https://api.github.com/users/don-petry/orgs", + "repos_url": "https://api.github.com/users/don-petry/repos", + "events_url": "https://api.github.com/users/don-petry/events{/privacy}", + "received_events_url": "https://api.github.com/users/don-petry/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "run_attempt": 1, + "referenced_workflows": [], + "run_started_at": "2026-11-07T06:31:47Z", + "triggering_actor": { + "login": "don-petry", + "id": 36422719, + "node_id": "MDQ6VXNlcjM2NDIyNzE5", + "avatar_url": "https://avatars.githubusercontent.com/u/36422719?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/don-petry", + "html_url": "https://github.com/don-petry", + "followers_url": "https://api.github.com/users/don-petry/followers", + "following_url": "https://api.github.com/users/don-petry/following{/other_user}", + "gists_url": "https://api.github.com/users/don-petry/gists{/gist_id}", + "starred_url": "https://api.github.com/users/don-petry/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/don-petry/subscriptions", + "organizations_url": "https://api.github.com/users/don-petry/orgs", + "repos_url": "https://api.github.com/users/don-petry/repos", + "events_url": "https://api.github.com/users/don-petry/events{/privacy}", + "received_events_url": "https://api.github.com/users/don-petry/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "jobs_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42347416962/jobs", + "logs_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42347416962/logs", + "check_suite_url": "https://api.github.com/repos/combsmith/software-factory/check-suites/114735810554", + "artifacts_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42347416962/artifacts", + "cancel_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42347416962/cancel", + "rerun_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42347416962/rerun", + "previous_attempt_url": null, + "workflow_url": "https://api.github.com/repos/combsmith/software-factory/actions/workflows/399025209", + "head_commit": { + "id": "499835d5384ba81c466b17199edcde1848431630", + "tree_id": "fe2a466d35ef359b8cf55e1ea322d01e982ddcf2", + "message": "The artifact storage is any productionresults account numbered in one to three digits (record 0151) (#598)\n\n* The artifact storage is any productionresults account numbered in one to three digits (record NNNN)\n\nThe cut of factory/v0.1.0 was refused with eval_gate_closed: the eval\nreport's download redirected to productionresultssa32, which the\ntransport's STORAGE pattern, sa0 to sa19 by decision 0045, refused, so\nthe report was read as unanswered. By the Maintainer's ruling, the\nstorage is productionresultssa and one to three digits, with no leading\nzero; the rest of 0045's row stands.\n\n- STORAGE in adapters/github.py widened, and a boundary test: sa0 to\n sa999 accepted; sa1000, a leading zero, a letter or non-ASCII digit\n in the number, another account name and another host refused.\n- Mutants: a fourth digit, a stop at sa99 or sa19, a leading zero, a\n trailing letter, Unicode digits, and any account name.\n- Record NNNN replaces 0147, the one record in force of those that hold\n 0045's rows (0045, then 0138, then 0147), and overturns only the\n accounts 0045's row names. 0147's Status says it is replaced.\n\nEvery artifact read through the redirect, a Run's outcome, a Lens's\napplied/1, the pass records and the eval report, had the same latent\nfailure whenever GitHub served it past sa19.\n\nCo-Authored-By: Claude Opus 5.5 \n\n* Fix round 1 on record 0151: no mutant that no test can kill, and the record named\n\n- The mutant giving the storage's number any Unicode digit is dropped:\n storage() refuses a URL that is not ASCII before STORAGE is read, so\n no test can tell it from the code. The record's row no longer claims\n it (the security pass, the Claude review, Astra and Argon).\n- The record says that every account from sa0 to sa999 being GitHub's\n is assumed, not known, and what the ruling accepts in it (the\n security pass).\n- The record says a leading zero is refused, narrower than the ruling,\n since GitHub's names have none (the Factory Builder).\n- NNNN is 0151, the Factory Builder's number, everywhere (Argon).\n\nCo-Authored-By: Claude Opus 5.5 \n\n---------\n\nCo-authored-by: Claude Opus 5.5 ", + "timestamp": "2026-11-07T06:03:10Z", + "author": { + "name": "Don Petry", + "email": "36422719+don-petry@users.noreply.github.com" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com" + } + }, + "repository": { + "id": 1414556245, + "node_id": "R_kgDOVFBqVQ", + "name": "software-factory", + "full_name": "combsmith/software-factory", + "private": false, + "owner": { + "login": "combsmith", + "id": 258516906, + "node_id": "O_kgDOD2inqg", + "avatar_url": "https://avatars.githubusercontent.com/u/258516906?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/combsmith", + "html_url": "https://github.com/combsmith", + "followers_url": "https://api.github.com/users/combsmith/followers", + "following_url": "https://api.github.com/users/combsmith/following{/other_user}", + "gists_url": "https://api.github.com/users/combsmith/gists{/gist_id}", + "starred_url": "https://api.github.com/users/combsmith/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/combsmith/subscriptions", + "organizations_url": "https://api.github.com/users/combsmith/orgs", + "repos_url": "https://api.github.com/users/combsmith/repos", + "events_url": "https://api.github.com/users/combsmith/events{/privacy}", + "received_events_url": "https://api.github.com/users/combsmith/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/combsmith/software-factory", + "description": "The Factory's decision core: a pure, checkable Kernel over GitHub facts, with schemas, lifecycles and a simulator", + "fork": false, + "url": "https://api.github.com/repos/combsmith/software-factory", + "forks_url": "https://api.github.com/repos/combsmith/software-factory/forks", + "keys_url": "https://api.github.com/repos/combsmith/software-factory/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/combsmith/software-factory/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/combsmith/software-factory/teams", + "hooks_url": "https://api.github.com/repos/combsmith/software-factory/hooks", + "issue_events_url": "https://api.github.com/repos/combsmith/software-factory/issues/events{/number}", + "events_url": "https://api.github.com/repos/combsmith/software-factory/events", + "assignees_url": "https://api.github.com/repos/combsmith/software-factory/assignees{/user}", + "branches_url": "https://api.github.com/repos/combsmith/software-factory/branches{/branch}", + "tags_url": "https://api.github.com/repos/combsmith/software-factory/tags", + "blobs_url": "https://api.github.com/repos/combsmith/software-factory/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/combsmith/software-factory/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/combsmith/software-factory/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/combsmith/software-factory/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/combsmith/software-factory/statuses/{sha}", + "languages_url": "https://api.github.com/repos/combsmith/software-factory/languages", + "stargazers_url": "https://api.github.com/repos/combsmith/software-factory/stargazers", + "contributors_url": "https://api.github.com/repos/combsmith/software-factory/contributors", + "subscribers_url": "https://api.github.com/repos/combsmith/software-factory/subscribers", + "subscription_url": "https://api.github.com/repos/combsmith/software-factory/subscription", + "commits_url": "https://api.github.com/repos/combsmith/software-factory/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/combsmith/software-factory/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/combsmith/software-factory/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/combsmith/software-factory/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/combsmith/software-factory/contents/{+path}", + "compare_url": "https://api.github.com/repos/combsmith/software-factory/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/combsmith/software-factory/merges", + "archive_url": "https://api.github.com/repos/combsmith/software-factory/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/combsmith/software-factory/downloads", + "issues_url": "https://api.github.com/repos/combsmith/software-factory/issues{/number}", + "pulls_url": "https://api.github.com/repos/combsmith/software-factory/pulls{/number}", + "milestones_url": "https://api.github.com/repos/combsmith/software-factory/milestones{/number}", + "notifications_url": "https://api.github.com/repos/combsmith/software-factory/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/combsmith/software-factory/labels{/name}", + "releases_url": "https://api.github.com/repos/combsmith/software-factory/releases{/id}", + "deployments_url": "https://api.github.com/repos/combsmith/software-factory/deployments" + }, + "head_repository": { + "id": 1414556245, + "node_id": "R_kgDOVFBqVQ", + "name": "software-factory", + "full_name": "combsmith/software-factory", + "private": false, + "owner": { + "login": "combsmith", + "id": 258516906, + "node_id": "O_kgDOD2inqg", + "avatar_url": "https://avatars.githubusercontent.com/u/258516906?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/combsmith", + "html_url": "https://github.com/combsmith", + "followers_url": "https://api.github.com/users/combsmith/followers", + "following_url": "https://api.github.com/users/combsmith/following{/other_user}", + "gists_url": "https://api.github.com/users/combsmith/gists{/gist_id}", + "starred_url": "https://api.github.com/users/combsmith/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/combsmith/subscriptions", + "organizations_url": "https://api.github.com/users/combsmith/orgs", + "repos_url": "https://api.github.com/users/combsmith/repos", + "events_url": "https://api.github.com/users/combsmith/events{/privacy}", + "received_events_url": "https://api.github.com/users/combsmith/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/combsmith/software-factory", + "description": "The Factory's decision core: a pure, checkable Kernel over GitHub facts, with schemas, lifecycles and a simulator", + "fork": false, + "url": "https://api.github.com/repos/combsmith/software-factory", + "forks_url": "https://api.github.com/repos/combsmith/software-factory/forks", + "keys_url": "https://api.github.com/repos/combsmith/software-factory/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/combsmith/software-factory/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/combsmith/software-factory/teams", + "hooks_url": "https://api.github.com/repos/combsmith/software-factory/hooks", + "issue_events_url": "https://api.github.com/repos/combsmith/software-factory/issues/events{/number}", + "events_url": "https://api.github.com/repos/combsmith/software-factory/events", + "assignees_url": "https://api.github.com/repos/combsmith/software-factory/assignees{/user}", + "branches_url": "https://api.github.com/repos/combsmith/software-factory/branches{/branch}", + "tags_url": "https://api.github.com/repos/combsmith/software-factory/tags", + "blobs_url": "https://api.github.com/repos/combsmith/software-factory/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/combsmith/software-factory/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/combsmith/software-factory/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/combsmith/software-factory/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/combsmith/software-factory/statuses/{sha}", + "languages_url": "https://api.github.com/repos/combsmith/software-factory/languages", + "stargazers_url": "https://api.github.com/repos/combsmith/software-factory/stargazers", + "contributors_url": "https://api.github.com/repos/combsmith/software-factory/contributors", + "subscribers_url": "https://api.github.com/repos/combsmith/software-factory/subscribers", + "subscription_url": "https://api.github.com/repos/combsmith/software-factory/subscription", + "commits_url": "https://api.github.com/repos/combsmith/software-factory/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/combsmith/software-factory/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/combsmith/software-factory/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/combsmith/software-factory/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/combsmith/software-factory/contents/{+path}", + "compare_url": "https://api.github.com/repos/combsmith/software-factory/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/combsmith/software-factory/merges", + "archive_url": "https://api.github.com/repos/combsmith/software-factory/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/combsmith/software-factory/downloads", + "issues_url": "https://api.github.com/repos/combsmith/software-factory/issues{/number}", + "pulls_url": "https://api.github.com/repos/combsmith/software-factory/pulls{/number}", + "milestones_url": "https://api.github.com/repos/combsmith/software-factory/milestones{/number}", + "notifications_url": "https://api.github.com/repos/combsmith/software-factory/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/combsmith/software-factory/labels{/name}", + "releases_url": "https://api.github.com/repos/combsmith/software-factory/releases{/id}", + "deployments_url": "https://api.github.com/repos/combsmith/software-factory/deployments" + } + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/actions/runs/42347416962/jobs (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:47:50 GMT", + "etag": "W/\"52a9e33fcb9cb5726e12f0a42e0ad2e85a0a573b98c1dbfd1e7b88a229dadeb3\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "EFB8:10630A:17F68C3:4EA9D85:6AF13456", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4834", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "166" + }, + "body": { + "total_count": 1, + "jobs": [ + { + "id": 128328058214, + "run_id": 42347416962, + "workflow_name": "factory", + "head_branch": "main", + "run_url": "https://api.github.com/repos/combsmith/software-factory/actions/runs/42347416962", + "run_attempt": 1, + "node_id": "CR_kwDOVFBqVc8AAAAd4PLFZg", + "head_sha": "499835d5384ba81c466b17199edcde1848431630", + "url": "https://api.github.com/repos/combsmith/software-factory/actions/jobs/128328058214", + "html_url": "https://github.com/combsmith/software-factory/actions/runs/42347416962/job/128328058214", + "status": "completed", + "conclusion": "success", + "created_at": "2026-11-07T06:31:48Z", + "started_at": "2026-11-07T06:31:53Z", + "completed_at": "2026-11-07T06:47:45Z", + "name": "eval", + "steps": [ + { + "name": "Set up job", + "status": "completed", + "conclusion": "success", + "number": 1, + "started_at": "2026-11-07T06:31:54Z", + "completed_at": "2026-11-07T06:31:55Z" + }, + { + "name": "Run actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1", + "status": "completed", + "conclusion": "success", + "number": 2, + "started_at": "2026-11-07T06:31:55Z", + "completed_at": "2026-11-07T06:31:57Z" + }, + { + "name": "Run python3 -m harness.eval.plan", + "status": "completed", + "conclusion": "success", + "number": 3, + "started_at": "2026-11-07T06:31:57Z", + "completed_at": "2026-11-07T06:31:57Z" + }, + { + "name": "Run url=\"https://downloads.claude.ai/claude-code-releases/${CLI_VERSION}/linux-x64/claude\"", + "status": "completed", + "conclusion": "success", + "number": 4, + "started_at": "2026-11-07T06:31:57Z", + "completed_at": "2026-11-07T06:32:13Z" + }, + { + "name": "Run python3 -m harness.eval.fetch", + "status": "completed", + "conclusion": "success", + "number": 5, + "started_at": "2026-11-07T06:32:13Z", + "completed_at": "2026-11-07T06:33:09Z" + }, + { + "name": "Run python3 -m harness.eval.run", + "status": "completed", + "conclusion": "success", + "number": 6, + "started_at": "2026-11-07T06:33:09Z", + "completed_at": "2026-11-07T06:47:40Z" + }, + { + "name": "Run actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9", + "status": "completed", + "conclusion": "success", + "number": 7, + "started_at": "2026-11-07T06:47:40Z", + "completed_at": "2026-11-07T06:47:42Z" + }, + { + "name": "Run python3 -m harness.eval.judge", + "status": "completed", + "conclusion": "success", + "number": 8, + "started_at": "2026-11-07T06:47:42Z", + "completed_at": "2026-11-07T06:47:42Z" + }, + { + "name": "Post Run actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1", + "status": "completed", + "conclusion": "success", + "number": 16, + "started_at": "2026-11-07T06:47:42Z", + "completed_at": "2026-11-07T06:47:42Z" + }, + { + "name": "Complete job", + "status": "completed", + "conclusion": "success", + "number": 17, + "started_at": "2026-11-07T06:47:42Z", + "completed_at": "2026-11-07T06:47:42Z" + } + ], + "check_run_url": "https://api.github.com/repos/combsmith/software-factory/check-runs/128328058214", + "labels": [ + "ubuntu-24.04" + ], + "runner_id": 1000861580, + "runner_name": "GitHub Actions 1000861580", + "runner_group_id": 0, + "runner_group_name": "GitHub Actions" + } + ] + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/actions/runs/42347416962/artifacts (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:47:51 GMT", + "etag": "W/\"2ad4baf1a85f7e83f7a69b675b93392c88cad5fd08535393694feb89b0f10519\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "EFC4:1EBD87:59E026:1295008:6AF13457", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4967", + "x-ratelimit-reset": "1794195922", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "33" + }, + "body": { + "total_count": 1, + "artifacts": [ + { + "id": 13564174523, + "node_id": "MDg6QXJ0aWZhY3QxMzU2NDE3NDUyMw==", + "name": "eval-report", + "size_in_bytes": 2401, + "url": "https://api.github.com/repos/combsmith/software-factory/actions/artifacts/13564174523", + "archive_download_url": "https://api.github.com/repos/combsmith/software-factory/actions/artifacts/13564174523/zip", + "expired": false, + "digest": "sha256:424a77993f66f0194164691ee84f194b7dc3a84fac4c8de55e683ed8bb2ac477", + "created_at": "2026-11-07T06:47:42Z", + "updated_at": "2026-11-07T06:47:42Z", + "expires_at": "2027-02-05T06:31:48Z", + "workflow_run": { + "id": 42347416962, + "repository_id": 1414556245, + "head_repository_id": 1414556245, + "head_branch": "main", + "head_sha": "499835d5384ba81c466b17199edcde1848431630" + } + } + ] + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/environments/factory-eval (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:47:51 GMT", + "etag": "W/\"d4d8a34a68319f41c1c60ab8db85842a93f0e59d26049228f8da75a3578c6b26\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "EFCD:1A872E:622349:1434F21:6AF13457", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4833", + "x-ratelimit-reset": "1794194503", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "167" + }, + "body": { + "id": 25082210981, + "node_id": "EN_kwDOVFBqVc8AAAAF1wQqpQ", + "name": "factory-eval", + "url": "https://api.github.com/repos/combsmith/software-factory/environments/factory-eval", + "html_url": "https://github.com/combsmith/software-factory/deployments/activity_log?environments_filter=factory-eval", + "created_at": "2026-10-23T00:03:49Z", + "updated_at": "2026-10-31T12:28:37Z", + "can_admins_bypass": false, + "protection_rules": [ + { + "id": 69789960, + "node_id": "GA_kwDOVFBqVc4EKOkI", + "type": "branch_policy" + } + ], + "deployment_branch_policy": { + "protected_branches": false, + "custom_branch_policies": true + } + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/environments/factory-eval/deployment-branch-policies (gh api --include)", + "headers": { + "accept": "application/vnd.github+json" + }, + "body": null + }, + "response": { + "status": 200, + "headers": { + "cache-control": "private, max-age=60, s-maxage=60", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 09 Nov 2026 02:47:52 GMT", + "etag": "W/\"452a4f8665642e0d8d9798a2ff884da259d53b147720546ae4f5fe083d925285\"", + "server": "github.com", + "vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "x-accepted-oauth-scopes": "", + "x-github-media-type": "github.v3; format=json", + "x-github-request-id": "EFD4:F1DDD:6294AB:14354B6:6AF13458", + "x-ratelimit-limit": "5000", + "x-ratelimit-remaining": "4966", + "x-ratelimit-reset": "1794195922", + "x-ratelimit-resource": "core", + "x-ratelimit-used": "34" + }, + "body": { + "total_count": 1, + "branch_policies": [ + { + "id": 64032716, + "node_id": "MDE2OkdhdGVCcmFuY2hQb2xpY3k2NDAzMjcxNg==", + "name": "main", + "type": "branch" + } + ] + } + } + }, + { + "request": { + "as": { + "kind": "person", + "name": "don-petry" + }, + "via": "rest", + "call": "GET /repos/combsmith/software-factory/actions/artifacts/13564174523/zip (gh api), then eval-report.json from the archive", + "headers": {}, + "body": null + }, + "response": { + "status": 200, + "headers": {}, + "body": { + "schema": "eval-report/1", + "release": "factory/v0.1.0", + "commit": "499835d5384ba81c466b17199edcde1848431630", + "role": "pr-review", + "intent": "review-change", + "set": { + "count": 40, + "sha256": "d3c5f6948f29fc9671d561451b5168dc702f7d3eb490e4e96ab157f53f4b1e78" + }, + "passed": 27, + "split_ok": true, + "kinds_pass": { + "finding": true, + "met": true + }, + "blocking_pass": false, + "cases": [ + { + "id": "c-03001d0ac7", + "sha256": "722383b5dabb44ed814b2e92f283da930696d7df386eb79786cc61db36330831" + }, + { + "id": "c-0e86f5fc22", + "sha256": "19aa05280de6191c9f80f3d42948550d5ceea55b2b19761277f612752540bb17" + }, + { + "id": "c-1086f48fc6", + "sha256": "66c17838f023e605df0454580bb0194d6cf1325b0b9ec4e530888d0aca308dca" + }, + { + "id": "c-112c141fa2", + "sha256": "0309f80665a1c00d13a1b1d0d95f62e184b4d2129b9f702c61cb3504415a9001" + }, + { + "id": "c-156a9804a4", + "sha256": "40a62e77243c8d818b1129ac0a9dcbdcb935ff42a0186e582466f7f63ee6033d" + }, + { + "id": "c-19f9af3c0c", + "sha256": "197a9d56737b26f7b8934a19fe94b415467780b6d225a7b1e66b139080356eb9" + }, + { + "id": "c-1fa281dc88", + "sha256": "5ac983dde1a7f595006536d41bd8fd12ca739d7aa10c6a2a135a099a5da3624c" + }, + { + "id": "c-2535ca2034", + "sha256": "fc02ce24ac226253631308ee8e772789404fe16f02b3bf46a7800c7ad91225b1" + }, + { + "id": "c-341d7de0f3", + "sha256": "5ae6e426e2d003eec2bab5048f37d62bacf84e1d9c7504b07002f44ba8c6ef4e" + }, + { + "id": "c-3b948311d8", + "sha256": "8badb7f9480cfe616bdf631d98325b90590b564f5cd74696d5e5f2f6c6880d22" + }, + { + "id": "c-4856bdd4cd", + "sha256": "a1a7d5f298f099291655d5f1c8ffef0be40539af608fb51d2efa9b2e6ff09234" + }, + { + "id": "c-4e89c21afb", + "sha256": "48e8637060cf91f9c4efe99192225a67b3ed7df55c99d6083943b1b2b3bcbb2c" + }, + { + "id": "c-5d9a106007", + "sha256": "cec6695bf98d52b47c8f3f92d11ad7e6e66da12ee6ecc89a8afadbfebc2c5c45" + }, + { + "id": "c-5e3ccca66b", + "sha256": "1e420bb4812980dcbe16aca95f12d74f3d54e82cb961d621aa24c979c943f433" + }, + { + "id": "c-629607c640", + "sha256": "accc8059f39b8510cfae91c201efbc40aa319be8a25715f269b82f2b52d2b27f" + }, + { + "id": "c-65c4fb026c", + "sha256": "d862ec8366b975911a1c94378e649ad80541fcbad45016c34e574cd2fedac5a1" + }, + { + "id": "c-696a4afcbb", + "sha256": "e62f890d84415f31c913a8c02dd5dc62858a0e770c23a79747e112dfcc51ef4f" + }, + { + "id": "c-7cc5e3b76e", + "sha256": "8862e1f78c51bd5f6976a43bae744ec5daede393378103b2b3d529b222c2fd30" + }, + { + "id": "c-7e086eff25", + "sha256": "1acc8ee19277be4860d8222bbb8238ca2cab032a27a5a1d0f8288860aeca28ec" + }, + { + "id": "c-83e5605cde", + "sha256": "9945a36b8db58fbf3023ab4109c9a10b9aa0f60eb204eeab46d1896852b2a626" + }, + { + "id": "c-8597d2df44", + "sha256": "04f4488ce42cc7ffdfa917ad16e36e462d0c85488babbe73baf2e3198582e448" + }, + { + "id": "c-8622ff7ce7", + "sha256": "b9f420a14547a5f6f40283ec251ddc3202a8fb4ea8174e10f26b5d9cb0b7cebb" + }, + { + "id": "c-9d95157d56", + "sha256": "5cc5063a3816f27ba0a533dcbe8ffcbba42d926e172b922c0eef0c816e75c2ae" + }, + { + "id": "c-a04bab24a3", + "sha256": "4cd6740187e5ec99e7b5b1dec0ff0eed388ba5d4dcc82d1095245620dbb7967e" + }, + { + "id": "c-a74e26e829", + "sha256": "ebdf7bdb81f463f5739f94343e25bb5fee366bcae99c7119007f038ae4c2cd4a" + }, + { + "id": "c-ba2a56f909", + "sha256": "28ff9e6dd41eef5c8d43d03a9714045e30f3ecde932c850564cfa545edde9a58" + }, + { + "id": "c-c7a0ce7ad6", + "sha256": "21df46a8284426d4c85d14556b81b7f25b0524e14b13aeea45fddf75ea06ca25" + }, + { + "id": "c-d220f12a06", + "sha256": "64bb7b2208f4ba1bef3cd6ccee4e6e5c83d0ced268bf1c0de7ae2c2c0a9f6336" + }, + { + "id": "c-d2f6619578", + "sha256": "7a30141ac5142c692a86692a5ee6fc7af932e2fac7bbebded9a1e422c159d634" + }, + { + "id": "c-d4d2c3b815", + "sha256": "174ced775b4bfbee643a31f466e33f22615d8e2a66072fab42c359a79721cc6f" + }, + { + "id": "c-dfbcb7c5e3", + "sha256": "f1049d609866542f379e1d9c735a9c42025620395fac034731814e1d0948e9e7" + }, + { + "id": "c-eeef0dbc38", + "sha256": "07c276d32a62a7a9f456f50273e4aa88467c45c45c1fd03a2cad75474d1abd3c" + }, + { + "id": "c-f03e3140e2", + "sha256": "a2c551bea3de2c5be31486be3098f5d8825839b7ba51ebf80d524a177fd5f4d8" + }, + { + "id": "c-f0c1654aac", + "sha256": "63e121eda8b6fed01cdf905d6a467934b4deadef6dfc44d0ba4688bb12cc089b" + }, + { + "id": "c-f12afe0d46", + "sha256": "7a03955a6b87afdc94d6ff681db9c623f29fe04c11c8fd5781a2185f58f0b65f" + }, + { + "id": "c-f16f7b1116", + "sha256": "1f9905d33ba97cf6e5976f77be5fab1e81b1cae860a44f6c23486cbe0614b1ee" + }, + { + "id": "c-f514bb30ad", + "sha256": "d8ada959bffcdb698def6a5ec94bd5e2b950c6ddb3709fe9fc01414de192ef2b" + }, + { + "id": "c-f8c15181eb", + "sha256": "38dd1068b6806cef8d99ad44106af925c0846753283621f37836930280d7d2e0" + }, + { + "id": "c-fb542b569f", + "sha256": "ea5359a9166b91a94bdc44175a5830c850b07e8f4820b389c9efc8d427b1fecd" + }, + { + "id": "c-fcd4fa9aca", + "sha256": "2628a7f593a950cc14984b1363bd1a42b9f07219e7442591023f3b14f377647b" + } + ] + } + } + } + ], + "removed": [ + "exchanges[0].request.headers.authorization", + "exchanges[1].request.headers.authorization", + "exchanges[2].request.headers.authorization", + "exchanges[3].request.headers.authorization", + "exchanges[4].request.headers.authorization", + "exchanges[5].request.headers.authorization", + "exchanges[*].response.headers: every header but those a trial's fixture keeps, as tools/redact_trial.py reported them; of exchanges[5], every header, since the archive was read as a file", + "exchanges[5].response.body: the zip archive itself, whose sha256 is the artifact's digest in exchanges[2]; of the eval-report.json it holds, each case's verdict, reasons and at_alternate, so that no case is told by its kind, and no case's content, which the report never holds" + ], + "verdict": "pass" +}