feat: add control/audit bootstrap envelope, durable stores, and D-158 handoff - #28
Conversation
… handoff Add the internal/control package: sealed BootstrapEnvelopeV1 with strict parsing, an owner-private state directory with exclusive 0600 fsync'd publish, typed generation-preconditioned control and append-only audit stores with in-memory fakes, the resumable K1a/K1b audit handoff over a narrow bucket port, exact K4 seed objects, and the closed resource-scoped K3/T6 bucket binding catalog. Pure local; no process execution. Claude-Session: https://claude.ai/code/session_01QitjD2fzVf5tiwV1eRVoqz
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a8c340019
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Coordinator (Thread F) review, one VALID finding; everything else in the M1-05 required-proof list maps to code and a test. F-1 —
No other finding met the adjudication bar. Rejected candidates (for the record, no action needed): 60 s adoption skew window (deliberate clock tolerance; the record should say "not before the claim minus 60 s"), untested conflicting-content branch in |
Require the exact 365-day period when a locked bucket is resumed, refuse expired approval or plan windows before any mutation, adopt a pre-existing bucket only when it holds the identical envelope bytes, bind the retention lock to the last observed metageneration, compare remote objects byte for byte, re-verify completed handoffs, refuse regressing clocks before persisting, reject symlinked state-directory components, preflight and strictly validate every existing K4 seed before creating any object, and cover each with a regression test. Claude-Session: https://claude.ai/code/session_01QitjD2fzVf5tiwV1eRVoqz
|
Coordinator finding F-1: VALID. Fixed in ac2a3ee: the locked-bucket resume branch of |
Summary
M1-05 part 1 (D-158 control/audit bootstrap, pure local): new
internal/controlpackage.envelope.go:BootstrapEnvelopeV1(schema id, canonical JSON, SHA-256) embedding the canonicalbootstrap.CompiledPlanbytes, a plan-boundApprovalProofV1, the complete expected (absent) observation set, and the firstJournalEntryV1. Strict parser rejects duplicate/unknown/null/trailing fields, hash mismatches, noncanonical encodings, and every cross-binding failure.statedir.go: explicit owner-privateStateDirectory; envelope writer uses exclusive create, mode 0600, fsync, atomic exclusive publish (os.Link, fails closed on an existing name), directory fsync; reader refuses symlinks, non-0600 modes, empty or oversized files;EnsureBootstrapEnvelopeaccepts only the identical hash on retry. No removal API.store.go: typedControlObjectName/AuditObjectNameconstructors for the ARCHITECTURE prefixes (locks/,adoption/,policy/,test/harness-state.json,test/ownership/,test/lifetime/,plans/,operations/<env>/<opId>/steps/viaworkflow.JournalObjectName);ControlStore{Create, Read, CompareAndSwap}with generation preconditions and no delete;AuditStore{Create, Read}with no overwrite/delete method at all; in-memory fakes.handoff.go: resumable K1a/K1b engine over a seven-methodAuditBucketPort(no delete/list/IAM): write-ahead local claim, describe-before-create, explicitErrBucketNameConflictprecondition failure (never an absence claim), create-only uploads verified by size+CRC32C+generation, archive lifecycle, verification before retention, separate lock call recorded as the PONR only when observed.seeds.go: exact K4 seed identities and content; existing objects preserved byte-for-byte; approved-policy mismatch blocks toward WF-ENV-02.iam.go: closed K3/T6 binding catalog; every binding resource-scoped to one approved bucket and onetest/prefix with the exact CEL condition; compensation limited to bindings absent before the operation.Closes the four PR #27 review items deferred to M1-05 (resource-scoping, in-operation compensation, exact K4 seeds, create-time bucket-name conflict). Assumptions and proposed ARCHITECTURE prefix additions are in
docs/specs/mongo-gcp-cli/m1-records/A-m1-05.md.Safety properties
internal/gcpchange, no new dependency, no frozen file edited.ErrPartialBootstrapBlocked); a bucket is adopted only with a local write-ahead claim or an identical remote envelope object.Verification
Run from the worktree with
GOWORK=off:go mod tidy -diff— cleango run ./internal/archcheck— passgo test ./...— pass (one transient helper-process failure in the untouchedinternal/gcppackage on a loaded machine; the package passed on rerun)go test -race ./internal/control/...— pass (changed package; aggregate race skipped locally per the board, GitHub Quality authoritative)QLTY_TELEMETRY=off qlty check --all --no-fix --level=low --fail-level=low— No issuesbash scripts/test-architecture-rules.sh— all acceptance/rejection cases passedbash scripts/check-go-licenses.sh— skipped:go-licensesnot on PATH; no dependency changedgit diff --check— cleanNo GCP mutation was performed. Read-only probes used:
gcloud --version,gcloud storage buckets list --format=json --limit=1(field-shape check only, no values recorded), and localgcloud storage ... --help.