docs: add known-issues.md and runbooks/local-dev-setup.md
Recovered from prior work. Previously pushed commit 03c6929 was lost during reset-to-origin/main divergence resolution. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2ca6ed7dc0
commit
335474b71b
141
known-issues.md
Normal file
141
known-issues.md
Normal file
@ -0,0 +1,141 @@
|
||||
# Known Issues — claude-code Workspace Template
|
||||
|
||||
This document tracks unresolved and partially-resolved issues that are known to occur when
|
||||
running this workspace template. Each entry includes the symptom, affected versions,
|
||||
workaround, and (where applicable) a link to the upstream or internal tracker.
|
||||
|
||||
---
|
||||
|
||||
## 1. `CLAUDE_CODE_OAUTH_TOKEN` Missing Causes Silent Auth Failures
|
||||
|
||||
**Severity:** High
|
||||
**Affects:** All template versions.
|
||||
|
||||
**Symptom:**
|
||||
The agent starts but immediately fails to call the LLM with:
|
||||
|
||||
```
|
||||
anthropic.AuthenticationError: Incorrect API key provided
|
||||
```
|
||||
|
||||
or, in platform-managed environments:
|
||||
|
||||
```
|
||||
401 Unauthorized — Bearer token invalid or expired
|
||||
```
|
||||
|
||||
**Root cause:**
|
||||
`config.yaml` requires `CLAUDE_CODE_OAUTH_TOKEN` but the adapter has no API-key
|
||||
fallback. If the environment variable is unset, empty, or expired, the LLM client
|
||||
uses an empty/bogus credential and the first turn fails.
|
||||
|
||||
**Workaround:**
|
||||
Set the token before starting the adapter:
|
||||
|
||||
```bash
|
||||
export CLAUDE_CODE_OAUTH_TOKEN="your-oauth-token-here"
|
||||
python adapter.py
|
||||
```
|
||||
|
||||
For platform-managed workspaces, ensure the token is injected via the workspace
|
||||
environment configuration in the Molecule platform dashboard.
|
||||
|
||||
**Fix:** The adapter should emit a startup warning if `CLAUDE_CODE_OAUTH_TOKEN` is
|
||||
empty or absent. Tracked in internal ticket MOL-XXXX.
|
||||
|
||||
---
|
||||
|
||||
## 2. HEARTBEAT Not Emitted — Platform Shows "Silent" Status
|
||||
|
||||
**Severity:** Medium
|
||||
**Affects:** All template versions prior to explicit HEARTBEAT wiring.
|
||||
|
||||
**Symptom:**
|
||||
The Molecule platform activity dashboard shows the workspace as "silent" even
|
||||
though the agent is actively processing tasks. No heartbeat events arrive at the
|
||||
platform. The platform may timeout the workspace as inactive.
|
||||
|
||||
**Root cause:**
|
||||
The `entrypoint.sh` launches the adapter but does not configure a HEARTBEAT
|
||||
interval. The platform relies on periodic POSTs to `/api/v1/heartbeat` to confirm
|
||||
liveness. Without this, long-running agent tasks (> ~60s) may trigger platform
|
||||
timeouts.
|
||||
|
||||
**Workaround:**
|
||||
Set `HEARTBEAT_INTERVAL_SECONDS` in the environment (if supported by the adapter):
|
||||
|
||||
```bash
|
||||
export HEARTBEAT_INTERVAL_SECONDS=30
|
||||
python adapter.py
|
||||
```
|
||||
|
||||
Or, if the adapter does not support this env var, keep agent tasks short (< 60s)
|
||||
or use `delegate_task_async` to return control immediately.
|
||||
|
||||
**Fix:** The adapter should emit a HEARTBEAT event every 30 seconds when running
|
||||
in platform mode. A future template update will add explicit HEARTBEAT wiring.
|
||||
|
||||
---
|
||||
|
||||
## 3. `system-prompt.md` Customisations Overwritten on Template Update
|
||||
|
||||
**Severity:** Medium
|
||||
**Affects:** Users who customise `system-prompt.md` directly in the workspace.
|
||||
|
||||
**Symptom:**
|
||||
After pulling a new template version (e.g. `git pull` in a persistent workspace),
|
||||
the agent's behaviour changes unexpectedly even though `config.yaml` was not
|
||||
modified. On inspection, `system-prompt.md` has been overwritten with the
|
||||
template's canonical version.
|
||||
|
||||
**Root cause:**
|
||||
`system-prompt.md` is a template-managed file. When the platform rebuilds or
|
||||
refreshes the workspace container it copies files from the registered template
|
||||
tag, overwriting any local customisations.
|
||||
|
||||
**Workaround — Option A (recommended):**
|
||||
Do not edit `system-prompt.md` directly. If the platform supports an override
|
||||
mechanism, use `MOLECULE_SYSTEM_PROMPT_OVERRIDE` environment variable or the
|
||||
`system_prompt_override` field in `config.yaml` (platform v1.2+).
|
||||
|
||||
**Workaround — Option B:**
|
||||
Fork the template and pin to a specific tag. Apply your customisations as patches
|
||||
on top of that tag.
|
||||
|
||||
---
|
||||
|
||||
## 4. `template_schema_version` Drift After Platform Upgrade
|
||||
|
||||
**Severity:** High
|
||||
**Affects:** Any workspace pinned to a schema version below the platform minimum
|
||||
after a platform upgrade.
|
||||
|
||||
**Symptom:**
|
||||
The adapter fails to start with:
|
||||
|
||||
```
|
||||
ValidationError: template schema version '1' is not supported.
|
||||
Minimum supported version: '2'. Please update config.yaml.
|
||||
```
|
||||
|
||||
**Root cause:**
|
||||
The Molecule platform increments the minimum supported `template_schema_version`
|
||||
when it makes backward-incompatible changes to the config format. Workspaces that
|
||||
pin an older schema version will fail validation immediately.
|
||||
|
||||
**Workaround:**
|
||||
After a platform upgrade, edit `config.yaml` and update the
|
||||
`template_schema_version` field to the new minimum reported in the platform's
|
||||
release notes:
|
||||
|
||||
```yaml
|
||||
template_schema_version: 2 # change from 1 to 2
|
||||
```
|
||||
|
||||
**Prevention:**
|
||||
Check the platform release notes before updating the platform. The release
|
||||
checklist in `CLAUDE.md` includes a step to review the platform's minimum
|
||||
schema version before tagging a new template release.
|
||||
|
||||
**Fix:** Once `template_schema_version` is updated, the adapter starts normally.
|
||||
No adapter code changes are required for schema-only bumps.
|
||||
220
runbooks/local-dev-setup.md
Normal file
220
runbooks/local-dev-setup.md
Normal file
@ -0,0 +1,220 @@
|
||||
# Runbook: Local Development Setup — claude-code Workspace Template
|
||||
|
||||
Use this runbook to set up a local development environment for the claude-code
|
||||
workspace template. It covers cloning, dependency installation, running the adapter
|
||||
outside Docker, overriding config for dev, building the container, and diagnosing
|
||||
common problems.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Requirement | Version | Notes |
|
||||
|---|---|---|
|
||||
| Python | 3.11+ | 3.12 recommended |
|
||||
| pip | 23+ | |
|
||||
| Docker | 24+ | |
|
||||
| Docker Compose | v2 (standalone or compose plugin) | |
|
||||
| Git | 2.40+ | |
|
||||
| `gh` CLI | 2.40+ | Required for agent autonomy features (git, gh operations) |
|
||||
| Molecule platform access | Token with `workspace:dev` scope | |
|
||||
|
||||
---
|
||||
|
||||
## Step 1 — Clone the Repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Molecule-AI/molecule-ai-workspace-template-claude-code.git
|
||||
cd molecule-ai-workspace-template-claude-code
|
||||
```
|
||||
|
||||
Always branch off `main` for local development:
|
||||
|
||||
```bash
|
||||
git checkout -b feat/your-feature-name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — Install Dependencies
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
If you encounter dependency conflicts with an existing virtual environment, create an
|
||||
isolated one:
|
||||
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate # Linux/macOS
|
||||
# .\.venv\Scripts\Activate.ps1 # Windows PowerShell
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
Verify the adapter is importable:
|
||||
|
||||
```bash
|
||||
python -c "from adapter import MoleculeClaudeCodeAdapter; print('OK')"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — Configure Environment Variables
|
||||
|
||||
The adapter requires `CLAUDE_CODE_OAUTH_TOKEN` to authenticate with the LLM.
|
||||
There is no API-key fallback — this variable must be set.
|
||||
|
||||
```bash
|
||||
# Required — OAuth token for the LLM provider
|
||||
export CLAUDE_CODE_OAUTH_TOKEN="your-oauth-token-here"
|
||||
|
||||
# Platform URL (required for agent task polling)
|
||||
export MOLECULE_PLATFORM_URL="https://platform.molecule.ai"
|
||||
|
||||
# Workspace instance ID (assigned by the platform)
|
||||
export MOLECULE_WORKSPACE_ID="ws-dev-local"
|
||||
|
||||
# Optional — override adapter log level
|
||||
export LOG_LEVEL=DEBUG
|
||||
|
||||
# Optional — HEARTBEAT interval in seconds (prevents platform timeout on long tasks)
|
||||
export HEARTBEAT_INTERVAL_SECONDS=30
|
||||
```
|
||||
|
||||
> **Security note:** Never commit `.env.local` to version control. Create a
|
||||
> `.env.local` file and ensure it is listed in `.gitignore`.
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Dev Overrides in `config.yaml`
|
||||
|
||||
The `config.yaml` shipped in the repo is production-oriented. For local dev,
|
||||
the recommended approach is to pass environment-variable overrides. Alternatively,
|
||||
create `config.dev.yaml` that the adapter merges on top of `config.yaml`:
|
||||
|
||||
```yaml
|
||||
# config.dev.yaml — local development overrides
|
||||
runtime_config:
|
||||
model: sonnet
|
||||
timeout: 300 # shorter timeout for faster dev cycles
|
||||
```
|
||||
|
||||
Apply dev overrides when running locally:
|
||||
|
||||
```bash
|
||||
python adapter.py --config config.yaml --config-override config.dev.yaml
|
||||
```
|
||||
|
||||
If the adapter does not support `--config-override`, set `MOLECULE_CONFIG_OVERLAY`
|
||||
to the path of the dev config file.
|
||||
|
||||
---
|
||||
|
||||
## Step 5 — Run the Adapter Locally
|
||||
|
||||
Start the adapter in foreground mode:
|
||||
|
||||
```bash
|
||||
python adapter.py
|
||||
```
|
||||
|
||||
Expected startup output:
|
||||
|
||||
```
|
||||
[molecule.adapter] INFO — resolved config template_schema_version=1
|
||||
[molecule.adapter] INFO — runtime: claude-code, model: sonnet
|
||||
[molecule.adapter] INFO — OAuth token: present
|
||||
[molecule.adapter] INFO — workspace ready, polling https://platform.molecule.ai/api/v1/tasks
|
||||
```
|
||||
|
||||
Press `Ctrl+C` to stop. For background operation:
|
||||
|
||||
```bash
|
||||
nohup python adapter.py > adapter.log 2>&1 &
|
||||
echo $! > adapter.pid
|
||||
```
|
||||
|
||||
Stop with:
|
||||
|
||||
```bash
|
||||
kill $(cat adapter.pid)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 6 — Test the Docker Build
|
||||
|
||||
Build the dev image:
|
||||
|
||||
```bash
|
||||
docker build \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
-t molecule-claude-code-workspace:dev \
|
||||
.
|
||||
```
|
||||
|
||||
Run a smoke test (adapter starts and reaches idle state):
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
--env CLAUDE_CODE_OAUTH_TOKEN \
|
||||
--env MOLECULE_PLATFORM_URL \
|
||||
--env MOLECULE_WORKSPACE_ID \
|
||||
molecule-claude-code-workspace:dev \
|
||||
python -c "
|
||||
from adapter import MoleculeClaudeCodeAdapter
|
||||
a = MoleculeClaudeCodeAdapter()
|
||||
a.load_config()
|
||||
print('smoke test PASSED')
|
||||
"
|
||||
```
|
||||
|
||||
Full Docker Compose stack:
|
||||
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
Logs:
|
||||
|
||||
```bash
|
||||
docker compose logs -f workspace
|
||||
```
|
||||
|
||||
Teardown:
|
||||
|
||||
```bash
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Issues Table
|
||||
|
||||
| Symptom | Likely Cause | Resolution |
|
||||
|---|---|---|
|
||||
| `401 Unauthorized — Bearer token invalid` | `CLAUDE_CODE_OAUTH_TOKEN` unset or expired | Set a valid token: `export CLAUDE_CODE_OAUTH_TOKEN=...` |
|
||||
| `anthropic.AuthenticationError` | Wrong token or token lacks required scopes | Verify token has `model:read` and `agent:invoke` scopes |
|
||||
| Adapter starts but never receives tasks | Wrong `MOLECULE_PLATFORM_URL` or token expired | Check URL; refresh token |
|
||||
| Platform shows "silent" after ~60s | No HEARTBEAT configured; platform timed out the workspace | Set `HEARTBEAT_INTERVAL_SECONDS=30`; upgrade adapter |
|
||||
| `docker build` fails with `Step N/12: RUN pip install...` | Network / pip index issue | Proxy through corporate firewall or mirror: `pip install --index-url https://pypi.org/simple/ -r requirements.txt` |
|
||||
| `docker run` exits immediately with code 0 | `CLAUDE_CODE_OAUTH_TOKEN` not set | Pass `-e CLAUDE_CODE_OAUTH_TOKEN` or `--env-file .env.local` |
|
||||
| `ValidationError: template schema version '1' not supported` | Platform minimum schema version increased | Update `template_schema_version` in `config.yaml` to match platform minimum |
|
||||
|
||||
---
|
||||
|
||||
## IDE Setup (VS Code)
|
||||
|
||||
```json
|
||||
// .vscode/settings.json — create in workspace root
|
||||
{
|
||||
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
|
||||
"python.analysis.typeCheckingMode": "basic",
|
||||
"files.insertFinalNewline": true,
|
||||
"[python]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "charliermarsh.ruff"
|
||||
}
|
||||
}
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user