Skip to content

feat(B-0883): determineEncryptionPath discriminator — EncryptionContext → PlannedEncryptionPath Result-shape (encryption lane substantive work; parallel to PR #5758)#5760

Merged
AceHack merged 2 commits into
mainfrom
otto-cli/b-0883-determine-encryption-path-discriminator-context-to-planned-path-result-shape-2026-05-28
May 28, 2026
Merged

feat(B-0883): determineEncryptionPath discriminator — EncryptionContext → PlannedEncryptionPath Result-shape (encryption lane substantive work; parallel to PR #5758)#5760
AceHack merged 2 commits into
mainfrom
otto-cli/b-0883-determine-encryption-path-discriminator-context-to-planned-path-result-shape-2026-05-28

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 28, 2026

Summary

Adds determineEncryptionPath discriminator to better-git-crypt PoC. Structurally parallel to workflow-engine's determineReviewLevel (PR #5758) at encryption-substrate scope. Substantive encryption-lane work per Aaron's 3-lane substrate-check (Amara ferry §33.2 PR #5757) + standing PoC permission.

What this adds

  • PlannedEncryptionPath interface (alg slots + recipientCount + senderIdentity + composesWith)
  • PlanResult discriminated union (ok with path | error with EncryptionFeedback)
  • determineEncryptionPath(context): PlanResult function with v1 design memo policy
  • 9 new tests covering happy paths + 6 distinct failure modes

31 tests pass / 0 fail

Policy

Condition Result
Empty recipients EmptyRecipientSet
Sender absent from recipients SenderNotInRecipientSet
Mixed KEM across recipients RecipientKeyInvalid (v1 single-KEM constraint)
Unknown or deferred-alternate KEM AlgUnsupported
Unknown or deferred-alternate signature AlgUnsupported
Valid context PlannedEncryptionPath with HKDF-SHA256 + ChaCha20-Poly1305-AEAD defaults

Composes with substrate

Test plan

  • 9 new tests; 31 total pass / 0 fail
  • Result-shape with discriminated PlanResult
  • Exhaustive over v1 design memo failure modes
  • CI: lint(tsc tools)
  • Auto-merge armed

🤖 Generated with Claude Code

…ontext → PlannedEncryptionPath Result-shape (structurally parallel to PR #5758 determineReviewLevel)

Substantive encryption-lane work per Aaron's 3-lane substrate-check (Amara
ferry §33.2 PR #5757) + standing PoC permission. Structurally parallel to
workflow-engine's determineReviewLevel discriminator (PR #5758) at
encryption-substrate scope.

Adds:
- PlannedEncryptionPath interface (algKem + algKdf + algWrap + algContent +
  algSig + recipientCount + senderIdentity + composesWith)
- PlanResult discriminated union (ok: true with path | ok: false with feedback)
- determineEncryptionPath(context): PlanResult function with v1 design memo
  policy:
  * Empty recipients → EmptyRecipientSet
  * Sender not in recipient set → SenderNotInRecipientSet
  * Mixed KEM algs across recipients → RecipientKeyInvalid (v1 single-KEM)
  * Unknown / deferred-alternate KEM → AlgUnsupported
  * Unknown / deferred-alternate signature → AlgUnsupported
  * Defaults: HKDF-SHA256 + ChaCha20-Poly1305-AEAD (wrap + content)

Tests (9 new):
- v1 path for single-recipient self-encrypt
- v1 path for multi-recipient with sender included
- EmptyRecipientSet for empty recipients
- SenderNotInRecipientSet when sender absent
- RecipientKeyInvalid for mixed KEM across recipients
- AlgUnsupported for deferred-alternate KEM (Saber)
- AlgUnsupported for unknown KEM
- AlgUnsupported for unknown signature
- Planned path composesWith B-0867.20 cross-lane substrate-engineering

31 tests pass / 0 fail.

Composes with substrate:
- B-0883 v1 design memo (algorithm selection per v1)
- B-0867.20 PR #5758 (structurally parallel discriminator at workflow-engine scope)
- B-0897 (Persist-as-bridge OPLE primitive — encryption IS Persist-as-bridge instance)
- PR #5728 (workflow-engine PoC scaffold)
- PR #5757 (Amara ferry substrate-check)
- PR #5516 (asymmetric-authorship — function authors TFeedback via EncryptionFeedback)
- PR #5511 (monad-propagation — Result<T, TFeedback> shape)

Per Aaron's 3-lane substrate-check ('so you finished the 3 lanes?'): NO, not
finished. This is incremental progress on the encryption lane; better-git-crypt
PoC now has a planning discriminator structurally parallel to what shipped for
workflow-engine. Phase 2 actual Noble integration + KEM operations still
deferred.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 28, 2026 10:53
@AceHack AceHack enabled auto-merge (squash) May 28, 2026 10:53
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a pure-function discriminator determineEncryptionPath to the better-git-crypt PoC that maps an EncryptionContext to a PlanResult (discriminated union of PlannedEncryptionPath on success or EncryptionFeedback on failure). The change is parallel in shape to PR #5758's determineReviewLevel discriminator but scoped to the encryption substrate, following the Result-shape monad-propagation pattern.

Changes:

  • Introduces PlannedEncryptionPath interface and PlanResult discriminated union in types.ts.
  • Implements determineEncryptionPath(context) selecting v1 KEM/KDF/WRAP/CONTENT/SIG algorithms with exhaustive failure handling (empty recipients, sender-not-in-recipients, mixed KEM, unsupported alg).
  • Adds 9 tests covering happy paths and 6 distinct failure modes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
tools/crypto/better-git-crypt/types.ts Adds PlannedEncryptionPath, PlanResult, and determineEncryptionPath discriminator.
tools/crypto/better-git-crypt/types.test.ts Adds 9 tests for the discriminator's happy paths and failure modes.

Comment thread tools/crypto/better-git-crypt/types.ts Outdated
… on PR #5760)

Comment incorrectly claimed 'Use AlgUnsupported as the failure variant' but
the code returns RecipientKeyInvalid. Updated comment to accurately describe
the chosen variant + reason:
- The per-recipient KEM is itself well-formed and supported
- The failure is v1's single-envelope-KEM-column constraint
- RecipientKeyInvalid surfaces the specific mismatched identity + reason

Per .claude/rules/blocked-green-ci-investigate-threads.md verify-before-fix
discipline: Copilot finding verified via direct inspection of code lines
381-388; comment-vs-code contradiction confirmed real; substrate-honest fix.

Tests still pass (31 / 0 fail).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 28, 2026
…nabilityVerdict (zflash lane substantive work; completes 3-lane parallel pattern with PR #5758 + PR #5760) (#5761)

Substantive zflash-lane work per Aaron's 3-lane substrate-check (Amara ferry
§33.2 PR #5757) + standing PoC permission. Completes the 3-lane parallel
substrate-engineering pattern:
- PR #5758 — workflow-engine determineReviewLevel (workflow scope)
- PR #5760 — better-git-crypt determineEncryptionPath (encryption scope)
- This PR — zflash determineRunnability (zflash scope)

Same substrate-engineering substrate (Result-shaped discriminator that maps
substrate-context → typed verdict) operating at 3 different substrate scopes.
The 3-lane work isn't 3 independent implementations; it's the same
substrate-engineering substrate from monad-propagation + asymmetric-authorship
rules operating across lanes producing parallel substrate.

Adds:
- RunnabilityVerdict discriminated union (6 variants: can-run-now,
  blocked-on-upstream-gate, blocked-on-state-preservation,
  blocked-on-multi-vm-orchestration, blocked-on-test-harness-path-fork,
  requires-physical-usb)
- determineRunnability(scenario, runnableUpstream): RunnabilityVerdict
  function with policy mapping per existing scenarios.ts notes
- computeRunnableSet() convenience — iterates SCENARIOS reflexively to
  surface the runnable subset

Tests (8 new; 20 total):
- initial-format → can-run-now (qemu-boot-test substrate)
- boot-cluster-up → can-run-now (qemu-full-install-test)
- reformat-with-retention → blocked-on-state-preservation (persisted-kv)
- reformat-from-scratch → blocked-on-test-harness-path-fork
- cluster-joining → blocked-on-multi-vm-orchestration
- all scenarios resolve to valid RunnabilityVerdict (exhaustiveness via
  TS strict-mode switch acknowledger)
- computeRunnableSet identifies composes-with-existing scenarios
- computeRunnableSet count matches composes-with-existing count

20 tests pass / 0 fail.

Composes with substrate:
- B-0891 row (zflash test-harness 5-scenario matrix)
- B-0867.20 PR #5758 (structurally parallel discriminator)
- B-0883 PR #5760 (structurally parallel discriminator)
- PR #5757 (Amara ferry substrate-check)
- PR #5516 asymmetric-authorship + PR #5511 monad-propagation
- tools/ci/qemu-full-install-test.ts (existing harness composition target)
- tools/ci/qemu-boot-test.ts (existing harness composition target)
- tools/ci/audit-installer-iso-content.ts (existing audit composition target)

Per Aaron's 3-lane substrate-check ('so you finished the 3 lanes?'): NO,
not finished. This is incremental progress on the zflash lane; all 3 lanes
now have structurally-parallel discriminator substrate. Phase 2 actual
QEMU state-preservation / multi-VM orchestration / path-fork support
deferred per operator-authorized follow-up.

Co-authored-by: Lior <lior@zeta.dev>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
@AceHack AceHack merged commit 75d00fa into main May 28, 2026
31 of 32 checks passed
@AceHack AceHack deleted the otto-cli/b-0883-determine-encryption-path-discriminator-context-to-planned-path-result-shape-2026-05-28 branch May 28, 2026 11:03
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.

2 participants