fix: use canonical dogfood seat identity #1489
+2
-2
@@ -10,7 +10,7 @@ GATEWAY_HOST_PORT=14242
|
||||
# Optional explicit dogfood overlay (docker-compose.dogfood.yml).
|
||||
# All three paths are required when that overlay is used. Use a dedicated
|
||||
# next-based worktree, its canonical clone's .git directory, and the external
|
||||
# home of the unprivileged stack-dogfood seat.
|
||||
# home of the unprivileged code-dogfood-01 functional seat.
|
||||
# MOSAIC_DOGFOOD_WORKTREE=/home/example/src/mosaic-stack-worktrees/dogfood-1487
|
||||
# MOSAIC_DOGFOOD_COMMON_GIT_DIR=/home/example/src/mosaic-stack/.git
|
||||
# MOSAIC_DOGFOOD_SEAT_HOME=/home/example/.mosaic/fleet/agents/stack-dogfood
|
||||
# MOSAIC_DOGFOOD_SEAT_HOME=/home/example/.mosaic/fleet/agents/code-dogfood-01
|
||||
|
||||
@@ -221,18 +221,19 @@ docker compose --profile stack up -d
|
||||
|
||||
The optional dogfood overlay gives one dedicated in-stack agent a writable stack
|
||||
worktree and its own read-only credential slot. It does not mount the fleet brain or
|
||||
any other seat. Prepare a `next`-based worktree and an unprivileged `stack-dogfood`
|
||||
seat outside the container, then set these paths in `.env`:
|
||||
any other seat. Prepare a `next`-based worktree and an unprivileged
|
||||
`code-dogfood-01` functional seat outside the container, then set these paths in
|
||||
`.env`:
|
||||
|
||||
```dotenv
|
||||
MOSAIC_DOGFOOD_WORKTREE=/path/to/mosaic-stack-worktrees/dogfood-1487
|
||||
MOSAIC_DOGFOOD_COMMON_GIT_DIR=/path/to/mosaic-stack/.git
|
||||
MOSAIC_DOGFOOD_SEAT_HOME=/path/to/.mosaic/fleet/agents/stack-dogfood
|
||||
MOSAIC_DOGFOOD_SEAT_HOME=/path/to/.mosaic/fleet/agents/code-dogfood-01
|
||||
```
|
||||
|
||||
The common Git directory must match the worktree's `.git` pointer. The seat home
|
||||
must contain only that seat's credential at
|
||||
`secrets/gitea-mosaicstack-stack-dogfood.token`. Never place the token value in
|
||||
`secrets/gitea-mosaicstack-code-dogfood-01.token`. Never place the token value in
|
||||
`.env`. Start the overlay with:
|
||||
|
||||
```bash
|
||||
@@ -245,7 +246,7 @@ docker compose \
|
||||
The overlay removes the general shell tool for every session, including admins.
|
||||
File tools stay inside the mounted checkout. Two dedicated delivery tools stage
|
||||
explicit paths, run the CI queue guard, push through `git-credential-mosaic`, and
|
||||
open PRs through `pr-create.sh`. They resolve only the `stack-dogfood` slot and fail
|
||||
open PRs through `pr-create.sh`. They resolve only the `code-dogfood-01` slot and fail
|
||||
if it is absent. The overlay enables Docker's init process so the R4 helper can
|
||||
establish the gateway's seat lineage below PID 1.
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ function deliveryEnv(extra: Partial<DeliveryToolEnvironment> = {}): DeliveryTool
|
||||
return {
|
||||
AGENT_DELIVERY_ENABLED: 'true',
|
||||
MOSAIC_GIT_TOOLS_DIR: '/opt/mosaic/tools/git',
|
||||
MOSAIC_GIT_IDENTITY: 'stack-dogfood',
|
||||
MOSAIC_AGENT_NAME: 'stack-dogfood',
|
||||
MOSAIC_GIT_IDENTITY: 'code-dogfood-01',
|
||||
MOSAIC_AGENT_NAME: 'code-dogfood-01',
|
||||
MOSAIC_BRAIN_HOME: '/opt/mosaic/brain',
|
||||
MOSAIC_INTEGRATION_TRUNK: 'next',
|
||||
HOME: '/home/node',
|
||||
@@ -73,9 +73,9 @@ describe('dogfood execution boundary', () => {
|
||||
'brain',
|
||||
'fleet',
|
||||
'agents',
|
||||
'stack-dogfood',
|
||||
'code-dogfood-01',
|
||||
'secrets',
|
||||
'gitea-mosaicstack-stack-dogfood.token',
|
||||
'gitea-mosaicstack-code-dogfood-01.token',
|
||||
);
|
||||
fs.mkdirSync(sandbox, { recursive: true });
|
||||
fs.mkdirSync(path.dirname(token), { recursive: true });
|
||||
@@ -130,7 +130,7 @@ describe('delivery tools', () => {
|
||||
paths: ['change.md'],
|
||||
commitMessage: 'docs: dogfood proof (#1487)',
|
||||
});
|
||||
expect(textOf(result)).toBe('Published branch feat/1487-dogfood-proof as stack-dogfood.');
|
||||
expect(textOf(result)).toBe('Published branch feat/1487-dogfood-proof as code-dogfood-01.');
|
||||
|
||||
expect(calls.map((call) => call.file)).toEqual([
|
||||
'/usr/bin/git',
|
||||
@@ -146,7 +146,7 @@ describe('delivery tools', () => {
|
||||
expect(call.env).not.toHaveProperty('BASH_ENV');
|
||||
expect(Object.keys(call.env).some((key) => key.startsWith('BASH_FUNC_'))).toBe(false);
|
||||
expect(call.env).not.toHaveProperty('GITEA_TOKEN');
|
||||
expect(call.env.MOSAIC_GIT_IDENTITY).toBe('stack-dogfood');
|
||||
expect(call.env.MOSAIC_GIT_IDENTITY).toBe('code-dogfood-01');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ services:
|
||||
environment:
|
||||
# Identity and credential layout match a fleet seat. This fixed name prevents
|
||||
# an operator from mounting one seat while attributing actions to another.
|
||||
MOSAIC_AGENT_NAME: stack-dogfood
|
||||
MOSAIC_GIT_IDENTITY: stack-dogfood
|
||||
MOSAIC_AGENT_NAME: code-dogfood-01
|
||||
MOSAIC_GIT_IDENTITY: code-dogfood-01
|
||||
MOSAIC_BRAIN_HOME: /opt/mosaic/brain
|
||||
AGENT_FILE_SANDBOX_DIR: /workspace/stack
|
||||
# Disable the general shell before admin/user allowlist resolution. Delivery
|
||||
@@ -32,6 +32,6 @@ services:
|
||||
target: ${MOSAIC_DOGFOOD_COMMON_GIT_DIR:?set to the canonical stack clone .git directory}
|
||||
# Only this seat home enters the container. Other fleet credentials stay outside.
|
||||
- type: bind
|
||||
source: ${MOSAIC_DOGFOOD_SEAT_HOME:?set to the external stack-dogfood seat directory}
|
||||
target: /opt/mosaic/brain/fleet/agents/stack-dogfood
|
||||
source: ${MOSAIC_DOGFOOD_SEAT_HOME:?set to the external code-dogfood-01 seat directory}
|
||||
target: /opt/mosaic/brain/fleet/agents/code-dogfood-01
|
||||
read_only: true
|
||||
|
||||
@@ -61,8 +61,8 @@ assert gateway.get("init") is True, "gateway must run below an init process for
|
||||
env = gateway["environment"]
|
||||
|
||||
expected_env = {
|
||||
"MOSAIC_AGENT_NAME": "stack-dogfood",
|
||||
"MOSAIC_GIT_IDENTITY": "stack-dogfood",
|
||||
"MOSAIC_AGENT_NAME": "code-dogfood-01",
|
||||
"MOSAIC_GIT_IDENTITY": "code-dogfood-01",
|
||||
"MOSAIC_BRAIN_HOME": "/opt/mosaic/brain",
|
||||
"AGENT_FILE_SANDBOX_DIR": "/workspace/stack",
|
||||
"AGENT_SHELL_ENABLED": "false",
|
||||
@@ -98,7 +98,7 @@ assert common_git["type"] == "bind"
|
||||
assert common_git["source"] == os.environ["EXPECT_COMMON_GIT"]
|
||||
assert not common_git.get("read_only", False), "common Git directory must accept branch updates"
|
||||
|
||||
seat = mounts["/opt/mosaic/brain/fleet/agents/stack-dogfood"]
|
||||
seat = mounts["/opt/mosaic/brain/fleet/agents/code-dogfood-01"]
|
||||
assert seat["type"] == "bind"
|
||||
assert seat["source"] == os.environ["EXPECT_SEAT"]
|
||||
assert seat.get("read_only") is True, "seat credential slot must be read-only"
|
||||
@@ -107,7 +107,7 @@ other_seat_mounts = [
|
||||
target
|
||||
for target in mounts
|
||||
if target.startswith("/opt/mosaic/brain/fleet/agents/")
|
||||
and target != "/opt/mosaic/brain/fleet/agents/stack-dogfood"
|
||||
and target != "/opt/mosaic/brain/fleet/agents/code-dogfood-01"
|
||||
]
|
||||
assert other_seat_mounts == [], f"other seat mounts leaked: {other_seat_mounts}"
|
||||
PY
|
||||
|
||||
Reference in New Issue
Block a user