Skip to content

feat(engine): manage verified engine lifecycle - #102

Open
qinyue0508-cmd wants to merge 2 commits into
codex/deployment-recovery-cleanfrom
codex/engine-lifecycle-clean
Open

feat(engine): manage verified engine lifecycle#102
qinyue0508-cmd wants to merge 2 commits into
codex/deployment-recovery-cleanfrom
codex/engine-lifecycle-clean

Conversation

@qinyue0508-cmd

Copy link
Copy Markdown

Summary

  • add versioned engine inventory with atomic activation and rollback
  • make active, verified, available inventory entries control deployment resolution
  • preserve Intent-pinned engine versions across Catalog updates
  • support generic engine ensure, rollback, and native offline import through MCP/CLI
  • recognize exact or compatible preinstalled Native engines and activate verified records
  • require trusted Catalog SHA256 evidence before an offline Native bundle can become verified
  • keep partner differences in Catalog YAML rather than vendor-specific code branches

Stack

This PR is intentionally stacked on codex/deployment-recovery-clean. Review and merge the deployment recovery PR first; then retarget this PR to develop.

Regression coverage

  • activate v2, roll back to v1, then resolve a new deployment through v1
  • recover an Intent-pinned old engine version after a Catalog update
  • reject unavailable or unverified rollback candidates
  • reject Native offline import without a trusted SHA256
  • verify and activate exact/compatible preinstalled Native engines
  • keep activation and rollback database writes atomic

Validation

  • engine, resolver, MCP, CLI, knowledge, recovery, and runtime tests passed
  • key package race tests passed
  • go vet ./... passed
  • CGO_ENABLED=0 builds passed for windows/amd64, darwin/arm64, linux/amd64, and linux/arm64
  • go test ./... has one environment-only failure in internal/external because this workstation exposes two real inference services; the same test fails identically on unmodified origin/develop

@qinyue0508-cmd
qinyue0508-cmd requested a review from rjckkkkk August 4, 2026 06:21

@rjckkkkk rjckkkkk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lifecycle structure and atomic DB transitions are solid, and the full suite, vet, and targeted race tests pass. I found four lifecycle/import correctness issues that should be addressed before merge.

Comment thread internal/engine/scanner.go Outdated
func imageContentDigest(id string) string {
id = strings.TrimSpace(id)
if strings.HasPrefix(strings.ToLower(id), "sha256:") {
return id

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Do not treat the runtime image ID as the Catalog OCI digest. Docker's docker images --no-trunc ID (and the CRI image id) identifies the image/config object; it is not the repository/manifest digest exposed through RepoDigests. ImportEngine later compares this value with asset.Image.Digest, so a normal imported image whose Catalog digest is a manifest digest will never be promoted to imported/verified and therefore cannot be activated. The existing VerifyImageDigest code already inspects RepoDigests; scanning/import should collect or verify that same evidence instead of passing img.id through as ContentDigest.

Comment thread cmd/aima/main.go
if img.RuntimeType == "native" && img.Origin == "preinstalled" && img.ContentDigest != "" &&
(img.VersionMatch == "exact" || img.VersionMatch == "compatible") {
entry.LifecycleStatus = "verified"
entry.VerificationStatus = "verified"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Do not mark a preinstalled executable verified merely because it has a locally computed hash and reports a compatible version. ContentDigest here is just the SHA256 of whatever file scanning found; it is never compared with Catalog trust evidence, and DetectedVersion may even come from probe.fallback_version when no successful version command ran. This turns an arbitrary/tampered binary from AIMA_ENGINE_DIR, PATH, or a probe path into an inactive verified record that engine.ensure may activate and the deployment overlay will execute. Keep it unverified unless its digest is checked against trusted Catalog evidence (or introduce an explicit operator trust action distinct from passive scan).

Comment thread cmd/aima/engine_lifecycle.go Outdated
continue
}
if current != nil {
return result, fmt.Errorf("engine asset %s has multiple active runtime versions on platform %s", result.AssetName, s.inventoryPlatform)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Make rollback address the same activation scope that the DB permits. The v21 unique index and ActivateEngineVersion scope activity by (asset_name, platform, runtime_type), so one asset may legitimately have both a Native and a container version active (for example after a Catalog update changes the preferred runtime). This API accepts only the asset name and rejects that valid state as ambiguous, leaving neither chain rollbackable. Either enforce one active version per asset/platform across runtimes, or add/select runtime_type in the rollback request and query that exact activation group.

if err != nil {
return fmt.Errorf("resolve path %s: %w", path, err)
}
if looksLikeNativeEngineBundle(absPath) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Detect package type by content or fall back to OCI import before returning. This extension gate sends every .tar.gz/.tgz directly to the Native importer; if the file is a gzip-compressed docker save/OCI archive, the native layout check fails and the existing container importer is never attempted. docker load and containerd import accept compressed image archives, so this regresses a common air-gapped container format. The later branch already demonstrates the safer order by trying one importer and then the other.

@qinyue0508-cmd
qinyue0508-cmd force-pushed the codex/engine-lifecycle-clean branch from 1d0fb3a to 6038ca1 Compare August 4, 2026 11:18
@qinyue0508-cmd
qinyue0508-cmd requested a review from rjckkkkk August 4, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants