מסמך מקור מתקדם. דפי ההתקנה, פרוטוקול ההפעלה וששת הסקילים זמינים לקריאה בעברית; קובץ המקור נשמר כפי שהוא.

V1 isolated integration ports — 2026-10-24

This slice implements offline policy contracts and injected adapters, not a live integration. No credentials, signing service, OAuth, Graph wrapper, network request, spreadsheet creation or active campaign method are included.

approval_v2.authorize_paused authenticates evidence through an injected verifier and binds tenant, account, Page, Form, exact positive budget, asset hashes, full spec digest, displayed full-spec digest and readable summary digest. Only create_new_paused is permitted, with identified approver and maximum 24-hour lifetime. The UI/executor must actually present both the summary and complete spec. The local Python object boundary is not security isolation. A deployment must separately prove that the agent cannot mint approvals, inject a verifier, reach signing secrets or bypass the executor via shell, connectors, workflows or raw API. test_only verifiers are rejected in customer-pilot mode; this is a contract check, not proof of infrastructure isolation. No signer ships in production code.

authorize_ingestion provides a separately verified, expiring, revocable ingestion scope bound to account/Page/Form, exact destination pair, allowed fields, owner, reporting and synthetic-only restriction. It does not authorize campaign creation, activation or edits of human-owned status. The deploying ingestion boundary must invoke it and validate every event against that scope; the offline Sheets transport alone is not an event authorization service.

PausedMetaExecutor.stage_campaign(spec, approval, now, write_id) validates verified leadgen terms acceptance, new entities and PAUSED at campaign/adset/ad levels before invoking MetaPort.create_new_paused. It reads back exact IDs, binding, digest and statuses. Any ambiguous write/readback halts as UncertainWriteError; a provider transport may raise BeforeWriteError only if it can guarantee no dispatch occurred. Preview remains explicitly unverified. The injected provider must normalize and validate complete entity configuration and parent relationships when constructing its readback digest, retain partial IDs durably, and never mutate existing assets. There is no live provider implementation. Current pilot metadata finding of leadgen_tos_accepted=false blocks writes; existing dated unrelated budget approval is not reusable.

CRMPort supports upsert_lead(record, write_id), reconcile(record, write_id) and set_status(record, write_id). SheetsAdapter additionally offers observe_status(record). Intake identity comprises tenant_id, source, source_lead_id; the stable source key hashes that tuple. The durable caller supplies a stable write_id before dispatch and records prepared/in-flight/confirmed/failed-safe/uncertain/confirmed_then_missing states. It must never call upsert again for an uncertain or confirmed-then-missing event. Empty reads, elapsed time and old worker fencing do not authorize retry. Reconciliation reports done only from exact positive target evidence, otherwise uncertain or conflict. No exactly-once guarantee is made.

Configure exact (spreadsheet_id, sheet_id) allowlist, tenant, bijective schema header mapping, intake fields and bounded max_rows. Transport read returns a header followed by rows; reaching the scan bound fails closed and requires an explicitly partitioned/paginated transport policy. No unbounded polling or quota retry is built in. Transport append/update must use RAW; formula-like untrusted text remains text. The caller must restrict a live transport to the precise allowlisted range and private synthetic test sheet. No live test was run.

Column ownership: machine owns stable identity/write/payload fields and configured intake fields. On first creation only, human columns initialize to חדש / טרם נבדק / blank owner, reason and notes. Replay preserves human changes. Intake cannot edit human columns. set_status is restricted to an explicit synthetic-status-test configuration plus is_test=true records. Every operation rescans schema and resolves source identity; row numbers are transient. Duplicate keys, malformed/changed headers, conflicting payload/write ID and missing confirmed rows block. Observation reports last observed fields without authenticated human identity or complete change history.

Sheets lookup followed by update is not atomic. Writers must be serialized by the durable worker and structural maintenance must pause writes; structure_controlled=True attests this deployment prerequisite but cannot enforce it against a sheet owner. Row movement between scans is handled; concurrent movement during update remains a deployment limitation and readback uncertainty, not a promise of safety against an unrestricted owner. Keep maintenance, revocation, scan limits and monitoring part of the pilot gate.

Verification: python3 -m unittest discover -s tests -p test_integrations_v2.py -v — 13 offline failure-oriented tests passed. Fixture transports perform no network or credential access. Tests cover forgery, expiry, binding mutation, live test-verifier refusal, ACTIVE/existing-entity/ToS refusal, RAW text, replay ownership, duplicate keys, schema mutation, moved/deleted rows, bounded reads, definitely-unsent failure, quota read failure, revoked/changed ingestion scope, separate campaign authority and timeout-after-append positive reconciliation.