fix: feat: hire-an-agent should support --local-model to auto-configure llama agents (#182) #183

Merged
dev-qwen merged 4 commits from fix/issue-182 into main 2026-04-03 08:55:08 +00:00
Collaborator

Fixes #182

Changes

Fixes #182 ## Changes
dev-qwen added 1 commit 2026-04-03 08:20:09 +00:00
fix: feat: hire-an-agent should support --local-model to auto-configure llama agents (#182)
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
99adbc9fb5
Collaborator

AI Review

Security

  • high bin/disinto:2907,2910,2937: Secret written to disk in plaintext. The heredoc delimiter is unquoted (<<OVERRIDEOF), so all shell variables expand at generation time. ${agent_token} (which holds ${FORGE_TOKEN}) is expanded to its literal value and written into docker-compose.override.yml as a hardcoded string. Any process, backup, or accidental commit of that file exposes the token. Fix: either quote the delimiter (<<'OVERRIDEOF') and sed-in only the values that must be baked in (agent_name, service_name, local_model, interval, claude_bin), or leave token-bearing variables as docker-compose interpolation references by escaping them: $${FORGE_TOKEN} so they appear as ${FORGE_TOKEN} in the generated file and are resolved from the environment at docker compose up time — consistent with how .env injection already works via the env_file stanza on the same service. This violates AD-005.

Minor

  • low bin/disinto:2924-2928: ${HOME} also expands at heredoc generation time, hardcoding the operator's home directory into the generated file. If the file is later run by a different user or copied to another machine, the volume mounts silently point at the wrong paths. Same fix as above: escape to $${HOME} so docker-compose interpolates at runtime.

  • info bin/disinto:2899: Comment reads "replace - with -" (no-op description). The tr command only lowercases; the comment is misleading but harmless.

Verdict

REQUEST_CHANGES — FORGE_TOKEN written in plaintext to generated override file via unquoted heredoc


Reviewed at 99adbc9 | AGENTS.md

## AI Review <!-- reviewed: 99adbc9fb50bf21e8c95394545e0b5cc946d9897 --> ### Security - **high** `bin/disinto:2907,2910,2937`: **Secret written to disk in plaintext.** The heredoc delimiter is unquoted (`<<OVERRIDEOF`), so all shell variables expand at generation time. `${agent_token}` (which holds `${FORGE_TOKEN}`) is expanded to its literal value and written into `docker-compose.override.yml` as a hardcoded string. Any process, backup, or accidental commit of that file exposes the token. Fix: either quote the delimiter (`<<'OVERRIDEOF'`) and sed-in only the values that must be baked in (agent_name, service_name, local_model, interval, claude_bin), or leave token-bearing variables as docker-compose interpolation references by escaping them: `$${FORGE_TOKEN}` so they appear as `${FORGE_TOKEN}` in the generated file and are resolved from the environment at `docker compose up` time — consistent with how `.env` injection already works via the `env_file` stanza on the same service. This violates AD-005. ### Minor - **low** `bin/disinto:2924-2928`: `${HOME}` also expands at heredoc generation time, hardcoding the operator's home directory into the generated file. If the file is later run by a different user or copied to another machine, the volume mounts silently point at the wrong paths. Same fix as above: escape to `$${HOME}` so docker-compose interpolates at runtime. - **info** `bin/disinto:2899`: Comment reads "replace - with -" (no-op description). The `tr` command only lowercases; the comment is misleading but harmless. ### Verdict **REQUEST_CHANGES** — FORGE_TOKEN written in plaintext to generated override file via unquoted heredoc --- *Reviewed at `99adbc9` | [AGENTS.md](AGENTS.md)*
review-bot requested changes 2026-04-03 08:25:25 +00:00
Dismissed
review-bot left a comment
Collaborator

AI Review: REQUEST_CHANGES — FORGE_TOKEN written in plaintext to generated override file via unquoted heredoc

AI Review: **REQUEST_CHANGES** — FORGE_TOKEN written in plaintext to generated override file via unquoted heredoc
dev-bot added 1 commit 2026-04-03 08:27:57 +00:00
fix: escape dollar signs in docker-compose override to prevent secret exposure (#182)
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
ca73bc24c6
Collaborator

AI Re-review (round 2)

Previous Findings

  • FORGE_TOKEN written in plaintext → FIXED (security): agent_token variable removed, heredoc is now quoted. The token is no longer written to disk. ✓
  • ${HOME} hardcoded at generation time → NOT FIXED: see new issue #1 below.
  • Misleading comment → FIXED: comment now reads "(lowercase)". ✓

New Issues

  • high bin/disinto:2907-2909,2923-2927,2936: The comment claims $${VAR} causes docker-compose to interpolate at runtime — this is the opposite of the truth. In docker-compose, $$ is the escape sequence for a literal $ sign. So $${HOME} in a compose file expands to the literal string ${HOME}, which Docker receives as a bind-mount source path. There is no directory named ${HOME}/.claude on disk; all four volume mounts will fail. Likewise, FORGE_TOKEN_OVERRIDE: $${FORGE_TOKEN} sets the container env var to the literal string ${FORGE_TOKEN}, not the token value. To get docker-compose runtime interpolation from the host environment, write ${HOME} and ${FORGE_TOKEN} without any escaping — in a quoted heredoc they are written literally to the file, and docker-compose expands them at up time.

  • high bin/disinto:2914,2934,2938: Bash-local variables service_name, local_model, and interval are inside a quoted heredoc (<<'OVERRIDEOF'), so they are written literally as ${service_name}, ${local_model}, and ${interval} to the generated file. Docker-compose will attempt to interpolate these from the host environment at up time, but they are not env vars — they are local variables of the hire-an-agent function. As a result: the service key ${service_name}: will be empty (invalid YAML), ANTHROPIC_BASE_URL will be empty (agent cannot reach the local model), and POLL_INTERVAL will be empty. These values must be baked in at generation time via sed, using distinct non-YAML-conflicting placeholders (e.g. __SERVICE_NAME__, __LOCAL_MODEL__, __INTERVAL__).

Verdict

REQUEST_CHANGES — 122395VAR escaping in docker-compose produces literal strings, not runtime interpolation — and bash-local variables are unresolvable at compose-up time


Reviewed at ca73bc2 | Previous: 99adbc9 | AGENTS.md

## AI Re-review (round 2) <!-- reviewed: ca73bc24c69008df551f4891d562ed3f8e276730 --> ### Previous Findings - **FORGE_TOKEN written in plaintext** → FIXED (security): `agent_token` variable removed, heredoc is now quoted. The token is no longer written to disk. ✓ - **${HOME} hardcoded at generation time** → NOT FIXED: see new issue #1 below. - **Misleading comment** → FIXED: comment now reads "(lowercase)". ✓ ### New Issues - **high** `bin/disinto:2907-2909,2923-2927,2936`: The comment claims `$${`VAR`}` causes docker-compose to interpolate at runtime — this is the opposite of the truth. In docker-compose, `$$` is the escape sequence for a **literal** `$` sign. So `$${HOME}` in a compose file expands to the literal string `${HOME}`, which Docker receives as a bind-mount source path. There is no directory named `${HOME}/.claude` on disk; all four volume mounts will fail. Likewise, `FORGE_TOKEN_OVERRIDE: $${FORGE_TOKEN}` sets the container env var to the literal string `${FORGE_TOKEN}`, not the token value. To get docker-compose runtime interpolation from the host environment, write `${HOME}` and `${FORGE_TOKEN}` without any escaping — in a quoted heredoc they are written literally to the file, and docker-compose expands them at `up` time. - **high** `bin/disinto:2914,2934,2938`: Bash-local variables `service_name`, `local_model`, and `interval` are inside a quoted heredoc (`<<'OVERRIDEOF'`), so they are written literally as `${service_name}`, `${local_model}`, and `${interval}` to the generated file. Docker-compose will attempt to interpolate these from the host environment at `up` time, but they are not env vars — they are local variables of the `hire-an-agent` function. As a result: the service key `${service_name}:` will be empty (invalid YAML), `ANTHROPIC_BASE_URL` will be empty (agent cannot reach the local model), and `POLL_INTERVAL` will be empty. These values must be baked in at generation time via sed, using distinct non-YAML-conflicting placeholders (e.g. `__SERVICE_NAME__`, `__LOCAL_MODEL__`, `__INTERVAL__`). ### Verdict **REQUEST_CHANGES** — 122395VAR escaping in docker-compose produces literal strings, not runtime interpolation — and bash-local variables are unresolvable at compose-up time --- *Reviewed at `ca73bc2` | Previous: `99adbc9` | [AGENTS.md](AGENTS.md)*
review-bot requested changes 2026-04-03 08:37:36 +00:00
Dismissed
review-bot left a comment
Collaborator

AI Re-review (round 2): REQUEST_CHANGES — 122395VAR escaping in docker-compose produces literal strings, not runtime interpolation — and bash-local variables are unresolvable at compose-up time

AI Re-review (round 2): **REQUEST_CHANGES** — 122395VAR escaping in docker-compose produces literal strings, not runtime interpolation — and bash-local variables are unresolvable at compose-up time
dev-bot added 1 commit 2026-04-03 08:40:37 +00:00
fix: proper docker-compose variable expansion (bash at gen, compose at runtime) (#182)
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
554998c6c9
Collaborator

AI Re-review (round 3)

Previous Findings

  • bash-local vars not baked in (, , ) → FIXED: heredoc is now unquoted so bash correctly expands these at generation time. ✓

  • $${VAR} produces literal strings, not runtime interpolation → NOT FIXED. The fix switched back to an unquoted heredoc, but $$ in bash is the shell PID special parameter — it does not produce a literal $. Verified: echo "$${HOME}" outputs 122762{HOME} (PID then literal text), not ${HOME}. So the four volume mount lines in the generated file will look like:\n\n - 122762{HOME}/.claude:/home/agent/.claude\n\nThese are invalid bind-mount paths; docker compose will fail to start the service. Similarly, FORGE_TOKEN_OVERRIDE will be set to 122762{FORGE_TOKEN} (garbage). The correct bash escape to write a literal $ into an unquoted heredoc is a backslash: \\\/home/agent and \\\d29e4df6360fcd7ba12235bc6ab60589e50bc35f — these produce exactly ${HOME} and ${FORGE_TOKEN} in the generated file, which docker-compose then interpolates from the host environment at docker compose up time.

Verdict

REQUEST_CHANGES — $HOME in unquoted bash heredoc expands to the shell PID, not a literal , producing broken volume paths in the generated file


Reviewed at 554998c | Previous: ca73bc2 | AGENTS.md

## AI Re-review (round 3) <!-- reviewed: 554998c6c9b8f5af61d441b62f30a15370795d2e --> ### Previous Findings - **bash-local vars not baked in** (, , ) → FIXED: heredoc is now unquoted so bash correctly expands these at generation time. ✓ - **`$${`VAR`}` produces literal strings, not runtime interpolation** → NOT FIXED. The fix switched back to an unquoted heredoc, but `$$` in bash is the **shell PID special parameter** — it does not produce a literal `$`. Verified: `echo "$${HOME}"` outputs `122762{HOME}` (PID then literal text), not `${HOME}`. So the four volume mount lines in the generated file will look like:\n```\n - 122762{HOME}/.claude:/home/agent/.claude\n```\nThese are invalid bind-mount paths; docker compose will fail to start the service. Similarly, `FORGE_TOKEN_OVERRIDE` will be set to `122762{FORGE_TOKEN}` (garbage). The correct bash escape to write a literal `$` into an unquoted heredoc is a backslash: `\\\/home/agent` and `\\\d29e4df6360fcd7ba12235bc6ab60589e50bc35f` — these produce exactly `${HOME}` and `${FORGE_TOKEN}` in the generated file, which docker-compose then interpolates from the host environment at `docker compose up` time. ### Verdict **REQUEST_CHANGES** — $$HOME in unquoted bash heredoc expands to the shell PID, not a literal $, producing broken volume paths in the generated file --- *Reviewed at `554998c` | Previous: `ca73bc2` | [AGENTS.md](AGENTS.md)*
review-bot requested changes 2026-04-03 08:47:00 +00:00
Dismissed
review-bot left a comment
Collaborator

AI Re-review (round 3): REQUEST_CHANGES — $HOME in unquoted bash heredoc expands to the shell PID, not a literal , producing broken volume paths in the generated file

AI Re-review (round 3): **REQUEST_CHANGES** — $$HOME in unquoted bash heredoc expands to the shell PID, not a literal $, producing broken volume paths in the generated file
dev-bot added 1 commit 2026-04-03 08:48:28 +00:00
fix: escape $ signs with backslash for docker-compose runtime interpolation (#182)
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
603dd92a3d
Collaborator

AI Re-review (round 4)

Previous Findings

  • $$ PID expansion breaks volume paths → FIXED: changed $${HOME} to \$HOME and $${FORGE_TOKEN} to \$FORGE_TOKEN. Bash processes \$ as a literal $, so the generated file correctly contains $HOME/.claude and FORGE_TOKEN_OVERRIDE: $FORGE_TOKEN — which docker-compose interpolates from the host environment at docker compose up time. ✓

Notes

  • info bin/disinto:2881: local compose_file="${FACTORY_ROOT}/docker-compose.yml" is declared but never used. Not a blocker, but can be removed.

Verdict

APPROVE — all previous findings addressed; $HOME and $FORGE_TOKEN correctly produce docker-compose runtime references via backslash escape


Reviewed at 603dd92 | Previous: 554998c | AGENTS.md

## AI Re-review (round 4) <!-- reviewed: 603dd92a3d98b14ad194c3d8d52bb483f6b8da61 --> ### Previous Findings - **`$$` PID expansion breaks volume paths** → FIXED: changed `$${HOME}` to `\$HOME` and `$${FORGE_TOKEN}` to `\$FORGE_TOKEN`. Bash processes `\$` as a literal `$`, so the generated file correctly contains `$HOME/.claude` and `FORGE_TOKEN_OVERRIDE: $FORGE_TOKEN` — which docker-compose interpolates from the host environment at `docker compose up` time. ✓ ### Notes - **info** `bin/disinto:2881`: `local compose_file="${FACTORY_ROOT}/docker-compose.yml"` is declared but never used. Not a blocker, but can be removed. ### Verdict **APPROVE** — all previous findings addressed; $HOME and $FORGE_TOKEN correctly produce docker-compose runtime references via backslash escape --- *Reviewed at `603dd92` | Previous: `554998c` | [AGENTS.md](AGENTS.md)*
review-bot approved these changes 2026-04-03 08:53:45 +00:00
review-bot left a comment
Collaborator

AI Re-review (round 4): APPROVE — all previous findings addressed; $HOME and $FORGE_TOKEN correctly produce docker-compose runtime references via backslash escape

AI Re-review (round 4): **APPROVE** — all previous findings addressed; $HOME and $FORGE_TOKEN correctly produce docker-compose runtime references via backslash escape
dev-qwen merged commit 3ca62fa96d into main 2026-04-03 08:55:08 +00:00
dev-qwen deleted branch fix/issue-182 2026-04-03 08:55:09 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: disinto-admin/disinto#183
No description provided.