Commit graph

325 commits

Author SHA1 Message Date
Claude
aeda17a601 chore: gardener housekeeping 2026-04-12
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-12 04:08:10 +00:00
9d778f6fd6 Merge pull request 'fix: vision(#623): disinto-chat conversation history persistence (#710)' (#730) from fix/issue-710 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-04-12 03:49:54 +00:00
Claude
6d148d669b fix: address AI review feedback - early-return guard and unused volume
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
2026-04-12 03:38:46 +00:00
Claude
dae15410ab fix: vision(#623): disinto-chat conversation history persistence (#710) 2026-04-12 03:38:46 +00:00
Claude
d367c9d258 fix: vision(#623): per-project subdomain fallback path (contingency) (#713)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 03:27:05 +00:00
Claude
3b4238d17f fix: vision(#623): disinto-chat cost caps + rate limiting (#711)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 03:06:06 +00:00
1ea5346c91 Merge pull request 'chore: gardener housekeeping' (#729) from chore/gardener-20260412-0243 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-04-12 03:05:03 +00:00
Claude
0bc027a25a chore: gardener housekeeping 2026-04-12
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-12 02:43:22 +00:00
Claude
ff79e64fc8 fix: exempt /chat/login and /chat/oauth/callback from forward_auth (#709)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Caddy forward_auth on /chat/* blocked unauthenticated users from
reaching the OAuth login/callback routes (401 instead of redirect).
Add explicit handle blocks for these public routes before the
forward_auth catch-all.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 02:37:43 +00:00
Claude
f8ac1d2ae2 fix: vision(#623): Caddy Remote-User forwarding + chat-side validation (defense-in-depth) (#709)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 02:21:02 +00:00
Claude
30e19f71e2 fix: vision(#623): Forgejo OAuth gate for disinto-chat (#708)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Gate /chat/* behind Forgejo OAuth2 authorization-code flow.

- Extract generic _create_forgejo_oauth_app() helper in lib/ci-setup.sh;
  Woodpecker OAuth becomes a thin wrapper, chat gets its own app.
- bin/disinto init now creates TWO OAuth apps (woodpecker-ci + disinto-chat)
  and writes CHAT_OAUTH_CLIENT_ID / CHAT_OAUTH_CLIENT_SECRET to .env.
- docker/chat/server.py: new routes /chat/login (→ Forgejo authorize),
  /chat/oauth/callback (code→token exchange, user allowlist check, session
  cookie). All other /chat/* routes require a valid session or redirect to
  /chat/login. Session store is in-memory with 24h TTL.
- lib/generators.sh: pass FORGE_URL, CHAT_OAUTH_CLIENT_ID,
  CHAT_OAUTH_CLIENT_SECRET, EDGE_TUNNEL_FQDN, DISINTO_CHAT_ALLOWED_USERS
  to the chat container environment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:52:16 +00:00
cf4e9983c2 Merge pull request 'fix: vision(#623): disinto-chat sandbox hardening (#706)' (#724) from fix/issue-706 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-04-12 01:41:00 +00:00
Claude
a8bf40d100 chore: gardener housekeeping 2026-04-12
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-12 01:16:08 +00:00
Claude
e74fc29b82 fix: vision(#623): disinto-chat sandbox hardening (#706)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:08:23 +00:00
Claude
eada673493 fix: vision(#623): disinto-chat container scaffold (no auth) (#705) 2026-04-12 00:46:57 +00:00
Claude
627496b6f2 fix: bug: architect-run.sh existing-PR check builds malformed URL — ${FORGE_API}/repos/… duplicates the repos segment (#717)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Introduce FORGE_API_BASE (bare API root without repo path) in lib/env.sh
and lib/load-project.sh. Replace all cross-repo curl calls in
architect-run.sh that incorrectly used ${FORGE_API}/repos/${FORGE_OPS_REPO}
(which expanded to .../repos/owner/repo/repos/owner/ops-repo) with
${FORGE_API_BASE}/repos/${FORGE_OPS_REPO}.

Also fix a same-repo label URL that duplicated the repos segment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:21:55 +00:00
2f75478aab Merge pull request 'fix: bug: architect-run.sh empty pitch — pitch_output=$(agent_run …) captures stdout but new agent_run writes to side-channels (#716)' (#720) from fix/issue-716 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-04-12 00:16:05 +00:00
545ccf9199 Merge pull request 'chore: gardener housekeeping' (#715) from chore/gardener-20260411-2343 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-04-12 00:13:13 +00:00
Claude
cb9381f1e4 fix: bug: architect-run.sh empty pitch — pitch_output=$(agent_run …) captures stdout but new agent_run writes to side-channels (#716)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Three fixes:

1. architect-run.sh:722 — extract `.result` not `.content` from claude JSON
   output. All other callers (dev-agent, formula-session) use `.result`;
   this was the direct cause of every pitch being empty.

2. lib/agent-sdk.sh — reset `_AGENT_LAST_OUTPUT=""` at the top of each
   `agent_run` call so stale data from a prior invocation can't bleed
   into the next caller when claude crashes or returns empty.

3. lib/agent-sdk.sh — scope the diagnostics file by `$LOG_AGENT` instead
   of hardcoding `dev/`. Concurrent agents (architect, gardener, planner,
   predictor) no longer clobber each other's diag output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:04:42 +00:00
Claude
bfdf252239 fix: vision(#623): Caddy subpath routing skeleton + Forgejo/Woodpecker host reconfig (#704)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
2026-04-11 23:48:54 +00:00
Claude
0cd20e8eea chore: gardener housekeeping 2026-04-11
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-11 23:43:09 +00:00
Claude
7dc03523d6 fix: bug: disinto-edge crashes on cold disinto up — clones from forgejo before forgejo HTTP is ready (#665)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:28:01 +00:00
Claude
9aeef51d9d fix: rename digested_files to batchfiles to pass agent-smoke function resolution
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
The CI smoke test's get_candidates awk pattern falsely matches
underscore-containing variable names (like digested_files+=) as
unresolved function calls. Rename to batchfiles to avoid the match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:17:47 +00:00
Claude
e1cdc78da0 fix: bug: profile journal digestion can hang for hours on local Qwen with many journals — blocks dev-agent (#702)
- Add digest-specific timeout (PROFILE_DIGEST_TIMEOUT, default 300s) instead
  of relying on the global 2h CLAUDE_TIMEOUT
- Cap journals per digest run (PROFILE_DIGEST_MAX_BATCH, default 5) to bound
  prompt size and let remaining journals drain over subsequent runs
- Only archive the journals that were actually included in the batch, not all
- On timeout/failure, preserve previous lessons-learned.md instead of leaving
  a near-empty file — journals stay unarchived for retry on next run
- Detect suspiciously small output (<=16 bytes) as failed digestion
- Add PROFILE_DIGEST_THRESHOLD env var (default 10) for digest trigger

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:17:47 +00:00
Claude
9acd0a2bc4 chore: gardener housekeeping 2026-04-11
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-11 22:28:49 +00:00
Claude
16477e69b0 fix: update AD-002 docs and stale comments to reflect CLAUDE_CONFIG_DIR isolation (#647)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
- AGENTS.md AD-002: document per-session CLAUDE_CONFIG_DIR as primary
  OAuth concurrency guard, CLAUDE_EXTERNAL_LOCK as rollback flag
- docker/agents/entrypoint.sh: update stale flock comment
- lib/agent-sdk.sh: move mkdir inside CLAUDE_EXTERNAL_LOCK branch

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:38:52 +00:00
Claude
810b083d53 fix: vision: remove external flock from lib/agent-sdk.sh once CLAUDE_CONFIG_DIR rollout is verified (#647)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Gate both flock call sites (agent_run main invocation and nudge) behind
CLAUDE_EXTERNAL_LOCK env var. Default off — the native Claude Code
proper-lockfile-based OAuth refresh lock handles concurrency. Set
CLAUDE_EXTERNAL_LOCK=1 to re-enable the external flock for rollback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:31:40 +00:00
0add73f409 Merge pull request 'fix: fix: ensure_ops_repo() should call migrate_ops_repo() to seed missing dirs (#688)' (#691) from fix/issue-688 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-04-11 21:25:55 +00:00
Claude
eb3327d2c9 chore: gardener housekeeping 2026-04-11
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-11 20:45:04 +00:00
Claude
3b1ca4a73a fix: ensure_ops_repo() should call migrate_ops_repo() to seed missing dirs (#688)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline failed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:40:36 +00:00
Claude
6d2e2e43f8 fix: config: gardener=1h, architect=9m, planner=11m for disinto factory (+ add PLANNER_INTERVAL env var) (#682)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
2026-04-11 17:47:07 +00:00
Claude
4347faf955 fix: feat: make gardener and architect schedules configurable via env vars (#558)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
2026-04-11 15:57:11 +00:00
Claude
3f66defae9 docs: update lib/AGENTS.md for env.sh preconditions and load-project.sh container path changes (#674)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 13:39:18 +00:00
Claude
6589c761ba fix: refactor: lib/env.sh — split into a defined-surface shared lib; entrypoints own context-specific paths (#674)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 13:21:30 +00:00
Claude
e933473848 fix: lib/git-creds.sh: repair_baked_cred_urls silently fails on agent-owned repos because it runs as root and trips dubious-ownership check (#671)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 08:27:42 +00:00
Claude
13b571c44c fix: lib/git-creds.sh + docker/edge/entrypoint-edge.sh: read $FORGE_PASS from env at git-runtime instead of baking it into the credential helper file (#669)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 07:55:06 +00:00
Claude
54d6e8b7b7 fix: bug: _profile_digest_journals writes lessons to the wrong file — real content lands in disinto-factory/lessons-learned.md, .profile gets the meta-summary (#663)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-11 06:07:32 +00:00
Claude
be406f193b fix: bug: dev-bot/.profile push fails with auth error — 91 journal commits stranded locally since ~2026-04-08 (#652)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-10 22:02:27 +00:00
Claude
9719d11d67 fix: bug: _profile_digest_journals never commits/pushes its output — knowledge folder appears empty on origin (#651)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-10 21:50:25 +00:00
Claude
9682ef0b2b fix: dev agents: distinct git author identity per bot container so commits are visibly attributable (#648)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-10 21:43:26 +00:00
Claude
4b6cc4afde fix: docker-compose.yml: switch .claude mounts to shared CLAUDE_CONFIG_DIR (#642)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
2026-04-10 20:32:07 +00:00
Claude
59e71a285b fix: disinto init: bootstrap shared CLAUDE_CONFIG_DIR for OAuth lock coherence (#641)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 20:15:35 +00:00
Claude
4757a9de7a fix: feat: move reverse tunnel into disinto-edge container with single-port forward (#622)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
- Dockerfile: add openssh-client + autossh to edge image
- entrypoint-edge.sh: start autossh reverse tunnel before Caddy when
  EDGE_TUNNEL_HOST is set; no-op when unset (local-only dev works unchanged)
- generators.sh: pass EDGE_TUNNEL_{HOST,USER,PORT,FQDN} env vars and
  bind-mount secrets/tunnel_key into the edge service

Decommission steps for old host-level reverse-tunnel.service:
  sudo systemctl disable --now reverse-tunnel.service
  sudo rm /etc/systemd/system/reverse-tunnel.service
  sudo systemctl daemon-reload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 19:51:03 +00:00
Claude
a0da97113b fix: bug: dev-poll stale detection ignores label scope — relabels in-progress bug-reports as blocked (#608)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Add issue_is_dev_claimable() helper to lib/issue-lifecycle.sh that checks
whether an issue's labels are compatible with dev-agent ownership. Labels
like bug-report, vision, in-triage, prediction/*, action, and formula
indicate another agent owns the issue.

In dev-poll.sh, replace the vision-only skip with the new helper so that
ALL non-dev labels are excluded from stale detection. This prevents
dev-poll from relabeling bug-reports (or other agent-owned issues) as
blocked while they are being triaged.

Also removes the now-redundant formula/prediction guard block in the
orphan section, since issue_is_dev_claimable covers those labels.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:10:58 +00:00
41f0210abf docs: document Claude Code OAuth concurrency model and external flock rationale (#637)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
## Summary

Adds `docs/CLAUDE-AUTH-CONCURRENCY.md` documenting why the external `flock` on `${HOME}/.claude/session.lock` in `lib/agent-sdk.sh` is load-bearing rather than belt-and-suspenders, and provides a decision matrix for adding new containers that run Claude Code.

Pure docs change. No code touched.

## Why

The factory runs N+1 concurrent Claude Code processes across containers (`disinto-agents` plus every transient container spawned by `docker/edge/dispatcher.sh`), all sharing `~/.claude` via bind mount. The historical "agents losing auth, frequent re-logins" issue that motivated the original `session.lock` flock is the OAuth refresh race — and the flock is the only thing currently protecting against it.

A reasonable assumption when looking at Claude Code is that its internal `proper-lockfile.lock(claudeDir)` (in `src/utils/auth.ts:1491` of the leaked TS source) handles the refresh race, making the external flock redundant. **It does not**, in our specific bind-mount layout. Empirically verified:

- `proper-lockfile` defaults to `<target>.lock` as a sibling file when no `lockfilePath` is given
- For `claudeDir = /home/agent/.claude`, the lock lands at `/home/agent/.claude.lock`
- `/home/agent/` is **not** bind-mounted in our setup — it is the container's local overlay filesystem
- Each container creates its own private `.claude.lock`, none shared
- Cross-container OAuth refresh race is therefore unprotected by Claude Code's internal lock

The external flock works because the lock file path `${HOME}/.claude/session.lock` is **inside** the bind-mounted directory, so all containers see the same inode.

This came up during design discussion of the chat container in #623, where the temptation was to mount the existing `~/.claude` and skip the external flock for interactive responsiveness. The doc captures the analysis so future implementers don't take that shortcut.

## Changes

- New file: `docs/CLAUDE-AUTH-CONCURRENCY.md` (~135 lines): rationale, empirical evidence, decision matrix for new containers, pointer to the upstream fix
- `lib/AGENTS.md`: one-line **Concurrency** addendum to the `lib/agent-sdk.sh` row pointing at the new doc

## Test plan

- [ ] Markdown renders correctly in Forgejo
- [ ] Relative link from `lib/AGENTS.md` to `docs/CLAUDE-AUTH-CONCURRENCY.md` resolves (`../docs/CLAUDE-AUTH-CONCURRENCY.md`)
- [ ] Code references in the doc still match the current state of `lib/agent-sdk.sh:139,144` and `docker/agents/entrypoint.sh:119-125`

## Refs

- #623 — chat container, the issue this analysis was driven by; #623 has a comment with the same analysis pointing back here once merged

Co-authored-by: Claude <noreply@anthropic.com>
Reviewed-on: #637
Co-authored-by: dev-bot <dev-bot@disinto.local>
Co-committed-by: dev-bot <dev-bot@disinto.local>
2026-04-10 18:01:18 +00:00
Claude
f4753b0ba1 fix: correct flock idiom to hold lock during claude invocation
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-10 17:48:33 +00:00
Claude
d6f93bb8f5 fix: fix flock/binding issues with claude_run_with_watchdog
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-10 17:41:39 +00:00
Claude
ec5eb48224 fix: fix: add idle-after-final-message watchdog around claude -p to mitigate upstream Claude Code hang (#606)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-04-10 17:33:56 +00:00
Claude
c3074e83fc fix: fix: agents container should clone project repo on first startup; treat init's host clone as operator-side only (#605)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
2026-04-10 17:19:33 +00:00
Claude
5c4ea7373a fix: fix: stop baking credentials into git remote URLs — use clean URLs + existing credential helper everywhere (#604)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:04:10 +00:00