Slice 021: Permission gate + approval UI - #28
Merged
Merged
Conversation
… opens ROADMAP row 021 to in_progress. NOTES.md carries the measurement of the two RFC 8785 packages (rfc8785 1.0.0 refuses OTP 28; jcs 0.2.0 matches the RFC's own vector byte for byte), the decision for jcs open to the owner's veto, the nine-line build plan, the two-item manual queue, and four deviations stated before any code. plan_check: PASS. Signed-off-by: Ayla Croft <aylacroft@proton.me>
RFC 8785 canonical JSON for the approval fingerprints (docs/07), chosen by the measurement in NOTES.md: jcs 0.2.0 matches the RFC's own vector on this OTP; rfc8785 1.0.0 refuses OTP 28. VERSIONS row added; hex.audit clean. Signed-off-by: Ayla Croft <aylacroft@proton.me>
…te, approval_wait, the card and the audit Lines 2 to 8 of the G1 plan. Trinity.Permissions.Fingerprint (sha256 over RFC 8785 of tool, args, scope, cwd, canonicalization_version 1; the RFC's vector is a test). The tool_permissions and approvals tables with their schemas (Rule: the pattern language `*`, `key=glob`, `fp:<hex>`, `re:`; Approval: status, decision, decided_at, decided_by, consumed_at, expires_at) and Store. The tier's source: the registry hands the core tools' declared risks to Permissions.put_core_tiers/1 at its start and nothing else writes them. Policy.Layered in docs/07's order: session grants, the newest unspent decision for the fingerprint (allow once and deny are each consumed by one execution), persona settings, global rules, the default by tier. Permissions.Gate: a request is a row then a broadcast on approvals:<id> and approvals:all, an expiry timer, pending rows reloaded at init; decide_request/3 records the decision and writes the session grant or the global rule it implies. The runner turns an :ask into a request and an approval_required result; the Session holds those calls in approval_wait (012's empty state, now entered) and runs them again when the last decision lands, where the policy re-derives the fingerprint. TrinityWeb.ApprovalComponents (the card, the risk badge, the pending indicator), the card in the chat, PermissionsLive at /permissions (pending decidable, every decision with its time and decider, rules revocable). scripts/dev_chat_on_test_registry.sh serves the chat on the test registry for the screenshots, on its own database. Tests, 25 in test/trinity/permissions and 4 in the LiveView suite: the RFC vector, the pattern language, each policy layer and their order, the Gate's rows and broadcasts, AC1 (a read tool never reaches the Gate), AC2's two halves (approval_wait and the card; allow once runs the tool, the final message follows), AC3 (a session grant: the identical call runs, other arguments ask, another session asks), AC4 (an always rule with a glob, outside it asks, revocable), AC5 (a denial the model reads, the turn goes on), AC6 (expiry into a denial decided by expiry within the timeout), AC7 (every decision a row with decided_at; the audit page), AC8 (killed in approval_wait: the row pending and decidable, the restarted session idle). Screenshots in proof/. Gate exit 0, 233 tests; credo --strict --all clean; sobelow clean; docs/01, 05 and 07 synced. Signed-off-by: Ayla Croft <aylacroft@proton.me>
PROOF.md with every criterion's evidence: AC1, AC3, AC4, AC5, AC6 and AC8 from the Session-flow and Gate tests, AC2 and AC7 from their test halves plus screenshots under proof/ taken from the chat on the test registry, with the owner's two-step manual queue. NOTES.md carries the eight findings and the follow-ups. coverage.tsv: 021 at 72.45% from 67.18%. ROADMAP row 021 to done. Gate exit 0, 233 tests. Signed-off-by: Ayla Croft <aylacroft@proton.me>
Signed-off-by: Ayla Croft <aylacroft@proton.me>
…a missing table Red: the postgres job on pull request #28 (run 35528824468) booted the application before migrating and the Gate's init/1 read the approvals table: `relation "approvals" does not exist`, the application refused to start. The reload is a handle_continue that rescues into a warning, so a Gate that cannot read its table starts empty and the chat starts; a request made before the table exists fails on its own insert. NOTES.md finding 9, PROOF.md correction. Signed-off-by: Ayla Croft <aylacroft@proton.me>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slice 021 per
slices/021-permission-gate/SLICE.md. Evidence in itsPROOF.md; the canonicalisation measurement, findings and follow-ups in itsNOTES.md.jcs ~> 0.2, the RFC vector as a test), the layered policy in docs/07's order, the Gate with expiries that survive restarts, the Session'sapproval_wait, the card, the header indicator and/permissions.decide_request/3.proof/.