ROOT CAUSE (kohen Day-3 escalation):
None of the four Dockerfiles pinned --platform. Build on Apple Silicon
shipped arm64-only images to a registry consumed by amd64 SKS nodes.
Init container failed exec format error before producing logs.
DOCKERFILE FIX (defense in depth):
Pin --platform=linux/amd64 on every FROM line in all four Dockerfiles.
The build artifact now self-corrects regardless of build host.
AZAZEL CO-RESIDENCE (anomaly the kohen flagged):
Azazel L3 migration shipped (20260428…create_azazel_records.exs) but
no separate container existed. Reading the code: azazel_processor is
imported by korban_processor.external_offering at runtime in the same
Python process — not a separate process. Dockerfile.korban_processor
now COPYs azazel_processor/src/ alongside korban_processor.
Documented in the Dockerfile (AZAZEL CO-RESIDENT section) and in
deployment.yaml. Both containers (vav-pipeline + korban-processor)
now mount the shared tmp-shorashim volume so the Python→Elixir file
bridge (azazel_ingest.ex polls /tmp/shorashim/azazel/pending_l3/)
works end-to-end.
CANONICAL BUILD/PUSH (scripts/build_and_push.sh):
- Pins linux/amd64 by default; PLATFORMS env for multi-arch
- Pre-flight checks (repo root, buildx, registry login)
- Builds and pushes all four images with one command
- Closes the gap KOHEN_PROMPT.md gate 0i would otherwise leave open
KOHEN.md DRIFT (kohen recorded these as anomalies through Day 1-3):
- Line 58 hash fragment 99bbd07a…0a0187b → 99bbd07a…4ea377 (correct)
- Inheritance table: "Not yet created" claims rewritten as
"Verify before assuming" — a prior partial setup may have left
state, and the kohen prompt requires verifying not assuming
- L1 PV row: marked NOT REQUIRED (L1 baked into images)
- §Day 3a ConfigMap recipe marked vestigial (kept as comment)
- §Day 3b: removed manna-volume.yaml from kubectl apply list
(deployment uses emptyDir; PVC is for a future move)
- §Day 3c: "5 containers" → "4 containers + 1 init"
- §Day 3 fail-mode list expanded with the four most common causes,
in order, including exec format error → gate 0i
KOHEN_PROMPT.md:
- Gate 0f corrected to four images (talmudic-engine is image #3;
azazel is co-resident in korban-processor not a separate image)
- Gate 0i added: image-architecture vs node-architecture verification
before Day 1, with kubectl one-liner and docker manifest inspect
per image. Drift handler in the gates section: 0i FAIL → escalate
to builder, do not begin Day 1.
NO SPEC FILES TOUCHED:
Doorpost.verify_identity() still :ok — none of these files are in
@spec_files. No atomic spec+hash commit needed.
NEXT STEP FOR THE KOHEN:
Once these images are rebuilt and pushed via scripts/build_and_push.sh
(by anyone with the Harbor CLI secret + a working docker daemon),
restart from Day 1. Existing DB role shorashim_app, ALTER DEFAULT
PRIVILEGES, rotated DATABASE_URL, shorashim-config, and shorashim-
registry secret all remain valid across the restart.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
memory/infrastructure.md and memory/build_log.md held environment-
specific details — hostnames, IPs, account names, credentials
retrieval commands, local kubeconfig paths, operational status
notes. These don't belong in a project repo; by convention they
live in private operator notes.
Moved to ~/shorashim-operator-notes/ (private, outside git).
In their place, added deploy/ARCHITECTURE.md — a generic
description of the deployment shape: components, external
dependencies, configuration surface. No hostnames. No IPs.
No account names. Any competent operator can read it and
know how to deploy shorashim to their own infrastructure.
Updated cross-references in AGENTS.md and BUILD_KORBAN.md to
point to "the operator's private notes" instead of memory/.
Project repo is spec + implementation + deployment shape.
Operator notes are the kohen's personal log.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The gitea-mcp server expects GITEA_ACCESS_TOKEN environment variable,
not GITEA_TOKEN. Without the correct env var, every API call to the
backend Gitea returns "token is required" — the MCP server can't
authenticate to fetch user info, repos, etc.
Also added GITEA_HOST env var as a backup to the --host flag.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two fixes for the mcp.shorashim.ch deployment:
1. cert-manager ClusterIssuer had acme-v2 (wrong) instead of acme-v02
(correct). Let's Encrypt ACME directory is at
https://acme-v02.api.letsencrypt.org/directory
2. gitea-mcp HTTP probes timed out because GET /mcp hangs (SSE).
Switched to TCP socket probes on port 8080.
MCP server now responds correctly over HTTPS at mcp.shorashim.ch:
curl -X POST https://mcp.shorashim.ch/mcp -d '{...initialize...}'
returns {"result":{"serverInfo":{"name":"Gitea MCP Server"}}}
Also: nginx-ingress configmap needed strict-validate-path-type=false
to allow cert-manager HTTP-01 challenges. Applied via kubectl patch,
not tracked in git manifests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The gitea-mcp-server image has no entrypoint set (null).
Args were being interpreted as the executable name.
Added command: ["/app/gitea-mcp"] to invoke the binary correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shemot 28:3 — v'asu et bigdei Aharon l'kadesho l'chahano li.
The garments connect the service to those who approach.
- gitea-mcp-deployment.yaml: Official gitea-mcp server in HTTP mode
Connects to Gitea at 185.19.29.94 via PAT
- gitea-mcp-ingress.yaml: TLS ingress at mcp.shorashim.ch
cert-manager auto-provisions Let's Encrypt certificate
- gitea-mcp-secret.yaml: Template for Gitea PAT (never committed with value)
- cert-manager-issuer.yaml: Let's Encrypt ClusterIssuer
Architecture: claude.ai → OAuth → mcp.shorashim.ch → Gitea API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
L1 (29MB, 5860 files) is read-only and immutable — it belongs
inside the image, not on a separate volume. The scroll is sealed
in the aron. It ships with the vessel.
- All 4 Dockerfiles: COPY l1/ /mnt/torah/ in runtime stage
- deployment.yaml: Removed L1 PVC volume and all L1 volumeMounts
- deployment.yaml: Added imagePullSecrets for registry auth
- deployment.yaml: Manna uses emptyDir (kohen writes via kubectl cp)
- No CSI driver needed — eliminates Exoscale block storage dependency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All 4 images now reference exo.container-registry.com/the-recognition-protocol/:
- vav-pipeline:latest (111MB)
- shoresh-engine:latest (128MB)
- talmudic-engine:latest (292MB)
- korban-processor:latest (187MB)
Images built and pushed. The garments are in the registry.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
haskell:9.6.4-slim is based on Debian Buster, which reached EOL.
The standard deb.debian.org repos return 404. Redirected to
archive.debian.org for zlib1g-dev installation.
Verified: shoresh-engine image builds successfully (128MB).
All 4 Docker images now build:
vav-pipeline: 111MB
shoresh-engine: 128MB
korban-processor: 187MB
talmudic-engine: 292MB
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pyswip 0.2.11 was never published to PyPI. Latest 0.2.x is 0.2.10.
Changed pin from ==0.2.11 to ==0.2.10.
Verified: korban-processor image builds successfully (187MB).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>