From 59368f8bc8205093a7f8428c9035229680260169 Mon Sep 17 00:00:00 2001 From: Natalie Date: Mon, 29 Jun 2026 10:56:38 -0400 Subject: [PATCH] feat(recursive_code_workspace): model producer namespaces + kind-orgs Encode the abstract workspace model: @org dirs are either producer namespaces (@ct) mirroring a forge, or kind-orgs (@applications/@packages/ @platform/@developer). Add rules for forge-mirroring, scope-by-repo-boundary, 3-tier package placement, and versioned @platform generations. v0.1.0->0.2.0. Co-Authored-By: Claude Opus 4.8 --- .../recursive_code_workspace.yaml | 68 ++++++++++++++++--- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/programming_general/recursive_code_workspace.yaml b/programming_general/recursive_code_workspace.yaml index aafcdea..7d2556d 100644 --- a/programming_general/recursive_code_workspace.yaml +++ b/programming_general/recursive_code_workspace.yaml @@ -1,32 +1,80 @@ apiVersion: conventions/v1 -version: 0.1.0 +version: 0.2.0 updated: "2026-06-29" name: recursive_code_workspace title: Recursive code workspace (~/Code @org tree) scope: general status: active -summary: ~/Code is a recursive tree of @org dirs, each holding many independent git repos; tools and agents resolve projects by walking it. +summary: ~/Code is a recursive tree of @org dirs — producer namespaces holding kind-orgs of independent git repos — that mirrors each producer's forge; tools resolve projects by walking it and cutting at repo boundaries. params: - name: root description: Workspace root to walk. default: "~/Code" appliesTo: ["~/Code/**"] rules: - - id: orgs + - id: org_dirs level: must text: > - Top-level @org dirs partition the workspace: @applications (apps/services you - operate), @projects (platforms incl. @cocottetech, @magic-civilization, @lilith), - @packages (shared libraries), @conventions (this repo), plus support buckets - @scripts / @docs / @forks / @external / @archives / @work. + Every @org dir is one of two things: a PRODUCER NAMESPACE (who builds it — e.g. + @ct, @lilith, @magic-civilization) or a KIND-ORG (what kind of artifact — @applications, + @packages, @platform, @developer). The same names recur at any depth; an @org's + meaning is positional, never global. + - id: producer_namespaces + level: must + text: > + A producer namespace groups everything one producer builds and MIRRORS that producer's + forge org structure 1:1. @ct (cocotte tech, ct-forge at 134.199.243.61) is the primary + one and is a symlink to @projects/@cocottetech. Inside a producer namespace live its + kind-orgs: @ct/@applications, @ct/@packages, @ct/@platform, @ct/@developer — each the + workspace checkout of the matching forge org (applications/, packages/, platform/, + developer/). + rationale: Producer is stable; license/distribution is not. A project released OSS later still belongs to its producer namespace — organize by who builds it, not by how it ships. + - id: kind_orgs + level: must + text: > + Kind-orgs partition a producer's repos by artifact role: + @applications = deployable products you operate (a composition of clients + backends + + databases serving real consumers); + @packages = shared libraries consumed by apps; + @platform = the core platform product, kept as VERSIONED GENERATIONS (current + archived); + @developer = dev-infra / meta repos (conventions, tooling). + rationale: An app is a deployable composition that CONSUMES packages; a package is a library CONSUMED BY apps. The role determines the kind-org, regardless of which producer or forge owns it. + - id: platform_versions + level: should + text: > + @platform holds successive generations of the core platform, not a single repo. Older + generations are archived (on the forge and as read-only checkouts); exactly one is the + live current. New platform generations are added beside the old, never overwritten. + rationale: The platform has evolved across named generations (egirl-platform -> lilith-platform -> lilith-platform.live / cocottetech); history is preserved as versions, not rewritten. - id: independent_repos level: must - text: Each project under an @org is its own independent git repo. Never assume a single monorepo at the root. - rationale: Repos are cloned/forge-managed per-project; cross-repo coupling is HTTP/registry, not filesystem. + text: Each project under a kind-org is its own independent git repo. Never nest one repo inside another's working tree, and never assume a single monorepo at the root or at a producer namespace. + rationale: Repos are cloned/forge-managed per-project; cross-repo coupling is HTTP/registry, not filesystem. A producer namespace that is itself a repo (rather than a plain container) cannot host sibling repos — make it a container (cf. @lilith). + - id: scope_by_boundary + level: must + text: > + Resolve an @org by the NEAREST enclosing repo / producer boundary, never by matching + the name alone. A @packages or @applications dir INSIDE a repo's working tree is + repo-local (a workspace member), NOT a workspace org. Tree-walkers must cut at .git + boundaries. + rationale: "@applications / @packages recur as both top-level kind-orgs and repo-internal workspace folders; name-only resolution conflates them." + - id: package_tiers + level: should + text: > + Place a library by its consumer reach, in three tiers: + (1) app-private — consumed by ONE app -> lives in /@packages/; + (2) producer-shared — consumed by >=2 apps of one producer -> lives in that producer's + @packages (e.g. @ct/@packages); + (3) cross-producer — consumed beyond one producer (workspace-wide tooling, foundational + scopes) -> lives in the top-level @packages. + rationale: Promotes a package no further than its actual reach; avoids both premature sharing and hidden cross-producer coupling. - id: per_project_infra level: should text: A deployable project owns its infra via a root .infra.yaml (see convention:infra-manifest). Shared infra (e.g. the managed PG cluster) is data-sourced, not owned per-project. rationale: Catch-all shared infra repos (uvlava-style) are superseded by per-project ownership. - id: support_buckets level: may - text: Cross-cutting or transient items live in the support buckets, not inside project repos. + text: > + Cross-cutting or transient items live in the top-level support buckets (@scripts / + @docs / @forks / @external / @archives / @work), not inside project repos. These sit + beside the producer namespaces and kind-orgs at the workspace root.