Skip to content

Refactor/authz evidence organization - #26

Open
phibkro wants to merge 9 commits into
mainfrom
refactor/authz-evidence-organization
Open

phibkro wants to merge 9 commits into
mainfrom
refactor/authz-evidence-organization

Conversation

@phibkro

@phibkro phibkro commented Sep 28, 2026

Copy link
Copy Markdown
Member

What changed

Related issue

Checklist

  • Self-reviewed my code
  • Verified it works as intended
  • CI passes

…mands

createDepartment, createTeam, and createFieldOfStudy take
OrganizationAdministratorEvidence instead of the OrganizationActor union.
requireOrganizationAdministrator is its only constructor, so a forged or
member actor no longer type checks, and the adapter's runtime re-check
(decodeOrganizationActor, authorizeOrganizationActor) is deleted. The
unused resolveActor option and organizationActorFrom are removed.

The stored actor_json keeps its shape, and the authorization-rules proof
observes the same tags. Pilot of docs/specs/authz-evidence.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
Flatten the evidence tests: Stryker 10 with Vitest 5 misses failures of
tests nested in describe, and killed 18 of 18 mutants once they were
top level. The authorization evidence spec records the falsifier
results, and STATE.md records the helpers still trusted by convention.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…ands

Add requireDepartmentReach, the only constructor of DepartmentReach<C>,
which proves a capability over one department. Three commands whose
only barrier was a check at their HTTP caller now take it:

- commandOnboarding takes the coordinator's admissions.outcomes reach and
  reads its department and audited actor from it.
- recordAdmissionOutcome takes the decider's reach and denies evidence for
  another department on the locked application, a check it lacked.
- Placements.execute takes a coordinator's placements.coordinate reach for
  board and coverage-board changes; own affiliation and coverage still act
  as the person.

Property tests show the evidence agrees with reaches, with department
administration, with canManagePlacements, and with the outcome Decide
permission, so the replaced handler checks keep their answers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
Four commands authorized before replay and then authorized again inside
the command, each resolving current authority twice in one transaction.
Their authorize step now returns branded evidence, and the command runs
from it without resolving authority again:

- Schools: SchoolCommandAuthorization carries the decoded command and
  the locked school and departments; executeCommand takes only it.
- Recruitment maintenance: RecruitmentMaintenanceAuthorization carries
  the decoded command; maintainRecruitment takes only it.
- Certificates: authorizeCertificateCommand and CertificateCommandTarget
  give way to DaysServedConfirmationAuthorization and
  CertificateIssueAuthorization; the scope, the assistant, the department
  row, and the issuer's seat come from the evidence.
- Team applications: authorize returns TeamApplicationAuthorization for
  the action; delete and revise take their application or team from it.

Schools and maintenance resolved authority at DateTime.now twice; they now
resolve it once. Each evidence is valid only in the transaction that
resolved it, which is the transaction the command runs in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
listTeamInterestRegistrations took a filter of authorized departments and
teams that its HTTP caller computed, so it read whatever scope a caller
named. requireTeamInterestScope now computes that scope from the resolved
authority, as the handler did, and is the only constructor of
TeamInterestReadScope, which the listing requires. The unused
departmentId filter is gone; the semester stays an argument.

A property test checks that the scope holds only departments and teams
that team-interest.read reaches, inside the requested department, and
that it denies exactly where nothing is readable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
SocialEvents.create took the creator's person id and trusted its caller
to have evaluated the create AccessSpec. requireSocialEventCreation now
builds SocialEventCreation from the same candidate grants, and create
takes it: the audited actor comes from the evidence, and a request for
another department than the evidence names is a defect.

A property test states the rule independently of the grants: an active
global administrator creates anywhere, an active appointment creates in
its department.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
Bun's node:http destroy() emits close but no error, so a probe attempt that
timed out never resumed, and waitForHttp outlived its deadline. The golden
team-application journey hung for 25 minutes before its first page when the
homepage's first request was slow. A probe against a silent listener with a
one-second deadline hung past 8 s before this change and fails at 4.1 s after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
@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.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-09-28T18:08:43.448842Z 6979637 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown

Worker Previews

Surface Latest pull-request revision Exact deployment
Public homepage Open Preview Open immutable deployment
Staff dashboard Open Preview Open immutable deployment

Previews are frontend-only: pages that read the API show their unavailable state.

Source: 69796377cfece929ff1a41acdfe32bb4accd9877

This branch has not been deployed

No deployments
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