fix: say what Allow network access really opens (release review)

The setting told users the sandbox and approvals stay on. With it on, a
command in Codex's sandbox can call Codeman's API, which can start a session
outside the sandbox with no approval prompt. Measured on codex 0.162.0 with
`codex sandbox`: a touch the sandbox refused landed through POST /api/sessions,
and from inside a Codeman pane it landed with a password set too, because a
pane inherits CODEMAN_PASSWORD. Without that password the same call gets 401.

The settings row, the wiki, the skill and the changeset now say so, the wiki
Security page and security-architecture name it, and the docs scope the claims
to what the code does: app-wide, local launches only, not cron jobs, and
--no-daemon is a local launch's flag. Agent-CLIs gains the --no-daemon
trade-off. A test pins that no surface sells the sandbox as still in charge.

Text only: the switch, the clamp and the launch are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-06 03:25:00 +01:00
1 parent 131a12d195
commit 353fe7ebcf
11 files changed
+90 -35

No files matched your search

+23
View File
@@ -237,6 +237,29 @@ describe('App Settings modal structure', () => {
);
});
it('never sells Allow network access as leaving the sandbox in charge', () => {
// Measured 2026-11-06 on codex 0.162.0: with the network open, a command the sandbox
// refused (`touch` outside the workspace) landed by asking Codeman's API for a shell
// session, and from inside a Codeman pane it did so with a password set, because a pane
// inherits CODEMAN_PASSWORD. So "the sandbox and approvals stay on" is false comfort.
const modal = settingsModal();
const start = modal.indexOf('data-search="codex network access');
expect(start).toBeGreaterThan(-1);
const row = modal.slice(start, modal.indexOf('id="appSettingsCodexNetworkAccess"', start));
const read = (path: string) => readFileSync(resolve(import.meta.dirname, '..', path), 'utf8');
const referenceRow = read('docs/wiki/Settings-Reference.md')
.split('\n')
.find((line) => line.startsWith('| Allow network access'));
expect(referenceRow).toBeDefined();
const safetyClaim = /sandbox and approvals? (prompts )?stay on|keeps? (Codex's |the )?sandbox and approval/i;
for (const text of [row, referenceRow!, read('docs/wiki/Codeman-Skill.md'), read('skills/codeman/SKILL.md')]) {
expect(text).not.toMatch(safetyClaim);
}
for (const text of [row, referenceRow!, read('docs/wiki/Security.md')]) {
expect(text).toContain("Codeman's API");
}
});
it('has retired the modal-tab chrome everywhere, not just here', () => {
// Session Options and Add Case moved onto this same `set-*` surface, so the
// old tab classes have no users left. A reappearance means a modal drifted