KB-3874
PD Full Operationalization — 02 Endpoint Deploy/Bind/DRY_RUN
4 min read Revision 1
02 — Endpoint Deploy / Bind / true DRY_RUN (Workstream A) — COMPLETE
Decision: SAFE_TO_DEPLOY_INTERNAL (credential-reuse authorized by owner instruction this session).
Deploy
- Build context
/opt/incomex/deploy/agent-api-executor/(copied from stagedservice/;container-build-recipe.txt→Dockerfile). - Credential reused from incomex-agent-data →
secrets/agent-api-executor.env(chmod 600,OPENAI_API_KEY=sk-...). No new secret minted; no value printed to logs. - Image
agent-api-executor-local:v1. - Run:
docker run -d --name incomex-agent-api-executor --network docker_incomex -p 127.0.0.1:8090:8090 --read-only --tmpfs /tmp --cap-drop ALL --security-opt no-new-privileges:true --restart unless-stopped --env-file secrets/agent-api-executor.env -e PROCESS_DOT_EXECUTE_ENABLED=false -e PROCESS_DOT_REAL_RUN_ENABLED=false -e PROCESS_DOT_DRY_RUN_ONLY=true -e MOCK_PRODUCER=false -e AGENT_API_PROVIDER=openai -e AGENT_API_OPENAI_MODEL=gpt-4o agent-api-executor-local:v1 - Exposure: loopback host bind + internal docker network only. No
ports:on 0.0.0.0. No nginx route added.
Verification ladder (all passed)
/healthz→ ok; runtime execute=false/real=false/dry_only=true; mock_producer=false; writes_db=false./selfcheck(no LLM) → fixture self-check 7/7 pass.- real
/dispatchmode=DRY_RUN → produced gpt-4o explanation citing only subgraph ids (kgn:dieu39, kgn:dot_kg_family, kgn:explain_pair, kgn:provenance); verifier 5/5 pass;is_mock=false;provider=openai;writes_db=false. narrative sha256dd1aa6598f8c45c9bd79e480b100de89f4acc25c3df728e0cff806aee7d59f92. Evidence saved:…/process-discovery-endpoint-service-2026-06-04/evidence/dispatch_dryrun_output.json. - negative control:
REAL_RUN→ HTTP 403 refused.
Bind + governed DRY_RUN (sql/true_dryrun.sql, one txn)
UPDATE dot_agent_api_contract … endpoint_ref='http://incomex-agent-api-executor:8090/dispatch', mode='DRY_RUN', contract_status='endpoint_bound' WHERE dot_code='DOT_KG_EXPLAIN' AND endpoint_ref IS NULL(idempotent guard).fn_process_agent_api_dispatch('DOT_KG_EXPLAIN', corr, 'agent', 'DRY_RUN', true, corr)→ wrote SIMULATED_DRY_RUN runbe547609-…+ component; returnedendpoint_present=true, true_dry_run_possible=true, blocker=null.- Upgrade: SIMULATED_DRY_RUN run + component →
evidence_type='DRY_RUN', status completed,evidence_refaugmented with executor verdict (producer=agent_api, provider=openai, model=gpt-4o, is_mock=false, verifier_pass=true, sha256, upgrade_reason),output_ref=evidence file. correlation_iddryrun-kgexplain-20260604T081942Z.
Post-state (proven)
births 1,163,464 (==) · guard 129 (==) · DRY_RUN runs=1 · components DRY_RUN=1 · REAL_RUN=0 · contract DOT_KG_EXPLAIN=DRY_RUN/endpoint_bound/bound=t · dot:kg candidate_status_v6=dry_run_observed · verified set still only job:cut.
DOT_KG_EXPLAIN_VERIFY — intentionally NOT bound
The verifier is deterministic (verifier.py / fn_dryrun_fixture_selfcheck), not an LLM. Binding it to the LLM endpoint would be wrong. Left VERIFY_ONLY/unbound as an explicit owner decision (doc 05/06): keep agent_api vs re-classify deterministic. binding_status=partial_binding (1 bound / 1 intentionally unbound) is correct, not a gap.