From 7fa3a77eb52063c48609337dd7d1040189de5cd4 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 10:48:42 -0600 Subject: [PATCH 01/53] chore: generate project charter for coder-ddev governance Co-Authored-By: Claude Sonnet 4.6 --- .kittify/charter/charter.md | 77 ++++++++++++++++++++++++ .kittify/charter/interview/answers.yaml | 79 +++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 .kittify/charter/charter.md create mode 100644 .kittify/charter/interview/answers.yaml diff --git a/.kittify/charter/charter.md b/.kittify/charter/charter.md new file mode 100644 index 0000000..1898eff --- /dev/null +++ b/.kittify/charter/charter.md @@ -0,0 +1,77 @@ +# Project Charter + + + +Generated: 2026-05-07T16:47:53Z + +## Testing Standards + +- Integration tests are BATS scripts that run against a live staging Coder instance (staging-coder.ddev.com) before any deployment to production. Plan-level tests use `terraform test` (no real infrastructure required). CI also runs `terraform fmt -check -recursive` and `terraform validate` for each touched template. There is no unit-test coverage percentage target — correctness is verified by staging promotion. + + +## Quality Gates + +- All changes require a pull request. CI must pass before merge. CI gates: `terraform fmt -check`, `terraform validate`, `terraform test` for each template. Integration test scripts run against staging before promoting to production. No direct commits to main. + + +## Performance Benchmarks + +- No quantitative latency targets. Workspace startup should complete within a reasonable time (under 5 minutes) as a qualitative target. CLI commands (terraform, make) should not timeout during CI runs. + + +## Branch Strategy + +- Every change requires a pull request. Single maintainer project currently, but PRs still required for traceability and CI gating. Conventional commit messages are preferred. + +- Deployment constraints: Two environments: staging-coder.ddev.com and production coder.ddev.com. Templates are promoted staging → production only after integration tests pass on staging. The main branch reflects the production-ready state. Feature branches are used for all development work. + + +## Governance Activation + +```yaml +mission: software-dev +selected_paradigms: [] +selected_directives: [] +available_tools: [git, spec-kitty] +template_set: software-dev-default +``` + +## Policy Summary + +- Intent: Manage and deploy coder.ddev.com — a cloud-hosted DDEV environment for web developers. The project owns the Coder workspace templates (Terraform HCL), the base Docker image, and the supporting shell scripts that enable Docker-in-Docker development via Sysbox runtime. A breaking change means developers cannot create or use workspaces; risk level is high for end users who depend on the service. + +- Languages/Frameworks: Terraform (HCL), Shell (Bash), Dockerfile (Ubuntu 24.04 base), bats-core (BATS test framework for shell-level integration tests), Go toolchain (available in image for future use). + +- Testing: Integration tests are BATS scripts that run against a live staging Coder instance (staging-coder.ddev.com) before any deployment to production. Plan-level tests use `terraform test` (no real infrastructure required). CI also runs `terraform fmt -check -recursive` and `terraform validate` for each touched template. There is no unit-test coverage percentage target — correctness is verified by staging promotion. + +- Quality Gates: All changes require a pull request. CI must pass before merge. CI gates: `terraform fmt -check`, `terraform validate`, `terraform test` for each template. Integration test scripts run against staging before promoting to production. No direct commits to main. + +- Review Policy: Every change requires a pull request. Single maintainer project currently, but PRs still required for traceability and CI gating. Conventional commit messages are preferred. + +- Performance Targets: No quantitative latency targets. Workspace startup should complete within a reasonable time (under 5 minutes) as a qualitative target. CLI commands (terraform, make) should not timeout during CI runs. + +- Deployment Constraints: Two environments: staging-coder.ddev.com and production coder.ddev.com. Templates are promoted staging → production only after integration tests pass on staging. The main branch reflects the production-ready state. Feature branches are used for all development work. + + +## Project Directives + +1. Respect risk boundaries: High-risk changes: modifications to startup scripts, Sysbox runtime configuration, Docker daemon setup, or base image layers — these affect all workspaces. Medium-risk: template variable changes or new templates. Low-risk: documentation, Makefile targets, version bumps. Any change that affects running workspaces requires staging validation. + +2. Keep documentation synchronized with workflow and behavior changes. + +## Reference Index + +| Reference ID | Kind | Summary | Local Doc | +|---|---|---|---| +| `USER:PROJECT_PROFILE` | user_profile | Project-specific interview answers captured for charter compilation. | `_LIBRARY/user-project-profile.md` | +| `TEMPLATE_SET:software-dev-default` | template_set | Build high-quality software with structured workflows and test-driven development | `_LIBRARY/template-set-software-dev-default.md` | + +## Amendment Process + +Charter amendments follow the same PR process as code changes. Significant governance changes should be discussed in the PR description. + + +## Exception Policy + +Hotfixes for production incidents may bypass staging testing with explicit maintainer acknowledgment in the PR, but must still pass CI. + diff --git a/.kittify/charter/interview/answers.yaml b/.kittify/charter/interview/answers.yaml new file mode 100644 index 0000000..333c05e --- /dev/null +++ b/.kittify/charter/interview/answers.yaml @@ -0,0 +1,79 @@ +schema_version: "1.0.0" +mission: "software-dev" +profile: "comprehensive" +answers: + project_intent: > + Manage and deploy coder.ddev.com — a cloud-hosted DDEV environment for + web developers. The project owns the Coder workspace templates (Terraform HCL), + the base Docker image, and the supporting shell scripts that enable + Docker-in-Docker development via Sysbox runtime. A breaking change means + developers cannot create or use workspaces; risk level is high for end users + who depend on the service. + + languages_frameworks: > + Terraform (HCL), Shell (Bash), Dockerfile (Ubuntu 24.04 base), + bats-core (BATS test framework for shell-level integration tests), + Go toolchain (available in image for future use). + + testing_requirements: > + Integration tests are BATS scripts that run against a live staging Coder + instance (staging-coder.ddev.com) before any deployment to production. + Plan-level tests use `terraform test` (no real infrastructure required). + CI also runs `terraform fmt -check -recursive` and `terraform validate` + for each touched template. There is no unit-test coverage percentage target — + correctness is verified by staging promotion. + + quality_gates: > + All changes require a pull request. CI must pass before merge. + CI gates: `terraform fmt -check`, `terraform validate`, `terraform test` + for each template. Integration test scripts run against staging before + promoting to production. No direct commits to main. + + review_policy: > + Every change requires a pull request. Single maintainer project currently, + but PRs still required for traceability and CI gating. Conventional commit + messages are preferred. + + performance_targets: > + No quantitative latency targets. Workspace startup should complete within + a reasonable time (under 5 minutes) as a qualitative target. CLI commands + (terraform, make) should not timeout during CI runs. + + deployment_constraints: > + Two environments: staging-coder.ddev.com and production coder.ddev.com. + Templates are promoted staging → production only after integration tests + pass on staging. The main branch reflects the production-ready state. + Feature branches are used for all development work. + + documentation_policy: > + User-facing documentation lives in /docs/. CLAUDE.md documents developer + and contributor guidance. Changes to template behavior or CLI commands + must be reflected in docs before merge. Doc-only changes are low-risk + but still require PRs. + + risk_boundaries: > + High-risk changes: modifications to startup scripts, Sysbox runtime + configuration, Docker daemon setup, or base image layers — these affect + all workspaces. Medium-risk: template variable changes or new templates. + Low-risk: documentation, Makefile targets, version bumps. + Any change that affects running workspaces requires staging validation. + + amendment_process: > + Charter amendments follow the same PR process as code changes. + Significant governance changes should be discussed in the PR description. + + exception_policy: > + Hotfixes for production incidents may bypass staging testing with explicit + maintainer acknowledgment in the PR, but must still pass CI. + +selected_paradigms: [] + +selected_directives: [] + +available_tools: + - git + - spec-kitty + - terraform + - docker + - make + - bats From e69728a043727fa2af662789207162819705bd50 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:00:31 -0600 Subject: [PATCH 02/53] Add spec for feature github-org-gated-signup-01KR1P4G --- kitty-specs/github-org-gated-signup-01KR1P4G/spec.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/spec.md diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md new file mode 100644 index 0000000..e69de29 From c630c2b96bc3bc06814e4d816e07937bf39d6866 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:00:31 -0600 Subject: [PATCH 03/53] Add meta for feature github-org-gated-signup-01KR1P4G --- kitty-specs/github-org-gated-signup-01KR1P4G/meta.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/meta.json diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json b/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json new file mode 100644 index 0000000..db24b03 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json @@ -0,0 +1,10 @@ +{ + "created_at": "2026-05-07T17:00:31.394646+00:00", + "friendly_name": "github org gated signup", + "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", + "mission_number": null, + "mission_slug": "github-org-gated-signup-01KR1P4G", + "mission_type": "software-dev", + "slug": "github-org-gated-signup-01KR1P4G", + "target_branch": "20260507_speckitty" +} From 2a09a3c2ebddc8a437df12a5ed5550633bcd2673 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:01:52 -0600 Subject: [PATCH 04/53] feat(spec): specify GitHub org-gated signup for coder.ddev.com Closes #64. References #54. Co-Authored-By: Claude Sonnet 4.6 --- .../checklists/requirements.md | 38 ++++++ .../meta.json | 6 +- .../github-org-gated-signup-01KR1P4G/spec.md | 112 ++++++++++++++++++ .../status.events.jsonl | 0 .../tasks/.gitkeep | 0 .../tasks/README.md | 64 ++++++++++ 6 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/checklists/requirements.md create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/tasks/.gitkeep create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/tasks/README.md diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/checklists/requirements.md b/kitty-specs/github-org-gated-signup-01KR1P4G/checklists/requirements.md new file mode 100644 index 0000000..f6d0728 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/checklists/requirements.md @@ -0,0 +1,38 @@ +# Specification Quality Checklist: GitHub Org-Gated Signup + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: 2026-05-07 +**Feature**: [spec.md](../spec.md) + +## Content Quality + +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Requirement types are separated (Functional / Non-Functional / Constraints) +- [x] IDs are unique across FR-###, NFR-###, and C-### entries +- [x] All requirement rows include a non-empty Status value +- [x] Non-functional requirements include measurable thresholds +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +All items pass. Spec is ready for `/spec-kitty.plan`. diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json b/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json index db24b03..1151b84 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json @@ -1,10 +1,12 @@ { "created_at": "2026-05-07T17:00:31.394646+00:00", - "friendly_name": "github org gated signup", + "friendly_name": "GitHub Org-Gated Signup", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_number": null, "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", "slug": "github-org-gated-signup-01KR1P4G", - "target_branch": "20260507_speckitty" + "source_description": "Restrict new account creation on coder.ddev.com and staging-coder.ddev.com to members of the ddev and coder-ddev-com GitHub organizations. References issues #64 and #54.", + "target_branch": "20260507_speckitty", + "vcs": "git" } diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md index e69de29..e886826 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md @@ -0,0 +1,112 @@ +# GitHub Org-Gated Signup + +## Summary + +Currently, anyone with a GitHub account can create a Coder account on coder.ddev.com and spin up unlimited workspaces. This is unsustainable and represents a direct cost and security risk to the service. This feature restricts new account signups to members of two GitHub organizations — the existing `ddev` org and a new `coder-ddev-com` org created specifically as a managed access list — while keeping existing user accounts and password authentication intact. + +**Related issues:** [#64 User creation and authentication control](https://github.com/ddev/coder-ddev/issues/64), [#54 Offer additional login options](https://github.com/ddev/coder-ddev/issues/54) + +--- + +## Goals + +- Prevent arbitrary GitHub users from self-registering on coder.ddev.com or staging-coder.ddev.com. +- Allow all members of the `ddev` GitHub org to sign in and create workspaces. +- Allow all members of the `coder-ddev-com` GitHub org to sign in and create workspaces. +- Preserve access for users who already have accounts on coder.ddev.com. +- Maintain an emergency escape hatch: manually-provisioned accounts using password authentication must remain usable. +- Retain full DDEV ownership of OAuth credentials (no data sharing with Coder the company). + +## Non-Goals + +- No password authentication is added for new users. The existing password auth path is preserved only for pre-created exception accounts. +- No OIDC, GitLab, or other providers are added as part of this change. +- No changes to workspace templates, Docker images, or resource limits. + +--- + +## User Scenarios & Testing + +**Scenario 1 — ddev org member signs up (happy path):** +A developer who is a public member of the `ddev` GitHub org visits coder.ddev.com, clicks "Sign in with GitHub," authorizes the OAuth app, and lands on the Coder dashboard. Account is created automatically. + +**Scenario 2 — coder-ddev-com org member signs up:** +A developer who has been added to the `coder-ddev-com` GitHub org visits coder.ddev.com, clicks "Sign in with GitHub," and successfully creates an account. + +**Scenario 3 — unauthorized GitHub user is rejected:** +A GitHub user who is not a member of either `ddev` or `coder-ddev-com` attempts to sign in. They see an error message indicating they are not authorized. No account is created. + +**Scenario 4 — existing user retains access:** +A user who already has a coder.ddev.com account (created before this change) logs in via GitHub OAuth or password auth and accesses their workspaces without disruption. + +**Scenario 5 — exception account via password:** +An admin pre-creates a user account with a password credential. That user logs in without GitHub OAuth. This path continues to work because `CODER_DISABLE_PASSWORD_AUTH` is never set to `true`. + +**Scenario 6 — staging parity:** +The same org-restriction configuration is applied to staging-coder.ddev.com, so staging behavior accurately reflects production before promotion. + +--- + +## Functional Requirements + +| ID | Requirement | Status | +| ---- | ------------- | -------- | +| FR-001 | New GitHub OAuth signups are restricted to members of the `ddev` GitHub org and the `coder-ddev-com` GitHub org. Users outside both orgs cannot create accounts. | Approved | +| FR-002 | The `coder-ddev-com` GitHub org exists and can have members added to grant access without requiring `ddev` org membership. | Approved | +| FR-003 | Existing user accounts on coder.ddev.com remain active and accessible after the restriction is applied. | Approved | +| FR-004 | Password-based login remains available for manually-provisioned accounts. Password auth is never globally disabled. | Approved | +| FR-005 | Both staging-coder.ddev.com and coder.ddev.com have identical org-restriction configuration. | Approved | +| FR-006 | A custom DDEV-owned GitHub OAuth App is registered and used for authentication, replacing the default Coder-provided app. | Approved | +| FR-007 | The OAuth App is registered under the `ddev` GitHub organization so credentials are DDEV-controlled, not held by an individual account. | Approved | +| FR-008 | Authorized users from both orgs can create and use workspaces on both environments. | Approved | +| FR-009 | An operator runbook documents how to add a user to the `coder-ddev-com` org and how to pre-create exception accounts with password credentials. | Approved | + +--- + +## Non-Functional Requirements + +| ID | Requirement | Threshold | Status | +| ---- | ------------- | ----------- | -------- | +| NFR-001 | Authorized users experience no increase in login time after the change. | Sign-in round-trip completes within the same time as before (under 10 seconds on a normal connection). | Approved | +| NFR-002 | The org membership check does not require users to make their org membership public. | Private `ddev` or `coder-ddev-com` org membership must be sufficient for login. | Approved | +| NFR-003 | Applying the configuration change causes zero downtime for existing active sessions. | No active workspace sessions are interrupted during config rollout. | Approved | + +--- + +## Constraints + +| ID | Constraint | Status | +| ---- | ---------- | -------- | +| C-001 | `CODER_DISABLE_PASSWORD_AUTH` must never be set to `true`. Password auth must remain available for exception accounts. | Approved | +| C-002 | The `coder-ddev-com` GitHub org must be a real GitHub organization (not a personal account) so membership can be managed by multiple org owners. | Approved | +| C-003 | The custom GitHub OAuth App must request at minimum: `read:user`, `user:email`, and `read:org` scopes. The `read:org` scope is required for Coder to verify org membership. | Approved | +| C-004 | The change must be applied to staging first and validated before applying to production. | Approved | +| C-005 | OAuth App credentials (client ID and client secret) must be stored as server-level secrets, not committed to the repository. | Approved | + +--- + +## Success Criteria + +1. A GitHub user who is not in `ddev` or `coder-ddev-com` cannot create an account on coder.ddev.com. +2. All current members of the `ddev` org can sign in to coder.ddev.com without any manual step beyond GitHub OAuth. +3. An admin can grant access to a new non-ddev-org user by adding them to `coder-ddev-com`, with no Coder server change required. +4. At least one pre-existing user account continues to function after the rollout (no accounts locked out). +5. Staging-coder.ddev.com and coder.ddev.com enforce the same restriction after both are reconfigured. + +--- + +## Assumptions + +- The `coder-ddev-com` GitHub organization does not yet exist and must be created before configuration is applied. +- The current Coder server deployment on both environments exposes environment variables that can be updated without rebuilding images. +- Coder's org membership check works with private org membership when the `read:org` scope is granted — users do not need to publicize their org membership. +- The GitHub OAuth App will be registered under the `ddev` org (not a personal account), so ownership is institutional. + +--- + +## Out of Scope + +- Automating `coder-ddev-com` membership management (e.g., via a bot or form). +- Removing or migrating existing user accounts. +- Implementing GitLab, OIDC, or any other auth provider. +- Rate limiting, abuse prevention, or workspace quota enforcement (separate concern from issue #64's unlimited workspace problem). diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl new file mode 100644 index 0000000..e69de29 diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/.gitkeep b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/README.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/README.md new file mode 100644 index 0000000..5757bd0 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/README.md @@ -0,0 +1,64 @@ +# Tasks Directory + +This directory contains work package (WP) prompt files. + +## Directory Structure (v0.9.0+) + +``` +tasks/ +├── WP01-setup-infrastructure.md +├── WP02-user-authentication.md +├── WP03-api-endpoints.md +└── README.md +``` + +All WP files are stored flat in `tasks/`. Status is tracked in `status.events.jsonl`, not in WP frontmatter. + +## Work Package File Format + +Each WP file **MUST** use YAML frontmatter: + +```yaml +--- +work_package_id: "WP01" +title: "Work Package Title" +dependencies: [] +planning_base_branch: "20260507_speckitty" +merge_target_branch: "20260507_speckitty" +branch_strategy: "Planning artifacts were generated on 20260507_speckitty; completed changes must merge back into 20260507_speckitty." +subtasks: + - "T001" + - "T002" +phase: "Phase 1 - Setup" +assignee: "" +agent: "" +shell_pid: "" +history: + - timestamp: "2025-01-01T00:00:00Z" + agent: "system" + action: "Prompt generated via /spec-kitty.tasks" +--- + +# Work Package Prompt: WP01 – Work Package Title + +[Content follows...] +``` + +## Status Tracking + +Status is tracked via the canonical event log (`status.events.jsonl`), not in WP frontmatter. +Use `spec-kitty agent tasks move-task` to change WP status: + +```bash +spec-kitty agent tasks move-task --to +``` + +Example: +```bash +spec-kitty agent tasks move-task WP01 --to doing +``` + +## File Naming + +- Format: `WP01-kebab-case-slug.md` +- Examples: `WP01-setup-infrastructure.md`, `WP02-user-auth.md` From 9794dbc8d37661c59ea5e9109345350bd1e5785a Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:05:07 -0600 Subject: [PATCH 05/53] chore: commit spec-kitty init artifacts and CI drupal-contrib addition Co-Authored-By: Claude Sonnet 4.6 --- .claudeignore | 58 ++++ .gitattributes | 1 + .gitignore | 29 ++ .kittify/config.yaml | 11 + .../memory/templates/POWERSHELL_SYNTAX.md | 245 +++++++++++++++ .kittify/metadata.yaml | 14 + .kittify/skills-manifest.json | 288 ++++++++++++++++++ 7 files changed, 646 insertions(+) create mode 100644 .claudeignore create mode 100644 .gitattributes create mode 100644 .kittify/config.yaml create mode 100644 .kittify/memory/templates/POWERSHELL_SYNTAX.md create mode 100644 .kittify/metadata.yaml create mode 100644 .kittify/skills-manifest.json diff --git a/.claudeignore b/.claudeignore new file mode 100644 index 0000000..5391107 --- /dev/null +++ b/.claudeignore @@ -0,0 +1,58 @@ +# Spec Kitty Configuration and Templates +# These are internal directories that shouldn't be scanned by AI assistants + +# Template directories (not working code) +.kittify/templates/ +.kittify/missions/ +.kittify/scripts/ + +# Agent command directories (generated from templates, not source) +.claude/ +.codex/ +.gemini/ +.cursor/ +.qwen/ +.opencode/ +.windsurf/ +.kilocode/ +.augment/ +.roo/ +.amazonq/ +.github/copilot/ + +# Git metadata +.git/ + +# Build artifacts and caches +__pycache__/ +*.pyc +*.pyo +.pytest_cache/ +.coverage +htmlcov/ +node_modules/ +dist/ +build/ +*.egg-info/ + +# Virtual environments +.venv/ +venv/ +env/ + +# OS-specific files +.DS_Store +Thumbs.db +desktop.ini + +# IDE directories +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Logs and databases +*.log +*.db +*.sqlite diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..07ef88a --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +kitty-specs/**/status.events.jsonl merge=spec-kitty-event-log diff --git a/.gitignore b/.gitignore index 7c5d86a..ba14d7f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,32 @@ __pycache__/ # Temp files composer.json.tmp + +# Added by Spec Kitty CLI (auto-managed) +.claude/ +.codex/ +.vibe/ +.opencode/ +.windsurf/ +.gemini/ +.cursor/ +.qwen/ +.kilocode/ +.augment/ +.roo/ +.amazonq/ +.kiro/ +.agent/ +.github/copilot/ +.kittify/.dashboard +.kittify/charter/context-state.json +.kittify/charter/directives.yaml +.kittify/charter/governance.yaml +.kittify/charter/metadata.yaml +.kittify/charter/references.yaml +.kittify/dossiers/ +.kittify/events/ +.kittify/merge-state.json +.kittify/missions/__pycache__/ +.kittify/runtime/ +.kittify/workspaces/ diff --git a/.kittify/config.yaml b/.kittify/config.yaml new file mode 100644 index 0000000..f8e6581 --- /dev/null +++ b/.kittify/config.yaml @@ -0,0 +1,11 @@ +vcs: + type: git +agents: + available: + - claude + auto_commit: true +project: + uuid: 595dcc83-8eee-4a87-8644-84d94a4b531c + slug: coder-ddev + node_id: a1b8182ad705 + build_id: ea439b9d-ce91-4e8c-a458-0f28a54b80bc diff --git a/.kittify/memory/templates/POWERSHELL_SYNTAX.md b/.kittify/memory/templates/POWERSHELL_SYNTAX.md new file mode 100644 index 0000000..a2f1d2d --- /dev/null +++ b/.kittify/memory/templates/POWERSHELL_SYNTAX.md @@ -0,0 +1,245 @@ +# PowerShell Syntax Guide for AI Agents + +**⚠️ READ THIS if you are working in a PowerShell environment** + +This guide helps AI agents use correct PowerShell syntax when working with spec-kitty workflows. + +--- + +## Quick Reference: Bash vs PowerShell + +| Task | ❌ Bash (WRONG) | ✅ PowerShell (CORRECT) | +|------|-----------------|-------------------------| +| **Command chaining** | `cmd1 && cmd2` | `cmd1; cmd2` | +| **Parameter flags** | `--json --paths-only` | `-Json -PathsOnly` | +| **Script path** | `./scripts/bash/script.sh` | `..\scripts\powershell\Script.ps1` | +| **Environment variable** | `$VAR_NAME` | `$env:VAR_NAME` | +| **Current directory** | `pwd` | `Get-Location` (or `pwd` alias) | +| **List files** | `ls -la` | `Get-ChildItem` (or `ls` alias) | +| **File exists check** | `[ -f file.txt ]` | `Test-Path file.txt` | +| **Directory separator** | `/path/to/file` | `\path\to\file` | +| **Home directory** | `~/projects` | `$HOME\projects` | + +--- + +## Location Verification (PowerShell) + +**Check your current location:** + +```powershell +Get-Location +git branch --show-current +``` + +**Expected for mission worktrees:** + +- Location: `C:\Users\...\project\.worktrees\001-mission-name` +- Branch: `001-mission-name` (NOT `main`) + +--- + +## Running Spec-Kitty Commands (PowerShell) + +### Using the spec-kitty CLI + +Spec-kitty uses a Python CLI that works across all platforms: + +**Common commands:** + +- `spec-kitty agent mission create-mission ` - Create a new feature +- `spec-kitty verify-setup` - Check environment and paths +- `spec-kitty agent workflow implement --agent ` - Start implementing a work package +- `spec-kitty agent workflow review --agent ` - Start reviewing a work package +- `spec-kitty agent tasks move-task --to for_review` - Complete implementation (move to review) +- `spec-kitty merge` - Merge completed mission + +### Parameter Naming Convention + +PowerShell uses **PascalCase** with leading dash: + +- `-Json` (not `--json`) +- `-MissionName` (not `--mission-name`) +- `-IncludeTasks` (not `--include-tasks`) +- `-RequireTasks` (not `--require-tasks`) + +### Examples + +**Create feature:** + +```powershell +.\.kittify\scripts\powershell\Create-NewMission.ps1 ` + -MissionName "User Authentication" ` + -FeatureDescription "Add login and registration" +``` + +**Check prerequisites:** + +```powershell +.\.kittify\scripts\powershell\check-prerequisites.ps1 -Json -IncludeTasks +``` + +**Move task to review (after implementation):** + +```powershell +# Using the CLI (recommended): +spec-kitty agent tasks move-task WP01 --to for_review --note "Ready for review" + +# Or using PowerShell script: +.\.kittify\scripts\powershell\Move-TaskToLane.ps1 ` + -Feature "001-auth" ` + -TaskId "WP01" ` + -Lane "for_review" ` + -ShellPid $PID ` + -Agent "claude" +``` + +--- + +## Common Mistakes to Avoid + +### ❌ Don't Use Bash Operators + +```powershell +# WRONG: +cd worktrees && pwd + +# CORRECT: +cd worktrees; Get-Location +``` + +### ❌ Don't Use Bash-Style Parameters + +```powershell +# WRONG: +.\check-prerequisites.ps1 --json --require-tasks + +# CORRECT: +.\check-prerequisites.ps1 -Json -RequireTasks +``` + +### Path Separators in PowerShell + +PowerShell on Windows uses backslashes for native paths: + +```powershell +# WRONG (Unix-style paths on Windows): +cd ./.kittify/memory + +# CORRECT (Windows-style paths): +cd .\.kittify\memory +``` + +Note: Git commands work with forward slashes, but native PowerShell file operations expect backslashes. The spec-kitty CLI handles this automatically. + +--- + +## Environment Variables + +**Setting variables:** + +```powershell +$env:SPEC_KITTY_TEMPLATE_ROOT = "C:\path\to\spec-kitty" +``` + +**Reading variables:** + +```powershell +echo $env:SPEC_KITTY_TEMPLATE_ROOT +``` + +**Checking if set:** + +```powershell +if ($env:SPEC_KITTY_TEMPLATE_ROOT) { + Write-Host "Variable is set" +} +``` + +--- + +## File Operations + +**Check if file exists:** + +```powershell +if (Test-Path "spec.md") { + Write-Host "Spec exists" +} +``` + +**Read file:** + +```powershell +$content = Get-Content "spec.md" -Raw +``` + +**Create directory:** + +```powershell +New-Item -ItemType Directory -Path "tasks\planned" -Force +``` + +--- + +## Workflow Tips + +1. **Always use full parameter names** in scripts (not abbreviations) +2. **Use semicolons** to chain commands, not `&&` or `||` +3. **Backslashes** for local paths, forward slashes OK for git operations +4. **$PID** contains current PowerShell process ID (use for --shell-pid) +5. **Tab completion** works for parameter names in PowerShell + +--- + +## When to Use What + +**Use PowerShell scripts when:** + +- User specified `--script ps` during init +- You're in a Windows PowerShell terminal +- Templates reference `.ps1` files in frontmatter + +**Use Bash scripts when:** + +- User specified `--script sh` during init +- You're in bash/zsh/fish terminal +- Templates reference `.sh` files in frontmatter + +**Using spec-kitty commands:** +All spec-kitty commands work the same way on PowerShell and Bash: + +```powershell +spec-kitty agent workflow implement WP01 --agent claude # Auto-moves to doing +spec-kitty agent tasks move-task WP01 --to for_review # Completion step +spec-kitty verify-setup +spec-kitty dashboard +``` + +The CLI is cross-platform and handles path differences automatically. + +--- + +## Debugging PowerShell Issues + +**Common errors and solutions:** + +1. **"Parameter cannot be found that matches parameter name"** + - You used bash-style parameters (`--json`) + - Fix: Use PowerShell style (`-Json`) + +2. **"The term '&&' is not recognized"** + - You used bash command chaining + - Fix: Use semicolon (`;`) instead + +3. **"Cannot find path"** + - You used forward slashes in PowerShell path + - Fix: Use backslashes (`\`) for local paths + +4. **"Unable to import mission module"** + - Python can't find specify_cli package + - Check: `pip show spec-kitty-cli` + - Fix: Reinstall or check virtual environment + +--- + +**For full spec-kitty documentation, see the main templates and README.** diff --git a/.kittify/metadata.yaml b/.kittify/metadata.yaml new file mode 100644 index 0000000..1863372 --- /dev/null +++ b/.kittify/metadata.yaml @@ -0,0 +1,14 @@ +# Spec Kitty Project Metadata +# Auto-generated by spec-kitty init/upgrade +# DO NOT EDIT MANUALLY + +spec_kitty: + version: 3.1.8 + initialized_at: '2026-05-07T10:43:17.519511' + last_upgraded_at: null +environment: + python_version: 3.14.4 + platform: darwin + platform_version: macOS-26.4.1-arm64-arm-64bit-Mach-O +migrations: + applied: [] diff --git a/.kittify/skills-manifest.json b/.kittify/skills-manifest.json new file mode 100644 index 0000000..5a35257 --- /dev/null +++ b/.kittify/skills-manifest.json @@ -0,0 +1,288 @@ +{ + "version": 1, + "created_at": "2026-05-07T16:43:17.476272+00:00", + "updated_at": "2026-05-07T16:43:17.506903+00:00", + "spec_kitty_version": "3.1.8", + "entries": [ + { + "skill_name": "ad-hoc-profile-load", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/ad-hoc-profile-load/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:85acce1cc660cdec6f0fe8fd669d82b393572d9c5cda561ffd17df3f7b59fc5e", + "installed_at": "2026-05-07T16:43:17.480986+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-bulk-edit-classification", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-bulk-edit-classification/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:30e444e44afc5db2b44c8a57627f9f69537816d8c7c9fea7049efed71cdd410e", + "installed_at": "2026-05-07T16:43:17.482823+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-charter-doctrine", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-charter-doctrine/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:c46f7804b175a3e185bf7d22f792bd80b1e67f798d8f9fc40ee58964838e1da0", + "installed_at": "2026-05-07T16:43:17.485117+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-charter-doctrine", + "source_file": "references/charter-command-map.md", + "installed_path": ".claude/skills/spec-kitty-charter-doctrine/references/charter-command-map.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:8d2cccd8dc727cb9ba78c2e9bf3559e83cdf93d6a632970254c9ae6b8b5733db", + "installed_at": "2026-05-07T16:43:17.485117+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-charter-doctrine", + "source_file": "references/doctrine-artifact-structure.md", + "installed_path": ".claude/skills/spec-kitty-charter-doctrine/references/doctrine-artifact-structure.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:f771e9e9e98d65aa4380b94e3f6a24e08d6c2cd3ca44ca1cba3bd14283af9f17", + "installed_at": "2026-05-07T16:43:17.485117+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-git-workflow", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-git-workflow/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:631f90114af7e9d108a58741af46dcd08163f3a814cbb9d95c905c19d337cc60", + "installed_at": "2026-05-07T16:43:17.487395+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-git-workflow", + "source_file": "references/git-operations-matrix.md", + "installed_path": ".claude/skills/spec-kitty-git-workflow/references/git-operations-matrix.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:6bb45291ff5ce626eaadde3a6e4a4c8d69577b3c4698c4551d251f293c66bfaa", + "installed_at": "2026-05-07T16:43:17.487395+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-glossary-context", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-glossary-context/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:e9592a088d2d6d2e2ecf65eaa6a8d31f0dbe1e6f4236d5747d6fe26ea980e89e", + "installed_at": "2026-05-07T16:43:17.489912+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-glossary-context", + "source_file": "references/glossary-field-guide.md", + "installed_path": ".claude/skills/spec-kitty-glossary-context/references/glossary-field-guide.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:9cddfccd64773976cf97450fa983dc8cc3aa7354a6002d763a7fa3ac65ff9ace", + "installed_at": "2026-05-07T16:43:17.489912+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-glossary-context", + "source_file": "references/semantic-drift-examples.md", + "installed_path": ".claude/skills/spec-kitty-glossary-context/references/semantic-drift-examples.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:d2df36b399316d12d05b10b36dab19a3eb330ed9c502b9b0fa2bb35ecf8341c4", + "installed_at": "2026-05-07T16:43:17.489912+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-implement-review", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-implement-review/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:6977839d92e84b4fb5da00e1c665003a95ead5fba92eaa9254ec78d074842f98", + "installed_at": "2026-05-07T16:43:17.492386+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-implement-review", + "source_file": "references/agent-dispatch-matrix.md", + "installed_path": ".claude/skills/spec-kitty-implement-review/references/agent-dispatch-matrix.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:94a2ddfb52a2b1da85e286221e580fd49d94cbb4e2a716fe02f4b76897c30ed0", + "installed_at": "2026-05-07T16:43:17.492386+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-implement-review", + "source_file": "references/rejection-loop-checklist.md", + "installed_path": ".claude/skills/spec-kitty-implement-review/references/rejection-loop-checklist.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:dcf6ffa8a173a5ea937a74fd1af4c0427f595008a00d91b5a7970a13f2e202ab", + "installed_at": "2026-05-07T16:43:17.492386+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-mission-review", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-mission-review/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:45ba9f04c2b9b337b7c27249a9779eb8613c0450ddd46adb12c11c02eaa80b5f", + "installed_at": "2026-05-07T16:43:17.494574+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-mission-review", + "source_file": "references/mission-review-fr-trace-guide.md", + "installed_path": ".claude/skills/spec-kitty-mission-review/references/mission-review-fr-trace-guide.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:4ae2391cd2e4c3bdb32a25e7a8476612fb1b94d156a4250701c9f537e011f0fd", + "installed_at": "2026-05-07T16:43:17.494574+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-mission-system", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-mission-system/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:b0172954384382df472ae94ae8754d1d98621530e1ae41336c1883a2827aafd0", + "installed_at": "2026-05-07T16:43:17.496533+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-mission-system", + "source_file": "references/mission-comparison-matrix.md", + "installed_path": ".claude/skills/spec-kitty-mission-system/references/mission-comparison-matrix.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:068063581aa360dcf114b32b65b31531367d4a7feacca7d607685a3862bfa3f4", + "installed_at": "2026-05-07T16:43:17.496533+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-orchestrator-api-operator", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-orchestrator-api-operator/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:750b35e440410841c41d811f26a59a3838b03458ff595b01ba594e9997ed2dd0", + "installed_at": "2026-05-07T16:43:17.499018+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-orchestrator-api-operator", + "source_file": "references/host-boundary-rules.md", + "installed_path": ".claude/skills/spec-kitty-orchestrator-api-operator/references/host-boundary-rules.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:fa806c1d0a1446b54ae589ea00f3edc55495bfaf43f801c90ca0872380e77fb0", + "installed_at": "2026-05-07T16:43:17.499018+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-orchestrator-api-operator", + "source_file": "references/orchestrator-api-contract.md", + "installed_path": ".claude/skills/spec-kitty-orchestrator-api-operator/references/orchestrator-api-contract.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:be5c0536a854771ace6c89db4e7b2f96c5f96e1f9a126f8a088941c1088c3a2d", + "installed_at": "2026-05-07T16:43:17.499018+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-runtime-next", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-runtime-next/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:4556cc9de0c88cf4b3b301b23b51deb39ed1338eecd5ee858988042d9dcc78aa", + "installed_at": "2026-05-07T16:43:17.501463+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-runtime-next", + "source_file": "references/blocked-state-recovery.md", + "installed_path": ".claude/skills/spec-kitty-runtime-next/references/blocked-state-recovery.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:787304873d5e8e254ea90ffd81e5af9d8d3c859a0688c7431f40fe4a3c20aa59", + "installed_at": "2026-05-07T16:43:17.501463+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-runtime-next", + "source_file": "references/runtime-result-taxonomy.md", + "installed_path": ".claude/skills/spec-kitty-runtime-next/references/runtime-result-taxonomy.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:80365f9eca8f07cd96a85aad55247707e90765caddc24037f1a60de4053df2fe", + "installed_at": "2026-05-07T16:43:17.501463+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-runtime-review", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-runtime-review/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:fd994f73054a11e98de7871526ea96df6e580e22e21a3b51d928498aaca02d6a", + "installed_at": "2026-05-07T16:43:17.503446+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-runtime-review", + "source_file": "references/review-checklist.md", + "installed_path": ".claude/skills/spec-kitty-runtime-review/references/review-checklist.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:9279016c3b96e71fbd5d06cbaedf719307fd4497afe1673af7a613a4e38b93ab", + "installed_at": "2026-05-07T16:43:17.503446+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-setup-doctor", + "source_file": "SKILL.md", + "installed_path": ".claude/skills/spec-kitty-setup-doctor/SKILL.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:8fb297bcb646a41abb0b8a024d842a956297ab12366bc6285a5bcacb880c6fb7", + "installed_at": "2026-05-07T16:43:17.506324+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-setup-doctor", + "source_file": "references/agent-path-matrix.md", + "installed_path": ".claude/skills/spec-kitty-setup-doctor/references/agent-path-matrix.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:6128bd3a1994467c24c168b9b998aa0b7c0d31a5f112c12aff4bebc5915416ff", + "installed_at": "2026-05-07T16:43:17.506324+00:00", + "delivery_mode": "symlink" + }, + { + "skill_name": "spec-kitty-setup-doctor", + "source_file": "references/common-failure-signatures.md", + "installed_path": ".claude/skills/spec-kitty-setup-doctor/references/common-failure-signatures.md", + "installation_class": "native-root-required", + "agent_key": "claude", + "content_hash": "sha256:fc5ccc9248a290f23507556d6cd25e2c38a63f8cba4cf4f40897735fd489198f", + "installed_at": "2026-05-07T16:43:17.506324+00:00", + "delivery_mode": "symlink" + } + ] +} From 18e9a423c3601fbc00921fd753b6aa6187714eed Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:10:44 -0600 Subject: [PATCH 06/53] revert validate.yml change that belongs in another worktree --- .github/workflows/validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 99012bd..63c599d 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - template: [user-defined-web, drupal-core, drupal-contrib, freeform] + template: [user-defined-web, drupal-core, freeform] fail-fast: false steps: - uses: actions/checkout@v6 From e6ae58d06533354871c7bc7b8883dc15c60f7345 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:21:32 -0600 Subject: [PATCH 07/53] Add plan for feature github-org-gated-signup-01KR1P4G --- .../github-org-gated-signup-01KR1P4G/plan.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/plan.md diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md new file mode 100644 index 0000000..bc59470 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md @@ -0,0 +1,108 @@ +# Implementation Plan: [FEATURE] +*Path: [templates/plan-template.md](templates/plan-template.md)* + + +**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link] +**Input**: Feature specification from `/kitty-specs/[###-feature-name]/spec.md` + +**Note**: This template is filled in by the `/spec-kitty.plan` command. See `src/specify_cli/missions/software-dev/command-templates/plan.md` for the execution workflow. + +The planner will not begin until all planning questions have been answered—capture those answers in this document before progressing to later phases. + +## Summary + +[Extract from feature spec: primary requirement + technical approach from research] + +## Technical Context + + + +**Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] +**Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] +**Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] +**Testing**: [Project-specific test approach or NEEDS CLARIFICATION] +**Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] +**Project Type**: [single/web/mobile - determines source structure] +**Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] +**Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] +**Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] + +## Charter Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +[Gates determined based on charter file] + +## Project Structure + +### Documentation (this feature) + +``` +kitty-specs/[###-feature]/ +├── plan.md # This file (/spec-kitty.plan command output) +├── research.md # Phase 0 output (/spec-kitty.plan command) +├── data-model.md # Phase 1 output (/spec-kitty.plan command) +├── quickstart.md # Phase 1 output (/spec-kitty.plan command) +├── contracts/ # Phase 1 output (/spec-kitty.plan command) +└── tasks.md # Phase 2 output (/spec-kitty.tasks command - NOT created by /spec-kitty.plan) +``` + +### Source Code (repository root) + + +``` +# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) +src/ +├── models/ +├── services/ +├── cli/ +└── lib/ + +tests/ +├── contract/ +├── integration/ +└── unit/ + +# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) +backend/ +├── src/ +│ ├── models/ +│ ├── services/ +│ └── api/ +└── tests/ + +frontend/ +├── src/ +│ ├── components/ +│ ├── pages/ +│ └── services/ +└── tests/ + +# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) +api/ +└── [same as backend above] + +ios/ or android/ +└── [platform-specific structure: feature modules, UI flows, platform tests] +``` + +**Structure Decision**: [Document the selected structure and reference the real +directories captured above] + +## Complexity Tracking + +*Fill ONLY if Charter Check has violations that must be justified* + +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | +| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | From 8fa7b05090defc0ce61697614317112e53446139 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:24:47 -0600 Subject: [PATCH 08/53] feat(plan): add implementation plan and research for github-org-gated-signup Co-Authored-By: Claude Sonnet 4.6 --- .../github-org-gated-signup-01KR1P4G/plan.md | 161 +++++++++--------- .../research.md | 72 ++++++++ 2 files changed, 151 insertions(+), 82 deletions(-) create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/research.md diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md index bc59470..2726246 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md @@ -1,108 +1,105 @@ -# Implementation Plan: [FEATURE] -*Path: [templates/plan-template.md](templates/plan-template.md)* +# Implementation Plan: GitHub Org-Gated Signup +**Branch**: `20260507_speckitty` | **Date**: 2026-05-07 | **Spec**: [spec.md](spec.md) -**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link] -**Input**: Feature specification from `/kitty-specs/[###-feature-name]/spec.md` +**Branch contract**: Planning base `20260507_speckitty` → merge target `20260507_speckitty`. -**Note**: This template is filled in by the `/spec-kitty.plan` command. See `src/specify_cli/missions/software-dev/command-templates/plan.md` for the execution workflow. - -The planner will not begin until all planning questions have been answered—capture those answers in this document before progressing to later phases. +--- ## Summary -[Extract from feature spec: primary requirement + technical approach from research] +Restrict new account signups on coder.ddev.com and staging-coder.ddev.com to members of the `ddev` and `coder-ddev-com` GitHub organizations. The Coder server is deployed via the apt deb package and managed by systemd; its runtime configuration lives in `/etc/coder.d/coder.env` on the server host (not committed to this repo). The docs in this repo (`docs/admin/server-setup.md`, `docs/admin/user-management.md`) are the authoritative operator reference and will be updated to reflect the new configuration. Two separate GitHub OAuth Apps (one per environment) will be registered under the `ddev` GitHub org for credential isolation. The `coder-ddev-com` GitHub org will be created as the managed access list for non-ddev-org users. + +--- ## Technical Context - - -**Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] -**Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] -**Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] -**Testing**: [Project-specific test approach or NEEDS CLARIFICATION] -**Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] -**Project Type**: [single/web/mobile - determines source structure] -**Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] -**Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] -**Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] +**Language/Version**: Markdown (documentation updates) +**Primary Dependencies**: Coder server env vars in `/etc/coder.d/coder.env` (managed on host, not in repo) +**Storage**: N/A +**Testing**: Manual scenario tests against staging-coder.ddev.com; existing BATS integration test suite +**Target Platform**: Ubuntu server running Coder via apt deb package + systemd +**Project Type**: Ops change + documentation update +**Performance Goals**: No increase in login round-trip time (under 10 seconds) +**Constraints**: Password auth must remain enabled; staging must be validated before production; OAuth credentials must not be committed to the repo + +--- ## Charter Check -*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* +- **All changes via PR**: ✓ — plan tracked in `kitty-specs/`, doc changes committed via PR on `20260507_speckitty` +- **Staging before production**: ✓ — explicit work package gate between staging validation and production rollout +- **No credentials in repo**: ✓ — `/etc/coder.d/coder.env` is a server-side file; client ID/secret documented as operator-supplied values only +- **Integration tests run against staging**: ✓ — staging validation WP includes manual scenario testing; BATS suite run post-config + +No charter violations. -[Gates determined based on charter file] +--- ## Project Structure -### Documentation (this feature) +### Spec artifacts ``` -kitty-specs/[###-feature]/ -├── plan.md # This file (/spec-kitty.plan command output) -├── research.md # Phase 0 output (/spec-kitty.plan command) -├── data-model.md # Phase 1 output (/spec-kitty.plan command) -├── quickstart.md # Phase 1 output (/spec-kitty.plan command) -├── contracts/ # Phase 1 output (/spec-kitty.plan command) -└── tasks.md # Phase 2 output (/spec-kitty.tasks command - NOT created by /spec-kitty.plan) +kitty-specs/github-org-gated-signup-01KR1P4G/ +├── spec.md ✓ complete +├── plan.md ← this file +├── research.md ← Phase 0 output +└── tasks/ ← populated by /spec-kitty.tasks ``` -### Source Code (repository root) - +### Source changes (repo root) +```text +docs/admin/ +├── server-setup.md ← update: add coder-ddev-com to ALLOWED_ORGS, staging OAuth App section +└── user-management.md ← update: add access management runbook section ``` -# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) -src/ -├── models/ -├── services/ -├── cli/ -└── lib/ - -tests/ -├── contract/ -├── integration/ -└── unit/ - -# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) -backend/ -├── src/ -│ ├── models/ -│ ├── services/ -│ └── api/ -└── tests/ - -frontend/ -├── src/ -│ ├── components/ -│ ├── pages/ -│ └── services/ -└── tests/ - -# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) -api/ -└── [same as backend above] - -ios/ or android/ -└── [platform-specific structure: feature modules, UI flows, platform tests] -``` -**Structure Decision**: [Document the selected structure and reference the real -directories captured above] +No Terraform, shell script, or Dockerfile changes required. All Coder server configuration changes are applied on the host via `/etc/coder.d/coder.env`. + +--- + +## Phase 0: Research + +See [research.md](research.md). + +Key findings: all open questions resolved. No `[NEEDS CLARIFICATION]` markers remain. + +--- + +## Phase 1: Work Package Approach + +This feature decomposes into three types of work: + +### Type A — Repository changes (agent-implementable) + +1. **Update `docs/admin/server-setup.md`** + - Change `CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev` to `CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com` + - Add a staging OAuth App sub-section (separate app with staging callback URL) + - Add a note explaining the `coder-ddev-com` org purpose and how to manage membership + - Add a note explaining why two separate OAuth Apps are used (credential isolation between environments) + +2. **Update `docs/admin/user-management.md`** + - Add a new "Access Management" section covering: + - How to add a user to the `coder-ddev-com` GitHub org (grants self-serve signup) + - How to pre-create a password exception account (for users who cannot use GitHub OAuth) + - Note: private org membership is sufficient — users do not need to publicize membership + +### Type B — Ops tasks (operator-executed, documented in runbook) -## Complexity Tracking +1. **Create `coder-ddev-com` GitHub org** — one-time action; org owner adds members as needed +2. **Register staging OAuth App** under `ddev` org with callback `https://staging-coder.ddev.com/api/v2/users/oauth2/github/callback` +3. **Register production OAuth App** under `ddev` org with callback `https://coder.ddev.com/api/v2/users/oauth2/github/callback` +4. **Apply config to staging**: update `/etc/coder.d/coder.env`, restart `coder` service, validate all 5 scenarios from spec +5. **Apply config to production**: repeat after staging validation passes -*Fill ONLY if Charter Check has violations that must be justified* +### Staging validation scenarios (must all pass before production) -| Violation | Why Needed | Simpler Alternative Rejected Because | -|-----------|------------|-------------------------------------| -| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | -| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | +| # | Scenario | Expected | +| - | -------- | -------- | +| 1 | `ddev` org member signs in via GitHub | Account created, dashboard loads | +| 2 | `coder-ddev-com` org member signs in via GitHub | Account created, dashboard loads | +| 3 | Unauthorized GitHub user attempts sign-in | Error shown, no account created | +| 4 | Existing user (pre-existing account) logs in | Access unchanged | +| 5 | Exception account via password | Password login succeeds | diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md new file mode 100644 index 0000000..e09990c --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md @@ -0,0 +1,72 @@ +# Research: GitHub Org-Gated Signup + +## How Coder server configuration is applied + +**Decision**: Edit `/etc/coder.d/coder.env` on the server host, then `sudo systemctl restart coder`. + +**Rationale**: Coder is installed via the apt deb package, which installs a systemd unit that reads `/etc/coder.d/coder.env` at startup. This file is the canonical location for all runtime env vars. It is not committed to this repo — credentials and environment-specific values stay on the host. + +**Alternatives considered**: Terraform-managed env injection (not applicable here — Terraform manages workspace templates, not the Coder server itself). + +--- + +## One OAuth App vs. two for staging and production + +**Decision**: Two separate OAuth Apps — one for staging-coder.ddev.com, one for coder.ddev.com. + +**Rationale**: Separate apps mean staging credentials cannot be used against production. Secret rotation on one environment does not affect the other. Aligns with the charter's staging-first validation constraint (C-004). + +**Alternatives considered**: Single app with both callback URLs — simpler to manage but couples the two environments' credentials. + +--- + +## Custom OAuth App vs. Coder's default app + +**Decision**: Custom DDEV-owned GitHub OAuth App registered under the `ddev` org. + +**Rationale**: Coder's documentation explicitly recommends custom apps for production: "For production environments, we strongly recommend that you configure your own GitHub OAuth app to ensure that your data is not shared with Coder (the company)." The default app routes org membership data through Coder's infrastructure. + +**Alternatives considered**: Default Coder app — zero setup, but shares org data with Coder the company. + +--- + +## Private org membership and `read:org` scope + +**Decision**: Private org membership works with `read:org` scope. Users do not need to publicize their `ddev` or `coder-ddev-com` membership. + +**Rationale**: The `read:org` OAuth scope allows the app to read organization membership regardless of visibility setting. GitHub's API returns private membership when this scope is granted. This satisfies NFR-002. + +**Warning already documented in server-setup.md**: Do not enable Device Flow (`CODER_OAUTH2_GITHUB_DEVICE_FLOW=true`) alongside `ALLOWED_ORGS` — device flow does not request `read:org` and org membership checks fail with 403. + +--- + +## Required env vars summary + +```bash +# /etc/coder.d/coder.env additions (staging and production, separate client IDs/secrets) +CODER_OAUTH2_GITHUB_CLIENT_ID= +CODER_OAUTH2_GITHUB_CLIENT_SECRET= +CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS=true +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com +# CODER_OAUTH2_GITHUB_DEVICE_FLOW must NOT be set to true +# CODER_DISABLE_PASSWORD_AUTH must NOT be set to true +``` + +--- + +## GitHub org for OAuth App ownership + +**Decision**: Register the OAuth Apps under the `ddev` GitHub organization. + +**Rationale**: Apps registered under an org show "by ddev" on the authorization screen instead of "by \". Institutional ownership means the app persists even if the registering individual leaves the org. Existing `docs/admin/server-setup.md` already documents this pattern. + +--- + +## What files in this repo change + +| File | Change | +| ---- | ------ | +| `docs/admin/server-setup.md` | Update `ALLOWED_ORGS` value, add staging OAuth App section, document `coder-ddev-com` org | +| `docs/admin/user-management.md` | Add "Access Management" section: how to add users to `coder-ddev-com`, how to pre-create password exception accounts | + +No Terraform, shell, or Dockerfile changes needed. From daf3ea6919deea732d14499ba15506df76b73e97 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:28:10 -0600 Subject: [PATCH 09/53] feat(spec): add org README, access-request repo, and blog post update requirements Co-Authored-By: Claude Sonnet 4.6 --- kitty-specs/github-org-gated-signup-01KR1P4G/plan.md | 12 +++++++++++- kitty-specs/github-org-gated-signup-01KR1P4G/spec.md | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md index 2726246..9e84526 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md @@ -40,7 +40,7 @@ No charter violations. ### Spec artifacts -``` +```text kitty-specs/github-org-gated-signup-01KR1P4G/ ├── spec.md ✓ complete ├── plan.md ← this file @@ -86,6 +86,16 @@ This feature decomposes into three types of work: - How to pre-create a password exception account (for users who cannot use GitHub OAuth) - Note: private org membership is sufficient — users do not need to publicize membership +3. **Write `coder-ddev-com` org README and access-request repo** + - Draft content for the `coder-ddev-com` org README (`.github/profile/README.md` in the org): org purpose, who qualifies, how membership grants Coder access + - Draft issue template for the access-request repo (e.g., `coder-ddev-com/access-requests`): name, GitHub username, reason for access + - Draft README for the access-request repo explaining how to open a request and what to expect + +4. **Update ddev.com blog post** (`ddev/ddev.com` repo — separate PR required) + - Update the "Log In with GitHub" section: replace "No separate account needed" with an explanation that signups are restricted to `ddev` and `coder-ddev-com` org members + - Add a paragraph explaining how users outside the `ddev` org can request access by opening an issue in the `coder-ddev-com/access-requests` repo + - Add a link to the access-request repo + ### Type B — Ops tasks (operator-executed, documented in runbook) 1. **Create `coder-ddev-com` GitHub org** — one-time action; org owner adds members as needed diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md index e886826..063c45c 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md @@ -60,6 +60,9 @@ The same org-restriction configuration is applied to staging-coder.ddev.com, so | FR-007 | The OAuth App is registered under the `ddev` GitHub organization so credentials are DDEV-controlled, not held by an individual account. | Approved | | FR-008 | Authorized users from both orgs can create and use workspaces on both environments. | Approved | | FR-009 | An operator runbook documents how to add a user to the `coder-ddev-com` org and how to pre-create exception accounts with password credentials. | Approved | +| FR-010 | The `coder-ddev-com` GitHub org has a README (in its `.github` or dedicated `about` repo) explaining the org's purpose, who it is for, and how access works. | Approved | +| FR-011 | A public repository in the `coder-ddev-com` org provides an issue tracker where prospective users can request access by opening a GitHub issue. | Approved | +| FR-012 | The ddev.com blog post announcing coder.ddev.com is updated to explain that signups are now restricted, how the `coder-ddev-com` org works, and where to open an access request. | Approved | --- @@ -92,6 +95,8 @@ The same org-restriction configuration is applied to staging-coder.ddev.com, so 3. An admin can grant access to a new non-ddev-org user by adding them to `coder-ddev-com`, with no Coder server change required. 4. At least one pre-existing user account continues to function after the rollout (no accounts locked out). 5. Staging-coder.ddev.com and coder.ddev.com enforce the same restriction after both are reconfigured. +6. A prospective user who is not in `ddev` or `coder-ddev-com` can find the access-request issue tracker without assistance. +7. The ddev.com blog post no longer implies open signup; it accurately describes the access model and links to the access-request repo. --- From d494035a9c24b7d05b125c7f0f404358b6f31bd1 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:31:50 -0600 Subject: [PATCH 10/53] feat(spec): add sponsor org access requirements (FR-013, FR-014, C-006, C-007) Co-Authored-By: Claude Sonnet 4.6 --- .../github-org-gated-signup-01KR1P4G/plan.md | 9 +++++-- .../research.md | 27 +++++++++++++++++++ .../github-org-gated-signup-01KR1P4G/spec.md | 5 ++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md index 9e84526..b6cea3b 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md @@ -91,7 +91,12 @@ This feature decomposes into three types of work: - Draft issue template for the access-request repo (e.g., `coder-ddev-com/access-requests`): name, GitHub username, reason for access - Draft README for the access-request repo explaining how to open a request and what to expect -4. **Update ddev.com blog post** (`ddev/ddev.com` repo — separate PR required) +4. **Resolve $100+ sponsor GitHub org names and update server-setup.md** + - Identify which current $100+/month sponsors are GitHub organizations (vs. individuals): cross-reference the invoiced list (cps-it, Redfin Solutions, LetsTalk, Institute for Advanced Studies, Tag1, Upsun, B13, Lullabot, 8mylez, Cambrico, Centarro, Pixel & Tonic) against GitHub org slugs + - Update `docs/admin/server-setup.md` to document the sponsor-org access policy and show the full example `ALLOWED_ORGS` value including sponsor org slugs + - Update the sponsors-to-orgs mapping as a maintained comment or table in `docs/admin/server-setup.md` (since `invoiced-sponsorships.jsonc` has no GitHub org field) + +5. **Update ddev.com blog post** (`ddev/ddev.com` repo — separate PR required) - Update the "Log In with GitHub" section: replace "No separate account needed" with an explanation that signups are restricted to `ddev` and `coder-ddev-com` org members - Add a paragraph explaining how users outside the `ddev` org can request access by opening an issue in the `coder-ddev-com/access-requests` repo - Add a link to the access-request repo @@ -101,7 +106,7 @@ This feature decomposes into three types of work: 1. **Create `coder-ddev-com` GitHub org** — one-time action; org owner adds members as needed 2. **Register staging OAuth App** under `ddev` org with callback `https://staging-coder.ddev.com/api/v2/users/oauth2/github/callback` 3. **Register production OAuth App** under `ddev` org with callback `https://coder.ddev.com/api/v2/users/oauth2/github/callback` -4. **Apply config to staging**: update `/etc/coder.d/coder.env`, restart `coder` service, validate all 5 scenarios from spec +4. **Apply config to staging**: update `/etc/coder.d/coder.env` with `ALLOWED_ORGS=ddev,coder-ddev-com,,...`, restart `coder` service, validate all scenarios from spec 5. **Apply config to production**: repeat after staging validation passes ### Staging validation scenarios (must all pass before production) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md index e09990c..84dc9c6 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md @@ -70,3 +70,30 @@ CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com | `docs/admin/user-management.md` | Add "Access Management" section: how to add users to `coder-ddev-com`, how to pre-create password exception accounts | No Terraform, shell, or Dockerfile changes needed. + +--- + +## $100+/month sponsor GitHub org names + +**Finding**: The `ddev/sponsorship-data` `invoiced-sponsorships.jsonc` file records billing tiers and company names in comments but contains no `github_org` field. GitHub org slugs must be resolved manually. + +**Known $100+/month invoiced sponsors** (from the data file comments) that need GitHub org slug mapping: + +| Company | Monthly amount | GitHub org slug (TBD) | +| ------- | -------------- | --------------------- | +| cps-it | ~$118 | TBD | +| Redfin Solutions | $100 | TBD | +| LetsTalk | $100 | TBD | +| Institute for Advanced Studies | $500 | TBD | +| Tag1 | $1,000 | TBD | +| Upsun | ~$1,162 | TBD | +| B13 | annual ($2,000/yr) | TBD | +| Lullabot | annual ($2,000/yr) | TBD | +| 8mylez | annual (~$1,153/yr) | TBD | +| Cambrico | annual ($1,200/yr) | TBD | +| Centarro | annual ($1,200/yr) | TBD | +| Pixel & Tonic | annual ($1,200/yr) | TBD | + +**Action required (operator)**: Confirm GitHub org slug for each before adding to `ALLOWED_ORGS`. Some may not have a GitHub org (individuals or companies without a public GitHub presence). + +**GitHub Sponsors orgs** (sponsoring via github.com/sponsors/ddev at $100+/month tier): requires a token with `read:user` scope on the `ddev` org owner account to enumerate via the GraphQL API. Out of scope for this mission's automated resolution — resolve manually or in a follow-up. diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md index 063c45c..360921f 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md @@ -63,6 +63,8 @@ The same org-restriction configuration is applied to staging-coder.ddev.com, so | FR-010 | The `coder-ddev-com` GitHub org has a README (in its `.github` or dedicated `about` repo) explaining the org's purpose, who it is for, and how access works. | Approved | | FR-011 | A public repository in the `coder-ddev-com` org provides an issue tracker where prospective users can request access by opening a GitHub issue. | Approved | | FR-012 | The ddev.com blog post announcing coder.ddev.com is updated to explain that signups are now restricted, how the `coder-ddev-com` org works, and where to open an access request. | Approved | +| FR-013 | GitHub organizations that sponsor DDEV at $100+/month (via GitHub Sponsors or invoiced billing) are eligible for access: all members of those orgs can sign in to coder.ddev.com without individual `coder-ddev-com` membership. | Approved | +| FR-014 | A runbook documents how to identify the GitHub org name for a new $100+ sponsor and add it to the allowed-orgs list on both environments. | Approved | --- @@ -85,6 +87,8 @@ The same org-restriction configuration is applied to staging-coder.ddev.com, so | C-003 | The custom GitHub OAuth App must request at minimum: `read:user`, `user:email`, and `read:org` scopes. The `read:org` scope is required for Coder to verify org membership. | Approved | | C-004 | The change must be applied to staging first and validated before applying to production. | Approved | | C-005 | OAuth App credentials (client ID and client secret) must be stored as server-level secrets, not committed to the repository. | Approved | +| C-006 | Sponsor orgs are added to `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` directly (not proxied via `coder-ddev-com` membership), so all members of a sponsor org benefit automatically without individual enrollment. | Approved | +| C-007 | The `invoiced-sponsorships.jsonc` data file does not contain GitHub org names; a manual or scripted mapping from company name to GitHub org name is required before any sponsor org can be added. | Approved | --- @@ -97,6 +101,7 @@ The same org-restriction configuration is applied to staging-coder.ddev.com, so 5. Staging-coder.ddev.com and coder.ddev.com enforce the same restriction after both are reconfigured. 6. A prospective user who is not in `ddev` or `coder-ddev-com` can find the access-request issue tracker without assistance. 7. The ddev.com blog post no longer implies open signup; it accurately describes the access model and links to the access-request repo. +8. Members of at least one confirmed $100+/month sponsor org can sign in to coder.ddev.com without being explicitly added to `coder-ddev-com`. --- From d07f3a65d187be760feca5df628b2e24ff3d65e8 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:35:32 -0600 Subject: [PATCH 11/53] feat(research): resolve sponsor GitHub org slugs, add platformsh alongside upsun Co-Authored-By: Claude Sonnet 4.6 --- .../research.md | 61 ++++++++++++------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md index 84dc9c6..42d9bf1 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md @@ -75,25 +75,42 @@ No Terraform, shell, or Dockerfile changes needed. ## $100+/month sponsor GitHub org names -**Finding**: The `ddev/sponsorship-data` `invoiced-sponsorships.jsonc` file records billing tiers and company names in comments but contains no `github_org` field. GitHub org slugs must be resolved manually. - -**Known $100+/month invoiced sponsors** (from the data file comments) that need GitHub org slug mapping: - -| Company | Monthly amount | GitHub org slug (TBD) | -| ------- | -------------- | --------------------- | -| cps-it | ~$118 | TBD | -| Redfin Solutions | $100 | TBD | -| LetsTalk | $100 | TBD | -| Institute for Advanced Studies | $500 | TBD | -| Tag1 | $1,000 | TBD | -| Upsun | ~$1,162 | TBD | -| B13 | annual ($2,000/yr) | TBD | -| Lullabot | annual ($2,000/yr) | TBD | -| 8mylez | annual (~$1,153/yr) | TBD | -| Cambrico | annual ($1,200/yr) | TBD | -| Centarro | annual ($1,200/yr) | TBD | -| Pixel & Tonic | annual ($1,200/yr) | TBD | - -**Action required (operator)**: Confirm GitHub org slug for each before adding to `ALLOWED_ORGS`. Some may not have a GitHub org (individuals or companies without a public GitHub presence). - -**GitHub Sponsors orgs** (sponsoring via github.com/sponsors/ddev at $100+/month tier): requires a token with `read:user` scope on the `ddev` org owner account to enumerate via the GraphQL API. Out of scope for this mission's automated resolution — resolve manually or in a follow-up. +**Finding**: The `ddev/sponsorship-data` `invoiced-sponsorships.jsonc` file records billing tiers and company names in comments but no `github_org` field. Slugs resolved by GitHub API lookup below. + +### Confirmed — GitHub org verified + +| Company | Monthly equiv. | GitHub org slug | +| ------- | -------------- | --------------- | +| Tag1 | $1,000 | `tag1consulting` | +| Upsun / Platform.sh | ~$1,162 | `upsun` and `platformsh` (Platform.sh rebranded to Upsun; both orgs added) | +| Institute for Advanced Studies | $500 | `Institute-for-Advanced-Studies` (org exists; no public name/description to confirm — needs operator verification) | +| CPS-IT | ~$118 | `CPS-IT` | +| Redfin Solutions | $100 | `redfinsolutions` | +| Lullabot | ~$167 (annual $2k) | `Lullabot` | +| B13 | ~$167 (annual $2k) | `b13` | +| Pixel & Tonic | $100 (annual $1.2k) | `pixelandtonic` | +| Cambrico | $100 (annual $1.2k) | `Cambrico` | +| Centarro | $100 (annual $1.2k) | `centarro` | + +### Needs operator verification + +| Company | Monthly equiv. | Notes | +| ------- | -------------- | ----- | +| LetsTalk | $100 | GitHub org `lets-talk` exists (name: "Let's Talk") — plausible match but unverified; operator should confirm | + +### Below $100/month threshold — excluded + +| Company | Monthly equiv. | Notes | +| ------- | -------------- | ----- | +| 8mylez | ~$96 (annual $1,153) | Annual equivalent is ~$96/month, just under the $100 threshold | + +### GitHub Sponsors orgs (github.com/sponsors/ddev) + +Sponsors via GitHub Sponsors at $100+/month tier require a token with `read:user` scope on the `ddev` org owner account to enumerate via the GraphQL API. Resolve manually or in a follow-up mission. + +### Resulting `ALLOWED_ORGS` value (staging/production) + +```bash +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro +# Add lets-talk after operator confirms it is the correct LetsTalk org +``` From 9a05348a38fb3aa4dc34d473d7b203b90aa98d42 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:38:02 -0600 Subject: [PATCH 12/53] feat(spec): add 8mylez, remove lets-talk, add sponsor notification task Co-Authored-By: Claude Sonnet 4.6 --- .../github-org-gated-signup-01KR1P4G/plan.md | 9 +++++++-- .../github-org-gated-signup-01KR1P4G/research.md | 15 +++++---------- .../github-org-gated-signup-01KR1P4G/spec.md | 2 ++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md index b6cea3b..3929262 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md @@ -91,12 +91,16 @@ This feature decomposes into three types of work: - Draft issue template for the access-request repo (e.g., `coder-ddev-com/access-requests`): name, GitHub username, reason for access - Draft README for the access-request repo explaining how to open a request and what to expect -4. **Resolve $100+ sponsor GitHub org names and update server-setup.md** +4. **Draft sponsor notification message** + - Write a short email/message template announcing the access benefit to sponsor orgs: what coder.ddev.com is, that their org members can now log in with GitHub, link to the getting-started doc, and DDEV Discord/issues for support + - Store draft in `docs/admin/` or as a committed template for the operator to send + +5. **Resolve $100+ sponsor GitHub org names and update server-setup.md** - Identify which current $100+/month sponsors are GitHub organizations (vs. individuals): cross-reference the invoiced list (cps-it, Redfin Solutions, LetsTalk, Institute for Advanced Studies, Tag1, Upsun, B13, Lullabot, 8mylez, Cambrico, Centarro, Pixel & Tonic) against GitHub org slugs - Update `docs/admin/server-setup.md` to document the sponsor-org access policy and show the full example `ALLOWED_ORGS` value including sponsor org slugs - Update the sponsors-to-orgs mapping as a maintained comment or table in `docs/admin/server-setup.md` (since `invoiced-sponsorships.jsonc` has no GitHub org field) -5. **Update ddev.com blog post** (`ddev/ddev.com` repo — separate PR required) +6. **Update ddev.com blog post** (`ddev/ddev.com` repo — separate PR required) - Update the "Log In with GitHub" section: replace "No separate account needed" with an explanation that signups are restricted to `ddev` and `coder-ddev-com` org members - Add a paragraph explaining how users outside the `ddev` org can request access by opening an issue in the `coder-ddev-com/access-requests` repo - Add a link to the access-request repo @@ -108,6 +112,7 @@ This feature decomposes into three types of work: 3. **Register production OAuth App** under `ddev` org with callback `https://coder.ddev.com/api/v2/users/oauth2/github/callback` 4. **Apply config to staging**: update `/etc/coder.d/coder.env` with `ALLOWED_ORGS=ddev,coder-ddev-com,,...`, restart `coder` service, validate all scenarios from spec 5. **Apply config to production**: repeat after staging validation passes +6. **Notify sponsor orgs**: reach out to each org in `ALLOWED_ORGS` (excluding `ddev` and `coder-ddev-com`) to let them know their members now have access — what coder.ddev.com is, how to use it, and where to get help (DDEV Discord, issues). Draft notification message as part of Type A work. ### Staging validation scenarios (must all pass before production) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md index 42d9bf1..0f285af 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md @@ -83,6 +83,7 @@ No Terraform, shell, or Dockerfile changes needed. | ------- | -------------- | --------------- | | Tag1 | $1,000 | `tag1consulting` | | Upsun / Platform.sh | ~$1,162 | `upsun` and `platformsh` (Platform.sh rebranded to Upsun; both orgs added) | +| 8mylez | ~$96 (annual $1,153) | `8mylez` — included at operator discretion despite being slightly under $100/month equivalent | | Institute for Advanced Studies | $500 | `Institute-for-Advanced-Studies` (org exists; no public name/description to confirm — needs operator verification) | | CPS-IT | ~$118 | `CPS-IT` | | Redfin Solutions | $100 | `redfinsolutions` | @@ -92,17 +93,11 @@ No Terraform, shell, or Dockerfile changes needed. | Cambrico | $100 (annual $1.2k) | `Cambrico` | | Centarro | $100 (annual $1.2k) | `centarro` | -### Needs operator verification +### No GitHub org found — excluded | Company | Monthly equiv. | Notes | | ------- | -------------- | ----- | -| LetsTalk | $100 | GitHub org `lets-talk` exists (name: "Let's Talk") — plausible match but unverified; operator should confirm | - -### Below $100/month threshold — excluded - -| Company | Monthly equiv. | Notes | -| ------- | -------------- | ----- | -| 8mylez | ~$96 (annual $1,153) | Annual equivalent is ~$96/month, just under the $100 threshold | +| LetsTalk | $100 | `lets-talk` GitHub org exists but is not the correct org for this sponsor; no confirmed GitHub org found — individual access via `coder-ddev-com` membership instead | ### GitHub Sponsors orgs (github.com/sponsors/ddev) @@ -111,6 +106,6 @@ Sponsors via GitHub Sponsors at $100+/month tier require a token with `read:user ### Resulting `ALLOWED_ORGS` value (staging/production) ```bash -CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro -# Add lets-talk after operator confirms it is the correct LetsTalk org +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro,8mylez +# LetsTalk has no confirmed GitHub org; grant access by adding individuals to coder-ddev-com instead ``` diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md index 360921f..96a8408 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/spec.md @@ -65,6 +65,7 @@ The same org-restriction configuration is applied to staging-coder.ddev.com, so | FR-012 | The ddev.com blog post announcing coder.ddev.com is updated to explain that signups are now restricted, how the `coder-ddev-com` org works, and where to open an access request. | Approved | | FR-013 | GitHub organizations that sponsor DDEV at $100+/month (via GitHub Sponsors or invoiced billing) are eligible for access: all members of those orgs can sign in to coder.ddev.com without individual `coder-ddev-com` membership. | Approved | | FR-014 | A runbook documents how to identify the GitHub org name for a new $100+ sponsor and add it to the allowed-orgs list on both environments. | Approved | +| FR-015 | Each sponsor org that has been granted access is notified about the benefit — what access they have, how to use it, and who to contact if they need help. | Approved | --- @@ -102,6 +103,7 @@ The same org-restriction configuration is applied to staging-coder.ddev.com, so 6. A prospective user who is not in `ddev` or `coder-ddev-com` can find the access-request issue tracker without assistance. 7. The ddev.com blog post no longer implies open signup; it accurately describes the access model and links to the access-request repo. 8. Members of at least one confirmed $100+/month sponsor org can sign in to coder.ddev.com without being explicitly added to `coder-ddev-com`. +9. Each sponsor org listed in `ALLOWED_ORGS` has been notified of the access benefit before or shortly after the production rollout. --- From 7deb13dc30ba3d1368621471bff5f44287e34889 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:40:21 -0600 Subject: [PATCH 13/53] feat(research): add dkd, liip, dougvann; finalize ALLOWED_ORGS list Co-Authored-By: Claude Sonnet 4.6 --- .../github-org-gated-signup-01KR1P4G/plan.md | 2 +- .../github-org-gated-signup-01KR1P4G/research.md | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md index 3929262..51d0efc 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md @@ -107,7 +107,7 @@ This feature decomposes into three types of work: ### Type B — Ops tasks (operator-executed, documented in runbook) -1. **Create `coder-ddev-com` GitHub org** — one-time action; org owner adds members as needed +1. **Create `coder-ddev-com` GitHub org** — one-time action; add `dougvann` (individual $100/month GitHub Sponsor) as an initial member; LetsTalk contact added when identified 2. **Register staging OAuth App** under `ddev` org with callback `https://staging-coder.ddev.com/api/v2/users/oauth2/github/callback` 3. **Register production OAuth App** under `ddev` org with callback `https://coder.ddev.com/api/v2/users/oauth2/github/callback` 4. **Apply config to staging**: update `/etc/coder.d/coder.env` with `ALLOWED_ORGS=ddev,coder-ddev-com,,...`, restart `coder` service, validate all scenarios from spec diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md index 0f285af..7919db7 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md @@ -84,6 +84,8 @@ No Terraform, shell, or Dockerfile changes needed. | Tag1 | $1,000 | `tag1consulting` | | Upsun / Platform.sh | ~$1,162 | `upsun` and `platformsh` (Platform.sh rebranded to Upsun; both orgs added) | | 8mylez | ~$96 (annual $1,153) | `8mylez` — included at operator discretion despite being slightly under $100/month equivalent | +| dkd Internet Service GmbH | $100 (GitHub Sponsors) | `dkd` | +| Liip | $100 (GitHub Sponsors) | `liip` | | Institute for Advanced Studies | $500 | `Institute-for-Advanced-Studies` (org exists; no public name/description to confirm — needs operator verification) | | CPS-IT | ~$118 | `CPS-IT` | | Redfin Solutions | $100 | `redfinsolutions` | @@ -99,13 +101,16 @@ No Terraform, shell, or Dockerfile changes needed. | ------- | -------------- | ----- | | LetsTalk | $100 | `lets-talk` GitHub org exists but is not the correct org for this sponsor; no confirmed GitHub org found — individual access via `coder-ddev-com` membership instead | -### GitHub Sponsors orgs (github.com/sponsors/ddev) +### GitHub Sponsors individual at $100/month -Sponsors via GitHub Sponsors at $100+/month tier require a token with `read:user` scope on the `ddev` org owner account to enumerate via the GraphQL API. Resolve manually or in a follow-up mission. +One individual (not an org) sponsors at $100/month via GitHub Sponsors. Because they have a personal account (not a GitHub org), they cannot be added to `CODER_OAUTH2_GITHUB_ALLOWED_ORGS`. Grant access by adding their GitHub username to the `coder-ddev-com` org directly. + +Identified as `dougvann` via [ddev/ddev.com#626](https://github.com/ddev/ddev.com/pull/626). Add `dougvann` to `coder-ddev-com` org directly after org creation. ### Resulting `ALLOWED_ORGS` value (staging/production) ```bash -CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro,8mylez -# LetsTalk has no confirmed GitHub org; grant access by adding individuals to coder-ddev-com instead +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro,8mylez,dkd,liip +# LetsTalk: no confirmed GitHub org — add individuals to coder-ddev-com instead +# dougvann ($100/month individual GitHub Sponsor): add to coder-ddev-com directly ``` From 4cadb388fbf7202561221b601f9eb5b555be8fda Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 11:43:59 -0600 Subject: [PATCH 14/53] feat(research): add all featured sponsors to ALLOWED_ORGS, exclude in-kind --- .../research.md | 83 ++++++++++++------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md index 7919db7..a8f089a 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/research.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/research.md @@ -77,40 +77,59 @@ No Terraform, shell, or Dockerfile changes needed. **Finding**: The `ddev/sponsorship-data` `invoiced-sponsorships.jsonc` file records billing tiers and company names in comments but no `github_org` field. Slugs resolved by GitHub API lookup below. -### Confirmed — GitHub org verified - -| Company | Monthly equiv. | GitHub org slug | -| ------- | -------------- | --------------- | -| Tag1 | $1,000 | `tag1consulting` | -| Upsun / Platform.sh | ~$1,162 | `upsun` and `platformsh` (Platform.sh rebranded to Upsun; both orgs added) | -| 8mylez | ~$96 (annual $1,153) | `8mylez` — included at operator discretion despite being slightly under $100/month equivalent | -| dkd Internet Service GmbH | $100 (GitHub Sponsors) | `dkd` | -| Liip | $100 (GitHub Sponsors) | `liip` | -| Institute for Advanced Studies | $500 | `Institute-for-Advanced-Studies` (org exists; no public name/description to confirm — needs operator verification) | -| CPS-IT | ~$118 | `CPS-IT` | -| Redfin Solutions | $100 | `redfinsolutions` | -| Lullabot | ~$167 (annual $2k) | `Lullabot` | -| B13 | ~$167 (annual $2k) | `b13` | -| Pixel & Tonic | $100 (annual $1.2k) | `pixelandtonic` | -| Cambrico | $100 (annual $1.2k) | `Cambrico` | -| Centarro | $100 (annual $1.2k) | `centarro` | - -### No GitHub org found — excluded - -| Company | Monthly equiv. | Notes | -| ------- | -------------- | ----- | -| LetsTalk | $100 | `lets-talk` GitHub org exists but is not the correct org for this sponsor; no confirmed GitHub org found — individual access via `coder-ddev-com` membership instead | - -### GitHub Sponsors individual at $100/month - -One individual (not an org) sponsors at $100/month via GitHub Sponsors. Because they have a personal account (not a GitHub org), they cannot be added to `CODER_OAUTH2_GITHUB_ALLOWED_ORGS`. Grant access by adding their GitHub username to the `coder-ddev-com` org directly. - -Identified as `dougvann` via [ddev/ddev.com#626](https://github.com/ddev/ddev.com/pull/626). Add `dougvann` to `coder-ddev-com` org directly after org creation. +### Confirmed — add to `ALLOWED_ORGS` + +All featured sponsors on ddev.com are at the $100/month level. MacStadium and JetBrains are in-kind (not cash) sponsors and are excluded. The ddev.com sponsor link for Webikon points to the individual `claudiu-cristea`, so the org is excluded and the individual gets `coder-ddev-com` membership instead. + +| Company | Source | GitHub org slug | +| ------- | ------ | --------------- | +| Tag1 | invoiced | `tag1consulting` | +| Upsun | invoiced | `upsun` | +| Platform.sh (rebranded to Upsun) | invoiced | `platformsh` | +| Institute for Advanced Studies | invoiced | `Institute-for-Advanced-Studies` ⚠️ org exists but unverified — confirm with operator | +| CPS-IT | invoiced | `CPS-IT` | +| Redfin Solutions | invoiced + featured | `redfinsolutions` | +| Lullabot | invoiced | `Lullabot` | +| B13 | invoiced + featured | `b13` | +| Pixel & Tonic (Craft CMS) | invoiced + featured | `pixelandtonic` | +| Cambrico | invoiced + featured | `Cambrico` | +| Centarro | invoiced + featured | `centarro` | +| 8mylez | invoiced | `8mylez` | +| dkd Internet Service GmbH | GitHub Sponsors | `dkd` | +| Liip | GitHub Sponsors | `liip` | +| i-gelb GmbH | featured | `i-gelb` | +| Fame Helsinki | featured | `FameHelsinki` | +| Gizra | featured | `Gizra` | +| mobilistics GmbH | featured | `mobilistics` | +| OPTASY | featured | `OPTASY` | +| Passbolt | featured | `passbolt` | +| Værsågod | featured | `vaersaagod` | +| Affinity Bridge | featured | `affinitybridge` | +| Agiledrop | featured | `AGILEDROP` | +| NPO Applications GmbH | featured | `NPO-Applications-GmbH` | +| Aten Design Group | featured | `AtenDesignGroup` | + +### Individual/unresolved — add to `coder-ddev-com` org + +| Sponsor | Notes | +| ------- | ----- | +| `dougvann` | Individual $100/month GitHub Sponsor — confirmed via [ddev/ddev.com#626](https://github.com/ddev/ddev.com/pull/626) | +| claudiu-cristea (Webikon) | ddev.com sponsor link points to individual, not org | +| LetsTalk | No confirmed GitHub org (`lets-talk` is wrong org); add individual GitHub username when known | +| Amedick Sommer | No GitHub org found; add individual GitHub username when known | +| Pottkinder GmbH | No GitHub org found; add individual GitHub username when known | + +### Excluded + +| Sponsor | Reason | +| ------- | ------ | +| MacStadium | In-kind (hardware), not cash sponsor | +| JetBrains | In-kind (licenses), not cash sponsor | ### Resulting `ALLOWED_ORGS` value (staging/production) ```bash -CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro,8mylez,dkd,liip -# LetsTalk: no confirmed GitHub org — add individuals to coder-ddev-com instead -# dougvann ($100/month individual GitHub Sponsor): add to coder-ddev-com directly +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro,8mylez,dkd,liip,i-gelb,FameHelsinki,Gizra,mobilistics,OPTASY,passbolt,vaersaagod,affinitybridge,AGILEDROP,NPO-Applications-GmbH,AtenDesignGroup +# Webikon: sponsor link is individual claudiu-cristea — add to coder-ddev-com instead +# LetsTalk, Amedick Sommer, Pottkinder GmbH: no GitHub org — add individuals to coder-ddev-com when known ``` From e4ad8b52b19f921e0f60176f0515d4f5bffb96c8 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 12:03:09 -0600 Subject: [PATCH 15/53] chore: Map requirements for WP01, WP02, WP03, WP04 on spec github --- .../tasks/WP01-server-setup-update.md | 265 +++++++++++++++ .../WP02-user-management-access-runbook.md | 228 +++++++++++++ .../tasks/WP03-coder-ddev-com-org-content.md | 302 ++++++++++++++++++ .../tasks/WP04-blog-post-draft.md | 181 +++++++++++ 4 files changed, 976 insertions(+) create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md new file mode 100644 index 0000000..0711f7a --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md @@ -0,0 +1,265 @@ +--- +work_package_id: WP01 +title: Update server-setup.md for Org-Gated Auth +dependencies: [] +requirement_refs: +- C-003 +- C-004 +- C-005 +- C-006 +- C-007 +- FR-001 +- FR-005 +- FR-006 +- FR-007 +- FR-009 +- FR-013 +- FR-014 +planning_base_branch: 20260507_speckitty +merge_target_branch: 20260507_speckitty +branch_strategy: Implement directly on branch 20260507_speckitty. No worktree needed. +subtasks: +- T001 +- T002 +- T003 +- T004 +- T005 +history: +- date: '2026-05-07' + event: created +authoritative_surface: docs/admin/server-setup.md +execution_mode: code_change +owned_files: +- docs/admin/server-setup.md +tags: [] +--- + +# WP01 — Update server-setup.md for Org-Gated Auth + +## Branch Strategy + +- **Planning base**: `20260507_speckitty` +- **Merge target**: `20260507_speckitty` +- Implement directly on `20260507_speckitty`. Run `spec-kitty agent action implement WP01 --agent claude`. + +## Objective + +Update `docs/admin/server-setup.md` to be the authoritative operator reference for the new GitHub org-gated authentication model. The current doc covers only a single `ddev`-org restriction; it needs to reflect: +- The full 27-org `ALLOWED_ORGS` list (sponsors + ddev + coder-ddev-com) +- Two separate OAuth Apps (staging vs. production) +- The purpose and management of the `coder-ddev-com` org +- The sponsor org access policy with the full mapping table +- A runbook for adding a new sponsor org + +## Context + +The Coder server is deployed via apt deb package on Ubuntu, managed by systemd. Runtime config lives in `/etc/coder.d/coder.env` on the host — not committed to this repo. `docs/admin/server-setup.md` is the operator's guide for setting up that file. + +The current GitHub OAuth section (around line 660) shows only: +```bash +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev +``` + +This needs to become the full list, and the surrounding documentation needs to explain why so many orgs appear and how to manage them. + +**Read the current file before editing**: `docs/admin/server-setup.md`. The GitHub OAuth section spans approximately lines 660–710. All changes are within that section unless adding a new sub-section. + +## Subtask T001 — Update `ALLOWED_ORGS` to Full 27-Org List + +**Purpose**: Change the example env var block to include all approved orgs. + +**Location**: `docs/admin/server-setup.md`, inside the env var code block in "Step 2: Add to `/etc/coder.d/coder.env`". + +**Current value**: +```bash +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev +``` + +**New value**: +```bash +# Access control: ddev org members, coder-ddev-com managed list, and $100+/month sponsor orgs +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro,8mylez,dkd,liip,i-gelb,FameHelsinki,Gizra,mobilistics,OPTASY,passbolt,vaersaagod,affinitybridge,AGILEDROP,NPO-Applications-GmbH,AtenDesignGroup +``` + +**Note**: `Institute-for-Advanced-Studies` is included but flagged for operator verification — the GitHub org exists but has no public name/description confirming identity. Add an inline comment noting this. + +**Validation**: +- [ ] The code block compiles as valid bash (no stray characters) +- [ ] All 27 org slugs are present (count them) +- [ ] The comment above the var explains the three access tiers + +--- + +## Subtask T002 — Add Staging OAuth App Sub-section + +**Purpose**: The current doc only documents the production OAuth App. Operators need to know they must register a *separate* app for staging, with a different callback URL, before testing on staging-coder.ddev.com. + +**Location**: Add a new sub-section immediately after the "Create a GitHub OAuth App" step (currently "Step 1"), before or as part of the env var step. + +**Content to add** (adapt prose as needed, keep the tone of the existing doc): + +```markdown +#### Two OAuth Apps: staging and production + +Register **two separate OAuth Apps** — one for staging, one for production. Separate apps isolate credentials between environments so that a staging secret compromise cannot affect production, and secret rotation on one environment does not require touching the other. + +**Staging app settings:** +- **Application name**: `Coder (staging-coder.ddev.com)` +- **Homepage URL**: `https://staging-coder.ddev.com` +- **Authorization callback URL**: `https://staging-coder.ddev.com/api/v2/users/oauth2/github/callback` +- **Enable Device Flow**: leave unchecked + +**Production app settings** (unchanged from above): +- **Application name**: `Coder (coder.ddev.com)` +- **Homepage URL**: `https://coder.ddev.com` +- **Authorization callback URL**: `https://coder.ddev.com/api/v2/users/oauth2/github/callback` +- **Enable Device Flow**: leave unchecked + +Use the staging app's Client ID and Client Secret in `/etc/coder.d/coder.env` on staging-coder.ddev.com, and the production app's credentials on coder.ddev.com. +``` + +**Validation**: +- [ ] Both callback URLs are present and correct +- [ ] Device Flow warning is clear +- [ ] Staging section appears before the env var block it feeds into + +--- + +## Subtask T003 — Document `coder-ddev-com` Org Purpose + +**Purpose**: Explain to operators what `coder-ddev-com` is for — the managed access list for individuals who are not members of the `ddev` org or a sponsor org. + +**Location**: Add a new sub-section after the env var block, titled "### Managing individual access via `coder-ddev-com`". + +**Content to add**: + +```markdown +### Managing individual access via `coder-ddev-com` + +The `coder-ddev-com` GitHub organization is the managed access list for individuals who do not belong to the `ddev` org or one of the sponsor orgs. Adding someone to `coder-ddev-com` grants them signup access to coder.ddev.com without requiring a Coder server restart. + +**To grant access to an individual:** +1. Go to [github.com/coder-ddev-com](https://github.com/coder-ddev-com) → **People** → **Invite member** +2. Enter the person's GitHub username and send the invitation +3. Once they accept, they can log in to coder.ddev.com via GitHub OAuth + +**Initial members** (add these when creating the org): +- `dougvann` — individual $100/month GitHub Sponsor +- `claudiu-cristea` — Webikon sponsor (linked as individual on ddev.com) +- Add LetsTalk, Amedick Sommer, and Pottkinder GmbH contacts when their GitHub usernames are confirmed + +**Note on private membership**: Users do not need to make their `coder-ddev-com` membership public. Private membership is sufficient — the `read:org` OAuth scope allows Coder to verify membership regardless of visibility setting. +``` + +**Validation**: +- [ ] The "initial members" list matches research.md +- [ ] The privacy note is present +- [ ] The section is placed logically after the env var block + +--- + +## Subtask T004 — Add Sponsor Org Access Table + +**Purpose**: Document the full list of approved sponsor org slugs so operators know what's in `ALLOWED_ORGS` and why. + +**Location**: Add a sub-section "### Sponsor org access policy" after the `coder-ddev-com` section from T003. + +**Content to add**: + +```markdown +### Sponsor org access policy + +All $100+/month DDEV sponsors receive access as an org-level benefit: every member of a sponsor's GitHub org can sign in to coder.ddev.com without individual enrollment. MacStadium and JetBrains are excluded (in-kind, not cash sponsors). + +| Company | GitHub org | Source | +| ------- | ---------- | ------ | +| Tag1 | `tag1consulting` | invoiced | +| Upsun | `upsun` | invoiced | +| Platform.sh (Upsun predecessor) | `platformsh` | invoiced | +| Institute for Advanced Studies | `Institute-for-Advanced-Studies` ⚠️ | invoiced | +| CPS-IT | `CPS-IT` | invoiced | +| Redfin Solutions | `redfinsolutions` | invoiced + featured | +| Lullabot | `Lullabot` | invoiced | +| B13 | `b13` | invoiced + featured | +| Pixel & Tonic (Craft CMS) | `pixelandtonic` | invoiced + featured | +| Cambrico | `Cambrico` | invoiced + featured | +| Centarro | `centarro` | invoiced + featured | +| 8mylez | `8mylez` | invoiced | +| dkd Internet Service GmbH | `dkd` | GitHub Sponsors | +| Liip | `liip` | GitHub Sponsors | +| i-gelb GmbH | `i-gelb` | featured | +| Fame Helsinki | `FameHelsinki` | featured | +| Gizra | `Gizra` | featured | +| mobilistics GmbH | `mobilistics` | featured | +| OPTASY | `OPTASY` | featured | +| Passbolt | `passbolt` | featured | +| Værsågod | `vaersaagod` | featured | +| Affinity Bridge | `affinitybridge` | featured | +| Agiledrop | `AGILEDROP` | featured | +| NPO Applications GmbH | `NPO-Applications-GmbH` | featured | +| Aten Design Group | `AtenDesignGroup` | featured | + +⚠️ `Institute-for-Advanced-Studies` — GitHub org exists but has no public name/description. Confirm with operator before deployment that this is the correct org. + +Sponsors with no GitHub org (access via `coder-ddev-com` individual membership instead): LetsTalk, Amedick Sommer, Pottkinder GmbH. +``` + +**Validation**: +- [ ] Table has 25 rows (all confirmed sponsor orgs) +- [ ] IAS warning note is present +- [ ] Excluded and unresolved sponsors are noted + +--- + +## Subtask T005 — Add "Adding a New Sponsor Org" Runbook + +**Purpose**: When a new organization becomes a $100+/month sponsor, an operator needs to know exactly how to grant them access. This runbook is the process. + +**Location**: Add after the sponsor org table, as "#### Adding a new sponsor org". + +**Content to add**: + +```markdown +#### Adding a new sponsor org + +When a new organization reaches the $100+/month sponsorship level: + +1. **Find their GitHub org slug**: Check the sponsor's GitHub profile or ask them directly. Verify with `gh api orgs/ --jq '.login'` — if the command returns the slug, the org exists. + +2. **Add the slug to `ALLOWED_ORGS`** on both staging and production: + ```bash + # On the server, edit /etc/coder.d/coder.env + # Append the new slug to CODER_OAUTH2_GITHUB_ALLOWED_ORGS (comma-separated, no spaces) + sudo systemctl restart coder + ``` + +3. **Test on staging first**: Ask someone from the org to attempt login on staging-coder.ddev.com before updating production. + +4. **Update this table**: Add the org to the sponsor org table above so the list stays accurate. + +5. **Notify the sponsor**: Send the sponsor notification (see `docs/admin/coder-ddev-com/sponsor-notification.md`) letting them know their org members now have access. + +**If the sponsor has no GitHub org**: Add their individual GitHub username to the `coder-ddev-com` org instead (see "Managing individual access" above). No server restart needed. +``` + +**Validation**: +- [ ] The five-step process is present +- [ ] The "no GitHub org" fallback path is documented +- [ ] References to staging-first are consistent with C-004 + +--- + +## Definition of Done + +- [ ] `docs/admin/server-setup.md` contains the full 27-org `ALLOWED_ORGS` value +- [ ] A staging OAuth App sub-section is present with correct callback URL +- [ ] `coder-ddev-com` org purpose and management is documented +- [ ] Sponsor org table is present with all 25 sponsor orgs +- [ ] "Adding a new sponsor org" runbook is present +- [ ] `terraform fmt` is not applicable (Markdown only — run `git diff docs/admin/server-setup.md` to review) +- [ ] No broken Markdown links + +## Risks + +- The `ALLOWED_ORGS` value is long; a typo in a slug silently excludes that org's members. Verify the slug list against `kitty-specs/github-org-gated-signup-01KR1P4G/research.md` before committing. +- `Institute-for-Advanced-Studies` is unverified — note this clearly in the doc. diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md new file mode 100644 index 0000000..b4d1711 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md @@ -0,0 +1,228 @@ +--- +work_package_id: WP02 +title: Update user-management.md with Access Runbook +dependencies: [] +requirement_refs: +- C-001 +- FR-001 +- FR-002 +- FR-004 +- FR-009 +planning_base_branch: 20260507_speckitty +merge_target_branch: 20260507_speckitty +branch_strategy: Implement directly on branch 20260507_speckitty. No worktree needed. +subtasks: +- T006 +- T007 +- T008 +- T009 +history: +- date: '2026-05-07' + event: created +authoritative_surface: docs/admin/user-management.md +execution_mode: code_change +owned_files: +- docs/admin/user-management.md +tags: [] +--- + +# WP02 — Update user-management.md with Access Runbook + +## Branch Strategy + +- **Planning base**: `20260507_speckitty` +- **Merge target**: `20260507_speckitty` +- Implement directly on `20260507_speckitty`. Run `spec-kitty agent action implement WP02 --agent claude`. + +## Objective + +Add a clear "Access Management" section to `docs/admin/user-management.md` covering: +- How to grant individual access via the `coder-ddev-com` GitHub org +- How to pre-create password exception accounts for users who cannot use GitHub OAuth +- Notes on private org membership (private is sufficient — users need not publicize) +- The initial list of `coder-ddev-com` members to add when the org is created + +## Context + +With the org-gated signup model, access to coder.ddev.com is no longer open. Operators need a clear day-to-day runbook for the two ways to grant access: + +1. **Add to `coder-ddev-com` org** — the normal path for individuals not in `ddev` or a sponsor org +2. **Pre-create a password account** — the escape hatch for users who cannot authenticate via GitHub OAuth + +The existing `docs/admin/user-management.md` has good content on Coder user management but says nothing about the org-gated access model. This WP adds a new top-level section that operators can turn to immediately after deployment. + +**Read the current file before editing**: `docs/admin/user-management.md`. The file is 496 lines. Add the new section after the existing "User Accounts" section (currently at the top of the file) — specifically, insert the new "## Access Management" section after line ~60 (after the User Roles subsection), before the existing section that follows it. + +--- + +## Subtask T006 — Add "Access Management" Section Header and Intro + +**Purpose**: Create the section that groups all access-granting procedures, so operators know where to look. + +**Location**: `docs/admin/user-management.md`, as a new top-level `## Access Management` section. Insert it after the "User Roles" subsection (the block ending around line 60) and before the next major section that follows. + +**Content to add**: + +```markdown +## Access Management + +coder.ddev.com restricts new GitHub OAuth signups to members of specific GitHub organizations. This section documents how to grant or revoke access for individuals who are not already in the `ddev` org or a $100+/month sponsor org. + +**The two access paths:** + +1. **`coder-ddev-com` org membership** — For individuals who should have ongoing access. Adding them to the `coder-ddev-com` GitHub org allows them to sign in immediately with no server change. + +2. **Password exception account** — For individuals who cannot or will not use GitHub OAuth. An admin pre-creates their Coder account with a password credential. + +See `docs/admin/server-setup.md` for the full `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` configuration and sponsor org policy. +``` + +**Validation**: +- [ ] Section heading is `## Access Management` (top-level) +- [ ] Both access paths are mentioned +- [ ] Link to server-setup.md is present + +--- + +## Subtask T007 — Document Granting Access via `coder-ddev-com` Org Membership + +**Purpose**: Give operators the exact steps to add an individual to the `coder-ddev-com` GitHub org. + +**Location**: Add a sub-section `### Granting access via coder-ddev-com org membership` immediately inside the "Access Management" section. + +**Content to add**: + +```markdown +### Granting access via `coder-ddev-com` org membership + +Adding someone to the `coder-ddev-com` GitHub org grants them signup access to coder.ddev.com without requiring a Coder server restart. + +**Steps:** +1. Go to [github.com/coder-ddev-com](https://github.com/coder-ddev-com) → **People** → **Invite member** +2. Enter the person's GitHub username and send the invitation +3. Once they accept, they can sign in to coder.ddev.com via GitHub OAuth + +**Requirements:** +- You must be an owner of the `coder-ddev-com` GitHub org to send invitations +- The invitee must have a GitHub account +- They do **not** need to make their membership public — private membership is sufficient (see note on private membership below) + +**Removing access:** +1. Go to [github.com/coder-ddev-com](https://github.com/coder-ddev-com) → **People** +2. Click the member's username → **Remove from organization** +3. Their Coder account remains (they can still log in if they are a `ddev` org member or a member of a sponsor org); their `coder-ddev-com` access path is removed + +**Note**: Removing a user from `coder-ddev-com` does not delete their Coder workspace or account. If full account removal is needed, also delete the user account in Coder (see "Removing User Accounts" below). +``` + +**Validation**: +- [ ] Steps 1–3 for invitation are present +- [ ] Requirements (org owner, no public membership required) are listed +- [ ] Removal steps are present +- [ ] Note about account vs. org membership distinction is present + +--- + +## Subtask T008 — Document Pre-Creating Password Exception Accounts + +**Purpose**: Operators need to know how to create accounts for users who cannot use GitHub OAuth. This is the "escape hatch" path that keeps password auth viable. + +**Location**: Add a sub-section `### Pre-creating password exception accounts` inside the "Access Management" section, after the `coder-ddev-com` sub-section. + +**Content to add**: + +```markdown +### Pre-creating password exception accounts + +For users who cannot or will not authenticate via GitHub OAuth, an admin can pre-create their Coder account with a password credential. This path depends on password authentication being enabled — **`CODER_DISABLE_PASSWORD_AUTH` must never be set to `true`**. + +**When to use this path:** +- The user does not have a GitHub account +- The user has a GitHub account but cannot authorize the OAuth app (e.g., corporate GitHub account with SSO restrictions) +- Emergency admin access is needed without GitHub + +**Steps (via CLI):** +```bash +# Create a user account with email and password prompt +coder users create --email --set-password + +# Or set a specific password (use a strong, random value — user should change it on first login) +coder users create --email --password "" +``` + +**After creating the account:** +1. Share the username and temporary password with the user via a secure channel (not email in plaintext) +2. Instruct the user to change their password on first login: **User Settings → Security → Update Password** +3. Confirm the user can log in at coder.ddev.com before closing the support request + +**Roles:** Accounts created this way default to the "Member" role. If a higher role is needed: +```bash +coder users edit-roles --roles template-admin +``` + +**Note**: Password accounts are exempt from the GitHub org membership check. They can log in regardless of GitHub org membership. +``` + +**Validation**: +- [ ] The `CODER_DISABLE_PASSWORD_AUTH` constraint is mentioned explicitly +- [ ] CLI commands for creating a user are correct +- [ ] The "when to use" list is present +- [ ] Password change instruction is included + +--- + +## Subtask T009 — Add Private Membership Note and Initial `coder-ddev-com` Members + +**Purpose**: Operators need to know that private GitHub org membership works (no extra action needed from users), and they need the initial member list to populate the org when it is created. + +**Location**: Add a sub-section `### Private org membership` inside the "Access Management" section, after the password exception sub-section. Then add a sub-section `### Initial coder-ddev-com members` after it. + +**Content to add**: + +```markdown +### Private org membership + +Users do **not** need to make their `coder-ddev-com` (or `ddev`) org membership public. The Coder server uses the `read:org` OAuth scope, which allows it to check org membership regardless of visibility. Private membership is sufficient. + +If a user reports that they accepted the `coder-ddev-com` invitation but still cannot log in, check: +1. They accepted the invitation (invitation emails expire after 7 days) +2. They are signing in at the correct URL (coder.ddev.com, not an old bookmark to an open-signup URL) +3. Their Coder account exists — if they have never signed in before, they will be creating a new account on first GitHub OAuth login + +### Initial `coder-ddev-com` members + +When the `coder-ddev-com` GitHub org is created, add these initial members: + +| GitHub username | Reason | +| --------------- | ------ | +| `dougvann` | Individual $100/month GitHub Sponsor (confirmed via [ddev/ddev.com#626](https://github.com/ddev/ddev.com/pull/626)) | +| `claudiu-cristea` | Webikon sponsor — ddev.com sponsor link points to individual, not org | + +**Pending — add when GitHub usernames are confirmed:** +- LetsTalk — no GitHub org found; add individual username when known +- Amedick Sommer — no GitHub org found; add individual username when known +- Pottkinder GmbH — no GitHub org found; add individual username when known +``` + +**Validation**: +- [ ] Private membership note is present with explanation of `read:org` scope +- [ ] The troubleshooting checklist for "accepted invite but can't log in" is present +- [ ] `dougvann` and `claudiu-cristea` are in the initial members table +- [ ] Pending members (LetsTalk, Amedick Sommer, Pottkinder) are listed + +--- + +## Definition of Done + +- [ ] `docs/admin/user-management.md` has a `## Access Management` top-level section +- [ ] `coder-ddev-com` org invitation process is documented step-by-step +- [ ] Password exception account creation is documented with CLI commands +- [ ] `CODER_DISABLE_PASSWORD_AUTH` constraint is mentioned +- [ ] Private org membership behavior is explained +- [ ] Initial `coder-ddev-com` member list is present with `dougvann` and `claudiu-cristea` +- [ ] No broken Markdown links + +## Risks + +- The `coder users create` CLI syntax should be verified against the current Coder CLI (`coder users create --help`) before committing — flags may differ across Coder versions. +- Avoid adding the "Access Management" section in a location that breaks the existing document flow. Insert it after the "User Roles" content, not at the very end. diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md new file mode 100644 index 0000000..8a8a349 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md @@ -0,0 +1,302 @@ +--- +work_package_id: WP03 +title: coder-ddev-com Org Content Drafts +dependencies: [] +requirement_refs: +- FR-002 +- FR-010 +- FR-011 +- FR-015 +planning_base_branch: 20260507_speckitty +merge_target_branch: 20260507_speckitty +branch_strategy: Implement directly on branch 20260507_speckitty. No worktree needed. +subtasks: +- T010 +- T011 +- T012 +- T013 +history: +- date: '2026-05-07' + event: created +authoritative_surface: docs/admin/coder-ddev-com/ +execution_mode: planning_artifact +owned_files: +- docs/admin/coder-ddev-com/** +tags: [] +--- + +# WP03 — coder-ddev-com Org Content Drafts + +## Branch Strategy + +- **Planning base**: `20260507_speckitty` +- **Merge target**: `20260507_speckitty` +- Implement directly on `20260507_speckitty`. Run `spec-kitty agent action implement WP03 --agent claude`. + +## Objective + +Produce all content needed to stand up the `coder-ddev-com` GitHub organization: + +1. **Org profile README** — displayed on the org's GitHub page; explains the org's purpose +2. **access-requests repo README** — explains how to open an access request +3. **Access request GitHub issue template** — the structured form prospective users fill out +4. **Sponsor notification message** — the message sent to newly-added sponsor orgs + +All content is committed to `docs/admin/coder-ddev-com/` in this repo for operator use. The operator copies them to the appropriate GitHub locations when setting up the org. + +## Context + +The `coder-ddev-com` GitHub organization does not yet exist. When an operator creates it, they need ready-to-use content for: + +- `.github/profile/README.md` in the org — the GitHub org profile (shown on the org's main page) +- `coder-ddev-com/access-requests` repo — a public repo where prospective users open issues requesting access +- The issue template in that repo (`.github/ISSUE_TEMPLATE/access-request.yml`) +- A short notification message to send to sponsor org owners/maintainers when their org is added to `ALLOWED_ORGS` + +**Create new files** — none of these files exist yet. Create the `docs/admin/coder-ddev-com/` directory and write each file fresh. + +--- + +## Subtask T010 — Write `coder-ddev-com` Org Profile README Draft + +**Purpose**: The org profile README is the first thing visitors see when they visit `github.com/coder-ddev-com`. It must explain the org's purpose, who qualifies, and how membership grants coder.ddev.com access. + +**File to create**: `docs/admin/coder-ddev-com/org-profile-README.md` + +**Operator instruction**: Copy this file's content to `.github/profile/README.md` in the `coder-ddev-com` GitHub org (create a `.github` repo in the org if it does not exist, then add `profile/README.md`). + +**Content to write**: + +```markdown +# coder-ddev-com + +This organization is the managed access list for [coder.ddev.com](https://coder.ddev.com) — a cloud-based DDEV development environment for web developers. + +## What is coder.ddev.com? + +[coder.ddev.com](https://coder.ddev.com) provides cloud-hosted workspaces running [DDEV](https://ddev.com), an open-source local development environment tool for PHP, Node.js, Python, and more projects. Workspaces include VS Code for Web, a terminal, Docker-in-Docker, and full DDEV support — no local setup required. + +## How membership works + +Members of this organization can sign in to coder.ddev.com using GitHub OAuth. Membership is granted by a coder-ddev-com org owner. + +You do **not** need to make your membership public. Private membership is sufficient. + +## Who qualifies? + +Access is available to: + +- Members of the [ddev](https://github.com/ddev) GitHub org +- Members of organizations that sponsor DDEV at $100+/month +- Individuals approved by the DDEV maintainers (this org) + +## Requesting access + +If you do not have access through one of the paths above, open an issue in the [access-requests](https://github.com/coder-ddev-com/access-requests) repository. + +## Questions + +Visit the [DDEV Discord](https://discord.ddev.com) or open an issue in [ddev/ddev](https://github.com/ddev/ddev/issues). +``` + +**Validation**: +- [ ] File is at `docs/admin/coder-ddev-com/org-profile-README.md` +- [ ] Operator instruction (where to copy it) is present as a comment or note at the top of the file +- [ ] Link to access-requests repo is present +- [ ] Private membership note is present +- [ ] The three access tiers (ddev org, sponsor orgs, approved individuals) are mentioned + +--- + +## Subtask T011 — Write access-requests Repo README Draft + +**Purpose**: The `coder-ddev-com/access-requests` repo is where prospective users open issues requesting access. Its README explains what the repo is for and how the process works. + +**File to create**: `docs/admin/coder-ddev-com/access-requests-README.md` + +**Operator instruction**: Create a public repo named `access-requests` in the `coder-ddev-com` GitHub org. Copy this file's content to `README.md` in that repo. + +**Content to write**: + +```markdown +# coder-ddev-com / access-requests + +This repository is the access request tracker for [coder.ddev.com](https://coder.ddev.com). + +## What is coder.ddev.com? + +[coder.ddev.com](https://coder.ddev.com) is a cloud-hosted DDEV development environment for web developers. It provides workspaces running [DDEV](https://ddev.com) with VS Code for Web, a terminal, and full Docker support. + +## Who already has access? + +Access is automatically available (no request needed) if you are: + +- A member of the [ddev](https://github.com/ddev) GitHub org +- A member of an organization that sponsors DDEV at $100+/month + +See the [DDEV sponsors page](https://ddev.com/support-ddev/) for the current list of sponsors. + +## Requesting access + +If you do not have access through one of the above paths, open an issue in this repository using the **Access Request** template. + +We will review your request and, if approved, add you to the `coder-ddev-com` org. You will receive a GitHub invitation — once you accept it, you can sign in to coder.ddev.com with your GitHub account. + +**What to include in your request:** +- Your GitHub username +- Why you want access (brief description — DDEV user, contributor, etc.) + +## Response time + +We aim to respond to requests within a few business days. If you have not heard back in a week, feel free to ping the issue. + +## Questions + +Visit the [DDEV Discord](https://discord.ddev.com) or open an issue in [ddev/ddev](https://github.com/ddev/ddev/issues). +``` + +**Validation**: +- [ ] File is at `docs/admin/coder-ddev-com/access-requests-README.md` +- [ ] Operator instruction (where to copy it) is present +- [ ] "Who already has access" section explains automatic access tiers +- [ ] Clear instructions for opening a request are present +- [ ] Response time expectation is set + +--- + +## Subtask T012 — Write Access Request GitHub Issue Template Draft + +**Purpose**: The issue template structures the access request so reviewers get the information they need (GitHub username, reason for access) without back-and-forth. + +**File to create**: `docs/admin/coder-ddev-com/access-request-issue-template.yml` + +**Operator instruction**: In the `coder-ddev-com/access-requests` repo, create `.github/ISSUE_TEMPLATE/access-request.yml` with this content. + +**Content to write**: + +```yaml +name: Access Request +description: Request access to coder.ddev.com +title: "Access request: [your GitHub username]" +labels: ["access-request"] +body: + - type: markdown + attributes: + value: | + Thanks for your interest in coder.ddev.com! Please fill out the form below. + + **Already have access?** If you are a member of the [ddev](https://github.com/ddev) org + or a $100+/month DDEV sponsor org, you should already have access — try signing in at + [coder.ddev.com](https://coder.ddev.com) first. + + - type: input + id: github_username + attributes: + label: GitHub username + description: Your GitHub username (the one you will use to sign in) + placeholder: "e.g. octocat" + validations: + required: true + + - type: textarea + id: reason + attributes: + label: Why do you want access? + description: Brief description — DDEV contributor, open-source developer, evaluating DDEV for a project, etc. + placeholder: "I maintain a DDEV add-on and want to test it in a cloud workspace..." + validations: + required: true + + - type: checkboxes + id: confirm + attributes: + label: Confirmation + options: + - label: I have checked that I do not already have access through the ddev org or a sponsor org + required: true + - label: I understand this is a shared resource and will use it responsibly + required: true +``` + +**Validation**: +- [ ] File is at `docs/admin/coder-ddev-com/access-request-issue-template.yml` +- [ ] Operator instruction is present +- [ ] `github_username` field is required +- [ ] `reason` textarea is required +- [ ] Confirmation checkboxes are present +- [ ] The pre-check note (ddev org / sponsor org members already have access) is included + +--- + +## Subtask T013 — Write Sponsor Notification Message Template + +**Purpose**: When a new sponsor org is added to `ALLOWED_ORGS`, the DDEV maintainers should notify that org's owners/maintainers so they know their members have access. This template is the message to send. + +**File to create**: `docs/admin/coder-ddev-com/sponsor-notification.md` + +**Operator instruction**: Use this as the text of an email, GitHub issue, or direct message to the sponsor org's maintainer(s). Substitute `[ORG NAME]` and `[GITHUB ORG SLUG]` before sending. + +**Content to write**: + +```markdown + + +Subject: coder.ddev.com access for [ORG NAME] org members + +Hi, + +As a $100+/month sponsor of DDEV, all members of the **[ORG NAME]** GitHub organization ([github.com/[GITHUB ORG SLUG]](https://github.com/[GITHUB ORG SLUG])) now have access to **[coder.ddev.com](https://coder.ddev.com)** — a cloud-hosted DDEV development environment. + +**What is coder.ddev.com?** + +coder.ddev.com provides on-demand cloud workspaces running DDEV with: +- VS Code for Web (full IDE in the browser) +- A terminal +- Docker-in-Docker via Sysbox (full DDEV support, all project types) + +No local setup required — spin up a workspace, start DDEV, and get coding. + +**How to access:** + +1. Visit [coder.ddev.com](https://coder.ddev.com) +2. Click **Sign in with GitHub** +3. Authorize the DDEV Coder app +4. You're in — create a workspace from the Drupal Core, Drupal Contrib, or Freeform template + +All members of the [ORG NAME] GitHub org can sign in. They do not need to be added individually. Org membership does not need to be public. + +**Questions or issues?** + +- [DDEV Discord](https://discord.ddev.com) — `#coder-ddev-com` channel (or any channel) +- [ddev/ddev issues](https://github.com/ddev/ddev/issues) + +Thank you for supporting DDEV! + +— The DDEV maintainers +``` + +**Validation**: +- [ ] File is at `docs/admin/coder-ddev-com/sponsor-notification.md` +- [ ] `[ORG NAME]` and `[GITHUB ORG SLUG]` placeholders are present and clearly marked +- [ ] Operator substitution note is at the top +- [ ] What coder.ddev.com is and how to access it are both explained +- [ ] Contact options (Discord, issues) are present + +--- + +## Definition of Done + +- [ ] `docs/admin/coder-ddev-com/` directory exists with four files: + - `org-profile-README.md` + - `access-requests-README.md` + - `access-request-issue-template.yml` + - `sponsor-notification.md` +- [ ] Each file has an operator instruction note explaining where to copy it +- [ ] Org profile README mentions all three access tiers and links to access-requests repo +- [ ] Issue template is valid YAML with required fields +- [ ] Sponsor notification has clearly marked placeholders + +## Risks + +- The `coder-ddev-com/access-requests` repo URL is referenced in T011 and the org profile README — the repo does not exist yet. Use the anticipated URL `https://github.com/coder-ddev-com/access-requests` in drafts; operator creates the repo before publishing. +- The issue template YAML syntax must be valid. The `type` values (`input`, `textarea`, `checkboxes`, `markdown`) are the standard GitHub issue form types. diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md new file mode 100644 index 0000000..a7c2522 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md @@ -0,0 +1,181 @@ +--- +work_package_id: WP04 +title: Blog Post Update Draft +dependencies: +- WP03 +requirement_refs: +- FR-012 +planning_base_branch: 20260507_speckitty +merge_target_branch: 20260507_speckitty +branch_strategy: Implement directly on branch 20260507_speckitty. Depends on WP03 (needs access-requests repo URL). Run `spec-kitty agent action implement WP04 --agent claude`. +subtasks: +- T014 +- T015 +- T016 +history: +- date: '2026-05-07' + event: created +authoritative_surface: docs/admin/blog-post-draft.md +execution_mode: planning_artifact +owned_files: +- docs/admin/blog-post-draft.md +tags: [] +--- + +# WP04 — Blog Post Update Draft + +## Branch Strategy + +- **Planning base**: `20260507_speckitty` +- **Merge target**: `20260507_speckitty` +- **Depends on WP03** — needs the `coder-ddev-com/access-requests` repo URL established in WP03. +- Implement directly on `20260507_speckitty`. Run `spec-kitty agent action implement WP04 --agent claude`. + +## Objective + +Produce a ready-to-apply patch for `ddev/ddev.com/src/content/blog/coder-ddev-com-announcement.md` that updates the auth description to reflect the org-gated signup model. The patch is committed to `docs/admin/blog-post-draft.md` in this repo; an operator applies it to the `ddev/ddev.com` repo as a separate PR. + +The existing blog post implies open signup ("No separate account needed"). That must be replaced with accurate language explaining: +- Signups are now restricted to org members +- How access works (ddev org, sponsor orgs, coder-ddev-com org) +- Where to request access (access-requests repo) + +## Context + +The blog post lives in a separate repo (`ddev/ddev.com`) and requires its own PR. This WP does not modify that repo directly — it produces a draft that the operator applies. + +**WP03 dependency**: The `coder-ddev-com/access-requests` URL (`https://github.com/coder-ddev-com/access-requests`) is used in the draft. WP03 establishes the content for that repo. Confirm WP03 is complete before finalizing this draft. + +**Target file in `ddev/ddev.com`**: `src/content/blog/coder-ddev-com-announcement.md` + +The draft format in `docs/admin/blog-post-draft.md` should be written so an operator can: +1. Open the file +2. Identify exactly what sections to change in the original blog post +3. Apply the changes with minimal effort (ideally a diff or annotated replacement blocks) + +--- + +## Subtask T014 — Update "Log In with GitHub" Section + +**Purpose**: The current blog post has a section explaining GitHub login ("No separate account needed"). This must be updated to explain that signups are now restricted. + +**File to create**: `docs/admin/blog-post-draft.md` + +**Operator instruction**: Apply the changes in this file to `ddev/ddev.com/src/content/blog/coder-ddev-com-announcement.md` and open a PR to `ddev/ddev.com`. + +First, create the file with a header explaining what this file is and how to use it, followed by the draft content. + +**Content structure for the file**: + +```markdown +# Blog Post Update Draft: coder.ddev.com Org-Gated Signup + +**Target file**: `ddev/ddev.com/src/content/blog/coder-ddev-com-announcement.md` +**Action**: Apply these section replacements to the blog post, then open a PR to `ddev/ddev.com` + +--- + +## Section: "Log In with GitHub" — Replace existing content + +Find the section in the blog post that explains GitHub login. Replace the existing content of that section with the following: + +--- + +### Log In with GitHub + +Access to coder.ddev.com requires a GitHub account. Sign in using the **Sign in with GitHub** button — no separate Coder account registration is needed. + +**Who has access:** + +- Members of the [ddev](https://github.com/ddev) GitHub organization +- Members of organizations that sponsor DDEV at $100+/month (see the [DDEV sponsors page](https://ddev.com/support-ddev/)) +- Individuals approved by the DDEV maintainers + +If you are a `ddev` org member or your organization is a $100+/month sponsor, you can sign in immediately — no request needed. + +--- +``` + +**Validation**: +- [ ] File is created at `docs/admin/blog-post-draft.md` +- [ ] Operator instruction (target file + how to apply) is at the top +- [ ] "Who has access" lists all three tiers +- [ ] The old "No separate account needed" language is replaced (not just appended) + +--- + +## Subtask T015 — Add Access Restriction Paragraph and Access Paths + +**Purpose**: Add a paragraph explaining that signups are restricted and describing the two paths to access: already-in-an-org, or request access. + +**Location**: In `docs/admin/blog-post-draft.md`, append to the section started in T014. + +**Content to append to the draft**: + +```markdown +## Section: Access Restriction and Request Path — Add after "Log In with GitHub" + +Add the following as a new paragraph or subsection immediately after the "Log In with GitHub" section: + +--- + +### Requesting Access + +If you do not have access through one of the paths above, you can request it by opening an issue in the [coder-ddev-com/access-requests](https://github.com/coder-ddev-com/access-requests) repository on GitHub. Include your GitHub username and a brief description of how you plan to use the environment. + +The DDEV maintainers review requests and add approved users to the `coder-ddev-com` GitHub organization. Once added, you can sign in immediately — no server restart needed on our end. + +--- +``` + +**Validation**: +- [ ] Link to `https://github.com/coder-ddev-com/access-requests` is present and correct +- [ ] The process (open issue → review → org invite → sign in) is explained +- [ ] The section is clearly marked as "add after" the previous section + +--- + +## Subtask T016 — Add Sponsor Org Access Benefit Mention + +**Purpose**: Sponsor organizations may not know their members can now log in. Adding a mention in the blog post (and the sponsor notification in WP03) covers the announcement angle. + +**Location**: In `docs/admin/blog-post-draft.md`, append a final section. + +**Content to append to the draft**: + +```markdown +## Section: Sponsor Org Access — Add to "Sponsors" or "Support DDEV" section + +If the blog post has a section mentioning DDEV sponsors, add the following sentence or short paragraph. If no such section exists, add it as a standalone callout near the end of the post: + +--- + +**Sponsor org access**: Organizations that sponsor DDEV at $100+/month receive access as an org-level benefit — all members of a sponsor's GitHub organization can sign in to coder.ddev.com without individual enrollment. See the [DDEV sponsors page](https://ddev.com/support-ddev/) if your organization is interested in sponsoring. + +--- + +**Note for operator**: If the blog post already has a sponsors callout, integrate this sentence rather than adding a duplicate section. +``` + +**Validation**: +- [ ] The sponsor benefit (org-level, all members) is stated clearly +- [ ] Link to ddev.com/support-ddev/ is present +- [ ] Operator note about avoiding duplicates is present + +--- + +## Definition of Done + +- [ ] `docs/admin/blog-post-draft.md` exists and has three clearly delineated sections: + 1. Updated "Log In with GitHub" content + 2. New "Requesting Access" paragraph with link to access-requests repo + 3. Sponsor org access benefit mention +- [ ] Operator instructions at the top of the file explain the target file and how to apply changes +- [ ] All three access tiers are mentioned somewhere in the draft +- [ ] The `coder-ddev-com/access-requests` URL is correct +- [ ] No broken Markdown links + +## Risks + +- The actual blog post content is in a separate repo (`ddev/ddev.com`) that this agent does not have direct access to. The draft is produced without reading the original post, so section names in "Find and replace" instructions are approximate. The operator will need to locate the correct sections by reading the original. +- If the blog post structure has changed significantly since the announcement, the operator may need to adapt the draft rather than apply it verbatim. From ce56ac0c508e570889555a38885a2027d080e81c Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 12:04:41 -0600 Subject: [PATCH 16/53] chore: Map requirements for WP01 on spec github --- .../tasks/WP01-server-setup-update.md | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md index 0711f7a..12371d3 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md @@ -12,6 +12,7 @@ requirement_refs: - FR-005 - FR-006 - FR-007 +- FR-008 - FR-009 - FR-013 - FR-014 From e6720649aab935e7cada8f86fbf06afbbfa8faa6 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 12:04:42 -0600 Subject: [PATCH 17/53] chore: Map requirements for WP02 on spec github --- .../tasks/WP02-user-management-access-runbook.md | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md index b4d1711..55121a6 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md @@ -6,6 +6,7 @@ requirement_refs: - C-001 - FR-001 - FR-002 +- FR-003 - FR-004 - FR-009 planning_base_branch: 20260507_speckitty From 1c34c2c84a578fb8a627a0df2d4830df3b47bfec Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 12:04:47 -0600 Subject: [PATCH 18/53] Add tasks for feature github-org-gated-signup-01KR1P4G --- .../lanes.json | 61 +++++++++++++ .../status.events.jsonl | 4 + .../status.json | 49 ++++++++++ .../github-org-gated-signup-01KR1P4G/tasks.md | 90 +++++++++++++++++++ .../tasks/WP01-server-setup-update.md | 2 +- .../WP02-user-management-access-runbook.md | 2 +- .../tasks/WP03-coder-ddev-com-org-content.md | 2 +- .../tasks/WP04-blog-post-draft.md | 2 +- 8 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/lanes.json create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/status.json create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/tasks.md diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/lanes.json b/kitty-specs/github-org-gated-signup-01KR1P4G/lanes.json new file mode 100644 index 0000000..bd15e64 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/lanes.json @@ -0,0 +1,61 @@ +{ + "version": 1, + "mission_slug": "github-org-gated-signup-01KR1P4G", + "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", + "mission_branch": "kitty/mission-github-org-gated-signup-01KR1P4G", + "target_branch": "20260507_speckitty", + "lanes": [ + { + "lane_id": "lane-a", + "wp_ids": [ + "WP01" + ], + "write_scope": [ + "docs/admin/server-setup.md" + ], + "predicted_surfaces": [ + "api" + ], + "depends_on_lanes": [], + "parallel_group": 0 + }, + { + "lane_id": "lane-b", + "wp_ids": [ + "WP02" + ], + "write_scope": [ + "docs/admin/user-management.md" + ], + "predicted_surfaces": [ + "artifact-rendering", + "legacy-cleanup", + "workspace" + ], + "depends_on_lanes": [], + "parallel_group": 0 + }, + { + "lane_id": "lane-planning", + "wp_ids": [ + "WP03", + "WP04" + ], + "write_scope": [ + "docs/admin/blog-post-draft.md", + "docs/admin/coder-ddev-com/**" + ], + "predicted_surfaces": [ + "planning" + ], + "depends_on_lanes": [], + "parallel_group": 0 + } + ], + "computed_at": "2026-05-07T18:04:47.239797+00:00", + "computed_from": "dependency_graph+ownership", + "planning_artifact_wps": [ + "WP03", + "WP04" + ] +} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index e69de29..7d11cb0 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -0,0 +1,4 @@ +{"actor": "finalize-tasks", "at": "2026-05-07T18:04:47.165313+00:00", "event_id": "01KR1ST5NXMPC2VG8WH5J2C72X", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP01"} +{"actor": "finalize-tasks", "at": "2026-05-07T18:04:47.235255+00:00", "event_id": "01KR1ST5R35T8JA744EC0RMJEN", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP02"} +{"actor": "finalize-tasks", "at": "2026-05-07T18:04:47.236342+00:00", "event_id": "01KR1ST5R4262WM8FB01TBP1QA", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP03"} +{"actor": "finalize-tasks", "at": "2026-05-07T18:04:47.237340+00:00", "event_id": "01KR1ST5R57BNZQ55XMMB3WG64", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP04"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json new file mode 100644 index 0000000..45908ed --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -0,0 +1,49 @@ +{ + "event_count": 4, + "last_event_id": "01KR1ST5R57BNZQ55XMMB3WG64", + "materialized_at": "2026-05-07T18:04:47.237340+00:00", + "mission_number": "", + "mission_slug": "github-org-gated-signup-01KR1P4G", + "mission_type": "software-dev", + "summary": { + "approved": 0, + "blocked": 0, + "canceled": 0, + "claimed": 0, + "done": 0, + "for_review": 0, + "in_progress": 0, + "in_review": 0, + "planned": 4 + }, + "work_packages": { + "WP01": { + "actor": "finalize-tasks", + "force_count": 1, + "lane": "planned", + "last_event_id": "01KR1ST5NXMPC2VG8WH5J2C72X", + "last_transition_at": "2026-05-07T18:04:47.165313+00:00" + }, + "WP02": { + "actor": "finalize-tasks", + "force_count": 1, + "lane": "planned", + "last_event_id": "01KR1ST5R35T8JA744EC0RMJEN", + "last_transition_at": "2026-05-07T18:04:47.235255+00:00" + }, + "WP03": { + "actor": "finalize-tasks", + "force_count": 1, + "lane": "planned", + "last_event_id": "01KR1ST5R4262WM8FB01TBP1QA", + "last_transition_at": "2026-05-07T18:04:47.236342+00:00" + }, + "WP04": { + "actor": "finalize-tasks", + "force_count": 1, + "lane": "planned", + "last_event_id": "01KR1ST5R57BNZQ55XMMB3WG64", + "last_transition_at": "2026-05-07T18:04:47.237340+00:00" + } + } +} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks.md new file mode 100644 index 0000000..a9495bf --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks.md @@ -0,0 +1,90 @@ +# Tasks: GitHub Org-Gated Signup + +**Mission**: github-org-gated-signup-01KR1P4G +**Branch**: `20260507_speckitty` → merge target `20260507_speckitty` +**Created**: 2026-05-07 + +--- + +## Subtask Index + +| ID | Description | WP | Parallel | +| -- | ----------- | -- | -------- | +| T001 | Update `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` in server-setup.md to full 27-org list | WP01 | [P] | +| T002 | Add staging OAuth App sub-section to server-setup.md | WP01 | [P] | +| T003 | Document `coder-ddev-com` org purpose and membership management in server-setup.md | WP01 | [P] | +| T004 | Add sponsor org access table to server-setup.md | WP01 | [P] | +| T005 | Add "Adding a new sponsor org" runbook to server-setup.md | WP01 | | +| T006 | Add "Access Management" top-level section to user-management.md | WP02 | [P] | +| T007 | Document granting access via `coder-ddev-com` org membership | WP02 | [P] | +| T008 | Document pre-creating password exception accounts | WP02 | [P] | +| T009 | Add note about private org membership and list initial `coder-ddev-com` members | WP02 | | +| T010 | Write `coder-ddev-com` org profile README draft | WP03 | [P] | +| T011 | Write access-requests repo README draft | WP03 | [P] | +| T012 | Write access-request GitHub issue template draft | WP03 | [P] | +| T013 | Write sponsor notification message template | WP03 | | +| T014 | Update blog post "Log In with GitHub" section | WP04 | [P] | +| T015 | Add access restriction paragraph and access paths to blog post | WP04 | [P] | +| T016 | Add sponsor org access benefit mention to blog post | WP04 | | + +--- + +## Work Packages + +### WP01 — Update server-setup.md for Org-Gated Auth + +**Priority**: High — all operator instructions depend on this doc +**Goal**: Make `docs/admin/server-setup.md` the authoritative reference for the new auth model: full org list, two-app strategy, coder-ddev-com purpose, sponsor mapping, and the runbook for adding new orgs. +**Dependencies**: none +**Estimated prompt size**: ~380 lines +**Prompt file**: [tasks/WP01-server-setup-update.md](tasks/WP01-server-setup-update.md) + +- [ ] T001 Update `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` to full 27-org list (WP01) +- [ ] T002 Add staging OAuth App sub-section (WP01) +- [ ] T003 Document `coder-ddev-com` org purpose and membership management (WP01) +- [ ] T004 Add sponsor org access table (WP01) +- [ ] T005 Add "Adding a new sponsor org" runbook (WP01) + +--- + +### WP02 — Update user-management.md with Access Runbook + +**Priority**: High — operators need this to grant access after deployment +**Goal**: Add a clear "Access Management" section to `docs/admin/user-management.md` covering individual access via `coder-ddev-com`, exception password accounts, private org membership behavior, and initial members. +**Dependencies**: none +**Estimated prompt size**: ~280 lines +**Prompt file**: [tasks/WP02-user-management-access-runbook.md](tasks/WP02-user-management-access-runbook.md) + +- [ ] T006 Add "Access Management" section header and intro (WP02) +- [ ] T007 Document granting access via `coder-ddev-com` org membership (WP02) +- [ ] T008 Document pre-creating password exception accounts (WP02) +- [ ] T009 Note on private org membership + initial coder-ddev-com members (WP02) + +--- + +### WP03 — coder-ddev-com Org Content Drafts + +**Priority**: High — operators need these to set up the GitHub org and access-request repo +**Goal**: Produce all content needed to stand up the `coder-ddev-com` GitHub org: org profile README, access-requests repo README, issue template, and sponsor notification message. Content committed to `docs/admin/coder-ddev-com/` in this repo for operator use. +**Dependencies**: none +**Estimated prompt size**: ~320 lines +**Prompt file**: [tasks/WP03-coder-ddev-com-org-content.md](tasks/WP03-coder-ddev-com-org-content.md) + +- [ ] T010 Write org profile README draft (WP03) +- [ ] T011 Write access-requests repo README draft (WP03) +- [ ] T012 Write access-request GitHub issue template draft (WP03) +- [ ] T013 Write sponsor notification message template (WP03) + +--- + +### WP04 — Blog Post Update Draft + +**Priority**: Medium — needed before or shortly after production rollout +**Goal**: Produce a ready-to-apply diff for `ddev/ddev.com/src/content/blog/coder-ddev-com-announcement.md` updating the auth description. Draft committed to `docs/admin/blog-post-draft.md` in this repo for operator to PR to ddev.com. +**Dependencies**: WP03 (needs access-requests repo URL) +**Estimated prompt size**: ~220 lines +**Prompt file**: [tasks/WP04-blog-post-draft.md](tasks/WP04-blog-post-draft.md) + +- [ ] T014 Update "Log In with GitHub" section (WP04) +- [ ] T015 Add access restriction paragraph and access paths (WP04) +- [ ] T016 Add sponsor org access benefit mention (WP04) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md index 12371d3..20af17c 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md @@ -18,7 +18,7 @@ requirement_refs: - FR-014 planning_base_branch: 20260507_speckitty merge_target_branch: 20260507_speckitty -branch_strategy: Implement directly on branch 20260507_speckitty. No worktree needed. +branch_strategy: Planning artifacts for this feature were generated on 20260507_speckitty. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into 20260507_speckitty unless the human explicitly redirects the landing branch. subtasks: - T001 - T002 diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md index 55121a6..4a2fdb3 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md @@ -11,7 +11,7 @@ requirement_refs: - FR-009 planning_base_branch: 20260507_speckitty merge_target_branch: 20260507_speckitty -branch_strategy: Implement directly on branch 20260507_speckitty. No worktree needed. +branch_strategy: Planning artifacts for this feature were generated on 20260507_speckitty. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into 20260507_speckitty unless the human explicitly redirects the landing branch. subtasks: - T006 - T007 diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md index 8a8a349..5dda787 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md @@ -9,7 +9,7 @@ requirement_refs: - FR-015 planning_base_branch: 20260507_speckitty merge_target_branch: 20260507_speckitty -branch_strategy: Implement directly on branch 20260507_speckitty. No worktree needed. +branch_strategy: Planning artifacts for this feature were generated on 20260507_speckitty. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into 20260507_speckitty unless the human explicitly redirects the landing branch. subtasks: - T010 - T011 diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md index a7c2522..61bf621 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md @@ -7,7 +7,7 @@ requirement_refs: - FR-012 planning_base_branch: 20260507_speckitty merge_target_branch: 20260507_speckitty -branch_strategy: Implement directly on branch 20260507_speckitty. Depends on WP03 (needs access-requests repo URL). Run `spec-kitty agent action implement WP04 --agent claude`. +branch_strategy: Planning artifacts for this feature were generated on 20260507_speckitty. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into 20260507_speckitty unless the human explicitly redirects the landing branch. subtasks: - T014 - T015 From 6e73737eb3788a3773a78a2c1d006e85b09ea3e4 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:50:21 +0000 Subject: [PATCH 19/53] Add plan for feature github-org-gated-signup-01KR1P4G --- .../github-org-gated-signup-01KR1P4G/plan.md | 183 ++++++++---------- 1 file changed, 83 insertions(+), 100 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md index 51d0efc..bc59470 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md @@ -1,125 +1,108 @@ -# Implementation Plan: GitHub Org-Gated Signup +# Implementation Plan: [FEATURE] +*Path: [templates/plan-template.md](templates/plan-template.md)* -**Branch**: `20260507_speckitty` | **Date**: 2026-05-07 | **Spec**: [spec.md](spec.md) -**Branch contract**: Planning base `20260507_speckitty` → merge target `20260507_speckitty`. +**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link] +**Input**: Feature specification from `/kitty-specs/[###-feature-name]/spec.md` ---- +**Note**: This template is filled in by the `/spec-kitty.plan` command. See `src/specify_cli/missions/software-dev/command-templates/plan.md` for the execution workflow. -## Summary +The planner will not begin until all planning questions have been answered—capture those answers in this document before progressing to later phases. -Restrict new account signups on coder.ddev.com and staging-coder.ddev.com to members of the `ddev` and `coder-ddev-com` GitHub organizations. The Coder server is deployed via the apt deb package and managed by systemd; its runtime configuration lives in `/etc/coder.d/coder.env` on the server host (not committed to this repo). The docs in this repo (`docs/admin/server-setup.md`, `docs/admin/user-management.md`) are the authoritative operator reference and will be updated to reflect the new configuration. Two separate GitHub OAuth Apps (one per environment) will be registered under the `ddev` GitHub org for credential isolation. The `coder-ddev-com` GitHub org will be created as the managed access list for non-ddev-org users. +## Summary ---- +[Extract from feature spec: primary requirement + technical approach from research] ## Technical Context -**Language/Version**: Markdown (documentation updates) -**Primary Dependencies**: Coder server env vars in `/etc/coder.d/coder.env` (managed on host, not in repo) -**Storage**: N/A -**Testing**: Manual scenario tests against staging-coder.ddev.com; existing BATS integration test suite -**Target Platform**: Ubuntu server running Coder via apt deb package + systemd -**Project Type**: Ops change + documentation update -**Performance Goals**: No increase in login round-trip time (under 10 seconds) -**Constraints**: Password auth must remain enabled; staging must be validated before production; OAuth credentials must not be committed to the repo - ---- + + +**Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] +**Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] +**Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] +**Testing**: [Project-specific test approach or NEEDS CLARIFICATION] +**Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] +**Project Type**: [single/web/mobile - determines source structure] +**Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] +**Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] +**Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] ## Charter Check -- **All changes via PR**: ✓ — plan tracked in `kitty-specs/`, doc changes committed via PR on `20260507_speckitty` -- **Staging before production**: ✓ — explicit work package gate between staging validation and production rollout -- **No credentials in repo**: ✓ — `/etc/coder.d/coder.env` is a server-side file; client ID/secret documented as operator-supplied values only -- **Integration tests run against staging**: ✓ — staging validation WP includes manual scenario testing; BATS suite run post-config +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* -No charter violations. - ---- +[Gates determined based on charter file] ## Project Structure -### Spec artifacts +### Documentation (this feature) -```text -kitty-specs/github-org-gated-signup-01KR1P4G/ -├── spec.md ✓ complete -├── plan.md ← this file -├── research.md ← Phase 0 output -└── tasks/ ← populated by /spec-kitty.tasks ``` - -### Source changes (repo root) - -```text -docs/admin/ -├── server-setup.md ← update: add coder-ddev-com to ALLOWED_ORGS, staging OAuth App section -└── user-management.md ← update: add access management runbook section +kitty-specs/[###-feature]/ +├── plan.md # This file (/spec-kitty.plan command output) +├── research.md # Phase 0 output (/spec-kitty.plan command) +├── data-model.md # Phase 1 output (/spec-kitty.plan command) +├── quickstart.md # Phase 1 output (/spec-kitty.plan command) +├── contracts/ # Phase 1 output (/spec-kitty.plan command) +└── tasks.md # Phase 2 output (/spec-kitty.tasks command - NOT created by /spec-kitty.plan) ``` -No Terraform, shell script, or Dockerfile changes required. All Coder server configuration changes are applied on the host via `/etc/coder.d/coder.env`. - ---- - -## Phase 0: Research - -See [research.md](research.md). - -Key findings: all open questions resolved. No `[NEEDS CLARIFICATION]` markers remain. - ---- +### Source Code (repository root) + -## Phase 1: Work Package Approach - -This feature decomposes into three types of work: - -### Type A — Repository changes (agent-implementable) - -1. **Update `docs/admin/server-setup.md`** - - Change `CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev` to `CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com` - - Add a staging OAuth App sub-section (separate app with staging callback URL) - - Add a note explaining the `coder-ddev-com` org purpose and how to manage membership - - Add a note explaining why two separate OAuth Apps are used (credential isolation between environments) - -2. **Update `docs/admin/user-management.md`** - - Add a new "Access Management" section covering: - - How to add a user to the `coder-ddev-com` GitHub org (grants self-serve signup) - - How to pre-create a password exception account (for users who cannot use GitHub OAuth) - - Note: private org membership is sufficient — users do not need to publicize membership - -3. **Write `coder-ddev-com` org README and access-request repo** - - Draft content for the `coder-ddev-com` org README (`.github/profile/README.md` in the org): org purpose, who qualifies, how membership grants Coder access - - Draft issue template for the access-request repo (e.g., `coder-ddev-com/access-requests`): name, GitHub username, reason for access - - Draft README for the access-request repo explaining how to open a request and what to expect - -4. **Draft sponsor notification message** - - Write a short email/message template announcing the access benefit to sponsor orgs: what coder.ddev.com is, that their org members can now log in with GitHub, link to the getting-started doc, and DDEV Discord/issues for support - - Store draft in `docs/admin/` or as a committed template for the operator to send - -5. **Resolve $100+ sponsor GitHub org names and update server-setup.md** - - Identify which current $100+/month sponsors are GitHub organizations (vs. individuals): cross-reference the invoiced list (cps-it, Redfin Solutions, LetsTalk, Institute for Advanced Studies, Tag1, Upsun, B13, Lullabot, 8mylez, Cambrico, Centarro, Pixel & Tonic) against GitHub org slugs - - Update `docs/admin/server-setup.md` to document the sponsor-org access policy and show the full example `ALLOWED_ORGS` value including sponsor org slugs - - Update the sponsors-to-orgs mapping as a maintained comment or table in `docs/admin/server-setup.md` (since `invoiced-sponsorships.jsonc` has no GitHub org field) - -6. **Update ddev.com blog post** (`ddev/ddev.com` repo — separate PR required) - - Update the "Log In with GitHub" section: replace "No separate account needed" with an explanation that signups are restricted to `ddev` and `coder-ddev-com` org members - - Add a paragraph explaining how users outside the `ddev` org can request access by opening an issue in the `coder-ddev-com/access-requests` repo - - Add a link to the access-request repo +``` +# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) +src/ +├── models/ +├── services/ +├── cli/ +└── lib/ + +tests/ +├── contract/ +├── integration/ +└── unit/ + +# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) +backend/ +├── src/ +│ ├── models/ +│ ├── services/ +│ └── api/ +└── tests/ + +frontend/ +├── src/ +│ ├── components/ +│ ├── pages/ +│ └── services/ +└── tests/ + +# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) +api/ +└── [same as backend above] + +ios/ or android/ +└── [platform-specific structure: feature modules, UI flows, platform tests] +``` -### Type B — Ops tasks (operator-executed, documented in runbook) +**Structure Decision**: [Document the selected structure and reference the real +directories captured above] -1. **Create `coder-ddev-com` GitHub org** — one-time action; add `dougvann` (individual $100/month GitHub Sponsor) as an initial member; LetsTalk contact added when identified -2. **Register staging OAuth App** under `ddev` org with callback `https://staging-coder.ddev.com/api/v2/users/oauth2/github/callback` -3. **Register production OAuth App** under `ddev` org with callback `https://coder.ddev.com/api/v2/users/oauth2/github/callback` -4. **Apply config to staging**: update `/etc/coder.d/coder.env` with `ALLOWED_ORGS=ddev,coder-ddev-com,,...`, restart `coder` service, validate all scenarios from spec -5. **Apply config to production**: repeat after staging validation passes -6. **Notify sponsor orgs**: reach out to each org in `ALLOWED_ORGS` (excluding `ddev` and `coder-ddev-com`) to let them know their members now have access — what coder.ddev.com is, how to use it, and where to get help (DDEV Discord, issues). Draft notification message as part of Type A work. +## Complexity Tracking -### Staging validation scenarios (must all pass before production) +*Fill ONLY if Charter Check has violations that must be justified* -| # | Scenario | Expected | -| - | -------- | -------- | -| 1 | `ddev` org member signs in via GitHub | Account created, dashboard loads | -| 2 | `coder-ddev-com` org member signs in via GitHub | Account created, dashboard loads | -| 3 | Unauthorized GitHub user attempts sign-in | Error shown, no account created | -| 4 | Existing user (pre-existing account) logs in | Access unchanged | -| 5 | Exception account via password | Password login succeeds | +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | +| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | From 8d985f8ef3dc4945f596abb22b41d236b6a2edc9 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:52:23 +0000 Subject: [PATCH 20/53] Add tasks for feature github-org-gated-signup-01KR1P4G --- .../lanes.json | 2 +- .../github-org-gated-signup-01KR1P4G/tasks.md | 97 +++++-------------- 2 files changed, 27 insertions(+), 72 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/lanes.json b/kitty-specs/github-org-gated-signup-01KR1P4G/lanes.json index bd15e64..213efbf 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/lanes.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/lanes.json @@ -52,7 +52,7 @@ "parallel_group": 0 } ], - "computed_at": "2026-05-07T18:04:47.239797+00:00", + "computed_at": "2026-05-07T18:52:22.964347+00:00", "computed_from": "dependency_graph+ownership", "planning_artifact_wps": [ "WP03", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks.md index a9495bf..214b7d3 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks.md @@ -1,90 +1,45 @@ -# Tasks: GitHub Org-Gated Signup +# Work Packages: github-org-gated-signup-01KR1P4G -**Mission**: github-org-gated-signup-01KR1P4G -**Branch**: `20260507_speckitty` → merge target `20260507_speckitty` -**Created**: 2026-05-07 +_Generated by finalize-tasks from wps.yaml. Do not edit directly._ --- -## Subtask Index +## Work Package WP01: Update server-setup.md for Org-Gated Auth -| ID | Description | WP | Parallel | -| -- | ----------- | -- | -------- | -| T001 | Update `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` in server-setup.md to full 27-org list | WP01 | [P] | -| T002 | Add staging OAuth App sub-section to server-setup.md | WP01 | [P] | -| T003 | Document `coder-ddev-com` org purpose and membership management in server-setup.md | WP01 | [P] | -| T004 | Add sponsor org access table to server-setup.md | WP01 | [P] | -| T005 | Add "Adding a new sponsor org" runbook to server-setup.md | WP01 | | -| T006 | Add "Access Management" top-level section to user-management.md | WP02 | [P] | -| T007 | Document granting access via `coder-ddev-com` org membership | WP02 | [P] | -| T008 | Document pre-creating password exception accounts | WP02 | [P] | -| T009 | Add note about private org membership and list initial `coder-ddev-com` members | WP02 | | -| T010 | Write `coder-ddev-com` org profile README draft | WP03 | [P] | -| T011 | Write access-requests repo README draft | WP03 | [P] | -| T012 | Write access-request GitHub issue template draft | WP03 | [P] | -| T013 | Write sponsor notification message template | WP03 | | -| T014 | Update blog post "Log In with GitHub" section | WP04 | [P] | -| T015 | Add access restriction paragraph and access paths to blog post | WP04 | [P] | -| T016 | Add sponsor org access benefit mention to blog post | WP04 | | +**Dependencies**: None +**Requirement Refs**: FR-001, FR-005, FR-006, FR-007, FR-013, FR-014, C-005, C-006, C-007 +**Owned Files**: docs/admin/server-setup.md +**Subtasks**: T001, T002, T003, T004, T005 +**Prompt**: `tasks/WP01-server-setup-update.md` --- -## Work Packages +## Work Package WP02: Update user-management.md with Access Runbook -### WP01 — Update server-setup.md for Org-Gated Auth - -**Priority**: High — all operator instructions depend on this doc -**Goal**: Make `docs/admin/server-setup.md` the authoritative reference for the new auth model: full org list, two-app strategy, coder-ddev-com purpose, sponsor mapping, and the runbook for adding new orgs. -**Dependencies**: none -**Estimated prompt size**: ~380 lines -**Prompt file**: [tasks/WP01-server-setup-update.md](tasks/WP01-server-setup-update.md) - -- [ ] T001 Update `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` to full 27-org list (WP01) -- [ ] T002 Add staging OAuth App sub-section (WP01) -- [ ] T003 Document `coder-ddev-com` org purpose and membership management (WP01) -- [ ] T004 Add sponsor org access table (WP01) -- [ ] T005 Add "Adding a new sponsor org" runbook (WP01) +**Dependencies**: None +**Requirement Refs**: FR-002, FR-003, FR-004, FR-009, NFR-002, C-001 +**Owned Files**: docs/admin/user-management.md +**Subtasks**: T006, T007, T008, T009 +**Prompt**: `tasks/WP02-user-management-access-runbook.md` --- -### WP02 — Update user-management.md with Access Runbook +## Work Package WP03: coder-ddev-com Org Content Drafts -**Priority**: High — operators need this to grant access after deployment -**Goal**: Add a clear "Access Management" section to `docs/admin/user-management.md` covering individual access via `coder-ddev-com`, exception password accounts, private org membership behavior, and initial members. -**Dependencies**: none -**Estimated prompt size**: ~280 lines -**Prompt file**: [tasks/WP02-user-management-access-runbook.md](tasks/WP02-user-management-access-runbook.md) - -- [ ] T006 Add "Access Management" section header and intro (WP02) -- [ ] T007 Document granting access via `coder-ddev-com` org membership (WP02) -- [ ] T008 Document pre-creating password exception accounts (WP02) -- [ ] T009 Note on private org membership + initial coder-ddev-com members (WP02) +**Dependencies**: None +**Requirement Refs**: FR-010, FR-011, FR-015, C-002 +**Owned Files**: docs/admin/coder-ddev-com/** +**Subtasks**: T010, T011, T012, T013 +**Prompt**: `tasks/WP03-coder-ddev-com-org-content.md` --- -### WP03 — coder-ddev-com Org Content Drafts - -**Priority**: High — operators need these to set up the GitHub org and access-request repo -**Goal**: Produce all content needed to stand up the `coder-ddev-com` GitHub org: org profile README, access-requests repo README, issue template, and sponsor notification message. Content committed to `docs/admin/coder-ddev-com/` in this repo for operator use. -**Dependencies**: none -**Estimated prompt size**: ~320 lines -**Prompt file**: [tasks/WP03-coder-ddev-com-org-content.md](tasks/WP03-coder-ddev-com-org-content.md) +## Work Package WP04: Blog Post Update Draft -- [ ] T010 Write org profile README draft (WP03) -- [ ] T011 Write access-requests repo README draft (WP03) -- [ ] T012 Write access-request GitHub issue template draft (WP03) -- [ ] T013 Write sponsor notification message template (WP03) +**Dependencies**: WP03 +**Requirement Refs**: FR-012, FR-008 +**Owned Files**: docs/admin/blog-post-draft.md +**Subtasks**: T014, T015, T016 +**Prompt**: `tasks/WP04-blog-post-draft.md` --- - -### WP04 — Blog Post Update Draft - -**Priority**: Medium — needed before or shortly after production rollout -**Goal**: Produce a ready-to-apply diff for `ddev/ddev.com/src/content/blog/coder-ddev-com-announcement.md` updating the auth description. Draft committed to `docs/admin/blog-post-draft.md` in this repo for operator to PR to ddev.com. -**Dependencies**: WP03 (needs access-requests repo URL) -**Estimated prompt size**: ~220 lines -**Prompt file**: [tasks/WP04-blog-post-draft.md](tasks/WP04-blog-post-draft.md) - -- [ ] T014 Update "Log In with GitHub" section (WP04) -- [ ] T015 Add access restriction paragraph and access paths (WP04) -- [ ] T016 Add sponsor org access benefit mention (WP04) From d0a0af178cdf54a2b599477c095bd2f853c47fc0 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:56:26 +0000 Subject: [PATCH 21/53] chore: WP01 claimed for implementation --- .../status.events.jsonl | 2 ++ .../status.json | 18 +++++++++--------- .../tasks/WP01-server-setup-update.md | 4 ++++ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 7d11cb0..fc0fa9c 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -2,3 +2,5 @@ {"actor": "finalize-tasks", "at": "2026-05-07T18:04:47.235255+00:00", "event_id": "01KR1ST5R35T8JA744EC0RMJEN", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP02"} {"actor": "finalize-tasks", "at": "2026-05-07T18:04:47.236342+00:00", "event_id": "01KR1ST5R4262WM8FB01TBP1QA", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP03"} {"actor": "finalize-tasks", "at": "2026-05-07T18:04:47.237340+00:00", "event_id": "01KR1ST5R57BNZQ55XMMB3WG64", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP04"} +{"actor": "implement-command", "at": "2026-05-07T18:56:26.259833+00:00", "event_id": "01KR1WRR4K4VCB3EHN49FWMNCD", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP01"} +{"actor": "implement-command", "at": "2026-05-07T18:56:26.350632+00:00", "event_id": "01KR1WRR7EDJNJ3QKMNGWQKN4C", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP01"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 45908ed..6b62b2e 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,7 +1,7 @@ { - "event_count": 4, - "last_event_id": "01KR1ST5R57BNZQ55XMMB3WG64", - "materialized_at": "2026-05-07T18:04:47.237340+00:00", + "event_count": 6, + "last_event_id": "01KR1WRR7EDJNJ3QKMNGWQKN4C", + "materialized_at": "2026-05-07T18:56:26.350632+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", @@ -12,17 +12,17 @@ "claimed": 0, "done": 0, "for_review": 0, - "in_progress": 0, + "in_progress": 1, "in_review": 0, - "planned": 4 + "planned": 3 }, "work_packages": { "WP01": { - "actor": "finalize-tasks", + "actor": "implement-command", "force_count": 1, - "lane": "planned", - "last_event_id": "01KR1ST5NXMPC2VG8WH5J2C72X", - "last_transition_at": "2026-05-07T18:04:47.165313+00:00" + "lane": "in_progress", + "last_event_id": "01KR1WRR7EDJNJ3QKMNGWQKN4C", + "last_transition_at": "2026-05-07T18:56:26.350632+00:00" }, "WP02": { "actor": "finalize-tasks", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md index 20af17c..d55d756 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md @@ -19,12 +19,16 @@ requirement_refs: planning_base_branch: 20260507_speckitty merge_target_branch: 20260507_speckitty branch_strategy: Planning artifacts for this feature were generated on 20260507_speckitty. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into 20260507_speckitty unless the human explicitly redirects the landing branch. +base_branch: kitty/mission-github-org-gated-signup-01KR1P4G +base_commit: e125c1d60f5ea0f1c84475d06a5947d15b201b60 +created_at: '2026-05-07T18:56:26.245758+00:00' subtasks: - T001 - T002 - T003 - T004 - T005 +shell_pid: '25745' history: - date: '2026-05-07' event: created From e125c1d60f5ea0f1c84475d06a5947d15b201b60 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:56:26 +0000 Subject: [PATCH 22/53] chore: planning artifacts for github-org-gated-signup-01KR1P4G Auto-committed by spec-kitty before creating the lane worktree for WP01 --- .../data-model.md | 98 +++++++++ .../mission-events.jsonl | 7 + .../github-org-gated-signup-01KR1P4G/plan.md | 189 ++++++++++-------- .../research/evidence-log.csv | 23 +++ .../research/source-register.csv | 25 +++ .../github-org-gated-signup-01KR1P4G/wps.yaml | 74 +++++++ 6 files changed, 333 insertions(+), 83 deletions(-) create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/data-model.md create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/research/evidence-log.csv create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/research/source-register.csv create mode 100644 kitty-specs/github-org-gated-signup-01KR1P4G/wps.yaml diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/data-model.md b/kitty-specs/github-org-gated-signup-01KR1P4G/data-model.md new file mode 100644 index 0000000..1c9b57e --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/data-model.md @@ -0,0 +1,98 @@ +# Data Model: GitHub Org-Gated Signup + +## Entities + +### GitHub OAuth App +Represents the custom DDEV-owned GitHub OAuth application registered under the `ddev` org. + +| Attribute | Type | Notes | +| --------- | ---- | ----- | +| `client_id` | string | Unique per environment (staging vs production) | +| `client_secret` | string | Secret; stored only in `/etc/coder.d/coder.env` on host | +| `owner_org` | string | Always `ddev` (institutional ownership) | +| `callback_url` | string | e.g. `https://coder.ddev.com/api/v2/users/oidc/callback` | +| `scopes` | string[] | `read:user`, `user:email`, `read:org` | + +**Notes**: Two separate OAuth App instances exist — one for staging, one for production. Credentials are never committed to this repo. + +--- + +### GitHub Organization +Represents a GitHub org whose members are allowed to create Coder accounts. + +| Attribute | Type | Notes | +| --------- | ---- | ----- | +| `org_slug` | string | GitHub org handle (e.g. `ddev`, `coder-ddev-com`) | +| `org_type` | enum | `core` \| `managed-access-list` \| `sponsor` | +| `access_method` | enum | `direct` — members sign in via org membership | +| `added_to_allowed_orgs` | bool | Whether the slug appears in `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` | + +**Org type meanings:** +- `core` — `ddev` org; all DDEV contributors. Primary access channel. +- `managed-access-list` — `coder-ddev-com` org; explicitly managed list for individuals outside `ddev`. +- `sponsor` — $100+/month sponsor orgs; members get access without individual enrollment in `coder-ddev-com`. + +**Current allowed orgs (27 total):** +`ddev`, `coder-ddev-com`, `tag1consulting`, `upsun`, `platformsh`, `Institute-for-Advanced-Studies`, `CPS-IT`, `redfinsolutions`, `Lullabot`, `b13`, `pixelandtonic`, `Cambrico`, `centarro`, `8mylez`, `dkd`, `liip`, `i-gelb`, `FameHelsinki`, `Gizra`, `mobilistics`, `OPTASY`, `passbolt`, `vaersaagod`, `affinitybridge`, `AGILEDROP`, `NPO-Applications-GmbH`, `AtenDesignGroup` + +--- + +### Coder User +Represents a user account on coder.ddev.com or staging-coder.ddev.com. + +| Attribute | Type | Notes | +| --------- | ---- | ----- | +| `username` | string | Coder account identifier | +| `auth_method` | enum | `github-oauth` \| `password` | +| `account_status` | enum | `existing` \| `new` | +| `github_org_membership` | string[] | Orgs the user belongs to (checked at signup) | + +**Notes**: Existing accounts created before org-gating are preserved. New signups require org membership. Password-auth accounts remain usable and are never disabled (`CODER_DISABLE_PASSWORD_AUTH` is not set). + +--- + +### Coder Server Environment +Represents the runtime configuration of one Coder server instance. + +| Attribute | Type | Notes | +| --------- | ---- | ----- | +| `config_file` | string | `/etc/coder.d/coder.env` | +| `environment` | enum | `staging` \| `production` | +| `CODER_OAUTH2_GITHUB_CLIENT_ID` | string | From OAuth App for this environment | +| `CODER_OAUTH2_GITHUB_CLIENT_SECRET` | string | From OAuth App for this environment | +| `CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS` | bool | Must be `true` | +| `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` | string | Comma-separated org slug list | +| `CODER_OAUTH2_GITHUB_DEVICE_FLOW` | bool | Must NOT be `true` (breaks `read:org`) | +| `CODER_DISABLE_PASSWORD_AUTH` | bool | Must NOT be `true` | + +--- + +## Relationships + +``` +Coder Server Environment + └─ uses ──► GitHub OAuth App (one per environment) + └─ allows ──► GitHub Organization (many, via ALLOWED_ORGS) + └─ grants access to ──► Coder User (new signups) + +Coder User + ├─ auth_method: github-oauth ──► must belong to at least one allowed GitHub org + └─ auth_method: password ──► manually pre-created; org membership not checked +``` + +--- + +## Configuration Scope + +This feature involves **no code changes** — only documentation and operator-applied server configuration: + +| Layer | Changes | +| ----- | ------- | +| Terraform templates | None | +| Docker image | None | +| Shell scripts | None | +| Docs (`docs/admin/server-setup.md`) | Update ALLOWED_ORGS, add staging OAuth section, document coder-ddev-com, add sponsor table and runbook | +| Docs (`docs/admin/user-management.md`) | Add Access Management section | +| Docs (`docs/admin/coder-ddev-com/`) | New directory: org profile README, access-requests repo README, issue template, sponsor notification | +| Docs (`docs/admin/blog-post-draft.md`) | Draft diff for ddev.com blog post | +| Server host (out of repo) | `/etc/coder.d/coder.env` on staging then production | diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl new file mode 100644 index 0000000..b714339 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -0,0 +1,7 @@ +{"mission": "software-dev", "payload": {"action": "research", "agent": "claude", "decision_kind": "step", "mission_state": "discovery", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:47:44.275563+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "specify", "agent": "claude", "decision_kind": "step", "mission_state": "specify", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:49:45.261254+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "plan", "agent": "claude", "decision_kind": "step", "mission_state": "plan", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:50:03.176007+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "tasks-outline", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_outline", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:51:05.562761+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "tasks-packages", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_packages", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:51:46.676287+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "tasks-finalize", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_finalize", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:52:15.848056+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-07T18:52:28.638408+00:00", "type": "MissionNextInvoked"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md index bc59470..f01d47d 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/plan.md @@ -1,108 +1,131 @@ -# Implementation Plan: [FEATURE] -*Path: [templates/plan-template.md](templates/plan-template.md)* +# Implementation Plan: GitHub Org-Gated Signup +**Branch**: `20260507_speckitty` | **Date**: 2026-05-07 | **Spec**: [spec.md](spec.md) -**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link] -**Input**: Feature specification from `/kitty-specs/[###-feature-name]/spec.md` +**Branch contract**: Planning base `20260507_speckitty` → merge target `20260507_speckitty`. -**Note**: This template is filled in by the `/spec-kitty.plan` command. See `src/specify_cli/missions/software-dev/command-templates/plan.md` for the execution workflow. - -The planner will not begin until all planning questions have been answered—capture those answers in this document before progressing to later phases. +--- ## Summary -[Extract from feature spec: primary requirement + technical approach from research] +Restrict new account signups on coder.ddev.com and staging-coder.ddev.com to members of the `ddev` and `coder-ddev-com` GitHub organizations. The Coder server is deployed via the apt deb package and managed by systemd; its runtime configuration lives in `/etc/coder.d/coder.env` on the server host (not committed to this repo). The docs in this repo (`docs/admin/server-setup.md`, `docs/admin/user-management.md`) are the authoritative operator reference and will be updated to reflect the new configuration. Two separate GitHub OAuth Apps (one per environment) will be registered under the `ddev` GitHub org for credential isolation. The `coder-ddev-com` GitHub org will be created as the managed access list for non-ddev-org users. + +--- ## Technical Context - - -**Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] -**Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] -**Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] -**Testing**: [Project-specific test approach or NEEDS CLARIFICATION] -**Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] -**Project Type**: [single/web/mobile - determines source structure] -**Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] -**Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] -**Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] +**Language/Version**: Markdown (documentation updates) +**Primary Dependencies**: Coder server env vars in `/etc/coder.d/coder.env` (managed on host, not in repo) +**Storage**: N/A +**Testing**: Manual scenario tests against staging-coder.ddev.com; existing BATS integration test suite +**Target Platform**: Ubuntu server running Coder via apt deb package + systemd +**Project Type**: Ops change + documentation update +**Performance Goals**: No increase in login round-trip time (under 10 seconds) +**Constraints**: Password auth must remain enabled; staging must be validated before production; OAuth credentials must not be committed to the repo + +--- ## Charter Check -*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* +- **All changes via PR**: ✓ — plan tracked in `kitty-specs/`, doc changes committed via PR on `20260507_speckitty` +- **Staging before production**: ✓ — explicit work package gate between staging validation and production rollout +- **No credentials in repo**: ✓ — `/etc/coder.d/coder.env` is a server-side file; client ID/secret documented as operator-supplied values only +- **Integration tests run against staging**: ✓ — staging validation WP includes manual scenario testing; BATS suite run post-config + +No charter violations. -[Gates determined based on charter file] +--- ## Project Structure -### Documentation (this feature) +### Spec artifacts -``` -kitty-specs/[###-feature]/ -├── plan.md # This file (/spec-kitty.plan command output) -├── research.md # Phase 0 output (/spec-kitty.plan command) -├── data-model.md # Phase 1 output (/spec-kitty.plan command) -├── quickstart.md # Phase 1 output (/spec-kitty.plan command) -├── contracts/ # Phase 1 output (/spec-kitty.plan command) -└── tasks.md # Phase 2 output (/spec-kitty.tasks command - NOT created by /spec-kitty.plan) +```text +kitty-specs/github-org-gated-signup-01KR1P4G/ +├── spec.md ✓ complete +├── plan.md ← this file +├── research.md ← Phase 0 output +└── tasks/ ← populated by /spec-kitty.tasks ``` -### Source Code (repository root) - +### Source changes (repo root) +```text +docs/admin/ +├── server-setup.md ← update: ALLOWED_ORGS full list, staging OAuth App section, coder-ddev-com docs, sponsor table, runbook +├── user-management.md ← update: add "Access Management" section +├── coder-ddev-com/ ← new: org README, access-requests repo README, issue template, sponsor notification +└── blog-post-draft.md ← new: ready-to-apply diff for ddev.com blog post ``` -# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) -src/ -├── models/ -├── services/ -├── cli/ -└── lib/ - -tests/ -├── contract/ -├── integration/ -└── unit/ - -# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) -backend/ -├── src/ -│ ├── models/ -│ ├── services/ -│ └── api/ -└── tests/ - -frontend/ -├── src/ -│ ├── components/ -│ ├── pages/ -│ └── services/ -└── tests/ - -# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) -api/ -└── [same as backend above] - -ios/ or android/ -└── [platform-specific structure: feature modules, UI flows, platform tests] -``` -**Structure Decision**: [Document the selected structure and reference the real -directories captured above] +No Terraform, shell script, or Dockerfile changes required. + +--- + +## Phase 0: Research + +See [research.md](research.md). + +Key findings: all open questions resolved. No `[NEEDS CLARIFICATION]` markers remain. + +--- + +## Phase 1: Work Package Approach + +This feature decomposes into four work packages corresponding to the four documentation areas. + +### WP01 — Update `docs/admin/server-setup.md` + +- Update `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` to full 27-org list +- Add staging OAuth App sub-section (separate app, staging callback URL) +- Document `coder-ddev-com` org purpose and membership management +- Add sponsor org access table (company → GitHub slug mapping) +- Add "Adding a new sponsor org" runbook + +### WP02 — Update `docs/admin/user-management.md` + +- Add "Access Management" top-level section +- Document granting access via `coder-ddev-com` org membership +- Document pre-creating password exception accounts +- Note on private org membership; list initial `coder-ddev-com` members + +### WP03 — `coder-ddev-com` org content drafts (`docs/admin/coder-ddev-com/`) + +- Org profile README draft (`.github/profile/README.md` content for the org) +- `access-requests` repo README draft (how to open a request, what to expect) +- Access-request GitHub issue template draft +- Sponsor notification message template + +### WP04 — Blog post update draft (`docs/admin/blog-post-draft.md`) + +- Update "Log In with GitHub" section — no longer open signup +- Add access restriction paragraph and access paths (coder-ddev-com, access-requests link) +- Add sponsor org access benefit mention +- This is a draft diff for an operator to submit as a PR to `ddev/ddev.com` + +**WP04 depends on WP03** (needs access-requests repo URL/name). + +--- + +## Staging Validation Scenarios (must all pass before production) + +| # | Scenario | Expected | +| - | -------- | -------- | +| 1 | `ddev` org member signs in via GitHub | Account created, dashboard loads | +| 2 | `coder-ddev-com` org member signs in via GitHub | Account created, dashboard loads | +| 3 | Unauthorized GitHub user attempts sign-in | Error shown, no account created | +| 4 | Existing user (pre-existing account) logs in | Access unchanged | +| 5 | Exception account via password | Password login succeeds | + +--- -## Complexity Tracking +## Ops Tasks (operator-executed, documented in runbook) -*Fill ONLY if Charter Check has violations that must be justified* +These are documented in the deliverables but not automated by this repo: -| Violation | Why Needed | Simpler Alternative Rejected Because | -|-----------|------------|-------------------------------------| -| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | -| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | +1. Create `coder-ddev-com` GitHub org; add initial members (`dougvann`, others when known) +2. Register staging OAuth App under `ddev` org with staging callback URL +3. Register production OAuth App under `ddev` org with production callback URL +4. Apply config to staging; validate all 5 scenarios above +5. Apply config to production after staging validation passes +6. Notify each sponsor org in `ALLOWED_ORGS` (use WP03 notification template) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/research/evidence-log.csv b/kitty-specs/github-org-gated-signup-01KR1P4G/research/evidence-log.csv new file mode 100644 index 0000000..226045f --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/research/evidence-log.csv @@ -0,0 +1,23 @@ +# Evidence Log: Track all research findings with citations +# +# Column Definitions: +# - timestamp: When evidence was collected (ISO format: YYYY-MM-DDTHH:MM:SS) +# - source_type: journal | conference | book | web | preprint +# - citation: Full citation (BibTeX, APA, or Simple format) +# - key_finding: Main takeaway from this source (1-2 sentences) +# - confidence: high | medium | low (based on source quality and clarity) +# - notes: Additional context, caveats, or methodological notes +# +# Validation: Citations must be non-empty, source_type must be valid +# Format: BibTeX (@article{...}) or APA (Author (Year). Title.) recommended +timestamp,source_type,citation,key_finding,confidence,notes +2026-05-07T17:00:00,web,"Coder Docs. GitHub OAuth. https://coder.com/docs/admin/external-auth",CODER_OAUTH2_GITHUB_ALLOWED_ORGS restricts new signups to members of listed GitHub orgs.,high,Primary reference for env var names and behavior +2026-05-07T17:00:00,web,"Coder Docs. GitHub OAuth — Custom App. https://coder.com/docs/admin/external-auth","For production, Coder strongly recommends a custom GitHub OAuth App to avoid sharing org membership data with Coder the company.",high,Quoted directly in research.md +2026-05-07T17:00:00,web,"GitHub Docs. OAuth scopes. https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps",The read:org scope allows reading private org membership without requiring users to publicize it.,high,Satisfies NFR-002 +2026-05-07T17:00:00,web,"Coder Docs. Device Flow warning. https://coder.com/docs/admin/external-auth",Device flow (CODER_OAUTH2_GITHUB_DEVICE_FLOW=true) does not request read:org; enabling it alongside ALLOWED_ORGS causes 403 errors on org membership checks.,high,Already documented in server-setup.md; must remain in runbook +2026-05-07T17:00:00,web,"ddev/ddev.com PR #626. https://github.com/ddev/ddev.com/pull/626","Individual GitHub Sponsor dougvann confirmed at $100/month tier; no associated org, so add to coder-ddev-com.",medium,Used to resolve individual vs org ambiguity for dougvann +2026-05-07T17:00:00,web,"ddev/sponsorship-data invoiced-sponsorships.jsonc (repo internal)",invoiced-sponsorships.jsonc records billing tiers and company names but does not contain GitHub org slugs; manual mapping required.,high,Constraint C-007 in spec +2026-05-07T17:00:00,web,"GitHub org search and API lookups (manual, 2026-05-07)",Resolved 24 sponsor org slugs via GitHub org search. Institute-for-Advanced-Studies org exists but unverified — requires operator confirmation.,medium,See sponsor table in research.md for full mapping +2026-05-07T17:00:00,web,"ddev.com /support/sponsors page (featured sponsors list)",Featured sponsors on ddev.com are all at $100+/month. MacStadium and JetBrains are in-kind (excluded). Webikon link points to individual claudiu-cristea (excluded from ALLOWED_ORGS).,high,Cross-referenced with invoiced-sponsorships.jsonc +2026-05-07T17:00:00,web,"GitHub org ownership docs. https://docs.github.com/en/organizations",Registering OAuth App under an org shows 'by ' on auth screen and survives individual departures.,high,Satisfies FR-007; institutional ownership requirement +2026-05-07T17:00:00,web,"Coder apt install docs. https://coder.com/docs/install/server",Coder installed via apt reads /etc/coder.d/coder.env at systemd startup; no image rebuild needed to apply env changes.,high,Informs deployment model — config-only change diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/research/source-register.csv b/kitty-specs/github-org-gated-signup-01KR1P4G/research/source-register.csv new file mode 100644 index 0000000..b4a2d11 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/research/source-register.csv @@ -0,0 +1,25 @@ +# Source Register: Master list of all research sources +# +# Column Definitions: +# - source_id: Unique identifier (lowercase, no spaces, e.g., "smith2024") +# - citation: Full citation (BibTeX or APA format) +# - url: Direct link to source (DOI, arXiv, or web URL) +# - accessed_date: Date source was accessed (YYYY-MM-DD) +# - relevance: high | medium | low (to primary research question) +# - status: reviewed | pending | archived +# +# Usage: Add sources when discovered, update status as research progresses +# Validation: source_id must be unique +source_id,citation,url,accessed_date,relevance,status +coder-external-auth,"Coder Documentation. External Auth / GitHub OAuth.",https://coder.com/docs/admin/external-auth,2026-05-07,high,reviewed +coder-custom-oauth-app,"Coder Documentation. Custom GitHub OAuth App recommendation.",https://coder.com/docs/admin/external-auth,2026-05-07,high,reviewed +github-oauth-scopes,"GitHub Documentation. Scopes for OAuth apps.",https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps,2026-05-07,high,reviewed +coder-device-flow,"Coder Documentation. Device Flow warning for ALLOWED_ORGS.",https://coder.com/docs/admin/external-auth,2026-05-07,high,reviewed +coder-install-server,"Coder Documentation. Server installation (apt, systemd, coder.env).",https://coder.com/docs/install/server,2026-05-07,high,reviewed +ddev-sponsorship-data,"DDEV internal. invoiced-sponsorships.jsonc (ddev/sponsorship-data repo).",(internal repo),2026-05-07,high,reviewed +ddev-ddev-com-sponsors,"DDEV website. Featured sponsors page. https://ddev.com/support/sponsors",https://ddev.com/support/sponsors,2026-05-07,high,reviewed +ddev-ddev-com-pr626,"ddev/ddev.com PR #626. Sponsor listing confirming dougvann as individual $100/month.",https://github.com/ddev/ddev.com/pull/626,2026-05-07,medium,reviewed +github-org-search,"GitHub org search (manual lookups, 2026-05-07). Resolved sponsor company names to org slugs.",(manual lookup),2026-05-07,medium,reviewed +github-issue-64,"ddev/coder-ddev issue #64. User creation and authentication control.",https://github.com/ddev/coder-ddev/issues/64,2026-05-07,high,reviewed +github-issue-54,"ddev/coder-ddev issue #54. Offer additional login options.",https://github.com/ddev/coder-ddev/issues/54,2026-05-07,medium,reviewed +github-org-ownership,"GitHub Documentation. About organizations / transferring ownership.",https://docs.github.com/en/organizations,2026-05-07,medium,reviewed diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/wps.yaml b/kitty-specs/github-org-gated-signup-01KR1P4G/wps.yaml new file mode 100644 index 0000000..2e2b8b7 --- /dev/null +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/wps.yaml @@ -0,0 +1,74 @@ +work_packages: + - id: WP01 + title: "Update server-setup.md for Org-Gated Auth" + dependencies: [] + owned_files: + - "docs/admin/server-setup.md" + requirement_refs: + - FR-001 + - FR-005 + - FR-006 + - FR-007 + - FR-013 + - FR-014 + - C-005 + - C-006 + - C-007 + subtasks: + - T001 + - T002 + - T003 + - T004 + - T005 + prompt_file: "tasks/WP01-server-setup-update.md" + + - id: WP02 + title: "Update user-management.md with Access Runbook" + dependencies: [] + owned_files: + - "docs/admin/user-management.md" + requirement_refs: + - FR-002 + - FR-003 + - FR-004 + - FR-009 + - NFR-002 + - C-001 + subtasks: + - T006 + - T007 + - T008 + - T009 + prompt_file: "tasks/WP02-user-management-access-runbook.md" + + - id: WP03 + title: "coder-ddev-com Org Content Drafts" + dependencies: [] + owned_files: + - "docs/admin/coder-ddev-com/**" + requirement_refs: + - FR-010 + - FR-011 + - FR-015 + - C-002 + subtasks: + - T010 + - T011 + - T012 + - T013 + prompt_file: "tasks/WP03-coder-ddev-com-org-content.md" + + - id: WP04 + title: "Blog Post Update Draft" + dependencies: + - WP03 + owned_files: + - "docs/admin/blog-post-draft.md" + requirement_refs: + - FR-012 + - FR-008 + subtasks: + - T014 + - T015 + - T016 + prompt_file: "tasks/WP04-blog-post-draft.md" From 0f4c50cc2343b4b61f61e18253551d97a4296807 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:56:27 +0000 Subject: [PATCH 23/53] chore: Start WP01 implementation [claude] --- .../tasks/WP01-server-setup-update.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md index d55d756..540bbf4 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md @@ -28,7 +28,8 @@ subtasks: - T003 - T004 - T005 -shell_pid: '25745' +shell_pid: "25745" +agent: "claude" history: - date: '2026-05-07' event: created @@ -268,3 +269,7 @@ When a new organization reaches the $100+/month sponsorship level: - The `ALLOWED_ORGS` value is long; a typo in a slug silently excludes that org's members. Verify the slug list against `kitty-specs/github-org-gated-signup-01KR1P4G/research.md` before committing. - `Institute-for-Advanced-Studies` is unverified — note this clearly in the doc. + +## Activity Log + +- 2026-05-07T18:56:27Z – claude – shell_pid=25745 – Assigned agent via action command From d8a378f4b3d397a0b8d50648354ab663f809ae12 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:58:08 +0000 Subject: [PATCH 24/53] feat(WP01): update server-setup.md for org-gated auth - Expand ALLOWED_ORGS to full 27-org list (ddev + coder-ddev-com + 25 sponsor orgs) - Add staging OAuth App sub-section with separate callback URL - Document coder-ddev-com org purpose and individual membership management - Add sponsor org access policy table with all confirmed org slugs - Add runbook for adding a new sponsor org Co-Authored-By: Claude Sonnet 4.6 --- docs/admin/server-setup.md | 105 +++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 4 deletions(-) diff --git a/docs/admin/server-setup.md b/docs/admin/server-setup.md index b88fbc8..5735b41 100644 --- a/docs/admin/server-setup.md +++ b/docs/admin/server-setup.md @@ -659,15 +659,35 @@ The initial admin account must be created with username/password via the web UI **1. Create a GitHub OAuth App** -Create the app under your **GitHub organization**, not your personal account — apps created under a personal account show "by \" on the authorization screen instead of "by \". Go to **github.com/organizations/\/settings/applications → New OAuth App** and fill in: +Create the app under your **GitHub organization**, not your personal account — apps created under a personal account show "by \" on the authorization screen instead of "by \". Go to **github.com/organizations/ddev/settings/applications → New OAuth App** and fill in: -- **Application name**: `Coder (coder.ddev.com)` (or similar) +- **Application name**: `Coder (coder.ddev.com)` - **Homepage URL**: `https://coder.ddev.com` - **Authorization callback URL**: `https://coder.ddev.com/api/v2/users/oauth2/github/callback` - **Enable Device Flow**: leave unchecked (see note below) After creating the app, generate a client secret. Note the **Client ID** and **Client Secret**. +#### Two OAuth Apps: staging and production + +Register **two separate OAuth Apps** — one for staging, one for production. Separate apps isolate credentials between environments so that a staging secret compromise cannot affect production, and secret rotation on one environment does not require touching the other. + +**Staging app settings:** + +- **Application name**: `Coder (staging-coder.ddev.com)` +- **Homepage URL**: `https://staging-coder.ddev.com` +- **Authorization callback URL**: `https://staging-coder.ddev.com/api/v2/users/oauth2/github/callback` +- **Enable Device Flow**: leave unchecked + +**Production app settings** (same as above): + +- **Application name**: `Coder (coder.ddev.com)` +- **Homepage URL**: `https://coder.ddev.com` +- **Authorization callback URL**: `https://coder.ddev.com/api/v2/users/oauth2/github/callback` +- **Enable Device Flow**: leave unchecked + +Use the staging app's Client ID and Client Secret in `/etc/coder.d/coder.env` on staging-coder.ddev.com, and the production app's credentials on coder.ddev.com. + **2. Add to `/etc/coder.d/coder.env`** ```bash @@ -678,8 +698,9 @@ CODER_OAUTH2_GITHUB_CLIENT_SECRET=your-client-secret # Allow sign-ups via GitHub (new users are created automatically on first login) CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS=true -# Restrict to members of a specific GitHub org (recommended): -CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev +# Access control: ddev org members, coder-ddev-com managed list, and $100+/month sponsor orgs +# Institute-for-Advanced-Studies is included but not yet verified — confirm the org identity before deploying +CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platformsh,Institute-for-Advanced-Studies,CPS-IT,redfinsolutions,Lullabot,b13,pixelandtonic,Cambrico,centarro,8mylez,dkd,liip,i-gelb,FameHelsinki,Gizra,mobilistics,OPTASY,passbolt,vaersaagod,affinitybridge,AGILEDROP,NPO-Applications-GmbH,AtenDesignGroup # Or allow any GitHub user (not recommended for a shared server): # CODER_OAUTH2_GITHUB_ALLOW_EVERYONE=true @@ -706,6 +727,82 @@ sudo systemctl restart coder There is also a toggle in the Coder admin UI at **Admin → Security** that can override the env var. Check that user sign-ups are not disabled there. +### Managing individual access via `coder-ddev-com` + +The `coder-ddev-com` GitHub organization is the managed access list for individuals who do not belong to the `ddev` org or one of the sponsor orgs. Adding someone to `coder-ddev-com` grants them signup access to coder.ddev.com without requiring a Coder server restart. + +**To grant access to an individual:** + +1. Go to **github.com/coder-ddev-com** → **People** → **Invite member** +2. Enter the person's GitHub username and send the invitation +3. Once they accept, they can log in to coder.ddev.com via GitHub OAuth + +**Initial members** (add these when creating the org): + +- `dougvann` — individual $100/month GitHub Sponsor +- `claudiu-cristea` — Webikon sponsor (linked as individual on ddev.com) +- Add LetsTalk, Amedick Sommer, and Pottkinder GmbH contacts when their GitHub usernames are confirmed + +**Note on private membership:** Users do not need to make their `coder-ddev-com` membership public. Private membership is sufficient — the `read:org` OAuth scope allows Coder to verify membership regardless of visibility setting. + +### Sponsor org access policy + +All $100+/month DDEV sponsors receive access as an org-level benefit: every member of a sponsor's GitHub org can sign in to coder.ddev.com without individual enrollment in `coder-ddev-com`. MacStadium and JetBrains are excluded (in-kind, not cash sponsors). + +| Company | GitHub org | Source | +| ------- | ---------- | ------ | +| Tag1 | `tag1consulting` | invoiced | +| Upsun | `upsun` | invoiced | +| Platform.sh (Upsun predecessor) | `platformsh` | invoiced | +| Institute for Advanced Studies | `Institute-for-Advanced-Studies` ⚠️ | invoiced | +| CPS-IT | `CPS-IT` | invoiced | +| Redfin Solutions | `redfinsolutions` | invoiced + featured | +| Lullabot | `Lullabot` | invoiced | +| B13 | `b13` | invoiced + featured | +| Pixel & Tonic (Craft CMS) | `pixelandtonic` | invoiced + featured | +| Cambrico | `Cambrico` | invoiced + featured | +| Centarro | `centarro` | invoiced + featured | +| 8mylez | `8mylez` | invoiced | +| dkd Internet Service GmbH | `dkd` | GitHub Sponsors | +| Liip | `liip` | GitHub Sponsors | +| i-gelb GmbH | `i-gelb` | featured | +| Fame Helsinki | `FameHelsinki` | featured | +| Gizra | `Gizra` | featured | +| mobilistics GmbH | `mobilistics` | featured | +| OPTASY | `OPTASY` | featured | +| Passbolt | `passbolt` | featured | +| Værsågod | `vaersaagod` | featured | +| Affinity Bridge | `affinitybridge` | featured | +| Agiledrop | `AGILEDROP` | featured | +| NPO Applications GmbH | `NPO-Applications-GmbH` | featured | +| Aten Design Group | `AtenDesignGroup` | featured | + +⚠️ `Institute-for-Advanced-Studies` — GitHub org exists but has no public name or description. Confirm with an operator that this is the correct org before deploying. + +Sponsors with no confirmed GitHub org (access via `coder-ddev-com` individual membership instead): LetsTalk, Amedick Sommer, Pottkinder GmbH. + +#### Adding a new sponsor org + +When a new organization reaches the $100+/month sponsorship level: + +1. **Find their GitHub org slug**: Check the sponsor's GitHub profile or ask them directly. Verify with `gh api orgs/ --jq '.login'` — if the command returns the slug, the org exists. + +2. **Add the slug to `ALLOWED_ORGS`** on both staging and production: + + ```bash + # On the server, edit /etc/coder.d/coder.env + # Append the new slug to CODER_OAUTH2_GITHUB_ALLOWED_ORGS (comma-separated, no spaces) + sudo systemctl restart coder + ``` + +3. **Test on staging first**: Ask someone from the org to attempt login on staging-coder.ddev.com before updating production. + +4. **Update the table above**: Add the org to the sponsor org table so the list stays accurate. + +5. **Notify the sponsor**: Send the sponsor notification (see `docs/admin/coder-ddev-com/sponsor-notification.md`) letting them know their org members now have access. + +**If the sponsor has no GitHub org**: Add their individual GitHub username to the `coder-ddev-com` org instead (see "Managing individual access" above). No server restart needed. + ### Fix cert permissions and test renewal Now that the `coder` system group exists, run the deploy hook you created in Step 6 to fix permissions on the certificate files: From 732ace1bd0fc7e012b6bec0ee9ea676d56444fc9 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:58:51 +0000 Subject: [PATCH 25/53] chore: Move WP01 to for_review on spec github [claude] --- .../status.events.jsonl | 1 + .../status.json | 18 +++++++++--------- .../tasks/WP01-server-setup-update.md | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index fc0fa9c..12911ab 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -4,3 +4,4 @@ {"actor": "finalize-tasks", "at": "2026-05-07T18:04:47.237340+00:00", "event_id": "01KR1ST5R57BNZQ55XMMB3WG64", "evidence": null, "execution_mode": "worktree", "force": true, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "canonical bootstrap", "review_ref": null, "to_lane": "planned", "wp_id": "WP04"} {"actor": "implement-command", "at": "2026-05-07T18:56:26.259833+00:00", "event_id": "01KR1WRR4K4VCB3EHN49FWMNCD", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP01"} {"actor": "implement-command", "at": "2026-05-07T18:56:26.350632+00:00", "event_id": "01KR1WRR7EDJNJ3QKMNGWQKN4C", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP01"} +{"actor": "user", "at": "2026-05-07T18:58:51.454594+00:00", "event_id": "01KR1WX5XY3JKX9XH9GTJHY6ER", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: server-setup.md updated with full 27-org ALLOWED_ORGS, staging OAuth App section, coder-ddev-com management docs, sponsor table, and runbook", "review_ref": null, "to_lane": "for_review", "wp_id": "WP01"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 6b62b2e..3e691c6 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,7 +1,7 @@ { - "event_count": 6, - "last_event_id": "01KR1WRR7EDJNJ3QKMNGWQKN4C", - "materialized_at": "2026-05-07T18:56:26.350632+00:00", + "event_count": 7, + "last_event_id": "01KR1WX5XY3JKX9XH9GTJHY6ER", + "materialized_at": "2026-05-07T18:58:51.454594+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", @@ -11,18 +11,18 @@ "canceled": 0, "claimed": 0, "done": 0, - "for_review": 0, - "in_progress": 1, + "for_review": 1, + "in_progress": 0, "in_review": 0, "planned": 3 }, "work_packages": { "WP01": { - "actor": "implement-command", + "actor": "user", "force_count": 1, - "lane": "in_progress", - "last_event_id": "01KR1WRR7EDJNJ3QKMNGWQKN4C", - "last_transition_at": "2026-05-07T18:56:26.350632+00:00" + "lane": "for_review", + "last_event_id": "01KR1WX5XY3JKX9XH9GTJHY6ER", + "last_transition_at": "2026-05-07T18:58:51.454594+00:00" }, "WP02": { "actor": "finalize-tasks", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md index 540bbf4..c59bc90 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md @@ -273,3 +273,4 @@ When a new organization reaches the $100+/month sponsorship level: ## Activity Log - 2026-05-07T18:56:27Z – claude – shell_pid=25745 – Assigned agent via action command +- 2026-05-07T18:58:51Z – claude – shell_pid=25745 – Ready for review: server-setup.md updated with full 27-org ALLOWED_ORGS, staging OAuth App section, coder-ddev-com management docs, sponsor table, and runbook From c5947e8de042165edbc34e515a9dd582a08e2617 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:59:05 +0000 Subject: [PATCH 26/53] chore: planning artifacts for github-org-gated-signup-01KR1P4G Auto-committed by spec-kitty before creating the lane worktree for WP02 --- .../github-org-gated-signup-01KR1P4G/mission-events.jsonl | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl index b714339..a0e6b3f 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -5,3 +5,4 @@ {"mission": "software-dev", "payload": {"action": "tasks-packages", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_packages", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:51:46.676287+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "tasks-finalize", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_finalize", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:52:15.848056+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-07T18:52:28.638408+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-07T18:59:00.206911+00:00", "type": "MissionNextInvoked"} From bdf9c6d286e7fb4e9e8e82b70922394e93f107c2 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:59:06 +0000 Subject: [PATCH 27/53] chore: WP02 claimed for implementation --- .../status.events.jsonl | 2 ++ .../status.json | 18 +++++++++--------- .../WP02-user-management-access-runbook.md | 4 ++++ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 12911ab..bf70be0 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -5,3 +5,5 @@ {"actor": "implement-command", "at": "2026-05-07T18:56:26.259833+00:00", "event_id": "01KR1WRR4K4VCB3EHN49FWMNCD", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP01"} {"actor": "implement-command", "at": "2026-05-07T18:56:26.350632+00:00", "event_id": "01KR1WRR7EDJNJ3QKMNGWQKN4C", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP01"} {"actor": "user", "at": "2026-05-07T18:58:51.454594+00:00", "event_id": "01KR1WX5XY3JKX9XH9GTJHY6ER", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: server-setup.md updated with full 27-org ALLOWED_ORGS, staging OAuth App section, coder-ddev-com management docs, sponsor table, and runbook", "review_ref": null, "to_lane": "for_review", "wp_id": "WP01"} +{"actor": "implement-command", "at": "2026-05-07T18:59:05.948699+00:00", "event_id": "01KR1WXM2WAQPBQ7KP0TF1DCE8", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP02"} +{"actor": "implement-command", "at": "2026-05-07T18:59:06.039477+00:00", "event_id": "01KR1WXM5QWPM67M2FQ6W2RH3H", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP02"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 3e691c6..eb414cc 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,7 +1,7 @@ { - "event_count": 7, - "last_event_id": "01KR1WX5XY3JKX9XH9GTJHY6ER", - "materialized_at": "2026-05-07T18:58:51.454594+00:00", + "event_count": 9, + "last_event_id": "01KR1WXM5QWPM67M2FQ6W2RH3H", + "materialized_at": "2026-05-07T18:59:06.039477+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", @@ -12,9 +12,9 @@ "claimed": 0, "done": 0, "for_review": 1, - "in_progress": 0, + "in_progress": 1, "in_review": 0, - "planned": 3 + "planned": 2 }, "work_packages": { "WP01": { @@ -25,11 +25,11 @@ "last_transition_at": "2026-05-07T18:58:51.454594+00:00" }, "WP02": { - "actor": "finalize-tasks", + "actor": "implement-command", "force_count": 1, - "lane": "planned", - "last_event_id": "01KR1ST5R35T8JA744EC0RMJEN", - "last_transition_at": "2026-05-07T18:04:47.235255+00:00" + "lane": "in_progress", + "last_event_id": "01KR1WXM5QWPM67M2FQ6W2RH3H", + "last_transition_at": "2026-05-07T18:59:06.039477+00:00" }, "WP03": { "actor": "finalize-tasks", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md index 4a2fdb3..7d57380 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md @@ -12,11 +12,15 @@ requirement_refs: planning_base_branch: 20260507_speckitty merge_target_branch: 20260507_speckitty branch_strategy: Planning artifacts for this feature were generated on 20260507_speckitty. During /spec-kitty.implement this WP may branch from a dependency-specific base, but completed changes must merge back into 20260507_speckitty unless the human explicitly redirects the landing branch. +base_branch: kitty/mission-github-org-gated-signup-01KR1P4G +base_commit: e125c1d60f5ea0f1c84475d06a5947d15b201b60 +created_at: '2026-05-07T18:59:05.937727+00:00' subtasks: - T006 - T007 - T008 - T009 +shell_pid: '29068' history: - date: '2026-05-07' event: created From 6b283ba53a044ff10ecafbbd9bfa5d81300300cb Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:59:06 +0000 Subject: [PATCH 28/53] chore: Start WP02 implementation [claude] --- .../tasks/WP02-user-management-access-runbook.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md index 7d57380..1e7483b 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md @@ -20,7 +20,8 @@ subtasks: - T007 - T008 - T009 -shell_pid: '29068' +shell_pid: "29068" +agent: "claude" history: - date: '2026-05-07' event: created @@ -231,3 +232,7 @@ When the `coder-ddev-com` GitHub org is created, add these initial members: - The `coder users create` CLI syntax should be verified against the current Coder CLI (`coder users create --help`) before committing — flags may differ across Coder versions. - Avoid adding the "Access Management" section in a location that breaks the existing document flow. Insert it after the "User Roles" content, not at the very end. + +## Activity Log + +- 2026-05-07T18:59:06Z – claude – shell_pid=29068 – Assigned agent via action command From ef16a1568c4078a41ee931fb724f750d9ccd0f3b Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:59:44 +0000 Subject: [PATCH 29/53] feat(WP02): add Access Management section to user-management.md - Add top-level Access Management section explaining the org-gated signup model - Document granting access via coder-ddev-com org membership - Document pre-creating password exception accounts via CLI and Web UI - Explain private org membership and read:org scope behavior - List initial coder-ddev-com members Co-Authored-By: Claude Sonnet 4.6 --- docs/admin/user-management.md | 58 +++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/docs/admin/user-management.md b/docs/admin/user-management.md index ccc3eff..e3ceb2f 100644 --- a/docs/admin/user-management.md +++ b/docs/admin/user-management.md @@ -487,6 +487,64 @@ coder ssh my-workspace -- coder gitssh --help coder users show ``` +## Access Management + +New account creation on coder.ddev.com and staging-coder.ddev.com is restricted to members of two GitHub organizations: the `ddev` org and the `coder-ddev-com` org. Additionally, members of $100+/month DDEV sponsor organizations can sign in directly. + +Existing accounts created before this restriction was applied remain active. Password authentication remains available for manually pre-created exception accounts. + +### Granting access via `coder-ddev-com` org membership + +The `coder-ddev-com` GitHub organization is the access list for individuals who are not members of the `ddev` org or a sponsor org. Adding someone to this org grants signup access without any Coder server change. + +**Steps:** + +1. Go to **github.com/coder-ddev-com** → **People** → **Invite member** +2. Enter the person's GitHub username and send the invitation +3. Once they accept the invitation, they can visit coder.ddev.com and sign in with GitHub + +**Note on private membership:** Users do not need to make their `coder-ddev-com` membership public. Private membership is sufficient — Coder uses the `read:org` OAuth scope to verify membership regardless of visibility. + +### Pre-creating password exception accounts + +For users who cannot authenticate via GitHub OAuth (e.g., users without a GitHub account, or accounts needed before org configuration is complete), an admin can pre-create a password-based account directly. + +**Via CLI:** + +```bash +# Create the account +coder users create --email user@example.com + +# Set a password interactively +coder users create --email user@example.com --set-password +``` + +**Via Web UI:** + +1. Log in as admin +2. Navigate to **Admin → Users → Create User** +3. Fill in username, email, and password +4. Assign the **Member** role + +The user logs in at coder.ddev.com with their username and password — GitHub OAuth is not required for password accounts. + +> **Important:** `CODER_DISABLE_PASSWORD_AUTH` must never be set to `true`. Password authentication must remain available for these exception accounts. + +### Private org membership and the `read:org` scope + +Users who are members of `ddev`, `coder-ddev-com`, or a sponsor org do not need to make that membership public. Coder requests the `read:org` GitHub OAuth scope, which allows it to verify private org membership during authentication. Users are prompted to grant this scope when they first click "Sign in with GitHub." + +### Initial `coder-ddev-com` members + +Add these individuals when creating the `coder-ddev-com` org: + +| GitHub username | Reason | +| --------------- | ------ | +| `dougvann` | Individual $100/month GitHub Sponsor | +| `claudiu-cristea` | Webikon sponsor (linked as individual on ddev.com) | + +The following sponsor contacts should also be added once their GitHub usernames are confirmed: LetsTalk, Amedick Sommer, Pottkinder GmbH. + ## Additional Resources - [Operations Guide](./operations-guide.md) - Template deployment and management From ce785cdd3b6e2407dc123adf168f6006093f0718 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 18:59:50 +0000 Subject: [PATCH 30/53] chore: Move WP02 to for_review on spec github [claude] --- .../status.events.jsonl | 1 + .../status.json | 18 +++++++++--------- .../WP02-user-management-access-runbook.md | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index bf70be0..8deb178 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -7,3 +7,4 @@ {"actor": "user", "at": "2026-05-07T18:58:51.454594+00:00", "event_id": "01KR1WX5XY3JKX9XH9GTJHY6ER", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: server-setup.md updated with full 27-org ALLOWED_ORGS, staging OAuth App section, coder-ddev-com management docs, sponsor table, and runbook", "review_ref": null, "to_lane": "for_review", "wp_id": "WP01"} {"actor": "implement-command", "at": "2026-05-07T18:59:05.948699+00:00", "event_id": "01KR1WXM2WAQPBQ7KP0TF1DCE8", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP02"} {"actor": "implement-command", "at": "2026-05-07T18:59:06.039477+00:00", "event_id": "01KR1WXM5QWPM67M2FQ6W2RH3H", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP02"} +{"actor": "user", "at": "2026-05-07T18:59:50.080669+00:00", "event_id": "01KR1WYZ60DJ46PDSRTMVG7X1P", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: Access Management section added to user-management.md", "review_ref": null, "to_lane": "for_review", "wp_id": "WP02"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index eb414cc..3bd511f 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,7 +1,7 @@ { - "event_count": 9, - "last_event_id": "01KR1WXM5QWPM67M2FQ6W2RH3H", - "materialized_at": "2026-05-07T18:59:06.039477+00:00", + "event_count": 10, + "last_event_id": "01KR1WYZ60DJ46PDSRTMVG7X1P", + "materialized_at": "2026-05-07T18:59:50.080669+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", @@ -11,8 +11,8 @@ "canceled": 0, "claimed": 0, "done": 0, - "for_review": 1, - "in_progress": 1, + "for_review": 2, + "in_progress": 0, "in_review": 0, "planned": 2 }, @@ -25,11 +25,11 @@ "last_transition_at": "2026-05-07T18:58:51.454594+00:00" }, "WP02": { - "actor": "implement-command", + "actor": "user", "force_count": 1, - "lane": "in_progress", - "last_event_id": "01KR1WXM5QWPM67M2FQ6W2RH3H", - "last_transition_at": "2026-05-07T18:59:06.039477+00:00" + "lane": "for_review", + "last_event_id": "01KR1WYZ60DJ46PDSRTMVG7X1P", + "last_transition_at": "2026-05-07T18:59:50.080669+00:00" }, "WP03": { "actor": "finalize-tasks", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md index 1e7483b..d3cebf1 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md @@ -236,3 +236,4 @@ When the `coder-ddev-com` GitHub org is created, add these initial members: ## Activity Log - 2026-05-07T18:59:06Z – claude – shell_pid=29068 – Assigned agent via action command +- 2026-05-07T18:59:50Z – claude – shell_pid=29068 – Ready for review: Access Management section added to user-management.md From 8a6c2baaca8faf2185b2799548adcfe24aa2a480 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:00:15 +0000 Subject: [PATCH 31/53] chore: Start WP03 implementation [claude] --- .../status.events.jsonl | 2 ++ .../status.json | 18 +++++++++--------- .../tasks/WP03-coder-ddev-com-org-content.md | 6 ++++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 8deb178..36a19e1 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -8,3 +8,5 @@ {"actor": "implement-command", "at": "2026-05-07T18:59:05.948699+00:00", "event_id": "01KR1WXM2WAQPBQ7KP0TF1DCE8", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP02"} {"actor": "implement-command", "at": "2026-05-07T18:59:06.039477+00:00", "event_id": "01KR1WXM5QWPM67M2FQ6W2RH3H", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP02"} {"actor": "user", "at": "2026-05-07T18:59:50.080669+00:00", "event_id": "01KR1WYZ60DJ46PDSRTMVG7X1P", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: Access Management section added to user-management.md", "review_ref": null, "to_lane": "for_review", "wp_id": "WP02"} +{"actor": "claude", "at": "2026-05-07T19:00:15.480301+00:00", "event_id": "01KR1WZQZR170YS0MTBZX359X5", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP03"} +{"actor": "claude", "at": "2026-05-07T19:00:15.572465+00:00", "event_id": "01KR1WZR2MZWT63YRJBDEXR4GY", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP03"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 3bd511f..8fd1b33 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,7 +1,7 @@ { - "event_count": 10, - "last_event_id": "01KR1WYZ60DJ46PDSRTMVG7X1P", - "materialized_at": "2026-05-07T18:59:50.080669+00:00", + "event_count": 12, + "last_event_id": "01KR1WZR2MZWT63YRJBDEXR4GY", + "materialized_at": "2026-05-07T19:00:15.572465+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", @@ -12,9 +12,9 @@ "claimed": 0, "done": 0, "for_review": 2, - "in_progress": 0, + "in_progress": 1, "in_review": 0, - "planned": 2 + "planned": 1 }, "work_packages": { "WP01": { @@ -32,11 +32,11 @@ "last_transition_at": "2026-05-07T18:59:50.080669+00:00" }, "WP03": { - "actor": "finalize-tasks", + "actor": "claude", "force_count": 1, - "lane": "planned", - "last_event_id": "01KR1ST5R4262WM8FB01TBP1QA", - "last_transition_at": "2026-05-07T18:04:47.236342+00:00" + "lane": "in_progress", + "last_event_id": "01KR1WZR2MZWT63YRJBDEXR4GY", + "last_transition_at": "2026-05-07T19:00:15.572465+00:00" }, "WP04": { "actor": "finalize-tasks", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md index 5dda787..26ce9b9 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md @@ -15,6 +15,8 @@ subtasks: - T011 - T012 - T013 +agent: "claude" +shell_pid: "30615" history: - date: '2026-05-07' event: created @@ -300,3 +302,7 @@ Thank you for supporting DDEV! - The `coder-ddev-com/access-requests` repo URL is referenced in T011 and the org profile README — the repo does not exist yet. Use the anticipated URL `https://github.com/coder-ddev-com/access-requests` in drafts; operator creates the repo before publishing. - The issue template YAML syntax must be valid. The `type` values (`input`, `textarea`, `checkboxes`, `markdown`) are the standard GitHub issue form types. + +## Activity Log + +- 2026-05-07T19:00:15Z – claude – shell_pid=30615 – Started implementation via action command From a2c734f9d8345484025991577ea694d99d4f4693 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:01:10 +0000 Subject: [PATCH 32/53] feat(WP03): add coder-ddev-com org content drafts - org-profile-README.md: org profile for the coder-ddev-com GitHub org - access-requests-README.md: README for the access-requests public repo - access-request-issue-template.yml: structured GitHub issue template for access requests - sponsor-notification.md: message template to notify sponsor orgs of access benefit Co-Authored-By: Claude Sonnet 4.6 --- .../access-request-issue-template.yml | 44 +++++++++++++++++++ .../coder-ddev-com/access-requests-README.md | 37 ++++++++++++++++ .../coder-ddev-com/org-profile-README.md | 32 ++++++++++++++ .../coder-ddev-com/sponsor-notification.md | 36 +++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 docs/admin/coder-ddev-com/access-request-issue-template.yml create mode 100644 docs/admin/coder-ddev-com/access-requests-README.md create mode 100644 docs/admin/coder-ddev-com/org-profile-README.md create mode 100644 docs/admin/coder-ddev-com/sponsor-notification.md diff --git a/docs/admin/coder-ddev-com/access-request-issue-template.yml b/docs/admin/coder-ddev-com/access-request-issue-template.yml new file mode 100644 index 0000000..e527b02 --- /dev/null +++ b/docs/admin/coder-ddev-com/access-request-issue-template.yml @@ -0,0 +1,44 @@ +# operator note: in the coder-ddev-com/access-requests repo, create +# .github/ISSUE_TEMPLATE/access-request.yml with this content. + +name: Access Request +description: Request access to coder.ddev.com +title: "Access request: [your GitHub username]" +labels: ["access-request"] +body: + - type: markdown + attributes: + value: | + Thanks for your interest in coder.ddev.com! Please fill out the form below. + + **Already have access?** If you are a member of the [ddev](https://github.com/ddev) org + or a $100+/month DDEV sponsor org, you should already have access — try signing in at + [coder.ddev.com](https://coder.ddev.com) first. + + - type: input + id: github_username + attributes: + label: GitHub username + description: Your GitHub username (the one you will use to sign in) + placeholder: "e.g. octocat" + validations: + required: true + + - type: textarea + id: reason + attributes: + label: Why do you want access? + description: Brief description — DDEV contributor, open-source developer, evaluating DDEV for a project, etc. + placeholder: "I maintain a DDEV add-on and want to test it in a cloud workspace..." + validations: + required: true + + - type: checkboxes + id: confirm + attributes: + label: Confirmation + options: + - label: I have checked that I do not already have access through the ddev org or a sponsor org + required: true + - label: I understand this is a shared resource and will use it responsibly + required: true diff --git a/docs/admin/coder-ddev-com/access-requests-README.md b/docs/admin/coder-ddev-com/access-requests-README.md new file mode 100644 index 0000000..1af58c9 --- /dev/null +++ b/docs/admin/coder-ddev-com/access-requests-README.md @@ -0,0 +1,37 @@ + + +# coder-ddev-com / access-requests + +This repository is the access request tracker for [coder.ddev.com](https://coder.ddev.com). + +## What is coder.ddev.com? + +[coder.ddev.com](https://coder.ddev.com) is a cloud-hosted DDEV development environment for web developers. It provides workspaces running [DDEV](https://ddev.com) with VS Code for Web, a terminal, and full Docker support. + +## Who already has access? + +Access is automatically available (no request needed) if you are: + +- A member of the [ddev](https://github.com/ddev) GitHub org +- A member of an organization that sponsors DDEV at $100+/month + +See the [DDEV sponsors page](https://ddev.com/support-ddev/) for the current list of sponsors. + +## Requesting access + +If you do not have access through one of the above paths, open an issue in this repository using the **Access Request** template. + +We will review your request and, if approved, add you to the `coder-ddev-com` org. You will receive a GitHub invitation — once you accept it, you can sign in to coder.ddev.com with your GitHub account. + +**What to include in your request:** +- Your GitHub username +- Why you want access (brief description — DDEV user, contributor, etc.) + +## Response time + +We aim to respond to requests within a few business days. If you have not heard back in a week, feel free to ping the issue. + +## Questions + +Visit the [DDEV Discord](https://discord.ddev.com) or open an issue in [ddev/ddev](https://github.com/ddev/ddev/issues). diff --git a/docs/admin/coder-ddev-com/org-profile-README.md b/docs/admin/coder-ddev-com/org-profile-README.md new file mode 100644 index 0000000..7ebe3d1 --- /dev/null +++ b/docs/admin/coder-ddev-com/org-profile-README.md @@ -0,0 +1,32 @@ + + +# coder-ddev-com + +This organization is the managed access list for [coder.ddev.com](https://coder.ddev.com) — a cloud-based DDEV development environment for web developers. + +## What is coder.ddev.com? + +[coder.ddev.com](https://coder.ddev.com) provides cloud-hosted workspaces running [DDEV](https://ddev.com), an open-source local development environment tool for PHP, Node.js, Python, and more projects. Workspaces include VS Code for Web, a terminal, Docker-in-Docker, and full DDEV support — no local setup required. + +## How membership works + +Members of this organization can sign in to coder.ddev.com using GitHub OAuth. Membership is granted by a coder-ddev-com org owner. + +You do **not** need to make your membership public. Private membership is sufficient. + +## Who qualifies? + +Access is available to: + +- Members of the [ddev](https://github.com/ddev) GitHub org +- Members of organizations that sponsor DDEV at $100+/month +- Individuals approved by the DDEV maintainers (this org) + +## Requesting access + +If you do not have access through one of the paths above, open an issue in the [access-requests](https://github.com/coder-ddev-com/access-requests) repository. + +## Questions + +Visit the [DDEV Discord](https://discord.ddev.com) or open an issue in [ddev/ddev](https://github.com/ddev/ddev/issues). diff --git a/docs/admin/coder-ddev-com/sponsor-notification.md b/docs/admin/coder-ddev-com/sponsor-notification.md new file mode 100644 index 0000000..9a6f88f --- /dev/null +++ b/docs/admin/coder-ddev-com/sponsor-notification.md @@ -0,0 +1,36 @@ + + +Subject: coder.ddev.com access for [ORG NAME] org members + +Hi, + +As a $100+/month sponsor of DDEV, all members of the **[ORG NAME]** GitHub organization ([github.com/[GITHUB ORG SLUG]](https://github.com/[GITHUB ORG SLUG])) now have access to **[coder.ddev.com](https://coder.ddev.com)** — a cloud-hosted DDEV development environment. + +**What is coder.ddev.com?** + +coder.ddev.com provides on-demand cloud workspaces running DDEV with: +- VS Code for Web (full IDE in the browser) +- A terminal +- Docker-in-Docker via Sysbox (full DDEV support, all project types) + +No local setup required — spin up a workspace, start DDEV, and get coding. + +**How to access:** + +1. Visit [coder.ddev.com](https://coder.ddev.com) +2. Click **Sign in with GitHub** +3. Authorize the DDEV Coder app +4. You're in — create a workspace from the Drupal Core, Drupal Contrib, or Freeform template + +All members of the [ORG NAME] GitHub org can sign in. They do not need to be added individually. Org membership does not need to be public. + +**Questions or issues?** + +- [DDEV Discord](https://discord.ddev.com) — `#coder-ddev-com` channel (or any channel) +- [ddev/ddev issues](https://github.com/ddev/ddev/issues) + +Thank you for supporting DDEV! + +— The DDEV maintainers From c4ef67ee6fcf6b2b9c5faf3369f47de58e451063 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:01:29 +0000 Subject: [PATCH 33/53] chore: update mission events for WP03 claim --- .../github-org-gated-signup-01KR1P4G/mission-events.jsonl | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl index a0e6b3f..961c8e0 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -6,3 +6,4 @@ {"mission": "software-dev", "payload": {"action": "tasks-finalize", "agent": "claude", "decision_kind": "step", "mission_state": "tasks_finalize", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T18:52:15.848056+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-07T18:52:28.638408+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-07T18:59:00.206911+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP03"}, "timestamp": "2026-05-07T18:59:54.583177+00:00", "type": "MissionNextInvoked"} From a05f989b375d2c87054727690412a6d6586d31a6 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:01:31 +0000 Subject: [PATCH 34/53] chore: Move WP03 to for_review on spec github [claude] --- .../status.events.jsonl | 1 + .../status.json | 18 +++++++++--------- .../tasks/WP03-coder-ddev-com-org-content.md | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 36a19e1..3e8e7fe 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -10,3 +10,4 @@ {"actor": "user", "at": "2026-05-07T18:59:50.080669+00:00", "event_id": "01KR1WYZ60DJ46PDSRTMVG7X1P", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: Access Management section added to user-management.md", "review_ref": null, "to_lane": "for_review", "wp_id": "WP02"} {"actor": "claude", "at": "2026-05-07T19:00:15.480301+00:00", "event_id": "01KR1WZQZR170YS0MTBZX359X5", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP03"} {"actor": "claude", "at": "2026-05-07T19:00:15.572465+00:00", "event_id": "01KR1WZR2MZWT63YRJBDEXR4GY", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP03"} +{"actor": "user", "at": "2026-05-07T19:01:31.269163+00:00", "event_id": "01KR1X2205N6K31W5W6MSDE0QE", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: org-profile-README, access-requests-README, issue template, sponsor notification all created in docs/admin/coder-ddev-com/", "review_ref": null, "to_lane": "for_review", "wp_id": "WP03"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 8fd1b33..4bf5f57 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,7 +1,7 @@ { - "event_count": 12, - "last_event_id": "01KR1WZR2MZWT63YRJBDEXR4GY", - "materialized_at": "2026-05-07T19:00:15.572465+00:00", + "event_count": 13, + "last_event_id": "01KR1X2205N6K31W5W6MSDE0QE", + "materialized_at": "2026-05-07T19:01:31.269163+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", @@ -11,8 +11,8 @@ "canceled": 0, "claimed": 0, "done": 0, - "for_review": 2, - "in_progress": 1, + "for_review": 3, + "in_progress": 0, "in_review": 0, "planned": 1 }, @@ -32,11 +32,11 @@ "last_transition_at": "2026-05-07T18:59:50.080669+00:00" }, "WP03": { - "actor": "claude", + "actor": "user", "force_count": 1, - "lane": "in_progress", - "last_event_id": "01KR1WZR2MZWT63YRJBDEXR4GY", - "last_transition_at": "2026-05-07T19:00:15.572465+00:00" + "lane": "for_review", + "last_event_id": "01KR1X2205N6K31W5W6MSDE0QE", + "last_transition_at": "2026-05-07T19:01:31.269163+00:00" }, "WP04": { "actor": "finalize-tasks", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md index 26ce9b9..28ce3c8 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md @@ -306,3 +306,4 @@ Thank you for supporting DDEV! ## Activity Log - 2026-05-07T19:00:15Z – claude – shell_pid=30615 – Started implementation via action command +- 2026-05-07T19:01:31Z – claude – shell_pid=30615 – Ready for review: org-profile-README, access-requests-README, issue template, sponsor notification all created in docs/admin/coder-ddev-com/ From fc09a359d4d63fe30cfa1a6ddc20bfc59f8df4ab Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:01:42 +0000 Subject: [PATCH 35/53] chore: Start WP04 implementation [claude] --- .../status.events.jsonl | 2 ++ .../status.json | 18 +++++++++--------- .../tasks/WP04-blog-post-draft.md | 6 ++++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 3e8e7fe..7f8392f 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -11,3 +11,5 @@ {"actor": "claude", "at": "2026-05-07T19:00:15.480301+00:00", "event_id": "01KR1WZQZR170YS0MTBZX359X5", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP03"} {"actor": "claude", "at": "2026-05-07T19:00:15.572465+00:00", "event_id": "01KR1WZR2MZWT63YRJBDEXR4GY", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP03"} {"actor": "user", "at": "2026-05-07T19:01:31.269163+00:00", "event_id": "01KR1X2205N6K31W5W6MSDE0QE", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: org-profile-README, access-requests-README, issue template, sponsor notification all created in docs/admin/coder-ddev-com/", "review_ref": null, "to_lane": "for_review", "wp_id": "WP03"} +{"actor": "claude", "at": "2026-05-07T19:01:42.007379+00:00", "event_id": "01KR1X2CFQ6ANG2YB9ZTDA44DT", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP04"} +{"actor": "claude", "at": "2026-05-07T19:01:42.100559+00:00", "event_id": "01KR1X2CJMGCSN411BGXADEVA2", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP04"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 4bf5f57..d296000 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,7 +1,7 @@ { - "event_count": 13, - "last_event_id": "01KR1X2205N6K31W5W6MSDE0QE", - "materialized_at": "2026-05-07T19:01:31.269163+00:00", + "event_count": 15, + "last_event_id": "01KR1X2CJMGCSN411BGXADEVA2", + "materialized_at": "2026-05-07T19:01:42.100559+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", @@ -12,9 +12,9 @@ "claimed": 0, "done": 0, "for_review": 3, - "in_progress": 0, + "in_progress": 1, "in_review": 0, - "planned": 1 + "planned": 0 }, "work_packages": { "WP01": { @@ -39,11 +39,11 @@ "last_transition_at": "2026-05-07T19:01:31.269163+00:00" }, "WP04": { - "actor": "finalize-tasks", + "actor": "claude", "force_count": 1, - "lane": "planned", - "last_event_id": "01KR1ST5R57BNZQ55XMMB3WG64", - "last_transition_at": "2026-05-07T18:04:47.237340+00:00" + "lane": "in_progress", + "last_event_id": "01KR1X2CJMGCSN411BGXADEVA2", + "last_transition_at": "2026-05-07T19:01:42.100559+00:00" } } } diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md index 61bf621..4e2393f 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md @@ -12,6 +12,8 @@ subtasks: - T014 - T015 - T016 +agent: "claude" +shell_pid: "32508" history: - date: '2026-05-07' event: created @@ -179,3 +181,7 @@ If the blog post has a section mentioning DDEV sponsors, add the following sente - The actual blog post content is in a separate repo (`ddev/ddev.com`) that this agent does not have direct access to. The draft is produced without reading the original post, so section names in "Find and replace" instructions are approximate. The operator will need to locate the correct sections by reading the original. - If the blog post structure has changed significantly since the announcement, the operator may need to adapt the draft rather than apply it verbatim. + +## Activity Log + +- 2026-05-07T19:01:42Z – claude – shell_pid=32508 – Started implementation via action command From 20670ca272b1a4b4b249c5bce37f5cda18aaaafa Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:01:59 +0000 Subject: [PATCH 36/53] feat(WP04): add blog post update draft for org-gated signup - docs/admin/blog-post-draft.md: ready-to-apply diff for ddev.com blog post - Replaces 'Log In with GitHub' section to explain access restrictions - Adds 'Requesting Access' paragraph with link to coder-ddev-com/access-requests - Adds sponsor org access benefit mention Co-Authored-By: Claude Sonnet 4.6 --- docs/admin/blog-post-draft.md | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 docs/admin/blog-post-draft.md diff --git a/docs/admin/blog-post-draft.md b/docs/admin/blog-post-draft.md new file mode 100644 index 0000000..75661d2 --- /dev/null +++ b/docs/admin/blog-post-draft.md @@ -0,0 +1,52 @@ +# Blog Post Update Draft: coder.ddev.com Org-Gated Signup + +**Target file**: `ddev/ddev.com/src/content/blog/coder-ddev-com-announcement.md` +**Action**: Apply these section replacements to the blog post, then open a PR to `ddev/ddev.com` + +--- + +## Section: "Log In with GitHub" — Replace existing content + +Find the section in the blog post that explains GitHub login. Replace the existing content of that section with the following: + +--- + +### Log In with GitHub + +Access to coder.ddev.com requires a GitHub account. Sign in using the **Sign in with GitHub** button — no separate Coder account registration is needed. + +**Who has access:** + +- Members of the [ddev](https://github.com/ddev) GitHub organization +- Members of organizations that sponsor DDEV at $100+/month (see the [DDEV sponsors page](https://ddev.com/support-ddev/)) +- Individuals approved by the DDEV maintainers + +If you are a `ddev` org member or your organization is a $100+/month sponsor, you can sign in immediately — no request needed. + +--- + +## Section: Access Restriction and Request Path — Add after "Log In with GitHub" + +Add the following as a new paragraph or subsection immediately after the "Log In with GitHub" section: + +--- + +### Requesting Access + +If you do not have access through one of the paths above, you can request it by opening an issue in the [coder-ddev-com/access-requests](https://github.com/coder-ddev-com/access-requests) repository on GitHub. Include your GitHub username and a brief description of how you plan to use the environment. + +The DDEV maintainers review requests and add approved users to the `coder-ddev-com` GitHub organization. Once added, you can sign in immediately — no server restart needed on our end. + +--- + +## Section: Sponsor Org Access — Add to "Sponsors" or "Support DDEV" section + +If the blog post has a section mentioning DDEV sponsors, add the following sentence or short paragraph. If no such section exists, add it as a standalone callout near the end of the post: + +--- + +**Sponsor org access**: Organizations that sponsor DDEV at $100+/month receive access as an org-level benefit — all members of a sponsor's GitHub organization can sign in to coder.ddev.com without individual enrollment. See the [DDEV sponsors page](https://ddev.com/support-ddev/) if your organization is interested in sponsoring. + +--- + +**Note for operator**: If the blog post already has a sponsors callout, integrate this sentence rather than adding a duplicate section. From 5ae65e42505cbdde0de70123a2a315250cf8e9f1 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:02:12 +0000 Subject: [PATCH 37/53] chore: update mission events for WP04 claim --- .../github-org-gated-signup-01KR1P4G/mission-events.jsonl | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl index 961c8e0..9914992 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -7,3 +7,4 @@ {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-07T18:52:28.638408+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-07T18:59:00.206911+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP03"}, "timestamp": "2026-05-07T18:59:54.583177+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP04"}, "timestamp": "2026-05-07T19:01:36.970634+00:00", "type": "MissionNextInvoked"} From 625d4a2e93bcfcf53b07fd2cbe7e99a6f723cb09 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:02:14 +0000 Subject: [PATCH 38/53] chore: Move WP04 to for_review on spec github [claude] --- .../status.events.jsonl | 1 + .../status.json | 18 +++++++++--------- .../tasks/WP04-blog-post-draft.md | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 7f8392f..50e87d4 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -13,3 +13,4 @@ {"actor": "user", "at": "2026-05-07T19:01:31.269163+00:00", "event_id": "01KR1X2205N6K31W5W6MSDE0QE", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: org-profile-README, access-requests-README, issue template, sponsor notification all created in docs/admin/coder-ddev-com/", "review_ref": null, "to_lane": "for_review", "wp_id": "WP03"} {"actor": "claude", "at": "2026-05-07T19:01:42.007379+00:00", "event_id": "01KR1X2CFQ6ANG2YB9ZTDA44DT", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP04"} {"actor": "claude", "at": "2026-05-07T19:01:42.100559+00:00", "event_id": "01KR1X2CJMGCSN411BGXADEVA2", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP04"} +{"actor": "user", "at": "2026-05-07T19:02:14.030626+00:00", "event_id": "01KR1X3BREWGYZD5VWHTCMMTEM", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: blog-post-draft.md created with 3 sections", "review_ref": null, "to_lane": "for_review", "wp_id": "WP04"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index d296000..3a9b277 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,7 +1,7 @@ { - "event_count": 15, - "last_event_id": "01KR1X2CJMGCSN411BGXADEVA2", - "materialized_at": "2026-05-07T19:01:42.100559+00:00", + "event_count": 16, + "last_event_id": "01KR1X3BREWGYZD5VWHTCMMTEM", + "materialized_at": "2026-05-07T19:02:14.030626+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", @@ -11,8 +11,8 @@ "canceled": 0, "claimed": 0, "done": 0, - "for_review": 3, - "in_progress": 1, + "for_review": 4, + "in_progress": 0, "in_review": 0, "planned": 0 }, @@ -39,11 +39,11 @@ "last_transition_at": "2026-05-07T19:01:31.269163+00:00" }, "WP04": { - "actor": "claude", + "actor": "user", "force_count": 1, - "lane": "in_progress", - "last_event_id": "01KR1X2CJMGCSN411BGXADEVA2", - "last_transition_at": "2026-05-07T19:01:42.100559+00:00" + "lane": "for_review", + "last_event_id": "01KR1X3BREWGYZD5VWHTCMMTEM", + "last_transition_at": "2026-05-07T19:02:14.030626+00:00" } } } diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md index 4e2393f..92fb476 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md @@ -185,3 +185,4 @@ If the blog post has a section mentioning DDEV sponsors, add the following sente ## Activity Log - 2026-05-07T19:01:42Z – claude – shell_pid=32508 – Started implementation via action command +- 2026-05-07T19:02:14Z – claude – shell_pid=32508 – Ready for review: blog-post-draft.md created with 3 sections From 9d366a587029f05880299371f49cd1f968555d3c Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:02:53 +0000 Subject: [PATCH 39/53] chore: update mission events for WP01 review --- .../github-org-gated-signup-01KR1P4G/mission-events.jsonl | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl index 9914992..dd07485 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -8,3 +8,4 @@ {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-07T18:59:00.206911+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP03"}, "timestamp": "2026-05-07T18:59:54.583177+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP04"}, "timestamp": "2026-05-07T19:01:36.970634+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-07T19:02:19.562296+00:00", "type": "MissionNextInvoked"} From d898d26570b49d76d8f2ca01f41bf409d4f7396e Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:03:03 +0000 Subject: [PATCH 40/53] chore: Move WP01 to approved on spec github [claude] --- .../status.events.jsonl | 2 ++ .../github-org-gated-signup-01KR1P4G/status.json | 16 ++++++++-------- .../tasks/WP01-server-setup-update.md | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 50e87d4..5029a8e 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -14,3 +14,5 @@ {"actor": "claude", "at": "2026-05-07T19:01:42.007379+00:00", "event_id": "01KR1X2CFQ6ANG2YB9ZTDA44DT", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "planned", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "claimed", "wp_id": "WP04"} {"actor": "claude", "at": "2026-05-07T19:01:42.100559+00:00", "event_id": "01KR1X2CJMGCSN411BGXADEVA2", "evidence": null, "execution_mode": "direct_repo", "force": false, "from_lane": "claimed", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": null, "review_ref": null, "to_lane": "in_progress", "wp_id": "WP04"} {"actor": "user", "at": "2026-05-07T19:02:14.030626+00:00", "event_id": "01KR1X3BREWGYZD5VWHTCMMTEM", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: blog-post-draft.md created with 3 sections", "review_ref": null, "to_lane": "for_review", "wp_id": "WP04"} +{"actor": "user", "at": "2026-05-07T19:03:02.971035+00:00", "event_id": "01KR1X4VHVTRKEBN8QNC7FJSWK", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all subtasks complete and verified", "review_ref": null, "to_lane": "in_review", "wp_id": "WP01"} +{"actor": "user", "at": "2026-05-07T19:03:03.055895+00:00", "event_id": "01KR1X4VMFF2143XS72GZD5KW6", "evidence": {"review": {"reference": "Review passed: all subtasks complete and verified", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all subtasks complete and verified", "review_ref": null, "to_lane": "approved", "wp_id": "WP01"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 3a9b277..b6e77bf 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,17 +1,17 @@ { - "event_count": 16, - "last_event_id": "01KR1X3BREWGYZD5VWHTCMMTEM", - "materialized_at": "2026-05-07T19:02:14.030626+00:00", + "event_count": 18, + "last_event_id": "01KR1X4VMFF2143XS72GZD5KW6", + "materialized_at": "2026-05-07T19:03:03.055895+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", "summary": { - "approved": 0, + "approved": 1, "blocked": 0, "canceled": 0, "claimed": 0, "done": 0, - "for_review": 4, + "for_review": 3, "in_progress": 0, "in_review": 0, "planned": 0 @@ -20,9 +20,9 @@ "WP01": { "actor": "user", "force_count": 1, - "lane": "for_review", - "last_event_id": "01KR1WX5XY3JKX9XH9GTJHY6ER", - "last_transition_at": "2026-05-07T18:58:51.454594+00:00" + "lane": "approved", + "last_event_id": "01KR1X4VMFF2143XS72GZD5KW6", + "last_transition_at": "2026-05-07T19:03:03.055895+00:00" }, "WP02": { "actor": "user", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md index c59bc90..9bc8c23 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP01-server-setup-update.md @@ -274,3 +274,4 @@ When a new organization reaches the $100+/month sponsorship level: - 2026-05-07T18:56:27Z – claude – shell_pid=25745 – Assigned agent via action command - 2026-05-07T18:58:51Z – claude – shell_pid=25745 – Ready for review: server-setup.md updated with full 27-org ALLOWED_ORGS, staging OAuth App section, coder-ddev-com management docs, sponsor table, and runbook +- 2026-05-07T19:03:03Z – claude – shell_pid=25745 – Review passed: all subtasks complete and verified From f8ddafe48ab95f8fe658201dc0b1190ee28d005d Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:03:22 +0000 Subject: [PATCH 41/53] chore: update mission events --- .../github-org-gated-signup-01KR1P4G/mission-events.jsonl | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl index dd07485..cea79b7 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -9,3 +9,4 @@ {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP03"}, "timestamp": "2026-05-07T18:59:54.583177+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP04"}, "timestamp": "2026-05-07T19:01:36.970634+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-07T19:02:19.562296+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-07T19:03:11.234101+00:00", "type": "MissionNextInvoked"} From 7f338999ef67dcdcd1cca7ae4a10c654d70e747d Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:03:24 +0000 Subject: [PATCH 42/53] chore: Move WP02 to approved on spec github [claude] --- .../status.events.jsonl | 2 ++ .../github-org-gated-signup-01KR1P4G/status.json | 16 ++++++++-------- .../tasks/WP02-user-management-access-runbook.md | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 5029a8e..7eb4b1b 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -16,3 +16,5 @@ {"actor": "user", "at": "2026-05-07T19:02:14.030626+00:00", "event_id": "01KR1X3BREWGYZD5VWHTCMMTEM", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "in_progress", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Ready for review: blog-post-draft.md created with 3 sections", "review_ref": null, "to_lane": "for_review", "wp_id": "WP04"} {"actor": "user", "at": "2026-05-07T19:03:02.971035+00:00", "event_id": "01KR1X4VHVTRKEBN8QNC7FJSWK", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all subtasks complete and verified", "review_ref": null, "to_lane": "in_review", "wp_id": "WP01"} {"actor": "user", "at": "2026-05-07T19:03:03.055895+00:00", "event_id": "01KR1X4VMFF2143XS72GZD5KW6", "evidence": {"review": {"reference": "Review passed: all subtasks complete and verified", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all subtasks complete and verified", "review_ref": null, "to_lane": "approved", "wp_id": "WP01"} +{"actor": "user", "at": "2026-05-07T19:03:23.980400+00:00", "event_id": "01KR1X5G2CA5MEABZV1NN1KSNH", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: Access Management section complete with all 4 subtask topics", "review_ref": null, "to_lane": "in_review", "wp_id": "WP02"} +{"actor": "user", "at": "2026-05-07T19:03:24.069266+00:00", "event_id": "01KR1X5G55FJ8762EW7PCQVRZ4", "evidence": {"review": {"reference": "Review passed: Access Management section complete with all 4 subtask topics", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: Access Management section complete with all 4 subtask topics", "review_ref": null, "to_lane": "approved", "wp_id": "WP02"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index b6e77bf..431ed4e 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,17 +1,17 @@ { - "event_count": 18, - "last_event_id": "01KR1X4VMFF2143XS72GZD5KW6", - "materialized_at": "2026-05-07T19:03:03.055895+00:00", + "event_count": 20, + "last_event_id": "01KR1X5G55FJ8762EW7PCQVRZ4", + "materialized_at": "2026-05-07T19:03:24.069266+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", "summary": { - "approved": 1, + "approved": 2, "blocked": 0, "canceled": 0, "claimed": 0, "done": 0, - "for_review": 3, + "for_review": 2, "in_progress": 0, "in_review": 0, "planned": 0 @@ -27,9 +27,9 @@ "WP02": { "actor": "user", "force_count": 1, - "lane": "for_review", - "last_event_id": "01KR1WYZ60DJ46PDSRTMVG7X1P", - "last_transition_at": "2026-05-07T18:59:50.080669+00:00" + "lane": "approved", + "last_event_id": "01KR1X5G55FJ8762EW7PCQVRZ4", + "last_transition_at": "2026-05-07T19:03:24.069266+00:00" }, "WP03": { "actor": "user", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md index d3cebf1..78f7370 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP02-user-management-access-runbook.md @@ -237,3 +237,4 @@ When the `coder-ddev-com` GitHub org is created, add these initial members: - 2026-05-07T18:59:06Z – claude – shell_pid=29068 – Assigned agent via action command - 2026-05-07T18:59:50Z – claude – shell_pid=29068 – Ready for review: Access Management section added to user-management.md +- 2026-05-07T19:03:24Z – claude – shell_pid=29068 – Review passed: Access Management section complete with all 4 subtask topics From fd9b6dac7507e0970c5a396b09874a96afb51285 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:03:59 +0000 Subject: [PATCH 43/53] chore: update mission events for WP03 review --- .../github-org-gated-signup-01KR1P4G/mission-events.jsonl | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl index cea79b7..14f40ca 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -10,3 +10,4 @@ {"mission": "software-dev", "payload": {"action": "implement", "agent": "claude", "decision_kind": "step", "mission_state": "implement", "result_input": "success", "wp_id": "WP04"}, "timestamp": "2026-05-07T19:01:36.970634+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-07T19:02:19.562296+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-07T19:03:11.234101+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP03"}, "timestamp": "2026-05-07T19:03:29.663020+00:00", "type": "MissionNextInvoked"} From 5e97046cb50ea88f5f92244d4512cd4c6146f9b1 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:04:01 +0000 Subject: [PATCH 44/53] chore: Move WP03 to approved on spec github [claude] --- .../status.events.jsonl | 2 ++ .../github-org-gated-signup-01KR1P4G/status.json | 16 ++++++++-------- .../tasks/WP03-coder-ddev-com-org-content.md | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index 7eb4b1b..f9246b3 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -18,3 +18,5 @@ {"actor": "user", "at": "2026-05-07T19:03:03.055895+00:00", "event_id": "01KR1X4VMFF2143XS72GZD5KW6", "evidence": {"review": {"reference": "Review passed: all subtasks complete and verified", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all subtasks complete and verified", "review_ref": null, "to_lane": "approved", "wp_id": "WP01"} {"actor": "user", "at": "2026-05-07T19:03:23.980400+00:00", "event_id": "01KR1X5G2CA5MEABZV1NN1KSNH", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: Access Management section complete with all 4 subtask topics", "review_ref": null, "to_lane": "in_review", "wp_id": "WP02"} {"actor": "user", "at": "2026-05-07T19:03:24.069266+00:00", "event_id": "01KR1X5G55FJ8762EW7PCQVRZ4", "evidence": {"review": {"reference": "Review passed: Access Management section complete with all 4 subtask topics", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: Access Management section complete with all 4 subtask topics", "review_ref": null, "to_lane": "approved", "wp_id": "WP02"} +{"actor": "user", "at": "2026-05-07T19:04:01.068809+00:00", "event_id": "01KR1X6M9CQZQKB10R2G973FQ1", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all 4 files created with operator notes. YAML template structure verified.", "review_ref": null, "to_lane": "in_review", "wp_id": "WP03"} +{"actor": "user", "at": "2026-05-07T19:04:01.160896+00:00", "event_id": "01KR1X6MC85P9D1GT7TKMYXNS9", "evidence": {"review": {"reference": "Review passed: all 4 files created with operator notes. YAML template structure verified.", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all 4 files created with operator notes. YAML template structure verified.", "review_ref": null, "to_lane": "approved", "wp_id": "WP03"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 431ed4e..3460a72 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,17 +1,17 @@ { - "event_count": 20, - "last_event_id": "01KR1X5G55FJ8762EW7PCQVRZ4", - "materialized_at": "2026-05-07T19:03:24.069266+00:00", + "event_count": 22, + "last_event_id": "01KR1X6MC85P9D1GT7TKMYXNS9", + "materialized_at": "2026-05-07T19:04:01.160896+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", "summary": { - "approved": 2, + "approved": 3, "blocked": 0, "canceled": 0, "claimed": 0, "done": 0, - "for_review": 2, + "for_review": 1, "in_progress": 0, "in_review": 0, "planned": 0 @@ -34,9 +34,9 @@ "WP03": { "actor": "user", "force_count": 1, - "lane": "for_review", - "last_event_id": "01KR1X2205N6K31W5W6MSDE0QE", - "last_transition_at": "2026-05-07T19:01:31.269163+00:00" + "lane": "approved", + "last_event_id": "01KR1X6MC85P9D1GT7TKMYXNS9", + "last_transition_at": "2026-05-07T19:04:01.160896+00:00" }, "WP04": { "actor": "user", diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md index 28ce3c8..33401d3 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP03-coder-ddev-com-org-content.md @@ -307,3 +307,4 @@ Thank you for supporting DDEV! - 2026-05-07T19:00:15Z – claude – shell_pid=30615 – Started implementation via action command - 2026-05-07T19:01:31Z – claude – shell_pid=30615 – Ready for review: org-profile-README, access-requests-README, issue template, sponsor notification all created in docs/admin/coder-ddev-com/ +- 2026-05-07T19:04:01Z – claude – shell_pid=30615 – Review passed: all 4 files created with operator notes. YAML template structure verified. From ef4b4b14d39e8c4630cf7ff1f9e21332817bbdd3 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:04:13 +0000 Subject: [PATCH 45/53] chore: update mission events for WP04 review --- .../github-org-gated-signup-01KR1P4G/mission-events.jsonl | 1 + 1 file changed, 1 insertion(+) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl index 14f40ca..6dd9389 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -11,3 +11,4 @@ {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP01"}, "timestamp": "2026-05-07T19:02:19.562296+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-07T19:03:11.234101+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP03"}, "timestamp": "2026-05-07T19:03:29.663020+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP04"}, "timestamp": "2026-05-07T19:04:05.346776+00:00", "type": "MissionNextInvoked"} From 69428f196c0b7e8e93097e1081fd4211f308263a Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:04:15 +0000 Subject: [PATCH 46/53] chore: Move WP04 to approved on spec github [claude] --- .../status.events.jsonl | 2 ++ .../github-org-gated-signup-01KR1P4G/status.json | 16 ++++++++-------- .../tasks/WP04-blog-post-draft.md | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl index f9246b3..df5e11a 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.events.jsonl @@ -20,3 +20,5 @@ {"actor": "user", "at": "2026-05-07T19:03:24.069266+00:00", "event_id": "01KR1X5G55FJ8762EW7PCQVRZ4", "evidence": {"review": {"reference": "Review passed: Access Management section complete with all 4 subtask topics", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: Access Management section complete with all 4 subtask topics", "review_ref": null, "to_lane": "approved", "wp_id": "WP02"} {"actor": "user", "at": "2026-05-07T19:04:01.068809+00:00", "event_id": "01KR1X6M9CQZQKB10R2G973FQ1", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all 4 files created with operator notes. YAML template structure verified.", "review_ref": null, "to_lane": "in_review", "wp_id": "WP03"} {"actor": "user", "at": "2026-05-07T19:04:01.160896+00:00", "event_id": "01KR1X6MC85P9D1GT7TKMYXNS9", "evidence": {"review": {"reference": "Review passed: all 4 files created with operator notes. YAML template structure verified.", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: all 4 files created with operator notes. YAML template structure verified.", "review_ref": null, "to_lane": "approved", "wp_id": "WP03"} +{"actor": "user", "at": "2026-05-07T19:04:15.031093+00:00", "event_id": "01KR1X71XQJK42VZ3CKAC0B85G", "evidence": null, "execution_mode": "worktree", "force": false, "from_lane": "for_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: blog-post-draft.md has all 3 required sections and correct access-requests link", "review_ref": null, "to_lane": "in_review", "wp_id": "WP04"} +{"actor": "user", "at": "2026-05-07T19:04:15.121111+00:00", "event_id": "01KR1X720HBERH8WV858JGT87Z", "evidence": {"review": {"reference": "Review passed: blog-post-draft.md has all 3 required sections and correct access-requests link", "reviewer": "Randy Fay", "verdict": "approved"}}, "execution_mode": "worktree", "force": false, "from_lane": "in_review", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", "mission_slug": "github-org-gated-signup-01KR1P4G", "policy_metadata": null, "reason": "Review passed: blog-post-draft.md has all 3 required sections and correct access-requests link", "review_ref": null, "to_lane": "approved", "wp_id": "WP04"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 3460a72..58f0031 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -1,17 +1,17 @@ { - "event_count": 22, - "last_event_id": "01KR1X6MC85P9D1GT7TKMYXNS9", - "materialized_at": "2026-05-07T19:04:01.160896+00:00", + "event_count": 24, + "last_event_id": "01KR1X720HBERH8WV858JGT87Z", + "materialized_at": "2026-05-07T19:04:15.121111+00:00", "mission_number": "", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", "summary": { - "approved": 3, + "approved": 4, "blocked": 0, "canceled": 0, "claimed": 0, "done": 0, - "for_review": 1, + "for_review": 0, "in_progress": 0, "in_review": 0, "planned": 0 @@ -41,9 +41,9 @@ "WP04": { "actor": "user", "force_count": 1, - "lane": "for_review", - "last_event_id": "01KR1X3BREWGYZD5VWHTCMMTEM", - "last_transition_at": "2026-05-07T19:02:14.030626+00:00" + "lane": "approved", + "last_event_id": "01KR1X720HBERH8WV858JGT87Z", + "last_transition_at": "2026-05-07T19:04:15.121111+00:00" } } } diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md index 92fb476..9bef68b 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/tasks/WP04-blog-post-draft.md @@ -186,3 +186,4 @@ If the blog post has a section mentioning DDEV sponsors, add the following sente - 2026-05-07T19:01:42Z – claude – shell_pid=32508 – Started implementation via action command - 2026-05-07T19:02:14Z – claude – shell_pid=32508 – Ready for review: blog-post-draft.md created with 3 sections +- 2026-05-07T19:04:15Z – claude – shell_pid=32508 – Review passed: blog-post-draft.md has all 3 required sections and correct access-requests link From 486b4404e64f61afd8611a83de1e86e3ecacf3fd Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 19:04:51 +0000 Subject: [PATCH 47/53] chore(github-org-gated-signup-01KR1P4G): assign mission_number=1 --- kitty-specs/github-org-gated-signup-01KR1P4G/meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json b/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json index 1151b84..5b00ae7 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/meta.json @@ -2,7 +2,7 @@ "created_at": "2026-05-07T17:00:31.394646+00:00", "friendly_name": "GitHub Org-Gated Signup", "mission_id": "01KR1P4G5AJEBQMAZH1DKNQZHV", - "mission_number": null, + "mission_number": 1, "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", "slug": "github-org-gated-signup-01KR1P4G", From 1573f444b1209bd779e2f9db98f44028b73492f4 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 21:17:56 +0000 Subject: [PATCH 48/53] chore: finalize mission event log and status after merge Co-Authored-By: Claude Sonnet 4.6 --- .../github-org-gated-signup-01KR1P4G/mission-events.jsonl | 1 + kitty-specs/github-org-gated-signup-01KR1P4G/status.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl index 6dd9389..4e46c16 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/mission-events.jsonl @@ -12,3 +12,4 @@ {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP02"}, "timestamp": "2026-05-07T19:03:11.234101+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP03"}, "timestamp": "2026-05-07T19:03:29.663020+00:00", "type": "MissionNextInvoked"} {"mission": "software-dev", "payload": {"action": "review", "agent": "claude", "decision_kind": "step", "mission_state": "review", "result_input": "success", "wp_id": "WP04"}, "timestamp": "2026-05-07T19:04:05.346776+00:00", "type": "MissionNextInvoked"} +{"mission": "software-dev", "payload": {"action": null, "agent": "claude", "decision_kind": "terminal", "mission_state": "done", "result_input": "success", "wp_id": null}, "timestamp": "2026-05-07T19:04:56.122284+00:00", "type": "MissionNextInvoked"} diff --git a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json index 58f0031..a32e80f 100644 --- a/kitty-specs/github-org-gated-signup-01KR1P4G/status.json +++ b/kitty-specs/github-org-gated-signup-01KR1P4G/status.json @@ -2,7 +2,7 @@ "event_count": 24, "last_event_id": "01KR1X720HBERH8WV858JGT87Z", "materialized_at": "2026-05-07T19:04:15.121111+00:00", - "mission_number": "", + "mission_number": "1", "mission_slug": "github-org-gated-signup-01KR1P4G", "mission_type": "software-dev", "summary": { From 9c161228cb43021a258e2939ad40a3b10d4a8317 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 21:33:53 +0000 Subject: [PATCH 49/53] fix: sync access-requests README corrections - Discord: ddev.com/s/discord - Issues: ddev/coder-ddev not ddev/ddev Co-Authored-By: Claude Sonnet 4.6 --- docs/admin/coder-ddev-com/access-requests-README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/admin/coder-ddev-com/access-requests-README.md b/docs/admin/coder-ddev-com/access-requests-README.md index 1af58c9..86e0fb1 100644 --- a/docs/admin/coder-ddev-com/access-requests-README.md +++ b/docs/admin/coder-ddev-com/access-requests-README.md @@ -34,4 +34,4 @@ We aim to respond to requests within a few business days. If you have not heard ## Questions -Visit the [DDEV Discord](https://discord.ddev.com) or open an issue in [ddev/ddev](https://github.com/ddev/ddev/issues). +Visit the [DDEV Discord](https://ddev.com/s/discord) or open an issue in [ddev/coder-ddev](https://github.com/ddev/coder-ddev/issues). From 932839352306535799eb9032f95d1ec41038aa6a Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 22:16:37 +0000 Subject: [PATCH 50/53] docs: update start page for org-gated auth, add access-denied page - start.coder.ddev.com auth-callout now explains ddev/sponsor org requirement and links to coder-ddev-com/access-requests - Add docs/access-denied.html for use as redirect target when unauthorized users hit the OAuth callback (used by the Caddy reverse-proxy fix) Co-Authored-By: Claude Sonnet 4.6 --- docs/access-denied.html | 176 ++++++++++++++++++++++++++++++++++++++++ docs/index.html | 6 +- 2 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 docs/access-denied.html diff --git a/docs/access-denied.html b/docs/access-denied.html new file mode 100644 index 0000000..9210df4 --- /dev/null +++ b/docs/access-denied.html @@ -0,0 +1,176 @@ + + + + + + Access Required — DDEV Coder Workspaces + + + + +
+
🔒
+

Access Required

+

+ Your GitHub account doesn't currently have access to coder.ddev.com. + Access is restricted to members of specific GitHub organizations. +

+ +
+

Who qualifies

+ +
+ + +
+ + + + diff --git a/docs/index.html b/docs/index.html index 53e828a..64d2209 100644 --- a/docs/index.html +++ b/docs/index.html @@ -57,7 +57,7 @@ margin-bottom: 1.75rem; font-size: 1rem; color: #bbb; - max-width: 420px; + max-width: 500px; } .auth-callout svg { flex-shrink: 0; } @@ -252,7 +252,7 @@

Coder Workspaces

- Requires a GitHub accountsign in at coder.ddev.com first + Requires GitHub membership in the ddev or a sponsor orgrequest access · sign in @@ -271,7 +271,7 @@

Coder Workspaces

How it works

    -
  1. Sign in with GitHub at coder.ddev.com
  2. +
  3. Sign in with GitHub at coder.ddev.com — access requires the ddev org, a $100+/mo sponsor org, or an approved request
  4. Click Create Workspace — your environment sets up automatically
  5. Click DDEV Web to open the running site, or VS Code to edit code
From 3eece6934f9e71513cf27bb7c72e29983d24f021 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 22:27:40 +0000 Subject: [PATCH 51/53] docs: fix auth-callout wording on start page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "the ddev" → "the ddev org" Co-Authored-By: Claude Sonnet 4.6 --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 64d2209..9f39f5c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -252,7 +252,7 @@

Coder Workspaces

- Requires GitHub membership in the ddev or a sponsor orgrequest access · sign in + Requires GitHub membership in the ddev org or a sponsor orgrequest access · sign in From b3e6fe2ed842a0340ff6bec4fe588f2f0ccfce9e Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 22:50:06 +0000 Subject: [PATCH 52/53] docs: add spec-kitty workflow guide Explains project structure (.kittify/, kitty-specs/), when to use spec-kitty, how to start a mission, implementation lanes, key files (wps.yaml, spec.md, mission-events.jsonl), common pitfalls, and a completed missions table. Co-Authored-By: Claude Sonnet 4.6 --- docs/admin/spec-kitty-workflow.md | 103 ++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 docs/admin/spec-kitty-workflow.md diff --git a/docs/admin/spec-kitty-workflow.md b/docs/admin/spec-kitty-workflow.md new file mode 100644 index 0000000..64f2c39 --- /dev/null +++ b/docs/admin/spec-kitty-workflow.md @@ -0,0 +1,103 @@ +# spec-kitty Workflow + +spec-kitty is the spec-driven development tool used for significant feature work in this project. It drives an AI agent through a structured lifecycle — discovery → research → spec → plan → implement → review — and keeps the paper trail in the repo. + +## When to use spec-kitty + +Use it for: +- New features or capabilities (new auth, new template type, new user-facing workflow) +- Breaking changes to infrastructure or user flows +- Work that touches multiple files and needs a traceable decision record + +Skip it for: bug fixes, typos, dependency bumps, config tweaks, one-line changes. + +## Project structure + +Two directories persist in the repo across all missions: + +``` +.kittify/ # Project-level config (set up once, shared by all missions) +├── charter/charter.md # Project governance, quality directives, stakeholder roles +├── config.yaml # spec-kitty project config +└── skills-manifest.json # Registered agent skills + +kitty-specs/ # One subdirectory per completed mission (permanent record) +└── / + ├── spec.md # Requirements document + ├── research.md # Research summary + ├── research/ # Evidence log + source register CSVs + ├── data-model.md # Entity model for the feature + ├── plan.md # Approved implementation plan + ├── wps.yaml # Work-package manifest (authoritative task source) + ├── tasks.md / tasks/WP*.md # Generated task files consumed by agents + ├── checklists/requirements.md # Requirement-traceability checklist + └── mission-events.jsonl # Append-only audit log of all state transitions +``` + +## Starting a new mission + +### 1. Create the feature scaffold + +```bash +spec-kitty specify +# e.g.: spec-kitty specify workspace-quotas +``` + +This creates `kitty-specs//` with the skeleton files and registers the mission. + +### 2. Run the agent + +From the repo root: + +```bash +spec-kitty next --agent claude --mission +``` + +The agent reads the current mission state and returns the next action. Keep running this command as the agent works through each phase. The state machine progresses through: + +``` +not_started → discovery → specify → plan → tasks_outline → tasks_packages + → tasks_finalize → implement → review → accept → done +``` + +**Important:** Always run `spec-kitty next` from the repo root, not from inside a worktree. + +### 3. Implementation lanes + +During implementation, spec-kitty creates git worktrees (`.worktrees/-lane-`) for parallel work packages. Each lane is an isolated branch. Edits to owned files **must happen inside the correct worktree**, not in the main repo checkout. After implementation: + +```bash +spec-kitty merge --mission --lane a # merge lane-a into target branch +spec-kitty merge --mission --lane b # merge lane-b, etc. +``` + +### 4. Review and accept + +After all work packages are implemented and merged: + +```bash +spec-kitty accept --mission +``` + +This validates completeness (all WPs done, all requirements traced) before the PR is opened. + +## Key files to know + +**`wps.yaml`** is the single source of truth for what needs to be built. It defines work packages, their dependencies, the files each WP owns, and the subtasks within each WP. The `finalize-tasks` step generates `tasks.md` and `lanes.json` from it. If you need to change scope, edit `wps.yaml` before finalize runs. + +**`spec.md`** contains the requirements (FR-xxx, C-xxx, NFR-xxx). Every requirement should trace to a WP in `wps.yaml` and appear in `checklists/requirements.md`. + +**`mission-events.jsonl`** is append-only. Never edit it directly — it's the audit log of every state transition. If spec-kitty rejects a `move-task` because the repo is dirty, commit any loose files first, then retry. + +## Common pitfalls + +- **Uncommitted files block transitions.** spec-kitty checks for a clean working tree before advancing state. Commit `mission-events.jsonl` and any other loose files before running `next` or `move-task`. +- **Git signing.** If the environment doesn't have an SSH signing agent, commits in external repos need `-c gpg.format=openpgp -c commit.gpgsign=false`. +- **`spec-kitty next` from the main repo.** Running it from inside a worktree fails with "must run from the main repository." +- **`--json` not supported everywhere.** The `implement` subcommand does not accept `--json`; drop the flag. + +## Completed missions + +| Mission ID | Title | PR | +|---|---|---| +| `github-org-gated-signup-01KR1P4G` | GitHub org-gated access for coder.ddev.com | #131 | From 076217220f4cc872a91f4cbe7c084a24d75c6d11 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 7 May 2026 23:08:31 +0000 Subject: [PATCH 53/53] docs: remove blog-post-draft, applied to ddev.com Changes have been applied directly to ddev/ddev.com src/content/blog/coder-ddev-com-announcement.md Co-Authored-By: Claude Sonnet 4.6 --- docs/admin/blog-post-draft.md | 52 ----------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 docs/admin/blog-post-draft.md diff --git a/docs/admin/blog-post-draft.md b/docs/admin/blog-post-draft.md deleted file mode 100644 index 75661d2..0000000 --- a/docs/admin/blog-post-draft.md +++ /dev/null @@ -1,52 +0,0 @@ -# Blog Post Update Draft: coder.ddev.com Org-Gated Signup - -**Target file**: `ddev/ddev.com/src/content/blog/coder-ddev-com-announcement.md` -**Action**: Apply these section replacements to the blog post, then open a PR to `ddev/ddev.com` - ---- - -## Section: "Log In with GitHub" — Replace existing content - -Find the section in the blog post that explains GitHub login. Replace the existing content of that section with the following: - ---- - -### Log In with GitHub - -Access to coder.ddev.com requires a GitHub account. Sign in using the **Sign in with GitHub** button — no separate Coder account registration is needed. - -**Who has access:** - -- Members of the [ddev](https://github.com/ddev) GitHub organization -- Members of organizations that sponsor DDEV at $100+/month (see the [DDEV sponsors page](https://ddev.com/support-ddev/)) -- Individuals approved by the DDEV maintainers - -If you are a `ddev` org member or your organization is a $100+/month sponsor, you can sign in immediately — no request needed. - ---- - -## Section: Access Restriction and Request Path — Add after "Log In with GitHub" - -Add the following as a new paragraph or subsection immediately after the "Log In with GitHub" section: - ---- - -### Requesting Access - -If you do not have access through one of the paths above, you can request it by opening an issue in the [coder-ddev-com/access-requests](https://github.com/coder-ddev-com/access-requests) repository on GitHub. Include your GitHub username and a brief description of how you plan to use the environment. - -The DDEV maintainers review requests and add approved users to the `coder-ddev-com` GitHub organization. Once added, you can sign in immediately — no server restart needed on our end. - ---- - -## Section: Sponsor Org Access — Add to "Sponsors" or "Support DDEV" section - -If the blog post has a section mentioning DDEV sponsors, add the following sentence or short paragraph. If no such section exists, add it as a standalone callout near the end of the post: - ---- - -**Sponsor org access**: Organizations that sponsor DDEV at $100+/month receive access as an org-level benefit — all members of a sponsor's GitHub organization can sign in to coder.ddev.com without individual enrollment. See the [DDEV sponsors page](https://ddev.com/support-ddev/) if your organization is interested in sponsoring. - ---- - -**Note for operator**: If the blog post already has a sponsors callout, integrate this sentence rather than adding a duplicate section.