Plan: Phase 1 DCT Work — uis Shim + Namespace/Secret Flags
IMPLEMENTATION RULES: Before implementing this plan, read and follow:
- WORKFLOW.md - The implementation process
- PLANS.md - Plan structure and best practices
Status: Active
Goal: Ship DCT's two Phase 1 items from INVESTIGATE-improve-template-docs-with-services.md: (1.8) the uis shim that lets users type bare uis ... commands inside DCT, and (1.9) updates to dev-template-configure to pass --namespace and --secret-name-prefix to UIS.
Priority: High — 1.8 unblocks TMP's README rewrites; 1.9 fixes the deploy-time crash-loop bug.
Last Updated: 2026-04-09
Investigation: helpers-no/dev-templates → INVESTIGATE-improve-template-docs-with-services.md (active)
Cross-team dependencies:
- 1.8: zero dependencies, can start immediately
- 1.9: depends on UIS 1.10 (
uis configure --namespace/--secret-name-prefixflags + new JSON fields)
Overview
The Phase B integration work (completed 2026-04-06) confirmed the architecture works end-to-end, but real-user testing of python-basic-webserver-database surfaced UX problems:
-
C2: "uis: command not found" from inside DCT. Users see
uis configurein docs and try to run it. The CLI lives inside theuis-provision-hostcontainer — not in DCT. The workaround isdocker exec uis-provision-host uis ...everywhere, which makes READMEs unreadable. -
Deploy-time crash-loop. The template's
deployment.yamlreferences a Kubernetes Secret ({{REPO_NAME}}-db) that doesn't exist in the cluster. ArgoCD deploys the app, the pod tries to read the secret, fails, crash-loops.
This plan ships the DCT half of the fix.
Phase 1: The uis shim (1.8) — IN PROGRESS
Tasks
- 1.1 Add
uis_bridge_run_tty()function to.devcontainer/manage/lib/uis-bridge.sh:uis_bridge_run_tty() {
docker exec -it "$UIS_CONTAINER" uis "$@"
} - 1.2 Created
.devcontainer/manage/uis.shwith TTY/stdin/no-TTY routing + help fast path#!/bin/bash
# /usr/local/bin/uis — DCT shim for the UIS CLI
set -e
source /opt/devcontainer-toolbox/manage/lib/uis-bridge.sh
# Fast path: help/no-args output is local-only — don't require UIS container
case "${1:-}" in
""|help|--help|-h)
# Print DCT-flavoured usage that mentions the shim
# Falls back to running 'uis help' if container is up; otherwise shows local message
if uis_bridge_check 2>/dev/null; then
uis_bridge_run_tty "$@"
else
cat <<'EOF'
uis — UIS CLI (proxied from DCT via docker-outside-of-docker)
Usage: uis <command> [args]
This is a DCT shim that forwards commands to the uis-provision-host
container. UIS provides commands for managing data services, deployments,
templates, and more.
Common commands (require uis-provision-host running):
uis status Show status of all UIS components
uis deploy <service> Deploy a service (postgresql, redis, ...)
uis configure <service> Configure a service for an app
uis connect <service> Connect to a service (psql, redis-cli, ...)
uis template install <id> Install a UIS stack template
uis expose <service> Expose a service via port-forward
⚠️ uis-provision-host container is not running.
Start it from the urbalurba-infrastructure repo.
EOF
exit 0
fi
;;
*)
uis_bridge_check || exit 1
if [ -t 0 ] && [ -t 1 ]; then
uis_bridge_run_tty "$@"
elif [ ! -t 0 ]; then
uis_bridge_run_stdin "$@"
else
uis_bridge_run "$@"
fi
;;
esac - 1.3 Added
uissymlink inimage/Dockerfile(alongside config-host-info) - 1.4
chmod +xalready covered by existingchmod +x /opt/devcontainer-toolbox/manage/*.shblock - 1.5 Test all four input modes (needs new image build):
- Interactive TTY:
uis status(should show formatted output, no garbled escape codes) - Piped stdin:
echo "SELECT 1;" | uis configure postgresql --init-file -(should work, no TTY allocated) - Non-TTY no stdin:
uis status > out.txt(should redirect cleanly) - Container down:
docker stop uis-provision-host && uis status(should print clear error) - Help fast path:
docker stop uis-provision-host && uis help(should print local help, exit 0)
- Interactive TTY:
Validation
uis help works regardless of UIS state. uis status, uis connect, uis configure work when UIS is running. README rewrites can drop the docker exec uis-provision-host noise.
Phase 2: dev-template-configure passes namespace + secret name prefix (1.9) — IN PROGRESS
UIS 1.10 shipped 2026-04-09 (PR #121, all 6 tester verification steps PASS).
Tasks
- 2.1 Resolved
namespacefrom${PARAMS[subdomain]:-${PARAMS[app_name]:-$GIT_REPO}}— done in_configure_service - 2.2 Resolved
secret_name_prefixfrom$GIT_REPO(matches deployment.yaml{{REPO_NAME}}-db) - 2.3 Pass both as new args via
extra_argsarray —uis_bridge_configurealready forwards them transparently - 2.4
uis_bridge_configurealready forwards arbitrary args via"$@"— no change needed - 2.5 Updated JSON parsing in
uis-bridge.sh: addedUIS_SECRET_NAME,UIS_SECRET_NAMESPACE,UIS_SECRET_ENV_VARglobals, parsed in bothokandalready_configuredbranches, reset on each call - 2.6 Updated completion message: shows
→ .env: DATABASE_URL=... (local)and→ K8s Secret: my-app-db in namespace my-app (cluster)when UIS returned secret fields. Falls back to writing.env.clusterfor legacy callers (no GIT_REPO, older UIS). - 2.7 Sourced
git-identity.shindev-template-configure.shand calldetect_git_identityearly to populateGIT_REPO
Validation
After running dev-template-configure on python-basic-webserver-database:
.envcontains a working local URLkubectl get secret <repo-name>-db -n <namespace>shows the secret existskubectl get namespace <namespace>shows the namespace exists- Re-running is idempotent (UIS returns
already_configured) - The secret's
DATABASE_URLkey matches the manifest'ssecretKeyRef - A pod deployed via
kubectl apply -f manifests/deployment.yamlwould NOT crash-loop on missing secret
Phase 3: Test end-to-end with TMP's rewritten templates
Tasks (after TMP finishes 1.5/1.6 README rewrites)
- 3.1 In a fresh DCT devcontainer with UIS running, follow the new
python-basic-webserver-databaseREADME literally:dev-template python-basic-webserver-database- Edit
template-info.yamlparams dev-template-configure- Run the Flask app, confirm
/tasksreturns seeded rows
- 3.2 Verify
uis connect postgresql <db>from the new "Verify" section works - 3.3 Verify
uis status postgresqlfrom the "Before you start" section works - 3.4 Verify
uis helpworks even when the UIS container is stopped - 3.5 Test
kubectl get secret <repo>-db -n <namespace>shows the secret with correct key
Validation
End-to-end happy path works with zero docker exec mentions in the README.
Acceptance Criteria
-
/usr/local/bin/uisexists and works as a transparent shim to UIS CLI -
uis_bridge_run_tty()function added tolib/uis-bridge.sh -
uis help/uis --help/uis -h/uis(no args) work without UIS container running - All other
uis ...commands fail clearly when container is down, work when up - Stdin pipe (
uis configure ... --init-file -) routes viadocker exec -iwithout TTY - Interactive TTY (
uis connect postgresql mydb) routes viadocker exec -it -
dev-template-configurepasses--namespaceand--secret-name-prefixto UIS -
uis-bridge.shreads new JSON fields (secret_name,secret_namespace,env_var) -
dev-template-configurecompletion message mentions both local and cluster secret - Re-run of
dev-template-configureis idempotent (UIS returnsalready_configured) - CI passes (static + unit + image build)
- Tested in fresh devcontainer with TMP's rewritten templates
Files to Create/Modify
New:
.devcontainer/manage/uis.sh— the shim
Modify:
.devcontainer/manage/lib/uis-bridge.sh— adduis_bridge_run_tty(), updateuis_bridge_configure()to forward new flags, update JSON parsing.devcontainer/manage/dev-template-configure.sh— resolve namespace + secret_name_prefix, pass to bridge, update completion messageimage/Dockerfile— adduissymlink
No template changes needed — Option A (use existing {{REPO_NAME}} placeholder) means the deployment.yaml stays as-is.
Cross-team coordination
| Item | DCT depends on | DCT blocks |
|---|---|---|
| 1.8 (shim) | Nothing | TMP 1.5, 1.6, 1.7, 1.12 (README rewrites) |
| 1.9 (--namespace) | UIS 1.10 (--namespace flag in uis configure) | Nothing — TMP READMEs reference the result, not the flag |
Recommended sequence (from TMP 7MSG):
- Day 1: DCT starts 1.8 (this plan Phase 1) in parallel with TMP and UIS
- Day 2-3: DCT 1.8 lands → TMP can rewrite postgresql-demo README
- Day 2-3: UIS 1.10 lands → DCT starts 1.9 (this plan Phase 2)
- Day 3-5: DCT Phase 3 verification once TMP READMEs are ready