ci: fail closed before executing on unverified hosted runner
MariaDB persistence qualification / mariadb (push) Failing after 8s

This commit is contained in:
cesnimda
2026-10-24 08:55:02 +02:00
parent 549b2cba5a
commit 75cd04cfc2
5 changed files with 159 additions and 1 deletions
+6 -1
View File
@@ -1,13 +1,18 @@
name: MariaDB persistence qualification
on:
push:
branches: [codex/rd21-mariadb-standardisation]
branches: [codex/rd21-mariadb-standardisation, fix/p9-ci-and-requalification]
pull_request:
workflow_dispatch:
jobs:
mariadb:
runs-on: ubuntu-latest
steps:
- name: Require verified runner isolation
# Remove this blocker only after the operator evidence and workflow review in the handoff.
run: |
echo '::error::BLOCKED: hosted runner isolation is unverified. See docs/redesign/phase-9/p9-requal-01/CI_OPERATOR_HANDOFF.md before enabling database execution.'
exit 1
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
@@ -0,0 +1,38 @@
# P9-REQUAL-01 hosted CI findings
Observed 2026-10-24 06:49 UTC. Verdict: **BLOCKED (runner isolation and hosted database execution)**. This is an infrastructure prerequisite, not evidence of a MariaDB product regression or a production qualification.
## Current evidence
| Evidence | Verified result | Limit |
| --- | --- | --- |
| Gitea `/api/v1/version` | 1.26.0 | Server version does not identify the runner binary. |
| Repository metadata | Existing Git credential can read Actions and reports repository admin/push/pull permissions. | `/user` and `/admin/actions/runners` return 403. Repository permission does not establish instance administration. |
| Repository runner listing | Runner 3 `pi-runner-1`, offline; `ubuntu-latest`, `ubuntu-22.04`; no version returned. | This is not the runner that ran the database lane. |
| Baseline [run 844](https://git.cesnimda.uk/cesnimda/jobtrackingapp/actions/runs/844), job 1734 | SHA `549b2cba5a791862ba3f854312ea819a86dc42a0`; job API identifies runner 5 `Live-Runner`, label `ubuntu-latest`; failure. | Instance-wide identity/configuration unavailable through the permitted API. |
| Run 844 raw log, lines 1, 12, 17 | Runner reports v0.4.1; `node:20-bookworm`; **merged** job HostConfig has `NetworkMode:host`, `/var/run/docker.sock:/var/run/docker.sock`, `Privileged:false`, no published ports. | An earlier reading of **custom** HostConfig `Binds:[]` was incomplete. Effective merged configuration includes the host socket. Socket daemon ownership and production separation are unverified. |
| Run 844 raw log, lines 130-151 | SDK 9.0.317 installed; five Python guard tests pass; `docker: command not found`, exit 127. | These are guard/unit tests, not the 32 MariaDB integration tests. Printed cleanup-failure/exit17/exit1 samples are mocked test cases; they do not show real database cleanup. |
| Run 844 raw log, line 152 | No integration artifact files available for upload. | Hosted MariaDB tests did not run. Job API marks all steps failure despite the raw five-test `OK`; use the raw log for step outcomes. |
Run 843 is historical corroboration of the same merged socket/host-network configuration. Run 844 is the baseline-SHA observation. No new hosted job, Docker command, database, or service was started in this investigation.
## Version-specific native service research
The official `act_runner` source URL redirects to `gitea/runner`. The official [v0.4.1 tag API](https://gitea.com/api/v1/repos/gitea/runner/git/refs/tags/v0.4.1) resolves to `9aafec169b7ebf3d71df2b06780868fb552b435e`. Read these pinned sources, not runner 2.x documentation:
- [Configuration example](https://gitea.com/gitea/runner/src/commit/9aafec169b7ebf3d71df2b06780868fb552b435e/internal/pkg/config/config.example.yaml): an empty container network delegates network creation; `docker_host: "-"` prevents the Docker host mount in job and service containers. These are operator configuration choices, not settings changed here.
- [Runner implementation](https://gitea.com/gitea/runner/src/commit/9aafec169b7ebf3d71df2b06780868fb552b435e/internal/app/run/runner.go): passes network/socket/privilege configuration to its execution engine, sets `ReuseContainers:false`, `AutoRemove:true`.
- [go.mod](https://gitea.com/gitea/runner/src/commit/9aafec169b7ebf3d71df2b06780868fb552b435e/go.mod): selects `gitea.com/gitea/act v0.261.10`.
- [Execution engine](https://gitea.com/gitea/act/src/tag/v0.261.10/pkg/runner/run_context.go): `networkNameForGitea` reuses configured networks (including `host`); only an empty configured network generates a job network. Native service containers share that network, receive service aliases, and have explicit port bindings only from declared service ports. Normal cleanup attempts service and generated-network removal, logging cleanup errors. Services start before job steps, so a step preflight cannot make an unsafe `services:` declaration safe.
This establishes source capability only. The installed binary has not been matched to these source bytes, and normal-cleanup code does not prove cleanup after cancellation, runner crash or daemon loss. Nothing proves the effective Live-Runner uses an empty network or socket suppression; the observed job does the opposite. Private native services therefore remain **NOT ENABLED**.
## Bounded workflow change
Retain the existing push branch and add `fix/p9-ci-and-requalification`. Add an unconditional failing isolation preflight before all workflow Docker/Compose/database commands. It reports this handoff and requires a later reviewed workflow change after operator evidence; no self-attested repository variable bypass exists. Existing checkout, SDK, five guard tests, integration command and artifact action remain. No services, socket mount, privileges, Docker CLI installation, deployment workflow or runner configuration was added.
Do not remove the blocker merely because Docker becomes available. Under the observed configuration that could grant the job control of an unidentified host daemon. The desired future native service must use `mariadb:12.2.2@sha256:42a27baaba3e8f3f0159d16381d5a7156661aa91dcc65f663cabb6a6f9503c00` on the already documented linux/amd64 platform, no published service ports, private job networking and verified disposable storage. No version upgrade is proposed.
The current fixture and `--existing-server` runner deliberately allow only explicit loopback TCP. A later private service transport must preserve those defaults and receive separately reviewed narrow endpoint validation; no fixture bypass is included here.
Sanitized API metadata, source/log hashes, precise blockers and next actions are in [ci-findings.json](ci-findings.json) and [CI_OPERATOR_HANDOFF.md](CI_OPERATOR_HANDOFF.md). Ignored raw files remain local; no credentials or full environment/configuration are copied into these tracked reports.
@@ -0,0 +1,15 @@
# Hosted MariaDB lane: operator handoff
Status: **BLOCKED**. The workflow intentionally exits before Docker/Compose/database execution. No repository-variable toggle can enable it. The existing runner already injects a host Docker socket and host networking; this task has not changed or used those facilities.
The infrastructure owner must supply sanitized evidence for the following before a reviewed workflow change can enable native services:
1. Identify actual runner 5 `Live-Runner` and its host/daemon ownership. Show its registration scope, labels, binary version/build identity, and relation to offline repository runner 3. Prove it is dedicated non-production CI infrastructure, with no production containers, volumes, networks, mounts or credentials reachable by jobs. A name or `ubuntu-latest` label is insufficient.
2. Provide only the relevant **effective** runner container network, Docker-host-mount, privilege, allowed-volume and option fields, with credentials redacted. Prove job/service containers use a fresh per-job private network, no Docker socket/daemon endpoint exposed to jobs/services, no privileged mode, no host networking and no published MariaDB ports. Source examples and custom pre-merge HostConfig are insufficient; capture merged runtime configuration. No host configuration or credential changes are authorized by this handoff.
3. On infrastructure the owner has established as isolated, prove service readiness and DNS reachability from the job, no cross-job database reachability, and disposable service storage. Use the pinned 12.2.2 linux/amd64 image digest already recorded in the repository, generated test schemas and synthetic data only.
4. Prove removal of service containers, private networks and test data after success, test failure, cancellation and interrupted-runner recovery. Retain before/after resource inventories scoped to that generated job. Cleanup source code and an `AutoRemove:true` flag alone are insufficient.
5. Supply a dedicated routing label (for example `jobtracker-mariadb-isolated`) and sanitized identity/configuration evidence for every eligible runner. The repository owner then reviews the workflow and fixture/runner transport changes together. Native `services:` starts before steps; isolation must be established before adding it. Preserve default loopback protection and the pinned image/version requirement.
Only after those evidence checks: replace the unconditional blocker and Compose path with the approved private service transport, retain fail-closed readiness and cleanup checks, and execute a fresh hosted lane. It must produce all 32 MariaDB integration results, zero skips, process exit codes, source SHA, server version/image identity and lifecycle evidence. Do not call an expected BLOCKED workflow run, five guard tests, a label match or a green unrelated main workflow a successful MariaDB qualification.
The API credential currently reports repository administration but receives 403 for instance runners. The owner can provide the narrowly scoped operator evidence without exporting credentials or full configuration. The next action is operator evidence collection, followed by review; no production deployment, socket/privilege grant, DinD, public port or live infrastructure mutation is part of this task.
@@ -0,0 +1,28 @@
# P9-REQUAL-01 — Hosted CI and Phase 9 Requalification
Approved specification: owner's P9-REQUAL-01 mission and implementation plan in this conversation.
Baseline: `549b2cba5a791862ba3f854312ea819a86dc42a0`; branch `fix/p9-ci-and-requalification`.
Main must remain `5f835e54a9b74e6b71418422e28431b2af06453f`.
## Tasks
1. Verify baseline/raw evidence; register RD01–RD28, Phase9 findings, M09-01–10 and57 preservation groups with independently sourced Phase9/Phase10/production/debt gates.
2. Investigate Gitea1.26/act_runner0.4.1 service isolation. Change only the database-test workflow. Prefer private runner-managed services after isolation/lifecycle proof; otherwise retain BLOCKED and provide an operator handoff. Never add a host socket, privileges, public ports, DinD or production access.
3. Map RD21 closure; reproduce safe outstanding observations, minimally repair confirmed in-scope defects, provide human test cards, and run a15minute isolated MariaDB workload with250 applications/two paced readers and exact before/after state checks.
4. Freeze rebuilt source/artifacts; run full backend/frontend/browser/contracts/MariaDB/sidecar/security/types/lint/build/PDF/preservation lanes. Retain exact membership, failures, exclusions, process exits and source/report hashes.
5. Independent whole-branch review; bounded fixes and affected successors; publish dated addendum, five verdicts, next action, exact commit/remote/main verification.
## Boundaries and accounting
No Phase10 implementation, SQLite retirement, DB-version change, production operations, main merge or force push.
No manual/physical-device/provider semantics claim from automation. C11/P5-13 stays withheld.
Existing1,123backend/32MariaDB/1MariaDBbrowser/18diagnostic/3volume results are historical, not fresh runs.
Use fresh `.artifacts/p9-requal-01/` paths, zero hidden retries/skips and independent durable reads.
Production-only gates do not automatically veto Phase9. Conditional Phase10 requires explicit authoritative carry-forward eligibility.
## Execution ledger
- Entry: clean baseline/remote equality and RD21 ancestry verified during planning; clean entry rechecked before branch creation.
- Ruling: use the clean existing checkout on the explicitly requested dedicated branch; retain installed tooling and historical raw evidence, without creating another checkout or asking for routine confirmation.
- Pre-flight: CI transport changes may affect fixture guards; keep default loopback protection and require verified private lifecycle before adding any CI-service endpoint. Performance source is separate; execute its workload without other qualification workloads.
- Task1: started. Task2: started. Task3: started. Task4/5: pending.
@@ -0,0 +1,72 @@
{
"schemaVersion": 1,
"observedUtc": "2026-10-24T06:49:22Z",
"verdict": "BLOCKED",
"scope": "Hosted MariaDB runner isolation and qualification only",
"baselineSha": "549b2cba5a791862ba3f854312ea819a86dc42a0",
"giteaVersion": "1.26.0",
"apiPermissions": {
"repository": {"admin": true, "push": true, "pull": true},
"userHttpStatus": 403,
"instanceRunnersHttpStatus": 403
},
"repositoryRunner": {"id": 3, "name": "pi-runner-1", "status": "offline", "labels": ["ubuntu-latest", "ubuntu-22.04"], "version": null},
"baselineRun": {
"id": 844,
"jobId": 1734,
"runnerId": 5,
"runnerName": "Live-Runner",
"runnerReportedVersion": "v0.4.1",
"label": "ubuntu-latest",
"conclusion": "failure",
"jobImage": "node:20-bookworm",
"mergedNetworkMode": "host",
"mergedDockerSocketMount": true,
"mergedPrivileged": false,
"publishedPorts": [],
"sdkInstalled": "9.0.317",
"pythonGuardTests": {"passed": 5, "kind": "unit guards; mocked infrastructure"},
"dockerFailure": "command not found",
"dockerExitCode": 127,
"mariaDbIntegrationExecuted": false,
"integrationArtifactUploaded": false,
"stepMetadataCaveat": "API marks all steps failure; raw log establishes SDK installation and five passing guard tests"
},
"officialSourceResearch": {
"runnerTag": "v0.4.1",
"runnerCommit": "9aafec169b7ebf3d71df2b06780868fb552b435e",
"executionEngine": "gitea.com/gitea/act v0.261.10",
"installedBinaryMatchedToSource": false,
"sourceCapability": "Native services with generated network only when configured network is empty; socket suppression requires operator configuration; normal cleanup attempts removal",
"effectivePrivateNetworkingProven": false,
"runtimeLifecycleProven": false
},
"blockers": [
"Effective job uses host networking and host Docker socket; daemon ownership and production separation unknown",
"Actual runner is absent from repository-only runner listing; instance API forbidden",
"Installed runner build identity and effective private service configuration unverified",
"Success/failure/cancellation/interruption service cleanup unproven",
"Current test transport deliberately accepts only loopback; private service transport not implemented or approved"
],
"workflowChange": {
"addedPushBranch": "fix/p9-ci-and-requalification",
"originalPushBranchRetained": true,
"unconditionalIsolationBlockBeforeDocker": true,
"variableBypass": false,
"nativeServicesAdded": false,
"runnerConfigurationChanged": false,
"deploymentWorkflowsChanged": false,
"hostedRunStartedByInvestigation": false
},
"futureImage": "mariadb:12.2.2@sha256:42a27baaba3e8f3f0159d16381d5a7156661aa91dcc65f663cabb6a6f9503c00",
"nextAction": "Infrastructure owner supplies dedicated-runner identity, effective private network/socket suppression and complete lifecycle proof; repository owner reviews transport/workflow before enabling execution",
"rawEvidenceSha256": {
".artifacts/mariadb/requal-ci-api.json": "3369a245165a40e20553f633ff7751f14bc8396d0523c379f658adff16f863ac",
".artifacts/mariadb/hosted-ci-843.log": "47ba05d12f08eb7a16a5649f71dde18cd582176a2bed818f3e045932ec025891",
".artifacts/mariadb/hosted-ci-844.log": "e03d82a3d24329482b9acd66866bdc500244a85af89932691d09f00d881fdaf9",
".artifacts/mariadb/act-runner-v0.4.1/go.mod": "9863a6049f423c537b02caf6307c8bb6c7dcfe809fb314193b1856274a160824",
".artifacts/mariadb/act-runner-v0.4.1/internal_pkg_config_config.example.yaml": "e47d046dc368eb85b35665b4a5dba57ce0be4053c665ff737916a7561f7337fa",
".artifacts/mariadb/act-runner-v0.4.1/runner.go": "857b163f42aeb350aa32fbdc884e8d2ceb738d77e8a25504ac38c3e0035ab590",
".artifacts/mariadb/act-runner-v0.4.1/pkg_runner_run_context.go": "45aea88466bc40c1cddad7ee6cfe98444ffd225a719683ee319c909075466c2c"
}
}