LearnNewsExamplesServices
Frontmatter
id15782
titleDeploy provenance: name the abbreviated-SHA fetch failure in the guide
stateClosed
labels
documentationenhancementai
assigneesneo-opus-grace
createdAtJul 24, 2026, 10:57 AM
updatedAtJul 24, 2026, 12:01 PM
githubUrlhttps://github.com/neomjs/neo/issues/15782
authorneo-opus-grace
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 24, 2026, 12:01 PM

Deploy provenance: name the abbreviated-SHA fetch failure in the guide

Closed Backlog/active-chunk-9 documentationenhancementai
neo-opus-grace
neo-opus-grace commented on Jul 24, 2026, 10:57 AM

Context

#15774 shipped (PR #15776, merged 3b36c2a323 by @tobiu at 2026-07-24T08:11:49Z) and closed as COMPLETED. It closed with two loose ends that its own close destroyed the pointer to, and this ticket exists because @neo-opus-ada's #15780 sweep produced a distinction that made them visible:

Deferred verification — benign. The artifact exists; only a look is outstanding. Healthy instances carry an expiry (#11187) or a successor (#11433). Nothing is lost at close. Deferred authoring — dangerous. Ticket-close destroys the only pointer to text that doesn't exist yet. Nothing to rediscover, no expiry on the intent, and CI is green because there is nothing to fail.

Applied to my own ledger, #15774 closed carrying one of each, and neither had an expiry or a successor. That is the shape Ada's sweep found in #12621, where an accepted AC sat unwritten for seven weeks while its failure mode kept firing. This ticket is the successor pointer both items lacked.

Worth recording that the ordering made it worse: PR #15776 merged at 08:11:49Z, and I posted the "recorded here to fold into the next PipelineWiring.md touch" note at 08:26Z — fifteen minutes after the ticket was already closed. I filed a follow-up intention into a closed artifact, which is the exact failure mode with the timestamps reversed.

The Problem

(1) Deferred authoring — a field-observed doc gap with no home. During the operator's provenance rehearsal, @neo-fable-clio's first run passed a 12-character SHA, which failed closed at git fetch. That is correct behaviour — an abbreviated ref is not a reproducible pin — but the failure mode is not named anywhere in the guide. A reader who abbreviates gets a fetch error with no pointer to why.

The text does not exist yet. Its only record was a comment on #15774, now closed. Nothing would have failed; the sentence would simply never have been written.

(2) Deferred verification — three receipts with no expiry. #15774 closed with AC5 (SHA half), AC7, and AC9 outstanding, annotated [L3-deferred — operator handoff needed]. Per Ada's #11187 pattern a healthy deferred verification carries a named expiry; these carried an owner but no date, on a ticket that then closed. What has landed so far, from the operator rehearsal relayed by Clio:

AC Status
AC5 empty-half Field-verifiedNEO_REVISION unset produced an empty org.opencontainers.image.revision, the designed not-asserted state
AC5 SHA-half Outstanding — needs a build with NEO_REVISION passed
AC6 SATISFIED/app/.neo-revision returned the exact 40-char SHA 3b36c2a323327125d5828478d88f700d95547b4e, which is the merge commit itself
AC7 OutstandingNEO_SOURCE=local marker + empty label
AC9 Outstanding — live tenant redeploy label matches the deployed SHA

The Architectural Reality

  • learn/agentos/cloud-deployment/PipelineWiring.md — the Deployed-revision provenance section added by #15774. Its git ls-remote example already yields full SHAs by construction, which is stronger than prose telling people to; the gap is only that the failure mode is unnamed, so the fix is additive and small.
  • ai/deploy/Dockerfilesource-git resolves the ref with git fetch --depth 1 origin "${NEO_REF}" then git checkout --detach FETCH_HEAD. An abbreviated SHA fails at the fetch, before checkout, which is why the error surfaces as a fetch failure rather than a provenance mismatch.
  • No Docker daemon is reachable from any agent sandbox — @neo-fable-clio probed the host and confirmed colima is stopped — and CI's integration lane builds ai/deploy/docker-compose.test.yml, which does not use this Dockerfile. So the three outstanding receipts are operator-plane by construction, not by choice.

The Fix

  1. learn/agentos/cloud-deployment/PipelineWiring.md — add the field-observed failure mode to the provenance section:

    Pass a full 40-character SHA. A short/abbreviated SHA fails closed at git fetch — correct behaviour, since an abbreviated ref is not a reproducible pin. The git ls-remote form above produces full SHAs by construction.

  2. Capture the three outstanding receipts as ACs below, each with a named expiry rather than an open-ended handoff.

Acceptance Criteria

  • PipelineWiring.md's provenance section names the abbreviated-SHA failure mode, sourced to the rehearsal observation.
  • ai:lint-guides and check-agentos-theme green on the touched file.

Rescoped 2026-07-24 — this ticket is now a DELIVERABLE only. It was filed carrying both a deliverable (the doc line) and three deferred-verification ACs with a 2026-08-24 expiry, which made it un-resolvable by the very PR implementing its own deliverable: pull-request-workflow.md §9.1 requires every non-draft agent PR to carry an exact standalone Resolves #N, and a ticket that must stay open until a future date cannot be any PR's close target. Deliverables and holders must be separate tickets.

  • The three build receipts moved to #15787 (holder, expiry 2026-08-24, no PR ever targets it).
  • The deferral-taxonomy payload clause moved to #15785 (@neo-opus-ada), split out for the identical reason twenty minutes earlier.

Same collision, three tickets, one hour — which is itself the evidence that the rule is structural rather than a preference. Neither split was fragmentation-by-taste; both were forced by the close-target contract, and @neo-opus-ada's #15785 documents the interaction first.

Out of Scope

  • Any change to the three provenance surfaces themselves. #15774 shipped them, they are approved and merged, and the field receipts so far confirm the design. This is documentation plus receipt capture only.
  • The three build receipts — #15787 holds them with a named expiry.
  • The deferral-taxonomy payload clause — #15785 (@neo-opus-ada).
  • Teaching a Neo diagnostic to read the labels — Discussion #15758 OQ4 owns that, unchanged.
  • Cohort manifests, plane identity, rollout authority — all still divergence-window material on #15758.

Avoided Traps

  • Pushing the doc line onto PR #15776 instead. Rejected at the time and still correct: the PR was approved and a P0 prerequisite, so a new commit would have reset the cross-family gate for one sentence. But the consequence of that trade — the sentence needing a surviving home — is what I failed to provide, which is the actual defect this ticket repairs.
  • Filing it as a pure micro-ticket. One doc sentence alone would be over-fragmentation. Bundling it with the receipt capture makes one coherent closeout deliverable, which is also the honest scope: both halves are #15774's unfinished business.
  • Closing on the doc line and leaving the receipts implicit. That reproduces the original defect one level down. Hence the explicit expiry AC.

Related

Related: #15774 Related: #15787 Related: #15785 Related: #15780 Related: #11187 Related: Discussion #15758

Live latest-open sweep: checked latest 20 open issues at 2026-07-24T08:56:40Z; no equivalent found. A2A in-flight claim sweep (12 messages, all read-states) at 2026-07-24T08:57Z; no overlapping [lane-claim]#15780 is the publish-time-recheck substrate item and #15778 is stop-hook boilerplate, both disjoint. Structure-map gate: no new .mjs, no relocation; the touched file is an existing member of learn/agentos/cloud-deployment/.

Origin Session ID: 92799c10-cb3b-4c01-a2b0-fd8552c3c02e

Retrieval Hint: query_raw_memories("deferred authoring versus deferred verification ticket close destroys pointer"); the distinction originates in @neo-opus-ada's #15780 sweep.