You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature] GitLab provider and qualification (PR-5) #166
Multi-Forge's initial target includes GitLab.com as a supported release source,
distributed through the GitLab Releases API and the Generic Package Registry with
the same integrity chain as GitHub. The v1 target excludes Self-Managed until
qualified. No GitLab provider exists today.
A GitLab.com release provider whose Release + Package identities are provably the
same project, whose integrity anchors come from the package file API, whose
object-storage redirects strip credentials, and whose secret patterns are
mandatory — plus a qualification report covering exactly the declared tuples.
Acceptance criteria
Blocked until PR-4 green.
PR-5A — Provider config requires provider, api_base_url, auth_origin, api_version, release_project_ref, credential_source; release_project_ref is a numeric project ID, namespace/project or namespace/subgroup/project — never a URL.
Single-project invariant: the exact same project identity is used for the
Releases API, the Generic Package Registry and package files; no separate
release/package project configuration.
PR-5B — Release discovery uses GitLab Releases for release discovery,
version and presentation; Release Link URLs are never integrity roots.
PR-5C — Generic Package Registry is the canonical distribution/integrity
surface: exact package match (type == generic, canonical package name,
selected release version), exactly one required.
Pagination: enumerate all relevant package records within configured bounds;
bounds reached before exhaustion → RELEASE_ENUMERATION_INCOMPLETE; partial
results are never used silently.
Manifest lookup: canonical filename ainative-release-v3.json; exactly one
match required; 0 → RELEASE_MANIFEST_MISSING; >1 → RELEASE_MANIFEST_AMBIGUOUS.
Integrity metadata from the package-file API: file_sha256 + size;
absent → RELEASE_INTEGRITY_METADATA_MISSING; malformed → RELEASE_INTEGRITY_METADATA_INVALID.
Object storage: cross-origin redirect on a metadata request → DENY;
authenticated blob request → redirect to object storage → strip all GitLab
credentials → follow HTTPS → verify expected digest.
Mandatory secret patterns: scanner contract moved from secret_patterns=<replacement> to extra_secret_patterns=();
effective set = MANDATORY_SECRET_PATTERNS ∪ operator extras. Repository
configuration can never remove, replace, disable or shadow mandatory
patterns. Retained at minimum: private key markers, existing AWS/GitHub/
Slack patterns, documented GitLab token prefixes.
Self-Managed qualification tuple includes access_token_prefix (default or
custom); a custom prefix requires an operator extra pattern plus a fixture
proving detection; otherwise the tuple stays unqualified.
Qualification: GitLab.com always qualified; Self-Managed qualified only if
an environment is available, otherwise UNTESTED and NOT declared supported
(never block the V1 release for missing Self-Managed infrastructure).
GHES remains undeclared; architecture may stay compatible; qualification
checklist recorded for later.
Purity tests: tests/purity/test_dependency_purity.py, test_contract_purity.py, test_distributed_policy_purity.py — neutral
modules do not depend on provider implementations; provider-neutral helpers
work on canonical GitHub and GitLab records; distributed policy contains no
hard-coded GitHub authority outside explicit provider mappings. No global
grep-based ban.
Documentation parity automation for EN/FR (heading hierarchy, support matrix
keys, critical security sections, release compatibility statements, known
limitations) — no raw line-count equality.
Out of scope
GHES, Bitbucket, Azure DevOps, Forgejo/Gitea.
Universal Forge SDK, generic ForgeHttpClient.
Claiming Self-Managed support without qualification evidence.
Context
ainative/lifecycle/provider.py (PR-4 contract).
ADR-MF-03 (GitLab release/package decisions and mandatory pattern policy).
Multi-Forge implementation merged into dev (squash f0101fc via PR #172), full CI matrix green (52/52: Linux/Windows/macOS, py3.11/3.13). The Issue stays open until the final dev -> main promotion, per the maintainer rule that main is untouched until everything is tested and integrated.
The follow-up increment (mandatory secret-pattern floor, scenarios J/M/P, documentation parity) is merged into dev (squash a8e1fb6 via PR #174, CI 76/76 green). The Issue stays open until the final dev -> main promotion.
GitLab.com live qualification recorded and merged into dev (PR #175): Generic Package Registry anchor, managed release discovery, exact version chain and the exact-runtime gate all verified against the real API; SUPPORT.md now declares GitLab.com supported (Self-Managed/GHES remain UNTESTED, not supported).
Problem
Multi-Forge's initial target includes GitLab.com as a supported release source,
distributed through the GitLab Releases API and the Generic Package Registry with
the same integrity chain as GitHub. The v1 target excludes Self-Managed until
qualified. No GitLab provider exists today.
Source: Multi-Forge v1.3.2-final §60–73 (PR-5, PR-5A–5C).
Expected outcome
A GitLab.com release provider whose Release + Package identities are provably the
same project, whose integrity anchors come from the package file API, whose
object-storage redirects strip credentials, and whose secret patterns are
mandatory — plus a qualification report covering exactly the declared tuples.
Acceptance criteria
provider,api_base_url,auth_origin,api_version,release_project_ref,credential_source;release_project_refis a numeric project ID,namespace/projectornamespace/subgroup/project— never a URL.Releases API, the Generic Package Registry and package files; no separate
release/package project configuration.
version and presentation; Release Link URLs are never integrity roots.
surface: exact package match (
type == generic, canonical package name,selected release version), exactly one required.
bounds reached before exhaustion →
RELEASE_ENUMERATION_INCOMPLETE; partialresults are never used silently.
ainative-release-v3.json; exactly onematch required; 0 →
RELEASE_MANIFEST_MISSING; >1 →RELEASE_MANIFEST_AMBIGUOUS.file_sha256+size;absent →
RELEASE_INTEGRITY_METADATA_MISSING; malformed →RELEASE_INTEGRITY_METADATA_INVALID.authenticated blob request → redirect to object storage → strip all GitLab
credentials → follow HTTPS → verify expected digest.
secret_patterns=<replacement>toextra_secret_patterns=();effective set =
MANDATORY_SECRET_PATTERNS∪ operator extras. Repositoryconfiguration can never remove, replace, disable or shadow mandatory
patterns. Retained at minimum: private key markers, existing AWS/GitHub/
Slack patterns, documented GitLab token prefixes.
access_token_prefix(default orcustom); a custom prefix requires an operator extra pattern plus a fixture
proving detection; otherwise the tuple stays unqualified.
an environment is available, otherwise UNTESTED and NOT declared supported
(never block the V1 release for missing Self-Managed infrastructure).
checklist recorded for later.
tests/purity/test_dependency_purity.py,test_contract_purity.py,test_distributed_policy_purity.py— neutralmodules do not depend on provider implementations; provider-neutral helpers
work on canonical GitHub and GitLab records; distributed policy contains no
hard-coded GitHub authority outside explicit provider mappings. No global
grep-based ban.
keys, critical security sections, release compatibility statements, known
limitations) — no raw line-count equality.
Out of scope
Context
ainative/lifecycle/provider.py(PR-4 contract).docs/RELEASING.md, support matrix documentation.Dependencies