Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .devcontainer/agent-versions.env
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Last reviewed together on 2026-08-30. Re-review every pin before each template release.
# Tool/runtime pins retained from the 2026-08-30 review. Re-review before each template release.
CLAUDE_CODE_VERSION=2.1.226
CODEX_VERSION=0.147.0
FIRSTDRAFT_CLI_VERSION=0.2.2
# CLI 0.2.x requires staging to serve First Draft API 0.3.x before template promotion.
FIRSTDRAFT_CLI_DEFAULT_API_URL=https://firstdraft.com
FIRSTDRAFT_STAGING_API_URL=https://staging.firstdraft.com
FIRSTDRAFT_SKILLS_REVISION=0a765f88d1cd500168e18ce1adda03802773f35e
# Source-only root-handoff update reviewed 2026-09-05; CLI and package versions are unchanged.
FIRSTDRAFT_SKILLS_REVISION=8ae02160b44b40d21ec432cf2d1ab2772f9aae6b
FIRSTDRAFT_CLAUDE_SKILL_NAME=create-full-stack-app
# Codex namespaces the canonical source checkout with its root plugin manifest.
FIRSTDRAFT_CODEX_SKILL_NAME=firstdraft:create-full-stack-app
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@
"remoteUser": "vscode",
"onCreateCommand": "sudo chown -R vscode:vscode /home/vscode/.claude /home/vscode/.codex /home/vscode/.cache",
"postCreateCommand": ".devcontainer/setup-agents",
"postAttachCommand": "script/refresh-codespaces-private-port"
"postAttachCommand": "if [ -x script/refresh-codespaces-private-port ]; then exec script/refresh-codespaces-private-port; else exec design/script/refresh-codespaces-private-port; fi"
}
3 changes: 2 additions & 1 deletion .devcontainer/setup-agents
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,6 @@ firstdraft --version
printf '\nDrawing Board setup complete.\n'
printf 'Next: paste your staging First Draft token into the `FIRSTDRAFT_API_TOKEN` entry in `.env`.\n'
printf 'Then run `claude` or `codex` and describe the app you want.\n'
printf 'The ordinary Compile creates `./application`; the agent initializes and verifies it before continuing there.\n'
printf 'The internal-alpha path is `--output .`: approve moving this Drawing Board into `design/`, then continue in the app at the root.\n'
printf 'Keep the same Git repository; never run the nested application initializer after root adoption.\n'
printf 'Ask explicitly for a private GitHub repository if you want the separate Publication mode.\n'
65 changes: 34 additions & 31 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,52 @@
# AGENTS.md — First Draft Drawing Board

This repository root is a pre-compilation workspace. Help the user describe one application and maintain its current
Foundation Plan through the installed `create-full-stack-app` Skill. A generated Rails Foundation may later appear
under the ignored `application/` directory; keep its source and commands within that directory rather than mixing
them into the Drawing Board root.
This repository starts as a planning workspace. Help the user describe one application and maintain its current
Foundation Plan through the installed `create-full-stack-app` Skill. The internal-alpha path compiles into this
root, preserving its Git history and remote while moving the original Drawing Board material under `design/`.
A plain request such as "Make me an app that tracks my inventory" is enough to begin; do not require the user to
name the Skill or translate the request into a command.

## Working boundary

- Follow the installed Skill for interviewing, Plan structure, validation, submission, Compilation, and recovery.
- The current candidate is `.firstdraft/foundation-plan.json`. Its sibling `state.json` is private CLI concurrency
state: never print, paste, commit, edit as Plan content, or expose it to another service.
- `.firstdraft/` is deliberately ignored by Git. Review the current Plan directly; do not infer its state from a
Git diff.
- `application/` is deliberately ignored by the Drawing Board. When present, it is the generated Rails Foundation;
run `bin/setup`, `bin/dev`, Rails, and application tests from there. The root `bin/` remains Drawing Board tooling.
Direct-download output has no nested Git repository; run root `script/initialize-application` once before entering
it so Git-sensitive application checks cannot resolve to the enclosing Drawing Board repository. Run it before
setup or edits; it stops without deleting ignored local state rather than risking that state in the first commit.
- In this Drawing Board, direct local output is the default completion mode. From the physical workspace root, the
installed Skill runs `bin/firstdraft plan compile --output ./application` after the user approves that exact mode.
The destination must still be absent. On success, run root `script/initialize-application application` before
setup or edits, then `script/application-smoke`; do not manufacture Git metadata or repair generated bytes by hand.
- Before Compile, the current candidate is `.firstdraft/foundation-plan.json`. Its sibling `state.json` is private
CLI concurrency state: never print, paste, commit, edit as Plan content, or expose it to another service.
- The planning `.firstdraft/` is ignored by Git. Review the current Plan directly; do not infer its state from a
Git diff. Root adoption moves this private state into `design/.firstdraft/`; the new root `.firstdraft/` contains
the generated app's submitted Plan and reviewed GapSet instead.
- Present `bin/firstdraft plan compile --output .` as the internal-alpha completion mode. Obtain explicit approval
of the reviewed Plan, gaps, and relocation of this Drawing Board into `design/` before running it from the physical
workspace root. A generic Compile request does not authorize that relocation. If root eligibility fails, preserve
the workspace and explain the exact refusal; do not delete files or switch modes to force it through.
- After root adoption, keep the existing `.git` and remote. Inspect and commit the staged generated baseline before
setup or source edits, checking that no credentials are staged. Never run `script/initialize-application` or
`script/application-smoke`, including their copies under `design/`: those helpers require a separate nested app.
Run ordinary Rails commands at the new root. For later First Draft authoring commands, enter `design/` and use its
`bin/firstdraft`; do not rely on the original container's bare `firstdraft` PATH after relocation.
- If the user chooses the optional nested mode, run `bin/firstdraft plan compile --output ./application` into an
absent destination. Then run root `script/initialize-application application` before setup or edits, followed by
`script/application-smoke`. Only in this mode is `application/` an ignored, separate Git repository with no remote;
continue with Rails commands inside it. Do not manufacture Git metadata or repair generated bytes by hand.
- If `application/` already exists, preserve it. Never delete, overwrite, or move it merely to satisfy the absent-path
precondition. Stop and ask the user whether to continue in the existing application, push its nested `main` to an
approved remote when that repository exists, or preserve it under the Drawing Board's ignored, bind-mounted `tmp/`
before starting a different Compile. Do not use `/tmp`, the container home, or another path that a Codespace
rebuild discards.
- The pinned CLI also supports explicit POSIX current-root adoption with `--output .`, but that is not this
template's default. Select it only when the user asks to turn this exact root into the application and has approved
moving the existing Drawing Board material under `design/`; never infer it from a generic request to Compile.
- If a Codespaces forwarded-port URL reaches Rails' **Blocked hosts** page, preserve the exact generated revision,
report the observed response, and stop. Do not edit or clear `config.hosts`, or add host-admission environment
variables to the Drawing Board or the generated application.
- Zero-flag `bin/firstdraft plan compile` is a separate mode for a user who explicitly asks for a private GitHub
repository. Never switch modes to recover from an ambiguous start. Neither mode deploys the application.
repository. Never switch modes to recover from an ambiguous start. No Compile mode deploys the application.
- Use `bin/firstdraft` for every First Draft command. When the installed Skill shows `firstdraft ...`, pass those
same arguments to this repository wrapper. It loads the ignored `.env`, requires staging, and launches the exact
pinned standalone CLI for both Claude and Codex. Do not bypass it, call the service with improvised HTTP, or
install another CLI version. If Codex's sandbox blocks the expected staging request, request approval for that
exact wrapper command; do not work around the sandbox or broaden network access.
- Setup creates `.env` from `.env.example` without overwriting it. The user pastes the staging First Draft token
- Drawing Board setup creates `.env` from `.env.example` without overwriting it. The user pastes the staging token
there once. Never read, print, edit, or commit `.env`; do not ask for `/plugin` configuration, Codespaces secrets,
shell exports, or a GitHub PAT. Use `bin/agent-doctor --installation-only` for installation diagnostics and the
full `bin/agent-doctor` to add validation of the shared wrapper and `.env` without printing the token.
full `bin/agent-doctor` to add validation of the shared wrapper and `.env` without printing the token. These are
pre-Compile diagnostics; after root adoption, use the generated README and the exact Rails error.

## Collaboration and credentials

Expand All @@ -57,11 +59,12 @@ name the Skill or translate the request into a command.
private repository, not a branch or pull request in this Drawing Board. Route an installation-readiness failure
back to First Draft's **Connect GitHub App** flow; do not improvise credentials.
- Do not publish or release packages from this repository.
- After direct Compile and initialization succeed, report `application/`, its nested initial commit, and its
`.firstdraft/submitted-foundation-plan.json` and `.firstdraft/gaps.json`. State that the parent Drawing Board
ignores this local repository and it has no remote; before the Codespace is deleted, offer to create and push a
remote only with the user's approval. Continue inside that directory. After explicit Publication succeeds, report
the validated private GitHub URL and continue only in a separate checkout when the user asks.
- After root Compile succeeds, report the generated-baseline commit, existing remote, and root
`.firstdraft/submitted-foundation-plan.json` and `.firstdraft/gaps.json`. Help save later edits in a separate commit
and push to that same repository when authorized. In nested mode, report the nested initial commit and no-remote
boundary; before the Codespace is deleted, offer to create and push a remote only with the user's approval.
After explicit Publication succeeds, report the validated private GitHub URL and continue only in a separate
checkout when the user asks.

## Continue after Compile

Expand All @@ -70,9 +73,9 @@ in the generated application with its normal Rails tools, tests, and README. Com
for an edited application. Keep missing Plan meaning visible in the retained GapSet, but do not require every gap
to be closed before ordinary development or handoff.

Follow the [beginner guide](README.md#8-save-your-app-to-github) for saving the separate application repository and
deployment. Deployment is an ordinary application-development step when the user requests it, not another Compile
or a prerequisite for continuing locally. Inspect that application's production configuration and current provider
Follow the [beginner guide](README.md#8-save-your-app-to-github) for saving to the existing repository after root
adoption. Deployment is optional application-development work when the user requests it, not another Compile
or a prerequisite for the internal-alpha test. Inspect that application's production configuration and current provider
guides; prefer Rails conventions over new First Draft deployment machinery. Never infer permission to spend money,
publish source, or expose private data from an earlier Compile approval.

Expand Down
37 changes: 26 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ A repository created from this template must provide one ready-to-use workspace
- bare `firstdraft` on the Codespace PATH resolves to `bin/firstdraft`, and AGENTS.md routes Skill-issued commands
through that wrapper; and
- the same container carries the current generated Foundation's Ruby and Node toolchain plus healthy PostgreSQL;
generated browser tests start the pinned Selenium service on demand, so an ignored application under
`./application` can be developed without a second Codespace.

The template does not commit generated application source. `application/` is ignored local output; its Rails source
remains distinct from the Drawing Board even though both use one container. The pinned CLI and Skill make direct
materialization available, and Drawing Board's `AGENTS.md` selects the absent `application/` directory as this
template's default completion mode. Zero-flag GitHub Publication remains a separate explicit mode. The accepted
generated browser tests start the pinned Selenium service on demand, so the generated application can be
developed without a second Codespace.

The template itself does not contain generated application source. For the internal alpha, Drawing Board's
`AGENTS.md` selects explicit `--output .` approval: the application replaces the workspace layout, original material
moves under `design/`, and the same Git repository and remote hold both. Inspect and commit the staged baseline
before setup or edits. Do not run the nested initializer or application smoke after root adoption, including their
relocated copies. The optional `--output ./application` mode keeps an ignored, separate nested application; only that
mode uses the initializer and application smoke. Zero-flag GitHub Publication remains another explicit mode. The accepted
cross-repository sequence and its safety boundaries live in
[DIRECT_COMPILATION_PLAN.md](DIRECT_COMPILATION_PLAN.md).

Expand Down Expand Up @@ -49,7 +51,7 @@ cross-repository sequence and its safety boundaries live in
| `script/selenium` | On-demand Selenium start, status, and stop inside the Dev Container |
| `script/application-smoke` | Setup, PostgreSQL, readiness, and full CI proof for a generated `./application` |

The initializer follows the generated application's own ignore rules. The only artifact-owned paths allowed to
The nested initializer follows the generated application's own ignore rules. The only artifact-owned paths allowed to
bypass those rules are `.firstdraft/submitted-foundation-plan.json` and `.firstdraft/gaps.json`. Any other ignored
path is preserved and stops initialization; a future generated ignored file must update this narrow allowlist and
its exact-byte fixture in the same coordinated release. Canonical `0644` and `0755` modes are part of the generated
Expand Down Expand Up @@ -145,6 +147,17 @@ as the runtime discriminator and
the current CLI's visibility command is the supported control surface. This is a containment for an observed
provider registration defect, not a custom tunnel or application workaround.

The `postAttachCommand` resolves that same helper at `script/refresh-codespaces-private-port` before root adoption
and `design/script/refresh-codespaces-private-port` afterward. This uses the standard
[Dev Container shell lifecycle](https://containers.dev/implementors/json_reference/#lifecycle-scripts), not a new
service: the [reference implementation](https://github.com/devcontainers/cli/blob/main/src/spec-common/injectHeadless.ts)
runs a string command in `/bin/sh` with the workspace as its working directory. An inline path selection survives
the move even when the already-running container retains its original lifecycle configuration. Helper errors still
propagate, including its active-listener refusal; no port policy changes with the path. The focused
`script/check-codespaces-private-port.mjs` exercises the configured command before and after a fixture's `script/`
directory moves under `design/`, alongside the existing private-port and listener cases. That local proof is not a
new Codespaces observation.

The repaired tunnel exposed the already-recorded generated Rails HostAuthorization boundary. Do not copy the
student template's broad `config.hosts.clear` or disabled origin check into Drawing Board. Generated-app host and
Origin handling remain target-owned. The [successor qualification](DIRECT_COMPILATION_PLAN.md#observed-successor-qualification-on-2026-09-0102)
Expand All @@ -166,13 +179,15 @@ are owned by [firstdraft/firstdraft](https://github.com/firstdraft/firstdraft);

Keep [README.md](README.md) focused on the beginner journey. Put maintainer commands and implementation details here,
and keep agent-only guardrails in [AGENTS.md](AGENTS.md). If a workflow change affects what a tester must do, update
the README and verify the affected journey before landing it: template-to-`application/` for direct mode, or the
separate-repository journey for Publication. [DIRECT_COMPILATION_PLAN.md](DIRECT_COMPILATION_PLAN.md) owns the
the README and verify the affected journey before landing it: root adoption for the internal-alpha path, nested
`application/` when selected, or the separate-repository journey for Publication.
[DIRECT_COMPILATION_PLAN.md](DIRECT_COMPILATION_PLAN.md) owns the
current direct-journey acceptance steps and every explicitly unfinished step; do not call that journey complete
until those steps are observed.

The internal-alpha delivery scope is the editor-first loop in the README: Codespace, installed Skill, existing
agent, direct Compile, boot, ordinary source iteration, and an application deployment. A separate Plan web editor,
agent, approved root Compile, boot, source inspection, ordinary source iteration, and saving to the same repository.
Deployment is optional follow-on work, not a pre-send gate for that code-sharing test. A separate Plan web editor,
public plugin promotion, and completion of all realization gaps are not prerequisites. The existing web surface
supplies access and credentials; an explorable read-only Plan view can improve independently.

Expand Down
Loading