mirror of
https://github.com/techforces-ai/Cial.git
synced 2026-05-15 19:14:11 +00:00
docs+fix: refresh /docs to match current container layout, fix BuildRunner filters
Audit pass over docs/ + adjacent code following the cial-* → core/platform/app
layout consolidation.
Bug fix:
- core/back BuildRunner ALL_FILTERS referenced @cial/core-back and
@cial/core-front, which no longer exist (the packages are @cial/back +
@cial/front). Self-edit deploys with scope=all would have silently
skipped those packages. Filters corrected.
Docs aligned with reality:
- docs/README.md — promotes file-structure.md to the start-here entry.
- architecture/dev-tenant.md — full rewrite: paths now /cial/* throughout,
documents the read-only :ro overlay of /cial/core, the new
--config.confirm-modules-purge=false install flag, the symlink dance for
project skills, and the agent's cwd=/cial + HOME=/cial/data/home setup.
- architecture/deploy-pipeline.md — package-name fix for ALL_FILTERS.
- architecture/core-vs-platform.md — package-name fix for the build list.
- ops/supervisor.md — drops stale "added in Phase 7" annotation.
- ops/deploy-logs.md — example log line uses @cial/back.
- self-edit/recipes.md — protocol path and dependency chain naming.
- design/self-edit-unrestricted.md — banner clarifying it's the original
design record (pre-rename) so an agent doesn't follow stale paths from it.
Tiny code touch:
- core/edge/src/supervisor.dev.ts — comment on CIAL_MONOREPO_ROOT no longer
contradicts itself ("not /cial" → "the bind-mounted repo at /cial").
Build verified: turbo run build for @cial/back still passes (cache miss
re-executed cleanly with the updated runner.ts).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
341c6dd728
commit
a0c9973412
10 changed files with 60 additions and 32 deletions
|
|
@ -51,8 +51,8 @@ const ALL_FILTERS = [
|
|||
'--filter', '@cial/protocol',
|
||||
'--filter', '@cial/sdk',
|
||||
'--filter', '@cial/core-ui',
|
||||
'--filter', '@cial/core-back',
|
||||
'--filter', '@cial/core-front',
|
||||
'--filter', '@cial/back',
|
||||
'--filter', '@cial/front',
|
||||
'--filter', '@cial/edge',
|
||||
'--filter', '@cial/platform-back',
|
||||
'--filter', '@cial/platform-front',
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ const SERVICES: ServiceSpec[] = [
|
|||
CLAUDE_HOME: `${STATE_DIR}/home`,
|
||||
// Tell core-back where to find the supervisor socket.
|
||||
CIAL_SUPERVISOR_SOCK: SOCKET_PATH,
|
||||
// Workspace is the dev monorepo root (bind-mounted), not /cial.
|
||||
// Workspace root inside the container — the bind-mounted repo at /cial.
|
||||
CIAL_MONOREPO_ROOT: ROOT,
|
||||
CIAL_PLATFORM_ROOT: `${ROOT}/platform`,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
Index for everything an agent (or human) might need to know to safely edit Cial from inside its own dev container.
|
||||
|
||||
## Start here
|
||||
- **`file-structure.md`** — canonical map of `/cial/{core,platform,app,docs,.claude,data}` inside the running container. **Read this first.**
|
||||
- **`architecture/overview.md`** — the 3-layer model (core / platform / app), what runs in the tenant container, and the supervisor + edge proxy.
|
||||
- **`architecture/core-vs-platform.md`** — what the agent can edit by default, and what `--unrestricted` unlocks.
|
||||
- **`self-edit/unrestricted-mode.md`** — what `pnpm dev:tenant --unrestricted` does and the risks.
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ What `pnpm dev:tenant --unrestricted` adds:
|
|||
- Edit any file under `core/`, `core/protocol/`, `core/sdk/`.
|
||||
- `POST /api/v1/self/deploy` with `scope=auto` builds:
|
||||
- `@cial/protocol`, `@cial/sdk`, `@cial/core-ui`,
|
||||
- `@cial/core-back`, `@cial/core-front`,
|
||||
- `@cial/back`, `@cial/front`,
|
||||
- `@cial/edge`,
|
||||
- `@cial/platform-back`, `@cial/platform-front`.
|
||||
- `POST /api/v1/self/restart` with `scope=auto` bounces every service, including `edge` (which exits the supervisor → Docker restart-policy bounces the container).
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ const ALL_FILTERS = [
|
|||
'--filter', '@cial/protocol',
|
||||
'--filter', '@cial/sdk',
|
||||
'--filter', '@cial/core-ui',
|
||||
'--filter', '@cial/core-back',
|
||||
'--filter', '@cial/core-front',
|
||||
'--filter', '@cial/back',
|
||||
'--filter', '@cial/front',
|
||||
'--filter', '@cial/edge',
|
||||
'--filter', '@cial/platform-back',
|
||||
'--filter', '@cial/platform-front',
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ End-to-end flow when you run `pnpm dev:tenant` (or `pnpm dev:tenant --unrestrict
|
|||
|
||||
## Driver
|
||||
|
||||
`scripts/dev-tenant.mjs` is a pure Node.js script. On each invocation:
|
||||
`core/scripts/dev-tenant.mjs` is a pure Node.js script. On each invocation:
|
||||
|
||||
1. Parses `--reset` and `--unrestricted` flags.
|
||||
2. Extracts host Claude Code OAuth credentials:
|
||||
|
|
@ -12,10 +12,11 @@ End-to-end flow when you run `pnpm dev:tenant` (or `pnpm dev:tenant --unrestrict
|
|||
- Linux: from `~/.claude/.credentials.json`.
|
||||
3. Builds `cial-tenant-dev:latest` from `core/docker/Dockerfile.dev` (cached on subsequent runs).
|
||||
4. `docker run` with:
|
||||
- bind mount `/cial` ← repo root (so source edits hot-reload).
|
||||
- named volume `cial-dev-tenant-state` ← `/cial/data` (sqlite, claude home).
|
||||
- named volume `cial-dev-tenant-modules` ← `/cial/node_modules`.
|
||||
- per-package anonymous volumes shadowing each `node_modules`.
|
||||
- bind mount `${ROOT}:/cial:delegated` ← repo root (so source edits hot-reload).
|
||||
- **`${ROOT}/core:/cial/core:ro,delegated`** when `--unrestricted` is NOT passed — read-only overlay enforcing the trust boundary at the FS level.
|
||||
- named volume `cial-dev-tenant-state` ← `/cial/data` (sqlite, agent home, deploy logs).
|
||||
- named volume `cial-dev-tenant-modules` ← `/cial/node_modules` (top-level workspace deps).
|
||||
- per-package anonymous volumes shadowing each `node_modules` (Linux-built per-pkg deps).
|
||||
- named volume `cial-dev-tenant-pnpm-store` ← `/pnpm-store`.
|
||||
- port 8080 forwarded to the host.
|
||||
- host creds bind-mounted read-only at `/run/secrets/claude-credentials.json`.
|
||||
|
|
@ -25,34 +26,53 @@ End-to-end flow when you run `pnpm dev:tenant` (or `pnpm dev:tenant --unrestrict
|
|||
|
||||
`core/docker/dev-entrypoint.sh` runs once at container start:
|
||||
1. Copies host creds → `/cial/data/home/.claude/.credentials.json` (mode 0600).
|
||||
2. `pnpm install --frozen-lockfile --prefer-offline`.
|
||||
3. Pre-builds `@cial/protocol` + `@cial/sdk` + `@cial/edge` (these don't have watchers).
|
||||
4. Execs `node /cial/core/edge/dist/supervisor.dev.js`.
|
||||
2. Symlinks `${CLAUDE_HOME}/.claude/{skills,agents,commands}` → `/cial/.claude/{skills,agents,commands}` so the harness picks up project skills.
|
||||
3. `pnpm install --frozen-lockfile --prefer-offline --config.confirm-modules-purge=false` (the last flag prevents pnpm from stalling on a stale modules volume after a layout change).
|
||||
4. Pre-builds `@cial/protocol` + `@cial/sdk` + `@cial/edge` (these don't have watchers).
|
||||
5. Execs `node /cial/core/edge/dist/supervisor.dev.js`.
|
||||
|
||||
## Dev supervisor
|
||||
|
||||
`core/edge/src/supervisor.dev.ts` spawns five children with watchers:
|
||||
- `core-back`: `tsx watch src/index.ts` on :4000
|
||||
- `core-front`: `next dev --turbopack -p 4001`
|
||||
- `platform-back`: `tsx watch src/index.ts` on :3001
|
||||
- `platform-front`: `next dev --turbopack -p 3000`
|
||||
- `edge`: `node dist/edge.js` on :8080 (no watcher — restart container if you edit it)
|
||||
`core/edge/src/supervisor.dev.ts` spawns five children with watchers, all rooted under `/cial`:
|
||||
|
||||
| Child | Command | cwd | Port |
|
||||
| ---------------- | ------------------------------------ | --------------------- | ---- |
|
||||
| `core-back` | `tsx watch src/index.ts` | `/cial/core/back` | 4000 |
|
||||
| `core-front` | `next dev --turbopack -p 4001` | `/cial/core/front` | 4001 |
|
||||
| `platform-back` | `tsx watch src/index.ts` | `/cial/platform/back` | 3001 |
|
||||
| `platform-front` | `next dev --turbopack -p 3000` | `/cial/platform/front`| 3000 |
|
||||
| `edge` | `node dist/edge.js` | `/cial/core/edge` | 8080 |
|
||||
|
||||
Each child's stdout/stderr is prefixed with a colored `[name]` tag and merged into a single stream the host's `pnpm dev:tenant` tails.
|
||||
|
||||
The dev supervisor also opens the same Unix-socket IPC server as prod (`/run/cial-supervisor.sock`), so the self-edit endpoints work in dev too.
|
||||
The dev supervisor also opens the same Unix-socket IPC server as prod (`/run/cial-supervisor.sock`), so the self-edit endpoints work in dev too. The agent harness is spawned from `core-back` with:
|
||||
|
||||
- `cwd = /cial`
|
||||
- `HOME = /cial/data/home`
|
||||
|
||||
so `/cial:self-edit`, `/cial:build`, `/cial:restart` are discoverable via `${CLAUDE_HOME}/.claude/skills` (symlinked to `/cial/.claude/skills`).
|
||||
|
||||
## Volumes (state survives restart)
|
||||
|
||||
| Volume | Mount in container | Persists |
|
||||
| ----------------------------------- | ------------------------------ | --------------------------- |
|
||||
| `cial-dev-tenant-state` | `/cial/data` | sqlite, claude home, logs |
|
||||
| `cial-dev-tenant-modules` | `/cial/node_modules` | top-level node_modules |
|
||||
| `cial-dev-tenant-state` | `/cial/data` | sqlite, agent home, logs |
|
||||
| `cial-dev-tenant-modules` | `/cial/node_modules` | top-level node_modules |
|
||||
| `cial-dev-tenant-pnpm-store` | `/pnpm-store` | pnpm cache |
|
||||
| anonymous (per workspace package) | `/cial/<pkg>/node_modules`| Linux-built per-pkg deps |
|
||||
| anonymous (per workspace package) | `/cial/<pkg>/node_modules` | Linux-built per-pkg deps |
|
||||
|
||||
`pnpm dev:tenant --reset` removes all four named volumes and the `.dev-tenant/` host state dir.
|
||||
`pnpm dev:tenant --reset` removes all four named volumes and the `.dev-tenant/` host state dir. Use this after a workspace layout change (renames, new packages) if you see "module not found" errors at startup.
|
||||
|
||||
## Why the named volumes for node_modules?
|
||||
|
||||
Without them, the host's macOS-built `node_modules` would leak into the Linux container through the bind mount, and `pnpm` would try to symlink to a `.pnpm/` store that points at darwin-arm64 binaries. The shadow volumes give the container its own clean Linux deps.
|
||||
|
||||
## Trust boundary in dev (`--unrestricted` vs default)
|
||||
|
||||
| Surface | Default (`pnpm dev:tenant`) | `--unrestricted` |
|
||||
| -------------------------------------- | ------------------------------- | ------------------------------ |
|
||||
| Bind mount of `/cial/core` | `:ro` (read-only) | `:rw` (writable) |
|
||||
| `BuildRunner` `scope=all` | rejected (`unrestricted_required`) | accepted |
|
||||
| Supervisor restart for `core-*`/`edge` | rejected | accepted |
|
||||
|
||||
The FS-level read-only mount is defense-in-depth — even if a bug let the agent reach the build endpoint with `scope=all`, the underlying `pnpm build` would fail to write into `/cial/core/*/dist`.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
# Self-Edit & `--unrestricted` Mode — Design
|
||||
|
||||
> Status: design (locked); next step `/sc:implement`.
|
||||
> **Status: implemented + superseded.** This is the original design record from before the layout consolidation. References to `cial-core/`, `cial-platform/`, `cial-app/`, `scripts/dev-tenant.mjs`, `@cial/core-back`, `@cial/core-front` describe the pre-rename layout. For current paths and package names, see:
|
||||
>
|
||||
> - `docs/file-structure.md` — current container layout
|
||||
> - `docs/architecture/core-vs-platform.md` — current edit boundaries
|
||||
> - `docs/architecture/dev-tenant.md` — current dev launcher behavior
|
||||
> - `docs/self-edit/{api,recipes,unrestricted-mode}.md` — current API contract
|
||||
>
|
||||
> Kept as a design record. Do not use as a path/name reference.
|
||||
|
||||
## Goal
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Plain text. Each line is prefixed with `OUT ` (stdout) or `ERR ` (stderr) follow
|
|||
```
|
||||
OUT [@cial/protocol] tsc -b
|
||||
OUT [@cial/protocol] ✓ done in 1.2s
|
||||
ERR [@cial/core-back] error TS2345: ...
|
||||
ERR [@cial/back] error TS2345: ...
|
||||
```
|
||||
|
||||
## Tail in real time
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export function getRestartableServices(unrestricted: boolean): ReadonlySet<Resta
|
|||
| ------------------------- | --------------------------------------- | ------------------------------------------ |
|
||||
| User per child | gosu cial / agent | single root user |
|
||||
| Children | compiled `node dist/...` | watchers (`tsx watch`, `next dev`) |
|
||||
| IPC server | yes | yes (added in Phase 7) |
|
||||
| IPC server | yes | yes |
|
||||
| Socket mode | 0660 cial:cial | 0666 (single-user dev) |
|
||||
| Edge restart | `process.exit(0)` → docker restart | same |
|
||||
|
||||
|
|
|
|||
|
|
@ -58,13 +58,13 @@ curl -sf -X POST http://127.0.0.1:4000/api/v1/self/restart \
|
|||
## Add a field to a protocol type
|
||||
|
||||
```sh
|
||||
$EDITOR /cial/protocol/src/sessions.ts # add field
|
||||
$EDITOR /cial/core/back/src/... # use it
|
||||
$EDITOR /cial/platform/front/src/... # use it
|
||||
$EDITOR /cial/core/protocol/src/sessions.ts # add field
|
||||
$EDITOR /cial/core/back/src/... # use it
|
||||
$EDITOR /cial/platform/front/src/... # use it
|
||||
curl -sf -X POST http://127.0.0.1:4000/api/v1/self/deploy -d '{}'
|
||||
```
|
||||
|
||||
In `--unrestricted`, the build filter graph picks up `@cial/protocol` first, then anything that depends on it (core-back, core-front, sdk, platform-*). One call rebuilds the chain.
|
||||
In `--unrestricted`, the build filter graph picks up `@cial/protocol` first, then anything that depends on it (`@cial/back`, `@cial/front`, `@cial/sdk`, `@cial/platform-*`). One call rebuilds the chain.
|
||||
|
||||
## Cancel an in-flight build
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue