Repository navigation
Converge main: telemetry auth wiring + absorb 202 reconcile - #367
Closed
aliasfoxkde wants to merge 27 commits into
Closed
aliasfoxkde wants to merge 27 commits into
aliasfoxkde wants to merge 27 commits into
Conversation
The deployed binary on 192.168.1.202 (69245e2 bundle, Oct 29) predates the job-level environment field; its parser rejects the key (fail-closed per 0857218), so every push event for 7f4e8fd failed with 'unknown job key environment'. The top-level environment: {} remains — that one the deployed parser requires and accepts.
Clippy (rust 1.99 in dsc-ci-rust:12) flags the manual str::repeat pattern as manual_str_repeat/manual_repeat_n under -D warnings. Co-Authored-By: Claude <noreply@anthropic.com>
A busy branch occupied its repository's FIFO trigger lane for the whole of each ~10-minute pipeline, leaving other refs of the same repo starved: five main-branch trigger requests sat pending for hours while codex-branch pushes kept re-arming the lane, and the republish redrive could not help because it re-queued into the same lane. Lane keys now include the ref name, so ordering holds within a ref while cross-ref starvation is impossible.
Route-by-route inventory of the API surface with auth class and per-handler authorization check for every registered route. Anchors the registration and webhook findings fixed in the preceding commit.
The skip_if evaluator concatenated an `export KEY=value` line built from the detect-changes job receipt into a single bash -c script. A receipt-controlled value such as `1; touch /tmp/pwned` therefore executed as shell code inside the CI service. The environment is now delivered through Command::envs — never interpolated into the script text — and CI_CHANGE_FILE_COUNT defaults to 0 when the receipt omits it. Regression tests cover both properties. Refs #358
GET /api/runners and GET /api/runners/{id} let any authenticated
user enumerate the fleet (names, capacity, heartbeats) — recon
directly feeding the F1-style identity spoofing. Apply the same
can_manage_jobs role gate retirement already uses, and fix the
integration tests that minted admin JWTs without persisting the
role row the middleware re-resolves.
Co-Authored-By: Claude <noreply@anthropic.com>
Authz audit F3: GET /api/runners and /api/runners/{id} accepted any
authenticated user, exposing fleet inventory (names, capacity,
heartbeat) to plain developers. Both reads now require maintainer or
admin via can_manage_jobs, matching the write-side gate.
Also records the 2026-11-01 authz audit, partial security audit, and
the 2026-11-02 production validation campaign (G1 pipeline-id drop in
trigger delegation, G2 uploaded-config bypass, G3 missing CI /metrics).
POST /api/pipelines/{id}/runs dropped the pipeline id when delegating
to the CI trigger, so the run bound to the repo's active pipeline and
the trigger dedup key — (repo_id, new_hash) — made two pipelines on
one commit dedup onto the first's row. The API-uploaded config was
bypassed whenever the pushed revision carried no committed
.gitforge.yml: the consumer fell back to cache/persisted/default
(G1/G2, docs/planning/PRODUCTION_VALIDATION_20261102.md).
The trigger request now carries an explicit pipeline_id, the dedup
key includes it (NULL keeps the old push-trigger semantics for
existing rows, added by a guarded column migration), and the webhook
event serializer forwards it. The old-hash sentinel uses git's fixed
all-zero ref-deletion value via is_zero_hash instead of a hard-coded
40-zero string.
Reproduced live on 202 (runs e80ed74f, 01f104df executed the wrong
pipeline); this change makes the requested definition authoritative.
Covers G1: two explicit pipeline triggers on one commit must each get their own trigger request; keying on (repo, hash) alone made the second dedup onto the first's row and never run.
Queued runs for a (repo, ref, pipeline) are superseded when a newer push lands, cancelling never-dispatched jobs so runner capacity serves the tip. Includes image-registry allowlist validation and runner fleet-pause runbook guidance.
The runners_online/pipelines_total/jobs_total/repos_total/artifacts_total gauges had no production setter and stayed at zero while real work flowed through the CI service. A 30s sweep now reads the dashboard counts plus a new JobQueries::count_all into the gauges. Co-Authored-By: Claude <noreply@anthropic.com>
…dicts - /metrics and /dashboard require auth unless GITFORGE_PUBLIC_TELEMETRY=1 (F5); /health stays public; decision core + middleware tests - pipeline_runs.ref_name column; webhook/ci populate it; supersede and integration/scheduler tests updated - release gate: unconditional-job check accepts satisfied rows (succeeded or skipped); quality-chain names stay fails-closed; gate tests extended - ledger verdicts for F1-F5 and the 2026-11-02 queue incident; F4 recorded as a design decision; architecture audit appended to the execution plan; __pycache__ ignored Co-Authored-By: Claude <noreply@anthropic.com>
Fix middleware-branch test expectations: /dashboard has its own route merge and never hits the PUBLIC_PATHS skip branch; " 1 " is a valid trim-tolerant opt-in.
/metrics and /dashboard were merged into public_routes, bypassing the auth middleware entirely, so the GITFORGE_PUBLIC_TELEMETRY gate was dead code at the route boundary. Wire both surfaces into the protected router by default and into public_routes only on explicit opt-in. Integration tests now pin the boundary: anonymous 401 by default, 200 with opt-in.
Make telemetry_is_public crate-visible and clone the metrics router so it can be merged into either the public or protected router without a double move.
The default-posture telemetry routes were merged into the /api-nested protected router, which relocated them to /api/metrics and /api/dashboard and left the canonical paths a 404. Mount them at top level behind their own auth-middleware layer instead. Serialize the three env-mutating telemetry tests with a shared mutex: the decision is read from the process env at router-build time, so parallel test threads race and randomly invert the asserted posture.
/metrics and /dashboard are now mounted at top level behind the auth middleware unless GITFORGE_PUBLIC_TELEMETRY=1. Full GitForge chain green on f1ebec0 (run df5fc6ec).
# Conflicts: # crates/gitforge-api/src/middleware.rs
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
🤖 AI Code Review ResultsAI review skipped: provider 'anthropic' is not configured; deterministic gates remain authoritative. ✅ No critical issues found. AI Code Review powered by GitForge |
Owner
Author
|
Closing as duplicate: this branch's tree hash (914820ed) is byte-identical to PR #368 (reconcile/linearize), which carries the same content as a linearized history — required because the Safeguards ruleset enforces required_linear_history with no bypass actors. If #368's shape doesn't work, reopen this one; the content is identical. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan