Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
543 commits
Select commit Hold shift + click to select a range
1261c38
docs(roadmap): close quota correction reviews for qualification
cemililik Oct 19, 2026
e95d67e
docs(roadmap): close merged P02b-4 and name the next packet
cemililik Oct 19, 2026
0e23cb1
chore: sync merged P02b-4 into development
cemililik Oct 19, 2026
5bfe3c3
docs(decisions): propose the P02b-5 authentication boundary
cemililik Oct 19, 2026
c94abe1
docs(roadmap): record P02b-5 decision reviews
cemililik Oct 19, 2026
5e8539c
docs(decisions): resolve tenant authentication review gaps
cemililik Oct 19, 2026
9ff8c8a
docs(roadmap): record first authentication revision reviews
cemililik Oct 19, 2026
945f7ba
docs(roadmap): close authentication proposal revision reviews
cemililik Oct 19, 2026
493d7f9
docs(decisions): accept the tenant authentication boundary
cemililik Oct 19, 2026
6526362
feat(kernel): add the isolated tenant token foundation
cemililik Oct 19, 2026
c6108bf
fix(kernel): keep metadata hosts out of native HTTP metrics
cemililik Oct 19, 2026
e67c329
docs(roadmap): close both token foundation review rounds
cemililik Oct 19, 2026
a736edb
feat(tenancy): add the host-bounded read-only account query
cemililik Oct 19, 2026
e36d47c
docs(tenancy): record account query review and implementation
cemililik Oct 19, 2026
8f9ecff
docs(roadmap): close both account query review rounds
cemililik Oct 19, 2026
c090970
feat(kernel): attribute tenant refusals and add subject admission
cemililik Oct 19, 2026
90724a5
docs(roadmap): record the first admission review round
cemililik Oct 19, 2026
40fe1ee
fix(kernel): export actor UUIDs at rejection log boundaries
cemililik Oct 19, 2026
6686d01
docs(roadmap): wrap the admission closeout pointer
cemililik Oct 19, 2026
0be26ab
feat(api): activate the closed tenant authentication boundary
cemililik Oct 19, 2026
746c0cd
fix(api): document the early request body refusal
cemililik Oct 19, 2026
a7c9d5a
docs(roadmap): close both HTTP activation review rounds
cemililik Oct 19, 2026
d463952
test(kernel): enforce closed tenant authentication authority
cemililik Oct 19, 2026
1942662
fix(kernel): close alternate authentication authority paths
cemililik Oct 19, 2026
e20b607
fix(kernel): close identity exports and inherited role metadata
cemililik Oct 19, 2026
b79acc8
docs(roadmap): close tenant API implementation and reviews
cemililik Oct 19, 2026
5676c75
docs(roadmap): link tenant authentication review handoff
cemililik Oct 19, 2026
afa8481
docs(decisions): fix punctuation in ADR index summaries
coderabbitai[bot] Oct 19, 2026
d335f2b
docs(decisions): accept bounded tenant assertion diagnostics
cemililik Oct 19, 2026
8a3892d
fix(kernel): close tenant authentication review gaps
cemililik Oct 19, 2026
ac82ca6
docs(roadmap): record authentication review corrections
cemililik Oct 19, 2026
f5befc9
fix(ci): retain closed public demo failure phases
cemililik Oct 19, 2026
ce2b746
fix(ci): recognize signalled browser startup exits
cemililik Oct 19, 2026
d9f21dd
fix(ci): accept native child status in diagnostic types
cemililik Oct 19, 2026
9aad55b
docs(roadmap): record hosted authentication qualification
cemililik Oct 19, 2026
9d4ec0e
docs(standards): Mark ADR-0065 diagnostic controls as implemented
coderabbitai[bot] Oct 20, 2026
15c2f49
fix(auth): close review privacy and proof gaps
cemililik Oct 20, 2026
653404a
fix(tests): close cross-assembly and middleware proof gaps
cemililik Oct 20, 2026
8f2ebb9
fix(tests): reject hidden fluent middleware registrations
cemililik Oct 20, 2026
09e1a16
docs(roadmap): record verified second review corrections
cemililik Oct 20, 2026
ed21d9f
docs(decisions): clarify subject admission fault ownership
cemililik Oct 20, 2026
4b4a9ac
docs(decisions): complete admission retry contract inventory
cemililik Oct 20, 2026
453d5c3
docs(roadmap): record subject admission revision reviews
cemililik Oct 20, 2026
c8b9d89
docs(decisions): accept bounded subject admission contract
cemililik Oct 20, 2026
0179955
feat(auth): own bounded subject admission cleanup
cemililik Oct 20, 2026
082a658
fix(auth): preserve no-store on every subject refusal
cemililik Oct 20, 2026
5daee8a
docs(roadmap): close subject admission implementation reviews
cemililik Oct 20, 2026
57f49ce
fix(auth): close HTTP boundary proofs and receipt chronology
cemililik Oct 20, 2026
6380fcc
test(auth): close provider and anonymous metadata escape paths
cemililik Oct 20, 2026
09dcb11
test(auth): pin effective action filters and authorization metadata
cemililik Oct 20, 2026
09fdf8a
docs(roadmap): close backend correction review rounds
cemililik Oct 20, 2026
8f433a7
fix(web): bind demo receipts and preserve failure ownership
cemililik Oct 20, 2026
9d08070
fix(web): retain the first owned demo failure
cemililik Oct 20, 2026
9b6794d
fix(web): observe failing native exits before output closure
cemililik Oct 20, 2026
49c2c43
fix(web): publish every unexpected daemon exit
cemililik Oct 20, 2026
00a7877
docs(roadmap): close systematic correction review rounds
cemililik Oct 20, 2026
9014ec6
fix(ci): refresh architecture weights from complete hosted receipts
cemililik Oct 20, 2026
b3abbce
docs(roadmap): close measured timing correction reviews
cemililik Oct 20, 2026
dbb2e9f
fix(ci): require identified hosted timing sources
cemililik Oct 20, 2026
419e456
docs(roadmap): close provenance guard reviews
cemililik Oct 20, 2026
b494570
docs(roadmap): close P02b-5 after PR 33 merge
cemililik Oct 20, 2026
6d75e53
docs(roadmap): propose P02b-6 realm and seed decision package
cemililik Oct 20, 2026
285db56
docs(roadmap): accept P02b-6 realm and seed decisions
cemililik Oct 20, 2026
8bd0990
feat(identity): declare executable development realm identities
cemililik Oct 20, 2026
0b6ce0a
fix(identity): close realm and vocabulary review gaps
cemililik Oct 20, 2026
95d0a0c
fix(identity): qualify client-role claim interpolation
cemililik Oct 20, 2026
8011c00
docs(roadmap): propose bounded server information read
cemililik Oct 20, 2026
ff8a8f1
feat(identity): bound development realm transport and ownership
cemililik Oct 20, 2026
fbd9e7d
docs(roadmap): compare authenticated version probe alternatives
cemililik Oct 20, 2026
7c66885
docs(roadmap): accept fixed server information response allowance
cemililik Oct 20, 2026
a261905
fix(identity): confine server information response allowance
cemililik Oct 20, 2026
3776947
feat(identity): reconcile owned development realm state safely
cemililik Oct 20, 2026
29735c7
fix(identity): qualify stored identity visibility before reconciliation
cemililik Oct 21, 2026
b94f6a2
fix(identity): qualify inherited claims and preserve projected users
cemililik Oct 21, 2026
2ef1e14
docs(roadmap): close realm review and qualify account self-service
cemililik Oct 21, 2026
ce05931
feat(identity): share realm convergence across seed and demo
cemililik Oct 21, 2026
9b51a0b
docs(roadmap): record first seed lifecycle review
cemililik Oct 21, 2026
29bb18d
fix(identity): confine seed preparation credentials
cemililik Oct 21, 2026
1f5cc04
fix(identity): keep readiness under one seed owner
cemililik Oct 21, 2026
1488814
test(identity): retain process absence witnesses in seed proofs
cemililik Oct 21, 2026
ea0363e
feat(identity): qualify realm self-service and real token admission
cemililik Oct 21, 2026
4a3173d
fix(ci): require executed realm cases alongside JUnit reports
cemililik Oct 21, 2026
1f0a8d0
fix(tests): classify the offline realm gate control source
cemililik Oct 21, 2026
bf9e689
docs(roadmap): close P02b-6 implementation and review steps
cemililik Oct 21, 2026
204a103
docs(roadmap): identify the live PR qualification owner
cemililik Oct 21, 2026
e0f9798
fix(identity): preserve setup prerequisites and failure cleanup
cemililik Oct 21, 2026
eb707ee
docs(roadmap): record verified PR identity corrections
cemililik Oct 21, 2026
d2d9b28
fix(identity): reject false convergence and close proof gaps
cemililik Oct 21, 2026
d8139de
style: align correction whitespace
cemililik Oct 21, 2026
837d9d5
fix(identity): validate first reads and complete fixture census
cemililik Oct 21, 2026
f09b16d
fix(identity): bind Docker preflight to the selected environment
cemililik Oct 21, 2026
0c9d287
docs(roadmap): close independent correction reviews
cemililik Oct 21, 2026
5fbbf09
fix(identity): keep seed authority generic and retain startup faults
cemililik Oct 21, 2026
6109268
docs(roadmap): record startup diagnosis correction reviews
cemililik Oct 21, 2026
57ff585
test(identity): distinguish bounded provider startup failure families
cemililik Oct 21, 2026
dc25ebb
test(identity): isolate pure startup diagnostics from fixture ownership
cemililik Oct 21, 2026
fddfc26
docs(roadmap): close provider classification correction reviews
cemililik Oct 21, 2026
9bbf2a3
fix(ci): retain closed Docker startup failure families
cemililik Oct 21, 2026
fb4ab5e
fix(ci): contain malformed diagnostic Unicode
cemililik Oct 21, 2026
4467492
docs(roadmap): record daemon diagnosis correction reviews
cemililik Oct 21, 2026
1bf18b8
fix(testing): align fixture publishers and browser readiness
cemililik Oct 21, 2026
faa8c2b
docs(roadmap): record publication correction first reviews
cemililik Oct 21, 2026
abd4561
docs(roadmap): complete publication correction reviews
cemililik Oct 21, 2026
47069be
fix(identity): clarify private setup and realm proof failures
cemililik Oct 21, 2026
d246754
docs(testing): preserve provider-only fixture boundaries
cemililik Oct 21, 2026
61924f0
docs(roadmap): complete setup correction reviews
cemililik Oct 21, 2026
d0528d1
fix(identity): prove coupled development token expiration
cemililik Oct 21, 2026
7bb9a3e
docs(roadmap): record first issuance correction review
cemililik Oct 21, 2026
c33e529
docs(roadmap): complete issuance correction reviews
cemililik Oct 21, 2026
03ebd77
docs(identity): accept development issuance decision
cemililik Oct 21, 2026
9461801
docs(roadmap): record first issuance acceptance review
cemililik Oct 21, 2026
330a8e2
docs(roadmap): complete issuance acceptance reviews
cemililik Oct 21, 2026
4cb6946
fix(ci): retain closed causal restart failure locations
cemililik Oct 21, 2026
e7a5bf0
docs(roadmap): record closed diagnostic correction review
cemililik Oct 21, 2026
57772a2
docs(roadmap): complete closed diagnostic correction reviews
cemililik Oct 21, 2026
7e8c54f
fix(tooling): preserve safe development lifecycle operations
cemililik Oct 21, 2026
dbc8e02
test(identity): strengthen convergence and CI gate counterexamples
cemililik Oct 21, 2026
3d1bd0e
docs(decisions): propose development identity visibility preparation
cemililik Oct 21, 2026
2ef9cf9
docs(identity): bound historical realm upgrade qualification
cemililik Oct 21, 2026
55ff0fe
test(tooling): declare isolated child test environments
cemililik Oct 21, 2026
8e914a8
docs(roadmap): record final correction and proposal reviews
cemililik Oct 21, 2026
25de7a6
fix(identity): resolve assigned console scopes by bound ID
cemililik Oct 21, 2026
2c06b4a
docs(decisions): qualify preparation authority and console evidence
cemililik Oct 21, 2026
d3e69b7
fix(ci): retain closed native settlement failure locations
cemililik Oct 21, 2026
02b886f
docs(roadmap): record revised decision inspection and failure limits
cemililik Oct 21, 2026
db3778c
docs(decisions): accept bounded warm-realm qualification
cemililik Oct 21, 2026
57497f0
feat(identity): qualify stock console assignment normalization
cemililik Oct 21, 2026
72ee83a
test(identity): cover every interrupted console assignment
cemililik Oct 21, 2026
52c73e6
docs(roadmap): close the first warm-realm correction step
cemililik Oct 21, 2026
8b99de3
feat(identity): prepare warm-realm identities before fresh planning
cemililik Oct 21, 2026
16771fc
fix(identity): qualify visible facts before warm-realm preparation
cemililik Oct 22, 2026
3810b07
docs(roadmap): record verified warm-preparation corrections
cemililik Oct 22, 2026
f714a5a
docs(roadmap): close reviewed warm-realm preparation step
cemililik Oct 22, 2026
ca3560d
test(identity): prove historical realm credentials and API
cemililik Oct 22, 2026
61e47ff
docs(roadmap): record warm qualification and Step 3 reviews
cemililik Oct 22, 2026
87ecc11
test(ci): bound ingress lookup and retain settlement facts
cemililik Oct 22, 2026
8ae35ec
docs(roadmap): record first CI correction review
cemililik Oct 22, 2026
7b0fd1b
docs(roadmap): close independent CI correction reviews
cemililik Oct 22, 2026
9adba27
test(jobs): attribute settlement loss to its execution
cemililik Oct 22, 2026
c9abc97
test(jobs): join issued settlement flights before cleanup
cemililik Oct 22, 2026
4e06ffa
docs(roadmap): close independent attribution reviews
cemililik Oct 22, 2026
55dfeae
test(jobs): preserve recurrence failure and cleanup observations
cemililik Oct 22, 2026
196a5b4
docs(roadmap): record recurrence diagnostic first reviews
cemililik Oct 22, 2026
dbfad06
docs(roadmap): close recurrence diagnostic review rounds
cemililik Oct 22, 2026
0dc962d
test(jobs): isolate settlement proofs from pre-ack renewal races
cemililik Oct 22, 2026
c971f4c
docs(roadmap): record first settlement scheduling reviews
cemililik Oct 22, 2026
c618414
test(jobs): arm settlement deadlines before publication holds
cemililik Oct 22, 2026
c1238ff
docs(roadmap): record independent deadline fix verification
cemililik Oct 22, 2026
2fdf31e
chore: reconcile merged main with development
cemililik Oct 22, 2026
e2a476c
fix(ci): audit links against immutable event commits
cemililik Oct 22, 2026
ecc9f92
docs(roadmap): record link audit correction review
cemililik Oct 22, 2026
b25c1c4
docs(roadmap): close link audit correction reviews
cemililik Oct 22, 2026
36adb3a
fix(ci): classify Markdown audit regression tooling
cemililik Oct 22, 2026
76ca3ad
docs(roadmap): record tooling census correction review
cemililik Oct 22, 2026
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
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .claude/skills/add-feature-gated-ui/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ to a `mailto:` on Self-Hosted). All of this lives in

## When not to use

- Authorisation (permission checks). Those use `auth().permissions.includes(...)`,
not feature flags.
- Authentication or authorization. The current app-local
`@/server/auth/auth` helper returns only a safe session projection, with no
permissions/roles. Phase 03 owns permission-aware UI, backed by API enforcement;
a feature flag never grants a permission.
- Greying-out a feature instead of hiding. Three UI patterns the project picked:
**hide** for missing features, **visualise** for limits, **block-then-link** for
exceeded hard limits.
Expand All @@ -48,6 +50,13 @@ to a `mailto:` on Self-Hosted). All of this lives in

## Workflow

The hook/package examples below describe the Phase 06 entitlement-aware UI
target, not exports in the current SDK. P02b-7 supplies session UI only; do not
invent entitlement hooks, a permissions array or SSE transport while adding a
session-protected page. Follow
[add-frontend-route](../add-frontend-route/SKILL.md#step-5-authentication--permission-gating)
for the implemented authentication boundary.

### Step 1: Feature gating with `useFeatureFlag`

```tsx
Expand Down
107 changes: 55 additions & 52 deletions .claude/skills/add-frontend-route/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ name: add-frontend-route
description: >
Add a Next.js App Router route under `frontend/apps/web/src/app/(public)/` /
`(studio)/` / `(portal)/` with the right route group, tenant + organization +
locale resolution, Server Component default, permission guards (for studio /
portal), and SDK-based data fetching. USE FOR: a new public page, Studio screen,
or learner / instructor portal screen. DO NOT USE FOR: thin BFF proxy endpoints
(those live in `app/api/`), routes for the operator portal (that's the separate
`operator-portal` app), or hand-rolled `fetch` to the backend (use the typed
SDK).
locale resolution, Server Component default, the owning phase's permission
guards, and admitted SDK-based data fetching. USE FOR: a new public page,
Studio screen, or learner / instructor portal screen. DO NOT USE FOR: native
BFF protocol changes or generic proxy endpoints, routes for the operator
portal (that's the separate `operator-portal` app), or hand-rolled `fetch` to
the backend (use the typed SDK).
---

# Adding a frontend route
Expand All @@ -26,7 +26,6 @@ SDK contract per
- A new public page (marketing / CMS-rendered).
- A new Studio screen for tenant admin / org admin.
- A new portal screen for learner / instructor.
- A new BFF route handler under `api/` (rare; mostly auth callbacks).

## When not to use

Expand All @@ -36,6 +35,8 @@ SDK contract per
`frontend/packages/config/eslint/index.cjs`).
- Routes that bypass tenant resolution — every authenticated route requires a
resolved tenant.
- Generic BFF proxies or a new authentication action. ADR-0070's auth protocol
belongs to its native response owner; `app/api` currently contains only healthz.

## Inputs

Expand All @@ -54,8 +55,8 @@ SDK contract per
| Group | Purpose | Auth | Default render |
|-------|---------|------|----------------|
| `(public)` | Tenant public site (marketing, catalog, blog). | Anonymous by default; auth optional. | Dynamic SSR, no-store per ADR-0053; see Step 8. |
| `(studio)` | Tenant admin Studio. | Tenant-admin or org-admin. Required at the edge. | SSR, no cache (always fresh). |
| `(portal)` | Learner / instructor portal. | Membership in the resolved tenant. | SSR shell + Client Component for interactivity. |
| `(studio)` | Current `/studio` account scaffold; future admin screens. | Native BFF session admission; permission-sensitive screens require Phase 03's real authorization. | SSR, no cache (always fresh). |
| `(portal)` | Current `/portal` account scaffold; future learner/instructor screens. | Native BFF session admission; the current projection proves no membership or permission. | SSR shell + Client Component for interactivity. |

### Step 2: Create the route folder

Expand All @@ -70,13 +71,15 @@ localized section names.
```
frontend/apps/web/src/app/
(studio)/
dashboard/
users/
page.tsx
loading.tsx
error.tsx
studio/page.tsx
(portal)/
portal/page.tsx
```

These exact paths are the current authenticated scaffold census. New screens
need their owning phase's admission/authorization decision and matching route
census controls; a route-group folder alone grants no access.

Use the `layout.tsx` already present in the route group; do not add a new layout
unless the screen genuinely needs one.

Expand Down Expand Up @@ -117,8 +120,10 @@ Rules:

- Default to Server Component. `"use client"` only when the screen needs hooks,
browser APIs, or third-party client-only libs.
- The SDK (`@learnstack/sdk/server`) is the **only** sanctioned way to call the
API. Hand-rolled `fetch('/v1/...')` is blocked by lint.
- Public pages use admitted resource loaders backed by `@learnstack/sdk/server`.
The exact authenticated AccountSite caller stays in the native BFF owner;
neither a page nor the SDK selects credentials, host or tenancy headers.
Hand-rolled `fetch('/v1/...')` is blocked by lint.
- Pass typed primitives across the RSC → Client boundary — no class instances, no
closures.

Expand Down Expand Up @@ -146,9 +151,11 @@ through bootstrap and the configured caller; Phase 11 owns participation/samplin
**ADR-0054 native/URL controls delivered — 2026-10-09.**
[The replacement contract](../../../docs/decisions/0054-bounded-public-renderer-admission.md)
requires native GET/HEAD admission on every HTTP callback path, including
middleware-exempt health/assets/scaffolds, with masked no-store refusal of other
methods and bodyless HEAD. Production upgrades close; development retains only
validated GET HMR. The [remediation record](../../../docs/roadmap/phase-02d-delivery-log.md#remediation-step-2--native-ingress-and-url-boundary)
middleware-exempt health/assets/scaffolds. ADR-0070 adds POST only on exact
`/api/auth/signin/keycloak`, `/api/auth/signout` and `/api/auth/extend`,
with their closed Origin/CSRF/body controls. Other methods retain masked
no-store refusal; HEAD remains bodyless. Production upgrades close; development
retains only validated GET HMR. The [remediation record](../../../docs/roadmap/phase-02d-delivery-log.md#remediation-step-2--native-ingress-and-url-boundary)
owns validation and both independent review rounds. Do not add
Server Actions/write routes or WebSocket consumers without an explicit owning
Phase 02b/Phase 06
Expand All @@ -159,33 +166,25 @@ accepted HTTPS port and local path select the destination.

### Step 5: Authentication + permission gating

Authentication below is the Phase 02b target, not current scaffold behavior.
Today's exact `/studio` and `/portal` roots pass only after public host bootstrap;
no sign-in/session helper is implemented. Phase 02b must explicitly admit its
login/callback namespace before adding authenticated routes.

For those future `(studio)` and `(portal)` routes:

- Unauthenticated requests redirect through the accepted BFF/Keycloak sign-in flow.
- A page-level permission check uses the future `auth()` helper:

```tsx
import { auth } from "@learnstack/auth/server"; // illustrative: no such package exists yet; Phase 02b's session work owns the real helper
import { redirect } from "next/navigation";

export default async function UsersPage() {
const session = await auth();
if (!session) redirect("/login");
if (!session.permissions.includes("identity.user.read")) {
redirect("/dashboard"); // or render a 403 UI
}
// ...
}
```

`auth()` reads from the HttpOnly cookie session set by the BFF; never touch tokens
in a Client Component. The frontend permission check is **mirror-only** — the API
is authoritative.
P02b-7 implements the optional native BFF under
[ADR-0070](../../../docs/decisions/0070-owned-tenant-bff-sessions.md).
Host bootstrap precedes cookie/provider work. Disabled mode refuses auth paths
with 404 and the exact `/studio` and `/portal` shells with 503. Enabled mode
redirects anonymous shell requests to `/api/auth/signin` with a closed local
return destination. Add no generic proxy or new auth action.

The app-local `auth()` is a passive safe projection lookup in the admitted native
request; it does not parse cookies, refresh or mutate idle state. Layout and page
consumers still check their own admission after awaits. Follow the actual
[`components/auth/shell.tsx`](../../../frontend/apps/web/src/components/auth/shell.tsx)
owner for those checks and the exact `/studio` or `/portal` return destination,
rather than constructing a second authentication path in a page.

Never touch tokens in a Client Component. The projection has no permissions or
roles. Phase 03 owns permission-based screens and their mirror-only UI checks;
the API remains authoritative. Current shells grant no authoring capability.
Use full document anchors, no-store responses and the protected history guard;
do not introduce prefetch/Router Cache reuse for protected navigation.

### Step 6: Feature gating (entitlement-aware UI)

Expand Down Expand Up @@ -222,7 +221,8 @@ export default async function CoursesPage() {
```

Messages live in `frontend/apps/web/src/i18n/messages/<locale>/<namespace>.json`;
P02d-6 supplies complete `en/public.json` and `tr/public.json`. General UI keys
P02d-6 supplies complete `en/public.json` and `tr/public.json`; P02b-7 supplies
`en/auth.json` and `tr/auth.json` through the same catalogue guard. General UI keys
are dotted feature identifiers, distinct from backend `lockey_*` wire keys. The
web app owns closed page-outcome mappings; the SDK supplies no translations.
See [add-i18n-key](../add-i18n-key/SKILL.md).
Expand All @@ -236,8 +236,8 @@ authority. Only whole-catalogue fallback is allowed for unauthored UI languages;
missing used keys in supported catalogues fail validation. Preserve exact content
locale, document language and actual resolved-label language.

The guarded frontend suite supplies ICU, argument and callsite checks. No
`lint:i18n` command or screenshot/axe tooling exists. The
The guarded frontend suite supplies ICU, argument and callsite checks; there is
no separate `lint:i18n` command. The full Playwright/axe suite belongs to Phase 06.
[Step 1 delivery record](../../../docs/roadmap/phase-02d-delivery-log.md#p02d-6-step-1-localization-and-document-foundation)
owns foundation validation; the
[packet closeout](../../../docs/roadmap/phase-02d-delivery-log.md#p02d-6-packet-closeout-2026-10-10)
Expand Down Expand Up @@ -330,8 +330,10 @@ records passing production replacement proofs, completed reviews and verified fi
which bans a direct `fetch` call outside the SDK.
- The route renders under the resolved tenant/org/locale and rejects mismatched
authn.
- A `(studio)` route returns 403 when the actor lacks the required permission;
the API was already authoritative — confirm.
- Current `/studio` and `/portal` follow the native enabled/disabled session
outcomes, with no authoring permission implied. Before adding a screen that
requires permission, Phase 03's API authorization must refuse unauthorized work;
a hidden button or successful session projection is insufficient.
- The public-route budgets in
[Performance Standards](../../../docs/standards/15-performance.md) hold on
representative routes — judged by reading until CI's `lighthouse budget` job is
Expand All @@ -340,7 +342,8 @@ records passing production replacement proofs, completed reviews and verified fi
## Common pitfalls

- **Mounting under the wrong route group.** Public institution routes are dynamic
and no-store under ADR-0053; Studio/Portal authentication remains Phase 02b.
and no-store under ADR-0053; exact Studio/Portal scaffolds use ADR-0070's native
BFF session admission. Future screens do not inherit permission from that shell.
- **Hand-rolled `fetch`.** Only the configured server adapter has an API transport
exemption. Page consumers call its SDK; no second header setter is permitted.
- **Reading `host` inside a page.** The API resolves authority. The native ingress
Expand Down
10 changes: 6 additions & 4 deletions .claude/skills/add-i18n-key/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ frontend/apps/web/src/i18n/
messages/
en/public.json
tr/public.json
en/auth.json
tr/auth.json
```

P02d-6 supplies only `public`; later features add a namespace beneath each locale.
`catalogues.ts` statically imports the two public files, and `request.ts` explicitly
mounts them as `messages.public`. There is no automatic file discovery. JSON nesting
P02d-6 supplies `public`; P02b-7 adds `auth`. `catalogues.ts` and
`auth-catalogues.ts` statically import their complete en/tr files; `request.ts`
explicitly mounts both namespaces. There is no automatic file discovery. JSON nesting
supplies dotted identifiers: `public.catalog.course_count` is
`catalog.course_count` within the `public` translator.

Expand Down Expand Up @@ -141,7 +143,7 @@ same layout; they do not introduce an enrollment catalogue in P02d-6.

For a new namespace, adding JSON files is insufficient. Wire their static imports
and locale map into `catalogues.ts`, mount the namespace in `request.ts`, and add
its typed translator and callsite-census coverage. Do not pass a catalogue to a
its typed translator and callsite-census coverage (`auth` uses typed `copy`). Do not pass a catalogue to a
Client Component. For public keys with new ICU arguments, update
`PublicMessageArguments` alongside the messages and their callsites.

Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Walk every change against the project's
| **Tenant id from the resolved context only** | Resolved per [ADR-0036](../../../docs/decisions/0036-tenant-resolution-trusted-inputs.md): from the host lookup of the effective host, or on a platform host from validated claims confirmed by live membership; off HTTP, from the validated authoritative job row or the integration-event envelope. Never from a request body, query string, cookie or tenant header — `X-Tenant-Id` and `X-Organization-Id` are assertions that can only reject, on every hop. Check command and DTO surfaces. |
| **SQL injection** | EF Core LINQ or `FromSqlInterpolated`; never raw string concatenation. Raw SQL has parameters. |
| **XSS** | No `dangerouslySetInnerHTML` outside a sanitisation wrapper; CSP nonces in place; markdown via allowlist. Nothing sets a CSP today: the [standards index](../../../docs/standards/README.md#honest-status-today) row for Security Standards carves § HTTP Headers out to [Phase 11](../../../docs/roadmap/phase-11-production-hardening.md#security), so a missing nonce is not a Blocker until that phase sets one. Accepted P02d-6 G42 requires atomic four-color validation and a fixed style element, with whole-palette fallback; output must be safe without CSP. [The accepted package](../../../docs/roadmap/phase-02d-delivery-log.md#p02d-6-accepted-answers) owns its proof obligations; acceptance alone is not delivery. |
| **CSRF** | Server Actions / Auth.js session check; non-Action mutating fetches carry CSRF tokens. |
| **CSRF** | ADR-0070's closed BFF POSTs require the exact verified Origin and explicit CSRF proof; OIDC callbacks require their bound state/nonce/PKCE transaction. Server Actions remain unadmitted until their owning phase authorizes them. |
| **Secrets** | No secret in source / appsettings / env-file-committed; reads through `ISecretProvider`. No log of token / password / national id. |
| **PII redaction** | `[PiiSensitive]` fields carry `SensitiveTokenCatalog.RedactedValue` in audit snapshots — the property stays, so the diff still records *that* it changed; logs don't carry raw PII. |
| **File upload** | MIME sniff + extension allowlist + size limit + EXIF strip + tenant-scoped key. |
Expand Down
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ KEYCLOAK_ADMIN_PASSWORD=admin-dev-secret
# reconciliation verifies an existing confidential secret and never rotates it.
# Never pass this value to the API, public renderer or .NET Seeder.
KEYCLOAK_WEB_CLIENT_SECRET=learnstack-web-dev-secret
# Optional native tenant BFF (ADR-0070). Explicit false keeps the anonymous demo
# independent of Keycloak. For local watch mode, opt in with true and the issuer
# below; production launch requires an HTTPS issuer and a trusting private CA.
# All present root/web/process values must agree. Private source files are 0600.
LEARNSTACK_BFF_ENABLED=false
# LEARNSTACK_BFF_ISSUER=http://localhost:8080/realms/learnstack

# ─── Vault (-dev mode; token shared with Dapr secret-store component) ────
# Boots the `vault` compose service via `-dev-root-token-id` AND is passed
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,10 @@ jobs:
working-directory: frontend
run: pnpm install --frozen-lockfile

- name: Compile native web and authenticated SDK fixture entries
working-directory: frontend
run: pnpm --filter @learnstack/web build:ingress

- name: Prepare pinned provider fixture images within the whole-job budget
timeout-minutes: 2
run: python3 scripts/ci-test-shards.py prepare-fixtures
Expand Down
14 changes: 4 additions & 10 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,10 @@ repository holds only LearnStack's side of the boundary, in
## What state this is in

**Phase 01, Phase 02a and Phase 02d are complete; Phase 02b is the live phase.**
[Phase 02d](docs/roadmap/phase-02d-walking-skeleton.md), the two-tenant walking
skeleton and the first user-visible milestone, merged through PR #28 on
2026-10-11: two hosts, two tenants, two education sites, one binary and one
database. In [Phase 02b](docs/roadmap/phase-02b-events-auth.md), P02b-0 through
P02b-5 are complete and P02b-1–5 merged through PRs #29–#33 — transactional event
production, durable dispatch, subscriber delivery, background jobs and tenant API
authentication — and P02b-6's realm and identity implementation is merged through
PR #34, with post-merge CI corrections continuing on `development`. P02b-7 (BFF
session) and P02b-8 (exit enforcement) are pending, and G13's session part stays
Open, so browser sign-in is not implemented. Phase 06 retains the full
[Phase 02d](docs/roadmap/phase-02d-walking-skeleton.md) owns the two-tenant walking
skeleton. [Phase 02b](docs/roadmap/phase-02b-events-auth.md) owns current packet
and decision state for events, background jobs, identity and sessions.
[Phase 06](docs/roadmap/phase-06-renderer-admin-studio.md) owns the full
renderer/Studio expansion.

**Status lives in one place.** Each phase document's Status block owns packet
Expand Down
Loading
Loading