feat(memory): harden jail hydration evidence and readback #227

Closed
clawdie wants to merge 0 commits from clawdie/jail-hydration-lifecycle-metadata into main AGit
Owner

Summary

Hardens jail hydration evidence and completes the readback path into the Jev-facing envelope.

  • Read lineage stamps only after verifying an exact, mounted jail root; unmounted root datasets and unowned parent directories stay unreadable.
  • Reject ambiguous ZFS mountpoint matches instead of attaching a parent dataset or its lifecycle tags.
  • Use documented plain bastille list output, reconcile jls with the Bastille State column, and fail closed to unknown on unrecognized/conflicting states.
  • Make the Bastille config/directory fallback reachable with default configuration, validate listing output, and report discovery failures distinctly from known-empty inventory.
  • Read current hasJailObservation links through QueryNodeCapacity, preserve observation timestamps/boot epoch/provenance/uncertainty, and carry them into CapacitySummary and the Boundary 1 envelope.

Regression coverage

  • mounted parent dataset with an unmounted separate root dataset: no parent tags or lineage leak
  • ambiguous ZFS mountpoints
  • unrecognized Bastille state with a running jls entry
  • unparseable Bastille listing falling back to a directory or reporting unavailable inventory
  • foreign/unmounted lineage files
  • failed vs known-empty discovery
  • config precedence and explicit config failures
  • current-link observation readback through capacity and envelope serialization
  • replacement deletion remains covered by the refresh test

Verification

go test ./..., go test -race ./..., go vet ./..., staticcheck ./..., CGO_ENABLED=0 go test ./..., FreeBSD cross-build, git diff --check, and docs gates pass locally.

Known limits

No live FreeBSD/ZFS host execution or complete Oxigraph round trip has been run for this head. The Bastille table parser is covered by fixtures based on the documented 1.4.x format; capture the installed version's bastille list output before merge.

## Summary Hardens jail hydration evidence and completes the readback path into the Jev-facing envelope. - Read lineage stamps only after verifying an exact, mounted jail root; unmounted root datasets and unowned parent directories stay `unreadable`. - Reject ambiguous ZFS mountpoint matches instead of attaching a parent dataset or its lifecycle tags. - Use documented plain `bastille list` output, reconcile `jls` with the Bastille `State` column, and fail closed to `unknown` on unrecognized/conflicting states. - Make the Bastille config/directory fallback reachable with default configuration, validate listing output, and report discovery failures distinctly from known-empty inventory. - Read current `hasJailObservation` links through `QueryNodeCapacity`, preserve observation timestamps/boot epoch/provenance/uncertainty, and carry them into `CapacitySummary` and the Boundary 1 envelope. ## Regression coverage - mounted parent dataset with an unmounted separate root dataset: no parent tags or lineage leak - ambiguous ZFS mountpoints - unrecognized Bastille state with a running `jls` entry - unparseable Bastille listing falling back to a directory or reporting unavailable inventory - foreign/unmounted lineage files - failed vs known-empty discovery - config precedence and explicit config failures - current-link observation readback through capacity and envelope serialization - replacement deletion remains covered by the refresh test ## Verification `go test ./...`, `go test -race ./...`, `go vet ./...`, `staticcheck ./...`, `CGO_ENABLED=0 go test ./...`, FreeBSD cross-build, `git diff --check`, and docs gates pass locally. ## Known limits No live FreeBSD/ZFS host execution or complete Oxigraph round trip has been run for this head. The Bastille table parser is covered by fixtures based on the documented 1.4.x format; capture the installed version's `bastille list` output before merge.
Gate lineage reads on verified mounted jail roots, reconcile jls and Bastille state conservatively, make the default Bastille config fallback reachable, and carry jail observations plus inventory certainty through QueryNodeCapacity into the Boundary 1 envelope.

Adds regression coverage for foreign/unmounted lineage files, ambiguous mountpoints, conflicting/unknown jail status, failed and known-empty discovery, config precedence, current-link observation readback, and replacement deletion.
fix(memory): close jail discovery uncertainty gaps
Some checks failed
CI / markdown (pull_request) Successful in 9s
CI / packaging (pull_request) Successful in 2s
CI / python-tests (pull_request) Failing after 20s
CI / mcp-cross-language (pull_request) Successful in 29s
CI / go (pull_request) Successful in 44s
leak-guard / guard (pull_request) Successful in 20s
5278fef707
Require exact root mount ownership before accepting a parent dataset, treat unrecognized Bastille states as unknown even when jls reported the jail, and reject unparseable Bastille listing output so discovery falls back or reports inventory unavailable instead of claiming a known-empty inventory.

Adds regression coverage for a mounted parent dataset with an unmounted separate root dataset, unrecognized Bastille states, and unparseable listing fallback/failure.
chore(tokens): refresh Go production token badge
All checks were successful
CI / markdown (pull_request) Successful in 9s
CI / packaging (pull_request) Successful in 1s
CI / python-tests (pull_request) Successful in 21s
CI / mcp-cross-language (pull_request) Successful in 25s
CI / go (pull_request) Successful in 40s
leak-guard / guard (pull_request) Successful in 21s
3a5f87854a
fix(memory): reject ambiguous Bastille rows without losing valid observations
All checks were successful
CI / markdown (pull_request) Successful in 10s
CI / packaging (pull_request) Successful in 2s
CI / python-tests (pull_request) Successful in 21s
CI / mcp-cross-language (pull_request) Successful in 25s
CI / go (pull_request) Successful in 39s
leak-guard / guard (pull_request) Successful in 23s
4f77f1408a
Reject whitespace-ambiguous or malformed Bastille rows instead of silently skipping them, preserve already-parsed rows when the table is incomplete, retry the Bastille 1.4.4 all table for Path, and prefer a unique exact jail-root dataset over its container dataset when both are visible.

Adds regression coverage for partial-row preservation, successful and failed fallback, whitespace paths, 1.4.4 default/all formats, VNET IP continuations, and exact-root precedence. Refreshes the Go token badge.
clawdie force-pushed clawdie/jail-hydration-lifecycle-metadata from 4f77f1408a
All checks were successful
CI / markdown (pull_request) Successful in 10s
CI / packaging (pull_request) Successful in 2s
CI / python-tests (pull_request) Successful in 21s
CI / mcp-cross-language (pull_request) Successful in 25s
CI / go (pull_request) Successful in 39s
leak-guard / guard (pull_request) Successful in 23s
to 53c535b80b
All checks were successful
CI / markdown (pull_request) Successful in 9s
CI / packaging (pull_request) Successful in 1s
CI / python-tests (pull_request) Successful in 20s
CI / mcp-cross-language (pull_request) Successful in 25s
CI / go (pull_request) Successful in 38s
leak-guard / guard (pull_request) Successful in 23s
2026-10-28 22:17:37 +01:00
Compare
clawdie closed this pull request 2026-10-30 13:30:44 +01:00
All checks were successful
CI / markdown (pull_request) Successful in 9s
CI / packaging (pull_request) Successful in 1s
CI / python-tests (pull_request) Successful in 20s
CI / mcp-cross-language (pull_request) Successful in 25s
CI / go (pull_request) Successful in 38s
leak-guard / guard (pull_request) Successful in 23s

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
clawdie/colibri!227
No description provided.