This repository ships no compose file. The host deployment (VisionClaw) implements the contract below and mounts this repository as a git submodule at codescape/. Any other host must meet the same contract.
The service the host defines. Values are VisionClaw's; another host substitutes its own paths. deploy/codescape-entrypoint.sh is the entrypoint and reads only the variables listed here.
services:
codescape:
container_name: codescape
hostname: codescape
build: # any image with cargo, node 22 and, for cuda, nvcc
context: .
dockerfile: Dockerfile.unified
target: development
entrypoint: ["/app/codescape/deploy/codescape-entrypoint.sh"]
environment:
CODESCAPE_SRC: /app/codescape # this repository, read-only
CODESCAPE_GPU_SRC: /app/crates/visionclaw-gpu # PTX build sources, read-only
CODESCAPE_NODE_MODULES: /app/client/node_modules # used when client/node_modules is absent
CODESCAPE_TARGET_DIR: /codescape-target # all build output, writable volume
CODESCAPE_PTX_DIR: /codescape-target/ptx # staged by the entrypoint
CODESCAPE_DATA_DIR: /data/codescape
CODESCAPE_PORT: "4100"
CODESCAPE_INGEST_PORT: "4101"
CODESCAPE_BIND: 0.0.0.0
CODESCAPE_PREFER_CUDA: "1"
# The first entry is the default scene. `estate` is the whole mount tree
# (its L0 is the repositories); each member is also its own scene.
CODESCAPE_REPO: estate=/repos/estate,visionclaw=/repos/estate/visionclaw,agentbox=/repos/estate/agentbox,codescape=/repos/estate/codescape,solid-pod-rs=/repos/estate/solid-pod-rs,nostr-rust-forum=/repos/estate/nostr-rust-forum,dreamlab-ai-website=/repos/estate/dreamlab-ai-website,loom=/repos/estate/loom,knowledgeGraph=/repos/estate/knowledgeGraph,sidestr-rs=/repos/estate/sidestr-rs,visiontouch-rs=/repos/estate/visiontouch-rs
CODESCAPE_EXCLUDES: target/**,node_modules/**,data/**,logs/**,.dev-inputs/**,archive/**,vircadia-world/**,dist/**,.venv/**
CODESCAPE_PATH_MAP: /home/devuser/workspace/project=/repos/estate/visionclaw:/home/devuser/workspace/project/agentbox=/repos/estate/agentbox:... # one agent-side prefix per mounted repository
CODESCAPE_INGEST_TOKEN_FILE: /run/secrets/codescape-ingest-token
CODESCAPE_ASR_URL: ws://nemotron-asr:8000/api/asr-streaming
CODESCAPE_TTS_URL: http://pocket-tts:8000
CODESCAPE_LOOM_URL: "" # optional; empty means unset
CODESCAPE_TRUST_PROXY: "1"
CODESCAPE_TRUST_PROXY_FROM: visionclaw-server # the nginx peer's network alias
CODESCAPE_PUBLIC_PATH_PREFIX: /codescape
RUST_LOG: info
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: compute,utility
secrets:
- codescape-ingest-token
volumes:
- ./codescape:/app/codescape:ro # the submodule
- ./crates/visionclaw-gpu:/app/crates/visionclaw-gpu:ro # PTX build only
- ./crates/visionclaw-domain:/app/crates/visionclaw-domain:ro # visionclaw-gpu's path dependency
# Dogfood repositories: source directories only, read-only (see Service).
- ./.gitignore:/repos/estate/visionclaw/.gitignore:ro
- ./src:/repos/estate/visionclaw/src:ro
- ./crates:/repos/estate/visionclaw/crates:ro
- ./client/src:/repos/estate/visionclaw/client/src:ro
- ./xr-client:/repos/estate/visionclaw/xr-client:ro
- ./scripts:/repos/estate/visionclaw/scripts:ro
- ./docs:/repos/estate/visionclaw/docs:ro
- ./tests:/repos/estate/visionclaw/tests:ro
- ./agentbox/.gitignore:/repos/estate/agentbox/.gitignore:ro
- ./agentbox/config:/repos/estate/agentbox/config:ro
- ./agentbox/services:/repos/estate/agentbox/services:ro
- ./agentbox/management-api:/repos/estate/agentbox/management-api:ro
- ./agentbox/crates:/repos/estate/agentbox/crates:ro
- ./agentbox/lib:/repos/estate/agentbox/lib:ro
- ./agentbox/scripts:/repos/estate/agentbox/scripts:ro
- ./agentbox/skills:/repos/estate/agentbox/skills:ro
- ./agentbox/voice:/repos/estate/agentbox/voice:ro
- ./agentbox/tests:/repos/estate/agentbox/tests:ro
- ./agentbox/docs:/repos/estate/agentbox/docs:ro
# Estate siblings (see below): one .gitignore plus source directories each,
# all under the one estate root.
- ${CODESCAPE_ESTATE_ROOT}/codescape/.gitignore:/repos/estate/codescape/.gitignore:ro
- ${CODESCAPE_ESTATE_ROOT}/codescape/crates:/repos/estate/codescape/crates:ro
- ${CODESCAPE_ESTATE_ROOT}/codescape/client:/repos/estate/codescape/client:ro
# ... and likewise for solid-pod-rs, nostr-rust-forum, dreamlab-ai-website,
# loom, knowledgeGraph, sidestr-rs and visiontouch-rs.
# Own caches and state, never shared with another container.
- codescape-cargo-cache:/root/.cargo/registry
- codescape-cargo-git:/root/.cargo/git
- codescape-target:/codescape-target
- codescape-data:/data/codescape
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- DAC_READ_SEARCH
ports:
- "127.0.0.1:4100:4100" # clients only; 4101 is never published
networks:
visionclaw_network:
aliases:
- codescape
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu, compute, utility]
runtime: nvidia
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:4100/api/health"]
interval: 30s
timeout: 5s
retries: 5
start_period: 900s # the first start compiles the workspace in release mode
volumes:
codescape-cargo-cache:
codescape-cargo-git:
codescape-target:
codescape-data:
secrets:
codescape-ingest-token:
file: ./secrets/codescape-ingest-tokenCompared with the service VisionClaw ran before extraction (docker-compose.unified.yml at cac36a028): the crates:/app/crates, client/src:/app/client/src and scripts:/app/scripts mounts are replaced by the submodule at /app/codescape and the two GPU source directories, and the entrypoint path moves into the submodule.
- Exits 2 if
RUVECTOR_PG_CONNINFOis set. CODESCAPE_FEATURES(autoby default:cudawhennvccand a device exist; orcuda, or anything else for CPU only).- With
cuda: buildsvisionclaw-gputhrough a throwaway wrapper package on the target volume (its sources are read-only) and stagesvisionclaw_unified.ptxandptx-build-manifest.txtintoCODESCAPE_PTX_DIR. The GPU sources are a build input for the PTX only; they never enter Codescape's Cargo graph (BASELINE I1a, I10). Without them the engine falls back to CPU. cargo build --release --locked -p codescape-serverfromCODESCAPE_SRCintoCODESCAPE_TARGET_DIR.--lockednever writes the read-only checkout; the first build fetchesvisionclaw-wireand graphicle into the cargo cache volumes.- Copies
CODESCAPE_SRC/clienttoCODESCAPE_TARGET_DIR/client-build, links itsnode_modulesto the checkout's own or, when absent,CODESCAPE_NODE_MODULES(VisionClaw's dev image ships the same pinned packages), and runsvite build --configLoader runnerthere intoCODESCAPE_STATIC_DIR(default$CODESCAPE_TARGET_DIR/codescape-dist). Nothing is written into the linkednode_modules. - Execs
codescape-serverwith the repos, excludes, ports, data and static directories, and the ingest token when set.
CODESCAPE_SKIP_BUILD=1 skips steps 3 to 5 and runs the last build.
| Port | Purpose | Exposure |
|---|---|---|
4100 |
Clients: REST, /ws/positions, /ws/events, /ws/voice, /wss, /ws/presence, static desktop bundle |
published on host loopback only (127.0.0.1:4100) until P6 NIP-98; VisionClaw's knob is CODESCAPE_PUBLISH_ADDR |
4101 |
Hook ingest: POST /ingest/v1/activity, bearer token |
never published; reachable on the container network only |
VisionClaw's deployment maps the whole VisionFlow estate, not only the two dogfood repositories. Every repository is mounted under one root, /repos/estate/<label>, by the same rule as above: the root .gitignore plus its source directories, read-only, and nothing else. CODESCAPE_ESTATE_ROOT is the host path of the directory holding the sibling checkouts (on the reference host, the agentbox workspace volume).
Scenes are nested roots. estate=/repos/estate is listed first and is therefore the default scene: L0 directory nodes are minted from the first path component, so its L0 is the ten repositories and the client's repository panel shows and hides each one. Each member is listed again as its own scene (visionclaw=/repos/estate/visionclaw and so on), reachable with ?repo=<label> and from the panel's scene links. A hook-reported path under nested roots is delivered to every scene that contains it, so activity lights up in the estate view and the member's. Nothing is ingested twice from disk beyond the walk itself: each scene keeps its own cache under the data directory.
| Label | Mounted | Deliberately left out |
|---|---|---|
codescape |
client, crates, deploy, docs |
target |
solid-pod-rs |
crates, docs, scripts |
.agentic-qe witness keys |
nostr-rust-forum |
crates, docs, scripts, tests, benchmarks |
dist, target |
dreamlab-ai-website |
src, content, marketing, forum-config, scripts, tests, docs |
dist, public (binary assets), node_modules, .agentbox push keys |
loom |
crates, deploy, docs, tools, tests, bench, scripts, model |
app, data, legacy, uplift-results (run output, ~700 MB) |
knowledgeGraph |
explorer, docs, scripts, static |
archive and dist: the published corpus. Codescape maps the explorer and tooling, never a corpus (BASELINE I4) |
sidestr-rs |
docs and the eleven sidestr-* / webledgers-teller crate directories |
.agentic-qe witness keys |
visiontouch-rs |
apps, crates, docs, scripts, tools |
archive, target |
Adding a sibling means: its .gitignore and source directories as :ro binds under /repos/estate/<label>, a <label>=/repos/estate/<label> entry in CODESCAPE_REPO for its own scene, and one CODESCAPE_PATH_MAP entry per agent-side path the hooks will report for it (longest prefix wins, so a nested checkout such as project/codescape may sit beside the standalone one). Build output and key material are never mounted; the exclude list is a second fence, not the first, and must never name a member repository (an agentbox/** exclude would remove that member from the estate).
- Its own compose service and container (
codescape, network aliascodescape). Codescape never runs as a process in a container that mounts a knowledge corpus or carriesRUVECTOR_PG_CONNINFO; if that variable is set the server exits 2. - Repositories are mounted read-only, source directories only: never a whole checkout, a corpus directory, a root
.envor a secrets tree.CODESCAPE_REPOnames them aslabel=/repos/<label>. CODESCAPE_PATH_MAPrewrites the absolute paths agents report (their view of the checkout) to the mount paths.- Its own cargo registry, git and target caches, never shared with another container.
security_opt: no-new-privileges:true,cap_drop: ALL,cap_add: DAC_READ_SEARCHonly (a compose file secret keeps the host's 0600 ownership).- Persistent volume for
CODESCAPE_DATA_DIR(/data/codescape): internerids.bin, warmpositions.bin, graphicle cache, timeline. - Healthcheck
GET http://127.0.0.1:4100/api/health. The first start compiles the workspace in release mode; allow a long start period. - GPU: NVIDIA runtime,
NVIDIA_DRIVER_CAPABILITIES=compute,utility;CODESCAPE_CUDA_DEVICEpins an ordinal.
- A file secret mounted at
/run/secrets/codescape-ingest-token, named byCODESCAPE_INGEST_TOKEN_FILE. VisionClaw's launcher mints it on first use under itssecrets/. - Without the file the ingest listener does not start.
- The agentbox activity-sink hook (agentbox ADR-2144) reads the same token and posts to
http://codescape:4101/ingest/v1/activity.
CODESCAPE_PTX_DIRpoints at a read-only directory holdingvisionclaw_unified.ptxandptx-build-manifest.txtfrom a real nvcc build (VisionClaw'svisionclaw-gpubuild output).- At load the engine checks the
c_paramssize (212 bytes), the launched kernels' arities,provenance=compiledin the manifest and the manifest's content tag against the file. Any failure falls back to the CPU engine and is reported in/api/health. - The PTX must be exactly the file the build wrote after its rewrite step, not raw nvcc output: the manifest's
rewrittentag is checked against it. - PTX is never committed here (
*.ptxis gitignored) and never compiled in.
VisionClaw's dev nginx exposes Codescape at http://<host>:3001/codescape/ as a network peer:
location = /codescaperedirects to/codescape/; the bundle uses relative asset paths.location ^~ /codescape/resolvescodescape:4100lazily through Docker DNS (resolver 127.0.0.11), so nginx starts and answers 502 while the service is down.rewrite ^/codescape/(.*)$ /$1 breakstrips the prefix.- Forwards
Host,X-Forwarded-Host,X-Forwarded-Proto,X-Forwarded-For, andX-Forwarded-Prefix: /codescape; WebSocket upgrade with 3600 s timeouts; buffering off. - Hides the upstream's
Cross-Origin-Opener-Policy,Cross-Origin-Embedder-PolicyandCross-Origin-Resource-Policyso the browser sees exactly one copy of each.
Server side, the service sets:
Trust is narrowed to that peer: a sibling container sending the same headers is treated as trust off. Rate limiting reads the last X-Forwarded-For hop, the one nginx appends.
:3001 is LAN-published in VisionClaw's dev profile, so /codescape/ there is a deliberate dev-only exposure of an open-auth service (owner waiver, ADR-2143 A4). Production nginx carries no Codescape location until P6.
CODESCAPE_ASR_URL (nemotron-asr streaming WebSocket), CODESCAPE_TTS_URL (pocket-tts) and optionally CODESCAPE_LOOM_URL (the Loom door, OpenAI-compatible /v1). These, plus the P6 voice-intent endpoint, are the only outbound targets.
