Skip to content

Reassess gapp init role and introduce gapp manifest command group #28

@krisrowe

Description

@krisrowe

Problem

gapp init is drifting toward a dumping ground for every possible
gapp.yaml configuration option. It already accepts entrypoint,
mcp_path, auth, runtime, secrets, and domain as keyword
arguments, and there is steady pressure to add more. This creates
several problems:

  • Conflated responsibilities. gapp init today does three
    different things: (a) bootstrap gapp.yaml, (b) add a
    gapp-solution topic to the GitHub repo, and (c) register the
    solution path in ~/.config/gapp/solutions.yaml. Stuffing
    per-field configuration into the same command blurs whether it
    is a one-time project-setup step or an ongoing configuration
    editor.
  • MCP-specific defaults in a cloud-agnostic tool. init
    currently seeds a manifest with service.entrypoint: PACKAGE.mcp.server:mcp_app — an assumption that the app is an
    MCP server using a specific module layout. gapp does not (and
    should not) know that the target is an MCP server.
  • No structured editing surface. Users who want to change one
    field — add an env var, declare a secret, set a domain — either
    rerun init with a growing pile of flags or hand-edit the yaml.
    Hand-editing is exactly what schema validation is supposed to
    make unnecessary; rerunning init pretends the command is
    idempotent configuration rather than one-time setup.
  • Name is a special case that leaks out. See the companion
    issue on solution-name resolution strategy — the name is
    effectively bootstrap-only (locked after init because labels,
    buckets, and discovery state are name-scoped), and the current
    yaml freely allows editing it, risking silent breakage.

Desired direction (no prescription — exploration)

Keep gapp init narrow and introduce a dedicated gapp manifest
command group for structured editing. The exact split is open; this
issue is the place to decide.

Possible taxonomy

  • gapp init — bootstrap only. Creates a minimal gapp.yaml,
    applies the GitHub topic, registers in solutions.yaml. Does
    not take per-field flags. Requires the bare minimum needed
    for any deployable app (not assuming MCP, not assuming a
    particular framework). On success, prints a suggestion list
    pointing at manifest subcommands for further configuration.
  • gapp manifest schema — already implemented.
  • gapp manifest verify — already implemented.
  • gapp manifest init — scaffold yaml only (no GitHub topic, no
    registration). Useful for repos that are already initialized
    but want a fresh or extended yaml.
  • gapp manifest env add|list|remove — structured env var
    editing. Fields map to EnvEntry in the schema. Supports both
    plain values and secret references.
  • gapp manifest secrets add|list|remove — prerequisites secrets
    editing (note: pluralsecrets, not secret, for
    consistency with list semantics; existing singular
    gapp secret * / gapp_secret_* surface would migrate).
  • gapp manifest set <key>=<value> — or per-field subcommands
    (gapp manifest set domain ..., gapp manifest set public ...)
    — for the simple scalar fields.
  • Interactive vs non-interactive: open question. Should
    gapp manifest env add with no flags drop into an interactive
    prompt? Or fail and require flags? Or interactive by default
    with --non-interactive to require flags?

Open design questions

Decide these explicitly before implementing:

  • Does gapp init stay as the one-shot entry point or get
    decomposed?
    If decomposed, what replaces it? If kept, what
    exactly goes in it vs in the manifest group?
  • Should gapp init be an alias for gapp manifest init plus
    the two project-registration side-effects?
    Only if those
    side-effects really are optional in some flows.
  • What fields are MCP-specific vs generic? Anything MCP-aware
    should go to a separate plugin/profile, not be gapp's default.
  • Naming convention across commands and tools. Plural for
    collections (secrets, envs?), singular for scalars
    (domain, public). Decide and apply uniformly across CLI
    and MCP tool names.
  • Interactive vs non-interactive defaults.
  • Migration of existing gapp secret * / gapp_secret_*
    commands
    for consistency with the new plural form.

Current state (for context)

  • Schema single-source-of-truth is established in
    gapp/admin/sdk/schema.py (see Formal schema validation for gapp.yaml (fail fast with clear errors) #26). Every manifest operation
    can derive valid field names, types, and descriptions from the
    Pydantic model. The CLI can introspect the schema at runtime
    (via Manifest.model_fields and its submodels) — structured
    editing commands should use this so they never drift from the
    schema.
  • gapp manifest schema and gapp manifest verify subcommands
    exist and are plumbed through CLI + MCP + SDK with uniform JSON
    error delivery.
  • gapp init still has the MCP-specific default
    service.entrypoint: PACKAGE.mcp.server:mcp_app baked in —
    explicit candidate for removal.

Non-goals for this issue

  • Implementation. This issue is the design conversation. A
    subsequent PR/issue does the work once the taxonomy is agreed.
  • Renaming support. See the companion issue on name resolution.

Work breakdown

  • Decide the command taxonomy above.
  • Decide the interactive/non-interactive posture.
  • Decide what (if any) MCP-specific defaults stay in gapp init.
  • Decide plural vs singular naming convention and apply it
    uniformly across all CLI commands and MCP tools.
  • Implement decided commands. Ensure each field-editing
    subcommand derives its accepted fields and types from the
    Pydantic schema models in gapp/admin/sdk/schema.py — no
    re-declaration of field lists anywhere (the single-source-of-
    truth rule in CONTRIBUTING.md).
  • Add tests covering: scaffold correctness, idempotency, and
    that every schema field has a structured CLI path (so adding
    a field automatically gets a command, or clearly doesn't).
  • Update CONTRIBUTING.md with the chosen taxonomy and the
    rationale behind it.
  • Update README.md to show the new editing surface and
    remove any suggestion to hand-edit gapp.yaml.
  • Update SKILL docs (skills/deploy/SKILL.md,
    skills/secrets/SKILL.md) to prefer manifest subcommands
    over yaml hand-edits.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions