04

Create an Organization, Project, and Application Specification

Turn a customer idea into a tenant-scoped, versioned contract without creating a runtime prematurely.

Run it in the public monorepo

This course is built around the public Zheta Kubernetes Lab monorepo. The excerpt below is runnable source, not pseudocode.

Source: services/control_plane/domain.py

def create(self, project_id: str, organization_id: str, name: str, actor: str, archetype: str) -> Project:
        project = Project(project_id, organization_id, name, actor, blueprint={"name": name, "archetype": archetype})
        project.collaborators.add(actor)
        with self.repository.transaction():
            self.repository.create(project)
            self._audit(project, actor, "project.created")
        return project

Code to reality

Declared intent
Create one tenant-owned project and its audit evidence as a single product operation.
Interpreter
Python executes the Forge domain model after the controller supplies authenticated command values.
Software effect
The repository durably owns the project while the event port publishes project.created evidence.
Hardware effect
The service process uses CPU and writes database pages to its persistent volume or managed database.
Observable evidence
A tenant-scoped GET plus a project.created evidence record proves both state and accountability.

Start with the people and the result they need

The source tables below remain the detailed contract. Begin with these customer paths:

  • D04-UC-01
    • Person: Organization owner
    • Job: Create a project and submit a bounded AI application specification
    • Observable result: Valid revision is immutable, tenant-scoped, and ready for generation review
  • D04-UC-02
    • Person: Application creator
    • Job: Choose one of three archetypes and revise its requirements
    • Observable result: New revision supersedes rather than overwrites prior intent

Turn each customer job into a testable story

Now turn each customer job into a story with a result that an engineer can check:

  • D04-US-01
    • Story: As an organization owner, I want every app specification validated and versioned, so that reviewers know exactly what generation will consume
    • Observable acceptance: Response contains organization, project, app, revision, schema version, and content hash
  • D04-US-02
    • Story: As an application creator, I want revisions instead of in-place edits, so that audit and rollback retain the original intent
    • Observable acceptance: Old revision remains readable; wrong-tenant read returns denial and trace ID

Add real state and observable proof

Finally trace each story through the system that owns its state and the evidence that proves the outcome:

  • D04-FLOW-01
    • Trigger: Owner submits an archetype brief
    • Responsible systems: verifybearer, ForgeController, Forge, injected repository and event publisher
    • Authoritative state: Local SQLite project and evidence stores; PostgreSQL is a configurable adapter target
    • Owned record: OrganizationProject
    • Observable evidence: Actor, organization, project, revision hash, expected/observed result, local environment, timestamp, trace ID
    • Failure signal: Invalid token or tenant, duplicate project ID, or failed persistence
  • D04-FLOW-02
    • Trigger: Creator requests a revision under another organization
    • Responsible systems: ForgeController, Forge, and deterministic generator validation later in the lifecycle
    • Authoritative state: Project payload currently owns the embedded blueprint; immutable revision store is not implemented
    • Owned record: ApplicationRevision
    • Observable evidence: Denial rule, zero foreign writes, audit trace, and successful own-tenant read
    • Failure signal: Unsupported archetype fails during generation; no standalone revision evidence exists yet

The enterprise problem and today’s slice

Enterprise problem: Free-form prompts omit ownership, data, identity, and lifecycle constraints, so generation can produce software that nobody can safely approve or retire.

Whole-course context: The service ports assign provider metadata to the control plane; today creates the first durable tenant-scoped project through those interfaces.

Today’s slice: Create the implemented organization-scoped project and embedded archetype blueprint, then specify the separate immutable application-revision record still needed for production.

End-of-day evidence: Authenticated project creation, tenant-scoped retrieval, project.created evidence, and a wrong-tenant denial are reproducible from the HTTP smoke and domain tests; revision hashes remain future evidence.

Still unsolved: No code is generated, previewed, connected, published, or deployed in this slice.

Customer use cases

An application cannot be governed when its tenant and owner are implicit. These use cases create a complete specification and deny a cross-organization reference.

Use case IDActorCustomer jobSuccess outcomeDenial or recovery evidence
D04-UC-01Organization ownerCreate a project and submit a bounded AI application specificationValid revision is immutable, tenant-scoped, and ready for generation reviewValidation returns field-level errors without creating a revision
D04-UC-02Application creatorChoose one of three archetypes and revise its requirementsNew revision supersedes rather than overwrites prior intentCross-organization project reference is denied and audited

Actor-centred user stories

Mutable requirements destroy reproducibility because a generation run can no longer name its input. These stories require stable revision identity and tenant denial.

Story IDUse case IDsUser storyObservable acceptance conditions
D04-US-01D04-UC-01As an organization owner, I want every app specification validated and versioned, so that reviewers know exactly what generation will consumeResponse contains organization, project, app, revision, schema version, and content hash
D04-US-02D04-UC-02As an application creator, I want revisions instead of in-place edits, so that audit and rollback retain the original intentOld revision remains readable; wrong-tenant read returns denial and trace ID

End-to-end product flows

Creation begins at Zheta Forge Studio and terminates in a reviewable contract. The denied flow proves that knowing another project's identifier does not grant access.

Flow IDUse case IDsPathTriggerNumbered stepsTerminal evidence
D04-FLOW-01D04-UC-01, D04-UC-02HappyOwner submits an archetype brief1. Authenticate provider user.; 2. Resolve organization membership.; 3. Create project and application shell.; 4. Validate specification.; 5. Append revision.Actor, organization, project, revision hash, expected/observed result, local environment, timestamp, trace ID
D04-FLOW-02D04-UC-01, D04-UC-02DeniedCreator requests a revision under another organization1. Resolve token organization.; 2. Compare project tenant key.; 3. Deny before write.; 4. Read own project as positive control.Denial rule, zero foreign writes, audit trace, and successful own-tenant read

The owner creates governed intent, not a Deployment or database. This keeps product review ahead of resource allocation.

System design derived from the flows

Tenant checks duplicated across handlers eventually disagree. Organization membership is resolved once, while Application Catalog owns project, application, and revision writes.

Use case IDEntry pointResponsible servicesAuthoritative storeFailure evidence
D04-UC-01POST /projectsverify_bearer, ForgeController, Forge, injected repository and event publisherLocal SQLite project and evidence stores; PostgreSQL is a configurable adapter targetInvalid token or tenant, duplicate project ID, or failed persistence
D04-UC-02Blueprint fields in POST /projectsForgeController, Forge, and deterministic generator validation later in the lifecycleProject payload currently owns the embedded blueprint; immutable revision store is not implementedUnsupported archetype fails during generation; no standalone revision evidence exists yet

Identity proves provider-plane membership; Application Catalog alone writes the specification revision after validation.

Data model and ownership

Tenant keys must participate in every lookup or guessed identifiers become an authorization bypass. Control-plane records remain separate from future generated-app data.

Generated-application database: Not created in this slice — only provider control-plane metadata and specification revisions are durable today.

Record or entityStore and ownerPrimary keyForeign key or opaque referenceTenant keyMaterial constraintLifecycle and deletionUse case IDs
OrganizationProjectControl-plane PostgreSQL, owned by Application Catalogproject_idorganization_id local FKorganization_idSlug unique within organization; tenant included in access predicatesCreated, archived, exported, then deleted after dependent apps retireD04-UC-01, D04-UC-02
ApplicationRevisionControl-plane PostgreSQL, owned by Application Catalogrevision_idapplication_id local FK and opaque schema versionorganization_idImmutable body and hash; contiguous successor relationAppended, superseded, retained for audit, deleted with approved lifecycle jobD04-UC-01, D04-UC-02

The revision hash becomes the input identity for generation; audit evidence proves acceptance or denial without gaining runtime authority.

Exercise the specification API

A 201 response is insufficient unless durable tenant-scoped state and audit evidence agree. The current implementation creates a project directly from an authenticated HTTP command; it has no separate organization service, PostgreSQL deployment, or versioned application-spec resource yet. Read the exact model operation in services/control_plane/domain.py.

def create(self, project_id: str, organization_id: str, name: str, actor: str, archetype: str) -> Project:
    project = Project(project_id, organization_id, name, actor, blueprint={"name": name, "archetype": archetype})
    project.collaborators.add(actor)
    self.repository.create(project)
    self._audit(project, actor, "project.created")
    return project
Declared intentInterpreterSoftware effectHardware effectEvidence
Create one organization-scoped project with an archetype blueprintThe Python controller supplies JWT-derived identity to Forge.create; injected repository and event ports perform side effectsPersists one project in local SQLite and publishes project.created; there is no independent spec-revision record in this implementationThe control-plane process uses CPU, its named volume receives SQLite pages, and the event adapter uses local networking/broker storageAuthenticated POST /projects, tenant-scoped GET /projects/{id}, the project.created event, and the wrong-tenant unit test

Decision rules

Keep specifications declarative and versioned; do not mix generated source, runtime secrets, or app-user permissions into them. A new archetype is inside the platform only when the same revision contract can describe it without adding app-specific fields to core services.