فهرست مستندات

مدل دامنه#

کجا پیاده شده است#

  • packages/contracts/src/registry.ts و packages/contracts/src/publication.ts — موجودیت‌ها و وضعیت‌های انتشاری که اینجا نام برده شده‌اند، به شکل schemaهای Zod که هر سطحی با آن‌ها اعتبارسنجی می‌کند.
  • packages/contracts/src/apps.ts — بازبینی اپ، نشست اپ و appActorSub.
  • apps/notes/packages/contracts — قراردادهای متعلق به محصول برای سند، پوشه و provenance اختیاری Notes؛ خصوصی و خارج از CVER پلتفرم.
  • apps/notes/packages/backend و apps/notes/src/editor — پیکرهٔ ماندگار actor-portable و projectionهای عادی/اوتلاین آن.
  • packages/contracts/src/host-services.ts — واژگان مکانی.
  • packages/contracts/src/notifications.ts — خود اعلان.
  • services/registry/src/repo/db.ts و services/registry/src/repo/sql/ — جایی که این رکوردها واقعاً ذخیره می‌شوند.

هویت پایدار#

  • ناشر (Publisher) مالک handleهای عمومی و پروژه‌ها (Project) است.
  • پروژه، ظرف مدیریتی تغییرپذیری از نوع environment | app | plugin است.
  • محیط (Environment)، اپ (App) و پلاگین (Plugin) در رجیستری (Registry) شناسه‌ای پایدار دارند که به پروژه، نام پکیج، slug یا ارائه‌دهندهٔ میزبانی وابسته نیست.

مالک احراز‌شده ریشهٔ اختیار مدیریت پروژه است و Publisher فقط attribution عمومی کاتالوگ. رکورد عضویت audit‌شده می‌تواند بدون افشای subject خام حساب، نقش مدیریت admin، developer یا viewer بدهد و ProjectView.currentRole نقش مؤثر هر درخواست‌کننده را اعلام می‌کند. Registry فقط مالک پروژهٔ Environment را ادمین اولیهٔ Runtime همان محیط می‌کند؛ admin مدیریت، ادمین Runtime نیست. اعضای پروژهٔ App یا Plugin نیز هیچ نقش Runtime محیطی نمی‌گیرند. انتقال اتمیک مالکیت عملیات آیندهٔ جداگانه است و هیچ‌یک از این نقش‌ها پرچم قابل‌ساخت client نیستند.

اسنپ‌شات‌های تغییرناپذیر#

  • EnvironmentManifestRevision ورودی، نمایش پرتال، قابلیت‌ها، event اعلان، واژگان مکانی، Host Services، نصب دقیق پلاگین و مرز بک‌اند اختیاری را ثبت می‌کند.
  • AppRevision نسخهٔ ورودی باندل، access، نمایش، حالت‌ها، درخواست قابلیت، event و مدل اعلان پس‌زمینه، سازگاری و مستندات اپ را ثبت می‌کند. AppBuildArtifact یک‌بارمصرف آن، سند ورودی و فهرست محدود فایل‌های archive را پیش از بازبینی با اندازهٔ دقیق، صحت SHA-512 و چکیدهٔ canonical build متصل می‌کند.
  • PluginRelease فراداده، مشخصات آداپتور فرانت‌اند، قرارداد مولفهٔ بک‌اند، طرح‌وارهٔ تنظیمات، مجوزها، سازگاری، مستندات و هش پکیج را ثبت می‌کند.
  • BackendDeployment هویت منطقی و پایدار یک مؤلفهٔ بک‌اند مستقرشده است. هر BackendDeploymentRevision یک اسنپ‌شات تغییرناپذیر از پیکربندی endpoint زندهٔ آن است. جابه‌جایی endpoint، revision تازه‌ای زیر همان هویت deployment می‌سازد؛ recovery نیز به‌جای بازنویسی یا حذف تاریخچهٔ منتشرشده، یک revision جبرانی دیگر ایجاد می‌کند.
  • بازبینی انتشار همیشه به هش‌های دقیق اسنپ‌شات و آرتیفکت متصل است. برای App، چکیدهٔ آرتیفکت همان چکیدهٔ تغییرناپذیر build میزبانی‌شده است؛ رکوردهای تاریخی فاقد این مدرک خواندنی می‌مانند، اما قابل انتشار نیستند.

اپ‌ها#

اپ برنامه‌ای کاربرمحور با مبدأ مشتق‌شدهٔ محصول، بک‌اند اختیاری، چرخهٔ داده و revisionهای باندل تغییرناپذیر خودش است. AppHost دسکتاپ آن را در WebContentsView ویژهٔ محصول اجرا می‌کند، بدون آن‌که اپ به کد یا Runtime محیط تبدیل شود. اپ می‌تواند از Home به‌صورت platform-hosted یا هنگام فعال بودن یک دنیا به‌صورت environment-hosted اجرا شود.

AppSession اختیار کوتاه‌عمر یک revision دقیق، نسل میزبان و permission-set digest است. نشست environment-hosted سه‌تایی کامل lease Runtime والد را هم دارد؛ نشست platform-hosted هیچ‌یک را ندارد و قابلیت Environment-scoped نمی‌گیرد. appActorSub نسبت به حساب و اپ جفتی است تا همان اپ کاربرش را میان محیط‌ها بدون دریافت شناسهٔ خام حساب بشناسد. این شناسه با actorSub پلاگین و actorKey میان‌پلاگینیِ محدود به دامنه متفاوت است.

هر revision حالت Compact دارد و Workspace presentation دوم و اختیاری همان سند است. تغییر حالت presentation میزبان را درجا به‌روز می‌کند و سند یا AppSession تازه‌ای نمی‌سازد.

AppCapabilityConsent تصمیم principal است که به App، scope محیط در صورت نیاز، digest درخواست revision، نسخهٔ capability و authority epoch متصل می‌شود؛ token یا اختیار دائمی نیست. HostSessionDescriptor projection زمان launch از grantها و نسل فعلی است.

پیکرهٔ شخصی متعلق به اپ به‌صورت پیش‌فرض environment_private است. گونهٔ actor_portable استثنایی بازبینی‌شده است: فقط-حساب، private_key_jwt، محیط فعلی introspectشده و فهرست مجاز صریح و غیرخالی محیط‌ها. Notes همین گونه را به‌کار می‌برد. Folder آن مستقیماً به actor جفتی اپ تعلق دارد؛ Note می‌تواند پوشه‌ای را نام ببرد و پیوست تغییرناپذیرِ بدون provenance، محیط، یا مکان captureشده داشته باشد. نه پوشه و نه پیوست اختیار را انتخاب نمی‌کند.

سند Notes یک AST بلوکی تخت، نسخه‌دار و متعلق به محصول است که شناسهٔ پایدار بلوک، بلوک body و heading سطح ۱ تا ۹ دارد. ویرایشگر عادی و اوتلاین دو projection همان سندند. شاخه‌های بسته، فیلتر سطح‌های قابل‌دیدن، selection و دیگر stateهای نمایشی اوتلاین سند دوم نیستند و به‌عنوان محتوا از قرارداد بک‌اند عبور نمی‌کنند.

واژگان مکانی و Host Services#

EnvironmentZone و EnvironmentSemanticLocation اصطلاحات تغییرناپذیر یک revision محیط‌اند؛ Project، اتاق Presence یا scene object عمومی نیستند. Zone partition معنایی فعلی و location مقصد authored پایدار با policy navigation است.

EnvironmentSpatialContext مشاهدهٔ یک visit شامل revision دقیق، visit ID، sequence صعودی، Zone، location اختیاری و زمان است و حقیقت آن در Adapter محیط قرار دارد.

EnvironmentLocationRef دو نوع دارد:

  • semantic به location اعلام‌شدهٔ پایدار اشاره می‌کند و برای launch میان محیط‌ها قابل validation است؛
  • captured locator opaque متصل به revision و resolver version است.

هیچ‌کدام pose بازیکن نیستند. captured میان revisionها portable نیست و داخل URL رجیستری قرار نمی‌گیرد. NavigationAssessment اختیار کوتاه‌عمر و caller-bound برای یک target است؛ commit از محیط حرکت می‌خواهد و رکورد حرکت رجیستری نمی‌سازد.

اعلان‌های پلتفرم#

NotificationOccurrence یک واقعیت تغییرناپذیر منبع با eventId پایدار و محدود به همان منبع است. revision دقیق App، family، مدل Subject، effectهای مجاز، منبع revision، preference key، policy Pulse و authorship presentation را بازبینی‌شده اعلام می‌کند. رجیستری یک occurrence دقیق را فقط یک بار می‌پذیرد؛ retry، revision قدیمی و revision پوشش‌داده‌شده با acknowledgement no-op هستند.

NotificationSubject projection جاری Center متعلق به رجیستری برای یک گفت‌وگو، سند، job، دعوت یا رخداد مستقل است. شناسهٔ opaque اعلان، revision دقیق منبع، event و family بازبینی‌شده، subjectRevision متعلق به منبع، projectionVersion متعلق به رجیستری، presentation/action محدود، expiry، scope، treatment و وضعیت seen/dismissed گیرنده را نگه می‌دارد. platform_notifications همین projection باقی می‌ماند و event store نمی‌شود؛ receipt رخداد و watermark acknowledgement رکوردهای کمکی محدودند.

Attention وضعیت ماندگار گیرنده برای revision جاری Subject است. Pulse درخواست گذرای نمایش یک episode واجد شرایط Attention است و از list، page، poll، boot یا reconnect بازسازی نمی‌شود. resolve متعلق به منبع Subject را می‌بندد، بدون اینکه ادعا کند گیرنده خوانده است. dismiss episode فعلی را مصرف می‌کند؛ raise جدیدتر می‌تواند آن را باز کند ولی refresh نمی‌تواند.

Desktop Shell projection کامل حساب را از device plane می‌خواند. Environment Widget فقط Subjectهای Environment جاری را می‌بیند. unseenCount ردیف quiet نوع mute را هم دارد؛ attentionCount آن را حذف می‌کند و badge و attention محیط را می‌سازد. unreadCount قدیمی برای reader immutable alias همان attention است.

NotificationPreference چیزی است که آدم دربارهٔ یک منبع یا یک منبع و preferenceKey بازبینی‌شده گفته: سطحی از default، announce، file یا mute و یک لحظهٔ اختیاری «الان نه». متعلق به گیرنده است، فقط از مبدأ رجیستری نوشته می‌شود و ثبت می‌کند از کدام محیط تنظیم شده تا اثر جهان کشف‌پذیر و برگشت‌پذیر بماند. ورودی تصمیم treatment هنگام reduction است و فیلتر خواندن نیست. متن منبع پیش‌فرض file دارد؛ template نوشته‌شده و بازبینی‌شدهٔ پلتفرم ممکن است پیش‌فرض announce داشته باشد. mute منبع همیشه floor است.

NotificationDelegation mapping تاریخ‌دار و revocable از یک secret opaque به principal حساب جفتی یک App است و رجیستری فقط hash آن را نگه می‌دارد. delegation به revision/digest اپ، authority epoch ناشر، consent و expiry متصل است. Project token پروژهٔ workload را ثابت می‌کند ولی principal انتخاب نمی‌کند؛ delegation فقط همان principal رضایت‌داده را مشخص می‌کند. بک‌اند محیط از Grant کوتاه‌عمر موجود خود استفاده می‌کند و این entity را ندارد.

CallAlert projection زنده و deadline-bound حقیقت backend است و Notification Subject، unread state یا Pulse نیست. Delivery به‌ازای هر دستگاه نیز جداست: نمایش Pulse یا live alert نمی‌تواند News را seen کند یا حقیقت تماس را تعیین کند. V1 اولیه CallAlert عمومی account/device را پیاده نمی‌کند؛ سفر تماس موجود Hub/Media در منبع خودش می‌ماند. push خارجی بخشی از V1 نیست.

بک‌اند متعلق به Environment#

این بک‌اند زیرساخت ناشر برای دامنهٔ یک Environment است؛ نه BackendDeploymentRevision رجیستری و نه BackendComponent پلاگین. revision محیط audience، endpoint، health، scopeها، context schema و disclosureها را ثابت می‌کند، ولی رکوردهای دامنه و نقش‌های تفویضی بیرون Registry ذخیره می‌شوند.

EnvironmentBackendGrant شامل actor جفتی با Environment، actorKey اختیاریِ محدود به scope، نقش محیط، context اعتبارسنجی‌شده و lease حصارشدهٔ Runtime است و subject خام حساب را افشا نمی‌کند. بک‌اند پیش از دسترسی به داده باید این مجوز را بررسی و وضعیت زندهٔ آن را introspect کند.

شکل‌های پلاگین#

  • frontend_only: یک یا چند آداپتور فرانت‌اند و بدون مولفهٔ بک‌اند.
  • full_stack: دست‌کم یک آداپتور فرانت‌اند و یک مولفهٔ بک‌اند.
  • backend_only: دست‌کم یک مولفهٔ بک‌اند و بدون آداپتور فرانت‌اند.

یک Environment تغییرناپذیر برای هر Plugin حداکثر یک نصب دارد و صریحاً یا یک frontend_adapter یا مجموعهٔ backend_components همان release دقیق را انتخاب می‌کند. حالت دوم آداپتر مرورگر یا artifact پکیج محلی ندارد. نصب release تمام‌پشته با frontend_adapter، مولفه‌های بک‌اند بازبینی‌شدهٔ همان release را نیز برای Runtime Grantهای محدود مجاز می‌کند؛ نصب تکراری بک‌اند لازم یا معتبر نیست. ترکیب معنایی فقط نصب‌های frontend-adapter را می‌بیند. نصب‌های قدیمیِ فاقد discriminator خواندنی می‌مانند و به lockfile v3 reconcile می‌شوند. برای جزئیات ADR-0058 را ببینید.

هر release تازه‌منتشرشده که مولفهٔ بک‌اند دارد، هر مولفه را به artifact تغییرناپذیر پروتکل متصل می‌کند. انتشار، بایت‌های ثابت‌شدهٔ بسته، مسیر گزارش‌شده توسط validator و چکیدهٔ محاسبه‌شده را با مرجع manifest می‌سنجد؛ نبود مرجع، نبود بایت یا ناهماهنگی چکیده به‌صورت fail-closed رد می‌شود. رکوردهای تاریخی منتشرشده خواندنی می‌مانند، اما بررسی انتشارهای جدید را تضعیف نمی‌کنند.

Player Rig پلاگین رسمی و قابل استفادهٔ مجدد از نوع frontend_only است. انتشارهای آن قابلیت‌های R3F مستقل از میزبان ارائه می‌کنند؛ این پلاگین مالک گراف ناحیه‌های هاب، جست‌وجوی کاتالوگ رجیستری، مقصد پرتال یا مسیر برنامه نیست.

ناحیه‌های محلی هاب#

ناحیه (Zone) نه موجودیتی در دامنهٔ رجیستری است، نه پروژه یا محیط و نه اسنپ‌شات انتشار. ناحیه صحنه‌ای با نشانی محلی درون env_hub است. بنابراین همهٔ ناحیه‌های هاب یک مالک، مبدأ، سیاست دسترسی، هویت زمان اجرا و حضور، رکورد سلامت، مجموعهٔ دقیق پلاگین‌های نصب‌شده، تنظیمات پلاگین و بازنگری محیط را به اشتراک می‌گذارند.

داده‌های گراف ناحیه‌ها، پوسته‌های بصری، مسیرها و زمین، نقاط آغاز و جای‌گذاری پرتال به هماهنگ‌سازی برنامهٔ هاب تعلق دارند. یک فضا زمانی به محیطی مستقل تبدیل می‌شود که به سیاست دسترسی، مالک، مبدأ، هویت حضور یا سلامت، مجموعهٔ نصب پلاگین یا چرخهٔ انتشار مستقل نیاز داشته باشد.

HubPlacementSlot مرجع محدود و تألیف‌شده‌ای با هویت Environment هاب، Zone و slotId است و هندسهٔ دلخواه Registry نیست. حالت گزینش fixed یا manual و ترتیب آن به موجودی تألیف‌شده تعلق دارد. HubEnvironmentPlacement در Registry فقط تخصیص اختیاری آن اسلات به یک Environment مقصد پایدار، مدیر و زمان تغییر را ثبت می‌کند. هر مقصد در یک Hub حداکثر یک بار تخصیص می‌یابد.

open، occupied و reserved وضعیت‌های خواندنی مشتق‌شده‌اند، نه پرچم workflow قابل تغییر. فقط اسلات manual بدون تخصیص open است. تخصیص فقط وقتی occupied است که مقصد به revision فعال، منتشرشده و عمومی کاتالوگ حل شود؛ اسلات fixed بدون تخصیص یا مقصد تخصیص‌یافتهٔ فاقد شرایط reserved است. خواندن عمومی فقط برای occupied مقصد را افشا می‌کند، ولی مدل مدیر metadata تخصیص را برای عیب‌یابی و clear نگه می‌دارد.

checkpoint بازگشت هاب، وضعیت زودگذر مسیریابیِ محیط مبدأ است؛ نه موجودیت رجیستری، claim زمان اجرا، رکورد حضور یا دامنهٔ تنظیمات. این checkpoint نسخه‌دار و محدود به یک تب مرورگر است، فقط برای خروجی صریح فعال می‌شود و پس از بازیابی امن ناحیه، وضعیت بی‌حرکت بازیکن و نمای دوربین مصرف می‌شود. ورود تازه و دادهٔ نامعتبر همچنان از نقطهٔ آغاز تألیف‌شدهٔ ناحیه استفاده می‌کنند.

تنظیمات#

تنظیمات پنج دامنه (scope) دارند: مقدار پیش‌فرض طرح‌واره، پیکربندی محیط، مقدار سراسری کاربر، مقدار کاربر در یک محیط و نشست محلی. ترتیب حل مقدار چنین است:

session > user_environment > user > environment > plugin_default

تنظیمات ماندگار کاربر با شناسهٔ پلاگین و نسخهٔ اصلی طرح‌وارهٔ تنظیمات، فضای نام جداگانه می‌گیرند. مولفهٔ بک‌اند به‌جای شناسهٔ سراسری کاربر، شناسهٔ کنشگر پایدار و جفتی ویژهٔ همان پلاگین را دریافت می‌کند.

چون تنظیمات ماندگار در سطح محیط قرار دارند، نه ناحیه، ترجیح‌های پلاگین در سراسر هاب و همهٔ ناحیه‌ها اعمال می‌شوند. پیش‌تنظیم‌های بصری و ترکیب‌بندی ویژهٔ هر ناحیه به‌صورت propهای نوع‌دار از میزبان فرستاده می‌شوند و دامنهٔ ششمی برای تنظیمات ایجاد نمی‌کنند.

یک scope در Multiplayer می‌تواند برای مدیریت علاقه بازتاب شناسهٔ ناحیه باشد، اما ناحیه را به دامنهٔ رجیستری ارتقا نمی‌دهد. کلید اتاق از هویت امضاشدهٔ محیط در Grant و scope اعتبارسنجی‌شدهٔ میزبان ساخته می‌شود. Presence زمان اجرا همچنان در سطح محیط است و عضویت زودگذر scope فقط به BackendComponent پلاگین Multiplayer تعلق دارد. هر اتاق دقیق یک epoch زودگذر، handleهای uint16 برای replicaها، ظرفیت بازبینی‌شدهٔ ۱۵۰ نشست حفظ‌شده و یک نویسندهٔ حصارشده دارد. این‌ها مفاهیم انتقال هستند، نه موجودیت‌های ماندگار Registry. هر واحد ظرفیت افزون بر این، حداکثر ۱۵۰ اعتبار participant و ۱۶ اعتبار اتاقِ غیرخالی دارد. descriptorهای حفظ‌شدهٔ مالک برای اتاق خالی هیچ اعتباری مصرف نمی‌کنند. رکورد مالک اتاق major پروتکل wire را نیز حمل می‌کند تا دو major ناسازگار نتوانند به یکدیگر route شوند یا رکورد مبادله کنند.

scope در Media نیز موجودیت Registry نیست؛ یک بخش‌بندی زودگذر میزبان است که با شناسهٔ امضاشدهٔ Environment ترکیب می‌شود. فضاهای جلسه و استیج در پیکربندی تغییرناپذیر نصب Environment تعریف می‌شوند و دعوت، عضویت، نقش و lease اشتراک صفحه داده‌های زودگذر BackendComponent هستند. حرکت، Zone، موقعیت و نزدیکی نزد Environment و Multiplayer می‌مانند و وضعیت Media نیستند. Media v2 وضعیت عملیاتی خود را به‌اندازه‌ای در Redis پایدار می‌کند که از راه‌اندازی مجدد سرویس کنترل جان سالم به در ببرد؛ این دوام، نشست Media را به موجودیت دامنه‌ای Registry تبدیل نمی‌کند. Grant فقط با مجوز profile:read می‌تواند نام نمایشی و آواتار را حمل کند و هرگز ایمیل را در اختیار Media نمی‌گذارد.

actorKey یک مقدار همبستگی زودگذر است، نه موجودیت جدید Actor یا Presence. Registry آن را از principal جفتی Environment که با HMAC محافظت شده و scope اعتبارسنجی‌شده مشتق می‌کند و همان مقدار نهایی را در Grant پلاگین‌های همکار امضا می‌کند. BackendComponentها این claim را مصرف می‌کنند، نه actorSub متفاوت هر Plugin را. مقدار فقط در همان بخش پایدار است تا Environment بتواند بدون افشای subject حساب یا ردیابی میان‌محیطی، اکشن Media را به آواتار replicated وصل کند. سطوح معنایی مانند avatar.overhead، avatar.fleet و avatar.fleet-overhead متادیتای ترکیب آداپتور هستند، نه اشیای صحنهٔ متعلق به Registry یا slotهای رابط قابل ویرایش.

مالک محیط و پیکربندی نصب

مالک احراز‌شدهٔ Project مرجع مدیریت است و Publisher فقط انتساب عمومی کاتالوگ است. رجیستری مالک Project از نوع Environment را بدون افشای subject خام حساب، ادمین اولیهٔ Runtime همان محیط می‌کند. مالک App و Plugin فقط دسترسی Project دارد. نقش‌های تفویضی رکورد مستقل رجیستری دارند و از flag کلاینت ساخته نمی‌شوند. مالک فعلی می‌تواند مالکیت را به یک عضو موجود منتقل کند؛ کاهش نقش مالک قبلی، ارتقای عضو هدف، تغییر ستون مالک معتبر و audit دلیل در یک تراکنش انجام می‌شود. گرنت‌های جدید Environment نیز admin را از مالک جدید مشتق می‌کنند.

environmentConfig تغییرناپذیر هر نصب، لایهٔ تنظیمات کاربر نیست. پلاگین می‌تواند برای سیاست پیچیدهٔ میزبان مانند آرایهٔ spaceهای Media یک environmentConfigSchema محدود و بسته اعلام کند. رجیستری همان مقدار دقیق نسخه را با آن می‌سنجد. در stage، ورود نیازمند media:join-space و انتشار صدا یا صفحه نیازمند scope امضاشدهٔ media:publish است؛ ترتیب ورود هیچ‌کس را ارائه‌دهنده نمی‌کند.