Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
697 commits
Select commit Hold shift + click to select a range
d2a32c9
docs(roadmap): close tooling census correction reviews
cemililik Oct 22, 2026
f3ca5c4
test(jobs): preserve native wait failure attribution
cemililik Oct 22, 2026
8234856
docs(roadmap): record native wait diagnostic review
cemililik Oct 22, 2026
12d4f08
docs(roadmap): close native wait diagnostic reviews
cemililik Oct 22, 2026
87ac371
test(jobs): wait for actual cleanup before fixture hints
cemililik Oct 22, 2026
9d1ba8c
test(jobs): retain cancellation before fixture hint emission
cemililik Oct 22, 2026
9eecf96
docs(roadmap): close fixture handoff correction reviews
cemililik Oct 22, 2026
b25d00a
fix(ci): bound browser dependency mirror waits
cemililik Oct 22, 2026
6027530
test(ci): exercise partial browser setup writes
cemililik Oct 22, 2026
e2954be
docs(ci): record browser acquisition review closeout
cemililik Oct 22, 2026
d5f1982
fix(ci): reserve bounded public demo completion time
cemililik Oct 22, 2026
2dc9d74
docs(roadmap): record first outer-budget correction reviews
cemililik Oct 22, 2026
58d9ecd
docs(roadmap): close outer-budget correction reviews
cemililik Oct 22, 2026
f5696ec
fix(ci): join maintenance in OpenAPI control repositories
cemililik Oct 22, 2026
ace2a77
test(ci): require successful owned Git maintenance proof
cemililik Oct 22, 2026
979750c
docs(roadmap): close Git maintenance fixture reviews
cemililik Oct 22, 2026
5bce55d
fix(ci): retain closed producer gate refusal diagnostics
cemililik Oct 22, 2026
84f681a
docs(roadmap): record gate diagnostic review evidence
cemililik Oct 22, 2026
95edb21
docs(roadmap): close producer gate diagnostic reviews
cemililik Oct 22, 2026
8231d17
fix(ci): own Outbox startup and attribute producer refusal
cemililik Oct 22, 2026
0fa8e64
docs(roadmap): record Outbox correction first review
cemililik Oct 22, 2026
ed223ac
docs(roadmap): record independent Outbox correction approval
cemililik Oct 22, 2026
4834e0c
fix(ci): bound pending producer metadata acquisition
cemililik Oct 22, 2026
8e437c3
fix(ci): validate creation times before metadata settlement
cemililik Oct 22, 2026
dada277
docs(roadmap): record independent metadata acquisition reviews
cemililik Oct 22, 2026
8a04bc5
docs(decisions): accept ADR-0069 phase documents and delivery logs
cemililik Oct 22, 2026
f5a4382
docs(roadmap): split Phase 02b and 02d records into delivery logs
cemililik Oct 22, 2026
34c6be9
docs: hold packet status once and record the delivery log rule
cemililik Oct 22, 2026
1b6107c
ci(meta): guard link fragments and roadmap structure
cemililik Oct 22, 2026
81cedbb
docs(decisions): amend ADR-0069 with generated delivery log indexes
cemililik Oct 22, 2026
fa32c0c
docs(roadmap): open each delivery log with a generated index
cemililik Oct 22, 2026
395d078
fix(ci): install Chromium without the APT mirror
cemililik Oct 23, 2026
baeb32f
docs(decisions): propose owned tenant BFF sessions
cemililik Oct 23, 2026
30933cb
docs(decisions): resolve BFF session proposal review findings
cemililik Oct 23, 2026
7474015
docs(roadmap): finish the BFF decision pass and prior closeout
cemililik Oct 23, 2026
325558e
docs(decisions): revise BFF ownership after maintainer review
cemililik Oct 23, 2026
ecb34b5
docs(decisions): retain logout owners in subject admission
cemililik Oct 23, 2026
d3033f3
docs(roadmap): complete revised BFF proposal review
cemililik Oct 23, 2026
eb91186
docs(decisions): accept native tenant BFF session ownership
cemililik Oct 23, 2026
1d51393
feat(identity): add inactive BFF RP and provider event policy
cemililik Oct 23, 2026
26ccc73
fix(identity): qualify logout and event response boundaries
cemililik Oct 23, 2026
fd70846
fix(identity): preserve provider defaults and closed network reasons
cemililik Oct 23, 2026
11cd37d
feat(identity): own bounded native BFF session lifecycles
cemililik Oct 23, 2026
47ffca7
fix(identity): preserve current callback visitor attribution
cemililik Oct 23, 2026
2ebae0c
docs(roadmap): close native BFF ownership reviews
cemililik Oct 23, 2026
3279258
feat(web): implement closed BFF HTTP and request projections
cemililik Oct 23, 2026
7fded69
fix(web): retain native RSC activity through Next middleware
cemililik Oct 23, 2026
e91cf15
docs(roadmap): close P02b-7 HTTP protocol review rounds
cemililik Oct 23, 2026
09b3aa6
feat(web): activate optional tenant BFF and localized session UI
cemililik Oct 23, 2026
2cf2a25
fix(web): close development auth traces and add skip links
cemililik Oct 23, 2026
a48011c
fix(web): preserve focus through session recovery transitions
cemililik Oct 23, 2026
5efecf7
test(identity): prove native BFF lifecycle and browser isolation
cemililik Oct 23, 2026
83858d1
fix(identity): join BFF proof owners before reporting success
cemililik Oct 23, 2026
b600a0f
fix(identity): observe parent EOF throughout BFF acquisition
cemililik Oct 23, 2026
fedffbe
chore: synchronize merged main history
cemililik Oct 23, 2026
d3d7c04
test(web): expect closed shells when tenant sign-in is disabled
cemililik Oct 23, 2026
19cd810
test(ci): isolate held-constructor cancellation and copied ingress
cemililik Oct 23, 2026
1784507
test(jobs): preserve the handoff control before constructor entry
cemililik Oct 24, 2026
c245afc
test(web): distinguish closed browser readiness failures
cemililik Oct 24, 2026
f2a3814
test(jobs): retain the first source-contention failure
cemililik Oct 24, 2026
419a8d9
test(jobs): accept lawful finalizer retries in causal restart
cemililik Oct 24, 2026
4ce7d4d
test(web): retain closed browser failure and cleanup evidence
cemililik Oct 24, 2026
5fc18ce
docs(roadmap): close P02b-7 implementation qualification
cemililik Oct 24, 2026
903ed92
fix(web): preserve anonymous reads and BFF failure ownership
cemililik Oct 24, 2026
a8ee8ba
docs(roadmap): record the reviewed BFF correction handoff
cemililik Oct 24, 2026
5e07cce
test(web): retain startup evidence until child absence
cemililik Oct 24, 2026
268e30c
test(jobs): distinguish recovery renewal from initial timer setup
cemililik Oct 24, 2026
c2a7e97
docs(roadmap): refresh the recovery follow-up index
cemililik Oct 24, 2026
c12f4ee
fix(ci): classify private fixture image preparation failures
cemililik Oct 24, 2026
f712fad
docs(auth): propose uncertain AccountSite refusal policy
cemililik Oct 24, 2026
e782f97
docs(auth): accept explicit AccountSite refusal decision
cemililik Oct 24, 2026
0fa1afe
fix(auth): bind closed BFF boundaries and lifecycle proofs
cemililik Oct 24, 2026
9a32318
test(auth): close configuration and scoped dependency escapes
cemililik Oct 24, 2026
7133f8a
fix(auth): retain ordinary sessions on uncertain API refusal
cemililik Oct 24, 2026
4dbb1d5
test(auth): pin the checked configuration plugin binding
cemililik Oct 24, 2026
31a2754
fix(auth): preserve accessible recovery and proof observations
cemililik Oct 24, 2026
18f3c70
test(auth): bind provider and CI proof failure boundaries
cemililik Oct 24, 2026
4ead28c
fix(auth): reconcile current session proof carriers
cemililik Oct 24, 2026
f64c51f
docs(auth): distinguish verified callback authority
cemililik Oct 24, 2026
9fb1cf3
test(auth): observe provider time and actual HTML refusal
cemililik Oct 24, 2026
4b7f01a
test(auth): bind authenticated SDK result boundaries
cemililik Oct 24, 2026
abdd5da
docs(auth): record SDK counterfactual review evidence
cemililik Oct 24, 2026
e42cc55
docs(auth): hand off the reviewed correction source
cemililik Oct 24, 2026
d380aa6
test(jobs): retain closed recurrence wait observations
cemililik Oct 24, 2026
43b12c7
test(ci): bind both recurrence observation cases independently
cemililik Oct 24, 2026
dd57d53
test(auth): preserve closed browser launch observations
cemililik Oct 24, 2026
aeeea13
test(auth): report browser liveness without inferring exit
cemililik Oct 24, 2026
ae2f7f7
test(jobs): isolate causal stop after actual provider acceptance
cemililik Oct 24, 2026
a286950
docs(roadmap): record final BFF correction qualification
cemililik Oct 24, 2026
cac786d
fix(auth): close review proof and recovery gaps
cemililik Oct 24, 2026
86598f7
docs(roadmap): retain first correction review receipts
cemililik Oct 24, 2026
806d6ba
docs(roadmap): record independent correction recheck
cemililik Oct 24, 2026
3dedda8
test(auth): delimit opaque observer child arguments
cemililik Oct 24, 2026
5748dbb
docs(roadmap): record observer argument review evidence
cemililik Oct 24, 2026
0bde36f
docs(roadmap): freeze reviewed observer correction
cemililik Oct 24, 2026
6b6f062
docs(roadmap): record reviewed BFF correction qualification
cemililik Oct 24, 2026
0d0696a
docs(roadmap): close merged tenant BFF delivery
cemililik Oct 24, 2026
c0261ca
docs(roadmap): propose phase exit enforcement decisions
cemililik Oct 24, 2026
7e6e61f
docs(roadmap): refine phase exit proposal after review
cemililik Oct 24, 2026
49b541c
docs(roadmap): require canonical inventory before gate acceptance
cemililik Oct 24, 2026
486588d
docs(roadmap): record phase exit proposal review verification
cemililik Oct 24, 2026
4b29ea7
docs(decisions): accept phase exit enforcement package
cemililik Oct 24, 2026
212ec0f
feat(kernel): guard sensitive exception messages at compile time
cemililik Oct 24, 2026
4682e26
fix(kernel): analyze dynamically bound exception constructors
cemililik Oct 24, 2026
fa56aac
docs(roadmap): close first phase exit implementation step
cemililik Oct 24, 2026
b20ffae
test(kernel): verify durable asynchronous inventory coverage
cemililik Oct 24, 2026
c241301
fix(kernel): refuse unsupported inventory table creation
cemililik Oct 24, 2026
bfa6ec8
fix(kernel): close inventory schema resolution bypasses
cemililik Oct 24, 2026
3a56444
docs(roadmap): close asynchronous inventory verification
cemililik Oct 24, 2026
1231aed
fix(kernel): reconcile delivered phase contract carriers
cemililik Oct 24, 2026
4d242bc
docs(roadmap): record carrier reconciliation review
cemililik Oct 24, 2026
63a4b52
docs(roadmap): close phase carrier reconciliation
cemililik Oct 24, 2026
c5847a9
chore(repo): merge current main into development
cemililik Oct 24, 2026
6224bd9
test(kernel): bind phase exit criteria to actual proof owners
cemililik Oct 25, 2026
7ae3d8f
docs(roadmap): record exit source review boundary
cemililik Oct 25, 2026
f5e73a1
docs(roadmap): record the second exit source review
cemililik Oct 25, 2026
141592f
docs(roadmap): close source-bound Phase 02b exit qualification
cemililik Oct 25, 2026
60a9721
fix(kernel): close exit guard and evidence review gaps
cemililik Oct 25, 2026
b4b85de
test(kernel): reject opaque SQL routine storage creation
cemililik Oct 25, 2026
5da6bab
test(kernel): validate complete SQL routine declaration boundaries
cemililik Oct 25, 2026
0d9dea4
docs(roadmap): record verified exit correction review boundaries
cemililik Oct 25, 2026
c399ba5
test(ci): include the new PostgreSQL fixture in the plan witness
cemililik Oct 25, 2026
93ef4b1
test(kernel): bind retry fairness and SQL literal proof to durable facts
cemililik Oct 25, 2026
ec03861
docs(roadmap): record the reviewed CI correction source
cemililik Oct 25, 2026
0d60980
test(kernel): qualify completion after acknowledged skipped wakeups
cemililik Oct 25, 2026
d6462dc
docs(roadmap): freeze the reviewed native completion correction
cemililik Oct 25, 2026
65f3283
test(frontend): own Playwright artifacts through fixture cleanup
cemililik Oct 25, 2026
7a2ef1d
docs(roadmap): freeze reviewed fixture ownership and carrier fixes
cemililik Oct 25, 2026
b1f19f5
docs(roadmap): close qualified PR corrections and exit evidence
cemililik Oct 25, 2026
819ef22
docs(roadmap): close merged phase 02b and point to phase 03
cemililik Oct 25, 2026
46da681
docs: prepare phase 03 identity implementation plan
cemililik Oct 25, 2026
8cf352f
docs(decisions): propose identity and membership foundation
cemililik Oct 25, 2026
c9a969f
docs(decisions): close first identity proposal review findings
cemililik Oct 25, 2026
d0fd67d
docs(decisions): define global audit outcomes and fresh lock reads
cemililik Oct 25, 2026
037fd56
docs(decisions): preserve canonical audit timestamp reconciliation
cemililik Oct 25, 2026
9211789
docs(roadmap): record reviewed identity proposal readiness
cemililik Oct 25, 2026
6bff3fe
docs(identity): resolve foundation authority and lifecycle gaps
cemililik Oct 25, 2026
26237b8
docs(decisions): complete identity acceptance carriers
cemililik Oct 25, 2026
acd2076
docs(roadmap): record revised identity proposal readiness
cemililik Oct 25, 2026
c63ca62
docs: bind identity proposals to existing execution paths
cemililik Oct 25, 2026
cd8150c
docs(decisions): bound initial identity role admission
cemililik Oct 25, 2026
06b3619
docs(roadmap): record source-bound identity review closeout
cemililik Oct 25, 2026
e627208
docs(decisions): accept the scoped identity foundation
cemililik Oct 25, 2026
7ded258
docs(architecture): reconcile accepted identity carriers
cemililik Oct 25, 2026
6602fb9
docs(roadmap): close identity authority adoption reviews
cemililik Oct 25, 2026
3261114
feat(kernel): classify every mapped production property
cemililik Oct 25, 2026
eccf2df
docs(identity): reconcile current classification proof status
cemililik Oct 25, 2026
e4a8a0a
docs(roadmap): close both classification review rounds
cemililik Oct 25, 2026
e3f56cb
feat(identity): persist global bindings with central audit
cemililik Oct 25, 2026
111ca11
fix(identity): preserve global owner lifetimes and deadlines
cemililik Oct 25, 2026
1c3fb96
docs(decisions): propose ordered membership admission timing
cemililik Oct 25, 2026
c4569ad
fix(identity): keep the global creation port countable
cemililik Oct 25, 2026
dce6cad
docs(decisions): accept ordered membership admission checks
cemililik Oct 25, 2026
0495f2b
feat(identity): add scoped membership and owned seed foundation
cemililik Oct 26, 2026
9c9ec4a
docs(identity): reconcile contextual proof inventory
cemililik Oct 26, 2026
f814d97
fix(identity): confine value-bearing storage diagnostics
cemililik Oct 26, 2026
67d75e6
fix(identity): confine exported storage failure descriptions
cemililik Oct 26, 2026
7d29843
docs(roadmap): close contextual identity foundation reviews
cemililik Oct 26, 2026
5f7a062
feat(identity): normalize existing bindings before tenant admission
cemililik Oct 26, 2026
cb5937a
fix(identity): confine binding read failure diagnostics
cemililik Oct 26, 2026
83f701d
docs(roadmap): close existing identity binding admission reviews
cemililik Oct 26, 2026
6c379f1
test(identity): reconcile complete qualification inventories
cemililik Oct 26, 2026
124ff4a
chore(repo): reconcile merged main ancestry
cemililik Oct 26, 2026
3f1d4f6
docs(identity): reconcile remaining foundation carrier claims
cemililik Oct 26, 2026
4fc7e1a
fix(identity): close complete qualification findings
cemililik Oct 26, 2026
3754e4e
fix(identity): qualify the complete parent refusal stack
cemililik Oct 26, 2026
e05ba3a
fix(testing): isolate the BFF browser credential store
cemililik Oct 26, 2026
193d61c
ci(testing): refresh source-bound advisory method timings
cemililik Oct 26, 2026
d32f310
docs(roadmap): close P03-1 implementation qualification
cemililik Oct 26, 2026
413c9bd
fix(identity): close reviewed migration and lifecycle boundaries
cemililik Oct 26, 2026
2692314
fix(identity): confine read failures and reject empty authority input
cemililik Oct 26, 2026
492f3f6
fix(identity): refuse ambiguous migration credentials
cemililik Oct 26, 2026
c14ec6a
fix(ci): include contextual read proofs in fixture census
cemililik Oct 26, 2026
dfdf9ca
fix(ci): refresh measured identity test timing weights
cemililik Oct 26, 2026
7aabc6d
fix(ci): isolate independent architecture mutation collections
cemililik Oct 26, 2026
2d2a6f9
docs(decisions): propose ordinary CI job window
cemililik Oct 26, 2026
e50e6d1
docs(decisions): close ordinary window proposal findings
cemililik Oct 26, 2026
b048412
docs(roadmap): record second ordinary window proposal review
cemililik Oct 26, 2026
d5ebab8
docs(decisions): clarify ordinary window review boundaries
cemililik Oct 26, 2026
9ba876f
docs(roadmap): record revised window proposal first review
cemililik Oct 26, 2026
c274fa6
docs(roadmap): record revised window proposal second review
cemililik Oct 26, 2026
2a1917c
docs(decisions): accept ordinary-only CI job window
cemililik Oct 26, 2026
7dc3f8b
docs(roadmap): record first CI window acceptance review
cemililik Oct 26, 2026
1d609d3
docs(roadmap): close CI window acceptance reviews
cemililik Oct 26, 2026
c2695f2
fix(ci): bind ordinary windows to verified producer identity
cemililik Oct 26, 2026
6bb91ed
docs(roadmap): record first ordinary budget code review
cemililik Oct 26, 2026
ea114d2
docs(roadmap): close ordinary budget reviews for qualification
cemililik Oct 26, 2026
0db4b42
docs(roadmap): record complete ordinary window hosted proof
cemililik Oct 26, 2026
146f743
docs(roadmap): record first hosted evidence review
cemililik Oct 26, 2026
468e9c6
docs(roadmap): distinguish hosted fixture subset evidence
cemililik Oct 26, 2026
58e5a1d
docs(roadmap): close ordinary CI window implementation
cemililik Oct 26, 2026
194992f
chore: sync merged identity foundation from main
cemililik Oct 27, 2026
daf03a4
docs(roadmap): close merged identity foundation packet
cemililik Oct 27, 2026
0389def
docs(decisions): propose live authorization and evidence contracts
cemililik Oct 27, 2026
7159c98
docs(decisions): clarify scoped delegation and evidence ownership
cemililik Oct 27, 2026
9f0edb6
docs: reconcile permission guidance with accepted foundation
cemililik Oct 27, 2026
b81ed06
docs(roadmap): record live authorization decision readiness
cemililik Oct 27, 2026
ead0a22
docs(decisions): close nested authorization and denial design gaps
cemililik Oct 27, 2026
55662b5
docs(roadmap): record revised authorization proposal review
cemililik Oct 27, 2026
725d255
docs(roadmap): close revised authorization decision review
cemililik Oct 27, 2026
e8266bb
docs: accept live authorization and trusted evidence contracts
cemililik Oct 27, 2026
c700084
docs: reconcile authorization setup and workflow guidance
cemililik Oct 27, 2026
5ee659b
docs(roadmap): close authorization acceptance reviews
cemililik Oct 27, 2026
8ec7ee1
feat(identity): add confined live authorization readers
cemililik Oct 27, 2026
7a7bb30
fix(identity): close confined authorization review findings
cemililik Oct 27, 2026
cf9454e
docs(roadmap): close confined authorization reader reviews
cemililik Oct 27, 2026
a15716d
feat(identity): enforce staged scoped operation policies
cemililik Oct 27, 2026
489746d
fix(identity): preserve sensitive read audit failure semantics
cemililik Oct 27, 2026
c1a61dd
docs(roadmap): close scoped execution reviews
cemililik Oct 27, 2026
6780597
feat(identity): retain trusted authorization evidence
cemililik Oct 27, 2026
16667e7
fix(identity): freeze refusals before transaction cleanup
cemililik Oct 27, 2026
56f9554
fix(identity): preserve admitted refusal observations
cemililik Oct 27, 2026
02bce2a
feat(identity): activate live scoped HTTP authorization
cemililik Oct 27, 2026
effc9c5
fix(identity): qualify live database lanes at startup
cemililik Oct 27, 2026
070aa67
docs(roadmap): close live authorization activation reviews
cemililik Oct 27, 2026
2e00aba
test(identity): complete live authorization proof populations
cemililik Oct 27, 2026
309e6d2
fix(identity): preserve explicit admission and completed evidence
cemililik Oct 27, 2026
f3b8d76
fix(identity): preserve public refusals and qualify fixture startup
cemililik Oct 27, 2026
696671b
ci(testing): freeze reviewed live authorization timing observations
cemililik Oct 27, 2026
84abac5
fix(kernel): close failed read owners and retain start diagnostics
cemililik Oct 27, 2026
f34849d
test(kernel): rebalance architecture from hosted timing evidence
cemililik Oct 27, 2026
72d76f2
style(kernel): retain stable ordering in the timing plan
cemililik Oct 27, 2026
6d1a43b
perf(kernel): reuse scoped census instruction indexes
cemililik Oct 27, 2026
c3adebe
docs(roadmap): record census performance review and controls
cemililik Oct 27, 2026
33142a8
docs(roadmap): freeze reviewed census performance correction
cemililik Oct 27, 2026
23262e9
refactor(kernel): separate independent job authority proof families
cemililik Oct 27, 2026
3ccdfc4
test(kernel): bind decomposed proof weights to clean receipts
cemililik Oct 27, 2026
05a5463
docs(roadmap): freeze reviewed whole-authority proof population
cemililik Oct 27, 2026
c1f1d4c
perf(kernel): bound repeated resolution subtype expansion
cemililik Oct 27, 2026
ad7cb5e
docs(roadmap): record resolution correction review and discovery
cemililik Oct 27, 2026
8241433
docs(roadmap): freeze reviewed resolution correction source
cemililik Oct 27, 2026
09ac7c8
fix(kernel): retain bounded provider startup diagnostics
cemililik Oct 28, 2026
01d8234
docs(roadmap): record startup diagnostic review evidence
cemililik Oct 28, 2026
9385c9e
docs(roadmap): freeze reviewed startup diagnostic source
cemililik Oct 28, 2026
7dbf68f
fix(web): wait for complete owned browser port publication
cemililik Oct 28, 2026
8a43eb9
docs(roadmap): record browser readiness review and clean replay
cemililik Oct 28, 2026
6ea5e67
fix(kernel): pace recovery settlement after proven renewals
cemililik Oct 28, 2026
16614b3
docs(roadmap): record recovery scheduling lifetime review
cemililik Oct 28, 2026
07a0431
docs(roadmap): freeze reviewed browser and recovery corrections
cemililik Oct 28, 2026
fb7a892
test(docs): admit the zero-adopted standard census
cemililik Oct 28, 2026
bf79404
docs(roadmap): record the zero census first review
cemililik Oct 28, 2026
c39ab61
docs(roadmap): freeze the reviewed final corpus source
cemililik Oct 28, 2026
6c6747e
docs(identity): close qualified authorization delivery carriers
cemililik Oct 28, 2026
c37c3df
docs(roadmap): record final authorization handoff reviews
cemililik Oct 28, 2026
74254c8
fix(tooling): reject incomplete auxiliary sources before setup
cemililik Oct 28, 2026
39c98e4
docs(roadmap): record PR 39 correction validation
cemililik Oct 28, 2026
6cf8c71
test(tooling): complete isolated API launcher dependencies
cemililik Oct 28, 2026
6ed0f12
test(identity): acknowledge the exact role-catalog blocker
cemililik Oct 28, 2026
ca82e24
docs(roadmap): record cancellation control proof and review
cemililik Oct 28, 2026
4406c1d
docs(roadmap): close cancellation control review rounds
cemililik Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
61 changes: 34 additions & 27 deletions .claude/skills/add-mediatr-handler/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,32 +257,33 @@ See [add-audit-coverage](../add-audit-coverage/SKILL.md).

### Step 5: Permission policy

> **Not wired yet.** No `IPermissionRegistry`, `registry.Tenant(...)` or `Roles`
> catalogue exists in `backend/src`, `LearnStack.Api` registers no authorization
> middleware, and `AuthorizationBehavior` passes every request through; the catalogue
> lands with the Identity module in
> [Phase 03](../../../docs/roadmap/phase-03-identity-admin.md). Until then this step's
> registration, Step 7's `[Authorize(Policy = …)]` and the `403` check under
> § Validation have nothing to bind to. A module's `permissions.md` is a forward
> declaration, a handler with no HTTP route stands on reachability, as
> [the Tenancy permission matrix](../../../docs/modules/tenancy/permissions.md)
> records, and an anonymous endpoint carries `[AllowAnonymous]` with its reason
> ([Permissions Standards § HTTP endpoints](../../../docs/standards/19-permissions.md#http-endpoints)).

The endpoint that invokes this handler is guarded by
`[Authorize(Policy = "enrollment.enrollment.write")]`. Register the permission in
the module:

```csharp
registry.Tenant(
key: "enrollment.enrollment.write",
description: "Create or update enrollments",
defaultGrants: [Roles.TenantAdmin, Roles.OrgAdmin]);
```

`Roles.*` references come from the **Built-in Roles** catalogue authoritative
at [19-permissions.md § Built-in Roles](../../../docs/standards/19-permissions.md).
Do not invent role names; pick from that table or extend it via PR.
Declare the exact request through the module's `IOperationPolicySource`, using
the existing scoped `PermissionDefinition` and the admitted `OperationPolicy`.
`OperationPolicyCatalog` freezes those declarations independently of stored Role
grants. Registration grants nothing and seed reruns never adopt new permissions.
There is no `registry.Tenant`, generated `Roles` facade or implicit default grant.

The canonical `AuthorizationBehavior` delegates to the scoped operation
coordinator at step 5, with its mandatory denial-evidence barrier. The unchanged
eight-step pipeline registers that owner and its frozen catalogue directly;
there is no staged replacement behavior. Unknown application requests default
deny before handler construction. Public, AccountSite and finite seed/event/job
classifications have different ceilings; none grants an implicit general
exception, and a SystemActor UUID supplies no bypass. Protected application
dispatch performs a fresh permission check independently of any earlier HTTP or
resolver result. The [phase Status block](../../../docs/roadmap/phase-03-identity-admin.md)
owns qualification and review state; registration or an attribute alone proves
no HTTP coverage.

Tests of authorization must use the canonical registered behavior and actual
source owner for their subject. Do not replace its DI descriptor, restore a
pass-through adapter or treat a test-only policy as a production permission.

When an HTTP operation is admitted, bind its exact application request metadata
and the named ASP.NET requirement generated from that canonical policy. Preserve
the [four-step authorization order](../../../docs/standards/11-security.md#live-authorization-contract)
and prove unknown/missing/conflicting declarations deny. Keep initial templates
and explicit grant adoption separate from definition composition.

See [add-permission](../add-permission/SKILL.md).

Expand Down Expand Up @@ -311,7 +312,8 @@ Endpoint controllers are thin:
public sealed class EnrollmentsController(ISender mediator) : ApiControllerBase
{
[HttpPost]
[Authorize(Policy = "enrollment.enrollment.write")]
[Authorize(Policy = "LearnStackOperation:enrollment.enrollment.create")]
[OperationPolicy(typeof(CreateEnrollmentCommand))]
public async Task<IActionResult> Create(
[FromBody] CreateEnrollmentRequest body, CancellationToken ct)
{
Expand All @@ -321,6 +323,11 @@ public sealed class EnrollmentsController(ISender mediator) : ApiControllerBase
}
```

This illustrates an already admitted operation whose module source uses policy
id `enrollment.enrollment.create`; it does not register that policy or license a
new endpoint. Use the current API classifier/requirement mapping and its exact
source census, rather than copying a policy string without its source.

## Validation

- `dotnet build` and `dotnet test` pass.
Expand Down
151 changes: 68 additions & 83 deletions .claude/skills/add-permission/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: add-permission
description: >
Register a new permission key in a module — closed action set
(`read | write | delete | admin`), explicit scope (Platform / Tenant /
Organization), default role grants, matrix entry, and `[Authorize(Policy = …)]`
Organization), finite grant manifests, matrix entry, and `[Authorize(Policy = …)]`
on the relevant endpoint. USE FOR: adding a permission for a new resource,
splitting an existing resource into separate read/write capabilities, or
promoting a "platform admin only" gate into a tenant-scoped permission. DO NOT
Expand All @@ -16,16 +16,21 @@ description: >

## Purpose

Add a permission to the module's
[IPermissionRegistry](../../../docs/standards/19-permissions.md) using the closed
naming convention, register it on the right endpoint, and update the per-module
permission matrix.

> **Not wired yet.** `IPermissionRegistry`, `IModule.RegisterPermissions` and the
> `Roles` catalogue land with the Identity module in
> [Phase 03](../../../docs/roadmap/phase-03-identity-admin.md); none exists in
> `backend/src`. Until then only Step 1 and Step 5 apply, as a forward declaration on
> [the Tenancy precedent](../../../docs/modules/tenancy/permissions.md).
Add an explicitly scoped definition through the module-owned source described in
[Permissions Standards](../../../docs/standards/19-permissions.md), bind the
admitted operation and update its matrix. Registration grants no Role authority.

> **Current implementation boundary.** P03-1 supplies `PermissionDefinition` and
> the retained `IdentityFoundationManifest.Version1` with actual seed consumers.
> Jointly Accepted ADR-0076/0077 select the
> [live contract](../../../docs/standards/19-permissions.md#live-permission-enforcement-contract);
> live policy/evaluator and grant-edit/adoption commands are implemented. The
> [Phase 03 Status block](../../../docs/roadmap/phase-03-identity-admin.md) owns
> current qualification and review state; the
> [phase decision register](../../../docs/roadmap/phase-03-identity-admin.md#the-decision-register)
> owns gate state. No `IModule` registration API or generated Roles facade is
> implied. Read the current source and accepted operation contract before coding;
> do not introduce a module loader to match an illustrative sketch.

## When to use

Expand All @@ -50,7 +55,7 @@ permission matrix.
| Permission key | Yes | Dotted `{module}.{resource}.{action}`, snake_case multi-word resources. |
| Scope | Yes | `Platform` / `Tenant` / `Organization`. |
| Description | Yes | One short sentence shown in Studio's role editor. |
| Default role grants | Yes | Which built-in roles get this on tenant provisioning. |
| Initial/adopted grant manifest | Yes | Explicit finite version; registration and seed reruns grant nothing to existing Roles. |

## Workflow

Expand Down Expand Up @@ -83,56 +88,40 @@ Rules:

### Step 2: Register in the module

In `<Module>.Application/<Module>Module.cs`:
Declare `(PermissionScope, PermissionKey)` through the admitted module definition
source. The current value-type shape is:

```csharp
public void RegisterPermissions(IPermissionRegistry registry)
{
registry.Tenant(
key: "enrollment.course_access.read",
description: "View entitlements",
defaultGrants: [Roles.TenantAdmin, Roles.OrgAdmin, Roles.Instructor]);

registry.Tenant(
key: "enrollment.course_access.write",
description: "Grant or revoke entitlements",
defaultGrants: [Roles.TenantAdmin]);

registry.Organization(
key: "enrollment.enrollment.write",
description: "Create or update enrollments (org-scoped)",
defaultGrants: [Roles.OrgAdmin, Roles.OrgInstructor]);
}
new PermissionDefinition(PermissionScope.Organization, "enrollment.enrollment.write");
```

`registry.Tenant(...)` / `registry.Organization(...)` / `registry.Platform(...)`
declare scope explicitly; the three registries are disjoint, asserted at seed.
This example registers nothing by itself. The same key at Tenant and Organization
scope is two distinct definitions; Platform definitions cannot enter tenant Role
grants. Unknown/inactive pairs authorize nothing.

`Roles.*` references come from the **Built-in Roles** catalogue authoritative
at [19-permissions.md § Built-in Roles](../../../docs/standards/19-permissions.md)
(`TenantAdmin`, `Instructor`, `Learner`, `Guardian`, `Editor`, `OrgAdmin`,
`OrgInstructor`, `PortalPublic`, `HubOperator`, `PlatformAdmin`). Do not invent
role names; pick from that table or extend it via PR + standard update.
Pick the template/capability from the canonical
[Built-in Roles](../../../docs/standards/19-permissions.md#built-in-roles).
Keep definition composition separate from finite initial grants and explicit
adoption. Never extend retained v1 seed grants or the immutable admin kernel by
editing a registration's defaults. A new assignable pair also needs the actual
database registry guard/migration and approved grant contract before its writer.

### Step 3: Apply to the endpoint

```csharp
[ApiController]
[Route("enrollments")] // the versioned prefix is the convention's, not yours
public sealed class EnrollmentsController : ControllerBase
{
[HttpGet]
[Authorize(Policy = "enrollment.enrollment.read")]
public Task<IActionResult> List(...) => ...;

[HttpPost]
[Authorize(Policy = "enrollment.enrollment.write")]
public Task<IActionResult> Create(...) => ...;
}
```
Bind the endpoint to the admitted named ASP.NET policy and exact application
request policy from the actual composition source. Scoped pair identity is
explicit: a same-key Tenant/Organization pair is not one permission. Do not
infer a functioning evaluator from an attribute; use the registered evaluator
and policy APIs. Unknown, missing or conflicting classifications deny
at runtime. Application step 5 repeats the policy on direct/nested dispatch.

Public and special AccountSite classifications retain their independent
HostScope/physical mode boundaries. Platform and additional human-facing
operations remain gated by their owning phase; this workflow grants no route.

The 4-step auth order ([11-security.md § Authorization](../../../docs/standards/11-security.md))
runs automatically:
The admitted surface must prove the 4-step auth order
([11-security.md § Authorization](../../../docs/standards/11-security.md));
an attribute alone does not install it:

1. Authentication (valid JWT).
2. Tenant membership (Membership exists in resolved tenant).
Expand All @@ -141,23 +130,15 @@ runs automatically:

### Step 4: Resource scope (when needed)

For "instructor edits only own courses", add an authorization handler:

```csharp
public sealed class CourseOwnedByActorHandler
: IAuthorizationHandler<CourseOwnedByActorRequirement, Course>
{
public Task HandleAsync(AuthorizationHandlerContext ctx, ...)
{
if (resource.OwnerId == ctx.Actor.UserId) ctx.Succeed();
return Task.CompletedTask;
}
}
```
Use the admitted application-layer resource policy after capability admission
and visible-scope lookup. A missing or foreign-scope resource is masked 404; a
visible resource failing ownership is 403. The application policy consumes the
trusted actor and exact resource facts; module code acquires no ASP.NET types.

The application-layer policy class combines with the permission key:
permission grants the **capability** (`education.course.write`), policy decides
**on which rows** (own course only).
[Security's live policy contract](../../../docs/standards/11-security.md#live-authorization-contract)
owns this ordering. Declared tenant-wide reads use the immutable
[operation witness](../../../docs/standards/05-database.md#operation-bound-read-authority),
never a header/body Boolean, Role name or cleared organization write scope.

### Step 5: Update the matrix

Expand All @@ -167,8 +148,8 @@ Open `docs/modules/<module>/permissions.md`. Add a row:
| Entitlement | ✓ | ✓ | – | – | tenant-admin: read+write; instructor: read |
```

Legend: ✓ = exists, – = N/A. The "Default role grants" column summarises
`defaultGrants` from the registration call.
Legend: ✓ = exists, – = N/A. The "Default role grants" column names the approved
finite initial manifest; it does not promise automatic grants on upgrade/rerun.

### Step 6: Tests

Expand All @@ -189,22 +170,27 @@ Plus, for org-scoped permissions, a cross-org test:

```csharp
[Fact]
public async Task Cross_org_actor_within_same_tenant_is_403() { ... }
public async Task Cross_org_actor_is_refused_without_disclosure() { ... }
```

Architecture test `Permission_Registry_Has_DeniedTest` ensures every registered
key has at least one denied test.
Use the admitted surface's masking/denial contract for exact status assertions;
foreign resource scope and a visible ownership denial are different controls.
The canonical obligation `Permission_Registry_Has_DeniedTest` requires actual
denied coverage; verify its current catalogue status and nonempty subjects.

## Validation

- `dotnet build` and `dotnet test` pass.
- The permission is visible in `IPermissionRegistry` (assert via a one-off
startup-test).
- The exact scoped pair is in the admitted composition source; a missing or
inactive definition denies, and registry additions do not mutate stored grants.
- The endpoint rejects unauthenticated, wrong-tenant, and wrong-permission callers
with the right status codes.
- The permission appears in `docs/modules/<module>/permissions.md`.
- The architecture tests `Permission_Keys_Match_Convention` and
`Permission_Scope_Matches_Resource_Scope` are green.
- Check `Permission_Keys_Match_Convention`,
`Permission_Scope_Matches_Resource_Scope` and
`Permission_Registry_Has_DeniedTest` against their current catalogue status.
Their P03-2 controls are Registered at acceptance; run the actual implemented
owners before claiming green, and never promote an absent proof.

## Common pitfalls

Expand All @@ -213,13 +199,12 @@ key has at least one denied test.
- **Skipping scope.** A `Tenant`-scope permission checked against an
`[OrganizationScoped]` resource without an org test is a bug; the matching
architecture test catches it.
- **Hard-coding the key string in policy code.** Use the generated catalogue
(`Permissions.Education.Course.Write`); typos in raw strings silently pass at
compile time.
- **Duplicating key strings.** Reuse the owning compiled definition/constants;
do not invent a generated catalogue that is not present in the source.
- **Frontend-only check.** Hidden buttons are not security. Every UI permission
check has a server-side counterpart.
- **Storing the permission in Keycloak.** Keycloak handles authentication, not
LearnStack authorization. Permissions live in `IPermissionRegistry` only.
- **Storing the permission in Keycloak.** Keycloak handles authentication;
LearnStack's admitted definition/Role contracts own application authorization.
- **Renaming an existing key.** A rename without a deprecation window
invalidates every role assignment in the wild. Renaming is a deprecation cycle
(one release with the old key warning-logged), not an in-place edit.
34 changes: 31 additions & 3 deletions .claude/skills/local-dev-setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,49 @@ installed deployment authority, following
[Identity deployment](../../../docs/modules/identity/README.md#global-implementation-and-deployment).
Authority qualification is mandatory before the API accepts requests.
The dispatcher credential belongs only to the API; every Seeder invocation uses
an explicit application-only environment, and the web launcher receives neither
an explicit application-role runtime environment, and the web launcher receives no
database credential. Both empty hop lists remain
valid in every mode; a network-only or secret-only configuration is refused.
The application connection must name `learnstack_app`; the data-source guard also
refuses direct or transitive BYPASSRLS/superuser access. Migration credentials
never enter either application launch recipe.

**P03-2 source configuration.** The confined authorization/
evidence sources use the same application role, not new credentials or roles.
[Standard 05's source ledger](../../../docs/standards/05-database.md#authorization-and-evidence-source-ledger)
owns the coupled backend configuration pair, Development-only direct-PostgreSQL
derivation and explicit non-Development requirement;
[Standard 12](../../../docs/standards/12-infrastructure.md#authorization-and-evidence-topology)
owns operational topology. Startup qualifies the installed authority and actual
database identity before admitting source use. Owned seed/demo runtime children
receive the selected authority and connection pair, with the existing
`Deployment__Mode=Development` for their direct local stack; their restore/build
and manifest children receive no runtime authority or database credentials.
The Seeder shares one process-owned evidence source across per-act providers.
Direct CLI use must supply the authority pair and explicit auxiliary pair unless
explicit Development permits supported direct-PostgreSQL derivation; the tool
does not load `.env`. Follow [seed-tenant](../seed-tenant/SKILL.md) for its exact
startup contract. Do not expose these values to the web, silently accept a
partial pair, or mistake extra client pools for PgBouncer backend reservation.
The local API configuration loader selects a complete explicit process
authorization/evidence pair atomically over the selected root-file pair.
When both process keys are absent, the root-file pair is used. Partial, empty or
whitespace process values refuse before the API child starts; sources never fill
one another's missing partner. The constructed runtime preserves selected strings
exactly and imports neither partner from its ambient prerequisite environment.
The owned demo separately retains its selected-stack conflict check: explicit
process values cannot disagree with values present in its selected private file.
The phase Status block owns current qualification and review state.

**`make migrate` runs as `learnstack_migration`, not as the API's role.** From
Phase 02a Packet 6 the stack provisions four database roles on the first boot of
a fresh `postgres-data` volume
([ADR-0003 Amendment 3](../../../docs/decisions/0003-tenant-isolation-defense-in-depth.md)):
`learnstack_migration` owns every table, `learnstack_app` is what the API
connects as, and `learnstack_platform` / `learnstack_outbox_admin` hold audited
bypasses. Four roles, four passwords, four connection strings — all in
`.env.example`, and none of them interchangeable. Running migrations as the
bypasses. The four roles/passwords and baseline connection strings are in
`.env.example`, and their privileges are not interchangeable. The accepted
P03-2 application-role sources do not expand this role set. Running migrations as the
runtime role would make it the table owner, which is the arrangement
`FORCE ROW LEVEL SECURITY` exists to defeat.

Expand Down
Loading
Loading