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
6 changes: 3 additions & 3 deletions .devcontainer/agent-versions.env
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Last reviewed together on 2026-08-27. Re-review every pin before each template release.
# Last reviewed together on 2026-08-28. Re-review every pin before each template release.
CLAUDE_CODE_VERSION=2.1.226
CODEX_VERSION=0.147.0
FIRSTDRAFT_CLI_VERSION=0.2.0
FIRSTDRAFT_CLI_VERSION=0.2.1
# 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=2ab23ecb4d0bc6f7a28c6d55de305f25b2f1d893
FIRSTDRAFT_SKILLS_REVISION=160d33a5a7d9f9b2282729ecfd3b2e24a1123143
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
3 changes: 2 additions & 1 deletion .devcontainer/setup-agents
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,5 @@ 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 'A successful Compile returns a fresh private GitHub repository; it does not modify this Drawing Board.\n'
printf 'The ordinary Compile creates `./application`; the agent initializes and verifies it before continuing there.\n'
printf 'Ask explicitly for a private GitHub repository if you want the separate Publication mode.\n'
31 changes: 23 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,20 @@ name the Skill or translate the request into a command.
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.
- The currently pinned CLI and Skill still Compile by publishing a separate private GitHub repository; they do
not accept `--output` or populate `application/`. The local path and initializer are preparation for a later
coordinated CLI/Skill/pin release. Do not improvise the unreleased command from this repository.
- 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.
- 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.
- If a Codespaces forwarded-port URL reaches Rails' **Blocked hosts** page, report the known target-owned defect 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.
- 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
Expand All @@ -38,11 +49,15 @@ name the Skill or translate the request into a command.
`bin/review-plan-with-claude` or `bin/review-plan-with-codex`.
- Never print, log, commit, or request a First Draft token in chat. The local `.env` is agent-readable development
credential delivery, not isolation from either agent; `bin/agent-doctor` reports presence only.
- Never request a GitHub personal access token. Publication uses the GitHub account already connected to First Draft
and creates a fresh private repository, not a branch or pull request in this Drawing Board.
- Never request a GitHub personal access token. Direct output creates no Publication or repository. If the user
explicitly selects Publication, it uses the GitHub account already connected to First Draft and creates a fresh
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 Compile succeeds, report the validated private GitHub URL and route the user to the generated repository's
`.firstdraft/submitted-foundation-plan.json` and `.firstdraft/gaps.json`. Continue only in a separate checkout when
the user asks.
- 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.

When changing the Drawing Board template itself, read `CONTRIBUTING.md` and run `script/check`.
16 changes: 11 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ A repository created from this template must provide one ready-to-use workspace
Selenium services, 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.
This is preparatory container plumbing: the currently pinned CLI and Skill still publish a separate private
repository. A later coordinated CLI/Skill/pin packet will activate direct materialization into `application/`.
The accepted cross-repository sequence and its safety boundaries live in
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
cross-repository sequence and its safety boundaries live in
[DIRECT_COMPILATION_PLAN.md](DIRECT_COMPILATION_PLAN.md).

## Repository map
Expand All @@ -47,6 +47,9 @@ bypass those rules are `.firstdraft/submitted-foundation-plan.json` and `.firstd
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
artifact contract; a mismatch requires a fresh compile into an absent directory rather than local mode repair.
A mode mismatch aborts initialization before the nested repository exists. Preserve that directory under the
Drawing Board's ignored, bind-mounted `tmp/` before recompiling; never use `/tmp` or the container home, and never
delete or overwrite it to manufacture an absent destination.

## Work on the template

Expand Down Expand Up @@ -86,4 +89,7 @@ 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 complete template-to-generated-repository journey before landing it.
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
current direct-journey acceptance steps and every explicitly unfinished step; do not call that journey complete
until those steps are observed.
57 changes: 57 additions & 0 deletions DIRECT_COMPILATION_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,20 @@ their owning tools rather than copying them. Drawing Board continues to install
so plugin publication or catalog promotion is not required for this packet. CLI `latest`, plugin publication, and
catalog promotion remain separate release choices.

The released packet-2.5 inputs observed on 2026-08-28 are:

- CLI `0.2.1`, source/tag commit `d38ef3e54a6476b3a91f22a17fe7bd47aa6d6d68`, tree
`e62ee3ff1fb6d188c5d2c5a6e5e0efd50b40245f`, published under npm's `next` tag while `latest` remains `0.1.0`;
- Skills `0.2.1` at `160d33a5a7d9f9b2282729ecfd3b2e24a1123143`, tree
`6f3db12c017e884d8b14c66f7d82e64229ec2073`, installed by Drawing Board from source; and
- staging advertising First Draft API contract `0.3.0`.

Drawing Board now pins that CLI/Skills pair and teaches direct `./application` output as its ordinary path. The
candidate plugin `0.2.1` digest is `36e3e80db76d4af6c2af96d87fe42e00b944aab01e16584e6eb5149dc3f196b1`, but this source-pin packet does not publish
plugin bytes, move a catalog, or move npm's `latest` dist-tag. The `next` tag moved to CLI `0.2.1` in step 3. Packet
3 owns the observed non-prebuilt journey rather than inferring it from these compatible release coordinates; the
result below also preserves what that journey did not yet prove.

## Packet 3: one real non-prebuilt Codespace journey

After packets 1 and 2 are integrated into a coherent candidate tuple, confirm that staging serves the API contract
Expand All @@ -136,6 +150,49 @@ required by that tuple, then exercise a newly created Drawing Board Codespace wi
7. Ask the same agent to explain one Plan decision from the retained design context and make one bounded application
change that follows it, then run a focused generated-app check.

### Observed Packet 3 boundary on 2026-08-28

A fresh private repository and Codespace exercised the exact Drawing Board candidate without a prebuild:

- Drawing Board source `f93d54a2a55ca7d06abe072424092b1dd0544117`, tree
`ade2a7079299d84cfd746c241aff905b3cd0115b`, was copied into one parentless test-repository commit
`fd73196251e341893f8e0496e4d1ba6765c89f49` with the same tree.
- One `basicLinux32gb` East US Codespace reached `Available` 404.5 seconds after its create request. Its runtime
reported CLI `0.2.1`, Skills `160d33a5a7d9f9b2282729ecfd3b2e24a1123143`, Claude Code `2.1.226`, and Codex
`0.147.0`; the Dev Container smoke and direct-output capability checks passed.
- The approved Neighborhood Guide Plan SHA-256 was
`1e88f919436d779176abd115f79f84293d4ea4579d21cc07bdc64db3b1a2a962`. Analysis
`01a04a08-e38a-7708-accb-d2980cfc0c7f` returned a valid zero-record GapSet with SHA-256
`e1d40a25d442b18380882e644ff1e4d5a6191159eb3b0cdaff258f20f7ad3fc7` before the owner approved direct mode.
- Exactly one direct Compile started. Compilation `01a04a0d-3484-7e29-b743-0c77b96db063` succeeded with artifact
SHA-256 `0f26014b38d64816ce4b7934e969ce9a3db715a96f3789df609a45b81bf35188`, 479,770 artifact bytes,
168 output files, and manifest SHA-256
`08269fa09226d41d89894dbef1f0a26cbd51c7fc47b7ca81d5085f44c8480d1c`. The emitted submitted Plan and
GapSet bytes matched the approved inputs, and the new directory had no Git metadata.
- The Project's Publication route returned exact `404 publication_not_found` before and after Compile. The owner's
551-repository GitHub inventory was byte-identical before and after, so the direct path created no Publication or
generated repository.
- `script/initialize-application application` produced parentless commit
`3f763a84ceab6d7f3564f382bc77cce267a528f1`, tree `11a52026505434bd3242c9cab94d49ed68638681`, on
nested `main`. `script/application-smoke` passed setup, PostgreSQL 18.6, readiness, 56 Rails tests with 209
assertions, seven system tests with 34 assertions, and the complete clean generated CI in 69.22 seconds under
Ruby 4.0.5 and Node 24.18.0.
- A real browser rendered `It works. · Neighborhood Guide` and the empty `Places · Neighborhood Guide` index
through an authenticated localhost forward to the same Codespace process. The ordinary private Codespaces
`*.app.github.dev` URL instead reached Rails' blocked-host page. The generated Rails development configuration did
not admit that exact Codespaces host; broadening the Drawing Board container environment would not preserve Rails'
exact host boundary. This is a generated Foundation target defect, not a successful ordinary forwarded-port
observation, and requires a target-owned correction before the colleague Codespaces browser journey is complete.
- The single task token was revoked after proof and the exact credential then received `401 authentication_required`.
The revoked value was removed from the Codespace, and the Codespace stop was requested.

This run proved agent and Skill installation/discovery, but neither installed agent was signed in inside the
Codespace. The active external agent drove the exact Skill sequence over SSH, loaded a previously reviewed Plan,
and obtained fresh owner approval of its exact Plan, GapSet, and direct effect. It did not perform the new
in-Codespace conversational authoring pass, boot the browser process through step 6's `bin/dev` wrapper, or perform
step 7's retained-context explanation and bounded source change. Those remain explicit acceptance work rather than
being inferred from installation, `bin/rails server`, or Compilation success.

Retain exact Service, CLI, Drawing Board, Plan, GapSet, artifact, generated tree, nested initial commit, container,
database, smoke output, and browser coordinates. If the Compilation start has an unknown outcome without a retained
identity, abort the qualification, preserve its Project/request/response/timing evidence, and ask a Service operator
Expand Down
Loading