Phase 1: Capability use semantics #65

Merged
erikinkinen merged 3 commits from 1-capability-use-semantics into main 2026-03-03 15:07:15 +01:00
Owner

Summary

Implements Capability Use Semantics v1 for #25 by making UseCap an explicit rights-checked attempt, persisting deterministic allow/deny reasons in the event log, and adding focused coverage for invalid and insufficient-rights paths.

Closes #25.

What Changed

1) Make UseCap explicit with rights checking

  • UseCapPayload now requires required_rights (not just edge).
  • Added UseCapOutcomeReason:
    • Ok
    • MissingEdge
    • InsufficientRights
  • Added UseCapOutcome { bool allowed; UseCapOutcomeReason reason; }.
  • Extended ApplyEventResult with std::optional<UseCapOutcome> use_cap_outcome.
  • Implemented locked runtime semantics in apply_event:
    • Invalid request shape (edge==0 or empty required_rights) => hard Errc::InvalidArgument.
    • Missing edge => non-fatal denied outcome, empty delta.
    • Insufficient rights => non-fatal denied outcome, empty delta.
    • Sufficient rights => non-fatal allowed outcome, empty delta.
  • UseCap remains graph-non-mutating in all outcomes.
  • Updated UseCap payload callsites and event/snapshot equality helpers accordingly.
  • Updated model docs for Phase 1 UseCap behavior.

2) Add event log v1 use outcome reasons

  • Added EventLogResultV1 and optional EventLogRecord::result_v1.
  • Added generic codec wrappers:
    • encode_event_log_record_jsonl(...)
    • decode_event_log_record_jsonl(...)
  • Kept v0 codec helpers intact and compatible.
  • Implemented strict v1 schema:
    • {"v":1,"t":...,"event":...,"delta":...,"result":{"ok":<bool>,"reason":"<enum>"}}
  • Enforced strict reason vocabulary:
    • ok
    • missing_edge
    • insufficient_rights
  • Enforced ok/reason consistency during encode/decode.
  • Updated JsonlEventLogWriter::append to version-dispatch encoding.
  • Updated read_event_log_jsonl to accept v0 + v1 and validate:
    • replayed delta equals logged delta
    • for v1, replayed use outcome equals logged result
  • Updated CLI aes simulate output to emit v=1 records and populate result_v1 for every event.

3) Add tests for invalid and insufficient-rights use

  • Expanded apply_event tests for:
    • allowed use (sufficient rights)
    • denied use (missing edge)
    • denied use (insufficient rights)
    • hard error (invalid edge id)
    • hard error (empty required rights)
  • Expanded deterministic invalid-event tests for new UseCap contract.
  • Expanded event log format/reader/replay tests for v1:
    • roundtrip
    • strict schema rejection
    • unknown/inconsistent reason rejection
    • replay tamper detection on logged result
  • Updated CLI simulate test to assert emitted logs are v=1 and include result.

Commits

  1. Phase 1: Make UseCap explicit with rights checking (#25)
  2. Phase 1: Add event log v1 use outcome reasons (#25)
  3. Phase 1: Add UseCap invalid and insufficient-rights tests (#25)

Compatibility Notes

  • Source-level update required: UseCapPayload now needs required_rights.
  • v0 logs remain readable/replayable.
  • v1 is additive and strict; v0 helpers are preserved.

Validation

  • Ran after each commit:
    • cmake --build _build
    • ctest --test-dir _build --output-on-failure
  • Final status: 36/36 tests passing.
## Summary Implements **Capability Use Semantics v1** for `#25` by making `UseCap` an explicit rights-checked attempt, persisting deterministic allow/deny reasons in the event log, and adding focused coverage for invalid and insufficient-rights paths. Closes #25. ## What Changed ### 1) Make `UseCap` explicit with rights checking - `UseCapPayload` now requires `required_rights` (not just `edge`). - Added `UseCapOutcomeReason`: - `Ok` - `MissingEdge` - `InsufficientRights` - Added `UseCapOutcome { bool allowed; UseCapOutcomeReason reason; }`. - Extended `ApplyEventResult` with `std::optional<UseCapOutcome> use_cap_outcome`. - Implemented locked runtime semantics in `apply_event`: - Invalid request shape (`edge==0` or empty `required_rights`) => hard `Errc::InvalidArgument`. - Missing edge => non-fatal denied outcome, empty delta. - Insufficient rights => non-fatal denied outcome, empty delta. - Sufficient rights => non-fatal allowed outcome, empty delta. - `UseCap` remains graph-non-mutating in all outcomes. - Updated `UseCap` payload callsites and event/snapshot equality helpers accordingly. - Updated model docs for Phase 1 `UseCap` behavior. ### 2) Add event log v1 use outcome reasons - Added `EventLogResultV1` and optional `EventLogRecord::result_v1`. - Added generic codec wrappers: - `encode_event_log_record_jsonl(...)` - `decode_event_log_record_jsonl(...)` - Kept v0 codec helpers intact and compatible. - Implemented strict v1 schema: - `{"v":1,"t":...,"event":...,"delta":...,"result":{"ok":<bool>,"reason":"<enum>"}}` - Enforced strict reason vocabulary: - `ok` - `missing_edge` - `insufficient_rights` - Enforced `ok`/`reason` consistency during encode/decode. - Updated `JsonlEventLogWriter::append` to version-dispatch encoding. - Updated `read_event_log_jsonl` to accept v0 + v1 and validate: - replayed delta equals logged delta - for v1, replayed use outcome equals logged `result` - Updated CLI `aes simulate` output to emit `v=1` records and populate `result_v1` for every event. ### 3) Add tests for invalid and insufficient-rights use - Expanded `apply_event` tests for: - allowed use (sufficient rights) - denied use (missing edge) - denied use (insufficient rights) - hard error (invalid edge id) - hard error (empty required rights) - Expanded deterministic invalid-event tests for new UseCap contract. - Expanded event log format/reader/replay tests for v1: - roundtrip - strict schema rejection - unknown/inconsistent reason rejection - replay tamper detection on logged `result` - Updated CLI simulate test to assert emitted logs are `v=1` and include `result`. ## Commits 1. `Phase 1: Make UseCap explicit with rights checking (#25)` 2. `Phase 1: Add event log v1 use outcome reasons (#25)` 3. `Phase 1: Add UseCap invalid and insufficient-rights tests (#25)` ## Compatibility Notes - Source-level update required: `UseCapPayload` now needs `required_rights`. - v0 logs remain readable/replayable. - v1 is additive and strict; v0 helpers are preserved. ## Validation - Ran after each commit: - `cmake --build _build` - `ctest --test-dir _build --output-on-failure` - Final status: **36/36 tests passing**.
erikinkinen added this to the Phase 1 milestone 2026-03-03 15:06:33 +01:00
Phase 1: Add UseCap invalid and insufficient-rights tests (#25)
All checks were successful
ci / smoke (push) Successful in 15s
clang-format / check-format (push) Successful in 9s
markdownlint / markdown-lint (push) Successful in 10s
ci / smoke (pull_request) Successful in 16s
clang-format / check-format (pull_request) Successful in 9s
markdownlint / markdown-lint (pull_request) Successful in 10s
e1b8c42ecb
Sign in to join this conversation.
No reviewers
No milestone
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
erikinkinen/AES!65
No description provided.