{"adapterRegistryPath": "/api/web/v1/plugins/nails/crawl-adapters", "apiVersion": "openeyes.nails.web.v1", "boundary": "local_crawl_records_batch_ingest_only_no_live_collection", "collectionExecutionEnabled": false, "contract": {"additionalProperties": false, "collectionReceiptInputModes": ["none", "local_path", "uri", "inline_json"], "contractVersion": 1, "inputModes": ["local_path", "uri", "inline_json"], "name": "nails-crawl-records-batch-ingest-request", "optionalFields": ["recordsBatchPath", "recordsBatchUri", "recordsBatch", "objectUriMirrorRoot", "collectionReceiptVerificationPath", "collectionReceiptVerificationUri", "collectionReceiptVerification", "envMode", "now"], "requiredFields": ["outputDir", "stateRoot", "objectRoot"], "responseFields": ["inputMode", "collectionReceiptInputMode", "intakeWorkflow", "readyForDesignFusion", "readyForMaliangApiInput", "readyForMaliangApiInputPackage", "maliangLatest", "maliangApiInputPackage", "maliangApiInputPackageDigest", "objectUriReads", "objectUriReadNetwork", "links"], "schemaDigest": "53522375610c9c70acd973e8b6552bc08a97be5f472896e94c99e7a86c017aab", "schemaId": "https://openeyes.local/plugins/nails/web/v1/crawl-records-batch-ingest-request.schema.json", "statusCodes": {"200": "batch packaged and reviewed", "400": "request shape, path, manifest, or contract error", "405": "method not allowed", "409": "batch review completed but is not ready"}}, "crawlExportContractPath": "/api/web/v1/plugins/nails/crawl-export-contract", "deployEnabled": false, "idempotency": {"idempotencyKeyHeader": null, "model": "caller_controlled_local_roots_and_digest_replay", "stableDigests": ["sourceManifestDigest", "crawlReviewDigest"]}, "ingestContractPath": "/api/web/v1/plugins/nails/crawl-records-batch:ingest-contract", "ingestPath": "/api/web/v1/plugins/nails/crawl-records-batch:ingest", "liveCollectionEnabled": false, "method": "GET", "network": false, "objectUriReader": {"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", "forbidsQueryOrFragment": true, "gcsModeEnv": "NAILS_WEB_GCS_URI_READ_ENABLED=1", "localMirrorRoot": "<objectUriMirrorRoot or outputDir/object-uri-readback>/<scheme>/<bucket>/<key>", "secretMaterialReturned": false}, "ok": true, "operatorScript": "scripts/nails_ingest_crawl_records_batch.py", "pluginId": "nails", "productionMutations": false, "responseLinks": {"crawlExportsQualityReportRequest": {"bodyFields": ["crawlExports"], "method": "POST", "network": false, "path": "/api/web/v1/plugins/nails/crawl-exports:quality-report"}, "designFusionReadinessReportRequest": {"bodyFields": ["stateRoot", "stateDigest"], "condition": "when_verified_design_package_is_persisted", "method": "POST", "network": false, "path": "/api/web/v1/plugins/nails/design-fusion:readiness-report", "requiresStateRoot": true}, "maliangApiInputPackageRequest": {"bodyFields": ["stateRoot", "payloadDigest"], "condition": "when_maliang_export_record_is_persisted", "method": "POST", "network": false, "path": "/api/web/v1/plugins/nails/maliang-exports:api-input-package", "requiresStateRoot": true}}, "responseShape": {"errorShape": {"code": "<stable_machine_code>", "error": "<human_readable_message>", "ok": false}, "intakeWorkflow": {"kind": "nails.crawl_records_batch_ingest.intake_workflow", "sections": ["source", "designFusion", "maliangApiInput", "links", "boundary"]}, "kind": "nails.crawl_records_batch_ingest"}, "route": "/api/web/v1/plugins/nails/crawl-records-batch:ingest-contract", "schema": {"$id": "https://openeyes.local/plugins/nails/web/v1/crawl-records-batch-ingest-request.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "allOf": [{"not": {"anyOf": [{"required": ["collectionReceiptVerificationPath", "collectionReceiptVerificationUri"]}, {"required": ["collectionReceiptVerificationPath", "collectionReceiptVerification"]}, {"required": ["collectionReceiptVerificationUri", "collectionReceiptVerification"]}]}}], "oneOf": [{"not": {"anyOf": [{"required": ["recordsBatchUri"]}, {"required": ["recordsBatch"]}]}, "required": ["recordsBatchPath"]}, {"not": {"anyOf": [{"required": ["recordsBatchPath"]}, {"required": ["recordsBatch"]}]}, "required": ["recordsBatchUri"]}, {"not": {"anyOf": [{"required": ["recordsBatchPath"]}, {"required": ["recordsBatchUri"]}]}, "required": ["recordsBatch"]}], "properties": {"collectionReceiptVerification": {"description": "Optional inline provider-pilot read-only collection receipt verification, or a wrapper containing collectionReceiptVerification and collectionReceiptVerificationDigest. Remote callers use this when they cannot share local paths with the service.", "type": "object"}, "collectionReceiptVerificationPath": {"description": "Optional local path to the verified external read-only collection receipt.", "minLength": 1, "type": "string"}, "collectionReceiptVerificationUri": {"description": "Optional stable non-secret gs:// or oss:// object URI for the verified external read-only collection receipt. It uses the same authorized object URI reader as recordsBatchUri.", "minLength": 1, "type": "string"}, "envMode": {"default": "process", "description": "process overlays configured Maliang Nails staging env; fixture uses deterministic local fixture values.", "enum": ["process", "fixture"], "type": "string"}, "now": {"description": "Optional RFC3339 timestamp for deterministic review.", "type": "string"}, "objectRoot": {"description": "Local object root used by the design-fusion and Maliang API-input dry-run review.", "minLength": 1, "type": "string"}, "objectUriMirrorRoot": {"description": "Optional local mirror root for stable gs:// or oss:// object URI reads. When omitted, URI mode reads from <outputDir>/object-uri-readback so the downstream objectRoot remains clean for design package artifacts.", "minLength": 1, "type": "string"}, "outputDir": {"description": "Local output directory for crawl exports, build reports, crawl review, summary, manifest, and README.", "minLength": 1, "type": "string"}, "recordsBatch": {"additionalProperties": false, "description": "Inline normalized crawl records batch for remote Web API callers that cannot share local paths with the service.", "properties": {"adapterRecords": {"description": "Inline normalized records grouped by registered adapterId. Each row must provide records plus observedAt/windowStart/windowEnd.", "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"}, "recordsBatchPath": {"description": "Local path to a normalized crawl records batch manifest returned by an approved external read-only collector.", "minLength": 1, "type": "string"}, "recordsBatchUri": {"description": "Stable non-secret gs:// or oss:// object URI for a normalized crawl records batch. The service reads it through an authorized object URI reader: a local object-uri mirror by default, or the GCS JSON API when explicitly enabled in the runtime environment.", "minLength": 1, "type": "string"}, "stateRoot": {"description": "Local state root used by the design-fusion and Maliang API-input dry-run review.", "minLength": 1, "type": "string"}}, "required": ["outputDir", "stateRoot", "objectRoot"], "title": "Nails Crawl Records Batch Ingest Request v1", "type": "object"}, "secretMaterialReturned": false, "submitEnabled": false, "uploadEnabled": false, "workflow": {"auth": "runtime deployment policy; no credential material in response", "caller": "approved external collector or same-repo operator UI", "consistency": "read-your-writes within caller-provided local stateRoot", "idempotency": "caller-controlled output/state roots plus stable digests", "name": "nails-crawl-records-to-design-fusion-to-maliang-api-input", "steps": [{"path": "/api/web/v1/plugins/nails/crawl-records-batch:ingest", "resultFields": ["sourceManifestDigest", "adapterCount", "recordCount", "crawlExportPaths"], "stepId": "crawl_records_batch_ingest"}, {"path": "/api/web/v1/plugins/nails/design-fusion:readiness-report", "resultFields": ["readyForDesignFusion", "crawlReviewDigest", "designPackagesQueryRequest"], "stepId": "design_fusion_review"}, {"path": "/api/web/v1/plugins/nails/maliang-exports:api-input-package", "resultFields": ["readyForMaliangApiInput", "readyForMaliangApiInputPackage", "maliangApiInputPackageDigest"], "stepId": "maliang_api_input_package"}], "versioning": "path-versioned under /api/web/v1/plugins/nails", "workflowVersion": 1}}