Harmonia’s local stack uses the official Firestore and Pub/Sub emulators and exercises the same application contracts. Emulator success is not Google Cloud deployment evidence. This page describes the target topology; use the post-deploy checks and evidence runbook to prove a particular deployment.
Target topology
Firestore also owns the durable runtime’s tenant-scoped
operations, event_inbox,
stage_outbox, effect_commands, artifacts, context_projections, and recovery_work
collections. infra/setup.sh creates the composite index used to page expired operation
leases deterministically; firestore.indexes.json is the reviewable source definition.
Provisioning outline
infra/setup.sh also creates regional staging and durable-media buckets. The media bucket uses uniform access, grants object access only to the two runtime service accounts, and is injected as GCS_BUCKET by infra/deploy.sh. Deployment configures CORS for the resulting Cloud Run web origin so direct resumable uploads do not depend on ephemeral container storage.
Uploads additionally require a private malware scanner that accepts raw bytes and returns the strict
verdict contract documented in Configuration. Set MALWARE_SCANNER_URL and provision
malware-scanner-token to enable upload completion. Without both, the core YouTube workflow may be
deployed but uploaded objects remain quarantined and unavailable. This repository does not claim to
deploy or verify a scanner engine itself. Capture the engine identity and definition version from a
real clean scan before presenting uploaded-media operation as production evidence.
Create one runtime service account for each Cloud Run service. The worker needs roles/cloudtrace.agent, roles/logging.logWriter, and roles/monitoring.metricWriter; preserve the existing least-privilege data, messaging, and asset permissions. The web identity can sign only as itself for short-lived upload/download URLs. The Pub/Sub service agent receives token-creator authority only on that web identity so the private worker push subscription can authenticate with OIDC.
Setup also creates harmonia-scheduler. Deployment grants it roles/run.invoker only on the private
agent service and converges the harmonia-durable-autonomy Cloud Scheduler job to an every-minute
OIDC POST. Do not enable the legacy resident loops in Cloud Run; stage-outbox recovery, scheduled
publishing, proactive checks, and retention are driven by this durable external tick and protected by workspace leases.
Deployment also converges harmonia-durable-recovery, a separate OIDC-authenticated five-minute
wake for model-free recovery. Its scan limit, deadline, retry ceiling, and cost ceiling are explicit
environment values. The split makes missed-work recovery independently observable and prevents a
slow cognitive arm from delaying lease repair. Concurrent tick and recovery delivery is safe because
recovery rechecks leases transactionally and emits idempotent recovery-work identities.
Resident Heartbeat, Dream, and Wakeup schedules are separate and disabled by default. They are provisioned only when HARMONIA_ENABLE_RESIDENT_AUTONOMY=1; HARMONIA_WORKSPACE_TIMEZONE controls their timezone. This repository state is not evidence that those jobs are deployed. Keep the flag off during local and recorded-replay development.
Deploying
Both services use digest-pinned base images and exact dependency inputs:- Web app: standalone Next.js image from
Dockerfile - Worker: Python image from
agent/Dockerfileandagent/requirements.lock
infra/deploy.sh builds each image once with the source commit as its tag, resolves the Artifact Registry SHA-256 digest, and deploys that exact tag@digest. It then fails closed unless Cloud Run reports a revision and image digest, emitting one RELEASE_IDENTITY line per service for the private release log. The script does not deploy mutable tags or reuse a separately rebuilt demo image.
Set the configuration secrets as Cloud Run environment variables (Secret Manager for tokens). With PUBSUB_EMULATOR_HOST unset, both clients connect to real Google Cloud services automatically.
The deployment script sends each role model ID separately, including COPYWRITER_MODEL_ID for Noni and PRESENTER_MODEL_ID for Maya. Noni defaults to Gemini 3.5 Flash because ADK skill loading is part of the writing contract.
Noni’s brief-scoped public research uses ADK’s native Google Search grounding and
does not require Programmable Search credentials. Verified prior-publication
search remains available through the authenticated tenant-scoped internal API.
Deploy a fresh cognitive-hierarchy revision for every rollout that changes ADK agents, schemas, or skill definitions (agent/harmonia_agent/skills/ — the liaison’s skills load from the deployed package at import time), then point the Cloud Run worker at the returned resource:
AGENT_ENGINE_RESOURCE and MEMORY_BANK_RESOURCE (they may identify the same reasoning engine) before running infra/deploy.sh. The Cloud Run script does not update Agent Engine and must never be given a pre-change resource after the hierarchy gains a specialist such as maya_presenter. Cloud deployment always enables Memory Bank and fails before rollout when either managed resource is absent. Workspace and brand scopes come from each authenticated job rather than deployment configuration. To expose paid media proposals, set GENERATIVE_MEDIA_ENABLED=true. The worker identity already receives Vertex prediction access in infra/setup.sh; Memory Bank retrieval/generation and Veo/Lyria calls fail visibly if unavailable.
REGION is the deployment’s residency boundary. Setup verifies the Firestore database and Agent Engine staging bucket location and applies a Pub/Sub message-storage policy with in-transit enforcement. Deployment rejects Agent Engine, Memory Bank, or Veo resources outside that region. Lyria uses a global endpoint, so generative media fails closed unless ALLOW_GLOBAL_LYRIA=true records an approved policy exception. This is a technical location control, not a claim of regulatory certification.
The deployed worker does not contain process-resident scheduler, polling, or proactive supervisors. Cloud Scheduler drives the durable tick, and Firestore workspace leases plus stage/effect claims make concurrent delivery safe.
Enable Google as the Identity Platform provider and register the deployed web origin and redirect domain. Pass the registered web application’s public Identity Platform configuration to infra/deploy.sh. A user’s first Google sign-in creates the owner workspace automatically.
Health and observability
GET /healthzon the worker reports model id and registered stages- Worker and web health responses report only non-secret durable protocol/compiler capabilities; the worker also reports recovery bounds so a deployed revision can be checked against policy
- Pub/Sub push delivery has explicit 10-second minimum and 10-minute maximum retry delay, seven-day retention, five delivery attempts, and a regional dead-letter topic
- The job event log, receipts ledger, and verification records in Firestore provide end-to-end audit trails
- Every stage failure is classified permanent vs transient; transient failures rely on Pub/Sub redelivery
- W3C context crosses Pub/Sub and internal HTTP, correlating web, stage, agent, model, and validation spans
- Firestore usage records retain the trace ID, operation ID, role, model, usage units, cost estimate, and pricing version
/api/metricsaggregates model calls and estimated cost by role/model using integer microdollars- Google ADK exports structured logs, standard agent/tool/token metrics, and invocation/tool/model spans to the corresponding Google Cloud backends when telemetry is enabled
- Monitoring → Agent activity reads a tenant-scoped, metadata-only Firestore projection with server-side filters and opaque cursor pagination
agent_activity collection group using retentionDeleteAfter as the expiration field. The application writes a 30-day expiry timestamp, but Firestore does not delete expired documents until the TTL policy exists.
Content capture must remain disabled in every deployed revision. Raw prompts, responses, transcripts, draft text, and media bytes are excluded; observability records the execution graph and explicit validation/delegation metadata, not private reasoning.
Post-deploy verification checklist
Completing deployment commands is not acceptance. A deployment becomes claimable only when the observed resources and one authenticated run satisfy this checklist:- Create a job from the deployed dashboard URL and watch it reach
awaiting_approval. - Read one job usage record and copy its
traceId. - Locate the same trace in Cloud Trace; confirm the Pub/Sub stage, Agent Engine invocation, memory lookup, agent/model generation, and validation spans are correlated.
- Confirm span attributes contain identifiers and usage metadata but none of the job’s source or generated text.
- Compare the usage record’s estimate with
/api/metrics; keep platform estimates distinct from observed billing data. - Approve an action and confirm its receipt and independent verification record.
- Approve one Veo or Lyria proposal, confirm its cost reservation, provider-operation record, stored asset digest, usage record, and independent verification.
- Interrupt a worker after a durable boundary, invoke
harmonia-durable-recovery, and confirm the replacement attempt resumes with a newer epoch while the stale token is rejected.
