diff --git a/.gds/bundle.lock.yaml b/.gds/bundle.lock.yaml index 0594895..3582f3d 100644 --- a/.gds/bundle.lock.yaml +++ b/.gds/bundle.lock.yaml @@ -5,14 +5,14 @@ bundle: version: "0.4.0-dev" release_sequence: 0 channel: "development" - source_tree_digest: "sha256:b091c872839681a6b51419aa37b68fe5217c0f540eef016f29da866200f5159e" - digest: "sha256:601df8bb6be0bf83c836c2b102f4af45a3d96f778fddec9b7521f840bdc5bf0b" + source_tree_digest: "sha256:48f2b1985e221205b7f0528948ff7dd7483b332f11afc33ca0f118af6eaf3554" + digest: "sha256:1463b23f250b5204041dd4f5de12c3a390f8a9a84b38e46c0a01d0e3eee9af8a" projection: - input_digest: "sha256:e6403f1f645b0c407d9941b166f49ff6ef618d86c69c6a26ced927330714e8da" - output_digest: "sha256:6db94c0b3f9a474855c639ed07e04c368c0040fe0c1c8dc512dfdbe6c81e1565" + input_digest: "sha256:453a5f58141f6206c3fe136e56c193275d7eade3ccb1e30fd6aa555f5a93cef8" + output_digest: "sha256:4dbaf721de0e61c8429766bf4449a31635eccd1ab179d1ff996c15fa33310b6a" files: - path: ".gds/compiled-policy.json" digest: "sha256:78d09606bb4168d74bce1f50ab62b46a7ded34652c6b23af1badfd26dd060e94" - path: ".github/workflows/gds-ci.yml" - digest: "sha256:3c64b291efc3b61a3f0827748df178b4fe11d6b415feba1a48d9a803f47e0205" + digest: "sha256:932c2ba6b4db499a2e7549ab9ee46085a7fa386f34b5b3a1837c93487eef119c" diff --git a/.gds/repository.yaml b/.gds/repository.yaml index b7c0377..d0908b2 100644 --- a/.gds/repository.yaml +++ b/.gds/repository.yaml @@ -37,6 +37,7 @@ product: - "Plan, approve, apply and verify GitHub changes as recoverable transactions" - "Build, attest and install immutable releases with offline verification" - "Render harness adapters for agent tooling" + - "Package canonical cross-harness skills for repository, CI and Drakkars operations" entrypoints: - change: "Generic public policy defaults and synthetic examples" path: "policies" @@ -56,6 +57,8 @@ product: path: "core/operations" - change: "Projection identity and rendering" path: "core/projections" + - change: "Canonical agent workflows and routing" + path: "skills/canonical" policy: profiles: diff --git a/.github/workflows/gds-ci.yml b/.github/workflows/gds-ci.yml index ffee354..5d833cb 100644 --- a/.github/workflows/gds-ci.yml +++ b/.github/workflows/gds-ci.yml @@ -1,8 +1,8 @@ # GENERATED FILE - DO NOT EDIT DIRECTLY # generator: gds # bundle: 0.4.0-dev -# source-tree-digest: sha256:b091c872839681a6b51419aa37b68fe5217c0f540eef016f29da866200f5159e -# input-digest: sha256:e6403f1f645b0c407d9941b166f49ff6ef618d86c69c6a26ced927330714e8da +# source-tree-digest: sha256:48f2b1985e221205b7f0528948ff7dd7483b332f11afc33ca0f118af6eaf3554 +# input-digest: sha256:453a5f58141f6206c3fe136e56c193275d7eade3ccb1e30fd6aa555f5a93cef8 # output-digest: sha256:c268237f2cffde69b7868265ba6ac331048c98036fb9030ee7b7b3a208a9ad49 # edit-source: # - .gds/repository.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index ac5bd35..4bc0d20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ Versioning. ## [Unreleased] +### Changed + +- Drakkars audit, triage, orientation and rollout skills now model the current + OTEL/OTLP/OpenObserve boundary, classified host-signal metrics, host + compliance coverage, external backend heartbeat and bounded alert-silence + recovery semantics. +- Correlation guidance preserves raw sparse identity during queued/assigned + capacity phases and treats only a running intent beyond its state-entry grace + as a persistent correlation fault. +- Workflow audit guidance no longer assumes an Actions-read `GITHUB_TOKEN` can + read the repository retention Administration endpoint. + ## [0.1.2] - 2026-08-24 ### Changed diff --git a/core/cli/repository_test.go b/core/cli/repository_test.go index 12c66ce..4bcf80a 100644 --- a/core/cli/repository_test.go +++ b/core/cli/repository_test.go @@ -9,6 +9,7 @@ import ( func repositoryOnboardFixture(t *testing.T) (string, string, string) { t.Helper() + disableGitFixtureMaintenance(t) repository := filepath.Join(t.TempDir(), "repository") if err := os.Mkdir(repository, 0o755); err != nil { t.Fatal(err) diff --git a/core/cli/session_test.go b/core/cli/session_test.go index 5001bfb..4f62e4e 100644 --- a/core/cli/session_test.go +++ b/core/cli/session_test.go @@ -29,6 +29,20 @@ func runSessionGit(t *testing.T, directory string, arguments ...string) string { return strings.TrimSpace(string(output)) } +// Git may start detached maintenance after a fixture command. On slower +// hosted architectures that process can still be creating files below .git +// when testing.TempDir removes the repository, turning a passing assertion +// into an unlinkat "directory not empty" failure. Disable only automatic +// maintenance for fixture processes; explicit Git behavior remains unchanged. +func disableGitFixtureMaintenance(t *testing.T) { + t.Helper() + t.Setenv("GIT_CONFIG_COUNT", "2") + t.Setenv("GIT_CONFIG_KEY_0", "maintenance.auto") + t.Setenv("GIT_CONFIG_VALUE_0", "false") + t.Setenv("GIT_CONFIG_KEY_1", "gc.auto") + t.Setenv("GIT_CONFIG_VALUE_1", "0") +} + func sessionFixture(t *testing.T) sessionFixtureState { return sessionFixtureWithPolicies(t, "preferred", "pull-request", true) } @@ -44,6 +58,7 @@ func sessionFixtureWithPolicies( requiredChecks bool, ) sessionFixtureState { t.Helper() + disableGitFixtureMaintenance(t) remote := filepath.Join(t.TempDir(), "remote.git") runSessionGit(t, filepath.Dir(remote), "init", "--bare", "-q", remote) client := filepath.Join(t.TempDir(), "client") diff --git a/skills/canonical/gds-drakkars-audit-fleet/SKILL.md b/skills/canonical/gds-drakkars-audit-fleet/SKILL.md index 3a55e1f..b92840a 100644 --- a/skills/canonical/gds-drakkars-audit-fleet/SKILL.md +++ b/skills/canonical/gds-drakkars-audit-fleet/SKILL.md @@ -38,9 +38,10 @@ Explain fleet health and bottlenecks from correlated, time-bounded evidence. repository, verify that it may use the full fleet. 5. Check support for every detected toolchain and package manager; classify unsupported-tool failures separately from project defects. 6. Check log completeness, redaction, retention, clock alignment, and missing - correlation fields. Distinguish the bounded pre-reconciliation account-only - window from intent records that remain unbound after authoritative queued - and already-running reconciliation. + correlation fields. Queued and assigned authoritative rehydration may retain + raw missing/unbound identity while waiting for capacity or a runner claim; + persistent correlation is actionable only after a running intent exceeds + its own state-entry grace. Treat `gha_fleet_queue_missing_runner_request_id` as incomplete pre-execution correlation only. A running direct-JIT job with UUID, workflow-run, numeric GitHub-runner and runner-name identity belongs to @@ -51,8 +52,22 @@ Explain fleet health and bottlenecks from correlated, time-bounded evidence. trace search type `traces`; queue spans expose `queue_job_uuid`, while provider spans expose `incus_member`. Do not use the provider process resource host as the compute placement member. -8. Separate confirmed faults, saturation, waste, and `NOT_PROVEN` gaps. -9. Inspect durable lifecycle recovery rather than process health alone: +8. Verify the telemetry plane by role: OpenTelemetry collection and transform, + OTLP transport, and OpenObserve storage/query/alerts. PromQL is an + OpenObserve query language, not evidence of a Prometheus server. Check every + declared collector's disk queue, refused/send-failure counters and restart + state, plus an external heartbeat that does not depend on OpenObserve. + Treat classified LVM, overlay, audit, firewall and workqueue metrics as + bounded host-signal evidence; their raw high-volume logs need not be copied + into the application stream. +9. Check host compliance coverage for package inventory freshness, + reboot-required, running kernel and kernel-reported vulnerability state. + Keep hardware/microcode boundaries separate from software drift. +10. Read alert outcome, last-satisfied time and configured silence together. + OpenObserve v0.92 pauses outcome evaluation during silence, so a recovered + expression may retain an older firing outcome until that bounded window. +11. Separate confirmed faults, saturation, waste, and `NOT_PROVEN` gaps. +12. Inspect durable lifecycle recovery rather than process health alone: terminal job tombstones, overdue non-terminal provider retries, assigned intents with an exact workflow-job row but no instance, scheduler recovery startup grace/cooldown/active attempt, and vanished-runner recovery @@ -83,7 +98,9 @@ Stop before restart, retry, cancellation, deployment, resize, or configuration w Cross-check GitHub service status, exact workflow-job delivery, runtime journals, recovery state, provider inventory, runner scale-set identity, hosts, -and observability freshness; mark gaps `NOT_PROVEN`. +collector delivery counters, external backend heartbeat, alert outcome +freshness, compliance coverage and observability freshness; mark gaps +`NOT_PROVEN`. ## References diff --git a/skills/canonical/gds-drakkars-audit-workflow/SKILL.md b/skills/canonical/gds-drakkars-audit-workflow/SKILL.md index 7acfb63..11bb7c8 100644 --- a/skills/canonical/gds-drakkars-audit-workflow/SKILL.md +++ b/skills/canonical/gds-drakkars-audit-workflow/SKILL.md @@ -38,7 +38,12 @@ Audit one project's CI/CD behavior without reducing verification scope or mutati 4. Build the dependency graph and critical path. Find accidental serialization, duplicated setup and security placements, oversized matrices, unsafe cache keys, and concurrency groups that can discard queued or running evidence. -5. Verify least-privilege permissions, pinning, secret isolation, fork safety, timeouts, concurrency, retry ownership, logs, telemetry, and artifact retention. +5. Verify least-privilege permissions, pinning, secret isolation, fork safety, + timeouts, concurrency, retry ownership, logs, telemetry, and artifact + retention. Do not assume `GITHUB_TOKEN` Actions-read permission can read + repository Actions-retention settings: that endpoint requires repository + Administration read. Prefer fresh credential-free evidence produced by an + existing bounded authority over exposing a broader token to workflow code. 6. Report missing coverage separately from speed opportunities. ## Output diff --git a/skills/canonical/gds-drakkars-orient/SKILL.md b/skills/canonical/gds-drakkars-orient/SKILL.md index 091da2c..2699ae6 100644 --- a/skills/canonical/gds-drakkars-orient/SKILL.md +++ b/skills/canonical/gds-drakkars-orient/SKILL.md @@ -29,6 +29,9 @@ Resolve the current CI/fleet context and its authority boundaries without mutati 2. Identify repository visibility, active profiles, module pins, and canonical owner. 3. Treat portable engines, reusable workflows, schemas, and generic skills as public product concerns. 4. Treat organizations, repository identities, priorities, hosts, networks, credentials, and runtime evidence as private estate concerns. + Portable OTEL components, alert/dashboard schemas and PromQL rendering are + public product concerns; collector topology, OpenObserve destination, + external heartbeat and live alert outcomes remain private estate facts. 5. Mark unfetched provider or telemetry facts `NOT_PROVEN`. 6. Treat Runner Scale Set V2 names as routing targets. Do not equate an empty classic self-hosted-label response with a missing scale-set name or listener. diff --git a/skills/canonical/gds-drakkars-rollout-consumer/SKILL.md b/skills/canonical/gds-drakkars-rollout-consumer/SKILL.md index 3549a53..6e30043 100644 --- a/skills/canonical/gds-drakkars-rollout-consumer/SKILL.md +++ b/skills/canonical/gds-drakkars-rollout-consumer/SKILL.md @@ -32,7 +32,11 @@ Change consumers without losing work or creating an unserviceable label window. ordinary real jobs created by the selected consumers; never create synthetic, benchmark, soak, canary, rerun, or empty-commit traffic. 5. Move consumers in bounded waves while old and new paths coexist. -6. Observe queue, failures, retries, provisioning, teardown, and end-to-end latency after each wave. +6. Observe queue, failures, retries, provisioning, teardown, end-to-end latency, + OTEL delivery queues/refusals and OpenObserve alert outcomes after each wave. + Allow the configured bounded silence window to produce a fresh recovery + outcome; do not treat a stale firing label or an empty raw-noise stream as + proof of failed telemetry. 7. Disable the old path only when its queued and running intent count is zero. Remove it only after a further verified drain window. 8. Record immutable evidence and preserve a tested rollback checkpoint. diff --git a/skills/canonical/gds-drakkars-triage-run/SKILL.md b/skills/canonical/gds-drakkars-triage-run/SKILL.md index ab1f307..dab396b 100644 --- a/skills/canonical/gds-drakkars-triage-run/SKILL.md +++ b/skills/canonical/gds-drakkars-triage-run/SKILL.md @@ -47,8 +47,10 @@ Trace one run from event receipt to terminal result without changing state. - For a delayed `JobAssigned`, check terminal tombstones before treating a completed job as live demand. - For an assigned job without an instance, inspect the scheduler recovery - attempt, startup grace and cooldown; healthy sibling progress is not proof - that the exact identity advanced. + attempt, typed capacity retry, startup grace and cooldown; healthy sibling + progress is not proof that the exact identity advanced. Raw missing workflow + or repository identity is expected before the authenticated running claim + and must not be confused with a running persistent-correlation gap. - For an `in_progress` job whose runner id disappeared, inspect the durable vanished-runner transaction and authoritative `run_attempt`. A force-cancel followed by one full rerun is one recovery lifecycle, not two independent @@ -80,4 +82,5 @@ Use stable identifiers and distinguish observation, inference, and `NOT_PROVEN`. Use current GitHub service status and job events, queue intents, terminal tombstones, scheduler/vanished recovery state, provider leases, runner logs, -and traces. +traces, OTEL delivery counters and the current OpenObserve alert outcome plus +its silence window. diff --git a/tests/golden/projections/control-plane/.claude/CLAUDE.md b/tests/golden/projections/control-plane/.claude/CLAUDE.md index a86903b..a9f2e29 100644 --- a/tests/golden/projections/control-plane/.claude/CLAUDE.md +++ b/tests/golden/projections/control-plane/.claude/CLAUDE.md @@ -3,7 +3,7 @@ GENERATED FILE - DO NOT EDIT DIRECTLY generator: gds bundle: 0.4.0-dev source-tree-digest: sha256:0000000000000000000000000000000000000000000000000000000000000001 -input-digest: sha256:d516e979d26eb08514c93e3b7cc2f0577ff8eef33340ba9e0dee51a561f86fbd +input-digest: sha256:be7ce80717d8e8e28bbffc2ea3931b68812b418199ba818a047cd035f16daf04 output-digest: sha256:88cb57297d8d713287872a8afaca8d42f7146ecf7a091e4996e65eee8f962665 edit-source: - .gds/repository.yaml diff --git a/tests/golden/projections/control-plane/.gds/bundle.lock.yaml b/tests/golden/projections/control-plane/.gds/bundle.lock.yaml index 4fc082c..56d9d9f 100644 --- a/tests/golden/projections/control-plane/.gds/bundle.lock.yaml +++ b/tests/golden/projections/control-plane/.gds/bundle.lock.yaml @@ -9,14 +9,14 @@ bundle: digest: "sha256:d4645c8b942733304420ab2b92860914887b2cf90ea41dc6a836ac870a4b3182" projection: - input_digest: "sha256:d516e979d26eb08514c93e3b7cc2f0577ff8eef33340ba9e0dee51a561f86fbd" - output_digest: "sha256:1ba6c42703257f4add3fb6307b2ad8640f9e4ee25403547e2343013ad121926c" + input_digest: "sha256:be7ce80717d8e8e28bbffc2ea3931b68812b418199ba818a047cd035f16daf04" + output_digest: "sha256:7c66a9eea5408ed8ec767d386d4376fbd5b986bf72bebaca9493bd27ffa1f72e" files: - path: ".claude/CLAUDE.md" - digest: "sha256:d0fb0aeaa6219e9f5962a369e321c6ae47c0b2185d006e46ef55349a3f787dd1" + digest: "sha256:85b693a48df9b21e7ba80aa5bbf203e76ace83bd125ec1c25dd308d7e16c3b38" - path: ".gds/compiled-policy.json" digest: "sha256:09752cc0cbe57dc3097f884927e2089a9730b9ebcf86ac27228812d54c5760f8" - path: ".github/workflows/gds-ci.yml" - digest: "sha256:61e492d4fddb2332f01d6c92788a4778f4c6c0afd48f82e0bede79e64de812df" + digest: "sha256:7b244b9e8d470f3780de8e5213e9056a81f070a2db66fe92cba3d9224319339f" - path: "AGENTS.md" - digest: "sha256:eec3204889eebec26623ae9e4c13800e91b60b2211372573effe6f5025f4a5bd" + digest: "sha256:4c7367a8bc2fdba3a4a96554ae3d7d687c6326df2170b957c77372f816fcd94c" diff --git a/tests/golden/projections/control-plane/.github/workflows/gds-ci.yml b/tests/golden/projections/control-plane/.github/workflows/gds-ci.yml index 6ee95c4..824ad45 100644 --- a/tests/golden/projections/control-plane/.github/workflows/gds-ci.yml +++ b/tests/golden/projections/control-plane/.github/workflows/gds-ci.yml @@ -2,7 +2,7 @@ # generator: gds # bundle: 0.4.0-dev # source-tree-digest: sha256:0000000000000000000000000000000000000000000000000000000000000001 -# input-digest: sha256:d516e979d26eb08514c93e3b7cc2f0577ff8eef33340ba9e0dee51a561f86fbd +# input-digest: sha256:be7ce80717d8e8e28bbffc2ea3931b68812b418199ba818a047cd035f16daf04 # output-digest: sha256:c268237f2cffde69b7868265ba6ac331048c98036fb9030ee7b7b3a208a9ad49 # edit-source: # - .gds/repository.yaml diff --git a/tests/golden/projections/control-plane/AGENTS.md b/tests/golden/projections/control-plane/AGENTS.md index 416dea1..8c39552 100644 --- a/tests/golden/projections/control-plane/AGENTS.md +++ b/tests/golden/projections/control-plane/AGENTS.md @@ -3,8 +3,8 @@ GENERATED FILE - DO NOT EDIT DIRECTLY generator: gds bundle: 0.4.0-dev source-tree-digest: sha256:0000000000000000000000000000000000000000000000000000000000000001 -input-digest: sha256:d516e979d26eb08514c93e3b7cc2f0577ff8eef33340ba9e0dee51a561f86fbd -output-digest: sha256:198abbde694dcaccaf8126a8cc7d645830e1400a36604ca8864e4de4e69e8d18 +input-digest: sha256:be7ce80717d8e8e28bbffc2ea3931b68812b418199ba818a047cd035f16daf04 +output-digest: sha256:670970518bda1458ad0fb14b276a6ba9add2ef7491ba406774e7094d159b7109 edit-source: - .gds/repository.yaml - policies/base/repository-default.yaml @@ -25,6 +25,7 @@ GDS is the public engine for a multi-owner GitHub estate. It loads an external e - Plan, approve, apply and verify GitHub changes as recoverable transactions - Build, attest and install immutable releases with offline verification - Render harness adapters for agent tooling +- Package canonical cross-harness skills for repository, CI and Drakkars operations ## Where to change what @@ -37,6 +38,7 @@ GDS is the public engine for a multi-owner GitHub estate. It loads an external e - GitHub reads, writes and their failure staging — `core/providers/github` - Plan, approval, lock and journal semantics — `core/operations` - Projection identity and rendering — `core/projections` +- Canonical agent workflows and routing — `skills/canonical` ## How to verify