# description
Pipeline-tier attestation envelope for the FIRST tier in IntelligencePro's 5-tier cryptographic chain-of-custody wedge (R16 cross-cutting): pipeline (THIS) → experiment (R16 M1) → leaderboard (R15 B1) → review (R16 R3 ip-merge-gate) → governance (R14 G1). Closes SYNTHESIS-acquisition Round 14 D1 [[elt-and-data-engineering]] ship-first action. ALSO closes one of the 2 aspirational tiers cycle-301 regulatory-compliance audit P0-4 flagged as 'only 2 of 5 tiers ship fully' — this is the pipeline tier landing. Designed as an OpenLineage RunFacet (BaseFacet subclass per OpenLineage spec) so it embeds into existing dbt-cloud / Airflow / Spark / Flink / Trino / Dagster / Prefect run-event emitters without requiring a new wire format. Composes UPWARD with R21 BI1 ip.bi.cited_number.attestation.v1 (cycle 313 references pipelineRunIds[] back to here) — when a SOX auditor walks the lineage from a regulated cited number, this is the upstream link. Composes DOWNWARD with the ip.experiment.receipt.v1 (R16 M1, planned) — when a training-run depends on pipeline-prepared data, this is the upstream link. One JSON Schema × every OpenLineage-emitting orchestrator + every dbt model + every Spark job + every Trino query. R14 D1's R-round headline finding: ~40-pipe transitive-deps via OpenLineage facet — single PR adds attestation to the entire data-engineering tier.

# $comment
Discovery: https://ip.tekton.cc/.well-known/ip-knowledge.json (full descriptor) | Badge: https://ip.tekton.cc/api/badge/v1/attestation/pipeline.facet.v1/<subjectSha256> (shields.io endpoint) | Free dry-run: POST https://ip.tekton.cc/api/credentials/dry-run with body {kind:"pipeline.facet.v1", body:<candidate>} (no auth required, validates against this schema) | Verification recipe: https://ip.tekton.cc/docs/verification-recipe.md (3-layer trust model + curl trail) | Revocation: https://ip.tekton.cc/credentials/status/v1 (W3C BitstringStatusList v1.0; check bit at credentialStatus.statusListIndex)

# x-controlMappingRefs.$comment
Cycle 720 (SP-716-P1-4 close): bidirectional back-link to the framework mapping docs. Pipeline-facet is the UPSTREAM tier in the wedge (R14 D1) — context-establishment evidence for every downstream attestation. Data-lineage tooling (Marquez/DataHub/Atlan/OpenMetadata) walks these refs to bind a pipeline run to data-quality + provenance controls.

# x-controlMappingRefs.iso42001Aims[].note
Quality of data — pipeline facet captures dataset provenance + quality signals at the data-engineering layer

# x-controlMappingRefs.iso42001Aims[].note
Data — data-and-information resources for AI system; pipeline facet IS the resource-provenance attestation

# x-controlMappingRefs.nistAiRmf[].note
Context establishment — the pipeline facet establishes the data-engineering context for every downstream attestation

# x-controlMappingRefs.nistAiRmf[].note
Monitor and document — the rmfFunctionHint default 'measure' on this schema points here

# x-controlMappingRefs.euAiAct[].note
Data and data governance — training/validation/testing data must meet quality criteria; pipeline facet is the audit substrate

# x-controlMappingRefs.euAiAct[].note
Record-keeping — pipeline facets contribute to the lifecycle record-keeping obligation

# x-controlMappingRefs.iso42001RiskRegister[].note
Signed pipeline-run facets give downstream evals a cryptographic upstream pointer instead of trust-the-pipeline assertions

# properties.schemaVersion.description
Semver of this schema. Bumps to 2.0.0 land at /credentials/pipeline-facet/v2 — v1 stays immutable (see /docs/schema-versioning.md for the cycle-726 canonical bump-mechanics + soft-change-detection contract).

# properties.rmfFunctionHint.description
Cycle 487 (cycle-483 follow-up): non-required NIST AI RMF 1.0 function hint. Pipeline facets map most naturally to MEASURE (MEASURE-2.7 'monitor and document AI system performance and trustworthiness') since they capture data-lineage metrics + dataset provenance. Drata/Vanta/OneTrust import mappings default this hint to 'measure'; operators override per-facet when a different function applies. Companion to ip.governance.compliance.v1.rmfFunction (cycle 483 canonical control-attribution surface).

# properties._producer.description
OpenLineage BaseFacet required field — URI identifying the producer of this facet. For CP-emitted attestations: 'https://ip.tekton.cc/openlineage-facet/ip.pipeline.facet.v1'. OpenLineage clients (Marquez, DataHub, Atlan, OpenMetadata) read this to route the facet to the right schema registry.

# properties._schemaURL.description
OpenLineage BaseFacet required field — URI pointing to the canonical schema. For CP-emitted attestations: 'https://ip.tekton.cc/credentials/pipeline-facet/v1'. Lets OpenLineage clients validate this facet against the canonical shape without hardcoding.

# properties.runId.description
OpenLineage run identifier — RFC 4122 UUID v4 or v7. The SAME UUID used in the parent OpenLineage RunEvent + in ip.bi.cited_number.attestation.v1 pipelineRunIds[] cross-reference. Verifier consumes both the OpenLineage run + the IntelligencePro attestation by walking this id.

# properties.jobName.description
OpenLineage job name — the canonical handle for the job within the namespace. Examples: 'revenue_quarterly_rollup', 'orders_to_warehouse_etl', 'fact_user_engagement.materialize', 'train_set_split_v2'. Job-naming conventions per OpenLineage.

# properties.producerVersionSha.description
Sha256 of the canonical producer-version artifact. For dbt: sha256 of dbt_project.yml + the version-pinned dbt-core wheel. For Airflow: sha256 of the DAG source + DAG-bag manifest. For Spark: sha256 of the application JAR + Spark version manifest. For Flink: sha256 of the job graph + Flink runtime version. For Trino: sha256 of the query plan + Trino server version. Pins WHICH BUILD of the orchestrator ran the job. Without this, an orchestrator could silently update between runs and downstream consumers wouldn't detect the lineage break.

# properties.transformCodeSha.description
Optional sha256 of the user's transform code. For dbt: sha256 of the model SQL + ref'd macro definitions. For Spark: sha256 of the user-supplied job code (Python/Scala/SQL). For Airflow: sha256 of the operator code + DAG topology. For Flink: sha256 of the job graph definition. Distinct from producerVersionSha (which is the runtime); transformCodeSha is the USER'S code that ran inside the runtime.

# properties.inputDatasets.items.properties.name.description
OpenLineage dataset name — fully-qualified within namespace.

# properties.inputDatasets.items.properties.snapshotSha256.description
Sha256 of the canonical dataset snapshot at job start. For time-travel-capable systems (Snowflake Time Travel, Iceberg, Delta Lake): sha256 of (namespace + name + snapshot-id + valid-as-of timestamp). For event streams (Kafka): sha256 of (topic + partition + offset-range). For S3-style object stores: sha256 of the object's ETag / VersionId.

# properties.inputDatasets.description
Array of input datasets the pipeline consumed, each pinned to its snapshot sha. OpenLineage compatible — the facet attaches to the parent RunEvent's inputs[] array. Required for SOX 404 + PCAOB AS-1105 audit-traceable upstream lineage. Cross-references downstream into ip.bi.cited_number.sourceTables[] via tableId match.

# properties.outputDatasets.items.properties.namespace.description
OpenLineage dataset namespace for the output.

# properties.outputDatasets.items.properties.outputSha256.description
Sha256 of the canonical output snapshot the job produced. After the job completes, downstream tools (ip.bi.cited_number / ip.experiment.receipt) reference this as their input snapshotSha256.

# properties.outputDatasets.description
Array of output datasets the pipeline produced. Lets downstream consumers (BI tools, training pipelines) bind their input to a specific upstream snapshot WITHOUT trusting the data-warehouse's own metadata. End-to-end audit-traceable lineage requires each downstream cite to match an upstream emit.

# properties.runStartedAt.description
Epoch milliseconds when the pipeline run started. Matches the OpenLineage START event timestamp. Required because lineage has temporal dimension — the same job-name can run nightly with different input snapshots.

# properties.runCompletedAt.description
Epoch milliseconds when the pipeline run completed (success or failure). Matches the OpenLineage COMPLETE / FAIL event timestamp. Optional during in-flight runs; required for terminal attestations. When present, runCompletedAt >= runStartedAt.

# properties.runStatus.description
OpenLineage run-status enum. 'COMPLETE' = success. 'FAILED' = job ran but errored. 'ABORTED' = killed mid-flight (timeout, manual cancel). 'OTHER' = ecosystem-specific status (Dagster materialization, Prefect crashed-task). Downstream consumers MUST refuse to cite numbers from FAILED / ABORTED runs.

# properties.runnerDid.description
DID of the entity that ran the pipeline. did:web for institutional / data-platform operators (did:web:dbtcloud.com, did:web:databricks.com, did:web:snowflake.com); did:key for self-hosted / individual operator. Resolves to a JWKS that can verify the `signature` field below.

# properties.facetSpecVersion.description
OpenLineage facet spec version this attestation targets. Examples: 'openlineage-1.30.0', 'openlineage-1.42.0'. Lets OpenLineage clients route the facet through the right validator.

# properties.judgesDigest.description
When this attestation results from a multi-judge peer review (3+ independent verifiers per CP's standard peer-review economy), the canonical digest of the judges manifest. Chains to the same judgesDigest field used in CP's brief/artifact/eval-result/sandbox-run/eval-run/synthetic-media/legal-citation/bi-cited-number manifests (cycle 303 derivationRecipes documentation applies).

# properties.ipAttestationEventId.description
When this attestation was emitted as a ip.attestation.event.v1 row (R11 T1) to the platform's Kafka/Tinybird/ClickHouse pipeline, the eventId of that wire row.

# properties.auditFlags.properties.sox404.description
True when this attestation is intended to satisfy SOX Section 404 audit-traceable-lineage upstream from a regulated number (chained downstream via ip.bi.cited_number.pipelineRunIds[]).

# properties.auditFlags.properties.euAiActAnnexIV.description
True when this attestation is intended to support EU AI Act Annex IV technical documentation requirements (data provenance + lineage for high-risk AI systems).

# properties.auditFlags.properties.gdprArticle22.description
True when this attestation supports GDPR Article 22 right-to-explanation for automated decisions — the upstream data lineage is part of the explanation chain.

# properties.auditFlags.description
Optional regulatory-context flags. Signals to a downstream regulator-facing verifier WHICH audit framework the issuer intended the attestation to cover.

# properties.signature.description
Ed25519 signature (128 hex chars = 64 raw bytes) over the canonical-JSON bytes of (runId ⊕ jobNamespace ⊕ jobName ⊕ producerVersionSha ⊕ transformCodeSha? ⊕ inputDatasets ⊕ outputDatasets? ⊕ runStartedAt ⊕ runCompletedAt? ⊕ runStatus? ⊕ runnerDid ⊕ facetSpecVersion? ⊕ judgesDigest? ⊕ ipAttestationEventId? ⊕ auditFlags?). Verify against the publicKey published in the runnerDid's JWKS. RFC 8037 (Ed25519 in JWS) canonicalization rules apply: JCS (RFC 8785) ordering on the inner object.

# properties.publicKey.description
Ed25519 public key (32 raw bytes = 64 hex) corresponding to the signature above.

# properties.extra.description
Open extension slot — runtime-specific or job-specific payload (dbt manifest sha, Airflow DAG-bag id, Spark application id, Trino query plan id, Dagster materialization metadata). Consumers MUST ignore unknown keys.