وثائق أصول Core

توثيق محرك حالة العالم الحتمي ومراجع API.

وثائق بوابة القرار

سلسلة مختبرات الحيازة: التسوية تحت التدقيق

قم بتهيئة رف المختبر من بيان إعلاني، قم بتحفيز فشل مسبق حتمي، وحقق التوافق من خلال وضع غير مرتبط بالشبكة.

إذا كنت تقرأ هذا النص بشكل مفاجئ، فهذا هو سير عمل تسوية المختبر: تتبع الحيازة الحتمي، اكتشاف تعارضات ما قبل الطيران، وتحرك تصحيح موثق. كل تغيير في الحيازة هو التزام يمكن تدقيقه حتى يتمكن المحققون من إعادة التشغيل، والتحقق، وشرح ما حدث دون استنتاج.

المشكلة: انقطاع الحضانة تحت التدقيق

سلاسل الحراسة السريرية تفشل عندما تتعارض الجرد الفعلي، سجلات الماسح الضوئي، والأنظمة التشغيلية. عندما يفشل التعيين، تحتاج إلى دليل حتمي يثبت أن النظام اكتشف النزاع قبل أي تغيير في الحالة.

هذا السيناريو يُظهر نمطًا من الدرجة الإنتاجية: فشل مسبق قسري، تصحيح موجه بالقراءة، ومسار تدقيق قابل لإعادة التشغيل.

لماذا هذا مهم

تحتاج المختبرات المنظمة إلى حراسة قابلة للتتبع وإصلاح حتمي عند ظهور النزاعات. تجعل Asset Core الحراسة موثوقة من خلال اعتبار كل تغيير كمعاملة حتمية وقابلة لإعادة التشغيل.

نموذج النظام

  • الرفوف: حاويات شبكية تفرض قواعد الإشغال لكل مختبر.
  • خليج الماسح: حاوية فتحة لفحوصات الحراسة أثناء الرحلة.
  • برك المواد: حاويات متوازنة مع كوانتيزات نقطة ثابتة.
  • الفئات والأشكال: مسجلة حتى تظل قواعد التوزيع متسقة.
  • الوحدات: خلايا (fixed_point_scale=1000).

نظرة عامة على سير العمل

  1. الإعداد - تسجيل الفصول وإنشاء حاويات المختبر.
  2. البذور - زراعة الأنابيب الأولية والأرصدة.
  3. تم حظر الطيران المسبق - يفشل الطيران المسبق عند وضعه في خلية مشغولة.
  4. شبكة خالية - اختر نقطة الشبكة المتاحة التالية.
  5. التسوية - نقل أنبوب الماسح إلى رصيف مجاني تم التحقق منه.
  6. تحقق من الشبكة - تأكيد الموضع المتوازن في عرض القراءة.

كيفية قراءة الدليل

  • تستخدم خطوات العملية الفردية مساعدي الإجراءات من أجل سهولة القراءة.
  • تظل خطوات العمليات المتعددة كاستدعاءات التزام للحفاظ على الذرية.
  • يستخدم Rust HTTP دائمًا نقطة النهاية الخاصة بالالتزام مع عملية واحدة أو أكثر.

أدوات السيناريو

أحدث تحقق

  • معرف التشغيل: 2026-01-19T18-52-12Z-lab_chain_of_custody
  • Status: تم النجاح
  • جذر هاش النزاهة: efcb02df86d0dd2bb9ffd14d8a7403e52bd06b7c5f56fb4fc4f04703dc9f542f
  • Checks:
    • {‘kind’: ‘structural_invariants’}: تم اجتيازه
    • {‘kind’: ‘world_seq_monotonic’}: تم النجاح
    • {‘kind’: ‘global_seq_monotonic’}: تم النجاح
    • {'kind': 'owner_scope', 'allowed_owners': [1, 2]}: تم القبول
    • {'kind': 'quantity_conservation', 'container_id': 4, 'class_id': 2, 'stack_key': None, 'expected': 250000}: تم النجاح
    • {‘kind’: ‘replay_idempotent’}: تم المرور
    • {'kind': 'commit_log_integrity', 'expected_chain_hash': 'aa3301e51d32150b30281395b68f6df815eaff8416260789832c06259e84a30c', 'expected_prev_chain_hash': 'c387f5f5a7fec5ce1223fa9dcbc8d564a5221e50a7afa1fba498c625d693f064', 'expected_start_offset': 1, 'expected_end_offset': 3, 'expected_entry_count': 3, 'expected_last_global_seq': 38}: تم النجاح
    • {‘kind’: ‘runpack_integrity’}: ناجح

تنزيلات Runpack

لقطة سيناريو

{
  "scenario_id": "lab_chain_of_custody",
  "version": "0.1.0",
  "namespace_id": 2,
  "containers": {
    "rack_lab_a": "container-32001",
    "rack_lab_b": "container-32002",
    "reagent_pool_lab_a": "container-32004",
    "reagent_pool_lab_b": "container-32005",
    "scanner_bay_lab_a": "container-32003"
  },
  "classes": {
    "reagent_buffer": "class-42002",
    "sample_tube": "class-42001"
  },
  "units": {
    "fixed_point_scale": 1000,
    "length_unit": "cells",
    "time_unit": "ms"
  }
}

فرع الفشل

POSITION_OCCUPIED -> grid_free -> reconcile move

سجل التدقيق (اختياري)

تلتقط النسخة النصية أزواج الطلبات والاستجابات الدقيقة التي تم إصدارها خلال التشغيل. هنا مقتطف مضغوط يمكنك استخدامه للتحقق من الحتمية وانتقال البيانات الوصفية:

{
  "kind": "commit",
  "name": "setup",
  "request": {
    "path": "/v1/write/namespaces/2/commit",
    "idempotency_key": "lab-chain-setup",
    "actor_id": "lab-chain",
    "metadata": {
      "phase": "setup",
      "scenario": "lab_chain_of_custody"
    },
    "operations": [
      "RegisterClass",
      "RegisterClassShape",
      "RegisterClass",
      "CreateContainer",
      "CreateContainer",
      "CreateContainer",
      "CreateContainer",
      "CreateContainer"
    ]
  },
  "response": {
    "commit_id": "00000000000000000000000000000003",
    "world_seq_start": 1,
    "world_seq_end": 8,
    "event_count": 8
  }
}

ملاحظة ما قبل الرحلة

  • تقوم استدعاءات الإجراء بتقديم الالتزامات بشكل افتراضي.
  • قم بتعيين ActionOptions(preflight=True) أو استدعاء assetcore_commit_preflight للتحقق من الصحة.

إعداد SDK

from assetcore_sdk import AssetCoreClient
from assetcore_sdk.actions import ActionOptions
from assetcore_sdk.operations import (
    AddFungible,
    AddInstance,
    CreateContainer,
    MoveInstance,
    RegisterClass,
    RegisterClassShape,
)

# Snippets assume an async context (e.g., inside async def main()).
write_client = AssetCoreClient(
    base_url="http://localhost:8080",
    api_key="WRITE_API_KEY",
)
read_client = AssetCoreClient(
    base_url="http://localhost:8081",
    api_key="READ_API_KEY",
)

دليل المستخدم

خطوة 1: الإعداد

سجل الفصول وأنشئ حاويات المختبر.

العمليات

  • RegisterClass (x2) - يسجل تعريف فئة بحيث يمكن للعمليات المستقبلية الإشارة إليه.
  • RegisterClassShape - يسجل بصمة شكل الشبكة لفئة أو نوع فئة.
  • CreateContainer (x5) - ينشئ حاوية (منطقة ذاكرة منظمة) بالنوع المطلوب.
await write_client.commit_operations(
    [
        RegisterClass(
            request={
                "behavior": {"balance_scale": 1},
                "class_id": "class-42001",
                "flags": 0,
                "name": "sample_tube",
            },
        ),
        RegisterClassShape(
            request={"class_id": "class-42001", "shape": {"height": 1, "width": 1}},
        ),
        RegisterClass(
            request={
                "behavior": {"balance_scale": 1000},
                "class_id": "class-42002",
                "flags": 0,
                "name": "reagent_buffer",
            },
        ),
        CreateContainer(
            client_tag="rack_lab_a",
            external_id="container-32001",
            kind={"capacity": 96, "grid_width": 12, "type": "grid"},
            owner_external_id="owner-101",
            policies=None,
        ),
        CreateContainer(
            client_tag="rack_lab_b",
            external_id="container-32002",
            kind={"capacity": 96, "grid_width": 12, "type": "grid"},
            owner_external_id="owner-102",
            policies=None,
        ),
        CreateContainer(
            client_tag="scanner_bay_lab_a",
            external_id="container-32003",
            kind={"count": 2, "type": "slots"},
            owner_external_id="owner-101",
            policies=None,
        ),
        CreateContainer(
            client_tag="reagent_pool_lab_a",
            external_id="container-32004",
            kind={"quantization_inv": 1000, "type": "balance"},
            owner_external_id="owner-101",
            policies=None,
        ),
        CreateContainer(
            client_tag="reagent_pool_lab_b",
            external_id="container-32005",
            kind={"quantization_inv": 1000, "type": "balance"},
            owner_external_id="owner-102",
            policies=None,
        ),
    ],
    namespace_id=2,
    idempotency_key="lab-chain-setup",
    actor_id="lab-chain",
    metadata={"phase": "setup", "scenario": "lab_chain_of_custody"},
)

خطوة 2: البذور

زرع الأنابيب الأولية والتوازنات.

العمليات

  • AddInstance (x25) - يصنع مثيلاً جديداً ويضعه في موقع مستهدف.
  • AddFungible (x2) - يضيف كمية قابلة للتداول إلى رصيد أو خلية شبكة محددة.
await write_client.commit_operations(
    [
        AddInstance(
            class_id="class-42001",
            client_tag="tube-001",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 1,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-002",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 2,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-003",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 3,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-004",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 4,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-005",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 5,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-006",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 6,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-007",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 7,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-008",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 8,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-009",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 9,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-010",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 10,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-011",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 11,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-012",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 12,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-013",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 13,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-014",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 14,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-015",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 15,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-016",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 16,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-017",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 17,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-018",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 18,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-019",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 19,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-020",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 20,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-021",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 21,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-022",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 22,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-023",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 23,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="tube-024",
            key=None,
            location={
                "container_id": "container-32001",
                "kind": "grid_cell",
                "position": 24,
                "rotation": None,
            },
        ),
        AddInstance(
            class_id="class-42001",
            client_tag="scanner-tube",
            key=None,
            location={
                "container_id": "container-32003",
                "kind": "slot",
                "slot_index": 1,
            },
        ),
        AddFungible(
            class_id="class-42002",
            client_tag="reagent-a",
            key=None,
            location={"container_id": "container-32004", "kind": "balance"},
            quantity="250",
        ),
        AddFungible(
            class_id="class-42002",
            client_tag="reagent-b",
            key=None,
            location={"container_id": "container-32005", "kind": "balance"},
            quantity="125",
        ),
    ],
    namespace_id=2,
    idempotency_key="lab-chain-seed",
    actor_id="lab-chain",
    metadata={"phase": "seed", "scenario": "lab_chain_of_custody"},
)

الخطوة 3: فشل الفحص المسبق (خطأ متوقع)

يفشل الفحص المسبق عند وضعه في خلية مشغولة.

العمليات

  • MoveInstance - ينقل مثيلاً موجودًا إلى موقع جديد.

خطأ متوقع

{
  "code": "POSITION_OCCUPIED",
  "detail": "Position 6 in container 1 is occupied by item at anchor 6",
  "hint": "Select an unoccupied position or move the existing item first.",
  "retryable": false,
  "status": 409,
  "title": "ConflictError",
  "type": "urn:assetcore:error:POSITION_OCCUPIED"
}
await write_client.actions.move_instance(
    instance="inst-25",
    to={
        "container_id": "container-32001",
        "kind": "grid_cell",
        "position": 6,
        "rotation": None,
    },
    options=ActionOptions(
        namespace_id=2,
        idempotency_key="lab-chain-blocked",
        actor_id="lab-chain",
        metadata={"phase": "exception", "scenario": "lab_chain_of_custody"},
    ),
)

الخطوة 4: الشبكة الحرة

اختر نقطة الشبكة المتاحة التالية.

await read_client.get_container_grid_free(
    container_id="container-32001",
    namespace_id=2,
    height=1,
    width=1,
)

الخطوة 5: التسوية

قم بتحريك أنبوب الماسح إلى رافعة مجانية تم التحقق منها.

العمليات

  • MoveInstance - ينقل مثيلاً موجودًا إلى موقع جديد.
await write_client.actions.move_instance(
    instance="inst-25",
    to={
        "container_id": "container-32001",
        "kind": "grid_cell",
        "position": 25,
        "rotation": None,
    },
    options=ActionOptions(
        namespace_id=2,
        idempotency_key="lab-chain-reconcile",
        actor_id="lab-chain",
        metadata={
            "phase": "reconcile",
            "scenario": "lab_chain_of_custody",
            "target_anchor": 25,
        },
    ),
)

الخطوة 6: تحقق من الشبكة

أكد على التوزيع المتوافق في عرض القراءة.

await read_client.get_container_grid(
    container_id="container-32001",
    namespace_id=2,
)