Skip to content

docs: per-project-config.md is out of sync with the shipped implementation #199

@neversettle17-101

Description

@neversettle17-101

Summary

docs/design/per-project-config.md has drifted from the implementation. The doc's status header acknowledges the current shape ("one projects.config JSON column", PUT /projects/{id}/config, ao project set-config), but the rest of the doc still describes the originally proposed per-field storage and per-group API surfaces. Anyone reading the doc fresh will get a contradictory picture.

Concrete deltas (non-exhaustive — please fully audit when picking this up)

  1. Storage strategy section vs. reality — Doc proposes:

    • Scalar fields (default_branch, session_prefix, …) → typed columns on projects
    • Small structured blobs (agent_config, tracker, scm, symlinks, post_create) → nullable JSON columns
    • env → child table project_env (key/value rows)

    Reality: the whole ProjectConfig is persisted as one JSON blob (projects.config) per the status header and backend/internal/domain/projectconfig.go comment: "persisted as one JSON blob per project."

  2. API surface section vs. reality — Doc proposes focused routes (PUT /projects/{id}/agent-config, PUT /projects/{id}/env, etc.) "rather than one mega-PUT." Reality (per status header) is exactly one PUT /projects/{id}/config. The status header and the surface section contradict each other in the same document.

  3. CLI surface — Doc lists examples like ao project set-config --model --permission, ao project env set KEY=VAL. Verify these match the actual ao project subcommands and flags shipped today.

  4. Field catalog table — The "Storage today" / "Target" columns describe per-column homes and the project_env child table that aren't the live model. Either retarget the table to "field → key inside the projects.config JSON blob," or flag clearly that the per-column plan was superseded.

  5. Sequencing section — Slices 2 ("identity scalars") and 3 ("workspace provisioning: env, symlinks, postCreate") were originally framed as separate column/table migrations. They effectively landed together inside the single config blob; the sequence story needs to be either rewritten to match what shipped or annotated to show what slices remain.

  6. Typed model code block — Matches backend/internal/domain/projectconfig.go today (DefaultBranch, SessionPrefix, AgentConfig, Worker, Orchestrator, Env, Symlinks, PostCreate). This part is fine — preserve it.

Suggested approach

  • Treat the status header as the new ground truth (single projects.config JSON blob, single PUT /projects/{id}/config, ao project set-config).
  • Rewrite "Storage strategy", "Surface (per field)", and "Sequencing" so the recommended pattern matches what shipped, and any remaining per-field column work is clearly marked as future-only.
  • Keep the "Typed model" section, the "Field catalog" left columns (YAML field / type), and the principle ("typed over map") — these are still accurate.
  • Audit the doc end-to-end against backend/internal/domain/projectconfig.go, the projects table schema, and the actual ao project CLI/HTTP surface before publishing.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationstoragePersistence lane

    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