create_project_from_template: add generation-time smoke gate + dry-run (infra#87, ADR-0005 F-A2) #62

Open
opened 2026-08-11 21:15:33 +00:00 by mathias · 2 comments
Owner

Filed from infra#87 and infra#122 (both closing). Scaffolding moved here from dma-cli per the 2026-08-05 decision — dma-cli has no scaffold command under any name, and its scope is now auth / code / models. This verb is the choke point where a generated repo can be prevented from ever shipping CI-red.

Part 1 — smoke gate (infra#87)

Goal: a repo generated from a template can never ship CI-red. Five checks at generation time:

  1. task check passes in the generated tree
  2. workflow YAML on: is not accidentally a string (the classic on: push → true YAML 1.1 trap)
  3. go.mod Go version pin matches what the template's CI image actually provides
  4. Dockerfile FROM version matches the same
  5. CDN-vs-vendored asset choice is consistent with the template's declared intent

Generation should fail loudly rather than emit a repo that goes red on its first push.

Part 2 — dry-run gate (ADR-0005 F-A2)

F-A2 was an open fork of infra's ADR-0005: scaffold performs remote stateful actions (creates a Gitea repo, wires GitOps/Flux/ESO, sets topics and secrets) with no dry-run and no gate. That fork is re-homed here, because this verb is where those actions happen.

Wanted: a dry-run mode that reports exactly what would be created or mutated remotely, without doing it. dma-cli's Layer B already models the pattern — WritePolicy with ConfirmRequireYes / ConfirmPrompt / ConfirmAutoApprove. Worth mirroring the shape rather than inventing a second one.

Why it matters

Both halves protect the same thing: scaffolding is the highest-leverage surface in the estate, since every future repo inherits whatever it emits. A wrong template propagates silently; a remote stateful action with no dry-run is unreviewable before the fact.

Acceptance

  • The 5 checks run at generation time and fail generation on violation
  • Dry-run reports remote actions without performing them
  • A deliberately broken template is proven to fail generation (mechanically, not just wired)

Refs

  • infra#87, infra#122 (both closed against this)
  • infra ADR-0005 F-A2 (docs/decisions/ADR-0005-agentic-dev-platform-three-layer-model.md)
  • infra docs/superpowers/specs/2026-08-11-backlog-verification.md
Filed from infra#87 and infra#122 (both closing). Scaffolding moved here from dma-cli per the 2026-08-05 decision — dma-cli has no scaffold command under any name, and its scope is now `auth` / `code` / `models`. This verb is the choke point where a generated repo can be prevented from ever shipping CI-red. ## Part 1 — smoke gate (infra#87) Goal: **a repo generated from a template can never ship CI-red.** Five checks at generation time: 1. `task check` passes in the generated tree 2. workflow YAML `on:` is not accidentally a string (the classic `on: push` → `true` YAML 1.1 trap) 3. `go.mod` Go version pin matches what the template's CI image actually provides 4. `Dockerfile` `FROM` version matches the same 5. CDN-vs-vendored asset choice is consistent with the template's declared intent Generation should fail loudly rather than emit a repo that goes red on its first push. ## Part 2 — dry-run gate (ADR-0005 F-A2) F-A2 was an open fork of infra's ADR-0005: **scaffold performs remote stateful actions** (creates a Gitea repo, wires GitOps/Flux/ESO, sets topics and secrets) with no dry-run and no gate. That fork is re-homed here, because this verb is where those actions happen. Wanted: a dry-run mode that reports exactly what would be created or mutated remotely, without doing it. dma-cli's Layer B already models the pattern — `WritePolicy` with `ConfirmRequireYes` / `ConfirmPrompt` / `ConfirmAutoApprove`. Worth mirroring the shape rather than inventing a second one. ## Why it matters Both halves protect the same thing: scaffolding is the highest-leverage surface in the estate, since every future repo inherits whatever it emits. A wrong template propagates silently; a remote stateful action with no dry-run is unreviewable before the fact. ## Acceptance - [ ] The 5 checks run at generation time and fail generation on violation - [ ] Dry-run reports remote actions without performing them - [ ] A deliberately broken template is proven to fail generation (mechanically, not just wired) ## Refs - infra#87, infra#122 (both closed against this) - infra ADR-0005 F-A2 (`docs/decisions/ADR-0005-agentic-dev-platform-three-layer-model.md`) - infra `docs/superpowers/specs/2026-08-11-backlog-verification.md`
mathias added the blocked/decision label 2026-08-27 05:11:59 +00:00
Author
Owner

Context from 2026-08-31: project scaffolding is consolidating on dma-cli (record in mathias/dma-cli#11).

This does not make the issue moot. create_project_from_template is the only creation path an agent can reach over MCP, which is a capability rather than duplication — the likely end state is that it stays as the remote entry point and delegates to the same logic dma-cli uses, instead of templating independently.

The smoke gate and dry-run asked for here are worth having under either shape, and arguably more so once this endpoint is a thin caller: a generation-time gate is what stops the two paths silently diverging. Worth confirming the delegation shape before implementing, so the gate is written against the logic that survives.

Context from 2026-08-31: project scaffolding is consolidating on **`dma-cli`** (record in mathias/dma-cli#11). This does not make the issue moot. `create_project_from_template` is the only creation path an *agent* can reach over MCP, which is a capability rather than duplication — the likely end state is that it stays as the remote entry point and delegates to the same logic `dma-cli` uses, instead of templating independently. The smoke gate and dry-run asked for here are worth having under either shape, and arguably more so once this endpoint is a thin caller: a generation-time gate is what stops the two paths silently diverging. Worth confirming the delegation shape before implementing, so the gate is written against the logic that survives.
Author
Owner

Correcting my previous comment. I said scaffolding was "consolidating on dma-cli" and that this endpoint would likely become a thin caller delegating to dma-cli's logic. That was wrong, and backwards.

ADR-0005 (Accepted 2026-08-11) puts Layer A — scaffold — here, permanently and deliberately:

"Scaffold never landed in dma-cli; the 2026-08-05 decision moved scaffolding to gitea-mcp's create_project_from_template. The dry-run gate is therefore a requirement on that verb, tracked in the gitea-mcp repo alongside infra#87's smoke-gate checks, not a fork of this ADR."

So this issue is not "worth having under either shape" — it is the correctly-homed owner of fork F-A2, and there is no delegation shape to confirm before implementing. My previous comment's closing advice ("worth confirming the delegation shape first") should be ignored; it would have blocked the issue on a question that does not exist. The issue body had this right from the start.

One genuinely useful pointer, and it is the reverse direction of the borrowing I proposed. ADR-0005 notes that Layer B already implements the gate mechanism:

"Layer B already implements the gate mechanism: WritePolicy supports ConfirmRequireYes / ConfirmPrompt / ConfirmAutoApprove."

Worth reusing that vocabulary for the dry-run rather than inventing a second confirmation model — not by depending on dma-cli, but so an operator meets one set of names for "ask me first" across both layers.

The dry-run's confirm semantics remain the open question on this issue. The smoke gate (Part 1) does not depend on it and could ship independently.

**Correcting my previous comment.** I said scaffolding was "consolidating on dma-cli" and that this endpoint would likely become a thin caller delegating to dma-cli's logic. That was wrong, and backwards. ADR-0005 (Accepted 2026-08-11) puts Layer A — scaffold — **here**, permanently and deliberately: > "Scaffold never landed in dma-cli; the 2026-08-05 decision moved scaffolding to gitea-mcp's `create_project_from_template`. The dry-run gate is therefore a requirement on that verb, tracked in the gitea-mcp repo alongside infra#87's smoke-gate checks, not a fork of this ADR." So this issue is not "worth having under either shape" — it is the correctly-homed owner of fork F-A2, and there is no delegation shape to confirm before implementing. My previous comment's closing advice ("worth confirming the delegation shape first") should be ignored; it would have blocked the issue on a question that does not exist. The issue body had this right from the start. One genuinely useful pointer, and it is the reverse direction of the borrowing I proposed. ADR-0005 notes that Layer B **already implements the gate mechanism**: > "Layer B already implements the gate mechanism: `WritePolicy` supports `ConfirmRequireYes` / `ConfirmPrompt` / `ConfirmAutoApprove`." Worth reusing that vocabulary for the dry-run rather than inventing a second confirmation model — not by depending on dma-cli, but so an operator meets one set of names for "ask me first" across both layers. The dry-run's confirm semantics remain the open question on this issue. The smoke gate (Part 1) does not depend on it and could ship independently.
mathias added the risk/highsize/mtype/feat labels 2026-09-16 22:37:14 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/gitea-mcp#62