Skip to content

Conversation

@kube
Copy link
Collaborator

@kube kube commented Oct 31, 2025

🌟 What is the purpose of this PR?

New Petrinaut version (prototype-stage), presented at Edinburgh, that supports progressive SDCPN definition + simulation.

🔍 What does this change?

  • @hashintel/petrinaut is a new prototype version of the current Petrinaut version
    • supports SDCPN definition + simulation.
  • @hashintel/petrinaut-old is a temporary copy of the current Petrinaut, to allow backporting some features/interfaces.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • affected the execution graph, and the turbo.json's have been updated to reflect this

🐾 Next steps

This is still the prototype code, made for Edinburgh demo, and will require enhancements.

The current state is a mix of hand-written interfaces and LLM-generated code, that really needs refactoring, and defining proper interfaces.

🛡 What tests cover this?

At the moment only some LLM-generated unit tests verify the behaviour of core/simulation functions, and need to be refactored.

❓ How to test this?

Already available at https://demo.petrinaut.org

@github-actions github-actions bot added area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team labels Oct 31, 2025
Copy link
Collaborator Author

kube commented Oct 31, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@kube kube changed the title Save SDCPN core prototype Oct 31, 2025
//

// Define U1 ~ Uniform(0,1)
const U1 = Math.random(); // TODO: Use simulation RNG

Check warning

Code scanning / Semgrep PRO

Semgrep Finding: ajinabraham.njsscan.crypto.crypto_node.node_insecure_random_generator Warning

crypto.pseudoRandomBytes()/Math.random() is a cryptographically weak random number generator.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already addressed. We rely on "real" RNG, not Math.random() anymore.

@vilkinsons vilkinsons changed the title SDCPN core prototype FE-62: Extend Petrinaut with SDCPN core Oct 31, 2025
@kube kube force-pushed the TA1-44-sdcpn-core branch from cf5a048 to 39d0616 Compare October 31, 2025 13:48
@kube kube mentioned this pull request Oct 31, 2025
15 tasks
@kube kube force-pushed the TA1-44-sdcpn-core branch from 39d0616 to 1659097 Compare November 2, 2025 14:07
@kube kube force-pushed the TA1-44-sdcpn-core branch from 1659097 to d6ceda0 Compare November 2, 2025 22:55
@kube kube force-pushed the TA1-44-sdcpn-core branch from d6ceda0 to f999727 Compare November 3, 2025 22:35
@kube kube force-pushed the TA1-44-sdcpn-core branch from f999727 to 106024d Compare November 4, 2025 11:13
@kube kube force-pushed the TA1-44-sdcpn-core branch from 106024d to bf90101 Compare November 4, 2025 11:42
@kube kube force-pushed the TA1-44-sdcpn-core branch from bf90101 to e62e0a1 Compare November 5, 2025 21:00
@kube kube force-pushed the TA1-44-sdcpn-core branch from e62e0a1 to 01a1408 Compare November 6, 2025 09:38
@kube kube force-pushed the TA1-44-sdcpn-core branch from 01a1408 to 9a362d6 Compare November 7, 2025 09:18
Copy link
Member

@CiaranMn CiaranMn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of dependencies no longer needed

"zustand": "5.0.8"
},
"devDependencies": {
"@emotion/react": "11.14.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"@emotion/react": "11.14.0",

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in d7f6ce9

"@dnd-kit/core": "6.3.1",
"@dnd-kit/sortable": "10.0.0",
"@dnd-kit/utilities": "3.2.2",
"@hashintel/design-system": "0.0.9-canary.2",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"@hashintel/design-system": "0.0.9-canary.2",

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in d7f6ce9

@kube kube added this pull request to the merge queue Nov 25, 2025
Merged via the queue into main with commit eeef51e Nov 25, 2025
164 checks passed
@kube kube deleted the TA1-44-sdcpn-core branch November 25, 2025 10:44
@github-actions
Copy link
Contributor

Benchmark results

@rust/hash-graph-benches – Integrations

policy_resolution_large

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2002 $$28.3 \mathrm{ms} \pm 178 \mathrm{μs}\left({\color{gray}1.68 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.36 \mathrm{ms} \pm 13.8 \mathrm{μs}\left({\color{gray}2.69 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1001 $$12.7 \mathrm{ms} \pm 91.9 \mathrm{μs}\left({\color{gray}-0.259 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$42.2 \mathrm{ms} \pm 266 \mathrm{μs}\left({\color{gray}-0.534 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$15.1 \mathrm{ms} \pm 77.3 \mathrm{μs}\left({\color{red}9.97 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1526 $$25.0 \mathrm{ms} \pm 157 \mathrm{μs}\left({\color{red}5.15 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$28.0 \mathrm{ms} \pm 157 \mathrm{μs}\left({\color{lightgreen}-36.915 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.59 \mathrm{ms} \pm 11.7 \mathrm{μs}\left({\color{gray}1.17 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$11.7 \mathrm{ms} \pm 73.9 \mathrm{μs}\left({\color{lightgreen}-58.987 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$3.69 \mathrm{ms} \pm 18.4 \mathrm{μs}\left({\color{gray}0.461 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.81 \mathrm{ms} \pm 10.6 \mathrm{μs}\left({\color{gray}-0.806 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 51 $$3.21 \mathrm{ms} \pm 12.6 \mathrm{μs}\left({\color{gray}0.152 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.13 \mathrm{ms} \pm 24.1 \mathrm{μs}\left({\color{gray}0.446 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.41 \mathrm{ms} \pm 14.8 \mathrm{μs}\left({\color{gray}-0.438 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 107 $$3.99 \mathrm{ms} \pm 15.9 \mathrm{μs}\left({\color{gray}0.757 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.40 \mathrm{ms} \pm 22.5 \mathrm{μs}\left({\color{red}6.80 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.31 \mathrm{ms} \pm 15.1 \mathrm{μs}\left({\color{gray}0.044 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$3.91 \mathrm{ms} \pm 18.3 \mathrm{μs}\left({\color{gray}-0.021 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.48 \mathrm{ms} \pm 9.64 \mathrm{μs}\left({\color{gray}4.79 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.46 \mathrm{ms} \pm 10.0 \mathrm{μs}\left({\color{red}7.69 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1 $$2.53 \mathrm{ms} \pm 8.56 \mathrm{μs}\left({\color{red}5.45 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$2.74 \mathrm{ms} \pm 12.8 \mathrm{μs}\left({\color{gray}4.81 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.62 \mathrm{ms} \pm 13.1 \mathrm{μs}\left({\color{gray}4.96 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$2.79 \mathrm{ms} \pm 16.0 \mathrm{μs}\left({\color{gray}2.50 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$2.88 \mathrm{ms} \pm 12.8 \mathrm{μs}\left({\color{red}6.37 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.54 \mathrm{ms} \pm 12.2 \mathrm{μs}\left({\color{red}5.80 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 25 $$2.72 \mathrm{ms} \pm 10.8 \mathrm{μs}\left({\color{red}7.77 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.33 \mathrm{ms} \pm 18.9 \mathrm{μs}\left({\color{red}8.40 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$2.77 \mathrm{ms} \pm 13.2 \mathrm{μs}\left({\color{red}5.05 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 26 $$3.02 \mathrm{ms} \pm 15.6 \mathrm{μs}\left({\color{red}7.16 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.15 \mathrm{ms} \pm 17.8 \mathrm{μs}\left({\color{red}5.66 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.75 \mathrm{ms} \pm 14.0 \mathrm{μs}\left({\color{red}6.04 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.02 \mathrm{ms} \pm 14.6 \mathrm{μs}\left({\color{red}7.44 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$38.7 \mathrm{ms} \pm 144 \mathrm{μs}\left({\color{gray}2.72 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$84.9 \mathrm{ms} \pm 380 \mathrm{μs}\left({\color{gray}1.30 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$42.2 \mathrm{ms} \pm 135 \mathrm{μs}\left({\color{gray}1.18 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$45.6 \mathrm{ms} \pm 257 \mathrm{μs}\left({\color{gray}3.05 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$53.2 \mathrm{ms} \pm 282 \mathrm{μs}\left({\color{gray}-0.437 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$40.1 \mathrm{ms} \pm 151 \mathrm{μs}\left({\color{gray}1.85 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$490 \mathrm{ms} \pm 706 \mathrm{μs}\left({\color{gray}-0.279 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$92.0 \mathrm{ms} \pm 384 \mathrm{μs}\left({\color{gray}1.32 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$83.1 \mathrm{ms} \pm 359 \mathrm{μs}\left({\color{gray}1.37 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$284 \mathrm{ms} \pm 607 \mathrm{μs}\left({\color{gray}-0.020 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$14.4 \mathrm{ms} \pm 71.0 \mathrm{μs}\left({\color{gray}-0.420 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$14.8 \mathrm{ms} \pm 60.4 \mathrm{μs}\left({\color{gray}1.27 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$15.1 \mathrm{ms} \pm 57.1 \mathrm{μs}\left({\color{gray}1.87 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$14.9 \mathrm{ms} \pm 64.5 \mathrm{μs}\left({\color{gray}3.08 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$17.8 \mathrm{ms} \pm 109 \mathrm{μs}\left({\color{gray}2.80 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$14.7 \mathrm{ms} \pm 71.0 \mathrm{μs}\left({\color{gray}4.04 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$14.5 \mathrm{ms} \pm 70.3 \mathrm{μs}\left({\color{gray}1.41 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$14.6 \mathrm{ms} \pm 65.4 \mathrm{μs}\left({\color{gray}1.86 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$15.3 \mathrm{ms} \pm 62.4 \mathrm{μs}\left({\color{gray}2.04 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$21.9 \mathrm{ms} \pm 133 \mathrm{μs}\left({\color{gray}-0.568 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity

Function Value Mean Flame graphs
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1 $$29.2 \mathrm{ms} \pm 294 \mathrm{μs}\left({\color{gray}-0.844 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$29.6 \mathrm{ms} \pm 260 \mathrm{μs}\left({\color{gray}0.875 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$28.6 \mathrm{ms} \pm 270 \mathrm{μs}\left({\color{lightgreen}-5.819 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$30.8 \mathrm{ms} \pm 278 \mathrm{μs}\left({\color{red}5.17 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$29.5 \mathrm{ms} \pm 274 \mathrm{μs}\left({\color{gray}0.274 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$29.2 \mathrm{ms} \pm 281 \mathrm{μs}\left({\color{gray}-4.272 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$28.1 \mathrm{ms} \pm 276 \mathrm{μs}\left({\color{lightgreen}-5.068 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$29.0 \mathrm{ms} \pm 259 \mathrm{μs}\left({\color{gray}-2.412 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$29.0 \mathrm{ms} \pm 260 \mathrm{μs}\left({\color{gray}-3.026 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity_type

Function Value Mean Flame graphs
get_entity_type_by_id Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba $$8.85 \mathrm{ms} \pm 36.4 \mathrm{μs}\left({\color{gray}0.321 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$56.5 \mathrm{ms} \pm 293 \mathrm{μs}\left({\color{gray}0.122 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$107 \mathrm{ms} \pm 395 \mathrm{μs}\left({\color{gray}-0.005 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$62.4 \mathrm{ms} \pm 279 \mathrm{μs}\left({\color{gray}-0.075 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$71.2 \mathrm{ms} \pm 405 \mathrm{μs}\left({\color{gray}-0.271 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$79.7 \mathrm{ms} \pm 485 \mathrm{μs}\left({\color{gray}0.106 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$86.3 \mathrm{ms} \pm 419 \mathrm{μs}\left({\color{gray}0.654 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$50.3 \mathrm{ms} \pm 293 \mathrm{μs}\left({\color{gray}-0.430 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$79.2 \mathrm{ms} \pm 331 \mathrm{μs}\left({\color{gray}-0.077 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$57.2 \mathrm{ms} \pm 313 \mathrm{μs}\left({\color{gray}0.478 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$65.9 \mathrm{ms} \pm 352 \mathrm{μs}\left({\color{gray}0.578 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$67.9 \mathrm{ms} \pm 312 \mathrm{μs}\left({\color{gray}-0.186 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$67.7 \mathrm{ms} \pm 276 \mathrm{μs}\left({\color{gray}-0.623 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$136 \mathrm{ms} \pm 498 \mathrm{μs}\left({\color{gray}1.68 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$132 \mathrm{ms} \pm 541 \mathrm{μs}\left({\color{gray}-0.731 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$42.3 \mathrm{ms} \pm 236 \mathrm{μs}\left({\color{lightgreen}-59.333 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$567 \mathrm{ms} \pm 949 \mathrm{μs}\left({\color{lightgreen}-8.948 \mathrm{\%}}\right) $$ Flame Graph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps > hash.design Affects the `hash.design` design site (app) area/apps > hash* Affects HASH (a `hash-*` app) area/apps area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team type/legal Owned by the @legal team

Development

Successfully merging this pull request may close these issues.

5 participants