Files
kandev/docs/plans/new-workspace-github-access-defaults/plan.md
T
2026-08-24 11:09:03 +00:00

193 lines
11 KiB
Markdown

---
spec: docs/specs/integrations/requirements/github-authentication.md
created: 2026-08-02
status: completed
---
# Implementation Plan: New Workspace GitHub Access Defaults
## Overview
The confirmed root cause is that `github_workspace_settings` resolves a missing task policy to
`managed`, while a new workspace has no `github_workspace_connections` row. Task launch therefore
requests a broker lease that fails with `ErrGitHubNotConfigured` before the agent starts. The fix
will persist executor task access for each new workspace, optionally snapshot an operator-authorized
active host `gh` account as a named CLI connection, and leave every existing installation unchanged.
The implementation begins with failing backend and browser regressions, then adds the smallest
workspace-initialization seam and GitHub persistence behavior required to make them pass. Public
documentation follows after the behavior is green.
---
## Backend
### GitHub workspace default initializer
- Add a focused workspace-default initialization path under
`apps/backend/internal/github/` (prefer a new `workspace_defaults.go` with sibling tests rather
than growing `service_connections.go`).
- Persist `TaskGitCredentialsModeExecutor` for a workspace created after this feature is active.
Keep `defaultWorkspaceSettings`, `normalizeTaskGitCredentialsMode`, existing schema defaults, and
upgrade fallbacks on `managed`; those are the backward-compatibility path for existing missing or
invalid state.
- Discover the currently active account through the service's injectable CLI account source. Only
an internal caller, synthetic administrator, or real administrator may receive the host account;
reuse the existing `requireGHCLIOperator` boundary for member denial.
- Validate and store the exact `github.com` host/login as a `gh_cli` connection without persisting a
bearer token. No active/valid CLI account is a soft condition: executor settings are still saved
and workspace creation succeeds disconnected.
- Record whether the GitHub schema belongs to a brand-new database before `NewStore` initializes
its tables. Expose a one-shot startup method that initializes the already-seeded default
workspace only in that fresh-database case. Existing databases, including workspaces with no
settings row, are not backfilled or rebound.
### Workspace creation seam
- Add a narrow `WorkspaceDefaultsInitializer` interface and setter in
`apps/backend/internal/task/service/service.go`.
- Call it in `CreateWorkspace` after the workspace transaction succeeds and before
`workspace.created` is published, so an immediately created task observes executor mode rather
than racing an event subscriber. The initializer owns optional-CLI degradation; a returned
persistence error is logged as a workspace-default initialization failure.
- Wire the GitHub service into this seam in `apps/backend/internal/backendapp/services.go` after
workspace authorization and connection-secret infrastructure are installed. Invoke the
fresh-database bootstrap at the same composition point for the repository-seeded initial
workspace.
- Do not use a `workspace.created` subscription as the correctness boundary: the NATS-backed bus
need not finish a subscriber before the create request can be followed by task launch.
### Upgrade and security boundaries
- Do not modify existing `github_workspace_connections` or
`github_workspace_settings.task_git_credentials_mode` rows.
- Do not change the current `managed` normalization for legacy missing/invalid values.
- Do not auto-bind host `gh` for a non-admin member context.
- Do not copy or persist the resolved CLI token, and do not follow later host active-account
changes for an already-created workspace.
---
## Frontend
No React component, route, API client, state slice, copy, or responsive composition changes are
required. The existing Workspace GitHub access summary and connection dialog already render the
backend's saved `executor` and `gh_cli` values.
### Mobile parity contract
The nearest shipped mobile exemplar remains
`apps/web/e2e/tests/integrations/mobile-github-workspace-settings.spec.ts`: the existing full-height,
single-scroll-owner connection drawer and 44px task-access controls are unchanged. Update that
scenario to prove the initial summary reads **Inherit executor Git credentials**. Because this is a
persisted backend-default change with no layout, navigation, scroll, touch, or composition change,
the focused existing mobile scenario satisfies mobile parity without a new mobile surface.
---
## Tests
- **What:** a new workspace always receives persisted executor task access; an internal/admin
creator with a valid active CLI account also receives an exact named CLI connection.
**File:** `apps/backend/internal/github/workspace_defaults_test.go`.
**How:** SQLite-backed service tests with injectable CLI account/token validation boundaries.
- **What:** member creation never receives the server operator's CLI identity; unavailable,
unauthenticated, or invalid CLI discovery degrades to disconnected automation without losing
executor task access.
**File:** `apps/backend/internal/github/workspace_defaults_test.go`.
**How:** table-driven service tests using real store reads and synthetic/admin/member contexts.
- **What:** a database with pre-existing GitHub schema/settings is not treated as fresh and its
missing or managed behavior is not rewritten, while a genuinely fresh schema initializes the
seeded workspace once.
**Files:** `apps/backend/internal/github/workspace_defaults_test.go`,
`apps/backend/internal/github/workspace_settings_test.go`.
**How:** fresh and replayed SQLite store setup with row-level assertions.
- **What:** task-service workspace creation runs default initialization before publishing the
created event.
**File:** `apps/backend/internal/task/service/service_resources_test.go`.
**How:** a recording initializer and event bus assert call order and error handling.
- **What:** backend composition wires runtime workspace creation and fresh-install startup to the
GitHub initializer.
**File:** `apps/backend/internal/backendapp/services_github_defaults_test.go` (or the nearest
existing service-composition test if a smaller harness is available during RED).
**How:** real SQLite repositories with injected GitHub account resolution and stored-state
assertions.
- **What:** executor policy skips broker lease injection.
**File:** `apps/backend/internal/orchestrator/executor/executor_credentials_test.go`.
**How:** retain the existing `executor inheritance` regression as downstream contract evidence;
add no duplicate test unless the new integration test cannot prove the no-lease outcome.
Targeted backend verification:
```bash
cd apps/backend && go test -tags fts5 ./internal/github ./internal/task/service ./internal/backendapp ./internal/orchestrator/executor -run 'Test.*Workspace.*Defaults|Test.*Workspace.*Initializ|TestTaskGitCredentialModeDefaultsManaged|TestApplyGitCredentialSnapshotUsesExecutorSources' -count=1
```
## E2E Tests
- **Scenario:** GIVEN a new workspace and an active mock CLI account, WHEN an administrator creates
the workspace and opens Workspace GitHub access, THEN the UI shows that exact CLI automation
identity and **Inherit executor Git credentials**.
**File:** `apps/web/e2e/tests/integrations/github-authentication.spec.ts`.
**What to verify:** automation source/login and task-access summary through the rendered settings
page, with backend seeding only for the CLI-account precondition.
- **Scenario:** GIVEN the initial fresh E2E workspace, WHEN desktop and mobile users open Workspace
GitHub access, THEN the existing summary and dialog/drawer show executor inheritance as the
initial task policy.
**Files:** `apps/web/e2e/tests/integrations/github-workspace-settings.spec.ts`,
`apps/web/e2e/tests/integrations/mobile-github-workspace-settings.spec.ts`.
**What to verify:** desktop and mobile report the same saved policy; existing mobile geometry,
scroll ownership, safe-area containment, and touch targets remain green.
Targeted browser verification after the fresh-worktree install:
```bash
cd apps && pnpm install --frozen-lockfile
cd apps && pnpm --filter @kandev/web run e2e:run -- tests/integrations/github-authentication.spec.ts tests/integrations/github-workspace-settings.spec.ts
cd apps && pnpm --filter @kandev/web run e2e:run -- --project mobile-chrome tests/integrations/mobile-github-workspace-settings.spec.ts
```
---
## Public Documentation
Update `docs/public/integrations.md` so **Inherit executor Git credentials** is documented as the
new-workspace default, managed credentials are described as an opt-in workspace policy, active host
`gh` auto-binding is limited to operator-authorized creation, remote executors remain responsible
for their own credentials, and upgrades are unchanged.
Validate with:
```bash
node --test scripts/validate-public-docs.test.mjs
node scripts/validate-public-docs.mjs
```
---
## Verification Results
- `cd apps/backend && go test -tags fts5 ./internal/github ./internal/task/service ./internal/backendapp ./internal/orchestrator/executor -run 'Test.*Workspace.*Defaults|Test.*Workspace.*Initializ|TestTaskGitCredentialModeDefaultsManaged|TestApplyGitCredentialSnapshotUsesExecutorSources' -count=1` — 12 passed in 4 packages.
- `cd apps/backend && go test -tags fts5 ./internal/github ./internal/task/service ./internal/backendapp ./internal/orchestrator/executor -count=1` — 2402 passed in 4 packages.
- `cd apps && pnpm --filter @kandev/web run e2e:run -- tests/integrations/github-authentication.spec.ts tests/integrations/github-workspace-settings.spec.ts` — 9 passed.
- `cd apps && pnpm --filter @kandev/web run e2e:run -- --project mobile-chrome tests/integrations/mobile-github-workspace-settings.spec.ts` — 2 passed.
- `cd apps/backend && make lint` — 0 issues.
- `cd apps && pnpm --filter @kandev/web run typecheck` — passed.
- `cd apps && pnpm --filter @kandev/web run lint` — passed.
- `cd apps && pnpm --filter @kandev/web run i18n:check && pnpm --filter @kandev/web run i18n:ratchet` — passed.
- `node --test scripts/validate-public-docs.test.mjs` — 58 passed.
- `node scripts/validate-public-docs.mjs` — 41 published docs pages validated.
- `cd apps && pnpm run format:check` and `git diff --check` — passed.
---
## Implementation Waves And Parallel Candidates
Execution is sequential in the primary conversation; no task is marked parallel-safe because the
RED tests define the contracts consumed by the backend implementation and documentation must match
the final green behavior.
- [x] [Task 01: Add failing default-behavior regressions](task-01-default-behavior-regressions.md)
- [x] [Task 02: Implement workspace GitHub defaults](task-02-workspace-github-defaults.md)
- [x] [Task 03: Update public integration documentation](task-03-public-integration-documentation.md)