feat(managementapi): emit counter deltas on the six remote evict routes

What this delivers

The six single-target remote DELETE route arms in internal/managementapi now move a storage-accounting counter after they answer. Each arm dispatches one repository-scoped delta on the repositories row the URL named, not on the remote child row.

Arm Counter Amount
mavenRemotePackageEvict, npmRemotePackageEvict artifacts_count the composer's hiddenVersions, the live cached versions one mark hid
mavenRemoteVersionEvict, npmRemoteVersionEvict artifacts_count one, the row the mark names
mavenRemoteFileEvict, npmRemoteFileEvict size_bytes the composer's freedSizeBytes

Every arm keeps its order: it writes the 202 first, then gates on the composer's own boolean, then dispatches. The four mark arms return on an unapplied mark, because the request that won the race owns the delta. The two file arms gate on the boolean the composer already returned above the 202.

The four mark arms also log that unapplied mark, at INFO. Each line names the arm's own id key and the namespace the write was scoped to. remoteContainerImageEvict and remoteContainerManifestEvict carry the form this copies, and the two remote file arms already logged their equivalent. Without the line, a scoping defect that marks no row answers the same 202 as a lost race, and nothing separates the two.

The cause

All six arms bound the composer's returned amount to _ and never called emitDeleteCountersDetached. A committed eviction therefore built no deleteCounters value at all. The amount existed inside the composer's transaction and the call site discarded it.

Nothing downstream was wrong. emitDeleteCounters, deleteCounters.needsDispatch and accounting.Emitter already handle every amount these arms now pass. The fix is at the cause, and it adds no new emit machinery.

Test coverage

Source: the issue card's derived acceptance list, 19 items. The issue declares no Acceptance section, so this run derived the list from the issue body and from the merged documents it cites.

# Item Tests
1 mavenRemotePackageEvict emits one repository delta (-hiddenVersions, 0) TestMavenRemotePackageEvict_EmitsTheTombstoneDelta/the_mark's_hidden-version_count_is_the_whole_delta
2 npmRemotePackageEvict emits the same, from EvictNpmRemotePackage TestNpmRemotePackageEvict_EmitsTheTombstoneDelta/the_mark's_hidden-version_count_is_the_whole_delta
3 mavenRemoteVersionEvict emits (-1, 0) when the mark applied TestMavenRemoteVersionEvict_EmitsOneHiddenArtifact/the_marked_version_row_is_the_whole_delta
4 npmRemoteVersionEvict emits the same TestNpmRemoteVersionEvict_EmitsOneHiddenArtifact/the_marked_version_row_is_the_whole_delta
5 mavenRemoteFileEvict emits (0, -freedSizeBytes) TestMavenRemoteFileEvict_EmitsTheFreedBytes/the_repository's_last_reference_frees_the_blob's_bytes
6 npmRemoteFileEvict emits the same TestNpmRemoteFileEvict_EmitsTheFreedBytes/the_repository's_last_reference_frees_the_blob's_bytes
7 No arm emits a namespace-scoped delta on any outcome requireRemoteEvictOutcome, on every subtest of all six suites
8 A mark emits a zero size delta; a file eviction emits a zero artifact delta requireRemoteEvictOutcome's exact delta equality, on the six emitting subtests
9 A still-referenced blob emits nothing, not a zero-valued delta TestMavenRemoteFileEvict_EmitsTheFreedBytes/a_still-referenced_blob_emits_nothing, TestNpmRemoteFileEvict_EmitsTheFreedBytes/a_blob_a_cached_packument_still_holds_emits_nothing
10 An unapplied re-mark emits nothing; a file eviction that found the row gone emits nothing a_lost_mark_race_answers_202_and_emits_nothing in the four mark suites, a_cached_file_already_gone_emits_nothing in the two file suites
11 A request answering 404 moves no counter an_already-marked_package_answers_404_and_emits_nothing, an_already-marked_version_answers_404_and_emits_nothing, an_already-evicted_file_answers_404_and_emits_nothing, one per suite
12 No arm emits a usage-data event requireRemoteEvictOutcome, on every subtest of all six suites
13 Each arm writes its 202 first, returns on an unapplied write, emits after Partly. The status is required before the emit is awaited in the four package and file suites, and the two version suites await the emit hook first and check the status after; the unapplied return is row 10. The emit's position after the response write is not asserted here; emitDeleteCountersDetached owns it and artifact_counters_internal_test.go covers that seam
14 All six arms carry their own route-level case Six suites, one per arm, each driving its own route and rig
15 docs/testing/e2e/maven.md and npm.md drop the no-counter sentence Not a test row. Documentation, on this branch: both scenario rows now read "move the same deltas, one target at a time"
16 The maven.md usage-event row is unchanged Not a test row. Documentation, no change needed
17 docs/dev/storage-accounting.md no longer says the six emit nothing Not a test row. Documentation, on this branch: the two eviction, single-delete route grid rows read emits, the Known-gaps row is deleted, and the purge section's prose is rewritten
18 Each emitted delta equals the change the counter's recompute sees Owned by the datastore integration suite; a route-level suite over fakes runs no recompute. TestIntegration_BulkDeleteNpmWorker_RemoteEmittedDeltasAgreeWithTheRecompute holds it for the shared composers
19 A negative control: dropping emission on every arm must fail a case The six emitting subtests are that control, and they are the six that failed against the unfixed arms

Rows 15 and 17 read "still owed" when the table was written, before the documentation commits landed on this branch. Both cells now state what the branch carries. No other cell is changed.

Two rows record a limit rather than a pass, and neither is hidden. Row 13 is covered in part at this level. Row 18 needs a live database, so the shared composers hold it in the datastore integration suite.

Row 19 needs a correction, because the negative control is weaker than the row states. Four of the six new boolean gates are pinned by no test. The fakes report the composers' documented no-op as (false, 0, nil), so both package arms and both file arms pass a zero amount, needsDispatch suppresses the emit on its own, and deleting the guard from any of those four leaves every test green. Only the two version arms pass a literal 1, and only there does the guard carry the assertion. The container remote suite this work mirrors has the identical gap: its fakes report the same (false, 0, nil), so its counter gates rest on the same suppression. No mirrored subtest was dropped. Pinning the other four gates needs a fake that reports a non-zero count on an unapplied mark, which the composers' contracts forbid.

Four tests outside this table cover the log the four mark arms now write. They are TestMavenRemotePackageDelete_LostMarkRaceLogsThePackageID, TestMavenRemoteVersionDelete_LostMarkRaceLogsTheVersionID, TestNpmRemotePackageDelete_LostMarkRaceLogsThePackageID and TestNpmRemoteVersionDelete_LostMarkRaceLogsTheVersionID. Each one drives its arm with an unapplied mark. It asserts the 202, the message, the INFO level, the arm's id key and namespace_id, and it asserts an empty usage-data tracker. Each is a top-level test in the suite that already owns its route, not a subtest of the counter file. The table above maps the 19 derived items, the log is not one of them, and no row moves.

Runtime evidence

Seven exercises drove a live service on this branch, over fourteen requests. Each exercise took three readings around each request: the repositories row before and after, the Redis buffer hash right after the response, and the gitlab_artifact_registry_management_api_delete_counter_emits_total metric. The metric separates "no emit at all" from "a zero-valued delta", because a skipped dispatch increments nothing. All seven produced the expected counter outcome. The session emitted five deltas over those fourteen requests, four on a tombstone and one on a file, and the other nine requests emitted nothing. Three exercises carried more than one request: the two version exercises each issued a repeat DELETE, and one exercise drove all six routes against an absent coordinate.

Five of the six arms were driven in an emitting configuration. The npm remote file arm was driven only in its non-emitting shape, where a cached packument still holds the blob, because that exercise exists to test the "no emit at all" case.

An earlier version of this section said seven requests and four that must not emit. Both figures came from the runtime record this section summarizes, which carries the same error, and the figures above replace them.

Two results are worth naming, because they are the ones a reader will doubt.

An npm remote file evict whose blob a cached packument still holds writes no buffer key and makes no emit. It is not a zero-valued delta. The delete itself was confirmed separately: the npm_remote_files row is gone and the packument row stands.

A second DELETE on an already-marked version moves no counter. The measured status was 404, not the 202 the exercise list predicted. The repeat never reaches the evictor, because the chain-verifying read returns live rows only and a marked row resolves to nil. Those resolvers live in internal/datastore/maven_remote_eviction_resolve.go and its npm sibling, and neither file is in this diff. The load-bearing half of the exercise still holds: a repeat DELETE of one coordinate moves no counter.

The runtime pass drove a binary built from this branch, before both rebases. Two things reached the three route-handler files after that build. The comments moved, and the four mark arms gained the INFO log on their unapplied branch. No counter emit, no status write and no signature moved, so the exercises above still describe the counter outcomes this merge request carries. No exercise reached the new log line: the repeat delete answered 404 ahead of the evictor, and every other mark applied.

The e2e scenario catalogs

Two catalog rows are updated, and both are the counter-assertion scenarios this change alters:

  • e2e.maven.lifecycle.management-delete-storage-counters in docs/testing/e2e/maven.md
  • e2e.npm.lifecycle.management-delete-storage-counters in docs/testing/e2e/npm.md

Each row replaces "The single-target remote DELETE routes move no counter, and reconciliation is what corrects those rows" with "The single-target remote DELETE routes move the same deltas, one target at a time". Both rows keep automatable and not started.

No new scenario is owed. The change adds no route, no status code and no user-visible outcome, so the only catalog claim it touches is the counter assertion these two rows already own. The two usage-data rows that carry the same scenario id stay true, because this change emits no usage-data event. The INFO log is a server-side record with no catalog row of its own, and the four route tests are what hold it.

Diff size and the LOC split

The diff is 703 insertions and 35 deletions over 14 files, past the 500 reviewable lines docs/dev/development-model.md sets. Derived with git diff --numstat 16bc85e39...d1567f95c, over the branch's five commits, at merge base 16bc85e39 and branch head d1567f95c. The rebase onto 16bc85e39 moved no figure in this table.

File group Files Insertions Deletions
Route handlers internal/managementapi/file_delete.go, internal/managementapi/package_delete.go, internal/managementapi/version_delete.go 113 13
Route-level counter tests internal/managementapi/artifact_delete_counters_test.go 421 0
Per-route log tests internal/managementapi/maven_remote_package_delete_test.go, internal/managementapi/maven_remote_version_delete_test.go, internal/managementapi/npm_remote_package_delete_test.go, internal/managementapi/npm_remote_version_delete_test.go 92 0
Test support internal/managementapi/fake_maven_remote_eviction_test.go, internal/managementapi/fake_npm_remote_eviction_test.go, internal/managementapi/export_test.go 63 10
Documentation docs/dev/storage-accounting.md, docs/testing/e2e/maven.md, docs/testing/e2e/npm.md 14 12
Total 14 files 703 35

A split does not help here, for four reasons.

The production change is 113 insertions over three files, and it is one defect with one cause repeated six times. A reviewer reads all six arms together or reads none of them, because the question on each arm is whether it passes the right amount and gates on the right boolean.

The 421-line test file is 60% of the insertions and it is six suites over one shared rig. Splitting it by format puts three arms in each half and duplicates the rig, the fakes and the assertion helper.

The 92 lines of log tests are four copies of one 23-line case, one per arm. Each copy lands in the suite that already owns its route, and a separate merge request for the four carries the log away from the counter emit that shares its gate.

The documentation edits name npm and Maven in the same sentences and the same table rows. A per-format split rewrites each of those rows twice and leaves the first half stating a claim the second half falsifies.

Scope decisions

internal/managementapi/artifact_write.go has zero contact with this change, by decision rather than by oversight. The two package arms carry their reason at their own emit sites instead. That file holds the shared doc comment on deleteCounterTargetTombstone, which four mark arms reach over four different tables, and the footprint reason differs per table. Widening one shared comment to state four readings is scope this issue does not ask for, and the arm sites say the true thing for the arm the reader is looking at.

This issue carries type::feature and no plan under docs/plans/ declares it. AGENTS.md asks for a plan MR before implementation, so this is a stated deviation from that guardrail.

Disclosures

Four sites carry a purger claim that this change shows to be false, and all four stay as they are. Each says that a mark on a cached remote package leaves the subtree for the lifecycle purger. lifecycle.DefaultPurgeLevels builds nine levels and none of them reads maven_remote_packages or npm_remote_packages, so no reap reaches that subtree while the repository is live.

Site The claim
internal/datastore/npm_remote_eviction.go:2 "the lifecycle purger reaps each row beneath it with its blob_storage_attachments row"
internal/datastore/npm_remote_eviction.go:62 EvictNpmRemotePackage "leaving the subtree for the purger"
internal/datastore/maven_remote_eviction.go:31 "A mark writes the named row only and leaves the subtree to the lifecycle purger"
internal/datastore/maven_remote_eviction.go:56 EvictMavenRemotePackage "leaving the subtree for the purger"

A fifth site has the same shape: internal/managementapi/bulk_npm_worker_remote.go:86, "marks one cached package for the purger's reap".

All five are adjacent defects in files this change does not touch, and the gap already belongs to #728. Its Known-gaps row in docs/dev/storage-accounting.md reads "No purge level reads the three remote parent tables". No new issue is filed for them.

This change makes a documented over-decrement window reachable from a user route. Before it, the window was reachable from the bulk delete worker alone. Both package composers count the live versions unserialized against a concurrent version mark, and the package row's lock does not reach that count: internal/datastore/maven_remote_eviction.go:223-224 and internal/datastore/npm_remote_eviction.go:271-272. A version marked after the count is decremented twice, so artifacts_count reads low until reconciliation's source-row recompute corrects it.

This change deletes the routes' only Known-gaps row from docs/dev/storage-accounting.md, because that row said the six routes emit nothing and this change falsifies it. The over-decrement window above is now stated in the npm remote grid's eviction paragraph, and the Maven remote grid points at it. It carries no Known-gaps row and no tracker. Every row of that table carries a tracker in its third column, so the row and the tracker are one choice rather than two, and the identical window on the container image arm is recorded as prose in its own grid, written by 9ac5c267d when that arm's own gap row was retired.

A cancelled or expired request context opens a second window, and it reaches all six arms of this change. logAndWriteInternalError returns on context.Canceled and context.DeadlineExceeded with no log line and no status written, at internal/managementapi/resolve.go:221. At that point Postgres can already hold the committed mark, so the counter delta is real and the arm never learns it. emitDeleteCountersDetached sits below the error return on all six arms, so the delta never reaches the emit metric, not even as its dropped outcome.

The record the six arms leave is not the same. The two remote file arms WARN, through writeMavenRemoteFileEvictFailure at internal/managementapi/file_delete.go:345 and writeNpmRemoteFileEvictFailure at :541. The four mark arms leave no line at all: internal/managementapi/package_delete.go:206 and :358, internal/managementapi/version_delete.go:239 and :379.

No code in this merge request touches this window, and the fix is not this change's to make. #744 scopes it to logAndWriteInternalError itself, because one change at the helper covers all nine of its call sites. #422 carries the same class as a type::bug at severity::3, and asks for the r.Context().Err() split with a 499 stamp. A fifth per-arm spelling of that predicate is work #422 then has to unwind.

The silent no-op branches that remain

All six routes of this change now record their no-op. The four mark arms log it as of this branch, and the two remote file arms already did at internal/managementapi/file_delete.go:322 and :520. The absence that remains is the hosted single-target mark arms, and there are four of them. Every line below was measured at d1567f95c. This table covers the no-op axis alone, where a mark applied nothing. The cancelled-context window in ## Disclosures is a different absence, on the error path, and this table does not cover it.

Silent arm Its gate What its no-op path records
mavenHostedPackageDelete internal/managementapi/package_delete.go:162, if !marked nothing
npmHostedPackageDelete internal/managementapi/package_delete.go:314, if !marked no log line. Its gate emits a counter delta as of !2232 (merged): the freed packument-cache bytes. The cache-row delete is that transaction's own whichever way the mark went
mavenHostedVersionDelete internal/managementapi/version_delete.go:197, if !applied nothing
npmHostedVersionDelete internal/managementapi/version_delete.go:344, if outcome.Marked the tags-count settle at :335 and the usage-data event at :340, which both run above the gate

The fourth row is the one a reader misses, and its shape differs twice over. Its gate is positive, so the no-op path holds no return and falls off the end of the function. And its no-op is not unrecorded: a usage-data event still fires, so only the log and the counter delta are absent there. The flag it reads is datastore.NpmVersionDeleteOutcome.Marked, declared at internal/datastore/npm_version_management_deleter.go:33.

Three readings this absence does not admit:

  • The hosted file arms are not silent. internal/managementapi/file_delete.go:251 and :444 log their miss, and both answer 404 rather than a no-op 202.
  • The hosted container image arm is not silent either. internal/managementapi/container_image_delete.go:123 writes the same line as its remote sibling at :178, so the split is not hosted against remote.
  • No bulk arm is silent, hosted or remote. The Maven bulk arms reach InfoContext through applyEntry at internal/managementapi/bulk_maven_worker.go:901-903, and the npm bulk arms reach it through logEntrySkipped at internal/managementapi/bulk_npm_worker.go:1002.

Of the 18 writeAccepted sites in internal/managementapi, those four hosted arms are the only ones whose no-op path writes no line. Every other site either logs its no-op or answers 404 on it.

Two facts hold the four silent, and neither is a plan. Issue #1018 (closed) states its own scope: it "takes the six single-target route arms and their tests, and nothing else". And package_delete.go:314 sits inside the block !2232 (merged) rewrote, where the !marked branch now emits the freed cache bytes instead of returning silently. That arm still writes no log line, so the count of four holds and only its second column moved.

One more claim is stale and stays as it is. internal/managementapi/npm_remote_version_delete_test.go:74-75 justifies its no-counter assertion with "no counter describes a cached row". This change falsifies that parenthetical for this route, and it was already false at the merge base, because the merged npm bulk remote worker emits for cached rows. This change appends one log test to that file, TestNpmRemoteVersionDelete_LostMarkRaceLogsTheVersionID at :391, and touches neither the comment nor the assertion it justifies.

A spec sentence is stale for the same reason, and it also stays as it is. docs/specs/S17-rest-management-api.md:659 says of artifacts_count and size_bytes that "none of the three is written here". Merged code on origin/main already falsifies it: nine single-target Phase 4 delete arms across five files in internal/managementapi reach emitDeleteCountersDetached, and four bulk-worker sites reach the same emit. This change widens that divergence from nine arms to fifteen rather than causing it. The counter semantics live in docs/dev/storage-accounting.md, which is where S22 redirects, and that is the document this change updates.

Merge order

This branch is rebased onto 16bc85e39, which is main with !2232 (merged) in it.

!2232 (merged), "fix(npm): credit the freed packument-cache bytes on every delete arm", merged into main at 16bc85e39 on 2026-09-03, minutes after this branch had been rebased onto e604815a4. Its collision with this branch went live rather than staying predicted, and this branch resolved all three conflicts because it merges second. git merge-tree --write-tree --name-only against 16bc85e39 reported the same three conflicting files the pre-merge measurement did: docs/dev/storage-accounting.md, docs/testing/e2e/npm.md and internal/managementapi/artifact_delete_counters_test.go. internal/managementapi/package_delete.go is the fourth shared file and it does not conflict, which is the last row below saying so. All three conflicts landed on the first replayed commit, and the table below carries each one's resolution.

Shared file The collision How it was resolved
docs/dev/storage-accounting.md Both rewrite the delete-target table's tombstone row. This branch widens the row's remote-arm sentence to the single-delete routes. !2232 (merged) splits the row and moves npm package onto a new one !2232 (merged)'s two-row split is kept, and this branch's rewritten middle column is carried onto the tombstone row. The two sides are disjoint by column: !2232 (merged) narrowed column 1 to npm version and left column 2 at its base text, this branch rewrote column 2 and left column 1 at its base text, and column 3 is untouched on both sides
docs/testing/e2e/npm.md Both rewrite the e2e.npm.lifecycle.management-delete-storage-counters row !2232 (merged)'s row is kept, and this branch's one sentence about the single-target remote routes is substituted into it. The two sides rewrite disjoint sentences of that row: !2232 (merged) the packument-cache credit and the mark-race exception, this branch only the sentence that had read "The single-target remote DELETE routes move no counter, and reconciliation is what corrects those rows"
internal/managementapi/artifact_delete_counters_test.go Both append at the end of the file, after TestTagDeletes_MoveNoCounter. This branch adds 375 lines there and !2232 (merged) adds 93 Both blocks are kept, !2232 (merged)'s 93 lines first and this branch's 375 after them. The merge base holds nothing at that point, so neither side touches a line the other added
internal/managementapi/package_delete.go No line collision. !2232 (merged) rewrites the NpmPackageDeleter interface block and npmHostedPackageDelete's !marked branch. This branch edits the two remote evict arms and one doc comment four lines below that interface block Merged with no hand resolution

One behavioural reading was checked before either documentation row was resolved. A conflict resolution cannot pick between two claims about the system, so that reading had to settle first. !2232 (merged)'s new sentence names "the package DELETE and the bulk job's package entry" as the arms whose packument cache rows come out whichever way the mark went. npmRemotePackageEvict at internal/managementapi/package_delete.go:332 emits deleteCounterTargetTombstone with hiddenArtifacts alone and no size delta. It also returns above that emit when the mark did not apply. So this branch's single-target remote arms sit outside that exception, and the two sides' claims hold together.

git range-diff --creation-factor=100 over the rebase reports four of the five commits byte-identical, and the first carrying the three resolutions above and nothing else.

An earlier rebase, onto 015d9974d, resolved a different conflict, in the ## Known gaps table of docs/dev/storage-accounting.md. Both sides edited a distinct row there and neither touched the other's line: this branch deletes the row for the six single-delete routes, and main rewrote the adjacent Eleven hand-rolled in-flight caps row. That resolution keeps both, so the table carries main's rewritten row and no longer carries the deleted one. The ## Known gaps table, the delete-target table and both remote grids are the regions to read first when main moves again, because they are where main and this branch both write.

Besides !2232 (merged), seven other open merge requests also edit docs/dev/storage-accounting.md. That figure is a sweep of the project's 87 open merge requests by changed path, run at 2026-09-03T02:20Z. One of the seven rewrites a line this branch removes from that file, and six do not.

!2262 (merged), "feat(oci): container remote fill emits its storage-accounting deltas", is the one. It rewrites the Maven remote cache fill row of the emit-site table, which is one of the ten lines this branch removes. This branch's replacement for that row keeps the clause "The container cache fill emits nothing — see #834 (closed)". !2262 (merged)'s replacement deletes that clause and points the row at a new Container remote cache fill row it inserts above. Both sides rewrite the same source line, so whichever merges second resolves that row by hand.

The other six were checked one at a time against the ten removed lines, by comparing the removed lines of each diff at 2026-09-03T02:20Z. None of the six removes or rewrites any of them. The removal counts each one carries on that file, which is what the comparison ran over, are !2272 (merged) 29 lines, !2162 (merged) 25, !2269 (merged) 3, !2230 (merged) 2, !2039 (merged) 2, and !2210 (merged) 1. None of the six is a merge-order dependency for this change. main took only !2232 (merged)'s commits between e604815a4 and 16bc85e39. So whichever of the six has merged since that sweep did not collide with this branch.

What ran, and what has not

The branch is five commits over 16bc85e39. ebb47233a carries the emit at the six arms and every documentation edit, and it is the commit that carries the three conflict resolutions above. bcbac7510 and 62c296493 change doc comments alone, six lines across the three route-handler files. e9ff3efec adds the INFO log at four arms, one import, four tests and two doc comments. d1567f95c states the package marks' over-decrement window in the two remote grids of docs/dev/storage-accounting.md, four lines.

These checks ran at d1567f95c, the branch head:

Check Result
go build ./... exit 0
go vet ./... exit 0
go test ./internal/managementapi/ -count=1 ok, 106.858s
golangci-lint 2.13.2 through mise exec --, --new-from-merge-base=origin/main ./... 0 issues
golangci-lint 2.13.2 through mise exec --, --build-tags=integration ./internal/managementapi/ 0 issues
scripts/ci/check-comment-caps.sh --base origin/main exit 0
markdownlint-cli2, vale and lychee through pre-commit, on the three changed Markdown files Passed

Both lint runs carried the flags --max-same-issues=0 --max-issues-per-linter=0 --uniq-by-line=false. The second run is the one CI cannot make: .golangci.yaml sets no run.build-tags, so the CI lint job never compiles the integration-tagged files. The three Markdown checks are re-run rather than carried over, because main rewrote all three of those files between 015d9974d and e604815a4, and !2232 (merged) rewrote two of them again at 16bc85e39.

The full pre-commit chain last ran at ae0473aac, with no bypass. This round added no commit of its own. It rebased, and the three resolutions went into the first replayed commit. A rebase does not run the hook chain over a replayed commit. The checks table above is what covers the resolved tree, and every one of those checks ran at d1567f95c.

driver.sh smoke against a binary built from this branch reported 73 passed, 0 failed. That run predates every rebase this branch has taken, as do the runtime exercises above. The rebase this round resolved three conflicts, all inside the first commit. It changed no other line this branch contributes, which is what the git range-diff in ## Merge order reports.

The merge request's pipeline is 2817707317, created by the rebase push onto 16bc85e39. It runs on refs/merge-requests/2270/merge, which is a synthesized merge commit rather than the branch head, so read the pipeline widget rather than matching its sha against the branch. No pipeline exists on the branch sha itself. It reported failed, on one job: editorconfig_check. That job fails across the project rather than on this branch. Its log reads /bin/sh: eval: line 330: ec: not found, and the job exits 127. The docker.io/mstruebing/editorconfig-checker image no longer carries the ec binary on its path, and the job pulls that image with the always policy. The same job failed the same way, with the same ec: not found and the same exit 127, on two unrelated merge requests. Those are !2306 (merged) pipeline 2817677356 at 17:31Z and !2271 (merged) pipeline 2817721054 at 17:45Z. The job passed on the pipeline this one supersedes, 2817530272 at ab6e770aa, which ran at 16:49Z and predates the regression. This branch's own content passes the check. The same common-ci-tasks editorconfig hook, run through pre-commit over every file this branch changes, passes. No code change is owed for that job, and this round made none. Each new commit supersedes the current pipeline in the same way, so read the merge request's own pipeline widget rather than any status quoted here.

The branch validation returned advisories only, with no blocker. That pass ran no test and reached neither Postgres nor Redis, so on its own it says nothing about whether the branch passes.

No conformance suite was run. The diff carries no Maven, npm or OCI protocol code, so no conformance suite can observe it.

Related to #1018 (closed)

The form is Related to rather than Closes, and the reason is the validation pass's own: all 19 acceptance items were derived by this run's enricher, since the issue declares no Acceptance section at all, so closing on them would remove the author's chance to disagree with the run's reading. What remains is that reading itself. The author decides whether the 19 items are what the issue asked for, and closes the issue when satisfied.

This is a bot message 🤖 — /smurfit

Edited by Pawel Rozlach

Merge request reports

Loading
Loading