Skills move from a global Git-only registry to a per-company library that orgs author and
version in-app — Git stays as the shared *starter* library.
Domain & persistence:
- Skill gains OrganizationId (null = shared builtin, visible to every org), Origin
(Builtin | Authored | Installed), AuthoredByMemberId. Identity is now
(OrganizationId, SkillKey, Version); the unique index uses NULLS NOT DISTINCT so builtins
stay unique by key+version while each org gets its own namespace (and can fork a builtin).
AddSkillOwnership migration backfills existing rows as Builtin.
- Owned GoldenExample rows are cloned in Skill.Index so a fork can't re-parent the source's
tracked entities.
Authoring (tenant, dynamic):
- POST /api/skills/authored — structured fields → same indexer pipeline (embedding +
publish gate apply identically), tagged org + author. POST /api/skills/{key}/fork copies a
builtin/global skill into your org as an editable Authored draft. List/Get are org-scoped
(your org + shared builtins). New Capability.ManageSkills (Owner + TeamOwner), audited.
- GET /api/skills/marketplace: read-only seam listing public skills across orgs (install is
the next step).
Security (from adversarial review — two confirmed criticals):
- Managing shared builtins is an operator action, not a tenant one. /index (posts arbitrary
content as a global builtin) and /sync (re-indexes the shared library) now require a
platform admin key (X-Skills-Admin-Key, fixed-time compare, fail-closed when unset) via
SkillAdminOptions — previously any authenticated user of any org could inject/poison global
skills. New test asserts an authenticated Owner without the key gets 403 on both.
UI: new /skills library page — browse shared + org skills grouped by key with their versions,
create / new-version / fork, golden-test editor + body, Draft/Published badge and the
publish-gate hint (needs roles + ≥1 golden test).
Verified: ArchitectureTests 8/8, IntegrationTests 46/46 (new SkillLibraryTests: org
isolation, version coexistence, fork, publish gate, Member 403, admin-gate 403), client build
green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
TeamUp.AI
Build human + AI teams. A live org chart that does work: model the org, fill open role-seats with governed AI agents, run delivery on one board. A product of AliaSaaS.
Status: pre-M1 skeleton — the repo builds, tests green, and runs, but carries no feature
code yet. See docs/V1_BUILD_PLAN.md for what M1–M6 add.
Stack
.NET 10 modular monolith (web + worker on one image) · PostgreSQL 17 + pgvector · EF Core 10 ·
React 19 + Vite SPA into wwwroot · Docker Compose for local dev. Full bill of materials in
docs/V1_BUILD_PLAN.md.
Layout
src/Shared/TeamUp.SharedKernel IModule seam, base Entity, IModuleDbContext
src/Shared/TeamUp.Infrastructure PlatformDbContext (pgvector + schemas), MigrationRunner, wiring
src/Bootstrap/TeamUp.Bootstrap the explicit module catalog (the only thing that knows all modules)
src/Modules/TeamUp.Modules.* OrgBoard · Identity · Skills · Assembler · Governance · Memory · Integrations
src/Hosts/TeamUp.Web ASP.NET Core API host (also serves the SPA)
src/Hosts/TeamUp.Worker Generic Host worker (background jobs; M4+)
client/ React/Vite SPA → builds into TeamUp.Web/wwwroot
tests/ ArchitectureTests (boundary rules) · IntegrationTests (Testcontainers)
docker/ Dockerfile (one image, two roles) · docker-compose.yml
Boundary rule: each module is its own assembly; everything but its IModule and public
contracts is internal, so no module can touch another's persistence. TeamUp.ArchitectureTests
backstops this — it fails the build if a module references another module / Infrastructure / a host.
Prerequisites
.NET SDK 10 · Node 22 · Docker. Packages and container images are pulled through a Nexus mirror — see Package & image sources below.
Quick start
# Backend: build, run the boundary + integration tests (integration needs Docker)
dotnet build TeamUp.slnx
dotnet test TeamUp.slnx
# Local dev — two terminals, with the Vite dev server proxying /api to the .NET host
docker compose -f docker/docker-compose.yml up postgres -d # Postgres 17 + pgvector
dotnet run --project src/Hosts/TeamUp.Web # http://localhost:5180 (applies migrations in Dev)
cd client && npm install && npm run dev # http://localhost:5173 (proxies /api, /health)
# Or run the whole thing in containers (web + worker + postgres, single image, RUN_MODE picks the role)
docker compose -f docker/docker-compose.yml up --build
GET /health is the DB health check; GET /api/<module>/ping proves each module seam; the OpenAPI
document is at /openapi/v1.json (Development only).
EF Core migrations
dotnet ef migrations add <Name> \
--project src/Shared/TeamUp.Infrastructure --startup-project src/Shared/TeamUp.Infrastructure \
--context PlatformDbContext --output-dir Persistence/Migrations
The initial InitialPlatform migration enables the vector extension and creates one schema per
module. Module-owned contexts (M1+) get their own migrations and apply after Platform via
MigrationRunner.
Package & image sources
NuGet packages (nuget.config) and container base images (docker/Dockerfile,
docker/docker-compose.yml) are pulled through the self-hosted Nexus mirror
mirror.soroushasadi.com, which proxies nuget.org / Docker Hub / MCR and is reachable from Iran.
To build against the public registries instead, point nuget.config at api.nuget.org and replace
the mirror.soroushasadi.com/... image prefixes with docker.io/library (node) and
mcr.microsoft.com (dotnet). Testcontainers picks up the mirror via
TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX=mirror.soroushasadi.com/.
More
CLAUDE.md— always-loaded project indexdocs/CLAUDE.md— full architecture & domain modeldocs/PRODUCT.md— complete product modeldocs/V1_BUILD_PLAN.md— the V1 wedge (M1–M6) + bill of materials