genesis.py
python
sha256:bba4b69de173366aeb7d490d687ccffb6db9726374033addece89cf2b87642d8
docs: add production launch discovery report and infra laun…
Sonnet 5
7 days ago
| 1 | """Genesis ID computation — canonical sha256: identities for every first-class entity. |
| 2 | |
| 3 | Every first-class semantic entity in the Muse ecosystem has an identity derived |
| 4 | from the minimal immutable facts about the moment it was declared to exist: its |
| 5 | **genesis context**. The formula is universal: |
| 6 | |
| 7 | entity_id = blob_id(NUL.join(genesis_fields).encode()) |
| 8 | |
| 9 | This is a **verifiability guarantee**: anyone who knows the genesis context of |
| 10 | an entity can independently derive its canonical identity and verify it matches. |
| 11 | UUIDs carry no such guarantee — they are opaque, random, and unverifiable. |
| 12 | |
| 13 | Separator |
| 14 | --------- |
| 15 | ``_SEP = "\\x00"`` (NUL byte) — the same separator used by |
| 16 | ``muse.core.snapshot`` for snapshot and commit IDs. It prevents |
| 17 | separator-injection attacks from field values containing ``|``, ``:``, or |
| 18 | other common separators. |
| 19 | |
| 20 | CONTRACT |
| 21 | -------- |
| 22 | Functions that have counterparts in ``muse.core.genesis`` (CLI-side) MUST |
| 23 | produce identical output for the same inputs. Any change to the hashing |
| 24 | algorithm or field ordering must be applied to both sides simultaneously. |
| 25 | A mismatch is a silent identity bug. |
| 26 | |
| 27 | Cross-verified by ``tests/test_genesis_ids.py``. |
| 28 | """ |
| 29 | |
| 30 | from muse.core.types import blob_id, public_key_fingerprint, short_id |
| 31 | |
| 32 | # Must match muse.core.snapshot._SEP and muse.core.genesis._SEP exactly. |
| 33 | _SEP = "\x00" |
| 34 | |
| 35 | def _genesis_hash(*fields: str) -> str: |
| 36 | """Return ``sha256:<hex>`` of NUL-joined *fields*. |
| 37 | |
| 38 | All fields must be non-empty strings representing stable, immutable |
| 39 | facts about the entity's declaration event. Field order is significant |
| 40 | — callers are responsible for a consistent, documented order. |
| 41 | """ |
| 42 | payload = _SEP.join(fields).encode() |
| 43 | return blob_id(payload) |
| 44 | |
| 45 | # --------------------------------------------------------------------------- |
| 46 | # Identity |
| 47 | # --------------------------------------------------------------------------- |
| 48 | |
| 49 | def compute_derived_agent_id(handle: str) -> str: |
| 50 | """Return a deterministic genesis identity_id for an agent known only by handle. |
| 51 | |
| 52 | Used when an agent appears in commit metadata but was never formally registered |
| 53 | with a key pair. The genesis context is the type discriminator + handle: |
| 54 | |
| 55 | identity_id = sha256("agent_handle" NUL handle) |
| 56 | |
| 57 | Anyone who knows the agent's handle can independently verify this ID. |
| 58 | """ |
| 59 | return _genesis_hash("agent_handle", handle) |
| 60 | |
| 61 | def compute_derived_org_id(handle: str) -> str: |
| 62 | """Return a deterministic genesis identity_id for an org known only by handle. |
| 63 | |
| 64 | identity_id = sha256("org_handle" NUL handle) |
| 65 | |
| 66 | Anyone who knows the org's handle can independently verify this ID. |
| 67 | """ |
| 68 | return _genesis_hash("org_handle", handle) |
| 69 | |
| 70 | def compute_identity_id(public_key_bytes: bytes) -> str: |
| 71 | """Return the canonical identity ID for an Ed25519 public key. |
| 72 | |
| 73 | The identity IS the key pair — the public key bytes are the complete, |
| 74 | immutable genesis context. No other fields are needed or included. |
| 75 | |
| 76 | This is the server-side equivalent of the MSign fingerprint: anyone who |
| 77 | holds the public key can independently derive the identity_id. |
| 78 | |
| 79 | identity_id = public_key_fingerprint(public_key_bytes) |
| 80 | """ |
| 81 | return public_key_fingerprint(public_key_bytes) |
| 82 | |
| 83 | # --------------------------------------------------------------------------- |
| 84 | # Repo |
| 85 | # --------------------------------------------------------------------------- |
| 86 | |
| 87 | def compute_repo_id( |
| 88 | owner_identity_id: str, |
| 89 | slug: str, |
| 90 | domain: str, |
| 91 | created_at_iso: str, |
| 92 | ) -> str: |
| 93 | """Return the canonical repo ID from its declaration event. |
| 94 | |
| 95 | The repo declaration is immutable: owner, slug, domain, and timestamp |
| 96 | uniquely identify the moment a repo was brought into existence. |
| 97 | Subsequent renames or transfers update ``owner``/``slug`` alias columns |
| 98 | only — the ``repo_id`` never changes. |
| 99 | |
| 100 | repo_id = sha256(owner_identity_id NUL slug NUL domain NUL created_at_iso) |
| 101 | |
| 102 | *owner_identity_id* is itself a genesis-addressed identity ID |
| 103 | (``sha256:<pubkey_hash>``), so the repo ID transitively encodes the |
| 104 | owner's cryptographic identity. |
| 105 | """ |
| 106 | return _genesis_hash(owner_identity_id, slug, domain, created_at_iso) |
| 107 | |
| 108 | # --------------------------------------------------------------------------- |
| 109 | # Issue |
| 110 | # --------------------------------------------------------------------------- |
| 111 | |
| 112 | def compute_issue_id( |
| 113 | repo_id: str, |
| 114 | author_identity_id: str, |
| 115 | created_at_iso: str, |
| 116 | ) -> str: |
| 117 | """Return the canonical issue ID from its declaration event. |
| 118 | |
| 119 | The integer ``number`` field is a human-readable alias; the ``issue_id`` |
| 120 | is the permanent, verifiable identity. |
| 121 | |
| 122 | issue_id = sha256(repo_id NUL author_identity_id NUL created_at_iso) |
| 123 | """ |
| 124 | return _genesis_hash(repo_id, author_identity_id, created_at_iso) |
| 125 | |
| 126 | # --------------------------------------------------------------------------- |
| 127 | # Proposal |
| 128 | # --------------------------------------------------------------------------- |
| 129 | |
| 130 | def compute_proposal_id( |
| 131 | repo_id: str, |
| 132 | author_identity_id: str, |
| 133 | from_branch: str, |
| 134 | to_branch: str, |
| 135 | created_at_iso: str, |
| 136 | ) -> str: |
| 137 | """Return the canonical proposal ID from its declaration event. |
| 138 | |
| 139 | The proposal declares intent to merge *from_branch* into *to_branch* at |
| 140 | a specific moment. ``proposal_number`` is a human-readable alias. |
| 141 | |
| 142 | proposal_id = sha256(repo_id NUL author_identity_id NUL from_branch NUL to_branch NUL created_at_iso) |
| 143 | """ |
| 144 | return _genesis_hash(repo_id, author_identity_id, from_branch, to_branch, created_at_iso) |
| 145 | |
| 146 | # --------------------------------------------------------------------------- |
| 147 | # Release |
| 148 | # --------------------------------------------------------------------------- |
| 149 | |
| 150 | def compute_release_id( |
| 151 | repo_id: str, |
| 152 | tag: str, |
| 153 | created_at_iso: str, |
| 154 | ) -> str: |
| 155 | """Return the canonical release ID from its declaration event. |
| 156 | |
| 157 | The semver tag string (e.g. ``v1.2.3``) is stable per repo. Combined |
| 158 | with ``repo_id`` and ``created_at`` it uniquely identifies the release |
| 159 | declaration. |
| 160 | |
| 161 | release_id = sha256(repo_id NUL tag NUL created_at_iso) |
| 162 | |
| 163 | CONTRACT: must match ``muse.core.genesis.compute_release_id`` exactly. |
| 164 | """ |
| 165 | return _genesis_hash(repo_id, tag, created_at_iso) |
| 166 | |
| 167 | # --------------------------------------------------------------------------- |
| 168 | # Tag (wire tag / semantic label) |
| 169 | # --------------------------------------------------------------------------- |
| 170 | |
| 171 | def compute_tag_id( |
| 172 | repo_id: str, |
| 173 | commit_id: str, |
| 174 | label: str, |
| 175 | created_at_iso: str, |
| 176 | ) -> str: |
| 177 | """Return the canonical tag ID from its declaration event. |
| 178 | |
| 179 | A semantic label (e.g. ``emotion:joyful``, ``section:verse``) is applied |
| 180 | to a specific commit at a specific time. The same label can be applied |
| 181 | to different commits, so ``commit_id`` and ``created_at`` are both part |
| 182 | of the genesis context. |
| 183 | |
| 184 | tag_id = sha256(repo_id NUL commit_id NUL label NUL created_at_iso) |
| 185 | |
| 186 | CONTRACT: must match ``muse.core.genesis.compute_tag_id`` exactly. |
| 187 | """ |
| 188 | return _genesis_hash(repo_id, commit_id, label, created_at_iso) |
| 189 | |
| 190 | # --------------------------------------------------------------------------- |
| 191 | # Branch |
| 192 | # --------------------------------------------------------------------------- |
| 193 | |
| 194 | def compute_branch_id(repo_id: str, name: str) -> str: |
| 195 | """Return the canonical branch ID from its declaration context. |
| 196 | |
| 197 | A branch is uniquely identified by its name within a repo. The same |
| 198 | name always refers to the same logical branch — delete + recreate yields |
| 199 | the same ID because it is still "branch *name* in repo *repo_id*". |
| 200 | |
| 201 | branch_id = sha256(repo_id NUL name) |
| 202 | """ |
| 203 | return _genesis_hash(repo_id, name) |
| 204 | |
| 205 | # --------------------------------------------------------------------------- |
| 206 | # Session |
| 207 | # --------------------------------------------------------------------------- |
| 208 | |
| 209 | def compute_session_id( |
| 210 | repo_id: str, |
| 211 | author_identity_id: str, |
| 212 | started_at_iso: str, |
| 213 | ) -> str: |
| 214 | """Return the canonical session ID from its declaration event. |
| 215 | |
| 216 | A recording session is declared at a specific moment by a specific |
| 217 | identity within a specific repo. |
| 218 | |
| 219 | session_id = sha256(repo_id NUL author_identity_id NUL started_at_iso) |
| 220 | """ |
| 221 | return _genesis_hash(repo_id, author_identity_id, started_at_iso) |
| 222 | |
| 223 | # --------------------------------------------------------------------------- |
| 224 | # Mist |
| 225 | # --------------------------------------------------------------------------- |
| 226 | |
| 227 | def compute_mist_id(content: bytes) -> str: |
| 228 | """Return the canonical mist ID — content-addressed, full sha256: form. |
| 229 | |
| 230 | Mists are immutable single-artifact shares: the content IS the identity. |
| 231 | The previous 12-char base-58 encoding was a display alias; this function |
| 232 | returns the full canonical ID. The short display form is derived |
| 233 | separately from the first 12 hex chars of the digest. |
| 234 | |
| 235 | mist_id = blob_id(content) |
| 236 | """ |
| 237 | return blob_id(content) |
| 238 | |
| 239 | def mist_short_id(mist_id: str) -> str: |
| 240 | """Return the 12-char human-readable alias for a mist. |
| 241 | |
| 242 | Derived from the first 12 hex chars of the sha256 digest (after the |
| 243 | ``sha256:`` prefix). Used for short URLs and display; not a PK. |
| 244 | """ |
| 245 | return short_id(mist_id, strip=True) |
| 246 | |
| 247 | # --------------------------------------------------------------------------- |
| 248 | # Issue comment |
| 249 | # --------------------------------------------------------------------------- |
| 250 | |
| 251 | def compute_comment_id( |
| 252 | parent_id: str, |
| 253 | author_identity_id: str, |
| 254 | created_at_iso: str, |
| 255 | ) -> str: |
| 256 | """Return the canonical comment ID from its declaration event. |
| 257 | |
| 258 | Used for both issue comments and proposal inline comments. |
| 259 | *parent_id* is the ``issue_id`` or ``proposal_id`` the comment belongs to. |
| 260 | |
| 261 | comment_id = sha256(parent_id NUL author_identity_id NUL created_at_iso) |
| 262 | """ |
| 263 | return _genesis_hash(parent_id, author_identity_id, created_at_iso) |
| 264 | |
| 265 | # --------------------------------------------------------------------------- |
| 266 | # Proposal review |
| 267 | # --------------------------------------------------------------------------- |
| 268 | |
| 269 | def compute_review_id( |
| 270 | proposal_id: str, |
| 271 | reviewer_identity_id: str, |
| 272 | created_at_iso: str, |
| 273 | ) -> str: |
| 274 | """Return the canonical review ID from its declaration event. |
| 275 | |
| 276 | A formal review submission is declared by a specific reviewer on a |
| 277 | specific proposal at a specific time. |
| 278 | |
| 279 | review_id = sha256(proposal_id NUL reviewer_identity_id NUL created_at_iso) |
| 280 | """ |
| 281 | return _genesis_hash(proposal_id, reviewer_identity_id, created_at_iso) |
| 282 | |
| 283 | # --------------------------------------------------------------------------- |
| 284 | # Label |
| 285 | # --------------------------------------------------------------------------- |
| 286 | |
| 287 | def compute_label_id( |
| 288 | repo_id: str, |
| 289 | name: str, |
| 290 | created_at_iso: str, |
| 291 | ) -> str: |
| 292 | """Return the canonical label ID from its declaration event. |
| 293 | |
| 294 | A label is scoped to a repo and declared at a specific moment. The name |
| 295 | is immutable after creation — updates change the colour/description only, |
| 296 | never the identity. |
| 297 | |
| 298 | label_id = sha256(repo_id NUL name NUL created_at_iso) |
| 299 | """ |
| 300 | return _genesis_hash(repo_id, name, created_at_iso) |
| 301 | |
| 302 | # --------------------------------------------------------------------------- |
| 303 | # Release asset |
| 304 | # --------------------------------------------------------------------------- |
| 305 | |
| 306 | def compute_asset_id( |
| 307 | release_id: str, |
| 308 | filename: str, |
| 309 | created_at_iso: str, |
| 310 | ) -> str: |
| 311 | """Return the canonical asset ID from its declaration event. |
| 312 | |
| 313 | A release asset is a named artifact attached to a specific release at a |
| 314 | specific moment. The filename is unique per release — adding the timestamp |
| 315 | makes the formula robust to edge cases (e.g. delete + re-upload). |
| 316 | |
| 317 | asset_id = sha256(release_id NUL filename NUL created_at_iso) |
| 318 | """ |
| 319 | return _genesis_hash(release_id, filename, created_at_iso) |
| 320 | |
| 321 | # --------------------------------------------------------------------------- |
| 322 | # Webhook |
| 323 | # --------------------------------------------------------------------------- |
| 324 | |
| 325 | def compute_webhook_id( |
| 326 | repo_id: str, |
| 327 | url: str, |
| 328 | created_at_iso: str, |
| 329 | ) -> str: |
| 330 | """Return the canonical webhook ID from its registration event. |
| 331 | |
| 332 | A webhook subscription is declared by registering a URL to receive events |
| 333 | from a specific repo at a specific moment. The declaration event is |
| 334 | immutable — the URL, repo, and timestamp together uniquely identify it. |
| 335 | |
| 336 | webhook_id = sha256(repo_id NUL url NUL created_at_iso) |
| 337 | """ |
| 338 | return _genesis_hash(repo_id, url, created_at_iso) |
| 339 | |
| 340 | # --------------------------------------------------------------------------- |
| 341 | # Fork |
| 342 | # --------------------------------------------------------------------------- |
| 343 | |
| 344 | def compute_fork_id( |
| 345 | source_repo_id: str, |
| 346 | fork_repo_id: str, |
| 347 | created_at_iso: str, |
| 348 | ) -> str: |
| 349 | """Return the canonical fork relationship ID from its declaration event. |
| 350 | |
| 351 | A fork relationship is immutable: a specific repo (fork_repo_id) was forked |
| 352 | from a specific source (source_repo_id) at a specific moment. |
| 353 | |
| 354 | fork_id = sha256(source_repo_id NUL fork_repo_id NUL created_at_iso) |
| 355 | """ |
| 356 | return _genesis_hash(source_repo_id, fork_repo_id, created_at_iso) |
| 357 | |
| 358 | # --------------------------------------------------------------------------- |
| 359 | # Collaborator |
| 360 | # --------------------------------------------------------------------------- |
| 361 | |
| 362 | def compute_collaborator_id( |
| 363 | repo_id: str, |
| 364 | identity_id: str, |
| 365 | created_at_iso: str, |
| 366 | ) -> str: |
| 367 | """Return the canonical collaborator ID from its declaration event. |
| 368 | |
| 369 | A collaborator invitation is a first-class declaration: a specific identity |
| 370 | is granted access to a specific repo at a specific moment. |
| 371 | |
| 372 | collaborator_id = sha256(repo_id NUL identity_id NUL created_at_iso) |
| 373 | """ |
| 374 | return _genesis_hash(repo_id, identity_id, created_at_iso) |
| 375 | |
| 376 | # --------------------------------------------------------------------------- |
| 377 | # Auth key |
| 378 | # --------------------------------------------------------------------------- |
| 379 | |
| 380 | def compute_key_id( |
| 381 | identity_id: str, |
| 382 | public_key_b64: str, |
| 383 | ) -> str: |
| 384 | """Return the canonical auth key ID from its registration context. |
| 385 | |
| 386 | The key IS its bytes — there is no stronger genesis context. No timestamp |
| 387 | is needed because a given public key can only be registered once per |
| 388 | identity (enforced by the UNIQUE fingerprint constraint). |
| 389 | |
| 390 | key_id = sha256(identity_id NUL public_key_b64) |
| 391 | """ |
| 392 | return _genesis_hash(identity_id, public_key_b64) |
| 393 | |
| 394 | # --------------------------------------------------------------------------- |
| 395 | # Domain plugin |
| 396 | # --------------------------------------------------------------------------- |
| 397 | |
| 398 | def compute_domain_id( |
| 399 | author_slug: str, |
| 400 | slug: str, |
| 401 | created_at_iso: str, |
| 402 | ) -> str: |
| 403 | """Return the canonical domain plugin ID from its registration event. |
| 404 | |
| 405 | A domain plugin is identified by its scoped name (@author_slug/slug) and |
| 406 | the moment it was registered. The scoped name is already enforced as a |
| 407 | unique composite in the DB, so the timestamp distinguishes re-registration |
| 408 | after deletion. |
| 409 | |
| 410 | domain_id = sha256(author_slug NUL slug NUL created_at_iso) |
| 411 | """ |
| 412 | return _genesis_hash(author_slug, slug, created_at_iso) |
| 413 | |
| 414 | # --------------------------------------------------------------------------- |
| 415 | # Intel result |
| 416 | # --------------------------------------------------------------------------- |
| 417 | |
| 418 | def compute_intel_result_id( |
| 419 | repo_id: str, |
| 420 | intel_type: str, |
| 421 | ref: str, |
| 422 | ) -> str: |
| 423 | """Return the canonical intel result ID from its computation context. |
| 424 | |
| 425 | An intelligence result is uniquely identified by what was computed |
| 426 | (intel_type), for which repo, and at which commit (ref). |
| 427 | |
| 428 | result_id = sha256(repo_id NUL intel_type NUL ref) |
| 429 | """ |
| 430 | return _genesis_hash(repo_id, intel_type, ref) |
| 431 | |
| 432 | # --------------------------------------------------------------------------- |
| 433 | # Attestation |
| 434 | # --------------------------------------------------------------------------- |
| 435 | |
| 436 | def compute_attestation_id( |
| 437 | attester: str, |
| 438 | subject: str, |
| 439 | claim: str, |
| 440 | issued_at_iso: str, |
| 441 | ) -> str: |
| 442 | """Return the canonical attestation ID. |
| 443 | |
| 444 | attestation_id = sha256(attester NUL subject NUL claim NUL issued_at_iso) |
| 445 | |
| 446 | Attestations are issued once and never mutated; ``issued_at_iso`` breaks |
| 447 | ties so the same claim can be re-issued after a previous one is revoked. |
| 448 | """ |
| 449 | return _genesis_hash(attester, subject, claim, issued_at_iso) |
| 450 | |
| 451 | # --------------------------------------------------------------------------- |
| 452 | # Bridge mirror |
| 453 | # --------------------------------------------------------------------------- |
| 454 | |
| 455 | def compute_bridge_mirror_id(repo_id: str, git_remote_url: str) -> str: |
| 456 | """Return the canonical bridge mirror ID. |
| 457 | |
| 458 | A Git mirror registration is uniquely identified by the repo it mirrors |
| 459 | and the remote URL — the UNIQUE(repo_id, git_remote_url) constraint |
| 460 | enforces exactly one row, so no timestamp is needed. |
| 461 | |
| 462 | bridge_mirror_id = sha256(repo_id NUL git_remote_url) |
| 463 | """ |
| 464 | return _genesis_hash(repo_id, git_remote_url) |
| 465 | |
| 466 | # --------------------------------------------------------------------------- |
| 467 | # Domain install |
| 468 | # --------------------------------------------------------------------------- |
| 469 | |
| 470 | def compute_domain_install_id(user_id: str, domain_id: str) -> str: |
| 471 | """Return the canonical domain install ID. |
| 472 | |
| 473 | A domain installation is uniquely identified by the user and the domain — |
| 474 | the UNIQUE(user_id, domain_id) constraint enforces exactly one row per |
| 475 | user per domain, so no timestamp is needed. |
| 476 | |
| 477 | domain_install_id = sha256(user_id NUL domain_id) |
| 478 | """ |
| 479 | return _genesis_hash(user_id, domain_id) |
| 480 | |
| 481 | # --------------------------------------------------------------------------- |
| 482 | # Issue event |
| 483 | # --------------------------------------------------------------------------- |
| 484 | |
| 485 | def compute_issue_event_id( |
| 486 | issue_id: str, |
| 487 | event_type: str, |
| 488 | actor: str, |
| 489 | created_at_iso: str, |
| 490 | ) -> str: |
| 491 | """Return the canonical issue event ID. |
| 492 | |
| 493 | An activity event on an issue is uniquely identified by the issue it |
| 494 | belongs to, the type of event, the actor who triggered it, and the |
| 495 | moment it occurred. |
| 496 | |
| 497 | issue_event_id = sha256(issue_id NUL event_type NUL actor NUL created_at_iso) |
| 498 | """ |
| 499 | return _genesis_hash(issue_id, event_type, actor, created_at_iso) |
| 500 | |
| 501 | # --------------------------------------------------------------------------- |
| 502 | # Background job |
| 503 | # --------------------------------------------------------------------------- |
| 504 | |
| 505 | def compute_job_id(repo_id: str, job_type: str, created_at_iso: str) -> str: |
| 506 | """Return the canonical background job ID. |
| 507 | |
| 508 | A background job is uniquely identified by the repo it operates on, |
| 509 | the type of work to perform, and the moment it was enqueued. If the |
| 510 | same job_type is enqueued twice for the same repo at the same instant, |
| 511 | the duplicate is rejected — which is the correct deduplication behavior. |
| 512 | |
| 513 | job_id = sha256(repo_id NUL job_type NUL created_at_iso) |
| 514 | """ |
| 515 | return _genesis_hash(repo_id, job_type, created_at_iso) |
| 516 | |
| 517 | # --------------------------------------------------------------------------- |
| 518 | # Webhook delivery |
| 519 | # --------------------------------------------------------------------------- |
| 520 | |
| 521 | def compute_webhook_delivery_id( |
| 522 | webhook_id: str, |
| 523 | event_type: str, |
| 524 | attempt: int, |
| 525 | delivered_at_iso: str, |
| 526 | ) -> str: |
| 527 | """Return the canonical webhook delivery ID. |
| 528 | |
| 529 | Each delivery attempt is a distinct event: the same webhook can fire |
| 530 | multiple times for the same event_type (retries increment ``attempt``). |
| 531 | Together they form a unique declaration. |
| 532 | |
| 533 | delivery_id = sha256(webhook_id NUL event_type NUL str(attempt) NUL delivered_at_iso) |
| 534 | """ |
| 535 | return _genesis_hash(webhook_id, event_type, str(attempt), delivered_at_iso) |
| 536 | |
| 537 | # --------------------------------------------------------------------------- |
| 538 | # Coord task |
| 539 | # --------------------------------------------------------------------------- |
| 540 | |
| 541 | def compute_task_id( |
| 542 | repo_id: str, |
| 543 | queue: str, |
| 544 | created_by: str, |
| 545 | created_at_iso: str, |
| 546 | ) -> str: |
| 547 | """Return the canonical coord task ID from its enqueue event. |
| 548 | |
| 549 | A task is declared by an agent into a queue within a repo at a specific |
| 550 | moment. Same inputs always produce the same ID — enabling idempotent |
| 551 | enqueue (re-enqueueing the same task at the same instant is a no-op). |
| 552 | |
| 553 | task_id = sha256(repo_id NUL queue NUL created_by NUL created_at_iso) |
| 554 | """ |
| 555 | return _genesis_hash(repo_id, queue, created_by, created_at_iso) |
| 556 | |
| 557 | # --------------------------------------------------------------------------- |
| 558 | # Coord reservation |
| 559 | # --------------------------------------------------------------------------- |
| 560 | |
| 561 | def compute_reservation_id( |
| 562 | repo_id: str, |
| 563 | agent_id: str, |
| 564 | addresses_sorted_joined: str, |
| 565 | created_at_iso: str, |
| 566 | ) -> str: |
| 567 | """Return the canonical coord reservation ID from its declaration event. |
| 568 | |
| 569 | A symbol reservation is declared by a specific agent for a specific set |
| 570 | of addresses in a specific repo at a specific moment. |
| 571 | |
| 572 | reservation_id = sha256(repo_id NUL agent_id NUL addresses_sorted_joined NUL created_at_iso) |
| 573 | |
| 574 | *addresses_sorted_joined* must be ``",".join(sorted(addresses))`` from the |
| 575 | caller — the comma is the intra-field separator, distinct from the NUL |
| 576 | inter-field separator used by ``_genesis_hash``. |
| 577 | """ |
| 578 | return _genesis_hash(repo_id, agent_id, addresses_sorted_joined, created_at_iso) |
| 579 | |
| 580 | # --------------------------------------------------------------------------- |
| 581 | # Proposal simulation |
| 582 | # --------------------------------------------------------------------------- |
| 583 | |
| 584 | def compute_simulation_id( |
| 585 | proposal_id: str, |
| 586 | simulation_type: str, |
| 587 | from_branch_commit_id: str, |
| 588 | ) -> str: |
| 589 | """Return the canonical simulation ID from its computation context. |
| 590 | |
| 591 | A simulation result is uniquely identified by the proposal it was run for, |
| 592 | the type of simulation, and the from_branch commit tip at the time of the |
| 593 | run. Re-running the same simulation after the branch advances yields a |
| 594 | different ID — the old result remains queryable for diffing. |
| 595 | |
| 596 | simulation_id = sha256(proposal_id NUL simulation_type NUL from_branch_commit_id) |
| 597 | """ |
| 598 | return _genesis_hash(proposal_id, simulation_type, from_branch_commit_id) |
| 599 | |
| 600 | # --------------------------------------------------------------------------- |
| 601 | # MPay claim |
| 602 | # --------------------------------------------------------------------------- |
| 603 | |
| 604 | def compute_mpay_claim_id( |
| 605 | sender: str, |
| 606 | recipient: str, |
| 607 | amount_nano: int, |
| 608 | nonce_hex: str, |
| 609 | ) -> str: |
| 610 | """Return the canonical MPay claim ID. |
| 611 | |
| 612 | claim_id = sha256(sender NUL recipient NUL str(amount_nano) NUL nonce_hex) |
| 613 | |
| 614 | ``nonce_hex`` is the 32-byte random hex nonce embedded in the MSign payment |
| 615 | payload; it makes each claim globally unique even for repeated same-amount |
| 616 | transfers between the same pair. |
| 617 | """ |
| 618 | return _genesis_hash(sender, recipient, str(amount_nano), nonce_hex) |
File History
2 commits
sha256:bba4b69de173366aeb7d490d687ccffb6db9726374033addece89cf2b87642d8
docs: add production launch discovery report and infra laun…
Sonnet 5
7 days ago
sha256:eb0928124669c933c0ef852bea1ad0c56649cf21bd7e9663c3b51004771b0591
docs: add MuseHub cloud identity/AWS operating model and Go…
Sonnet 5
patch
8 days ago