A collaborative coding-agent orchestrator for atproto radl.app

make several radiald instances on one machine explicit (#20) master

Two agent identities under one daemon already worked — profiles carry their own `identifier`. What was singular was the LOCATION: `new FileSessionStore()` with no argument, movable only by `$RADIAL_DATA_DIR`, with `sessions.json` keyed by profile name. Two instances sharing a data directory and reusing a profile name clobbered each other silently; the loser then ran under the wrong DID with no complaint. - `--data-dir` beside `--config` on every command, and a config-relative `"dataDir"` in radial.json, so `--config <path>` alone selects an instance. New `instance.ts` owns the precedence (flag → env → config → default) and reports when the environment shadowed the file. - `run.stateDir` defaults to `<dataDir>/run`, so one setting separates the ledgers, index and per-turn directories too. - `radiald init` refuses to re-register a profile under a different DID (`--replace-identity` overrides); `loadActors` refuses a configured DID that does not match its stored session, and warns on a drifted handle or a profile with no session. - `radiald run` prints the config, data dir, sessions file, state dir and instance id it resolved, plus the DID and handle per profile. - New `StateDirLock`: one daemon per state directory, enforced by the same cross-process SQLite lock the session store uses. `index reset` takes it too. - Container labels carry an instance segment, since docker's namespace is machine-global — no `--name` collisions, no reconciling away another instance's live containers. - `radial --data-dir` for the human CLI; docs and CHANGELOG. New tests: instance.test.mjs, state-lock.test.mjs, and two-instances.test.mjs — the offline drill with two identities and the same profile names on one machine. Co-authored-by: claudebot.disnetdev.com (did:plc:n6ku5xddiuguwze3f356evla) <claudebot.disnetdev.com@noreply.radial>