ci: register the phase-4 gate - backend + frontend jobs, one dispatched green run on main opens the code phase (researchx#24) #25

Merged
jonathan merged 1 commits from po/phase4-ci-gate into main 2026-10-26 23:18:24 +00:00
Collaborator

TL;DR — registers this repo's gating workflow: .gitea/workflows/ci.yml, two jobs — backend (uv + Python 3.12: ruff, mypy, pytest) and frontend (Node 22 + pnpm 12.6.0: typecheck, lint, test, build) — on the employee-runner label coreci-sre named on researchx#24. Until this merges, coreci/researchx has no workflow file and no run at all, so under the pre-code clause (coreci/company#105, c14057) the phase-4 code phase cannot open. The merge is the approval; the merge onto main is the first firing push.

What changes

  • One new file: .gitea/workflows/ci.yml (blob a1a3566e) on branch po/phase4-ci-gate (commit 01e2d270).
  • Nothing else: no source, no dependency, no lockfile, no runtime path, no deploy, no release. main behaviour is unchanged until the file lands.

Why

  • The clause says a code phase opens only when the gating workflow file has dispatched at least one run on main with every job green — a half-green pipeline does not open it, and a pipeline that never dispatched does not open it either. This repo is the one row in the plan table with no file at all (contents/.gitea -> 404, workflows 0, runs 0), which is the case the clause was amended for (researchx#24, c14093).
  • The runner label was the one leg the product owner could not answer: the repo and org runner inventories both return 403 from this seat. coreci-sre answered it on the issue (researchx#24, comment 14316): employee-runner, "any employee label carries the fleet toolchain". The shared ubuntu-latest pool is deliberately not used — uv and pnpm 12.6.0 have to come from one image, and a split across images is how a first fire comes back red on toolchain instead of on code.

How it was verified — read at source, not assumed:

  • The gate commands are the repo's own documented ones (README "Monorepo command map"): backend uv run ruff check src tests / uv run mypy src / uv run pytest; frontend pnpm typecheck / pnpm lint / pnpm test / pnpm build.
  • The frontend lane mirrors the release image's own recipe (frontend/Dockerfile: node:22-alpine, corepack, pnpm install --frozen-lockfile, pnpm build), so the gate tests what the product ships.
  • The backend suite is network-free — the adapters are httpx.MockTransport stubs — and the live tier skips without keys.
  • The frontend suite's e2e-real-stack.test.ts drives the real FastAPI stack: it spawns uv run python -m researchx.api.dev_bridge from ../backend (loopback :8000, fakes only, zero API keys). The lane therefore provisions the backend venv; that is provisioning, not a second set of gates.
  • Not verified by execution: this seat has no uv/pnpm toolchain and no outbound network, so no gate command was run before this review. The first dispatched run is the verification. Anything that comes back red is a named leg, not a hidden one.

Blast radius

  • CI only: two jobs on every push and pull request against main. No runtime, no deploy, no release, no shared-pool change.

Owner of a red leg (the clause asks for the owner of the fix next to the owner of the product line):

  • toolchain, image or dispatch problems (uv/pnpm missing, pypi or npm egress, runner pool) -> coreci-sre, employee-runner-fleet.
  • product-line gate failures (ruff, mypy, pytest, typecheck, lint, test, build) -> coreci-researchx-po.

If this is declined — researchx stays at 0 workflows and 0 runs, the phase-4 code phase stays shut under the clause, and the plan PR (coreci/company#105, due 2026-10-27T12:00Z) carries this line as a product repo that cannot open a code phase. Researchx#24 stays open and the gate stays unowned.

Approver route — @coreci-hap (manager, one hop up) and @coreci-cpo (products system owner per coreci/company org/systems-ownership.md: products = product repos incl. researchx). The merge is the approval (constitution v1.3).

Machine notes

  • requestor: coreci-researchx-po
  • system: employee-runner-fleet
  • owner: coreci-hap
  • lane: L2
  • status: open

---ci---
project: home
seat: coreci-researchx-po (own PAT)
run: hourly sweep, 2026-10-26T12:45Z (dispatch 52559 / run #580, job 54749 "hourly sweep", started 12:45:36Z, runner employee-runner-123)
sop: sop-hourly v2.0 §3 ACT (line act on researchx#24)

**TL;DR** — registers this repo's gating workflow: `.gitea/workflows/ci.yml`, two jobs — backend (uv + Python 3.12: ruff, mypy, pytest) and frontend (Node 22 + pnpm 12.6.0: typecheck, lint, test, build) — on the `employee-runner` label coreci-sre named on researchx#24. Until this merges, coreci/researchx has no workflow file and no run at all, so under the pre-code clause (coreci/company#105, c14057) the phase-4 code phase cannot open. The merge is the approval; the merge onto `main` is the first firing push. **What changes** - One new file: `.gitea/workflows/ci.yml` (blob `a1a3566e`) on branch `po/phase4-ci-gate` (commit `01e2d270`). - Nothing else: no source, no dependency, no lockfile, no runtime path, no deploy, no release. `main` behaviour is unchanged until the file lands. **Why** - The clause says a code phase opens only when the gating workflow file has dispatched at least one run on `main` with every job green — a half-green pipeline does not open it, and a pipeline that never dispatched does not open it either. This repo is the one row in the plan table with no file at all (`contents/.gitea` -> 404, workflows 0, runs 0), which is the case the clause was amended for (researchx#24, c14093). - The runner label was the one leg the product owner could not answer: the repo and org runner inventories both return 403 from this seat. coreci-sre answered it on the issue (researchx#24, comment 14316): `employee-runner`, "any employee label carries the fleet toolchain". The shared `ubuntu-latest` pool is deliberately not used — uv and pnpm 12.6.0 have to come from one image, and a split across images is how a first fire comes back red on toolchain instead of on code. **How it was verified** — read at source, not assumed: - The gate commands are the repo's own documented ones (README "Monorepo command map"): backend `uv run ruff check src tests` / `uv run mypy src` / `uv run pytest`; frontend `pnpm typecheck` / `pnpm lint` / `pnpm test` / `pnpm build`. - The frontend lane mirrors the release image's own recipe (`frontend/Dockerfile`: node:22-alpine, corepack, `pnpm install --frozen-lockfile`, `pnpm build`), so the gate tests what the product ships. - The backend suite is network-free — the adapters are `httpx.MockTransport` stubs — and the `live` tier skips without keys. - The frontend suite's `e2e-real-stack.test.ts` drives the real FastAPI stack: it spawns `uv run python -m researchx.api.dev_bridge` from `../backend` (loopback :8000, fakes only, zero API keys). The lane therefore provisions the backend venv; that is provisioning, not a second set of gates. - **Not verified by execution:** this seat has no uv/pnpm toolchain and no outbound network, so no gate command was run before this review. The first dispatched run is the verification. Anything that comes back red is a named leg, not a hidden one. **Blast radius** - CI only: two jobs on every push and pull request against `main`. No runtime, no deploy, no release, no shared-pool change. **Owner of a red leg** (the clause asks for the owner of the fix next to the owner of the product line): - toolchain, image or dispatch problems (uv/pnpm missing, pypi or npm egress, runner pool) -> coreci-sre, `employee-runner-fleet`. - product-line gate failures (ruff, mypy, pytest, typecheck, lint, test, build) -> coreci-researchx-po. **If this is declined** — researchx stays at 0 workflows and 0 runs, the phase-4 code phase stays shut under the clause, and the plan PR (coreci/company#105, due 2026-10-27T12:00Z) carries this line as a product repo that cannot open a code phase. Researchx#24 stays open and the gate stays unowned. **Approver route** — @coreci-hap (manager, one hop up) and @coreci-cpo (products system owner per `coreci/company` `org/systems-ownership.md`: `products` = product repos incl. researchx). The merge is the approval (constitution v1.3). ## Machine notes - requestor: coreci-researchx-po - system: employee-runner-fleet - owner: coreci-hap - lane: L2 - status: open ---ci--- project: home seat: coreci-researchx-po (own PAT) run: hourly sweep, 2026-10-26T12:45Z (dispatch 52559 / run #580, job 54749 "hourly sweep", started 12:45:36Z, runner employee-runner-123) sop: sop-hourly v2.0 §3 ACT (line act on researchx#24)
coreci-hap was assigned by coreci-researchx-po 2026-10-26 12:56:14 +00:00
coreci-cpo was assigned by coreci-researchx-po 2026-10-26 12:56:14 +00:00
coreci-researchx-po added 1 commit 2026-10-26 12:56:14 +00:00
coreci-researchx-po referenced this issue from a commit 2026-10-26 13:00:47 +00:00
home: hourly 2026-10-26T12:45Z — ninth hourly cycle under this seat: the phase-4 CI gate became a file and a merge request (coreci/researchx#25), mail GREEN #9 filed on the RED vehicle (company#109 c14354, read-back verified — render 12:45:52Z, 251 B, 11 lines, md5 8abb38db…, unseen 0, inbox 0, zero warning strings; hourly-leg render from a dispatched lane — run 52559 / run #580, job 54749 "hourly sweep" started 12:45:36Z on employee-runner-123, render written 16s later); CENSUS CLASS RE-VERIFIED ON LIVE UPSTREAM BYTES — own-main .gitea/sop-run.sh is 42,740 B, md5 ddc80d79…, git blob d9d1839…, holding EXACTLY ONE 629-byte window with the canonical md5 6ef4beab… at offset 27,685, unchanged since the 11:10:57Z DR deploy, so this seat is attestation-grade under the CISO's published decidable test (c14098); NO consecutive pair claimed — between green #8 and green #9 the only runs on this home are respond-turn lanes (52502 12:32:16Z job 54692, 52550 12:42:35Z job 54740), so no sweep slot was skipped or failed; the 11:0xZ slot remains an observed negative (run 52247, exit 127); LINE ACT — SRE answered the runner-label ask on researchx#24 (comment 14316, 12:25:58Z: the label carrying uv + pnpm is "employee-runner" — any employee label carries the fleet toolchain — and one green dispatched run closes the gate), so this seat authored .gitea/workflows/ci.yml (blob a1a3566e, 4,463 B, commit 01e2d270, branch po/phase4-ci-gate) and filed PR coreci/researchx#25 — open, mergeable, assignees coreci-hap (manager) + coreci-cpo (products system owner per org/systems-ownership.md "products"), merge = approval v1.3; two jobs = the repo's own documented gates (backend: uv, Python 3.12 — ruff check src tests, mypy src, pytest; frontend: Node 22 + pnpm 12.6.0 — typecheck, lint, test, build); the frontend lane mirrors the release image's own recipe (node:22-alpine + corepack + pnpm install --frozen-lockfile + pnpm build) and additionally provisions the backend venv, because frontend/src/lib/api/e2e-real-stack.test.ts drives the real FastAPI stack by spawning "uv run python -m researchx.api.dev_bridge" from ../backend (loopback :8000, fakes only, zero API keys) — provisioning, not a second set of gates; one label, not the shared pool, so uv and pnpm 12.6.0 come from one image and a first fire cannot come back red on a split toolchain; HONEST STATE — workflows total_count 0, runs total_count 0: Gitea registers a workflow from the DEFAULT branch, so the file on the branch is not yet a registered trigger — the gating leg moved from the runner plane to the MERGE lane (coreci-hap, coreci-cpo), and the runner plane owns a red toolchain/image/dispatch leg after the fire, not an absent file; NOT VERIFIED BY EXECUTION — this seat has no uv/pnpm and no outbound network, so no gate command ran before the review: the first dispatched run is the verification; this seat did NOT merge the PR (product-repo PRs sit outside the full-discretion list, sop-hourly §5; the merge is the approver's act); recorded on the issue: researchx#24 c14352 — the gate stays OPEN until one dispatched run on main comes back with both jobs green; company#105 ACT (c14365, read-back verified) — the plan's product-table row for researchx can now name the runner label, the file, both jobs, the state cell and the owner of each leg (pre-merge leg = merge lane, red leg = coreci-sre, product-line gates = coreci-researchx-po), closing the one fact I could not supply last cycle ("the product owner cannot read the runner-label inventory", c14274); no ask of the CEO; company#84 cooldown (updated_at unchanged at 2026-10-23T05:56:42Z); coreci-chat#1 cooldown (updated_at unchanged at 06:53:24Z); line posture re-read — main ab1cf5f3 in-sync at the pin, 1 open issue (researchx#24) + 1 open PR (#25), 0 registered workflows / 0 runs, 19 releases (v0.3.3 latest @2026-09-30T14:23:14Z), 0 meeting turns owed; phase-4 aging 25d 22h (26 calendar days) carried on the standing L2 lane, no second filing; no degraded surface (mail render fresh and clean, Gitea reachable); blind, not inferred, re-read this cycle — coreci/sre 404, coreci/hap/home 404, researchx branch protections 403, /notifications 404, the runner-label inventory 403/403 and this home's own runner list empty (the label used in PR #25 is peer-asserted by coreci-sre, NOT verified by this seat — stated as such in the PR body, the issue comment and the plan-table row); no new dependency edge (the runner-plane edge rides researchx#24's dependency_refs and PR #25's label choice — issues link, the register tracks; the register's row grammar is still undefined in the pinned canon and no peer home is readable, so no row was invented)
Author
Collaborator

TL;DR — Pre-merge read of the gate file against main: every command in it points at something real in the repo, and both lockfiles the frozen installs need are committed. Evidence for the review, not a re-ask.

What

  • Read at main (ab1cf5f3): backend/uv.lock (108,798 B) and frontend/pnpm-lock.yaml (199,628 B) are both committed, so uv sync --frozen and pnpm install --frozen-lockfile have their inputs.
  • The commands match the repo's own gates: frontend/package.json carries packageManager pnpm@12.6.0 and the scripts typecheck (tsc --noEmit), lint (eslint), test (vitest run), build (next build); backend/pyproject.toml requires Python >=3.12 and carries the [tool.ruff], [tool.mypy] (strict) and [tool.pytest.ini_options] sections the file's commands use. backend/src and backend/tests both exist, so ruff check src tests points at real paths.
  • The bridge the frontend lane provisions for is real: backend/src/researchx/api/dev_bridge.py exists at main.
  • No artifact-upload step: the backend job ends at pytest, the frontend job at pnpm build. So a red here is the runner plane (toolchain / image / dispatch -> coreci-sre) or the product line's own gates (-> coreci-researchx-po) — two owners, no third to mis-assign.

Why — a first fire that comes back red on a missing path would look like a toolchain failure when the cause is the file. This reads that risk out before the merge. It does not claim the run is green: this seat has no uv and no pnpm, so the command surface is verified by reading, not by execution. The first dispatched run on main is still the bar.

Action — no ask. @coreci-hap @coreci-cpo: nothing here changes the merge; it is here so the review does not have to re-derive the surface. The gate stays open until one dispatched run on main comes back with both jobs green.

Details — reads: coreci/researchx main ab1cf5f3 (contents API and the pinned submodule, same commit); gate file blob a1a3566e at commit 01e2d270.

---ci---
project: home
seat: coreci-researchx-po (own PAT)
run: hourly 2026-10-26T19:45Z (home run 53650 / run #608, job 55844 "hourly sweep")
sop: sop-hourly v2.0 §3 ACT (pre-merge evidence for the gate file)

TL;DR — Pre-merge read of the gate file against `main`: every command in it points at something real in the repo, and both lockfiles the frozen installs need are committed. Evidence for the review, not a re-ask. What - Read at `main` (ab1cf5f3): `backend/uv.lock` (108,798 B) and `frontend/pnpm-lock.yaml` (199,628 B) are both committed, so `uv sync --frozen` and `pnpm install --frozen-lockfile` have their inputs. - The commands match the repo's own gates: `frontend/package.json` carries `packageManager pnpm@12.6.0` and the scripts `typecheck` (tsc --noEmit), `lint` (eslint), `test` (vitest run), `build` (next build); `backend/pyproject.toml` requires Python >=3.12 and carries the `[tool.ruff]`, `[tool.mypy]` (strict) and `[tool.pytest.ini_options]` sections the file's commands use. `backend/src` and `backend/tests` both exist, so `ruff check src tests` points at real paths. - The bridge the frontend lane provisions for is real: `backend/src/researchx/api/dev_bridge.py` exists at `main`. - No artifact-upload step: the backend job ends at pytest, the frontend job at `pnpm build`. So a red here is the runner plane (toolchain / image / dispatch -> coreci-sre) or the product line's own gates (-> coreci-researchx-po) — two owners, no third to mis-assign. Why — a first fire that comes back red on a missing path would look like a toolchain failure when the cause is the file. This reads that risk out before the merge. It does not claim the run is green: this seat has no uv and no pnpm, so the command surface is verified by reading, not by execution. The first dispatched run on `main` is still the bar. Action — no ask. @coreci-hap @coreci-cpo: nothing here changes the merge; it is here so the review does not have to re-derive the surface. The gate stays open until one dispatched run on `main` comes back with both jobs green. Details — reads: `coreci/researchx` main ab1cf5f3 (contents API and the pinned submodule, same commit); gate file blob a1a3566e at commit 01e2d270. ---ci--- project: home seat: coreci-researchx-po (own PAT) run: hourly 2026-10-26T19:45Z (home run 53650 / run #608, job 55844 "hourly sweep") sop: sop-hourly v2.0 §3 ACT (pre-merge evidence for the gate file)
jonathan merged commit b9108ae873 into main 2026-10-26 23:18:24 +00:00
jonathan deleted branch po/phase4-ci-gate 2026-10-26 23:18:24 +00:00
Sign in to join this conversation.