tokra 0.0.1.pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.pre-commit-config.yaml +16 -0
  3. data/AGENTS.md +126 -0
  4. data/CHANGELOG.md +21 -0
  5. data/CODE_OF_CONDUCT.md +16 -0
  6. data/Cargo.toml +23 -0
  7. data/LICENSE +661 -0
  8. data/LICENSES/AGPL-3.0-or-later.txt +235 -0
  9. data/LICENSES/Apache-2.0.txt +73 -0
  10. data/LICENSES/CC-BY-SA-4.0.txt +170 -0
  11. data/LICENSES/CC0-1.0.txt +121 -0
  12. data/LICENSES/MIT.txt +18 -0
  13. data/README.md +45 -0
  14. data/README.rdoc +4 -0
  15. data/REUSE.toml +11 -0
  16. data/Rakefile +27 -0
  17. data/Steepfile +15 -0
  18. data/clippy.toml +5 -0
  19. data/clippy_exceptions.rb +59 -0
  20. data/doc/contributors/adr/001.md +187 -0
  21. data/doc/contributors/adr/002.md +132 -0
  22. data/doc/contributors/adr/003.md +116 -0
  23. data/doc/contributors/chats/001.md +3874 -0
  24. data/doc/contributors/plan/001.md +271 -0
  25. data/examples/verify_hello_world/app.rb +114 -0
  26. data/examples/verify_hello_world/index.html +88 -0
  27. data/examples/verify_ping_pong/README.md +0 -0
  28. data/examples/verify_ping_pong/app.rb +132 -0
  29. data/examples/verify_ping_pong/public/styles.css +182 -0
  30. data/examples/verify_ping_pong/views/index.erb +94 -0
  31. data/examples/verify_ping_pong/views/layout.erb +22 -0
  32. data/exe/semantic-highlight +0 -0
  33. data/ext/tokra/Cargo.toml +23 -0
  34. data/ext/tokra/extconf.rb +12 -0
  35. data/ext/tokra/src/lib.rs +719 -0
  36. data/lib/tokra/native.rb +79 -0
  37. data/lib/tokra/rack/handler.rb +177 -0
  38. data/lib/tokra/version.rb +12 -0
  39. data/lib/tokra.rb +19 -0
  40. data/mise.toml +8 -0
  41. data/rustfmt.toml +4 -0
  42. data/sig/tokra.rbs +7 -0
  43. data/tasks/lint.rake +151 -0
  44. data/tasks/rust.rake +63 -0
  45. data/tasks/steep.rake +11 -0
  46. data/tasks/test.rake +26 -0
  47. data/test_native.rb +37 -0
  48. data/vendor/goodcop/base.yml +1047 -0
  49. metadata +112 -0
@@ -0,0 +1,116 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
+
4
+ SPDX-License-Identifier: CC-BY-SA-4.0
5
+ -->
6
+
7
+ # ADR 003: Tokra Build System & "Ping Pong" Validation
8
+
9
+ ## Status
10
+ Accepted
11
+
12
+ ## Date
13
+ 2026-01-29
14
+
15
+ ## Context
16
+ Tokra bridges three distinct ecosystems: Ruby (Gems), Rust (Cargo), and System Libraries (Tao/Wry dependencies like GTK/WebKit).
17
+ A naive implementation using standard `bundle gem --ext` often fails in CI/CD or on user machines because it assumes the presence of Rust toolchains and system headers in non-standard locations.
18
+
19
+ Furthermore, because Ractors isolate memory state, "classic" Ruby tests (RSpec) that mock objects often produce false positives. They verify logic but fail to verify that objects can actually traverse the Ractor boundary without crashing the VM.
20
+
21
+ ## Decision
22
+
23
+ ### 1. The Build Glue: `rb_sys`
24
+ We will mandate the use of `rb_sys` to normalize the Rust build environment.
25
+
26
+ * **gemspec:** Must include `spec.add_dependency "rb_sys"`.
27
+ * **extconf.rb:** Must use `create_rust_makefile` to defer compilation to Cargo while respecting Ruby's `mkmf` environment.
28
+ * **Cargo.toml:** Must use `crate-type = ["cdylib"]` to generate a shared object loadable by Ruby.
29
+
30
+ ### 2. The Validation Standard: "The Ping Pong Test"
31
+
32
+ Before any feature is accepted, it must pass the **Ping Pong Test**. This test verifies the full round-trip capability of the architecture, proving that the Ractor bridge, Main Loop, and IPC are functional.
33
+
34
+ #### The Test Protocol
35
+
36
+ 1. **Boot:** Ruby Main Ractor starts.
37
+ 2. **Init:** Rust creates Window & WebView.
38
+ 3. **Frontend Emit:** JS executes `window.ipc.postMessage("PING")`.
39
+ 4. **Rust Bridge:** `Tokra::Native` shareable callback fires (on Main Thread).
40
+ 5. **Port Send:** Main Ractor sends "PING" to Worker Ractor via `Ractor::Port`.
41
+ 6. **Logic Processing:** Worker Ractor appends "PONG".
42
+ 7. **Response Port:** Worker sends response back via response `Ractor::Port`.
43
+ 8. **Proxy Wake:** Worker Ractor triggers `proxy.wake_up()`.
44
+ 9. **Rust Wake:** `Tao` loop wakes, executes callback on Main Thread.
45
+ 10. **Frontend Receive:** Main Ractor calls `webview.eval` to send "PINGPONG".
46
+ 11. **Verify:** JS assertion confirms receipt of "PINGPONG".
47
+
48
+ #### Reference Implementation
49
+
50
+ ```ruby
51
+ # test/integration/ping_pong_test.rb
52
+ # frozen_string_literal: true
53
+
54
+ require "tokra"
55
+ require "timeout"
56
+
57
+ class PingPongTest < Minitest::Test
58
+ def test_full_round_trip
59
+ Timeout.timeout(0.5) do # 500ms for CI stability
60
+ # Communication ports (explicit, not default)
61
+ ipc_port = Ractor::Port.new
62
+ response_port = Ractor::Port.new
63
+
64
+ # Worker Ractor - processes messages and responds
65
+ worker = Ractor.new(response_port) do |resp_port|
66
+ msg = Ractor.receive
67
+ resp_port << (msg + "PONG")
68
+ end
69
+
70
+ event_loop = Tokra::Native::EventLoop.new
71
+ proxy = event_loop.create_proxy
72
+ result = nil
73
+
74
+ # IPC handler must be shareable
75
+ ipc_handler = Ractor.shareable_proc do |raw_msg|
76
+ ipc_port << raw_msg
77
+ end
78
+
79
+ window = Tokra::Native::Window.new(event_loop)
80
+ webview = Tokra::Native::WebView.new(
81
+ window,
82
+ "data:text/html,<script>window.ipc.postMessage('PING')</script>",
83
+ ipc_handler
84
+ )
85
+
86
+ event_loop.run do |event|
87
+ case event
88
+ when Tokra::Native::IpcEvent
89
+ worker << event.message
90
+ when Tokra::Native::WakeUpEvent
91
+ result = response_port.receive
92
+ webview.eval("window.result = '#{result}'")
93
+ break
94
+ end
95
+ end
96
+
97
+ assert_equal "PINGPONG", result
98
+ end
99
+ end
100
+ end
101
+ ```
102
+
103
+ **Failure Condition:** If the app hangs, crashes, or times out (>500ms in CI), the build fails. This test MUST run in CI on Linux (headless), macOS, and Windows.
104
+
105
+ ## Consequences
106
+
107
+ ### Positive
108
+
109
+ * **Reliability:** `rb_sys` handles the complexity of finding `libclang` and linking Ruby headers.
110
+ * **Isolation Verification:** The Ping Pong test proves that objects are actually Ractor-safe (Shareable or Movable), preventing "Works in RSpec, Segfaults in Production" bugs.
111
+ * **Port Ownership:** Using explicit `Ractor::Port` makes message flow clear and prevents accidental cross-Ractor access.
112
+
113
+ ### Negative
114
+
115
+ * **CI Complexity:** CI runners must have Rust, GTK-dev, and WebKit-dev headers installed.
116
+ * **Timeout Tuning:** The 500ms timeout may need adjustment for slower CI runners or first-run compilation.