From 323e55ddbfea633e55f9b43871d02439892cd8e6 Mon Sep 17 00:00:00 2001 From: lr00rl Date: Fri, 31 Jul 2026 06:00:04 -0700 Subject: [PATCH 1/3] [zeus] Make workspace greens reproducible across sibling changes The integration workflow previously followed four moving default branches, so an external module-graph change could rewrite lattice/go.work.sum while make test still exited zero. Exact checkout refs now define the tested workspace, the canonical sum matches that graph, and a reusable post-build gate rejects any checkout that becomes dirty. Constraint: The umbrella go.work spans five sibling repositories and exports GOWORK into every Go command Constraint: Workflow and CI files are Zeus-owned under the Olympus profile Rejected: Refresh go.work.sum alone | the next sibling main change would silently recreate the drift Rejected: Pin dependencies to integration instead of the currently resolved main heads | that would change the workflow's tested baseline rather than make its existing baseline reproducible Confidence: high Scope-risk: moderate Reversibility: clean Directive: Update all four checkout refs and go.work.sum together, then run test, build, and check-clean in the five-repository sibling layout Tested: Exact drift repro (exit 0, 2 to 10 lines); repeat test held sum hash 041fe6e3; make build; workflow YAML parse; 4/4 remote ref matches; dirty gate reported all four real root changes and failed Not-tested: GitHub-hosted workflow run pending branch push --- .github/workflows/ci.yml | 23 +++++++++++++++++++---- Makefile | 15 ++++++++++++++- README.md | 7 +++++++ go.work.sum | 12 ++++++++++-- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a87b28a..833c528 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,16 +14,28 @@ jobs: with: { path: lattice } - name: checkout lattice-sdk uses: actions/checkout@v6 - with: { repository: LatticeNet/lattice-sdk, path: lattice-sdk } + with: + repository: LatticeNet/lattice-sdk + path: lattice-sdk + ref: 4a318f246d23875cdd6448d96a62bd87bd67215c - name: checkout lattice-server uses: actions/checkout@v6 - with: { repository: LatticeNet/lattice-server, path: lattice-server } + with: + repository: LatticeNet/lattice-server + path: lattice-server + ref: ef13509e74b7564d2c4a9847f11f6b86e3bd6cfd - name: checkout lattice-node-agent uses: actions/checkout@v6 - with: { repository: LatticeNet/lattice-node-agent, path: lattice-node-agent } + with: + repository: LatticeNet/lattice-node-agent + path: lattice-node-agent + ref: 03f730acb9653cc1a99c62c95510cafd58a4afad - name: checkout lattice-plugin-template uses: actions/checkout@v6 - with: { repository: LatticeNet/lattice-plugin-template, path: lattice-plugin-template } + with: + repository: LatticeNet/lattice-plugin-template + path: lattice-plugin-template + ref: 793b476f346d1a8584d34c89e6d8da3f4b115d3e - uses: actions/setup-go@v6 with: go-version: '1.26.x' @@ -45,6 +57,9 @@ jobs: - name: make build working-directory: lattice run: make build + - name: workspace stays clean + working-directory: lattice + run: make check-clean - name: gosec run: | go install github.com/securego/gosec/v2/cmd/gosec@latest diff --git a/Makefile b/Makefile index 3c8c9ba..a008f1e 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,10 @@ -.PHONY: test build run-server run-agent check-dashboard +.PHONY: test build check-clean run-server run-agent check-dashboard export GOCACHE := $(CURDIR)/.cache/go-build export GOWORK := $(CURDIR)/go.work +WORKSPACE_REPOS := . ../lattice-sdk ../lattice-server ../lattice-node-agent ../lattice-plugin-template + test: mkdir -p $(GOCACHE) cd ../lattice-sdk && go test ./... @@ -16,6 +18,17 @@ build: cd ../lattice-node-agent && go build -o ../lattice/bin/lattice-agent ./cmd/lattice-agent cd ../lattice-plugin-template/system-go && go build ./... +check-clean: + @dirty=0; \ + for repo in $(WORKSPACE_REPOS); do \ + status="$$(git -C "$$repo" status --porcelain --untracked-files=all)"; \ + if [ -n "$$status" ]; then \ + printf 'workspace checkout is dirty: %s\n%s\n' "$$repo" "$$status" >&2; \ + dirty=1; \ + fi; \ + done; \ + test "$$dirty" -eq 0 + run-server: cd ../lattice-server && LATTICE_WEB_ROOT=../lattice-dashboard go run ./cmd/lattice-server diff --git a/README.md b/README.md index 4396c87..bc9f421 100644 --- a/README.md +++ b/README.md @@ -170,3 +170,10 @@ Current published SDK baseline: latest `lattice-sdk` tag is `v0.2.17`; `v0.2.17`. The workspace `use` list includes the local SDK checkout, so cross-repo development exercises the current model sources without relying on a stale version-specific replace. + +Workspace CI pins each sibling checkout to an exact commit in +`.github/workflows/ci.yml`. Update those refs and `go.work.sum` together when +advancing the integration set, then run `make test`, `make build`, and +`make check-clean` in the five-repository sibling layout. The clean-tree gate is +intentional: a successful Go command that rewrites a tracked sum is not a +reproducible green build. diff --git a/go.work.sum b/go.work.sum index a3c0f2e..041fe6e 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,2 +1,10 @@ -github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= -github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= +golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= From cbf7091bd82dd0ff408ce0852e6135fa2695ecd4 Mon Sep 17 00:00:00 2001 From: lr00rl Date: Fri, 31 Jul 2026 06:34:22 -0700 Subject: [PATCH 2/3] [zeus] Make an unreadable workspace fail the reproducibility gate The first clean-tree guard treated a failed git status as an empty clean result. Preserve the five-repo gate while adding an explicit inspection-failure path and a permanent four-case regression so missing or non-repository siblings cannot produce a green build. Constraint: CI must distinguish clean, dirty, missing, and non-repository workspace inputs without adding dependencies Rejected: Rely on planted manual checks only | the exact fail-open path would regress silently Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep the real five-repo check after every workspace-mutating phase and after the guard regression Tested: make test; make build; guard regression 4/4; isolated missing sibling exit 2; shellcheck; sh -n; YAML parse; diff check; dependency trees clean; go.work.sum blob unchanged Not-tested: GitHub CI for this replacement head has not run yet --- .github/workflows/ci.yml | 3 ++ Makefile | 11 ++++++-- README.md | 8 ++++-- scripts/test-check-clean.sh | 55 +++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 scripts/test-check-clean.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 833c528..9ea5663 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,6 +57,9 @@ jobs: - name: make build working-directory: lattice run: make build + - name: clean-tree gate regression + working-directory: lattice + run: make test-check-clean - name: workspace stays clean working-directory: lattice run: make check-clean diff --git a/Makefile b/Makefile index a008f1e..d1fe495 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: test build check-clean run-server run-agent check-dashboard +.PHONY: test build check-clean test-check-clean run-server run-agent check-dashboard export GOCACHE := $(CURDIR)/.cache/go-build export GOWORK := $(CURDIR)/go.work @@ -21,7 +21,11 @@ build: check-clean: @dirty=0; \ for repo in $(WORKSPACE_REPOS); do \ - status="$$(git -C "$$repo" status --porcelain --untracked-files=all)"; \ + if ! status="$$(git -C "$$repo" status --porcelain --untracked-files=all)"; then \ + printf 'workspace checkout cannot be inspected: %s\n' "$$repo" >&2; \ + dirty=1; \ + continue; \ + fi; \ if [ -n "$$status" ]; then \ printf 'workspace checkout is dirty: %s\n%s\n' "$$repo" "$$status" >&2; \ dirty=1; \ @@ -29,6 +33,9 @@ check-clean: done; \ test "$$dirty" -eq 0 +test-check-clean: + @sh scripts/test-check-clean.sh + run-server: cd ../lattice-server && LATTICE_WEB_ROOT=../lattice-dashboard go run ./cmd/lattice-server diff --git a/README.md b/README.md index bc9f421..a7c61fa 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,8 @@ stale version-specific replace. Workspace CI pins each sibling checkout to an exact commit in `.github/workflows/ci.yml`. Update those refs and `go.work.sum` together when advancing the integration set, then run `make test`, `make build`, and -`make check-clean` in the five-repository sibling layout. The clean-tree gate is -intentional: a successful Go command that rewrites a tracked sum is not a -reproducible green build. +`make test-check-clean` followed by `make check-clean` in the five-repository +sibling layout. The regression covers clean, dirty, missing, and non-repository +checkouts. The real clean-tree gate then fails if any checkout cannot be +inspected or has changes: a successful Go command that rewrites a tracked sum +is not a reproducible green build. diff --git a/scripts/test-check-clean.sh b/scripts/test-check-clean.sh new file mode 100644 index 0000000..68b3f1e --- /dev/null +++ b/scripts/test-check-clean.sh @@ -0,0 +1,55 @@ +#!/bin/sh +set -eu + +root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) +tmp=$(mktemp -d "${TMPDIR:-/tmp}/lattice-check-clean.XXXXXX") + +cleanup() { + case "$tmp" in + "${TMPDIR:-/tmp}"/lattice-check-clean.*) rm -rf -- "$tmp" ;; + *) printf 'refusing to remove unexpected test path: %s\n' "$tmp" >&2 ;; + esac +} +trap cleanup EXIT HUP INT TERM + +clean="$tmp/clean" +dirty="$tmp/dirty" +not_repo="$tmp/not-repo" +missing="$tmp/missing" + +git init -q "$clean" +git init -q "$dirty" +mkdir -p "$not_repo" +printf 'dirty\n' >"$dirty/untracked.txt" + +expect_pass() { + name=$1 + repo=$2 + if ! output=$(make -s -C "$root" check-clean "WORKSPACE_REPOS=$repo" 2>&1); then + printf 'not ok - %s unexpectedly failed\n%s\n' "$name" "$output" >&2 + exit 1 + fi + printf 'ok - %s\n' "$name" +} + +expect_fail() { + name=$1 + repo=$2 + message=$3 + if output=$(make -s -C "$root" check-clean "WORKSPACE_REPOS=$repo" 2>&1); then + printf 'not ok - %s unexpectedly passed\n' "$name" >&2 + exit 1 + fi + case "$output" in + *"$message"*) ;; + *) printf 'not ok - %s failed without %s\n%s\n' "$name" "$message" "$output" >&2; exit 1 ;; + esac + printf 'ok - %s\n' "$name" +} + +expect_pass clean "$clean" +expect_fail dirty "$dirty" 'workspace checkout is dirty:' +expect_fail missing "$missing" 'workspace checkout cannot be inspected:' +expect_fail non-repository "$not_repo" 'workspace checkout cannot be inspected:' + +printf 'check-clean regression: 4/4 passed\n' From e0f4354e616dfa3cd106ca0c5651e4b54813b863 Mon Sep 17 00:00:00 2001 From: lr00rl Date: Fri, 31 Jul 2026 06:47:21 -0700 Subject: [PATCH 3/3] [zeus] Prove the workspace gate reports every broken checkout The four isolated fixtures proved classification but not the aggregate contract, and the real clean check was followed by a nominally read-only security step. Add one mixed scan that must retain every failure and make the real gate the workflow's literal final step. Constraint: Review evidence says the guard must aggregate all sibling failures, not stop at the first Rejected: Treat per-repo cases as proof of aggregation | a future early exit could keep all four green Confidence: high Scope-risk: narrow Directive: Preserve both isolated classification cases and the mixed aggregate case Tested: guard regression 5/5; sh -n; shellcheck; workflow YAML parse; diff check Not-tested: Remote CI and Athena r3 verdict are pending --- .github/workflows/ci.yml | 6 +++--- README.md | 3 ++- scripts/test-check-clean.sh | 19 ++++++++++++++++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ea5663..e09c65c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,10 +60,10 @@ jobs: - name: clean-tree gate regression working-directory: lattice run: make test-check-clean - - name: workspace stays clean - working-directory: lattice - run: make check-clean - name: gosec run: | go install github.com/securego/gosec/v2/cmd/gosec@latest gosec ./lattice-server/... ./lattice-node-agent/... + - name: workspace stays clean + working-directory: lattice + run: make check-clean diff --git a/README.md b/README.md index a7c61fa..50bb835 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ Workspace CI pins each sibling checkout to an exact commit in advancing the integration set, then run `make test`, `make build`, and `make test-check-clean` followed by `make check-clean` in the five-repository sibling layout. The regression covers clean, dirty, missing, and non-repository -checkouts. The real clean-tree gate then fails if any checkout cannot be +checkouts both separately and in one aggregate scan. CI keeps the real +clean-tree gate as its final step, where it fails if any checkout cannot be inspected or has changes: a successful Go command that rewrites a tracked sum is not a reproducible green build. diff --git a/scripts/test-check-clean.sh b/scripts/test-check-clean.sh index 68b3f1e..298f54e 100644 --- a/scripts/test-check-clean.sh +++ b/scripts/test-check-clean.sh @@ -52,4 +52,21 @@ expect_fail dirty "$dirty" 'workspace checkout is dirty:' expect_fail missing "$missing" 'workspace checkout cannot be inspected:' expect_fail non-repository "$not_repo" 'workspace checkout cannot be inspected:' -printf 'check-clean regression: 4/4 passed\n' +aggregate_repos="$clean $dirty $missing $not_repo" +if aggregate_output=$(make -s -C "$root" check-clean "WORKSPACE_REPOS=$aggregate_repos" 2>&1); then + printf 'not ok - aggregate failures unexpectedly passed\n' >&2 + exit 1 +fi +for expected in \ + "workspace checkout is dirty: $dirty" \ + "workspace checkout cannot be inspected: $missing" \ + "workspace checkout cannot be inspected: $not_repo" +do + case "$aggregate_output" in + *"$expected"*) ;; + *) printf 'not ok - aggregate output omitted %s\n%s\n' "$expected" "$aggregate_output" >&2; exit 1 ;; + esac +done +printf 'ok - aggregate reports every failure\n' + +printf 'check-clean regression: 5/5 passed\n'