compose-org

star 0

Fork an agentic substrate into a customer-flavoured digital clone using an org-brief YAML (from research-company) + the matching industry primer. Clones the substrate to a sibling repo, rebrands literal tokens, repacks the data-fabric generators against the brief's subsidiaries + named ELT, swaps the Kuzu entity-kind tables per the primer, extends the domain registry with the primer's workflow library, generates personae (ELT named from the brief, archetypes from the primer), seeds cadenced rituals + narrative arcs, and scaffolds Node MCP mocks for the brief's stack overrides. Local-only fork by default; no GitHub push. Refuses dirty trees, idempotent re-runnable. USE FOR: fork the substrate for a named customer (Telco, FSI, Airline, Retail, OEM, …), produce a digital-clone-grade demo repo. DO NOT USE FOR: incrementally adding one domain (use compose-domain inside the fork — planned, not yet available), authoring a new substrate from scratch, pitch decks.

aiappsgbb By aiappsgbb schedule Updated 5/26/2026

name: compose-org description: > Fork an agentic substrate into a customer-flavoured digital clone using an org-brief YAML (from research-company) + the matching industry primer. Clones the substrate to a sibling repo, rebrands literal tokens, repacks the data-fabric generators against the brief's subsidiaries + named ELT, swaps the Kuzu entity-kind tables per the primer, extends the domain registry with the primer's workflow library, generates personae (ELT named from the brief, archetypes from the primer), seeds cadenced rituals + narrative arcs, and scaffolds Node MCP mocks for the brief's stack overrides. Local-only fork by default; no GitHub push. Refuses dirty trees, idempotent re-runnable. USE FOR: fork the substrate for a named customer (Telco, FSI, Airline, Retail, OEM, …), produce a digital-clone-grade demo repo. DO NOT USE FOR: incrementally adding one domain (use compose-domain inside the fork — planned, not yet available), authoring a new substrate from scratch, pitch decks. metadata: version: "1.0.2"

compose-org

Fork the agentic substrate into a customer-flavoured digital clone by joining a thin org-brief with the matching industry primer.

research-company  →  briefs/<slug>-org-brief.yaml
                                  ↓
                  industry-primers/<vertical>.md
                                  ↓
                          compose-org (this skill)
                                  ↓
                  <substrate>-<slug>/  (local fork)
                                  ↓
                          make up  (operator)

When to use

Invoke after research-company has produced an org-brief whose meta.status is ready and whose meta.primer points at an existing industry primer.

Inputs

  1. Brief path — absolute path or path relative to cwd to the org-brief produced by research-company (e.g. briefs/<slug>-org-brief.yaml if you ran the catalog-clone flow, or <cwd>/briefs/<slug>-org-brief.yaml if you ran the remote-bootstrap flow per RUNBOOK.md).
  2. Substrate source (optional) — one of:
    • A local path to an existing substrate clone (e.g. ../zava-control-plane).
    • A git URL to clone from (e.g. https://github.com/arturcrmbot/zava-control-plane).
    • Omitted — defaults to cloning from https://github.com/arturcrmbot/zava-control-plane.
  3. Fork target path (optional) — where to write the fork. Defaults to <cwd>/zava-control-plane-<slug> (a sibling of the briefs/ directory inside cwd).

Output

A new local git repo at the fork-target path containing the rebranded

  • customised substrate. No GitHub remote is configured. Operator runs gh repo create later if they want to push.

Pre-flight (refuse to proceed if any fail)

Check Failure mode
Brief file exists and parses as YAML Stop; ask operator.
brief.meta.status == ready Stop; tell operator to sign off the brief first.
brief.meta.primer resolves to an existing primer Stop; offer to graduate a stub primer or pick a different vertical.
Substrate source available — either the supplied local path is a clean git tree on default branch, OR the supplied/default URL is reachable via git ls-remote Stop; refuse to clone from a dirty state or a network failure.
Fork target path does not already exist Stop. To re-run, the operator removes the target dir first (or uses --allow-overwrite flag explicitly — see § "Idempotent re-runs").
git, python3 ≥ 3.11, node ≥ 20, npm available Stop; install hint per missing tool.

Substrate paths (Zava control plane reference)

The skill assumes the target substrate follows the zava-control-plane layout. The phases below reference these paths verbatim. If you fork this skill for a different substrate, update the path table here.

Concept Path in substrate
Subsidiary seed list api/server/data_fabric/employee_gen.py (SUBSIDIARIES tuple)
Client/Brand generator api/server/data_fabric/client_brand_gen.py
Cadenced rituals seed api/server/data_fabric/cadenced_rituals.py
Narrative arcs seed api/server/data_fabric/narrative_arcs.py
Kuzu entity schema api/server/services/entity_graph.py
Function registry api/shared/functions.py
Persona registry api/shared/personas.py + api/server/personae/<role>/
Domain registry api/shared/domains.py
Node mocks mocks/<id>/
Rebrand playbook plan/archive/refactor-rebrand-zava-1.md

The ten phases

Phase 0 — Pre-flight

Run every check in the table above. Print a green/red summary. Stop on any red.

Phase A — Acquire the substrate

Either clone fresh from a git URL, or copy from a local path, depending on what was supplied:

# Default — fresh clone from the public substrate repo
git clone https://github.com/arturcrmbot/zava-control-plane <fork-target>

# OR — if a local substrate path was supplied
git clone <local-substrate-path> <fork-target>

cd <fork-target>
git remote remove origin            # no remote — local-only
git checkout -b main                # ensure clean main

Phase A always re-points origin to nothing — the fork is local-only by default. The operator runs gh repo create later if they want to push.

Phase B — Rebrand (literal find-and-replace)

The substrate already ships a rebrand playbook — plan/archive/refactor-rebrand-zava-1.md — that documents every literal token to swap. Follow it verbatim with the mappings derived from the brief:

Old token New token (derived from brief)
Zava Control Plane <brief.identity.short_name> Control Plane
zava-control-plane zava-control-plane-<brief.identity.slug>
Zava (literal, with trailing space) <brief.identity.short_name>
Zava- <brief.identity.short_name>-
zava.skill, zava.tool.*, zava.fleet_manager.* <brief.identity.slug>.skill, <brief.identity.slug>.tool.*, <brief.identity.slug>.fleet_manager.*
Zava (standalone, last) <brief.identity.short_name>

Tight allowlist of file extensions: .md, .py, .ts, .tsx, .js, .jsx, .yml, .yaml, .json, .toml, .sh, .css, .html, Dockerfile, Makefile.

Forbidden paths — never edit (would corrupt binary assets or break tests with cosmetic changes): **/*.png, **/*.jpg, **/*.avif, **/*.svg, **/*.mp4, **/azurite-data/**, **/data/portal/**/*.kuzu, **/data/.eval/**, **/__pycache__/**, **/.venv/**, **/node_modules/**, **/.git/**.

Commit the rebrand as one atomic commit: chore: literal rebrand <substrate> → <substrate>-<slug>.

Phase C — Repack the data fabric

C.1 — SUBSIDIARIES tuple

Replace the SUBSIDIARIES tuple at the top of api/server/data_fabric/employee_gen.py with rows derived from brief.subsidiaries[]. Format (per existing convention):

SUBSIDIARIES: tuple[str, ...] = (
    # one entry per brief.subsidiaries[].name
    "<Subsidiary 1 name>",
    "<Subsidiary 2 name>",
    ...
)

If the brief has fewer than 5 subsidiaries, pad with placeholder opcos drawn from the primer's regulator countries (e.g. <short_name> Singapore Pte Ltd) to keep the substrate's data-volume expectations intact.

C.2 — Client/Brand generator

Replace api/server/data_fabric/client_brand_gen.py with the primer's vertical-equivalent. For telco, that means generating Customer rows (enterprise accounts) and Service SKUs instead of Client rows and Brand rows. Seed customer names from brief.customers_or_segments; seed Service catalogue from the primer's typical Service list.

The function signature generate_clients_and_brands(...) stays the same (callers in pack.py don't change); only the implementation swaps. Add a one-line module docstring noting the source primer.

C.3 — Cadenced rituals seed

Append to api/server/data_fabric/cadenced_rituals.py one row per ritual in the primer's "Canonical cadenced rituals" table. The substrate's ritual schema is {id, display_name, cadence, owner_function} — read the file's existing format and match.

C.4 — Narrative arcs seed

Append to api/server/data_fabric/narrative_arcs.py one row per brief.strategic_themes[]. The substrate's narrative-arc schema is {id, headline, summary, function_focus, timeline_hint}.

Phase D — Schema swap (Kuzu entity kinds)

Edit api/server/services/entity_graph.py to:

  1. Rename the agency-specific node tables per the primer's "Canonical vertical entity kinds" table. Telco mapping:
    • BrandService
    • CampaignCircuit
    • PitchQuote
    • MediaPlanCapacityPlan
  2. Add the new-kind tables the primer introduces (telco: Site, PointOfPresence, Customer, Incident, Ticket, NetworkElement, IPPrefix, BGPPeering, CrossConnect, Licence, Spectrum).
  3. Update the projection mapping in api/server/services/entity_projections.py so existing code that wrote to Brand now writes to Service, etc. Mechanical find-and-replace inside that file ONLY.

Respect the stored Kuzu schema-syntax constraints — inline LIMIT ints, backtick reserved words, trailing PRIMARY KEY (id), no SET n += $map.

Phase E — Functions & personae

E.1 — Function registry

Replace api/shared/functions.py with rows derived from the primer's "Canonical functions" table. Each function gets:

Function(
    id="<id>",
    display_name="<display_name>",
    importance="<hero|core|support>",
)

E.2 — Persona folders

For each row in brief.leadership[], ensure a folder exists at api/server/personae/<role>/ with a SKILL.md whose frontmatter includes the real name + title + function from the brief. If the folder already exists in the substrate (e.g. ceo, cfo, coo), edit the frontmatter — don't overwrite the persona logic.

For each persona archetype in the primer's "Org chart archetypes" section that does NOT correspond to a brief-named leader, generate a folder at api/server/personae/<id>/ with a stub SKILL.md. The decision_policy block can be a minimal default; archetype names get expanded by faker in employee_gen.py at boot.

Update api/shared/personas.py to register every new persona.

Phase F — Domain composition

Append rows to api/shared/domains.py for each entry in the primer's "Proposed-domains starter library". Use the substrate's Domain(...) constructor signature verbatim:

Domain(
    workflow_type="<workflow_type>",
    display_name="<display_name>",
    workflow_id_prefix="<UPPER-PREFIX>-",
    orchestrator_name="<PascalCase>Orchestrator",
    operator_surface="...",
    phases=(...),
    hitl_gates=(...),
    skills=(...),
    function="<function-id>",
    realistic_interval_seconds=<int>,
    stub=True,    # all new domains start as stubs
),

Mark every newly-added domain as stub=True — the operator graduates them one at a time via compose-domain inside the new fork. Do not generate orchestrator files / graphs / skills here. That's compose-domain's job.

Tag each new domain with the brief's strategic-theme overrides: domains whose function is in any brief.strategic_themes[].function_focus[] get importance: hero; the rest importance: supporting (subject to ≤ 3 hero cap).

Phase G — Stack mocks

For each row in brief.stack_overrides[], scaffold a Node mock under mocks/<id>/:

  • mocks/<id>/server.ts — minimal FastMCP-style mock, ~80 lines, copies the shape of an existing mock under mocks/ (e.g. workday, concur).
  • mocks/<id>/package.json — one entry in mocks/<id>/package.json referencing the same parent deps as existing mocks.
  • Port assignment: next free port in the 4200–4299 range (read existing mocks/* to find used ports).

Generic Zava mocks (workday, concur, etc.) stay in place — the overrides are additive, not replacing.

Phase H — Re-seed the data fabric

Run the substrate's snapshot regeneration:

cd <fork-target>
make funcvenv         # one-time, Windows-friendly
uv sync
python -m api.server.data_fabric.pack --regenerate-snapshot

This rebuilds the Kuzu snapshot under data/snapshots/ so a cold-start make up reads the new entity-kind tables + new subsidiaries.

Phase I — Smoke test

make test            # substrate's existing test suite

If anything fails:

  • Test failures referencing literal Zava strings — incomplete rebrand; re-run Phase B with the failed-test paths added to the allowlist.
  • Kuzu schema errors — Phase D mistake; check primer's relations list and the substrate's _VALID_RELS.
  • Persona registry mismatch — Phase E.2 missed a row; cross-check personas.py against api/server/personae/ folder list.

Do NOT proceed to hand-off with red tests. Fixes are a tight loop between the agent and the operator.

Phase J — Hand off

Print to operator:

✅ Fork ready: <fork-target>

   git log --oneline       # one rebrand commit + N compose commits
   cd <fork-target>
   make up                 # boots Azurite, mocks, FastAPI, control-plane UI

   Visit http://localhost:5273 (control plane)
        http://localhost:5275 (blueprint microsite)

   To promote a stub domain to live:
     copilot
     > Run compose-domain on `<workflow_type>` (inside this fork)

   To push to GitHub later:
     gh repo create zava-control-plane-<slug> --private
     git remote add origin <url>
     git push -u origin main

Idempotent re-runs

Re-running compose-org against an existing fork target is supported via --allow-overwrite. The skill:

  1. Checks the existing fork's git status is clean.
  2. Discards uncommitted changes only if the operator confirms.
  3. Re-applies every phase as if from a fresh clone.

If the operator has hand-edited the fork, the safest path is to delete the fork dir and re-run from scratch — the brief is the source of truth.

Safety rails

  • No gh repo create automatic push. Forks are local-only by default; pushing to GitHub is an explicit operator action.
  • Rebrand allowlist is tight. Binary assets, .git/, node_modules/, .venv/, azurite-data/, data/.eval/ are never edited.
  • No .png / .mp4 / avatar regeneration. Demo media is intentionally inherited — the rebrand is text-only.
  • Refuses to overwrite without explicit flag. First failure mode for accidentally re-running is a no-op.
  • Per-phase commit boundaries. Every phase commits atomically so git revert <sha> rolls back one phase cleanly.

Output budget

A first-run compose-org against a Tier-1 vertical produces:

  • ~30–40 commits
  • ~150–250 files modified by the rebrand
  • ~10–15 new files (mocks, persona folders)
  • ~5,000–10,000 lines of diff total

If diff exceeds 20,000 lines, the rebrand allowlist is probably too broad — re-check the forbidden-paths list.

Iterating the skill

When a generated fork looks wrong:

  • Per-phase issues: fix the phase prose in this SKILL.md, then re-run with --allow-overwrite.
  • Primer issues: fix the matching primer file, then re-run.
  • Brief issues: fix the brief, re-run.

Two runs against the same brief + primer should diff to nothing meaningful except commit timestamps.

Downstream

After compose-org finishes, the operator's typical next steps:

  1. Verifymake up, walk the control plane UI, confirm domain names, persona names, KPIs match expectations.
  2. Graduate a stub domain — pick a hero domain (e.g. quote-to-circuit for telco) and run compose-domain on it inside the new fork. That fleshes out orchestrator / phase graphs / agent skills / personae.
  3. Demo prep — boot, time-warp scrub, capture a 30-min walkthrough.
Install via CLI
npx skills add https://github.com/aiappsgbb/zava-constellation --skill compose-org
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator