LearnNewsExamplesServices
Frontmatter
id16791
titleThe deployment-state snapshot does not carry the revision that produced it
stateClosed
labels
bugaiarchitectureagent-os
assigneesneo-opus-grace
createdAtAug 9, 2026, 3:47 PM
updatedAtAug 9, 2026, 6:44 PM
githubUrlhttps://github.com/neomjs/neo/issues/16791
authorneo-opus-grace
commentsCount1
parentIssue16706
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 9, 2026, 6:44 PM

The deployment-state snapshot does not carry the revision that produced it

Closed Backlog/active-chunk-14 bugaiarchitectureagent-os
neo-opus-grace
neo-opus-grace commented on Aug 9, 2026, 3:47 PM

⚠️ NARROWED 2026-08-09 by its own author — the headline premise was FALSIFIED by measurement

I filed this and it is partly wrong. Measured on the canonical plane after today's rebuild at dev head 55219f40d8: both MCP healthchecks publish the running revision.

memory-core healthcheck   → deployedRevision: "55219f40d8d1766ba44bd5b40708a3e0c8f2fec4"
knowledge-base healthcheck → deployedRevision: "55219f40d8d1766ba44bd5b40708a3e0c8f2fec4"

Both also carry runtimeFreshness.status: "current". A healthcheck is a continuously-read published surface, so the original claim — "nothing an agent or operator continuously reads ever reports it" — does not survive. The .neo-revision consumer table below is accurate and was the wrong population to reason from: it enumerated file readers, not published surfaces, so it could not have found the field that already exists.

What survives, and it is the whole remaining ticket: the deployment-state snapshot — the artifact the container-health and recovery lanes actually consume — publishes inspect summaries, stats, log tails, service classification, selfHeal, recoveryRuns, tenantRepoSync and maintenance, and does not carry the revision that produced any of it. Verified against a live snapshot today: no revision field at any level.

That is a much smaller leaf than the title claimed, and it is a real one: a recovery decision recorded without the revision that made it cannot be re-read later against the code that made it.

Struck rather than rewritten below, because anyone who read this before now took away a broader absence than exists.

Context

Every Neo image writes /app/.neo-revision. Nothing an agent or operator continuously reads ever reports it.

Named search rather than an asserted absence — grep -rn "\.neo-revision" across ai/, buildScripts/, apps/ and test/ returns exactly four consumers, and none of them is a published surface:

consumer shape
ai/examples/cloud-deployment/deploy-pipeline.sh comments only
ai/scripts/diagnostics/captureParityLatencyPair.mjs one-shot capture script
ai/scripts/maintenance/deploymentMigrationCore.mjs migration receipt cohort
ai/scripts/maintenance/migrateDeployment.mjs migration receipt cohort

All four are run by a human, once, during a migration. grep -rn "planeRevision\|runningRevision\|neoRevision\|buildRevision" ai/ returns nothing.

The DeploymentStateBridgeService snapshot publishes inspect summaries, stats, log tails, provider residency, service classification, selfHeal, recoveryRuns, tenant-repo sync and maintenance state. It does not publish which code produced any of it.

The Problem

A diagnostic without its revision is not evidence, and we have now made the same mistake twice in one day on two different planes.

  1. An external plane was diagnosed against current dev while running a 17-hour-old image. Four merged fixes it lacked were written against the exact symptoms being analysed — one of them, #16717, addresses the precise consecutiveFailures backoff-lock that was being investigated. The analysis was not wrong so much as aimed at a codebase that plane was not running.

  2. On this repository's own canonical plane, a Memory Core fault was filed as a "live reproduction" against #16677. Measured afterwards: the containers were at 92c0a49fda, dev was at 5eca010c1219 commits behind, and the missing set included ed5b8bb0ca, the merged fix for the very mailbox defect being reproduced. The evidence had to be publicly restated at a weaker strength within the hour.

Both are the same defect. A merged fix reaches a plane only when that plane is rebuilt, and no surface reports the gap — so "is this behaviour still broken?" and "is this plane simply old?" are indistinguishable from every tool we have.

This is a we saw it failure at the most basic layer. #16691 made a healthy Knowledge Base mean something on an empty corpus; a plane can still be silently nineteen commits stale with every indicator green.

The Architectural Reality

  • The datum already exists in every container and needs no new collection mechanism — /app/.neo-revision, written by the image build.
  • The bridge already performs a per-service readObserve sweep and already publishes a per-service record, so the revision belongs beside inspect and stats rather than in a new surface.
  • The cohort matters. migrateDeployment.mjs already establishes that only Neo-built services can produce a revision; chroma and a provider container cannot. A field that reads unknown for a third-party image is correct, and must be distinguishable from a Neo service that failed to report.
  • Staleness is a comparison, and the comparison is not the plane's to make: a plane knows what it runs, not what dev holds. Publishing the revision is this ticket; comparing it against a remote is a consumer's job and explicitly out of scope below.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
deployment-state snapshot, per service existing DeploymentStateBridgeService record Publish the service's running revision beside inspect / stats Unreadable ⇒ an explicit unavailable reason, never an omitted field and never an empty string Method JSDoc + the snapshot contract A fixture proves a Neo service reports its revision and a non-Neo service reports not-applicable
revision read /app/.neo-revision, written by the image Read through the existing bounded read-observe envelope A read failure degrades that service's entry only; the snapshot still writes JSDoc Negative fixture: read throws ⇒ unavailable + reason, siblings unaffected
snapshot size existing maxSnapshotBytes One short string per service Bounded by construction — a revision is 40 chars The existing size guard covers it

Acceptance Criteria

  • Each Neo service in the deployment snapshot carries its running revision.
  • A service whose image writes no revision reports not-applicable, distinguishable from a Neo service whose read failed (unavailable plus a reason). Conflating those is the defect one layer over — an absent axis reported as a normal value.
  • A revision read failure degrades only that service's entry; the snapshot still writes, and the sibling services keep their fields.
  • The value is the one the container actually holds, read through the existing read-observe envelope — not re-derived from a build arg, an env var, or a label, any of which can disagree with what is running.
  • Negative control: a plane whose services are all current is not flagged in any way by this ticket's change — publishing a fact is not publishing a verdict.
  • Coverage fails against today's code and passes against the repair.

Out of Scope

  • Comparing the revision against a remote and deciding "stale". A plane knows what it runs, not what dev holds; that comparison belongs to a consumer with network access and a policy about how far behind is acceptable. Filing that as a verdict here would put a judgment on a surface whose value is that it reports facts.
  • Rebuilding, redeploying or scheduling upgrades.
  • Config-leaf drift between revisions — #16765 owns that, and it is the config axis of the same question.
  • Deploy-provenance build-receipt verification — #15787 holds those, and it is a holder that cannot host a deliverable by construction.

Avoided Traps

  • Reading the revision from a build arg or label instead of the container. deploy-pipeline.sh already documents the failure: a tag object's id can disagree with /app/.neo-revision, so the label attests something other than what is running. Only the file the image wrote answers "what is this process".
  • Publishing a staleness verdict. The moment the plane asserts "behind", it needs a policy for how far is acceptable, and that policy will be wrong for someone. Publish the fact; let the consumer judge.
  • Treating unknown as a single state. A third-party image that never writes a revision and a Neo service whose read failed need opposite responses, and one field value for both would recreate the class this ticket exists to close.
  • Assuming the gap is small because the plane looks healthy. The measurement that produced this ticket found nineteen commits on a plane reporting healthy across every service.

Related

#16765 (config-leaf drift between revisions — the config axis) · #15787 (deploy-provenance receipts holder) · #16677 (where the misdiagnosis landed) · #16706 (the deployment-readiness epic whose "we saw it" clause this sits under) · #16691 (the precedent: a status that means nothing is worse than no status)

Origin Session ID: a641ddac-565a-4fc8-adc1-6c25629bddb7

Retrieval Hint: plane running revision not published deployment snapshot stale image misdiagnosis neo-revision