mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-09-05 23:26:06 +00:00
0928765232
* fix(git): make gitSourceStatus exhaustive over GitSourceErrorCode GIT_ERROR was the only code falling through the implicit default branch. Give it an explicit case and add the same never-guard webhookPullStatus already uses, so a future code with no mapping is a compile error instead of a silent 400. * fix(git): fail loudly under CI when git or sshd is missing Every real-git and real-sshd integration suite carried its own local gitAvailable()/sshdAvailable() probe and skipped silently when the dependency was absent, in CI as well as locally. A cell in the upcoming support matrix could then advertise automated proof while the test that proves it never ran. Consolidate into shared requireGitBinary()/requireSshd() helpers (one for backend vitest, one for Playwright, since backend's rootDir pin blocks a cross-directory import) that take an injectable probe. Locally a missing dependency still skips; under CI it throws with an actionable message naming what's missing. * feat(docs): publish a versioned Git transport support matrix Adds docs/git-transport-support.yaml as the canonical claim set for every transport/ref/auth/host/CA combination Git Sources supports, each claim naming its own reproducible evidence rather than generalizing from a related test. A claim is supported only when a real end-to-end test (or a dated live attestation) proves that exact combination; everything else is marked unverified, never assumed. The published page (docs/features/git-transport-support.mdx) is generated from the YAML by backend/scripts/git-support-matrix, so it cannot silently drift from what the tests actually prove. A new backend test (git-support-matrix.test.ts) enforces this: schema validity, evidence semantics (supported needs success evidence, unsupported needs a reproducible rejection, unverified forbids evidence entirely), byte-identical page generation, and that every referenced test title resolves via the TypeScript AST rather than a string search that a skipped or commented-out test would pass. The error-model section is cross-checked against the real GitSourceErrorCode and TransportFacingCode unions and against gitSourceStatus's actual HTTP mapping, so the matrix and the runtime behavior cannot diverge either. Named Git hosts (GitHub, GitLab, Gitea, Forgejo, Bitbucket) and the direct-proxy/Pilot execution paths are seeded as unverified pending a live attestation pass; only the generic local-fixture combinations already proven by the real-git integration suites are marked supported today. * docs(git): scope GitHub claims to what this pass can actually attest Splits the GitHub row into a public no-auth claim (attestable with a real public repository) and separate PAT/SSH deploy-key claims marked unverified with an explicit reason: this pass holds no real GitHub credential to exercise them with, and none is assumed or fabricated. * feat(docs): attest the Git transport matrix live against real hosts Runs the QA fleet's live Sencho instance through the transport combinations that automated fixtures cannot exercise, then records each result in docs/git-transport-attestations.yaml so it can be re-run and compared later. GitHub, GitLab, and Bitbucket are attested over public HTTPS against real, stable, publicly-owned demo repositories (branch and pinned SHA; GitLab additionally has a tagged fixture). Gitea and Forgejo get full coverage (branch, tag, and SHA, over both HTTPS with a per-source CA and SSH with a deploy key) against disposable self-hosted instances stood up for this pass, including a private repository so the authentication and host-key failure classifiers were exercised against a real wrong credential and a real wrong host key, not just the mocked corpus. The direct-proxy and Pilot execution paths are each confirmed once against a real public host, proving the distributed dispatch itself rather than assuming it from the local-path evidence. Left honestly unverified: GitHub PAT and SSH deploy-key auth (this pass holds no real GitHub credential), a GitHub tag combination (no small stable tagged fixture found), and a Bitbucket tag combination (the fixture repository carries none). Every claim's evidence records its exact transport, ref, auth, host, CA, and node path so nothing here is extrapolated from a neighboring result. All infrastructure created for this pass (two throwaway Git server containers, one probe stack) was torn down afterward and the fleet's container list was confirmed to match its state before the pass. * style(git): replace em dashes and fix a stale .mjs reference Directive 18 applies to code comments and build markers too, not just prose. Also corrects the claim set's header comment, which still named render.mjs after the renderer was moved to render.js to match the house convention for backend scripts.
632 lines
22 KiB
YAML
632 lines
22 KiB
YAML
# Git transport support matrix: canonical source of truth (SEN-9 PR 5).
|
|
#
|
|
# Every entry here is a claim about one exercised combination, not an
|
|
# independently-tested dimension: a PAT test, a tag test, and a GitLab
|
|
# observation do not jointly prove "GitLab + PAT + tag" unless something
|
|
# actually ran that exact combination. `docs/features/git-transport-support.mdx`
|
|
# is generated from this file (backend/scripts/git-support-matrix/render.js);
|
|
# a backend test (git-support-matrix.test.ts) enforces byte-for-byte parity
|
|
# and validates every rule below. Internal test paths, PR numbers, and Linear
|
|
# IDs never appear on the published page; they live here instead.
|
|
#
|
|
# Schema (schema: matrix-v1):
|
|
# implementation_baseline: the git commit this file's claims describe.
|
|
# claims[]: one entry per exercised (transport, ref, auth, host, ca,
|
|
# node_path[, port]) combination.
|
|
# - support: supported | unsupported | unverified
|
|
# - supported requires evidence with outcome: success
|
|
# - unsupported requires evidence with outcome: rejected (a reproducible
|
|
# refusal, not silence; an unsupported claim with no evidence is as
|
|
# unreproducible as an unproven supported one)
|
|
# - unverified forbids evidence entirely
|
|
# - evidence.kind: automated (a handle into a test file + exact test
|
|
# title) or live (a pointer into docs/git-transport-attestations.yaml).
|
|
# Every evidence record repeats all six combination dimensions, and the
|
|
# validator requires them to match the claim exactly: a direct-proxy
|
|
# result proves the direct-proxy combination, nothing else.
|
|
# limitations[]: named gaps, each with its operator-facing consequence.
|
|
# error_model[]: the transport-facing error codes this matrix covers
|
|
# (TransportFacingCode plus REF_DELETED and FILE_NOT_FOUND), each with
|
|
# its HTTP status and one-line meaning. GitOps plan-lifecycle codes
|
|
# (STALE_PLAN, PLAN_FINGERPRINT_REQUIRED, PLAN_BLOCKED, LEGACY_PENDING,
|
|
# PLAN_UNAVAILABLE, OPERATION_IN_FLIGHT) belong to reconciliation, not
|
|
# transport, and are listed separately so the partition is visible.
|
|
# attestations: pointer to the retained live-evidence file.
|
|
|
|
version: '1'
|
|
schema: 'matrix-v1'
|
|
implementation_baseline: 79b86ddcd4aefdd6941f098e35990ab397b13c72
|
|
attestations: docs/git-transport-attestations.yaml
|
|
|
|
claims:
|
|
# ===== Automated: real git, real TLS/SSH, against a local fixture server =====
|
|
# host: generic, node_path: local for all of these: no proxy hop, no
|
|
# branded host. Branded-host and non-local node-path claims live below,
|
|
# pending or drawn from the live attestation pass.
|
|
|
|
- id: https-pat-branch-system-generic-local
|
|
transport: https
|
|
ref: branch
|
|
auth: pat
|
|
host: generic
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- History rewritten on this ref after resolution is detected and rejected as non-fast-forward, not silently deployed.
|
|
evidence:
|
|
kind: automated
|
|
outcome: success
|
|
handles:
|
|
- file: backend/src/__tests__/git-transport-auth.integration.test.ts
|
|
title: clones a private repo end-to-end with a valid token
|
|
- file: backend/src/__tests__/git-transport-auth.integration.test.ts
|
|
title: treats a linear branch advance as a fast-forward
|
|
- file: backend/src/__tests__/git-transport-auth.integration.test.ts
|
|
title: treats a multi-commit branch advance as a fast-forward
|
|
- file: backend/src/__tests__/git-transport-auth.integration.test.ts
|
|
title: rejects rewritten history as non-fast-forward
|
|
|
|
- id: https-pat-tag-system-generic-local
|
|
transport: https
|
|
ref: tag
|
|
auth: pat
|
|
host: generic
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Proven for both an annotated tag (peeled through its ^{} commit) and a lightweight tag.
|
|
evidence:
|
|
kind: automated
|
|
outcome: success
|
|
handles:
|
|
- file: backend/src/__tests__/git-transport-auth.integration.test.ts
|
|
title: resolves and fetches an annotated tag through the peeled commit
|
|
- file: backend/src/__tests__/git-transport-auth.integration.test.ts
|
|
title: resolves and fetches a lightweight tag
|
|
|
|
- id: https-pat-sha-system-generic-local
|
|
transport: https
|
|
ref: sha
|
|
auth: pat
|
|
host: generic
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers: []
|
|
evidence:
|
|
kind: automated
|
|
outcome: success
|
|
handles:
|
|
- file: backend/src/__tests__/git-transport-auth.integration.test.ts
|
|
title: resolves and fetches a pinned commit SHA
|
|
|
|
- id: https-none-branch-persource-generic-local
|
|
transport: https
|
|
ref: branch
|
|
auth: none
|
|
host: generic
|
|
ca: per-source
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Also proven to survive a same-origin redirect (the repository relocating on the same host).
|
|
evidence:
|
|
kind: automated
|
|
outcome: success
|
|
handles:
|
|
- file: backend/src/__tests__/git-private-ca.integration.test.ts
|
|
title: clones a private-CA HTTPS repo when the per-source CA PEM is supplied
|
|
- file: backend/src/__tests__/git-redirect.integration.test.ts
|
|
title: resolves a ref through an unauthenticated same-host redirect
|
|
|
|
- id: https-pat-branch-persource-generic-local
|
|
transport: https
|
|
ref: branch
|
|
auth: pat
|
|
host: generic
|
|
ca: per-source
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Proven through a same-origin redirect; the token is forwarded to the relocated path and never offered to a different host.
|
|
evidence:
|
|
kind: automated
|
|
outcome: success
|
|
handles:
|
|
- file: backend/src/__tests__/git-redirect.integration.test.ts
|
|
title: resolves a ref through an authenticated same-host redirect and sends the token to the relocated path
|
|
|
|
- id: ssh-deploy-key-branch-na-generic-local-nonstandard-port
|
|
transport: ssh
|
|
ref: branch
|
|
auth: deploy-key
|
|
host: generic
|
|
ca: not-applicable
|
|
node_path: local
|
|
port: nonstandard
|
|
support: supported
|
|
qualifiers:
|
|
- Full round trip (resolve, fetch, and content verification) proven at this port.
|
|
evidence:
|
|
kind: automated
|
|
outcome: success
|
|
handles:
|
|
- file: backend/src/__tests__/git-transport-ssh.integration.test.ts
|
|
title: resolves and fetches over SSH with a deploy key and trusted host key
|
|
- file: backend/src/__tests__/git-transport-ssh.integration.test.ts
|
|
title: 'resolves over ssh:// with a nonstandard port'
|
|
|
|
- id: ssh-deploy-key-branch-na-generic-local-default-port
|
|
transport: ssh
|
|
ref: branch
|
|
auth: deploy-key
|
|
host: generic
|
|
ca: not-applicable
|
|
node_path: local
|
|
port: default
|
|
support: supported
|
|
qualifiers:
|
|
- Ref resolution proven at the default port; the full content fetch is proven only at a nonstandard port (see the sibling claim), not separately re-run here.
|
|
evidence:
|
|
kind: automated
|
|
outcome: success
|
|
handles:
|
|
- file: backend/src/__tests__/git-transport-ssh.integration.test.ts
|
|
title: resolves over scp-style URL on the default SSH port
|
|
|
|
# ===== Live: named Git hosts, external SaaS and self-hosted =====
|
|
# Evidence lives in docs/git-transport-attestations.yaml. A row stays
|
|
# `unverified` (no evidence permitted) until a live pass actually exercises
|
|
# it; nothing here is extrapolated from a different host or node_path.
|
|
# Live-attested 2026-09-01 (see the attestation ids referenced below).
|
|
|
|
- id: https-none-branch-system-github-local
|
|
transport: https
|
|
ref: branch
|
|
auth: none
|
|
host: github
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; GitHub does not receive a token or an SSH deploy key from this attestation.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-github-branch
|
|
|
|
- id: https-none-tag-system-github-local
|
|
transport: https
|
|
ref: tag
|
|
auth: none
|
|
host: github
|
|
ca: system
|
|
node_path: local
|
|
support: unverified
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; GitHub does not receive a token or an SSH deploy key from this attestation.
|
|
- Not attested: no small, stable, publicly tagged GitHub repository was found for this pass within a reasonable search.
|
|
|
|
- id: https-none-sha-system-github-local
|
|
transport: https
|
|
ref: sha
|
|
auth: none
|
|
host: github
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; GitHub does not receive a token or an SSH deploy key from this attestation.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-github-sha
|
|
|
|
- id: https-pat-branch-system-github-local
|
|
transport: https
|
|
ref: branch
|
|
auth: pat
|
|
host: github
|
|
ca: system
|
|
node_path: local
|
|
support: unverified
|
|
qualifiers:
|
|
- Not attested: requires a real GitHub Personal Access Token, which this pass does not hold.
|
|
|
|
- id: ssh-deploy-key-branch-na-github-local
|
|
transport: ssh
|
|
ref: branch
|
|
auth: deploy-key
|
|
host: github
|
|
ca: not-applicable
|
|
node_path: local
|
|
support: unverified
|
|
qualifiers:
|
|
- Not attested: requires a real GitHub-registered SSH deploy key, which this pass does not hold.
|
|
|
|
- id: https-pat-branch-persource-gitea-local
|
|
transport: https
|
|
ref: branch
|
|
auth: pat
|
|
host: gitea
|
|
ca: per-source
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Attested against a private repository on a disposable, self-signed Gitea instance; the self-signed certificate is trusted via the per-source custom CA field, not system trust.
|
|
- A wrong token against this private repository was separately confirmed to classify as an authentication failure, and a wrong SSH host key as a host-key mismatch.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitea-https-branch
|
|
|
|
- id: https-pat-tag-persource-gitea-local
|
|
transport: https
|
|
ref: tag
|
|
auth: pat
|
|
host: gitea
|
|
ca: per-source
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Annotated tag, resolved through its peeled commit.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitea-https-tag
|
|
|
|
- id: https-pat-sha-persource-gitea-local
|
|
transport: https
|
|
ref: sha
|
|
auth: pat
|
|
host: gitea
|
|
ca: per-source
|
|
node_path: local
|
|
support: supported
|
|
qualifiers: []
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitea-https-sha
|
|
|
|
- id: ssh-deploy-key-branch-na-gitea-local
|
|
transport: ssh
|
|
ref: branch
|
|
auth: deploy-key
|
|
host: gitea
|
|
ca: not-applicable
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Host key fetched and trusted through Sencho's own probe endpoint, exactly as an operator would.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitea-ssh-branch
|
|
|
|
- id: ssh-deploy-key-tag-na-gitea-local
|
|
transport: ssh
|
|
ref: tag
|
|
auth: deploy-key
|
|
host: gitea
|
|
ca: not-applicable
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Lightweight tag.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitea-ssh-tag
|
|
|
|
- id: ssh-deploy-key-sha-na-gitea-local
|
|
transport: ssh
|
|
ref: sha
|
|
auth: deploy-key
|
|
host: gitea
|
|
ca: not-applicable
|
|
node_path: local
|
|
support: supported
|
|
qualifiers: []
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitea-ssh-sha
|
|
|
|
- id: https-pat-branch-persource-forgejo-local
|
|
transport: https
|
|
ref: branch
|
|
auth: pat
|
|
host: forgejo
|
|
ca: per-source
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Attested against a private repository on a disposable, self-signed Forgejo instance; the self-signed certificate is trusted via the per-source custom CA field, not system trust.
|
|
- A wrong token against this private repository was separately confirmed to classify as an authentication failure, and a wrong SSH host key as a host-key mismatch.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-forgejo-https-branch
|
|
|
|
- id: https-pat-tag-persource-forgejo-local
|
|
transport: https
|
|
ref: tag
|
|
auth: pat
|
|
host: forgejo
|
|
ca: per-source
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Annotated tag, resolved through its peeled commit.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-forgejo-https-tag
|
|
|
|
- id: https-pat-sha-persource-forgejo-local
|
|
transport: https
|
|
ref: sha
|
|
auth: pat
|
|
host: forgejo
|
|
ca: per-source
|
|
node_path: local
|
|
support: supported
|
|
qualifiers: []
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-forgejo-https-sha
|
|
|
|
- id: ssh-deploy-key-branch-na-forgejo-local
|
|
transport: ssh
|
|
ref: branch
|
|
auth: deploy-key
|
|
host: forgejo
|
|
ca: not-applicable
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Host key fetched and trusted through Sencho's own probe endpoint, exactly as an operator would.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-forgejo-ssh-branch
|
|
|
|
- id: ssh-deploy-key-tag-na-forgejo-local
|
|
transport: ssh
|
|
ref: tag
|
|
auth: deploy-key
|
|
host: forgejo
|
|
ca: not-applicable
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Lightweight tag.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-forgejo-ssh-tag
|
|
|
|
- id: ssh-deploy-key-sha-na-forgejo-local
|
|
transport: ssh
|
|
ref: sha
|
|
auth: deploy-key
|
|
host: forgejo
|
|
ca: not-applicable
|
|
node_path: local
|
|
support: supported
|
|
qualifiers: []
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-forgejo-ssh-sha
|
|
|
|
- id: https-none-branch-system-gitlab-local
|
|
transport: https
|
|
ref: branch
|
|
auth: none
|
|
host: gitlab
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; GitLab does not receive a token or an SSH deploy key from this attestation.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitlab-branch
|
|
|
|
- id: https-none-tag-system-gitlab-local
|
|
transport: https
|
|
ref: tag
|
|
auth: none
|
|
host: gitlab
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; GitLab does not receive a token or an SSH deploy key from this attestation.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitlab-tag
|
|
|
|
- id: https-none-sha-system-gitlab-local
|
|
transport: https
|
|
ref: sha
|
|
auth: none
|
|
host: gitlab
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; GitLab does not receive a token or an SSH deploy key from this attestation.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-gitlab-sha
|
|
|
|
- id: https-none-branch-system-bitbucket-local
|
|
transport: https
|
|
ref: branch
|
|
auth: none
|
|
host: bitbucket
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; Bitbucket does not receive a token or an SSH deploy key from this attestation.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-bitbucket-branch
|
|
|
|
- id: https-none-tag-system-bitbucket-local
|
|
transport: https
|
|
ref: tag
|
|
auth: none
|
|
host: bitbucket
|
|
ca: system
|
|
node_path: local
|
|
support: unverified
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; Bitbucket does not receive a token or an SSH deploy key from this attestation.
|
|
- Not attested: the public fixture repository used for this pass carries no tags.
|
|
|
|
- id: https-none-sha-system-bitbucket-local
|
|
transport: https
|
|
ref: sha
|
|
auth: none
|
|
host: bitbucket
|
|
ca: system
|
|
node_path: local
|
|
support: supported
|
|
qualifiers:
|
|
- Only a public, read-only repository is exercised; Bitbucket does not receive a token or an SSH deploy key from this attestation.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-bitbucket-sha
|
|
|
|
# ===== Distribution: does the same combination hold off the local node =====
|
|
# Scoped to host: github (a real branded host reachable over public egress)
|
|
# rather than the self-hosted fixtures above: the fleet's inbound firewall
|
|
# only opens ports 22 and 1852, so a remote or Pilot node cannot reach a
|
|
# container port newly published on the hub, but every node has unrestricted
|
|
# outbound egress to the public internet.
|
|
|
|
- id: https-none-branch-system-github-direct-proxy
|
|
transport: https
|
|
ref: branch
|
|
auth: none
|
|
host: github
|
|
ca: system
|
|
node_path: direct-proxy
|
|
support: supported
|
|
qualifiers:
|
|
- Proves the direct-proxy path forwards and executes the fetch on the target node; it does not by itself prove any other host, ref, auth, or CA combination on this path.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-github-direct-proxy
|
|
|
|
- id: https-none-branch-system-github-pilot
|
|
transport: https
|
|
ref: branch
|
|
auth: none
|
|
host: github
|
|
ca: system
|
|
node_path: pilot
|
|
support: supported
|
|
qualifiers:
|
|
- Proves the Pilot dial-out path forwards and executes the fetch on the target node; it does not by itself prove any other host, ref, auth, or CA combination on this path.
|
|
evidence:
|
|
kind: live
|
|
outcome: success
|
|
attestation: att-2026-09-01-github-pilot
|
|
|
|
limitations:
|
|
- id: no-rate-limit-classification
|
|
title: No rate-limit classification
|
|
statement: A Git host rate-limit response (for example GitHub's secondary rate limits) is not classified as its own error state. It surfaces as an authentication failure or a generic transport error depending on the host's exact response. Wait and retry; there is no dedicated rate-limit message or backoff guidance yet.
|
|
|
|
- id: no-git-lfs
|
|
title: No Git LFS
|
|
statement: Compose and env files tracked via Git LFS are rejected rather than silently fetched as pointer stubs. Commit plain files instead.
|
|
|
|
- id: no-submodules
|
|
title: No submodules
|
|
statement: Submodule contents are not fetched. Inputs and build contexts that reference submodule contents are refused with an actionable message; a warning is shown when .gitmodules is present.
|
|
|
|
- id: no-sparse-partial-clone
|
|
title: No sparse or partial clone
|
|
statement: Every fetch materializes the complete repository at the resolved commit (shallow, single-branch); there is no sparse or partial clone for large monorepos.
|
|
|
|
- id: no-github-app-authentication
|
|
title: No GitHub App authentication
|
|
statement: Authentication is Personal Access Token or SSH deploy key only. GitHub App installation tokens are not supported.
|
|
|
|
- id: no-provider-pull-request-revisions
|
|
title: No provider pull/merge request revisions
|
|
statement: Sources track a branch, a tag, or a pinned commit SHA. A provider-specific pull request or merge request revision (for example GitHub's refs/pull/N/head) is not a supported ref shape.
|
|
|
|
- id: outbound-target-restrictions
|
|
title: Outbound target restrictions
|
|
statement: Repository targets that resolve to loopback, link-local, multicast, or selected special-use addresses are refused before any request is sent. Private hosts on an operator's own LAN or VPN are not affected by this restriction.
|
|
|
|
- id: branch-tag-name-collision
|
|
title: Branch/tag name collisions
|
|
statement: A bare ref name resolves as a branch first, then as a tag. If an operator renames a branch and a tag of the same name later appears, the source silently starts resolving the tag instead. A ref name that is also a valid 40 or 64 character hex string resolves as a commit SHA before either lookup.
|
|
|
|
error_model:
|
|
- code: REPO_NOT_FOUND
|
|
label: Repository not found
|
|
status: 404
|
|
meaning: The repository does not exist, or (indistinguishably, matching GitHub's own private-repo masking) exists but is private and no usable credential was supplied.
|
|
- code: AUTH_FAILED
|
|
label: Authentication failed
|
|
status: 400
|
|
meaning: The Git host rejected the supplied credential. Mapped to 400, never 401, so an upstream Git-host auth failure never triggers the dashboard's own session logout.
|
|
- code: SSH_HOST_KEY_FAILED
|
|
label: SSH host key mismatch
|
|
status: 400
|
|
meaning: The server's SSH host key does not match the fingerprint trusted for this source.
|
|
- code: REF_NOT_FOUND
|
|
label: Ref not found
|
|
status: 404
|
|
meaning: The configured branch, tag, or commit SHA does not exist on the remote.
|
|
- code: REF_DELETED
|
|
label: Ref deleted or rewritten
|
|
status: 404
|
|
meaning: A ref that previously resolved to a commit no longer matches that history (deleted, force-pushed, or superseded by a same-named tag).
|
|
- code: UNSUPPORTED_REF
|
|
label: Commit not reachable on this host
|
|
status: 400
|
|
meaning: A pinned commit SHA that the Git host will not serve because it is not advertised by any branch or tag tip.
|
|
- code: NETWORK_TIMEOUT
|
|
label: Network timeout
|
|
status: 504
|
|
meaning: A connect, fetch, or DNS-resolution timeout, or a target the host actively refused.
|
|
- code: GIT_ERROR
|
|
label: Git error
|
|
status: 400
|
|
meaning: Any other transport failure not covered above (invalid URL, disallowed target, TLS/certificate problem, oversized repository, canceled fetch), classified with a specific operator-facing message.
|
|
- code: FILE_NOT_FOUND
|
|
label: File not found
|
|
status: 404
|
|
meaning: A configured compose or env file path does not exist on the resolved commit.
|
|
|
|
reconciliation_only_codes:
|
|
# Not part of this transport matrix; listed so the partition of
|
|
# GitSourceErrorCode is visible and auditable. Owned by the GitOps
|
|
# change-plan lifecycle, not by repository transport.
|
|
- STALE_PLAN
|
|
- PLAN_FINGERPRINT_REQUIRED
|
|
- PLAN_BLOCKED
|
|
- LEGACY_PENDING
|
|
- PLAN_UNAVAILABLE
|
|
- OPERATION_IN_FLIGHT
|