{"apiVersion": "openeyes.nails.web.v1", "boundary": "go_live_provider_collector_return_completion_local_only", "collectionExecutionEnabled": false, "completionBoundary": {"acceptsInlineRecordsBatch": true, "acceptsProviderCrawlJobManifest": true, "acceptsProviderCrawlJobManifestUri": true, "acceptsRecordsBatchUri": true, "advancesLocalGoLiveTracker": true, "authorizesProviderCrawlJobManifest": true, "collectionExecutionEnabled": false, "deployEnabled": false, "generatesCollectorRecords": false, "importsDesignFusionDryRun": true, "liveCollectionEnabled": false, "mode": "provider_collector_return_completion_local_files_inline_records_uri_or_manifest", "network": false, "normalizesReturnedRawSources": true, "productionMutations": false, "readsLocalFiles": true, "secretMaterialReturned": false, "submitEnabled": false, "uploadEnabled": false, "validatesFilledCollectorRecords": true, "writesLocalAuditState": false, "writesLocalFiles": true}, "completionContractPath": "/api/web/v1/plugins/nails/production-cutover:provider-collector-return-contract", "completionPath": "/api/web/v1/plugins/nails/production-cutover:provider-collector-return", "contract": {"additionalProperties": false, "contractVersion": 1, "inputModes": ["default_latest", "local_path", "inline_json", "uri", "provider_crawl_job_manifest_inline_json", "provider_crawl_job_manifest_uri"], "methods": ["POST"], "name": "nails-production-cutover-provider-collector-return", "objectUriReader": {"acceptedPayloadKinds": ["nails.normalized_crawl_records_batch", "nails.provider_crawl_job_manifest"], "acceptedSchemes": ["gs", "oss"], "bucketAllowlistEnv": ["MALIANG_NAILS_RESOURCE_BUCKETS", "NAILS_AUDIT_EVIDENCE_BUCKET", "NAILS_SOURCE_ASSETS_BUCKET", "NAILS_DESIGN_PACKAGES_BUCKET", "NAILS_PUBLIC_ASSETS_BUCKET"], "defaultMode": "local_object_uri_mirror", "gcsModeEnv": "NAILS_WEB_GCS_URI_READ_ENABLED=1", "mirrorRootField": "objectUriMirrorRoot", "payloadKind": "nails.normalized_crawl_records_batch"}, "optionalFields": ["recordsBatch", "recordsBatchInline", "recordsBatchUri", "providerCrawlJobManifest", "providerCrawlJobManifestUri", "objectUriMirrorRoot", "sourceManifest", "handoffDir", "outputDir", "stateRoot", "objectRoot", "collectorRole", "crawlExportUriPrefix", "envMode", "now", "replace", "compactOutputFiles"], "providerCrawlJobManifestAuthorization": {"adapterJobAuthorizationFields": ["adapterId", "adapterVersion", "providerId", "market", "platform", "collectionMethod"], "adapterRegistryPath": "/api/web/v1/plugins/nails/crawl-adapters", "capabilityKind": "nails.provider_crawl_adapter_plugin", "policyId": "nails-crawl-adapters-v1", "requiredCollectorRuntime": "external_read_only_collector", "requiredRightsBoundary": {"collectionExecutionByNailsWeb": false, "liveCollectionAlreadyCompleted": true, "networkByNailsWeb": false}}, "requiredFields": ["startBundle"], "schemaDigest": "baab85bc789aaad30662d03883ad18e1e65a261b7ab5eafb3d0c3ad5559634cf", "schemaId": "https://openeyes.local/plugins/nails/web/v1/production-cutover-provider-collector-return-request.schema.json"}, "deployEnabled": false, "links": {"providerCollectorWorkspace": {"contractPath": "/api/web/v1/plugins/nails/production-cutover:provider-collector-workspace-contract", "method": "POST", "network": false, "path": "/api/web/v1/plugins/nails/production-cutover:provider-collector-workspace"}, "realEvidenceEntryConfirmedWrite": {"contractPath": "/api/web/v1/plugins/nails/production-cutover:real-evidence-entry-confirmed-write-contract", "evidenceEntryId": "provider_collector_return", "method": "POST", "network": false, "path": "/api/web/v1/plugins/nails/production-cutover:real-evidence-entry-confirmed-write"}, "stagingExecutionPacketAudit": {"contractPath": "/api/web/v1/plugins/nails/production-cutover:staging-execution-packet-audit-contract", "method": "POST", "network": false, "path": "/api/web/v1/plugins/nails/production-cutover:staging-execution-packet-audit"}}, "liveCollectionEnabled": false, "localWrapper": {"collectionExecutionEnabled": false, "commandTemplate": "rtk python scripts/nails_complete_go_live_provider_collector_return.py --start-bundle <startBundle> --records-batch <filledRecordsBatch> --handoff-dir <handoffDir> --output-dir <outputDir>", "deployEnabled": false, "liveCollectionEnabled": false, "network": false, "productionMutations": false, "providerCrawlJobManifestCommandTemplate": "POST /api/web/v1/plugins/nails/production-cutover:provider-collector-return with startBundle, providerCrawlJobManifest or providerCrawlJobManifestUri, handoffDir, and outputDir", "script": "scripts/nails_complete_go_live_provider_collector_return.py", "sourceAwareCommandTemplate": "rtk python scripts/nails_complete_go_live_provider_collector_return.py --start-bundle <startBundle> --records-batch <recordsBatch> --source-manifest <sourceManifest> --handoff-dir <handoffDir> --output-dir <outputDir>", "steps": ["optionally normalize returned raw source files or authorized provider crawl-job manifests", "validate filled provider collector records", "advance provider_collector_workspace_validation", "import collector return into crawl export/design-fusion review", "advance provider_collector_import"], "submitEnabled": false, "uploadEnabled": false}, "method": "GET", "network": false, "ok": true, "pluginId": "nails", "productionMutations": false, "route": "/api/web/v1/plugins/nails/production-cutover:provider-collector-return-contract", "schema": {"$id": "https://openeyes.local/plugins/nails/web/v1/production-cutover-provider-collector-return-request.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "not": {"anyOf": [{"required": ["recordsBatch", "recordsBatchInline"]}, {"required": ["recordsBatch", "recordsBatchUri"]}, {"required": ["recordsBatch", "providerCrawlJobManifest"]}, {"required": ["recordsBatch", "providerCrawlJobManifestUri"]}, {"required": ["recordsBatchInline", "recordsBatchUri"]}, {"required": ["recordsBatchInline", "providerCrawlJobManifest"]}, {"required": ["recordsBatchInline", "providerCrawlJobManifestUri"]}, {"required": ["recordsBatchUri", "providerCrawlJobManifest"]}, {"required": ["recordsBatchUri", "providerCrawlJobManifestUri"]}, {"required": ["providerCrawlJobManifest", "providerCrawlJobManifestUri"]}, {"required": ["providerCrawlJobManifest", "sourceManifest"]}, {"required": ["providerCrawlJobManifestUri", "sourceManifest"]}]}, "properties": {"collectorRole": {"default": "external-read-only-provider-collector", "description": "Non-secret collector role label.", "minLength": 1, "type": "string"}, "compactOutputFiles": {"default": false, "description": "Write compact JSON artifacts when true.", "type": "boolean"}, "crawlExportUriPrefix": {"default": "oss://nails-provider-pilot/read-only-exports", "description": "Stable non-secret URI prefix for local crawl export references generated by the import helper.", "minLength": 1, "type": "string"}, "envMode": {"default": "process", "description": "Environment mode for downstream Maliang API-input command templates.", "enum": ["fixture", "process"], "type": "string"}, "handoffDir": {"description": "Optional verified provider crawl handoff directory. Defaults to the latest provider collector workspace report.", "minLength": 1, "type": "string"}, "now": {"description": "Optional deterministic timestamp for local artifacts.", "minLength": 1, "type": "string"}, "objectRoot": {"description": "Optional local import object root. When supplied it must resolve inside outputDir.", "minLength": 1, "type": "string"}, "objectUriMirrorRoot": {"description": "Optional local object-uri mirror root for tests and operator dry-runs. Cloud Run normally uses GCS JSON API reads when NAILS_WEB_GCS_URI_READ_ENABLED=1.", "minLength": 1, "type": "string"}, "outputDir": {"description": "Optional empty output directory for completion artifacts. When supplied it must resolve inside the start bundle.", "minLength": 1, "type": "string"}, "providerCrawlJobManifest": {"additionalProperties": true, "description": "Authorized provider crawl-job manifest returned by an external read-only collector. The Web API validates the collector plugin, rights boundary, and adapter registry binding before materializing a normalized records batch.", "properties": {"adapterJobs": {"items": {"additionalProperties": true, "properties": {"adapterId": {"minLength": 1, "type": "string"}, "adapterVersion": {"minLength": 1, "type": "string"}, "collectionMethod": {"minLength": 1, "type": "string"}, "exportSuffix": {"minLength": 1, "type": "string"}, "market": {"minLength": 1, "type": "string"}, "observedAt": {"minLength": 1, "type": "string"}, "platform": {"minLength": 1, "type": "string"}, "providerId": {"minLength": 1, "type": "string"}, "records": {"items": {"type": "object"}, "minItems": 1, "type": "array"}, "windowEnd": {"minLength": 1, "type": "string"}, "windowStart": {"minLength": 1, "type": "string"}}, "required": ["adapterId", "adapterVersion", "providerId", "market", "platform", "collectionMethod", "observedAt", "windowStart", "windowEnd", "records"], "type": "object"}, "minItems": 1, "type": "array"}, "collectorPlugin": {"additionalProperties": true, "properties": {"pluginId": {"minLength": 1, "type": "string"}, "runtime": {"const": "external_read_only_collector", "type": "string"}}, "required": ["pluginId", "runtime"], "type": "object"}, "contractVersion": {"const": 1, "type": "integer"}, "jobId": {"minLength": 1, "type": "string"}, "kind": {"const": "nails.provider_crawl_job_manifest", "type": "string"}, "rightsBoundary": {"additionalProperties": true, "properties": {"collectionExecutionByNailsWeb": {"const": false, "type": "boolean"}, "liveCollectionAlreadyCompleted": {"const": true, "type": "boolean"}, "networkByNailsWeb": {"const": false, "type": "boolean"}}, "required": ["liveCollectionAlreadyCompleted", "collectionExecutionByNailsWeb", "networkByNailsWeb"], "type": "object"}}, "required": ["contractVersion", "kind", "jobId", "collectorPlugin", "rightsBoundary", "adapterJobs"], "type": "object"}, "providerCrawlJobManifestUri": {"description": "Stable gs:// or oss:// URI for an authorized provider crawl-job manifest. The Web API reads the object through the allowlisted object URI reader, validates the same collector and adapter authorization boundary, materializes a normalized records batch under the start bundle, and then runs the existing local completion wrapper.", "minLength": 1, "type": "string"}, "recordsBatch": {"description": "Optional filled records-batch.json path inside the start bundle. Defaults to the latest prepared workspace records batch.", "minLength": 1, "type": "string"}, "recordsBatchInline": {"additionalProperties": false, "description": "Inline normalized collector records for Web API callers that cannot share a local records-batch path. This still requires a prepared local startBundle and does not execute live collection.", "properties": {"adapterRecords": {"description": "Inline normalized records grouped by registered adapterId. The API materializes records under the start bundle before running the local completion wrapper.", "items": {"additionalProperties": false, "properties": {"adapterId": {"minLength": 1, "type": "string"}, "exportSuffix": {"minLength": 1, "type": "string"}, "observedAt": {"minLength": 1, "type": "string"}, "records": {"items": {"type": "object"}, "minItems": 1, "type": "array"}, "windowEnd": {"minLength": 1, "type": "string"}, "windowStart": {"minLength": 1, "type": "string"}}, "required": ["adapterId", "records", "observedAt", "windowStart", "windowEnd"], "type": "object"}, "minItems": 1, "type": "array"}, "contractVersion": {"const": 1, "type": "integer"}, "kind": {"const": "nails.normalized_crawl_records_batch", "type": "string"}}, "required": ["contractVersion", "kind", "adapterRecords"], "type": "object"}, "recordsBatchUri": {"description": "Stable gs:// or oss:// URI for a normalized collector records batch. The Web API reads the object through the allowlisted object URI reader, materializes it under the start bundle, and then runs the same local completion wrapper.", "minLength": 1, "type": "string"}, "replace": {"default": false, "description": "Allow replacing provider collector validation/import stage entries when advancing the local go-live tracker.", "type": "boolean"}, "sourceManifest": {"description": "Optional returned raw collector source manifest inside the start bundle. When supplied, raw JSON/JSONL source files are normalized into records before validation.", "minLength": 1, "type": "string"}, "startBundle": {"description": "Local go-live start bundle whose provider collector workspace has been prepared.", "minLength": 1, "type": "string"}, "stateRoot": {"description": "Optional local import state root. When supplied it must resolve inside outputDir.", "minLength": 1, "type": "string"}}, "required": ["startBundle"], "title": "Nails Production Cutover Provider Collector Return Request v1", "type": "object"}, "sideEffects": "local_provider_collector_return_completion_files_inline_records_uri_or_manifest", "submitEnabled": false, "uploadEnabled": false}