docs(tasks): establish tasks/do.md execution protocol and link from path.md
This commit is contained in:
parent
36bad05b35
commit
d0a1492f6c
49
tasks/do.md
Normal file
49
tasks/do.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Task Implementation Execution Protocol (`tasks/do.md`)
|
||||||
|
|
||||||
|
This protocol defines the standard for executing an approved task from
|
||||||
|
`tasks/new/`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Direct Execution Protocol (When You Are Doing the Task)
|
||||||
|
|
||||||
|
When commanded to **"tasks/do `[TASK_FILE]`"**:
|
||||||
|
|
||||||
|
1. **Move to WIP:** Move the task file from `tasks/new/` to `tasks/wip/` before
|
||||||
|
starting work.
|
||||||
|
2. **Follow the 4-Step State Machine:**
|
||||||
|
- **Step 1 (Research):** Inspect the target files and verify architectural
|
||||||
|
assumptions.
|
||||||
|
- **Step 2 (Implementation):** Apply minimal, pure functional modifications.
|
||||||
|
Preserve existing docstrings and comments.
|
||||||
|
- **Step 3 (Quality Gates):** Run all verification gates:
|
||||||
|
- `deno fmt`
|
||||||
|
- `deno task lint`
|
||||||
|
- `deno task check`
|
||||||
|
- `deno test --allow-all` (Run ONLY hermetic unit tests; NEVER run
|
||||||
|
`deno task start` in container sandboxes).
|
||||||
|
- **Step 4 (Review & Move):** Upon all gates passing, move the task file to
|
||||||
|
`tasks/complete/YYYY-MMDD.XX.agent.type.scope.title-HHMM.md`.
|
||||||
|
3. **Commit & Sync:** Commit with standard conventional commit syntax and push
|
||||||
|
to both remotes (`origin` and `gitea`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Dispatch Template (When Preparing a Prompt for Jules or External Agents)
|
||||||
|
|
||||||
|
When commanded to **"tasks/do a prompt for Jules on `[TASK_FILE]`"**, fill in
|
||||||
|
and provide the following block:
|
||||||
|
|
||||||
|
```text
|
||||||
|
**Role:** Act as an Implementation Engineer.
|
||||||
|
|
||||||
|
**The Task:** Please review and execute the approved task plan in `[tasks/new/TASK_FILENAME.md]`.
|
||||||
|
|
||||||
|
**Directives:**
|
||||||
|
1. Follow the strict 4-step state machine (Research -> Implementation -> Quality Gates -> Review).
|
||||||
|
2. Move the task file from `tasks/new/` to `tasks/wip/` before starting, and to `tasks/complete/` upon verification.
|
||||||
|
3. Apply minimal, pure functional modifications adhering to `AGENTS.md`.
|
||||||
|
4. Run all quality gates: `deno fmt`, `deno task lint`, `deno task check`, and `deno test --allow-all`.
|
||||||
|
5. Run ONLY unit tests (`deno test --allow-all`). Do NOT run `deno task start` or `deno task dev` (database daemons are not running in container sandboxes).
|
||||||
|
6. Provide a concise summary of all modified files and verified test results upon completion.
|
||||||
|
```
|
||||||
@ -1,40 +1,76 @@
|
|||||||
# TASK METADATA
|
# TASK METADATA
|
||||||
|
|
||||||
- **Target Files:** `server/auth-session.ts`, `server/routes/sessions.ts`, `server/routes/events.ts`, `server/main.ts`, `ui/mod.ts`, `server/main.test.ts`
|
- **Target Files:** `server/auth-session.ts`, `server/routes/sessions.ts`,
|
||||||
- **Core Objective:** Implement strict Zero-Trust scope enforcement and permission guards across all Auth-Yes internal API routes and SSR UI pages to ensure delegated and read-only sessions cannot escalate privileges, perform unauthorized mutations, or access admin interfaces.
|
`server/routes/events.ts`, `server/main.ts`, `ui/mod.ts`,
|
||||||
|
`server/main.test.ts`
|
||||||
|
- **Core Objective:** Implement strict Zero-Trust scope enforcement and
|
||||||
|
permission guards across all Auth-Yes internal API routes and SSR UI pages to
|
||||||
|
ensure delegated and read-only sessions cannot escalate privileges, perform
|
||||||
|
unauthorized mutations, or access admin interfaces.
|
||||||
- **Dependencies:** None
|
- **Dependencies:** None
|
||||||
- **Additional Important Notes:** Delegated sessions (`is_agent = true`) must hold strictly the intersection of user permissions and assigned `custom_scopes`. Self-revocation of a delegated session is permitted, but revoking other sessions is prohibited without `write:sessions` or `*`.
|
- **Additional Important Notes:** Delegated sessions (`is_agent = true`) must
|
||||||
|
hold strictly the intersection of user permissions and assigned
|
||||||
|
`custom_scopes`. Self-revocation of a delegated session is permitted, but
|
||||||
|
revoking other sessions is prohibited without `write:sessions` or `*`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Architectural Considerations & Risks
|
## Architectural Considerations & Risks
|
||||||
|
|
||||||
- **Risks:**
|
- **Risks:**
|
||||||
- **Backward-Compatibility with Cached Sessions:** Existing delegated sessions in the Valkey cache might lack explicit scopes if they were created before this strict enforcement. The middleware must default to a safe deny state for unknown or missing scopes but handle legacy `is_agent = true` sessions gracefully by denying mutating actions unless explicitly permitted.
|
- **Backward-Compatibility with Cached Sessions:** Existing delegated sessions
|
||||||
- **Self-Revocation Edge Case:** The guard logic must correctly distinguish between a session revoking itself (which is always allowed for clean logouts) and a session attempting to revoke a sibling or parent session.
|
in the Valkey cache might lack explicit scopes if they were created before
|
||||||
- **Global Admin Resolution:** The `isGlobalAdmin` check relies on database queries or cache. Ensure that the new middleware does not introduce significant latency by repeatedly querying PostgreSQL on every protected route. Use Valkey caching where possible.
|
this strict enforcement. The middleware must default to a safe deny state
|
||||||
|
for unknown or missing scopes but handle legacy `is_agent = true` sessions
|
||||||
|
gracefully by denying mutating actions unless explicitly permitted.
|
||||||
|
- **Self-Revocation Edge Case:** The guard logic must correctly distinguish
|
||||||
|
between a session revoking itself (which is always allowed for clean
|
||||||
|
logouts) and a session attempting to revoke a sibling or parent session.
|
||||||
|
- **Global Admin Resolution:** The `isGlobalAdmin` check relies on database
|
||||||
|
queries or cache. Ensure that the new middleware does not introduce
|
||||||
|
significant latency by repeatedly querying PostgreSQL on every protected
|
||||||
|
route. Use Valkey caching where possible.
|
||||||
|
|
||||||
- **Alternatives:**
|
- **Alternatives:**
|
||||||
- Instead of injecting `customScopes` into the Valkey cache session payload, we could perform a database lookup on every privileged API request to determine exact grants. However, this violates the Auth-Yes architectural principle of fast-path caching at the edge and would significantly degrade performance. The chosen approach of checking scopes from the cached `AuthenticatedUser` object is highly modular and performant.
|
- Instead of injecting `customScopes` into the Valkey cache session payload,
|
||||||
|
we could perform a database lookup on every privileged API request to
|
||||||
|
determine exact grants. However, this violates the Auth-Yes architectural
|
||||||
|
principle of fast-path caching at the edge and would significantly degrade
|
||||||
|
performance. The chosen approach of checking scopes from the cached
|
||||||
|
`AuthenticatedUser` object is highly modular and performant.
|
||||||
|
|
||||||
## Proposed Implementation
|
## Proposed Implementation
|
||||||
|
|
||||||
### 1. Scope Guard Helpers (`server/auth-session.ts`)
|
### 1. Scope Guard Helpers (`server/auth-session.ts`)
|
||||||
Implement reusable composable functions to evaluate the current user's capabilities.
|
|
||||||
- `hasScope(auth: AuthenticatedUser, requiredScope: string): boolean`: Evaluates if `auth.customScopes` contains `*` or the `requiredScope`. If `!auth.isAgent`, returns `true` (primary sessions have all capabilities).
|
Implement reusable composable functions to evaluate the current user's
|
||||||
|
capabilities.
|
||||||
|
|
||||||
|
- `hasScope(auth: AuthenticatedUser, requiredScope: string): boolean`: Evaluates
|
||||||
|
if `auth.customScopes` contains `*` or the `requiredScope`. If
|
||||||
|
`!auth.isAgent`, returns `true` (primary sessions have all capabilities).
|
||||||
- Create Hono middleware helpers:
|
- Create Hono middleware helpers:
|
||||||
- `requirePrimarySession()`: Denies access with `403 Forbidden` if `auth.isAgent === true`.
|
- `requirePrimarySession()`: Denies access with `403 Forbidden` if
|
||||||
- `requireScope(scope: string)`: Denies access if `hasScope(auth, scope)` returns false.
|
`auth.isAgent === true`.
|
||||||
- `requireAdmin(auth: AuthenticatedUser)`: Uses `isGlobalAdmin(auth.userId)` and verifies `!auth.isAgent` OR `auth.customScopes.includes("*")`.
|
- `requireScope(scope: string)`: Denies access if `hasScope(auth, scope)`
|
||||||
|
returns false.
|
||||||
|
- `requireAdmin(auth: AuthenticatedUser)`: Uses `isGlobalAdmin(auth.userId)`
|
||||||
|
and verifies `!auth.isAgent` OR `auth.customScopes.includes("*")`.
|
||||||
|
|
||||||
### 2. Guard Internal API Routes
|
### 2. Guard Internal API Routes
|
||||||
|
|
||||||
Apply the newly created guards to critical endpoints.
|
Apply the newly created guards to critical endpoints.
|
||||||
|
|
||||||
- **`server/routes/sessions.ts`**
|
- **`server/routes/sessions.ts`**
|
||||||
- `DELETE /api/sessions/:id`: Allow if target `id === auth.sessionId`. Otherwise, require `write:sessions` scope.
|
- `DELETE /api/sessions/:id`: Allow if target `id === auth.sessionId`.
|
||||||
- `PUT /api/sessions/:id/scopes`: Require `admin` or `*` scope, OR `write:sessions`.
|
Otherwise, require `write:sessions` scope.
|
||||||
|
- `PUT /api/sessions/:id/scopes`: Require `admin` or `*` scope, OR
|
||||||
|
`write:sessions`.
|
||||||
- `POST /api/sessions/:id/extend`: Require `write:sessions` or `*`.
|
- `POST /api/sessions/:id/extend`: Require `write:sessions` or `*`.
|
||||||
- `POST /api/sessions/delegate`: Prevent privilege escalation. Require `admin` or `*` scope to delegate an `admin` mode session. If creating a `read_only` or `operator` session, require the delegator to have at least those equivalent scopes.
|
- `POST /api/sessions/delegate`: Prevent privilege escalation. Require `admin`
|
||||||
|
or `*` scope to delegate an `admin` mode session. If creating a `read_only`
|
||||||
|
or `operator` session, require the delegator to have at least those
|
||||||
|
equivalent scopes.
|
||||||
|
|
||||||
- **`server/routes/events.ts`**
|
- **`server/routes/events.ts`**
|
||||||
- `POST /api/events`: Require `write:events` or `*`.
|
- `POST /api/events`: Require `write:events` or `*`.
|
||||||
@ -42,15 +78,26 @@ Apply the newly created guards to critical endpoints.
|
|||||||
- `POST /api/events/:id/extend`: Require `write:events` or `*`.
|
- `POST /api/events/:id/extend`: Require `write:events` or `*`.
|
||||||
|
|
||||||
- **`server/main.ts`**
|
- **`server/main.ts`**
|
||||||
- Apply `requirePrimarySession()` or `requireAdmin()` to `/api/admin/*` and `/api/passkeys/*` endpoints.
|
- Apply `requirePrimarySession()` or `requireAdmin()` to `/api/admin/*` and
|
||||||
|
`/api/passkeys/*` endpoints.
|
||||||
|
|
||||||
### 3. SSR UI Gates (`ui/mod.ts`)
|
### 3. SSR UI Gates (`ui/mod.ts`)
|
||||||
|
|
||||||
Guard the user interfaces against unauthorized delegated sessions.
|
Guard the user interfaces against unauthorized delegated sessions.
|
||||||
- `/admin/*`: Verify `isAdmin && (!auth.isAgent || auth.customScopes.includes("*"))`. Redirect unauthorized sessions to `/dashboard` or return a `403 Forbidden` page.
|
|
||||||
- `/dashboard/passkeys`: Verify `!auth.isAgent`. Delegated sessions cannot manage passkeys.
|
- `/admin/*`: Verify
|
||||||
|
`isAdmin && (!auth.isAgent || auth.customScopes.includes("*"))`. Redirect
|
||||||
|
unauthorized sessions to `/dashboard` or return a `403 Forbidden` page.
|
||||||
|
- `/dashboard/passkeys`: Verify `!auth.isAgent`. Delegated sessions cannot
|
||||||
|
manage passkeys.
|
||||||
|
|
||||||
### 4. Testing (`server/main.test.ts`)
|
### 4. Testing (`server/main.test.ts`)
|
||||||
|
|
||||||
- Write tests that create a delegated session with only `read_only` scopes.
|
- Write tests that create a delegated session with only `read_only` scopes.
|
||||||
- Assert that this session gets a `403 Forbidden` when attempting to call `POST /api/sessions/delegate`, `DELETE /api/sessions/:other_id`, and `POST /api/events`.
|
- Assert that this session gets a `403 Forbidden` when attempting to call
|
||||||
- Assert that the delegated session can successfully call `DELETE /api/sessions/:own_id`.
|
`POST /api/sessions/delegate`, `DELETE /api/sessions/:other_id`, and
|
||||||
- Write tests verifying that a delegated session attempting to access `/admin/users` is redirected/blocked.
|
`POST /api/events`.
|
||||||
|
- Assert that the delegated session can successfully call
|
||||||
|
`DELETE /api/sessions/:own_id`.
|
||||||
|
- Write tests verifying that a delegated session attempting to access
|
||||||
|
`/admin/users` is redirected/blocked.
|
||||||
|
|||||||
@ -1,73 +1,126 @@
|
|||||||
# TASK METADATA
|
# TASK METADATA
|
||||||
|
|
||||||
- **Target Files:** `server/main.ts`, `server/main.test.ts`, `ui/components/SessionsPage.tsx`, `server/auth-session.ts`, `ui/mod.ts`, `infra/setup.ts`, `ui/utils/bip39_wordlist.ts` (and copies), `spire_ffi/Cargo.lock`, `ui/components/AdminInvitesPage.tsx`, `ui/components/AdminUserDetailsPage.tsx`, `deno.lock`, `ui/components/AdminRolesPage.tsx`, `ui/components/AdminAppsPage.tsx`
|
- **Target Files:** `server/main.ts`, `server/main.test.ts`,
|
||||||
- **Core Objective:** Architect a phased, zero-regression modular decomposition plan to eliminate monoliths and enforce the Single Responsibility Principle.
|
`ui/components/SessionsPage.tsx`, `server/auth-session.ts`, `ui/mod.ts`,
|
||||||
|
`infra/setup.ts`, `ui/utils/bip39_wordlist.ts` (and copies),
|
||||||
|
`spire_ffi/Cargo.lock`, `ui/components/AdminInvitesPage.tsx`,
|
||||||
|
`ui/components/AdminUserDetailsPage.tsx`, `deno.lock`,
|
||||||
|
`ui/components/AdminRolesPage.tsx`, `ui/components/AdminAppsPage.tsx`
|
||||||
|
- **Core Objective:** Architect a phased, zero-regression modular decomposition
|
||||||
|
plan to eliminate monoliths and enforce the Single Responsibility Principle.
|
||||||
- **Dependencies:** None.
|
- **Dependencies:** None.
|
||||||
- **Additional Important Notes:** Must preserve zero-dependency SDK purity (`@auth-yes/sdk`) and guarantee 100% backward compatibility with all quality gates (`deno fmt`, `deno task lint`, `deno task check`, `deno task test`).
|
- **Additional Important Notes:** Must preserve zero-dependency SDK purity
|
||||||
|
(`@auth-yes/sdk`) and guarantee 100% backward compatibility with all quality
|
||||||
|
gates (`deno fmt`, `deno task lint`, `deno task check`, `deno task test`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. Architectural Considerations & Risks
|
### 2. Architectural Considerations & Risks
|
||||||
|
|
||||||
- **Risks:**
|
- **Risks:**
|
||||||
- **Circular Dependencies:** Moving components could introduce circular dependencies, especially between `auth-session.ts` and routing files.
|
- **Circular Dependencies:** Moving components could introduce circular
|
||||||
- **Regression:** Splitting monolithic files (e.g., `main.test.ts`) might cause tests to fail or miss edge cases if not carefully separated by domain tier.
|
dependencies, especially between `auth-session.ts` and routing files.
|
||||||
- **Client-Side Breakage:** Extracting inline JS strings from JSX (e.g., `SessionsPage.tsx`) to external vanilla JS files could break dynamic interactions if DOM elements are not correctly targeted or if loading sequence is altered.
|
- **Regression:** Splitting monolithic files (e.g., `main.test.ts`) might
|
||||||
|
cause tests to fail or miss edge cases if not carefully separated by domain
|
||||||
|
tier.
|
||||||
|
- **Client-Side Breakage:** Extracting inline JS strings from JSX (e.g.,
|
||||||
|
`SessionsPage.tsx`) to external vanilla JS files could break dynamic
|
||||||
|
interactions if DOM elements are not correctly targeted or if loading
|
||||||
|
sequence is altered.
|
||||||
- **Alternatives:**
|
- **Alternatives:**
|
||||||
- Instead of extracting completely to static files, use Deno Island architectures if supported, but given the strict instruction to use pure Hono SSR JSX (strictly no React) and vanilla JavaScript, static ES modules under `ui/public/ui/` or `ui/static/` is the optimal, native approach.
|
- Instead of extracting completely to static files, use Deno Island
|
||||||
|
architectures if supported, but given the strict instruction to use pure
|
||||||
|
Hono SSR JSX (strictly no React) and vanilla JavaScript, static ES modules
|
||||||
|
under `ui/public/ui/` or `ui/static/` is the optimal, native approach.
|
||||||
|
|
||||||
### 3. Proposed Implementation
|
### 3. Proposed Implementation
|
||||||
|
|
||||||
The refactoring will be executed in a safe, phased approach to guarantee zero regressions:
|
The refactoring will be executed in a safe, phased approach to guarantee zero
|
||||||
|
regressions:
|
||||||
|
|
||||||
#### Phase 1: UI Sessions Decomposition (Frontend)
|
#### Phase 1: UI Sessions Decomposition (Frontend)
|
||||||
|
|
||||||
- **Target:** `ui/components/SessionsPage.tsx`
|
- **Target:** `ui/components/SessionsPage.tsx`
|
||||||
- **Actions:**
|
- **Actions:**
|
||||||
- Extract the Event Cockpit Deck logic into `ui/components/sessions/EventCockpitDeck.tsx`.
|
- Extract the Event Cockpit Deck logic into
|
||||||
- Extract the Workshop Launch Drawer logic into `ui/components/sessions/WorkshopDrawer.tsx`.
|
`ui/components/sessions/EventCockpitDeck.tsx`.
|
||||||
- Extract the 1:1 Delegation Drawer logic into `ui/components/sessions/DirectPassDrawer.tsx`.
|
- Extract the Workshop Launch Drawer logic into
|
||||||
|
`ui/components/sessions/WorkshopDrawer.tsx`.
|
||||||
|
- Extract the 1:1 Delegation Drawer logic into
|
||||||
|
`ui/components/sessions/DirectPassDrawer.tsx`.
|
||||||
- Extract the Scope Modal logic into `ui/components/sessions/ScopeModal.tsx`.
|
- Extract the Scope Modal logic into `ui/components/sessions/ScopeModal.tsx`.
|
||||||
- Move the 400+ lines of raw client-side JavaScript currently embedded in string templates (`dangerouslySetInnerHTML`) into a dedicated static vanilla JS module (e.g., `ui/public/ui/sessions.js`) and link it via a `<script type="module" src="...">` tag.
|
- Move the 400+ lines of raw client-side JavaScript currently embedded in
|
||||||
- **Validation:** Run UI unit tests, `deno task lint`, and visual checks to ensure all modals and JS interactions still work.
|
string templates (`dangerouslySetInnerHTML`) into a dedicated static vanilla
|
||||||
|
JS module (e.g., `ui/public/ui/sessions.js`) and link it via a
|
||||||
|
`<script type="module" src="...">` tag.
|
||||||
|
- **Validation:** Run UI unit tests, `deno task lint`, and visual checks to
|
||||||
|
ensure all modals and JS interactions still work.
|
||||||
|
|
||||||
#### Phase 2: UI Admin Pages Decomposition (Frontend)
|
#### Phase 2: UI Admin Pages Decomposition (Frontend)
|
||||||
- **Target:** `ui/components/AdminInvitesPage.tsx`, `ui/components/AdminUserDetailsPage.tsx`, `ui/components/AdminRolesPage.tsx`, `ui/components/AdminAppsPage.tsx`
|
|
||||||
|
- **Target:** `ui/components/AdminInvitesPage.tsx`,
|
||||||
|
`ui/components/AdminUserDetailsPage.tsx`, `ui/components/AdminRolesPage.tsx`,
|
||||||
|
`ui/components/AdminAppsPage.tsx`
|
||||||
- **Actions:**
|
- **Actions:**
|
||||||
- Refactor large admin pages (all > 490 lines) by extracting repeated layout structures, table rendering, and modal dialogs into reusable components (e.g., `ui/components/admin/AdminTable.tsx`, `ui/components/admin/AdminModal.tsx`).
|
- Refactor large admin pages (all > 490 lines) by extracting repeated layout
|
||||||
- Move embedded client-side javascript logic from these files into corresponding static vanilla JS modules in `ui/public/ui/`.
|
structures, table rendering, and modal dialogs into reusable components
|
||||||
|
(e.g., `ui/components/admin/AdminTable.tsx`,
|
||||||
|
`ui/components/admin/AdminModal.tsx`).
|
||||||
|
- Move embedded client-side javascript logic from these files into
|
||||||
|
corresponding static vanilla JS modules in `ui/public/ui/`.
|
||||||
- **Validation:** Visual validation of admin interfaces, `deno task lint`.
|
- **Validation:** Visual validation of admin interfaces, `deno task lint`.
|
||||||
|
|
||||||
#### Phase 3: Server Route Modularization (Backend)
|
#### Phase 3: Server Route Modularization (Backend)
|
||||||
|
|
||||||
- **Target:** `server/main.ts` and `server/routes/`
|
- **Target:** `server/main.ts` and `server/routes/`
|
||||||
- **Actions:**
|
- **Actions:**
|
||||||
- Extract Admin CRUD routes (`/api/admin/*`) into a new file: `server/routes/admin.ts`.
|
- Extract Admin CRUD routes (`/api/admin/*`) into a new file:
|
||||||
- Extract WebAuthn and Passkey logic (`/api/login`, `/api/register`, `/api/passkeys`) into `server/routes/auth.ts`.
|
`server/routes/admin.ts`.
|
||||||
- Move ConnectRPC daemon orchestration and middleware/rate limiting setup into dedicated configuration modules (e.g., `server/middleware.ts`, `server/rpc.ts`).
|
- Extract WebAuthn and Passkey logic (`/api/login`, `/api/register`,
|
||||||
- Keep `server/main.ts` purely as the application entrypoint for mounting sub-routers.
|
`/api/passkeys`) into `server/routes/auth.ts`.
|
||||||
- **Validation:** Run `deno task test` to ensure all API endpoints resolve correctly.
|
- Move ConnectRPC daemon orchestration and middleware/rate limiting setup into
|
||||||
|
dedicated configuration modules (e.g., `server/middleware.ts`,
|
||||||
|
`server/rpc.ts`).
|
||||||
|
- Keep `server/main.ts` purely as the application entrypoint for mounting
|
||||||
|
sub-routers.
|
||||||
|
- **Validation:** Run `deno task test` to ensure all API endpoints resolve
|
||||||
|
correctly.
|
||||||
|
|
||||||
#### Phase 4: Infrastructure Scripts Refactoring (DevOps)
|
#### Phase 4: Infrastructure Scripts Refactoring (DevOps)
|
||||||
|
|
||||||
- **Target:** `infra/setup.ts`
|
- **Target:** `infra/setup.ts`
|
||||||
- **Actions:**
|
- **Actions:**
|
||||||
- Split the 1000+ line setup script.
|
- Split the 1000+ line setup script.
|
||||||
- Extract CLI configuration/prompt logic into `infra/setup/cli.ts`.
|
- Extract CLI configuration/prompt logic into `infra/setup/cli.ts`.
|
||||||
- Extract Docker compose generation/writing logic into `infra/setup/compose.ts`.
|
- Extract Docker compose generation/writing logic into
|
||||||
|
`infra/setup/compose.ts`.
|
||||||
- Extract environment variable handling into `infra/setup/env.ts`.
|
- Extract environment variable handling into `infra/setup/env.ts`.
|
||||||
- **Validation:** Run `deno check infra/setup.ts` and verify script execution against a dummy environment.
|
- **Validation:** Run `deno check infra/setup.ts` and verify script execution
|
||||||
|
against a dummy environment.
|
||||||
|
|
||||||
#### Phase 5: Test Suite Tier Separation (Testing)
|
#### Phase 5: Test Suite Tier Separation (Testing)
|
||||||
|
|
||||||
- **Target:** `server/main.test.ts`
|
- **Target:** `server/main.test.ts`
|
||||||
- **Actions:**
|
- **Actions:**
|
||||||
- Split the 1,300+ line test monolith by domain.
|
- Split the 1,300+ line test monolith by domain.
|
||||||
- Create `server/tests/auth.test.ts` for WebAuthn PRF and Cookie Domain scoping.
|
- Create `server/tests/auth.test.ts` for WebAuthn PRF and Cookie Domain
|
||||||
|
scoping.
|
||||||
- Create `server/tests/forward_auth.test.ts` for Tier 1/2 ForwardAuth tests.
|
- Create `server/tests/forward_auth.test.ts` for Tier 1/2 ForwardAuth tests.
|
||||||
- Create `server/tests/rpc.test.ts` for Tier 3 ConnectRPC tests.
|
- Create `server/tests/rpc.test.ts` for Tier 3 ConnectRPC tests.
|
||||||
- Create `server/tests/events.test.ts` for Event passes and Session delegation tests.
|
- Create `server/tests/events.test.ts` for Event passes and Session delegation
|
||||||
- **Validation:** Run `deno task test` and ensure all hermetic tests pass without Docker.
|
tests.
|
||||||
|
- **Validation:** Run `deno task test` and ensure all hermetic tests pass
|
||||||
|
without Docker.
|
||||||
|
|
||||||
#### Phase 6: Core Logic Refactoring (Utilities)
|
#### Phase 6: Core Logic Refactoring (Utilities)
|
||||||
|
|
||||||
- **Target:** `server/auth-session.ts` and `ui/mod.ts`
|
- **Target:** `server/auth-session.ts` and `ui/mod.ts`
|
||||||
- **Actions:**
|
- **Actions:**
|
||||||
- Split `server/auth-session.ts`: Move ForwardAuth ingress logic to `server/forward_auth.ts`, and Valkey/Postgres resolution to `server/session_resolver.ts`.
|
- Split `server/auth-session.ts`: Move ForwardAuth ingress logic to
|
||||||
- Split `ui/mod.ts`: Separate database queries and admin authorization checks from pure SSR page routing. Create `ui/db_queries.ts` and `ui/auth_checks.ts`.
|
`server/forward_auth.ts`, and Valkey/Postgres resolution to
|
||||||
- **Validation:** Full suite `deno task check`, `deno fmt`, and `deno task test`.
|
`server/session_resolver.ts`.
|
||||||
|
- Split `ui/mod.ts`: Separate database queries and admin authorization checks
|
||||||
|
from pure SSR page routing. Create `ui/db_queries.ts` and
|
||||||
|
`ui/auth_checks.ts`.
|
||||||
|
- **Validation:** Full suite `deno task check`, `deno fmt`, and
|
||||||
|
`deno task test`.
|
||||||
|
|||||||
@ -3,46 +3,75 @@
|
|||||||
- **Target Files:**
|
- **Target Files:**
|
||||||
- `ui/components/SessionsPage.tsx`
|
- `ui/components/SessionsPage.tsx`
|
||||||
- `ui/ui_scripts.test.ts`
|
- `ui/ui_scripts.test.ts`
|
||||||
- **Core Objective:** Redesign the Sessions management page header and drawer to eliminate dual competing top buttons, restoring the clean single `[+ Delegate Session]` header action, and unifying both pass creation workflows (1:1 Direct Pass vs. Multi-Claim Workshop Pass) into clean internal drawer tabs.
|
- **Core Objective:** Redesign the Sessions management page header and drawer to
|
||||||
|
eliminate dual competing top buttons, restoring the clean single
|
||||||
|
`[+ Delegate Session]` header action, and unifying both pass creation
|
||||||
|
workflows (1:1 Direct Pass vs. Multi-Claim Workshop Pass) into clean internal
|
||||||
|
drawer tabs.
|
||||||
- **Dependencies:** None.
|
- **Dependencies:** None.
|
||||||
- **Additional Important Notes:** Must maintain 100% compliance with zero-framework SSR JSX standards and pass `ui/ui_scripts.test.ts` without client-side syntax errors.
|
- **Additional Important Notes:** Must maintain 100% compliance with
|
||||||
|
zero-framework SSR JSX standards and pass `ui/ui_scripts.test.ts` without
|
||||||
|
client-side syntax errors.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Architectural Considerations & Risks
|
## Architectural Considerations & Risks
|
||||||
|
|
||||||
- **Risks:** The primary risk involves introducing JavaScript syntax errors when consolidating the drawer forms and adding the tab-switching logic. Since this is an SSR JSX environment without a framework like React, all DOM manipulation and state management (like toggling tabs) rely on raw inline or embedded `<script>` blocks. A syntax error here could break the page interactions and fail the `ui/ui_scripts.test.ts` gate.
|
- **Risks:** The primary risk involves introducing JavaScript syntax errors when
|
||||||
- **Alternatives:** We could keep the forms completely separate, but this violates the core objective of eliminating cognitive clutter and unified navigation. The proposed vanilla JavaScript tab toggle is the most native and compliant approach for this specific architectural boundary.
|
consolidating the drawer forms and adding the tab-switching logic. Since this
|
||||||
- **UX Consistency:** The Event Cockpit Deck must remain rendered *above* the Active Sessions table to ensure real-time visibility for workshop hosts.
|
is an SSR JSX environment without a framework like React, all DOM manipulation
|
||||||
|
and state management (like toggling tabs) rely on raw inline or embedded
|
||||||
|
`<script>` blocks. A syntax error here could break the page interactions and
|
||||||
|
fail the `ui/ui_scripts.test.ts` gate.
|
||||||
|
- **Alternatives:** We could keep the forms completely separate, but this
|
||||||
|
violates the core objective of eliminating cognitive clutter and unified
|
||||||
|
navigation. The proposed vanilla JavaScript tab toggle is the most native and
|
||||||
|
compliant approach for this specific architectural boundary.
|
||||||
|
- **UX Consistency:** The Event Cockpit Deck must remain rendered _above_ the
|
||||||
|
Active Sessions table to ensure real-time visibility for workshop hosts.
|
||||||
|
|
||||||
## Proposed Implementation
|
## Proposed Implementation
|
||||||
|
|
||||||
### 1. Header Consolidation
|
### 1. Header Consolidation
|
||||||
|
|
||||||
- In `ui/components/SessionsPage.tsx`, locate the top header section.
|
- In `ui/components/SessionsPage.tsx`, locate the top header section.
|
||||||
- Remove the `[🎟️ + Create Workshop Pass]` button completely.
|
- Remove the `[🎟️ + Create Workshop Pass]` button completely.
|
||||||
- Retain only the single, primary `[🔑 + Delegate Session]` button (and ensure it triggers `openDelegateDrawer()`).
|
- Retain only the single, primary `[🔑 + Delegate Session]` button (and ensure
|
||||||
|
it triggers `openDelegateDrawer()`).
|
||||||
|
|
||||||
### 2. Drawer Consolidation (`#delegateDrawer`)
|
### 2. Drawer Consolidation (`#delegateDrawer`)
|
||||||
|
|
||||||
- Remove the entire `#eventDrawer` DOM node.
|
- Remove the entire `#eventDrawer` DOM node.
|
||||||
- Inside `#delegateDrawer`, introduce a segmented flexbox tab selector at the top of the form area.
|
- Inside `#delegateDrawer`, introduce a segmented flexbox tab selector at the
|
||||||
|
top of the form area.
|
||||||
- Add the following styling for the tab container:
|
- Add the following styling for the tab container:
|
||||||
`display: flex; background: var(--surface-muted); padding: 4px; border-radius: var(--radius-sm); border: 1px solid var(--border-subtle); gap: 4px;`
|
`display: flex; background: var(--surface-muted); padding: 4px; border-radius: var(--radius-sm); border: 1px solid var(--border-subtle); gap: 4px;`
|
||||||
- Add styling for the tab buttons:
|
- Add styling for the tab buttons:
|
||||||
`flex: 1; padding: 0.5rem 0.75rem; border-radius: var(--radius-sm); border: none; font-weight: 600; cursor: pointer; transition: all 0.15s;`
|
`flex: 1; padding: 0.5rem 0.75rem; border-radius: var(--radius-sm); border: none; font-weight: 600; cursor: pointer; transition: all 0.15s;`
|
||||||
(Use an `.active` class with `background: var(--surface-card); color: var(--primary); box-shadow: var(--shadow-xs);`).
|
(Use an `.active` class with
|
||||||
- Wrap the existing 1:1 Direct Pass form fields inside a `<div id="tabDirectPass">`.
|
`background: var(--surface-card); color: var(--primary); box-shadow: var(--shadow-xs);`).
|
||||||
- Move the fields from the deleted `#eventDrawer` into a new `<div id="tabWorkshopPass" style="display: none;">` inside `#delegateDrawer`.
|
- Wrap the existing 1:1 Direct Pass form fields inside a
|
||||||
|
`<div id="tabDirectPass">`.
|
||||||
|
- Move the fields from the deleted `#eventDrawer` into a new
|
||||||
|
`<div id="tabWorkshopPass" style="display: none;">` inside `#delegateDrawer`.
|
||||||
|
|
||||||
### 3. JavaScript Tab-Switching Logic
|
### 3. JavaScript Tab-Switching Logic
|
||||||
- Add vanilla JavaScript functions to the embedded `<script>` block in `SessionsPage.tsx` to handle tab switching.
|
|
||||||
|
- Add vanilla JavaScript functions to the embedded `<script>` block in
|
||||||
|
`SessionsPage.tsx` to handle tab switching.
|
||||||
- Implement a function (e.g., `switchDelegateTab(tabId)`) that:
|
- Implement a function (e.g., `switchDelegateTab(tabId)`) that:
|
||||||
- Toggles `display: block` and `display: none` between `#tabDirectPass` and `#tabWorkshopPass`.
|
- Toggles `display: block` and `display: none` between `#tabDirectPass` and
|
||||||
|
`#tabWorkshopPass`.
|
||||||
- Updates the active state styling on the corresponding tab buttons.
|
- Updates the active state styling on the corresponding tab buttons.
|
||||||
|
|
||||||
### 4. Code Cleanup
|
### 4. Code Cleanup
|
||||||
- Remove the `openEventDrawer()` and `closeEventDrawer()` functions from the `<script>` block.
|
|
||||||
|
- Remove the `openEventDrawer()` and `closeEventDrawer()` functions from the
|
||||||
|
`<script>` block.
|
||||||
- Ensure `closeDelegateDrawer()` correctly resets the forms or hides the drawer.
|
- Ensure `closeDelegateDrawer()` correctly resets the forms or hides the drawer.
|
||||||
|
|
||||||
### 5. Quality Gates
|
### 5. Quality Gates
|
||||||
|
|
||||||
- Run `deno fmt` and `deno task lint` to ensure code style compliance.
|
- Run `deno fmt` and `deno task lint` to ensure code style compliance.
|
||||||
- Run `deno task test` to ensure `ui/ui_scripts.test.ts` passes, verifying there are no syntax errors in the newly consolidated `<script>` block.
|
- Run `deno task test` to ensure `ui/ui_scripts.test.ts` passes, verifying there
|
||||||
|
are no syntax errors in the newly consolidated `<script>` block.
|
||||||
|
|||||||
@ -32,10 +32,11 @@ draft a compliant task file in `tasks/new/`._
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Implementation Execution Template (Developer)
|
## 2. Implementation Execution Template (`tasks/do.md`)
|
||||||
|
|
||||||
_Use this template when ready to command an agent to execute the work outlined
|
_Use this template when ready to command an agent to execute the work outlined
|
||||||
in an existing task file._
|
in an existing task file. See complete protocol in
|
||||||
|
[`tasks/do.md`](file:///home/tylerg/p/data/auth-yes/tasks/do.md)._
|
||||||
|
|
||||||
```text
|
```text
|
||||||
**Role:** Act as an Implementation Engineer.
|
**Role:** Act as an Implementation Engineer.
|
||||||
@ -44,11 +45,12 @@ in an existing task file._
|
|||||||
|
|
||||||
**Directives:**
|
**Directives:**
|
||||||
1. Follow the strict 4-step state machine (Research -> Implementation -> Quality Gates -> Review).
|
1. Follow the strict 4-step state machine (Research -> Implementation -> Quality Gates -> Review).
|
||||||
2. Apply minimal, pure functional modifications.
|
2. Move the task file from `tasks/new/` to `tasks/wip/` before starting, and to `tasks/complete/` upon verification.
|
||||||
3. Ensure all downstream pipeline steps and context contracts remain intact.
|
3. Apply minimal, pure functional modifications.
|
||||||
4. Run all quality gates (`deno fmt`, `deno task lint`, `deno task check`, `deno task test`).
|
4. Ensure all downstream pipeline steps and context contracts remain intact.
|
||||||
5. Run ONLY unit tests (`deno task test` / `deno test --allow-all`). Do NOT execute `deno task start` or `deno task dev` (live database daemons are not running in sandbox containers).
|
5. Run all quality gates (`deno fmt`, `deno task lint`, `deno task check`, `deno task test`).
|
||||||
6. Upon successful completion and verification, update the task status according to `tasks/GUIDELINES.md`.
|
6. Run ONLY unit tests (`deno task test` / `deno test --allow-all`). Do NOT execute `deno task start` or `deno task dev` (live database daemons are not running in sandbox containers).
|
||||||
|
7. Upon successful completion and verification, update the task status according to `tasks/GUIDELINES.md`.
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user