Skip to content

Add distributed first-embodiment activation - #126

Merged
nicoechaniz merged 2 commits into
mainfrom
rc/independent-custody-20260828
Aug 29, 2026
Merged

Add distributed first-embodiment activation#126
nicoechaniz merged 2 commits into
mainfrom
rc/independent-custody-20260828

Conversation

@nicoechaniz

@nicoechaniz nicoechaniz commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Issue

Closes #127

Claim-ID: 42901987-69b6-43fc-9da0-da5bb3b0204c
Deployment: not deployed

Outcome

Adds a reproducible, fail-closed path from threshold-separated genesis custody to a runnable first embodiment. The same separated root holders can authorize later embodiments without copying a root seed or holder package to a target or keyless aggregator.

Invariants

  • Identity and provenance remain verifiable.
  • No private memory or credentials were added.
  • Existing compatibility commitments are preserved.
  • Root and recovery thresholds are unchanged.
  • The real genesis remains unactivated and unpublished.

Validation

  • Full supported repository suite on the corrected head: 647 tests discovered, 626 passed, 21 declared skips, zero failures, using disposable checkouts at the pinned Cluster and Collective Memory commits.
  • Focused review-regression gate: 40/40 passed.
  • Ruff format/check and strict mypy passed on the changed surface.
  • Two isolated builds from exact commit 52945123ec4d323c03eaafe216dce8a1d7e48565 were byte-identical.
  • The installed wheel rejects a FIFO genesis input within the bounded timeout, exits 2, and creates no output directory.
  • Secret scanning passed for the checkout, wheel, and sdist.
  • Exact-wheel two-container qualification on disposable Incus containers passed for 52945123...: separated 2-of-3 custody, first activation, second-enrollment activation, revision 1→2 bundle advancement, native encrypted peer pull, and exact import of one historical event. Both daemons were stopped and container port isolation restored. The unsigned real-host preparation from 3eb9de74... remains superseded and inactive.

Tests

  • python -m unittest discover -s tests -v: 647 discovered, 626 passed, 21 declared skips, zero failures.
  • python -m ruff format --check ... and python -m ruff check ...: passed.
  • python -m mypy --strict ...: passed.
  • python tools/reproducible_build.py ...: two byte-identical builds, with source parity inspection.
  • Installed-wheel FIFO/special-input smoke: passed.

Build identities:

  • commit: 52945123ec4d323c03eaafe216dce8a1d7e48565
  • tree: 0af4dfdb3506cfe826ee53533f67eee88fb96389
  • wheel SHA-256: da1274be3b03b5e213d715f718c7de14af50a89087985839fbc80fe0f49646d6
  • sdist SHA-256: 6378ca1f490c2d714c864cdaf76fb05582fa6191a30648280ff33807d70c773c

Security and rollback

No live being authority, production route, or service was changed. The unsigned real-host preparation from the superseded head was moved aside together with its local credential and was never root-approved. Rollback is to reject or revert this commit; no real genesis transition needs reversal because none was performed.

@nicoechaniz
nicoechaniz requested a review from compaii August 28, 2026 08:10
@nicoechaniz

Copy link
Copy Markdown
Contributor Author

@compaii Independent review requested for exact head 3eb9de74c2119df689659c3b477ef8354f3e96d5. Please focus on fail-closed threshold handling, holder/target trust boundaries, time-window checks, atomic target creation, and historical-event authentication after bundle advancement. CI and signed coordination are green; no real genesis activation or deployment has occurred.

@compaii compaii 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.

Independent review of exact head 3eb9de74c2119df689659c3b477ef8354f3e96d5.

Verdict: changes requested. The positive path and release gates are healthy, but four contract invariants still fail.

Blocking findings

  1. First-embodiment holder shares do not authenticate the exact request.

    create_root_share() signs only the embodiment credential body (operator_first_embodiment.py:291-295); request_id is an unsigned wrapper field (:296-302). Aggregation checks that wrapper value (:351-366) but cannot prove that the holder approved it.

    Reproduction: obtain two valid shares for request R1; create target-signed R2 with the same credential body but a new request ID, nonce, and extended expiry; change only each share wrapper's request_id. Aggregation and final validation accept R2 after R1 has expired, while both root signatures remain byte-identical. The same gap allows reassociation with another incarnation authorization that uses the same credential.

    This violates issue #127's requirement for per-holder approval of the exact request and weakens the stated freshness boundary. Add a holder signature/attestation over a closed share body that includes at least the request ID and credential signature, then reject request-ID, expiry, nonce, and incarnation reassociation in regression tests.

  2. Enrollment activation time is not bound to the signed transition.

    validate_activation() uses body["issued_at_ms"] for request and credential-time validation (operator_rebirth.py:1080-1095) but never requires it to equal the transition's signed issued_at_ms (:1095-1104).

    Reproduction: change activation issued_at_ms from 1800000000040 to 1800000000041, recompute the content-addressed activation ID, and validate. It is accepted while the signed transition still says 1800000000040.

    Require equality with the verified transition timestamp (or derive the activation timestamp from it). Add a regression and inspect the analogous recovery activation path for the same invariant.

  3. advance-bundle can emit a candidate from an unverified runtime document and an invalid peer endpoint.

    The CLI passes --base-runtime directly to apply_activation_to_runtime_bundle() (operator_rebirth.py:4045-4060). That function checks only bundle["manifest"], the history list, and a bounded endpoint string (:1663-1705); it does not verify the runtime bundle as a whole or apply native peer-endpoint validation.

    Reproduction: a three-field mapping containing only the matching manifest, an empty authority history, and peer targets is accepted with file:///etc/passwd; the returned candidate has no schema or control_head.

    Validate the input with authority_from_runtime_bundle(), require its exact authority to match base, validate the endpoint with the native peer-transport contract, and validate the completed candidate before writing it.

  4. Intermediate ancestor symlinks are followed by the new first-embodiment output path.

    _owner_directory() normalizes the path and checks only the final directory component (operator_first_embodiment.py:102-115). A secure tree containing alias -> real is accepted when preparing under alias/parent/output, and files are written under real/parent/output.

    Issue #127 explicitly requires symlink/alias attempts to fail closed. Resolve the path through stable directory descriptors (or verify every ancestor without following links) and add an intermediate-component regression. Check the shared rebirth filesystem helpers for the same class.

Reproduced positive evidence

  • Exact head/tree: 3eb9de74c2119df689659c3b477ef8354f3e96d5 / 064ccdb25543ab947c3ae20628f1d51ea4c64078.
  • Base: bf5f7415f075af09442973144bc529f4c5ce7985; merge tree clean.
  • Focused first-embodiment suite: 5/5 pass.
  • Full source suite: 644 tests pass, 8 skipped, Python 3.13.5.
  • Compileall, Ruff format/check, mypy, and git diff --check: pass.
  • Reproducible build matches the declared artifacts twice:
    • wheel SHA-256 f0ea8eb60773c7fd686a04ef077dba56b08423fd7853976e3dee73532a5fa7bb
    • sdist SHA-256 498d2ce226e95c2aa300b1f7e4fafa38806b1047e66a83d38c38f7e75096d88f
  • Distribution allowlist/metadata verification: pass.
  • GitHub CI is green across Python 3.11-3.14 and coordination.

No deployment or host mutation was performed.

@compaii compaii 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.

Supplement to the CHANGES_REQUESTED review on 3eb9de74c2119df689659c3b477ef8354f3e96d5. Two further findings confirmed independently after the review; the decision is unchanged.

1. Blocker — installed first-embodiment CLI hangs on a FIFO input

src/daimon_matrix/operator_first_embodiment.py:142-151

_document() opens the path at line 145 before establishing it is a regular file. Opening a FIFO with O_RDONLY blocks before the fstat() S_ISREG rejection can run, so a named pipe as --genesis (or --request/--holder/--profile) hangs the CLI instead of failing closed. This applies to every subcommand that reads a document through _document.

Reproduction against the installed wheel:

daimon-first-embodiment prepare --genesis <fifo> --profile <regular.json> \
  --password-fd 0 --output <out>

Result: timeout (2.0s), vs a regular-file control that returns immediately.

The shared helper already does this correctly: operator_rebirth.py::_owner_file_descriptor (:2007-2042) performs lstat() and the S_ISREG check before opening. The new module diverges from that in-repo safe pattern rather than introducing a new class of problem. Fix by mirroring the lstat-first (or O_NONBLOCK + post-open identity/type) sequence in _document, and add an installed-CLI FIFO regression with a timeout.

2. Major — distribution verification does not bind the new module's bytes to source

tools/check_distribution.py:308-358 (sdist source-parity loop) and :460-519 (wheel source_map)

Both byte-parity loops skip from operator_genesis.py directly to operator_rebirth.py, omitting operator_first_embodiment.py. The module is present in both allowlists (so _assert_exact passes and the artifact ships), but its shipped bytes are never compared against the source tree. A source-divergent operator_first_embodiment.py payload inside the wheel or sdist would pass the current package-integrity gate.

The artifacts I built are byte-correct (wheel f0ea8eb6…, sdist 498d2ce2…, matching the PR hashes), but the CI "package" gate does not prove it for this module. Add the module to both parity maps and a regression that rejects a mutated payload.

3. Non-blocking evidence note — two-isolated-container qualification is not committed

.github/workflows/tests.yml:148-194 installs the wheel but never invokes daimon-first-embodiment; tests/test_operator_first_embodiment.py:399-446 exercises both runtimes in one process via a loopback thread, and tests/test_dm070_multihost.py:59-60 skips the repository's only named "two installed processes" test (pre-V7 fixture). The issue #127 "two isolated containers" rehearsal is therefore asserted only in the PR body, not as a reproducible committed runner/receipt. Recommend committing a reproducible installed-wheel V7 two-container runner and its closed receipt (including the negative CLI cases), separate from this PR if desired.

No deployment or host mutation was performed.

@nicoechaniz

Copy link
Copy Markdown
Contributor Author

@compaii Nueva revisión solicitada sobre el head exacto 52945123ec4d323c03eaafe216dce8a1d7e48565. Mapa de los seis findings de 3eb9de74...:

  1. Cada first-root share ahora atesta criptográficamente request_sha256 + request_id + la firma de credential; la activación conserva y vuelve a verificar esas aprobaciones contra los bytes exactos de la request. Regresión: test_root_approvals_cannot_be_reassociated_to_a_new_request.
  2. Activaciones normales y de recovery exigen igualdad entre transition.issued_at_ms y body.issued_at_ms, incluso si se recalcula el activation ID.
  3. apply_*_activation_to_runtime_bundle valida el bundle V7 completo y su authority, valida transporte/endpoints con el parser nativo, y vuelve a validar el candidato. El target fresco se valida antes de escribir custody/runtime/journal. Regresiones para bundle mínimo y file:///etc/passwd.
  4. First embodiment y rebirth rechazan symlinks en cualquier ancestro del path.
  5. Los documentos se clasifican con lstat antes de abrir y se abren con O_NONBLOCK|O_NOFOLLOW; FIFO falla acotadamente. Hay regresión en proceso separado y smoke sobre wheel instalado.
  6. operator_first_embodiment.py quedó incorporado a la paridad fuente↔sdist↔wheel y a un test de bytes mutados.

Gates locales del head: focalizado 40/40; suite completa 647 descubiertos, 626 pass, 21 skips declarados, 0 failures; Ruff/mypy limpios; secret scan limpio; build doble byte-idéntico. Wheel da1274be...46d6, sdist 6378ca1f...773c. La preparación real sin firmas del head anterior fue supersedida y no se activó ningún root ni servicio.

@nicoechaniz

Copy link
Copy Markdown
Contributor Author

@compaii Actualización de evidencia, sin cambio de head: completé la calificación descartable de dos contenedores con el wheel exacto de 52945123ec4d323c03eaafe216dce8a1d7e48565 (da1274be...46d6).

  • Génesis distribuida nueva: root 2-of-3 y recovery 2-of-3; root-a operó sólo en iso-a, root-b sólo en iso-b.
  • First activation SHA-256: 245602fae2c4ce06a577e353181b5e5e0e020443c0d506533b34578215b8436e.
  • Second enrollment: shares aislados, activación c274b476272c53a0ca0850265491cc5893a1565d1416395ef1afea12426475d3, y avance de manifest revision 1→2 (f6c97baf...a79cbc3f476b95...2656f).
  • Peer transport nativo importó exactamente 1 evento histórico: 6a7aecd0-f03a-4635-ac59-1cd3c0c5e6b8; page hash cc28d7a3e799a449056226fe118ba45f9f12519c46866efd5ca4ddb8cadf6888; receipt hash 85584eae4d9f68d1b4234eb23ea23ab27a2ed121b0226bf6510a973e89bad169.
  • El primer intento falló cerrado como ambiguo porque Incus bloqueaba tráfico lateral. Para el éxito se desactivó temporalmente security.port_isolation sólo en iso-a/iso-b, con restauración garantizada; quedó verificado nuevamente true en ambos.
  • Ambos daemons quedaron detenidos. No se produjo génesis real, publicación ni deployment.

Receipt público local cerrado por hashes: qualification-receipt.json SHA-256 d9a63063b36f24d6bbeded4805252994ae519638b5d67f73bd32892d2da5ce37.

@compaii compaii 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.

Independent review of exact head 52945123ec4d323c03eaafe216dce8a1d7e48565 (fix commit over 3eb9de74).

Verdict: approve. All six findings from the CHANGES_REQUESTED review are fixed and independently re-verified.

Finding-by-finding confirmation

  1. Root-share request binding — fixed. create_root_share now signs a closed share body (being_ref, control_head, request_id, request_sha256, credential_signature) with a holder attestation (operator_first_embodiment.py:325-338); aggregate_activation and validate_activation re-verify each attestation and cross-check the approved signatures against the credential's root-authorization set. Independent probe: reusing two valid shares against a re-signed request (extended expiry, new nonce) is now rejected with first_embodiment_share_rejected. Regression: test_root_approvals_cannot_be_reassociated_to_a_new_request.

  2. Activation time bound to the signed transition — fixed. Both validate_activation (operator_rebirth.py:1097-1099) and validate_recovery_activation (:1643-1645) now require transition.issued_at_ms == body.issued_at_ms. Independent probe: a +1 tamper with recomputed activation ID is rejected. Regressions in test_dm078_rebirth.py and test_dm078_recovery_rebirth.py.

  3. advance-bundle validates the full V7 bundle — fixed. apply_activation_to_runtime_bundle and apply_recovery_activation_to_runtime_bundle now derive the source authority via authority_from_runtime_bundle, validate peer transport through the native http_peer_round_trip parser, and re-validate the candidate against the successor authority; _activate_target_runtime re-validates before writing custody. Independent probe: a minimal three-field bundle is rejected (invalid_rebirth_runtime_bundle) and file:///etc/passwd is rejected (rebirth_runtime_peer_transport_invalid).

  4. Ancestor symlink rejection — fixed. _reject_symlink_ancestors is wired into _owner_directory, _document, and _owner_file_descriptor in both modules. Regression: test_intermediate_symlink_and_fifo_inputs_fail_without_writes (no write occurs through an alias/parent path).

  5. FIFO fail-closed — fixed. _document now classifies with lstat() and rejects non-regular files before opening, then opens O_RDONLY|O_NOFOLLOW|O_NONBLOCK; _owner_file_descriptor also opens O_NONBLOCK. Independent installed-wheel probe: a FIFO as --genesis now returns exit code 2 in ~0.7s instead of hanging. Regression in-suite plus a CI smoke (dm087_fifo with timeout 2).

  6. Distribution parity — fixed. operator_first_embodiment.py is added to both the sdist parity loop and the wheel source_map via a shared _assert_source_parity helper (tools/check_distribution.py). Regression: test_first_embodiment_distribution_bytes_are_source_bound rejects a mutated payload.

Reproduced gates

  • Focused suites (first-embodiment, rebirth, recovery, package-scaffold): 40/40 pass.
  • Full suite: 647 tests, 0 failures/errors (8 skipped in this environment, which lacks the daimon-cluster/hermes-agent pinned checkouts).
  • Reproducible build byte-identical across two independent runs:
    • wheel SHA-256 da1274be3b03b5e213d715f718c7de14af50a89087985839fbc80fe0f49646d6
    • sdist SHA-256 6378ca1f490c2d714c864cdaf76fb05582fa6191a30648280ff33807d70c773c
      (both match the PR body's declared hashes).
  • tools/check_distribution.py passes; git diff --check clean; worktree clean.
  • GitHub CI green: tests 3.11-3.14, conformance, hermes-contract, package, pull-request.

Note (non-blocking)

The two-isolated-container qualification is now evidenced by the closed receipt in the PR comments (first activation 245602fa…, second enrollment c274b476…, single imported historical event 6a7aecd0…). It is still not committed as a reproducible runner in-repo; adding one remains a worthwhile follow-up but does not block merge.

No deployment or host mutation was performed.

@nicoechaniz
nicoechaniz merged commit 899c6d9 into main Aug 29, 2026
15 of 16 checks passed
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.

[DM-087] Activate a distributed first embodiment without centralized root custody

2 participants