Title
CI workflow: build, lint, test, vulnerability and boundary checks
Summary
Add the GitHub Actions CI pipeline that every later PR must keep green:
build + gofmt + go vet + golangci-lint + go test -race +
govulncheck + go mod tidy drift check + the network import-boundary
script, on ubuntu and macos runners.
Context
DESIGN.md §14 defines CI as the enforcement point for the testing strategy,
and §3.2 fixes an import boundary (only internal/llm may import
net/net/http; only internal/source/gitsrc may import os/exec) that
makes invariants I1/I2 mechanically auditable. The boundary script created
here is extended into a full invariant suite by issue 30.
Scope
.github/workflows/ci.yml
scripts/check_net_imports.sh
.golangci.yml
Detailed Requirements
- Workflow
ci.yml:
- Triggers:
pull_request, and push to main.
- Top-level
permissions: contents: read (least privilege).
- Matrix:
ubuntu-latest, macos-latest; Go from go.mod
(actions/setup-go with go-version-file: go.mod, caching on).
- All third-party actions pinned to a full commit SHA (not a tag), with
the tag noted in a comment (per ADR-005 release-integrity posture).
- Steps in order: checkout → setup-go →
gofmt -l . (fail if output
non-empty) → go vet ./... → golangci-lint → go build ./... →
go test -race ./... → govulncheck ./... → tidy check →
shellcheck scripts/*.sh (ubuntu job only; shellcheck is preinstalled
on ubuntu runners) → scripts/check_net_imports.sh.
- Tidy check:
go mod tidy && git diff --exit-code go.mod go.sum (tolerate
absent go.sum while there are no deps).
govulncheck: install with a pinned version
(golang.org/x/vuln/cmd/govulncheck@vX.Y.Z, latest at implementation
time; record the chosen version in the PR).
scripts/check_net_imports.sh (POSIX sh, no bashisms):
- Uses
go list -deps -json ./... or go list -f over ./internal/...
and ./cmd/... to assert:
- packages importing
net or net/http ⊆ {internal/llm},
- packages importing
os/exec ⊆ {internal/source/gitsrc},
- no package imports
net/rpc, net/smtp, or net/mail.
- Prints each violation as
VIOLATION <package> imports <import> and
exits 1 on any; exits 0 silently otherwise.
- Must pass on the issue-01 skeleton (no such imports exist yet).
.golangci.yml: enable at minimum govet, staticcheck, errcheck,
ineffassign, unused, misspell, gosec; exclude testdata/;
golangci-lint invoked via its official action (SHA-pinned) with a pinned
lint version.
- Badge/README edits are out of scope (issue 31).
Acceptance Criteria
Validation
Open a draft PR to trigger the workflow; paste the green run URL. Include
the demonstrated red run URL (or log excerpt) for the boundary violation
test. Run shellcheck scripts/check_net_imports.sh locally.
Dependencies
Non-goals
Release workflow (32), E2E/invariant suite content (30), coverage upload,
CodeQL/Dependabot configuration (repo-hardening is handled outside the issue
plan by the repository owner).
Design References
docs/DESIGN.md §3.2 (import boundary), §12.2 (supply chain row), §14 (CI)
docs/decisions/ADR-002-network-boundary.md (boundary rationale)
docs/decisions/ADR-005-licensing-and-distribution.md (pinned actions)
Source of truth: docs/issues/02-ci-workflow.md (PR #1, branch docs/v1-design). If this issue and the repo docs disagree, the docs win. Execution order and dependencies: docs/ISSUE_PLAN.md (this is issue 02 of 33).
Title
CI workflow: build, lint, test, vulnerability and boundary checks
Summary
Add the GitHub Actions CI pipeline that every later PR must keep green:
build +
gofmt+go vet+golangci-lint+go test -race+govulncheck+go mod tidydrift check + the network import-boundaryscript, on ubuntu and macos runners.
Context
DESIGN.md §14 defines CI as the enforcement point for the testing strategy,
and §3.2 fixes an import boundary (only
internal/llmmay importnet/net/http; onlyinternal/source/gitsrcmay importos/exec) thatmakes invariants I1/I2 mechanically auditable. The boundary script created
here is extended into a full invariant suite by issue 30.
Scope
.github/workflows/ci.ymlscripts/check_net_imports.sh.golangci.ymlDetailed Requirements
ci.yml:pull_request, andpushtomain.permissions: contents: read(least privilege).ubuntu-latest,macos-latest; Go fromgo.mod(
actions/setup-gowithgo-version-file: go.mod, caching on).the tag noted in a comment (per ADR-005 release-integrity posture).
gofmt -l .(fail if outputnon-empty) →
go vet ./...→ golangci-lint →go build ./...→go test -race ./...→govulncheck ./...→ tidy check →shellcheck scripts/*.sh(ubuntu job only; shellcheck is preinstalledon ubuntu runners) →
scripts/check_net_imports.sh.go mod tidy && git diff --exit-code go.mod go.sum(tolerateabsent
go.sumwhile there are no deps).govulncheck: install with a pinned version(
golang.org/x/vuln/cmd/govulncheck@vX.Y.Z, latest at implementationtime; record the chosen version in the PR).
scripts/check_net_imports.sh(POSIX sh, no bashisms):go list -deps -json ./...orgo list -fover./internal/...and
./cmd/...to assert:netornet/http⊆ {internal/llm},os/exec⊆ {internal/source/gitsrc},net/rpc,net/smtp, ornet/mail.VIOLATION <package> imports <import>andexits 1 on any; exits 0 silently otherwise.
.golangci.yml: enable at minimumgovet,staticcheck,errcheck,ineffassign,unused,misspell,gosec; excludetestdata/;golangci-lint invoked via its official action (SHA-pinned) with a pinned
lint version.
Acceptance Criteria
against the issue-01 tree.
import "net/http"intointernal/modelin a scratchcommit makes
check_net_imports.sh(and thus CI) fail — demonstratedin the PR description with the failing output, then reverted.
permissions.scripts/check_net_imports.shis executable, POSIX-sh clean(
sh -n), and passesshellcheckwith no errors.Validation
Open a draft PR to trigger the workflow; paste the green run URL. Include
the demonstrated red run URL (or log excerpt) for the boundary violation
test. Run
shellcheck scripts/check_net_imports.shlocally.Dependencies
Non-goals
Release workflow (32), E2E/invariant suite content (30), coverage upload,
CodeQL/Dependabot configuration (repo-hardening is handled outside the issue
plan by the repository owner).
Design References
docs/DESIGN.md§3.2 (import boundary), §12.2 (supply chain row), §14 (CI)docs/decisions/ADR-002-network-boundary.md(boundary rationale)docs/decisions/ADR-005-licensing-and-distribution.md(pinned actions)Source of truth:
docs/issues/02-ci-workflow.md(PR #1, branchdocs/v1-design). If this issue and the repo docs disagree, the docs win. Execution order and dependencies:docs/ISSUE_PLAN.md(this is issue 02 of 33).