Confirmed via README version markers + git history: egirl=v0, lilith-platform=v1, lilith-platform.live=v2 (still live prod), atlilith=v3, cocottetech=v4. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
5.3 KiB
YAML
85 lines
5.3 KiB
YAML
apiVersion: conventions/v1
|
|
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 — 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: org_dirs
|
|
level: must
|
|
text: >
|
|
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. There are exactly TWO producers, each with exactly ONE forge:
|
|
@ct (cocotte tech, ct-forge at 134.199.243.61) and @mc (magic civilization, mc-forge at
|
|
159.203.170.249). No other forges exist (the former black.lan/lilith forge is retired;
|
|
its repos migrate to ct-forge). @ct is a symlink to @projects/@cocottetech. Inside a
|
|
producer namespace live its kind-orgs: e.g. @ct/@applications, @ct/@packages,
|
|
@ct/@platform, @ct/@developer — each the workspace checkout of the matching forge org.
|
|
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. "lilith"/"egirl" are NOT producers — they are version names of the ct platform lineage (see platform_versions).
|
|
- 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 ct platform is ONE lineage across named generations, all owned by @ct:
|
|
egirl-platform = v0; lilith = v1-v3 (lilith-platform = v1, lilith-platform.live = v2
|
|
[still the LIVE production system], atlilith = v3); cocottetech = v4 (current build).
|
|
A "lilith"/"egirl" name denotes a platform VERSION, never a separate producer.
|
|
- id: independent_repos
|
|
level: must
|
|
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 <app>/@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 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.
|