Dev tooling: container_tinker and container_db_read broken for this project #58
Labels
No labels
bug
duplicate
enhancement
good first issue
help wanted
question
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lvl0/incr#58
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two
container-devMCP tools do not work against incr, which has blocked verification on #49 and #50.container_db_read— wrong client binaryThe tool invokes a
mariadbclient, but incr's db container isdocker.io/library/mysql:8.0(docker/dev/docker-compose.yml:26), which shipsmysql, notmariadb. Works for sibling projects on MariaDB (ffr usesmariadb:11), so the tool appears to assume MariaDB.container_tinker— silently returns nothingEvery expression returns
(no output), including trivial ones. Worse, it appears to execute anyway while reporting nothing: during #50 the migration was run via tinker, produced no output, and a laterdev-artisan migratereportedNothing to migrate— so it had in fact applied.A tool that runs code but reports nothing is worse than one that fails loudly. Two consequences hit during #50:
SUM(quantity)→trackers.countbackfill against real datadown()) works, so that path is verified by reading onlyImpact
With both broken and the
no-container-clihook (correctly) blocking directpodman exec/docker composecalls, there is no working path to inspect the dev database or run an arbitrary artisan command. Verification falls back to the test suite (which only proves migrations work on an empty schema viaRefreshDatabase) or manual browser checks.Suggested fix
container_db_read: detect the db image, or trymysqlthen fall back tomariadbcontainer_tinker: surface stdout/stderr; fail loudly rather than returning empty on errorNote this is tooling config outside the app repo — this ticket tracks it, but the fix likely belongs in the
container-devMCP server config rather than here.Fixed — in
~/.local/share/mcp/container-dev/server.pyBoth tools work now. No changes to this repo — the fix is entirely in the MCP server, as the ticket predicted.
container_db_read— root cause_run_db_query()had this, unconditionally, for every non-postgres project:Both the client binary and ffr's root password were hardcoded. It would have failed on any MariaDB project other than ffr too, not just on incr's MySQL.
Fixes:
_classify_service()now distinguishesmariadbfrommysqlby image rather than lumping both under"mysql"MYSQL_ROOT_PASSWORD/MARIADB_ROOT_PASSWORDand*_DATABASE_resolve_env()resolves compose${VAR},${VAR:-default}and${VAR-default}interpolation — ffr's password is${DB_ROOT_PASSWORD:-ffr_root_dev}, which would otherwise have been passed through literallyERROR 1046: No database selected)container_tinker— root causetinker --executediscards return values; it only emits what the code explicitly prints. Everyreturn ...;expression ran correctly and reported nothing — which is exactly why the migration in #50 applied while appearing to do nothing.Fixes:
return X;is rewritten todump(X);so the value surfaces.echoand multi-statement expressions are unaffected.dump()'s psysh source annotation is stripped from output(expression ran; no output — use return or echo to see a value)instead of nothingVerified
ffr regression check — resolves to
mariadb/ffr_root_dev, exactly the old hardcoded values, plus it now selects theffr_devdatabase, which the previous code did not. No regression.Incidentally this confirms the v0.4.0 schema from the database itself:
trackersis the only application table. Nousers,sessions,entries,milestones,assetsorasset_prices.⚠️ Two caveats
The MCP server is not under version control.
~/.local/share/mcp/container-dev/is not a git repo, so these edits have no history and no rollback path. Worth putting under git.A Claude Code restart is required for the changes to load — the server process starts once per session. Calls in this session still hit the old code.