Roadmap item 6: Add inactive GitLab forge normalizer payload - #239
Conversation
First alternative forge. adapters/gitlab-forge/v1/normalize.jq validates one untrusted GitLab merge-request snapshot against caller-supplied project, merge-request iid, head, base, bot-user, time, instruction, and config bindings and returns the same canonical generic observation the GitHub forge returns: open-ready, open-blocked, closed-unmerged, merged, stale, or inconclusive, with the same output keys, effect boundary, and stale-binding shape, so a profile can swap one forge for the other. GitLab vocabulary stays at the edge: a locked request and a checking or unchecked merge status are inconclusive, a merged request is never also closed, a closed or merged request carries no merge status, and the acting identity is the bot user the integration runs as, since GitLab has no app id. Provider metadata stays opaque data; GitHub-shaped states, mergeability values, and trust contexts are refused. Pure jq, offline, unqualified: no GitLab or CLI call, credential, project or merge-request change, authority, qualification, or profile activation. The test proves the contract equals the GitHub forge's output contract key for key. Proof: scripts/test/default-gitlab-forge-adapter.test.sh 54/54, shellcheck 0.11.0 clean, rename gate clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Deploying ystack with
|
| Latest commit: |
2c61065
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c70464c8.fabrica-6yx.pages.dev |
| Branch Preview URL: | https://ystack-roadmap-6-gitlab-forg.fabrica-6yx.pages.dev |
The test imports the public schema module to check reference shapes, the same way the GitHub forge test does, so it joins that closed allowlist. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex reviewer (cross-vendor, read-only)Reviewed-head: ade23b7 Posted verbatim by The new GitLab normalizer rejects common GitLab merge-request API status values, so it will fail for ordinary mergeable or blocked GitLab MRs. The issue is localized but blocks the adapter's main purpose. Review comment:
|
Review finding on the previous head: the snapshot used an invented merge-status vocabulary, so an ordinary GitLab merge request could not be normalized. The snapshot now carries detailed_merge_status with GitLab's documented values. mergeable is open-ready; the fourteen blocking values are open-blocked; the four transitional values are inconclusive (gitlab.merge-status-unsettled); not_open belongs only to a closed or merged request. An invented value, the legacy merge_status field, a GitHub-shaped value, or not_open on an open request is refused. scripts/test/default-gitlab-forge-adapter.test.sh 71/71, shellcheck 0.11.0 clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex reviewer (cross-vendor, read-only)Reviewed-head: fea2ff9 Posted verbatim by The new GitLab normalizer rejects a valid documented merge status, so it will fail for security-policy-blocked merge requests despite the intended GitLab API coverage. Review comment:
|
Review finding on the previous head: security_policy_violations, a documented GitLab detailed_merge_status value, was refused as an invalid snapshot. The blocking set now carries all twenty documented blocking values, including security_policy_violations, status_checks_must_pass, merge_request_blocked, merge_time, locked_paths, and locked_lfs_files; each normalizes an open request to open-blocked. scripts/test/default-gitlab-forge-adapter.test.sh 76/76, shellcheck 0.11.0 clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex reviewer (cross-vendor, read-only)Reviewed-head: 4b7365d Posted verbatim by The GitLab normalizer misclassifies a transient CI-running merge status as a blocked merge request. This can produce incorrect forge observations once the adapter is wired in. Review comment:
|
Review finding on the previous head: ci_still_running was normalized to open-blocked, but it settles on its own once the pipeline finishes, like checking or preparing. It is now transitional and normalizes to inconclusive (gitlab.merge-status-unsettled); ci_must_pass stays blocking because it names a failed requirement. scripts/test/default-gitlab-forge-adapter.test.sh 76/76, shellcheck 0.11.0 clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex reviewer (cross-vendor, read-only)Reviewed-head: 633603a Posted verbatim by No actionable correctness issues were found in the added GitLab forge normalizer, tests, or manifest updates. |
Codex reviewer (cross-vendor, read-only)Reviewed-head: ccf060c Posted verbatim by The GitLab normalizer otherwise follows the existing adapter shape, but it accepts a contradictory Review comment:
|
Review finding: an unknown state accepted detailed_merge_status not_open, although that value belongs only to a closed or merged request. The unknown branch now refuses it, like the opened and locked branches. Regression added. default-gitlab-forge-adapter 77/77, shellcheck 0.11.0 clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex reviewer (cross-vendor, read-only)Reviewed-head: 2c61065 Posted verbatim by I found no discrete correctness issues in the added inactive GitLab forge normalizer, its manifest entry, or the accompanying tests/docs. |
Summary
adapters/gitlab-forge/v1/normalize.jqvalidates one untrusted GitLab merge-request snapshot against caller-supplied project, merge-request iid, head, base, bot-user, time, instruction, and config bindings and returns the same canonical generic observation the GitHub forge returns (open-ready, open-blocked, closed-unmerged, merged, stale, inconclusive) with the same output keys, effect boundary, and stale-binding shape, so a profile can swap one forge for the other.maindirectly; not stacked on the item 5 eval stack.Same contract as the GitHub forge
The test normalizes a GitHub and a GitLab baseline side by side and requires identical output keys, identical adapter keys, and identical non-provider content (state, stale bindings, authority, qualification, effects). The six generic states appear in both payloads by name.
Inactive boundary
Pure jq, offline, unqualified: no GitLab or CLI call, credential, project or merge-request change, authority, qualification, or profile activation. The test greps the payload for any network, shell, or provider-host reference.
Exact candidate
25667e9mainata637451adapters/gitlab-forge/v1/normalize.jq(new),scripts/test/default-gitlab-forge-adapter.test.sh(new),README.md,ci/required-files.txtCurrent-head local proof
bash scripts/test/default-gitlab-forge-adapter.test.sh— 54/54 checks passedFresh CI and a fresh independent review are required for this head.