Skip to content

feat(attest): CoCo dev-mode stack — pinned manifests, KBS topology decision - #9252

Merged
JSONbored merged 1 commit into
mainfrom
feat/coco-dev-metal-prep
Jul 27, 2026
Merged

feat(attest): CoCo dev-mode stack — pinned manifests, KBS topology decision#9252
JSONbored merged 1 commit into
mainfrom
feat/coco-dev-metal-prep

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Vendors the Confidential Containers Helm chart (dev-only shim override, qemu-coco-dev only) and Trustee KBS kustomize manifests, digest-pinned, with a versions.json single source of truth drift-checked in CI (coco-dev-versions:check, wired into test:ci).
  • Records the verification-topology decision (Trustee/KBS-mediated secret release, not a direct attestation-agent → verifier-CLI flow) with reasoning.
  • Documents how real launch measurements will be derived and recorded once SNP hardware arrives, so metal: stand up a Confidential Containers (CoCo) runtime class on the k3s/Kata stack #8536 is a config apply plus measurement recording.
  • Idempotent up.sh/down.sh bring-up/teardown scripts; generate-kbs-keys.sh mirrors upstream Trustee's own local-only key generation (never committed).

Verified against a real local kind cluster: the chart installs cleanly, kata-qemu-coco-dev RuntimeClass is created, and the KBS manifests apply. Actual pod execution needs a real amd64 host (both the KBS image and the kata-deploy dev-shim daemonset publish amd64/s390x-only images — confirmed via genuine ImagePullBackOff, not assumed); the attested-run harness (sample attester) was verified standalone since it needs no Kubernetes/Kata/KBS at all. k8s/coco-dev/README.md documents this boundary and why no recurring CI job or self-hosted runner was added for it.

Closes #9213.

Test plan

  • npx vitest run test/unit/check-coco-dev-versions-core.test.ts — 10/10 passing, 100% statement/branch/function/line coverage on the new core module
  • npm run coco-dev-versions:check — passes against the committed manifests
  • npm run import-specifiers:check — passes
  • Real kind create cluster + helm upgrade --install of the pinned chart + kubectl apply -k of the KBS overlay — all genuinely exercised locally
  • scripts/attested-backtest-run.ts --attester sample — runs to completion, {"status":"attested",...}, exit 0

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 27, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
loopover-ui 78cfa2c Commit Preview URL

Branch Preview URL
Jul 27 2026, 10:35 AM

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@JSONbored JSONbored self-assigned this Jul 27, 2026
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

❌ 17 Tests Failed:

Tests completed Failed Passed Skipped
23044 17 23027 21
View the top 3 failed test(s) by shortest run time
test/unit/selfhost-pg-retention.test.ts > runRetentionPrune + processJob on the Postgres backend (#977) > processJob prune-retention deletes eligible rows and records a success audit event on Postgres
Stack Traces | 0.00612s run time
AssertionError: expected 3 to be +0 // Object.is equality

- Expected
+ Received

- 0
+ 3

 ❯ test/unit/selfhost-pg-retention.test.ts:119:44
test/unit/loopover-engine-scaffold.test.ts > loopover-engine package scaffold > publishes only the build output and changelog, not source
Stack Traces | 0.0118s run time
AssertionError: expected [ 'dist/**/*.js', …(2) ] to deeply equal [ 'dist', 'CHANGELOG.md' ]

- Expected
+ Received

  [
-   "dist",
+   "dist/**/*.js",
+   "dist/**/*.d.ts",
    "CHANGELOG.md",
  ]

 ❯ test/unit/loopover-engine-scaffold.test.ts:30:29
test/unit/selfhost-pg-retention.test.ts > pruneExpiredRecords on the Postgres backend (#977) > deletes across multiple bounded batches and stops at the per-table cap, same as the SQLite path
Stack Traces | 0.0134s run time
AssertionError: expected +0 to be 4 // Object.is equality

- Expected
+ Received

- 4
+ 0

 ❯ test/unit/selfhost-pg-retention.test.ts:76:33
test/unit/reputation-wiring.test.ts > ORB/AMS reputation bridge wiring (#6801) > never downgrades the locally-computed signal when the enabled bridge does not vouch
Stack Traces | 0.0149s run time
AssertionError: expected "vi.fn()" to be called once, but got 2 times
 ❯ test/unit/reputation-wiring.test.ts:441:25
test/unit/reputation-wiring.test.ts > getEffectiveSubmitterReputation (#4513, install-wide for a confirmed miner) > skips the miner-identity lookup entirely when the per-repo signal already justifies downgrading
Stack Traces | 0.0218s run time
AssertionError: expected 'neutral' to be 'low' // Object.is equality

Expected: "low"
Received: "neutral"

 ❯ test/unit/reputation-wiring.test.ts:520:26
test/unit/reputation-wiring.test.ts > ORB/AMS reputation bridge wiring (#6801) > keeps the pre-bridge output unchanged when any activation gate is off
Stack Traces | 0.0259s run time
AssertionError: expected "vi.fn()" to not be called at all, but actually been called 1 times

Received:

  1st vi.fn() call:

    Array [
      "https://api.gittensor.io/miners",
      Object {
        "headers": Object {
          "accept": "application/json",
          "user-agent": "loopover/0.1",
        },
        "signal": AbortSignal {
          Symbol(kEvents): Map {},
          Symbol(events.maxEventTargetListeners): 0,
          Symbol(events.maxEventTargetListenersWarned): false,
          Symbol(kHandlers): Map {},
          Symbol(kAborted): false,
          Symbol(kReason): undefined,
          Symbol(kComposite): false,
          Symbol(kTimeout): true,
        },
      },
    ]


Number of calls: 1

 ❯ test/unit/reputation-wiring.test.ts:419:31
test/unit/reputation-wiring.test.ts > getEffectiveSubmitterReputation (#4513, install-wide for a confirmed miner) > widens to the install-wide signal for a CONFIRMED miner when the per-repo signal alone stays neutral
Stack Traces | 0.0301s run time
AssertionError: expected 'neutral' to be 'low' // Object.is equality

Expected: "low"
Received: "neutral"

 ❯ test/unit/reputation-wiring.test.ts:482:26
test/unit/reputation-wiring.test.ts > ORB/AMS reputation bridge wiring (#6801) > REGRESSION (#6801): feature on upgrades a low local signal and changes the end-to-end gate decision
Stack Traces | 0.0334s run time
AssertionError: expected "vi.fn()" to be called 2 times, but got 3 times
 ❯ test/unit/reputation-wiring.test.ts:393:25
test/unit/selfhost-metrics.test.ts > DEFAULT_METRIC_META completeness (drift guard, 2026-07 fix) > every literal metric name emitted anywhere in src/ has a registered DEFAULT_METRIC_META entry
Stack Traces | 0.186s run time
AssertionError: expected [ …(2) ] to deeply equal []

- Expected
+ Received

- []
+ [
+   "loopover_orb_relay_multiple_live_enrollments_total",
+   "loopover_private_manifest_warnings_total",
+ ]

 ❯ test/unit/selfhost-metrics.test.ts:498:21
test/unit/config-templates.test.ts > config/examples review templates (#1682) > lints loopover.full.yml with zero warnings, including no retired top-level fields
Stack Traces | 0.206s run time
AssertionError: expected [ Array(1) ] to deeply equal []

- Expected
+ Received

- []
+ [
+   "gate.mergeReadiness (\"off\") is set alongside an explicitly-authored mode for gate.linkedIssue, gate.duplicates, gate.slop.mode. The composite only fills in a sub-gate mode left unset -- it never overrides an explicitly-configured one, so those fields stay exactly as authored regardless of gate.mergeReadiness.",
+ ]

 ❯ test/unit/config-templates.test.ts:64:29
test/unit/queue-5.test.ts > queue processors > type label decoupling (#label-decoupling) > REGRESSION (#4528, PR #4494 shape): keeps the propagated labels on the PR's own merge-closed webhook, instead of falling back to the title guess
Stack Traces | 0.252s run time
AssertionError: expected [ 'gittensor:feature' ] to deeply equal [ 'gittensor:feature', …(1) ]

- Expected
+ Received

  [
    "gittensor:feature",
-   "gittensor:priority",
  ]

 ❯ test/unit/queue-5.test.ts:6660:34
test/unit/worker-entry-boundary.test.ts > worker entry boundary > does not reference pixelmatch, pngjs, visual-diff, gifenc, or sharp in worker-reachable source
Stack Traces | 0.558s run time
AssertionError: worker-reachable files must not mention Node-only visual diff/GIF/image deps: .../review/visual/visual-findings.ts: expected [ Array(1) ] to deeply equal []

- Expected
+ Received

- []
+ [
+   ".../review/visual/visual-findings.ts",
+ ]

 ❯ test/unit/worker-entry-boundary.test.ts:82:118
View the full list of 5 ❄️ flaky test(s)
test/contract/engine-parity.test.ts > predicted-gate engine parity (#2286) > 'merge-readiness-composite-preserves-e…' matches the committed golden output

Flake rate in main: 100.00% (Passed 0 times, Failed 6 times)

Stack Traces | 0.02s run time
AssertionError: expected { predicted: true, …(11) } to deeply equal { predicted: true, …(10) }

- Expected
+ Received

  {
    "basis": "public_config",
-   "blockers": [
+   "blockers": [],
+   "conclusion": "success",
+   "confirmedContributor": undefined,
+   "funnel": null,
+   "note": "Predicted from the repo's public .loopover.yml gate config + safe defaults. The maintainer may have private dashboard overrides not reflected here, and the dual-model AI-consensus blocker is only evaluated on a real PR. The slop score is NOT evaluated pre-submission (it needs the diff content) and may still fail the real gate. Provide the PR's changed paths to also predict the focus-manifest path policy, the size/guardrail hold, and any pre-merge check scoped to changed paths; without them only path-independent title/description/label pre-merge checks are predicted. Every author is gated the same: a configured hard blocker fails the gate regardless of confirmed-contributor status (which affects only on-chain scoring).",
+   "pack": "gittensor",
+   "predicted": true,
+   "readinessScore": 80,
+   "summary": "No configured hard blocker was found. Advisory findings, if any, stay advisory.",
+   "title": "LoopOver Orb Review Agent passed",
+   "warnings": [
      {
        "action": "If this PR is intended to solve an issue, link it explicitly in the PR body.",
        "code": "missing_linked_issue",
        "detail": "No closing reference or linked issue number was found in the PR metadata/body.",
        "title": "No linked issue detected",
      },
    ],
-   "conclusion": "failure",
-   "funnel": null,
-   "note": "Predicted from the repo's public .loopover.yml gate config + safe defaults. The maintainer may have private dashboard overrides not reflected here, and the dual-model AI-consensus blocker is only evaluated on a real PR. The slop score is NOT evaluated pre-submission (it needs the diff content) and may still fail the real gate. Provide the PR's changed paths to also predict the focus-manifest path policy, the size/guardrail hold, and any pre-merge check scoped to changed paths; without them only path-independent title/description/label pre-merge checks are predicted. Every author is gated the same: a configured hard blocker fails the gate regardless of confirmed-contributor status (which affects only on-chain scoring).",
-   "pack": "gittensor",
-   "predicted": true,
-   "readinessScore": 80,
-   "summary": "No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.",
-   "title": "LoopOver Orb Review Agent: No linked issue detected",
-   "warnings": [],
  }

 ❯ test/contract/engine-parity.test.ts:46:21
test/unit/engine-parity-fixtures.test.ts > predicted-gate engine parity fixtures > keeps the 'merge-readiness-composite-preserves-e…' fixture parseable and aligned with its documented surface

Flake rate in main: 100.00% (Passed 0 times, Failed 6 times)

Stack Traces | 0.0142s run time
AssertionError: expected 'success' to be 'failure' // Object.is equality

Expected: "failure"
Received: "success"

 ❯ test/unit/engine-parity-fixtures.test.ts:29:31
test/unit/linked-issue-label-propagation-fetch.test.ts > fetchLinkedIssueLabelsForPropagation (#priority-linked-issue-gate) > reward-label gate on direct author/assignee match (#9161) > propagates the reward label to its own issue's author when that author genuinely IS a repo maintainer (opt-in + maintainer check both satisfied)

Flake rate in main: 100.00% (Passed 0 times, Failed 6 times)

Stack Traces | 0.0304s run time
AssertionError: expected { labels: [ 'gittensor:bug' ], …(1) } to deeply equal { …(2) }

- Expected
+ Received

  {
    "inconclusive": false,
    "labels": [
      "gittensor:bug",
-     "gittensor:priority",
    ],
  }

 ❯ expectPropagation test/unit/linked-issue-label-propagation-fetch.test.ts:40:18
 ❯ test/unit/linked-issue-label-propagation-fetch.test.ts:1087:7
test/unit/predicted-gate-engine.test.ts > predicted-gate engine branch coverage (#2283) > exercises gate-advisory gateMode and blocker policy branches

Flake rate in main: 100.00% (Passed 0 times, Failed 6 times)

Stack Traces | 0.039s run time
AssertionError: expected 'block' to be 'advisory' // Object.is equality

Expected: "advisory"
Received: "block"

 ❯ test/unit/predicted-gate-engine.test.ts:1558:55
test/unit/salvageability.test.ts > resolveAiReviewSalvageableHold > defaults: no configured floor uses the gate default, and a confidence-less blocker counts as certainty (at/above floor)

Flake rate in main: 100.00% (Passed 0 times, Failed 6 times)

Stack Traces | 0.00686s run time
AssertionError: expected undefined to be defined
 ❯ test/unit/salvageability.test.ts:88:18

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 27, 2026
@loopover-orb

loopover-orb Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - fixes required

Review updated: 2026-07-27 10:32:02 UTC

18 files · 1 AI reviewer · no blockers · CI failing · unstable

🛑 Suggested Action - Manual Review

Review summary
This PR vendors a digest-pinned CoCo Helm chart override and Trustee KBS kustomize manifests, adds a small pure-function drift checker (checkCocoDevVersionDrift/findKustomizationImage) with 100% branch coverage on its core logic, and wires it into test:ci. The core logic is straightforward and correctly tested (name-only drift, digest-only drift, both, and missing-entry cases are all exercised). The two CI failures (validate-tests, validate) have no detail provided and this branch is 1 commit behind default, so the more likely explanation is something that landed on main after divergence rather than a defect visible in this diff.

Nits — 5 non-blocking
  • scripts/check-coco-dev-versions.ts:14 reads relative paths (`k8s/coco-dev/versions.json`, etc.) without resolving from repo root, so this only works when invoked from the repository root — worth a comment or an explicit root-relative resolution like other check scripts likely use.
  • k8s/coco-dev/kbs/base/kbs-config.toml sets `insecure_http = true` and `insecure_header_jwk = true` — clearly flagged as dev-only in the comment, but consider a startup assertion or naming convention (e.g. `-dev` suffix) to make it harder to accidentally reuse this file verbatim for metal: stand up a Confidential Containers (CoCo) runtime class on the k3s/Kata stack #8536.
  • The generate-kbs-keys.sh script silently reuses any pre-existing key file forever with no rotation path or warning if the key is stale — fine for a throwaway kind cluster but worth a one-line README caveat if scripts/up.sh output is ever copy-pasted into a longer-lived environment.
  • package.json:117 inserts `coco-dev-versions:check` into the middle of an already very long `test:ci` chain — no functional issue, but this monolithic script is becoming hard to read/maintain and could benefit from being split into a small runner script at some point (unrelated to this PR, just noting the trend).
  • Consider adding a one-line note in k8s/coco-dev/README.md's CI section explicitly stating that `coco-dev-versions:check` is a pure static file comparison and never touches a real cluster, to preempt a reviewer wondering why it's safe to run on every push.

CI checks failing

  • validate
  • validate-tests

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9213
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 13 registered-repo PR(s), 13 merged, 331 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 13 PR(s), 331 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Linked issue satisfaction

Addressed
The PR delivers digest-pinned k3s/Helm/Kata-CoCo manifests plus Trustee KBS kustomize manifests with a versions.json single source of truth and a CI drift check, idempotent up.sh/down.sh scripts, a clearly reasoned topology decision (KBS-mediated over direct attestation-agent flow), and documentation for deriving real measurements on SNP hardware, and it demonstrates a genuine dev-mode run (kind c

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Ruby, Go, MDX, Shell, Solidity, JavaScript
  • Official Gittensor activity: 13 PR(s), 331 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Decision record
  • action: hold · clause: success
  • config: 03a7f8b529a9 · pack: oss-anti-slop
  • record: b90444bd70f6 (schema v3, head a1fc68c)

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 27, 2026
…cision (#9213)

Vendors the Confidential Containers Helm chart (dev-only shim override) and
Trustee KBS kustomize manifests in no-TEE dev mode, with every version pinned
in versions.json and drift-checked in CI. Records the Trustee/KBS-mediated
topology decision and the plan for recording real launch measurements once
SNP hardware arrives, so #8536 becomes a config apply plus measurement
recording on real metal.

Verified against a real local kind cluster: the chart installs, the
kata-qemu-coco-dev RuntimeClass is created, and the KBS manifests apply
cleanly. Pod execution itself needs a real amd64 host (both the KBS image and
the kata-deploy dev-shim daemonset are amd64/s390x-only); the attested-run
harness (sample attester path) was verified standalone since it needs no
Kubernetes/Kata/KBS at all.
@JSONbored
JSONbored force-pushed the feat/coco-dev-metal-prep branch from a1fc68c to 78cfa2c Compare July 27, 2026 10:32
@JSONbored
JSONbored merged commit d04d0fe into main Jul 27, 2026
5 of 6 checks passed
@JSONbored
JSONbored deleted the feat/coco-dev-metal-prep branch July 27, 2026 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

metal-prep: CoCo stack in no-TEE dev mode — pinned manifests, Trustee topology decision, sample-attester E2E

1 participant