Skip to content

ID-127 {127.3} TECH — adversarial review notes (S403)

{127.3} TECH review — verdict PASS_WITH_NOTES (S403)

Section titled “{127.3} TECH review — verdict PASS_WITH_NOTES (S403)”

Multi-lens adversarial review (3 lenses: per-BI fidelity · manifest/Q-EX2 correctness · resolution/operational risk → synthesis). Verdict: PASS_WITH_NOTES — zero blockers. TECH may proceed to {127.4} PLAN; every note below is a precision item the PLAN/Checker must fold in (not a TECH rewrite). Full verdict JSON: workflow run wf_662ded3b-ce9.

  1. BI-11 / BACKUP — verified inaccurate claim. lmdb-backup-cold.sh:57 hardcodes the literal suffix _cocoindex-state (LMDB_HOST_DIR=…/${APP_UUID}_cocoindex-state/_data/lmdb/mdb) — it is NOT derived from a renamed Platform volume. TECH’s “auto-derivation” wording is false; backup works ONLY with an explicit LMDB_HOST_DIR override. PLAN must carry an explicit LMDB_HOST_DIR=/var/lib/docker/volumes/<platform-uuid>_<volume-name>/_data/lmdb/mdb in the Platform backup env-file and correct the TECH wording.

  2. SYNC / volume-name coupling. The rsync dest (TECH <platform-uuid>_ca-cocoindex-platform-state) and the backup read-path (_cocoindex-state) DISAGREE on the volume name. PLAN must pick ONE volume name and apply it to BOTH the compose volume declaration AND the backup LMDB_HOST_DIR override. Sync and backup are coupled, not independent.

  3. BI-2 / deploy-dispatch collision. The prod deploy job fires on ref==main && (push || inputs.deploy=='true') (onprem-deploy.yml:356-357). The new Platform job must guard if: workflow_dispatch && inputs.deploy_platform=='true', AND the existing prod/staging guards must be extended with && inputs.deploy_platform != 'true' — else a Platform dispatch on main ALSO fires the client-prod deploy. PLAN must specify the full guard composition.

  4. BI-15 / parity guard + sentinel are NET-NEW. bl-346 has zero repo refs — there is no existing deploy/compose-parity substrate (only check-token-parity.ts for CSS + schema-parity.yml for DB, neither watches deploy/coolify/**). TECH’s “extend the existing parity-guard pattern” understates this: it is a brand-new compose-parity check (warn-only/non-required acceptable, per the token-parity posture). The .never-auto-deploy-sentinel is a Coolify SETTING, not a committed file — record it as an operator/Coolify-side standup step with an explicit verification note (a Checker cannot confirm it from source).

  5. HOST / isolation. A Coolify project is an organisational grouping, not a hard isolation primitive — the Platform rig shares one Docker daemon / Traefik / kernel / host FS with the client PROD + STAGING stacks. PLAN should add concrete guards (CPU/mem resource limits + disk quota on the Platform app, distinct Traefik router labels) rather than rely on “separate project = boundary”. The BI-9 intermittent shape + separate DB are genuine mitigations; the project-isolation framing is the soft link.

  6. SEED / sequencing + NOT-NULL. (a) The squash baseline creates application_types with NO seeded rows — the 6 types exist only if seed-platform-from-staging.ts has been RUN against zjqbrdctesqvouboziae. PLAN must sequence it as an explicit gating step (app_types → workspaces → feed_sources → feed_articles). (b) The feed seed undercounts NOT-NULL columns: feed_articles also needs external_url + title; feed_sources needs name + url

    • workspace_id (squash_baseline.sql:557-559, 6184-6188).
  7. BI-4 / PullMD residue (low risk). (a) adapters.py retains the live PULLMD_SERVICE_URL adapter, dormant only because the env is unset — the deploy artefact meets BI-4, but a container audit finds adapter code; one-line scope note. (b) feed_articles_extraction_method_check still enumerates pullmd_* values (squash_baseline.sql:6207) — the feed seed must NOT stamp a pullmd_* extraction_method; pick a non-pullmd value.

  8. BI-7 / manifest-mandatory — ACCURATE, correctly resolved (no action; for the Checker). app_main (flow.py:3403-3427) loads the manifest UNCONDITIONALLY once COCOINDEX_SOURCE_PATH is set and raises manifest_missing if absent — so “content slice ingests manifest-free” is false for the deployed entrypoint (the manifest-None branch is unit-test-only). TECH resolves WITHOUT a pipeline-code change by shipping a root manifest with forms-only mappings (content files → UnmappedPath soft-warn → route ‘content’). Nuance: the manifest gate also runs before the URL-source walk, so the single root manifest gates the FEED slice too (the feed slice is a separate FeedUrlSource that never hits resolve_route/UnmappedPath — the “feed soft-warn UnmappedPath” phrasing mischaracterises the feed mechanism, though one manifest still satisfies it). PLAN/Checker: add the absent-manifest-abort regression guard as the BI-7 gate. OQ-127-MANIFEST-RENAME is correctly escalated (ship .kh-workspace-map.json to match deployed code → bl-368).

  9. BI-7 / __qa__/ reserved-prefix hazard (operator corpus-construction). The pipeline has a frozen reserved prefix __qa__/ with a loud defensive belt: any file under __qa__/ that resolves to route ‘content’ (no qa_sidecar manifest mapping) emits qa_sidecar_route_missing and is ingested as junk content (flow.py:2021-2037). TECH’s manifest plan lists only the forms-slice mapping. PLAN must instruct the operator to either avoid the __qa__/ prefix in the synthetic corpus OR add an explicit qa_sidecar mapping for it.