Skip to content

Scaffold full-stack application Skill - #1

Draft
raghubetina wants to merge 3 commits into
mainfrom
codex/author-plan-scaffold
Draft

Scaffold full-stack application Skill#1
raghubetina wants to merge 3 commits into
mainfrom
codex/author-plan-scaffold

Conversation

@raghubetina

@raghubetina raghubetina commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Why

First Draft needs its first portable Skill to be discoverable when a user wants custom software, not only when the
user already knows the term Foundation Plan. This scaffold makes the pre-Compilation authoring workflow reviewable
while the public discovery surface describes the intended end-to-end launch outcome.

What

  • rename the independently installable Skill to create-full-stack-app and add portable UI/invocation metadata;
  • describe the launch journey from software idea through a deployed Rails/PostgreSQL Foundation with web, iOS, and
    Android clients, followed by ordinary source-development workflows;
  • keep the installed Skill declarative while the audited CLI owns UUID, file, concurrency, and network behavior;
  • bundle the exact provisional sketch/0.19 schema from First Draft revision
    12fa2a6bcac122196d55f5528fbc3f1363c684e3;
  • make consent, privacy, diagnostic, stale-writer, ambiguous-outcome, and state-recovery stops explicit;
  • include harness-neutral trigger and behavior cases with typed input/output artifacts and reproducible staging;
    and
  • add dependency-locked repository checks on Node 22.0 and 24.18.

Current scaffold boundary

  • The discovery description is the intended launch product description.
  • The reviewed CLI baseline has plan init and plan push; the Skill capability-checks plan subject-id
    rather than assuming an unreleased command.
  • The reviewed API accepts only the empty starter subset. Nonempty examples are structurally valid but not yet
    importable through that slice or Compiler-proven.
  • Pull/reconciliation, Publish, Compilation, and generated Foundations are outside this scaffold.
  • The Skill contains no executable code and never installs or upgrades the CLI automatically.

Verification

  • npm ci --ignore-scripts
  • sh script/check on Node 22.0.0 and Node 24.18.0: 8 tests pass
  • npm audit --audit-level=low: 0 vulnerabilities
  • Skill Creator validator: valid
  • gh skill publish --dry-run: structurally valid; the optional frontmatter-license and release-tag ruleset
    recommendations remain intentionally deferred, while the installed Skill carries the exact MIT notice
  • bundled schema is byte-identical to the pinned upstream revision and has SHA-256
    5994c41f65eab52f92020fa24437e76b6957b7016ccf231dce06e8097f0b34b5
  • eval fixtures are schema-validated or byte-bound to their diagnostics, with staging destinations constrained to
    project-relative paths

Related implementation slices: firstdraft/firstdraft#162 and firstdraft/cli#4.

Establish a portable pre-Compilation workflow before the CLI and API support nonempty import. Keep deterministic operations in the CLI, bundle the exact provisional schema, and make concurrency, recovery, privacy, and capability stops explicit.
@raghubetina

Copy link
Copy Markdown
Contributor Author

Review: technical

Reviewed the first PR in this repository against main. Nothing to fix; one dated note at the end.

Most of this is prose, so the parts worth checking mechanically are the pinned artifacts and whether the workflow describes software that actually exists.

Verified

  • sh script/check passes on Node 24.18.0: 5 tests, including that the three complete examples validate against the bundled schema and that the installed Skill retains the license.
  • The bundled schema is exactly what it says it is. foundation-plan-0.19.schema.json hashes to 12f8f2c5...b6734, and references/foundation-plan-019.md records that it "was copied from First Draft revision 4d956a5". I diffed the file against docs/architecture/design/foundation-plan.schema.json at that exact commit and it is byte-identical. Recording the source revision alongside the digest is what makes this a copy someone can re-derive rather than a fork.
  • The digest is pinned in a test, not only in prose, so the bundled copy cannot drift inside this repository without repository.test.mjs failing.
  • The CLI baseline claim is accurate. The doc names af33be3 and says it "exposes only plan init and plan push". That is the head of Push local Foundation Plans conditionally cli#3, and those are exactly the two commands it implements.
  • The missing command is handled by detection rather than assumption. SKILL.md tells the agent to check whether firstdraft plan --help lists subject-id before adding a new subject, and if it does not, explicitly not to invent a UUIDv7 or copy one from an example. Shipping a Skill ahead of the CLI it depends on is reasonable precisely because the gap is probed at runtime instead of assumed away.

A dated note: the upstream schema has already moved

The recorded source revision 4d956a5 is the head of firstdraft/firstdraft#162, which sits on one side of a fork in that stack. On the other side, #165 changes the schema to digest 5994c41f65eab52f92020fa24437e76b6957b7016ccf231dce06e8097f0b34b5.

That change is prose-only. I verified it in that review by parsing both revisions and stripping every title and description, and the structures are identical, so no document that validates against the bundled copy would fail against the newer one. The practical impact today is zero.

The reason to say it anyway is that this Skill's own instruction is "update this Skill deliberately when either contract changes", and the contract has changed while this PR was open. Nothing here detects that, by design, since the pinned test compares the copy against itself rather than against upstream. So the update is a person's job, and this is the note that keeps it from being forgotten. The new digest above is the value to move to once #165 lands.

Design notes

  • Keeping the installed Skill free of executable code, with UUID minting, file writes, concurrency, and network behavior all in the audited CLI, is the right split. A Skill is instructions an agent reads; the moment it also carries code, it needs its own supply-chain story.
  • The stop points are the useful part of the workflow prose. Refusing to proceed after local_state_not_saved, keeping the printed recovery material local rather than pasting it anywhere, and declining to infer whether a push created or replaced a Project all match the ambiguity the CLI actually reports. I checked the CLI's behavior on Push local Foundation Plans conditionally cli#3, including the deliberately honest "the Plan may have been accepted; local state was not changed" path, and the Skill's instructions line up with it rather than assuming a cleaner outcome than exists.
  • The "Current boundary" section in the PR body is unusually direct about what is not released: no CLI satisfies the full workflow, the API takes only the empty starter, and there is no pull, Publish, or Compilation. That framing makes the scaffold reviewable without implying a product.

@raghubetina

Copy link
Copy Markdown
Contributor Author

Lesson: what this PR actually did

A new repository holding instructions for agents, not code. The ideas worth keeping are how to copy a file from another project honestly, and how to write instructions for software that does not exist yet.

The one-sentence version

This creates a public repository of Skills and its first Skill, firstdraft-author-plan, which tells an agent how to create, edit, validate, and push a Foundation Plan using the firstdraft CLI.

What a Skill is here

A Skill is a folder with a SKILL.md and some reference documents. An agent reads it when the task matches its description. It is documentation with a calling convention.

The notable decision is that this one contains no executable code at all. Every side effect stays in the CLI: minting UUIDs, writing files, handling concurrency, talking to the network. The Skill only decides what should happen and when to ask the user.

That split is worth copying if you ever ship agent instructions. Prose that an agent reads is reviewed by reading it. Code that an agent runs needs a supply chain: dependencies, audits, release process, a story for what happens when it is installed on a machine you have never seen. Mixing the two means the whole bundle inherits the harder requirements.

Copying a file from another repo without lying about it

The Skill bundles a copy of the Foundation Plan JSON Schema, because an agent validating a document offline needs the schema locally.

Copying a file across repository boundaries is where staleness is born. The usual version of this is a file that says nothing about where it came from, and two years later nobody can tell which upstream revision it matches or whether the differences are intentional.

What this does instead, in three parts:

  1. It records the source revision. The reference doc says the schema "was copied from First Draft revision 4d956a5". I checked out that exact commit and diffed: byte-identical.
  2. It pins the digest in a test, not only in prose. repository.test.mjs holds the SHA-256, so editing the bundled copy without updating the pin fails the build.
  3. It states the maintenance rule: "Update this Skill deliberately when either contract changes."

The residual gap is honest and inherent: nothing here can tell when upstream moves, because this repository has no view of the other one. That is a person's job, and saying so is better than pretending automation covers it. As it happens the schema did move while this PR was open, in a prose-only way, so I noted the new digest on the review so the deliberate update does not get lost.

If you take one habit from this: when you vendor a file, record the upstream revision next to it and pin its hash. Those two lines turn "is this current?" from an investigation into a comparison.

Writing instructions for software that does not exist yet

The interesting problem in this Skill is that it describes a workflow the tooling cannot fully perform. The CLI has plan init and plan push. It does not have plan subject-id, which the workflow needs in order to add a new subject with a fresh identity.

There are three ways to handle that, and two are bad. You can pretend the command exists, and the agent tries it and fails confusingly. You can leave that step out, and the Skill silently cannot do a thing it appears to cover. What this does instead is tell the agent to look:

Before adding a genuinely new subject, check whether firstdraft plan --help lists subject-id. If it does, use it. If it does not, do not invent a UUIDv7 or copy an example UUID.

That is capability detection, the same pattern as feature-testing a browser API rather than sniffing the user agent. It also closes the failure mode that matters most: an agent that cannot get a real ID might helpfully make one up, or paste one from the examples, and either would corrupt the identity model the whole system depends on. The instruction forbids exactly those two improvisations by name.

The Skill's own description carries the same caveat, so an agent choosing whether to load it knows the limit before it starts.

Telling the user when you do not know

The last thing worth noting is how the stop points line up with reality. The CLI has one genuinely ambiguous outcome: a request went out and no valid response came back, so the Plan may or may not have been accepted. I verified that behavior when reviewing the CLI.

The Skill does not paper over it. On that failure it stops, keeps the printed recovery material local and private, and refuses to infer whether the push created a Project or updated one. Instructions that inherit a tool's uncertainty instead of resolving it optimistically are rarer than they should be, and they are the difference between an agent that recovers and one that confidently makes things worse.

@raghubetina

Copy link
Copy Markdown
Contributor Author

The supporting CLI slice is now firstdraft/cli#4. It implements the firstdraft plan subject-id capability that this Skill checks before structured authoring. The Skill should keep the capability gate until a CLI release contains the command, and the separate server limitation remains: the current reviewed API accepts only the empty starter subset.

@raghubetina

Copy link
Copy Markdown
Contributor Author

Evaluated the dated #165 schema note. I am keeping this PR pinned to 4d956a5 for now because that is the exact implemented conditional-PUT/API slice the Skill targets; #165 is a sibling stack, not yet integrated into that line, and its one schema edit is description-only with an identical validation structure. Once the API integration line includes #165, the source revision, bundled copy, digest test, and reference note should move together in a separate deliberate update.

@raghubetina

Copy link
Copy Markdown
Contributor Author

Agreed, and the fork is the part I under-weighted. I treated "upstream moved" as one line when #165 sits on a sibling branch that this Skill's target slice does not include, so pinning to 4d956a5 is pinning to the API behavior the Skill actually describes rather than to whatever is newest.

Moving the source revision, bundled copy, digest test, and reference note together in one deliberate update once the API integration line includes #165 is the right shape, and it keeps the four things from drifting apart individually. Nothing further from me on this.

Make the public name and discovery copy describe the complete First Draft journey rather than the internal Foundation Plan stage.

Keep the current pre-Compilation scaffold explicit, and refresh the vendored 0.19 schema to the merged Project-graph baseline.
@raghubetina raghubetina changed the title Scaffold Foundation Plan authoring Skill Scaffold full-stack application Skill Jul 29, 2026
@raghubetina

Copy link
Copy Markdown
Contributor Author

The draft Skill's public name and discovery surface have changed from firstdraft-author-plan to
create-full-stack-app. Historical comments above use the former name.

The installed workflow in this PR remains the pre-Compilation scaffold, while its portable metadata describes the
full First Draft launch journey. The bundled v0.19 schema pin also moved to the merged First Draft baseline
12fa2a6bcac122196d55f5528fbc3f1363c684e3, with SHA-256
5994c41f65eab52f92020fa24437e76b6957b7016ccf231dce06e8097f0b34b5. Reproducible eval staging and fixtures
were added during review.

@raghubetina

Copy link
Copy Markdown
Contributor Author

Re-reviewed 1b4f848 after the rename. My earlier head 046d5a4 is still an ancestor, so this is an extension rather than a rewrite: a directory rename, a re-pinned schema, new fixtures, and a much larger test file.

Verified

  • The schema re-pin resolves the thread we had open. The bundle is byte-identical to docs/architecture/design/foundation-plan.schema.json at 12fa2a6, and the SHA-256 matches the body exactly:

    bundled  5994c41f65eab52f92020fa24437e76b6957b7016ccf231dce06e8097f0b34b5
    upstream 5994c41f65eab52f92020fa24437e76b6957b7016ccf231dce06e8097f0b34b5
    

    12fa2a6 is the merge commit of firstdraft/firstdraft#182, so the pin moved from a sibling branch to the integrated mainline. That is the right resolution of the earlier disagreement, and worth noting how small the stakes turned out to be: the entire delta between the old pin and this one is one description string on associations, no structural change.

  • sh script/check gives 7 passing tests on Node 24.18.0, matching the body, and the workflow matrix is [22.0.0, 24.18.0] as claimed. npm audit --audit-level=low reports 0 vulnerabilities. npm ci --ignore-scripts is clean.

  • The test file grew in the right direction, +195 lines, and the new cases are about binding claims to artifacts rather than restating prose: examples validate against the bundled schema, the malformed fixture is bound to its coordinate diagnostic, the resume eval binds an identity-preserving rename, and the installed Skill is checked to carry the repository license.

The discovery description asserts things the project's own ledger says are not shown

This is the one place I would push back, and I know from the body that it is deliberate, so treat it as a disagreement to resolve rather than an oversight to fix.

The frontmatter, which is the text a user reads when deciding whether to install:

"Turns a software idea into a robust, deployed full-stack application. First Draft ... deterministically generates a high-quality Foundation: an ordinary Ruby on Rails and PostgreSQL codebase with authentication, authorization, tests, CI, secure defaults, diagnostics, and accessible web, iOS, and Android clients."

Present tense, and it names Android. docs/evidence/status.md in the repository this Skill describes:

| Android | Documented product idea only | Project generation, build, emulator,
                                           device, FCM, distribution, release,
                                           and continuation |

and, four lines from the top of the same file:

"iOS does not prove Android. A Simulator does not prove a device."

AGENTS.md guardrail 3 uses this exact pair as its worked example of a boundary not to blur. So the discovery surface makes a stronger claim about Android than any other document in the project, and it makes it in the one place read by people who will read nothing else.

I take the argument in the body, that the description is the intended launch product description and the scaffold is what is reviewable now. My difficulty is that the two audiences are different. The PR body is read by you and me. The frontmatter is read by a stranger choosing whether to install this, and the correction sits eleven lines below it in a file they may never open:

"This Skill is experimental. The reviewed CLI can initialize and push an empty starter, but it cannot yet mint IDs for new authored subjects. The reviewed server cannot yet import nonempty content."

That sentence is honest and well placed for someone already reading. It cannot carry the weight of a description that promises a deployed application with three clients.

A version that keeps discoverability without asserting the unbuilt might open with what the Skill does today and name the destination as intent:

"Designs and validates a First Draft Foundation Plan: the data model and initial screens for an application First Draft will compile into a Rails and PostgreSQL codebase with web and native clients. Experimental: the current toolchain authors and validates Plans; Compilation and generated applications are not yet available."

Same search terms, same destination, no present-tense claim about output nothing has produced. If you would rather keep the aspirational wording, I would at least drop Android to the same hedge as the rest, since it is the only item in that list with no exercised evidence at all.

The narrower alternative, if the launch description has to stay verbatim for marketing reasons, is to make the experimental sentence the first line of the body rather than the fifth paragraph, so it survives truncation in any surface that shows a preview.

Smaller notes

  • Gating on plan init and plan push while capability-checking plan subject-id rather than assuming it is the right shape, and it now matches Generate Foundation Plan subject IDs cli#4 having landed that command. Worth re-checking the gate once Teach enum Field authoring #4 merges, since the Skill will then be able to require rather than probe.
  • "Do not install, download, or upgrade the CLI automatically" plus treating .firstdraft/state.json as private and never copying it into chat are both good instructions to give an agent, and both are the kind of thing that only works if stated imperatively, which they are.
  • The Skill still contains no executable code. For something distributed and installed into other people's agents, that remains the most valuable property it has.

Nothing blocking on the mechanics. The description is a judgement call and it is yours.

Stage an existing Plan and opaque CLI state for diagnostic and recovery cases so their preservation behavior is observable. Bind the unsupported-content diagnostic to the exact staged Plan bytes.
@raghubetina

Copy link
Copy Markdown
Contributor Author

Re-checked b1332a4. Eval fixtures and tests only; the Skill text is untouched, so my note on the frontmatter description still stands as an open question rather than something this amendment answers.

sh script/check now gives 8 passing tests, up from 7, and npm audit --audit-level=low still reports 0 vulnerabilities.

The change worth calling out is the one-line fixture fix. unsupported-nonempty-diagnostics.json carried

"source_sha256": "0000000000000000000000000000000000000000000000000000000000000000"

which is a placeholder wearing the costume of a real digest. It now carries 2686cd14..., and I confirmed that is exactly the SHA-256 of resume.foundation-plan.json, the Plan staged alongside it in the prototype-nonempty-diagnostic case. So the fixture is now genuinely bound to the document it claims to describe.

That distinction matters more in an eval fixture than almost anywhere else. A fixture is evidence about how the system behaves, and an all-zeros digest is evidence about nothing: it cannot fail, so it cannot catch the case where the staged Plan and the recorded response drift apart. Replacing it with the real value turns a decorative field into a check.

The new diagnostic and recovery evals stage and preserve existing Plan state test is the right companion to that, since it exercises the staging path the digest now pins.

@raghubetina

Copy link
Copy Markdown
Contributor Author

The pending server stack now supersedes this scaffold blanket nonempty-import boundary. firstdraft/firstdraft#190 imports and atomically replaces Entities, short_text Fields, and Field or system-Field Primary Descriptors; firstdraft/firstdraft#192 expands the supported Field set to boolean, date, datetime, decimal, integer, language_code, long_text, short_text, time_zone, and url. A follow-up Skill slice should replace the empty-only stop and unsupported-nonempty eval with the exact supported and unsupported boundary. Defaults, Validations, References, Associations, enum/settings topology, and the remaining graph are still unsupported. The bundled 0.19 schema pin does not change, and the existing CLI transport already supports this workflow.

@raghubetina

raghubetina commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

The bounded nonempty follow-up is now #2. It supersedes the empty-only importer language and obsolete unsupported-nonempty eval in this scaffold PR with the exact firstdraft/firstdraft#190 and #192 boundary. The sketch/0.19 schema pin, discovery metadata, and CLI PUT transport remain unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant