Repository navigation
Conversation
…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
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…ect RPC Delete the HttpApi contract, its backend handlers and endpoint tests, the generated SDK, and OpenAPI generation. Better Auth, the OAuth2 routes, and /health stay plain HTTP behind the same ingress. Add packages/rpc: the RPC contract with one group per context, the credential middlewares, the defect boundary, typed problem errors, the AccessSpec annotation, the client, and a script client for journeys. The backend serves NativeRpcs at /api/rpc; each context exports one handler layer that the router lists. Social events is ported end to end as the precedent; every other group is an empty stub that its worker fills from the base commit, following docs/specs/rpc-only.md. 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
…board session check, and the request recorder 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
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
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
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
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
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
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
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
Enable all five @effect/tsgo presets (correctness, antipattern, style, effectNative, recommended) as errors everywhere. apps/homepage and apps/dashboard keep their previous set: recommended and correctness without effectNative. The guard test now enumerates every rule the package ships, so a rule or category added by an upgrade is an error at once, and it accepts the React applications' override as the only relaxation. Measured on 6979637, the newly enabled rules report 3,475 findings outside the React applications, 323 of them in files the RPC migration deletes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
The RPC server lays each message's headers over the HTTP request headers, so a caller could forge the source address, user agent, or request correlation that session revocation audit and the contact quota read. The ingress now keeps only the headers a caller may supply inside a message (cookie, authorization, and the two contact headers the contact RPC reads behind its secret) on both the external and the internal RPC paths. A test at the ingress failed before the change (cf-connecting-ip reached the handler) and passes after it. The RPC path also answers preflight with a trailing slash, and both router builders take NativeRpcOptions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
strict-effect-provide cannot recognise an entry point; its documentation asks to disable it there. The exemption derives from effectConfig: files declared as composition roots or tests, and the backend test harness. The guard pins it as the only relaxation outside the React applications. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
# Conflicts: # oxlint.config.ts
# Conflicts: # docs/effect-exceptions.json
…ct program It runs its commands through ChildProcess, reads ambient configuration through Config, owns its temporary directory, cluster, and pool as scoped resources, and runs at a Bun composition root. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…ffect services The conventions CLI is a Bun composition root. Reading a repository loads its files through FileSystem once, so the checks keep their synchronous reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…rogram Its loopback receiver is a Bun HttpServer in the proof scope, it reads its database URL through Config, and it queries through SqlClient. The Bun server types conflict with the Node request types of the other verification programs, so the proof type-checks in its own tsconfig.bun.json, as tools/e2e does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
The runner and its evidence module become TypeScript. Processes run through ChildProcess in owned scopes, the provider and browser callbacks run through a FiberSet runtime, and time, environment, files, and JSON go through Clock, DateTime, Config, FileSystem, Path, and Schema. A declaration file types the browser driver's hooks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…itest admission as Effect programs The lock keeps its file protocol and flock(1) on the descriptor that it holds (EX-0013). Vitest admission writes the holder into the environment of its main process for its workers (EX-0014). A measured job runs through node spawn so that the ledger and the exit keep its terminating signal (EX-0015). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
Two journeys failed at random on color-contrast for a button: the golden reimbursement owner page and the onboarding spec. The shared button has transition-all and disabled:opacity-50, so right after a submission it is enabled but still half transparent, and axe reads the midpoint colours. auditSettledPage in apps/dashboard/e2e/settled-axe.ts waits in the page for every animation with a finite end, then runs axe with the caller's tags and regions and returns each violation's rule, impact, targets, and failure summary, without markup. It lives beside the dashboard journeys because the dashboard owns @axe-core/playwright and Playwright; the homepage journeys import it by path as the homepage Vite config already imports dashboard source, and the tools import it as they import native-operations.ts. All 24 modules that ran axe now audit through it, each with its own tags, regions, and assertion. The construct joins the new browser-audit category. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
anti-slop/no-unsettled-axe rejects new AxeBuilder(...) and any load of @axe-core/playwright (import, dynamic import, or a require call such as requireDashboard) outside apps/dashboard/e2e/settled-axe.ts, so no audit can run on a page whose transitions still move. The RuleTester test keeps negative controls beside the invalid cases. AGENTS.md records the defect class in Construction over trust with the flaky runs of 2026-09-28. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…ervations Effect programs The rehearsal owns its cluster, pool, and backend processes in its scope, runs commands through ChildProcess, reads configuration through Config, and serves the 0097 delivery sink on the Bun HttpServer that its entry provides. The delivery and reopening observations return Effects that require platform services; Playwright, pg, and the script client stay behind journey steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…ct program The runner becomes TypeScript: children run through ChildProcess in owned scopes, the recording proxy serves through Bun.serve and forwards with HttpClient from a FiberSet runtime, ports and executables come from Config, and the psql and browser evidence decode through Schema. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
… sink stops Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…eview deployment as Effect programs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…as Effect programs The artifact checks and the subprocess runner become TypeScript modules that return Effects; the CI job runs the renamed test file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
The recommendation probe and its helpers (returning assistant, report observer, co-interviewer correction, correction boundaries) become Effect programs on the Bun platform: ChildProcess through startOwnedProcess and commandOutput, HttpClient for fetch, FileSystem and Path, Config, DateTime, Effect.sleep and timeouts, Console through one ordered output queue, and typed failures. owned-process.ts and its test go; EX-0009 retires, and EX-0013 registers the page fetch of the returning options probe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
…n Effect program The proof owns its native processes through ChildProcess and signals them as before, serves its loopback provider on the Bun HttpServer of its entry, waits through Clock and Effect.sleep, and writes its evidence through FileSystem. It joins the Bun composition-root group and tsconfig.bun.json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
# Conflicts: # tools/verification/receipt-reopen-observation.ts
# Conflicts: # docs/effect-exceptions.json # tools/acceptance/recommendation-check.ts
…ect programs The Promise API of tools/postgres now bridges Effect programs over FileSystem, Path, and ChildProcessSpawner in one module runtime of the shared Node implementations, which Bun programs and Node suites both run. initdb, createdb, pg_isready, PgBouncer, and the sentinels run through ChildProcess; the postmaster and the synchronous installation resolution stay on Node under EX-0017. The exported functions of two parameters gain dual forms. The package tests become @effect/vitest programs. 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
…as Effect programs placement-check.ts becomes one Effect program at a Bun composition root: owned children through ChildProcess, the loopback receiver through Bun.serve with Effect handlers, readiness and sign-in through HttpClient, the artifacts through FileSystem, and the variables through Config. The golden school-service and recruitment observers and the evidence reader become typed TypeScript modules whose checkpoints are Effects; the evidence reader keeps its .mjs path and Promise forms for the CI wrapper and the browser drivers (EX-0017). The journey clock reads instants through DateTime, and the projection file lock through Semaphore (EX-0018, EX-0019). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmXVLTGJH6D28NK4jkdy3e
# Conflicts: # docs/effect-exceptions.json
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Worker Previews
Previews are frontend-only: pages that read the API show their unavailable state. |
This branch has not been deployed
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.
What changed
Related issue
Checklist