fix(file-upload): dedup returns a FileRef without checking the blob still exists (#713) #49
Workflow file for this run
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
| # Fast governance checks (pipeline Phase 1+). Pure bash, no toolchain — | |
| # feedback in seconds, long before the build workflows finish. | |
| # | |
| # Jobs: | |
| # doctor — enforces "every pipeline asset registers a ./dev verb or carries | |
| # a reasoned exemption" (see scripts/doctor for the contract). | |
| # lint — the NeoHaskell dialect gate: hlint with the dialect-first | |
| # .hlint.yaml (vanilla-module restrictions, banned partials, | |
| # teaching hints). Standalone pinned binary — no nix needed. | |
| name: checks | |
| on: | |
| pull_request: | |
| # ready_for_review included so the spec job's drift gate fires the moment | |
| # a draft (parked spec) is promoted — default types would miss the flip | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| push: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: checks-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| doctor: | |
| name: dev doctor (verb registration) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| - run: ./dev doctor | |
| codemap: | |
| name: codemap check (localization ontology) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| # Same check.py as ./dev codemap-check; runner python + pinned pyyaml | |
| # (pulling the full nix dev shell for a YAML check is not worth 40m — | |
| # the PYTHON override is the sanctioned CI path, like lint's HLINT=). | |
| - run: python3 -c "import yaml" 2>/dev/null || pip3 install pyyaml==6.0.3 | |
| - run: PYTHON=python3 ./dev codemap-check | |
| spec: | |
| name: spec check (contract-delta gate) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| # spec-drift --pr diffs against the merge base — needs history | |
| fetch-depth: 0 | |
| # Structure gate: every committed spec (incl. TEMPLATE.md, which is a | |
| # validated instance) parses and machine-joins. Runs on drafts too — | |
| # this is what the maintainer's gate decision reads. | |
| - run: ./dev spec-check | |
| # Drift gate: at PR-READY only, the specs this PR touches must be | |
| # honored by the generated API surface (codemap-sync proves committed | |
| # signatures == code; this proves signatures == promise). A draft is | |
| # still implementing its spec — drift there is expected, not an error. | |
| - name: Spec drift (PR-ready only) | |
| if: github.event_name == 'pull_request' && github.event.pull_request.draft == false | |
| env: | |
| # env-var indirection, not inline ${{ }} in run: — the standard | |
| # template-injection defense-in-depth for workflow expressions | |
| BASE_REF: ${{ github.base_ref }} | |
| run: ./dev spec-drift --pr "origin/${BASE_REF}" | |
| # Review-record gate: at PR-ready, every COMMITTED design review a changed | |
| # spec ROUTES (touches ∩ perf-sensitive) must have its committed record. | |
| # Security reviews are local-only (gitignored, never pushed — they map | |
| # attack surface; ADR-0069), enforced on the dev machine via | |
| # `spec-check --reviews-local`, so CI's --reviews-pr gates only perf. | |
| - name: Design-review records present (PR-ready only) | |
| if: github.event_name == 'pull_request' && github.event.pull_request.draft == false | |
| env: | |
| BASE_REF: ${{ github.base_ref }} | |
| run: ./dev spec-check --reviews-pr "origin/${BASE_REF}" | |
| # Changelog gate: at PR-ready, every changed spec must have a CHANGELOG.md | |
| # entry (breaking ones with a migration note) — the changelog is generated, | |
| # not hand-written (Phase 6, task 3). | |
| - name: Changelog entries present (PR-ready only) | |
| if: github.event_name == 'pull_request' && github.event.pull_request.draft == false | |
| env: | |
| BASE_REF: ${{ github.base_ref }} | |
| run: ./dev changelog --check "origin/${BASE_REF}" | |
| # DoD criterion-test gate: at PR-ready, every criterion in a changed spec | |
| # must name a proving test that RESOLVES (a real .hurl or *.hs spec module) | |
| # — a criterion can't cite a test that was never written (Phase 6, task 1). | |
| - name: Criterion proving-tests resolve (PR-ready only) | |
| if: github.event_name == 'pull_request' && github.event.pull_request.draft == false | |
| env: | |
| BASE_REF: ${{ github.base_ref }} | |
| run: ./dev spec-check --criteria-tests "origin/${BASE_REF}" | |
| expectations: | |
| name: expectation guard (test-contract diff) | |
| # PRs only (drafts included — weakening a test is never OK); never on push. | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| # census-diffs committed test files against the merge base | |
| fetch-depth: 0 | |
| - name: Expectation census (maintainer label overrides) | |
| env: | |
| BASE_REF: ${{ github.base_ref }} | |
| # a maintainer-only PR label — labels need write access, so the agent | |
| # cannot self-apply it (unlike the local, gitignored marker). This is | |
| # the load-bearing approval signal. | |
| EXPECTATIONS_APPROVED: ${{ contains(github.event.pull_request.labels.*.name, 'expectations-approved') }} | |
| run: python3 .claude/hooks/expectation-guard.py --pr-diff "origin/${BASE_REF}" | |
| lint: | |
| name: hlint (dialect gate) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| - name: Install hlint 3.10 (pinned binary + checksum) | |
| run: | | |
| curl -sSfL -o hlint.tar.gz \ | |
| https://github.com/ndmitchell/hlint/releases/download/v3.10/hlint-3.10-x86_64-linux.tar.gz | |
| echo "ccabc8802a58154699a3583b8dddc5ea2e6d65753a62c45c0e80088ebb16b42b hlint.tar.gz" | sha256sum -c - | |
| tar xzf hlint.tar.gz | |
| - name: Dialect gate | |
| run: HLINT=./hlint-3.10/hlint ./dev lint |