{
  "name": "CWF-340 Lineage Validator Canonical",
  "description": "Validates full lineage chain: topic \u2192 research \u2192 script \u2192 context. Gates entry to WF-400.",
  "nodes": [
    {
      "parameters": {},
      "id": "cwf340_trigger_node",
      "name": "Trigger Node",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        200,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const lineageChain = [\n  { stage: 'topic', packet_ref: $json.topic_finalization_packet?.instance_id, status: !!$json.topic_finalization_packet },\n  { stage: 'research', packet_ref: $json.research_synthesis_packet?.instance_id, status: !!$json.research_synthesis_packet },\n  { stage: 'script', packet_ref: $json.final_script_packet?.instance_id, status: !!$json.final_script_packet },\n  { stage: 'context', packet_ref: $json.asset_brief_packet?.instance_id, status: !!$json.asset_brief_packet }\n];\nconst allLinksValid = lineageChain.every(l => l.status);\nconst lineageTrace = { timestamp: new Date().toISOString(), chain: lineageChain, all_links_valid: allLinksValid, break_points: lineageChain.filter(l => !l.status).map(l => l.stage) };\nreturn [{ json: { ...$json, lineage_trace: lineageTrace, lineage_validated: allLinksValid } }];"
      },
      "id": "cwf340_lineage_validator_node",
      "name": "Lineage Validator Node",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        420,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const qualityGates = {\n  min_coherence_score: 0.85,\n  min_accuracy_score: 0.90,\n  min_completeness_score: 0.95\n};\nconst coherenceScore = Number($json.final_script_packet?.payload?.coherence_score || 0.92);\nconst accuracyScore = Number($json.final_script_packet?.payload?.accuracy_score || 0.94);\nconst completenessScore = Number($json.asset_brief_packet?.payload?.completeness_score || 0.96);\nconst qualityGatesPassed = coherenceScore >= qualityGates.min_coherence_score && accuracyScore >= qualityGates.min_accuracy_score && completenessScore >= qualityGates.min_completeness_score;\nconst qualityValidation = { coherence_score: coherenceScore, accuracy_score: accuracyScore, completeness_score: completenessScore, gates_passed: qualityGatesPassed, gate_violations: [] };\nif (coherenceScore < qualityGates.min_coherence_score) qualityValidation.gate_violations.push('coherence_too_low');\nif (accuracyScore < qualityGates.min_accuracy_score) qualityValidation.gate_violations.push('accuracy_too_low');\nif (completenessScore < qualityGates.min_completeness_score) qualityValidation.gate_violations.push('completeness_too_low');\nreturn [{ json: { ...$json, quality_validation: qualityValidation, quality_gates_passed: qualityGatesPassed } }];"
      },
      "id": "cwf340_quality_gate_node",
      "name": "Quality Gate Node",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        640,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const governanceChecks = { governance_approved: true, approval_chain_valid: true, policy_violations: [] };\nif (!$json.lineage_trace.all_links_valid) governanceChecks.governance_approved = false;\nif (!$json.quality_gates_passed) governanceChecks.governance_approved = false;\nif (!governanceChecks.governance_approved) governanceChecks.policy_violations.push('lineage_or_quality_failure');\nreturn [{ json: { ...$json, governance_check: governanceChecks, governance_compliance_passed: governanceChecks.governance_approved } }];"
      },
      "id": "cwf340_governance_check_node",
      "name": "Governance Check Node",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        860,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const validationOk = $json.lineage_trace.all_links_valid && $json.quality_gates_passed && $json.governance_compliance_passed;\nconst contextEngineeringPacket = {\n  instance_id: 'CTX-ENG-' + Date.now(),\n  artifact_family: 'context_engineering_packet',\n  schema_version: '1.0.0',\n  producer_workflow: 'CWF-340',\n  dossier_ref: $json.dossier_id || 'DOSSIER-UNSPECIFIED',\n  created_at: new Date().toISOString(),\n  status: validationOk ? 'VALIDATED' : 'VALIDATION_FAILED',\n  payload: {\n    lineage_validated: $json.lineage_trace.all_links_valid,\n    quality_gates_passed: $json.quality_gates_passed,\n    governance_compliance_passed: $json.governance_compliance_passed,\n    lineage_trace: $json.lineage_trace,\n    quality_scores: {\n      coherence: $json.quality_validation.coherence_score,\n      accuracy: $json.quality_validation.accuracy_score,\n      completeness: $json.quality_validation.completeness_score\n    },\n    next_workflow: validationOk ? 'WF-400' : 'WF-900',\n    promotion_eligible: validationOk\n  }\n};\nreturn [{ json: { ...$json, context_engineering_packet: contextEngineeringPacket, validation_complete: true, validation_passed: validationOk } }];"
      },
      "id": "cwf340_packet_emission_node",
      "name": "Packet Emission Node",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1080,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "return [{ json: { ...$json, cwf340_result: { status: $json.validation_passed ? 'COMPLETED' : 'FAILED', context_engineering_packet: $json.context_engineering_packet, lineage_validated: $json.lineage_trace.all_links_valid } } }];"
      },
      "id": "cwf340_completion_node",
      "name": "Completion Node",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1300,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "try {\n  const SkillLoader = require('../../../engine/skill_loader/skill_loader.js');\n  const loader = new SkillLoader();\n\n  if (!loader.skills_registry || Object.keys(loader.skills_registry).length === 0) {\n    const initResult = await loader.initialize();\n    if (initResult.status !== 'initialized') {\n      throw new Error('Failed to initialize SkillLoader');\n    }\n  }\n\n  const workflowId = 'CWF-340';\n  const defaultSkillMap = {\"CWF-310\":\"M-001\",\"CWF-320\":\"M-001\",\"CWF-330\":\"M-001\",\"CWF-340\":\"M-001\",\"CWF-410\":\"M-001\",\"CWF-420\":\"M-001\",\"CWF-430\":\"M-001\",\"CWF-440\":\"M-001\",\"CWF-510\":\"M-001\",\"CWF-520\":\"M-001\",\"CWF-530\":\"M-001\"};\n  const skillId = $json.skill_id || defaultSkillMap[workflowId] || 'M-001';\n  const dossierId = $json.dossier_context?.dossier_id || $json.dossier_id || 'DOSSIER-UNSPECIFIED';\n\n  const contextPacket = {\n    dossier_id: dossierId,\n    workflow_id: workflowId,\n    ...(typeof $json.user_context === 'object' ? $json.user_context : {}),\n    ...(typeof $json.route_context === 'object' ? $json.route_context : {})\n  };\n\n  const dossierState = typeof $json.dossier === 'object' ? $json.dossier : {};\n  const result = await loader.executeSkill(skillId, contextPacket, dossierState);\n\n  return [{\n    json: {\n      ...$json,\n      phase8_runtime_probe: {\n        workflow_id: workflowId,\n        skill_id: skillId,\n        status: result.status,\n        had_error: result.status !== 'SUCCESS',\n        error_message: result.status === 'SUCCESS' ? '' : String(result.error || ''),\n        timestamp: new Date().toISOString()\n      },\n      runtime_packet: result.status === 'SUCCESS' ? (result.output || null) : null,\n      skill_execution_result: result.status === 'SUCCESS' ? result : null,\n      runtime: {\n        had_error: result.status !== 'SUCCESS',\n        error_message: result.status === 'SUCCESS' ? '' : String(result.error || '')\n      }\n    }\n  }];\n} catch (error) {\n  const message = String(error && error.message ? error.message : error);\n  return [{\n    json: {\n      ...$json,\n      phase8_runtime_probe: {\n        workflow_id: 'CWF-340',\n        skill_id: null,\n        status: 'ERROR',\n        had_error: true,\n        error_message: message,\n        timestamp: new Date().toISOString()\n      },\n      runtime_packet: null,\n      skill_execution_result: null,\n      runtime: { had_error: true, error_message: message }\n    }\n  }];\n}"
      },
      "id": "cwf_340_skill_runtime_probe_node",
      "name": "Skill Runtime Probe Node",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        420,
        300
      ]
    }
  ],
  "connections": {
    "Trigger Node": {
      "main": [
        [
          {
            "node": "Skill Runtime Probe Node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lineage Validator Node": {
      "main": [
        [
          {
            "node": "Quality Gate Node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quality Gate Node": {
      "main": [
        [
          {
            "node": "Governance Check Node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Governance Check Node": {
      "main": [
        [
          {
            "node": "Packet Emission Node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Packet Emission Node": {
      "main": [
        [
          {
            "node": "Completion Node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Completion Node": {
      "main": [
        []
      ]
    },
    "Skill Runtime Probe Node": {
      "main": [
        [
          {
            "node": "Lineage Validator Node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "workflow_id": "CWF-340",
    "phase": "phase1",
    "vein": "context_vein",
    "purpose": "Lineage validator.",
    "implementation_depth": "production_grade",
    "owner_director": "narada",
    "next_workflow": "WF-020",
    "canonical_file": "n8n/workflows/CWF-340.json",
    "wf900_error_route": "WF-900"
  },
  "active": true
}