diff --git a/.github/workflows/release-bundle.yml b/.github/workflows/release-bundle.yml index dc8f9ab..267c50b 100644 --- a/.github/workflows/release-bundle.yml +++ b/.github/workflows/release-bundle.yml @@ -87,8 +87,11 @@ jobs: - name: Run release gates shell: bash + env: + GDS_TEST_PYTHON: ${{ runner.temp }}/gds-release-python/bin/python run: | - python3 -m pip install --quiet --require-hashes -r requirements/test.txt + python3 -m venv "${GDS_TEST_PYTHON%/bin/python}" + "$GDS_TEST_PYTHON" -m pip install --quiet --require-hashes -r requirements/test.txt scripts/validate_release.sh - name: Materialize bounded signed harness evidence input diff --git a/CHANGELOG.md b/CHANGELOG.md index aceb5e2..04b0d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,11 @@ Versioning. repository identity or embedded projection templates. - Static analysis now covers the Go engine and Actions workflows on the public authority before a private estate can advance its gitlink. +- The release workflow now installs and uses one job-scoped hash-locked Python + environment instead of depending on undeclared runner packages or a second + tool-managed interpreter. +- The declared `gds-drakkars` plugin now has its canonical source manifest, so + full and release validation cannot silently stop at a redirected JSON result. ## [0.1.1] - 2026-08-16 diff --git a/core/releasebuilder/workflow_contract_test.go b/core/releasebuilder/workflow_contract_test.go index 193dafb..3372564 100644 --- a/core/releasebuilder/workflow_contract_test.go +++ b/core/releasebuilder/workflow_contract_test.go @@ -167,11 +167,15 @@ func TestHostedReleaseWorkflowInstallsLockedPythonDependenciesBeforeReleaseGate( t.Fatal(err) } content := string(workflow) - install := strings.Index(content, "python3 -m pip install --quiet --require-hashes -r requirements/test.txt") + install := strings.Index(content, `"$GDS_TEST_PYTHON" -m pip install --quiet --require-hashes -r requirements/test.txt`) validate := strings.Index(content, "scripts/validate_release.sh") if install < 0 || validate < 0 || install > validate { t.Fatal("release workflow must install hash-locked Python dependencies before validation") } + if !strings.Contains(content, "GDS_TEST_PYTHON: ${{ runner.temp }}/gds-release-python/bin/python") || + !strings.Contains(content, `python3 -m venv "${GDS_TEST_PYTHON%/bin/python}"`) { + t.Fatal("release workflow must run tests with the Python environment it populated") + } } // The release chain runs on the estate's own fleet. What matters is that all diff --git a/plugins/gds-drakkars/.codex-plugin/plugin.json b/plugins/gds-drakkars/.codex-plugin/plugin.json new file mode 100644 index 0000000..6d4d708 --- /dev/null +++ b/plugins/gds-drakkars/.codex-plugin/plugin.json @@ -0,0 +1,20 @@ +{ + "name": "gds-drakkars", + "version": "0.1.0", + "description": "GDS Drakkars fleet orientation, audit, triage, workflow design, optimization, onboarding, rollout, and performance verification workflows.", + "author": { + "name": "example-user" + }, + "repository": "https://github.com/NDDev-OpenNetwork/github-device-sync", + "license": "Proprietary", + "skills": "./skills/", + "interface": { + "displayName": "GDS Drakkars", + "shortDescription": "Operate and optimize CI through Drakkars", + "longDescription": "Provides the profiled GDS skills for fleet audits, run triage, CI/CD workflow design, critical-path optimization, project onboarding, consumer rollout, and performance verification. Canonical skill sources remain in the public GDS engine and plugin copies are generated.", + "developerName": "example-user", + "category": "Developer Tools", + "capabilities": ["Read", "Write"], + "defaultPrompt": "Resolve the repository visibility, workflow obligations, and current fleet evidence before changing CI/CD behavior." + } +} diff --git a/scripts/validate_go_core.sh b/scripts/validate_go_core.sh index 089fe47..bd86e8e 100755 --- a/scripts/validate_go_core.sh +++ b/scripts/validate_go_core.sh @@ -81,11 +81,24 @@ python3 scripts/validate_gds_schemas.py --json >/dev/null GDS_BIN="$BUILD_DIR/gds-host" go build -trimpath -o "$GDS_BIN" ./core/cmd/gds +run_json_validator() { + local output=$1 + shift + local status + if "$@" >"$output"; then + return 0 + else + status=$? + fi + cat "$output" >&2 + return "$status" +} for CONTRACT in schemas repository estate skills plugins memories; do - "$GDS_BIN" --json validate "$CONTRACT" \ - >"$BUILD_DIR/validate-$CONTRACT.json" + run_json_validator "$BUILD_DIR/validate-$CONTRACT.json" \ + "$GDS_BIN" --json validate "$CONTRACT" done -"$GDS_BIN" --json generate repository --check >"$BUILD_DIR/generate-repository.json" +run_json_validator "$BUILD_DIR/generate-repository.json" \ + "$GDS_BIN" --json generate repository --check if [ "$MODE" = "full" ]; then go test -race ./...