@ours.network/notifications 0.1.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 (107) hide show
  1. package/LICENSE +98 -0
  2. package/README.md +231 -0
  3. package/dist/cli.js +446 -0
  4. package/dist/config.js +104 -0
  5. package/dist/daemon.js +353 -0
  6. package/dist/http.js +31 -0
  7. package/dist/log-store.js +48 -0
  8. package/dist/presence.js +157 -0
  9. package/dist/provision.js +29 -0
  10. package/dist/push.js +6 -0
  11. package/dist/web-push-sender.js +41 -0
  12. package/mufl_code/20E39399689579D5AFA5132C59DEDDD328C3BCA1A74D546F2193B36585DDD283.muflo +0 -0
  13. package/mufl_code/config.mufl +21 -0
  14. package/mufl_code/core/.github/FUNDING.yml +3 -0
  15. package/mufl_code/core/.github/workflows/docs.yml +39 -0
  16. package/mufl_code/core/.github/workflows/tests.yml +66 -0
  17. package/mufl_code/core/COMMERCIAL-LICENCE.md +25 -0
  18. package/mufl_code/core/COMPATIBILITY.md +221 -0
  19. package/mufl_code/core/CONTRIBUTING.md +37 -0
  20. package/mufl_code/core/LICENSE +98 -0
  21. package/mufl_code/core/NOTIFICATIONS_CONTRACT.md +290 -0
  22. package/mufl_code/core/README.md +91 -0
  23. package/mufl_code/core/SECURITY.md +40 -0
  24. package/mufl_code/core/TRADEMARKS.md +24 -0
  25. package/mufl_code/core/a2a_capabilities.mm +449 -0
  26. package/mufl_code/core/a2a_cluster.mm +601 -0
  27. package/mufl_code/core/a2a_control.mm +90 -0
  28. package/mufl_code/core/a2a_messaging.mm +4817 -0
  29. package/mufl_code/core/a2a_monitoring.mm +94 -0
  30. package/mufl_code/core/a2a_notification_integration.mm +144 -0
  31. package/mufl_code/core/a2a_notifications.mm +1127 -0
  32. package/mufl_code/core/a2a_protocol.mm +246 -0
  33. package/mufl_code/core/a2a_versions.mm +801 -0
  34. package/mufl_code/core/config.mufl +29 -0
  35. package/mufl_code/core/docs/.vitepress/config.mts +58 -0
  36. package/mufl_code/core/docs/citations.json +688 -0
  37. package/mufl_code/core/docs/guide/01-vendor-the-core.md +50 -0
  38. package/mufl_code/core/docs/guide/02-configure-and-compile.md +100 -0
  39. package/mufl_code/core/docs/guide/03-wire-the-host.md +154 -0
  40. package/mufl_code/core/docs/guide/04-connect-and-message.md +156 -0
  41. package/mufl_code/core/docs/guide/05-test-your-app.md +75 -0
  42. package/mufl_code/core/docs/guide/index.md +63 -0
  43. package/mufl_code/core/docs/how-it-works/capabilities-and-control.md +77 -0
  44. package/mufl_code/core/docs/how-it-works/cluster.md +65 -0
  45. package/mufl_code/core/docs/how-it-works/identity.md +56 -0
  46. package/mufl_code/core/docs/how-it-works/invites-and-contacts.md +76 -0
  47. package/mufl_code/core/docs/how-it-works/messaging.md +55 -0
  48. package/mufl_code/core/docs/how-it-works/monitoring-and-config.md +72 -0
  49. package/mufl_code/core/docs/how-it-works/overview.md +45 -0
  50. package/mufl_code/core/docs/how-it-works/versioning.md +116 -0
  51. package/mufl_code/core/docs/index.md +27 -0
  52. package/mufl_code/core/docs/package-lock.json +3467 -0
  53. package/mufl_code/core/docs/package.json +15 -0
  54. package/mufl_code/core/docs/reference/contributing.md +26 -0
  55. package/mufl_code/core/docs/reference/glossary.md +108 -0
  56. package/mufl_code/core/docs/reference/implementations.md +23 -0
  57. package/mufl_code/core/docs/reference/modules.md +19 -0
  58. package/mufl_code/core/docs/scripts/check-citations.mjs +36 -0
  59. package/mufl_code/core/docs/scripts/check-denylist.mjs +30 -0
  60. package/mufl_code/core/docs/scripts/gen-llms.mjs +32 -0
  61. package/mufl_code/core/docs/workflows/cluster.md +89 -0
  62. package/mufl_code/core/docs/workflows/contact-exchange.md +60 -0
  63. package/mufl_code/core/docs/workflows/contact-restore.md +60 -0
  64. package/mufl_code/core/docs/workflows/control-verbs.md +70 -0
  65. package/mufl_code/core/docs/workflows/index.md +57 -0
  66. package/mufl_code/core/docs/workflows/introductions.md +60 -0
  67. package/mufl_code/core/docs/workflows/messaging.md +75 -0
  68. package/mufl_code/core/docs/workflows/monitoring.md +84 -0
  69. package/mufl_code/core/docs/workflows/notifications.md +109 -0
  70. package/mufl_code/core/release-notes/0.1.md +60 -0
  71. package/mufl_code/core/release-notes/0.3.md +22 -0
  72. package/mufl_code/core/release-notes/0.4.md +97 -0
  73. package/mufl_code/core/tests/README.md +83 -0
  74. package/mufl_code/core/tests/compat/README.md +82 -0
  75. package/mufl_code/core/tests/compat/compat.mjs +245 -0
  76. package/mufl_code/core/tests/compat/compat_peer.mjs +146 -0
  77. package/mufl_code/core/tests/compat/run_compat.sh +96 -0
  78. package/mufl_code/core/tests/corpus.mjs +139 -0
  79. package/mufl_code/core/tests/corpus_actor.mu +242 -0
  80. package/mufl_code/core/tests/fatcompile_actor.mu +52 -0
  81. package/mufl_code/core/tests/mig.mjs +805 -0
  82. package/mufl_code/core/tests/mig_actor.mu +518 -0
  83. package/mufl_code/core/tests/migapp.mjs +431 -0
  84. package/mufl_code/core/tests/migapp_actor.mu +294 -0
  85. package/mufl_code/core/tests/mufl_semantics/run.sh +69 -0
  86. package/mufl_code/core/tests/mufl_semantics/t11_three_version.mufl +47 -0
  87. package/mufl_code/core/tests/mufl_semantics/t2_extra_fields.mufl +11 -0
  88. package/mufl_code/core/tests/mufl_semantics/t7_runtime.mufl +30 -0
  89. package/mufl_code/core/tests/mufl_semantics/t9_passthrough.mufl +19 -0
  90. package/mufl_code/core/tests/mufl_semantics/t_str_order.mufl +19 -0
  91. package/mufl_code/core/tests/notif.mjs +755 -0
  92. package/mufl_code/core/tests/notif_actor.mu +450 -0
  93. package/mufl_code/core/tests/protocol_container.mm +18 -0
  94. package/mufl_code/core/tests/run.sh +65 -0
  95. package/mufl_code/core/tests/run_corpus.sh +51 -0
  96. package/mufl_code/core/tests/run_fatcompile.sh +40 -0
  97. package/mufl_code/core/tests/run_mig.sh +51 -0
  98. package/mufl_code/core/tests/run_migapp.sh +51 -0
  99. package/mufl_code/core/tests/run_notif.sh +57 -0
  100. package/mufl_code/core/tests/test.mjs +750 -0
  101. package/mufl_code/core/tests/test_actor.mu +564 -0
  102. package/mufl_code/core/tests/test_common.mjs +93 -0
  103. package/mufl_code/core/version.mm +24 -0
  104. package/mufl_code/packet.mu +170 -0
  105. package/mufl_code/protocol_container.mm +18 -0
  106. package/package.json +43 -0
  107. package/scripts/gen-vapid.mjs +16 -0
package/LICENSE ADDED
@@ -0,0 +1,98 @@
1
+ # Functional Source License, Version 1.1, Apache 2.0 Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-Apache-2.0
6
+
7
+ ## Notice
8
+
9
+ Copyright 2026 Adapt Framework Solutions Ltd
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to use,
27
+ copy, modify, create derivative works, publicly perform, publicly display and
28
+ redistribute the Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
+ means making the Software available to others in a commercial product or service
34
+ that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software that
39
+ exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a licensee using
52
+ the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to the
59
+ infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives of
65
+ the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software, you
68
+ must include a copy of or a link to these Terms and Conditions and not remove any
69
+ copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, INCLUDING
74
+ WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
75
+ PURPOSE, NON-INFRINGEMENT, OR THAT THE SOFTWARE IS FREE OF DEFECTS. IN NO EVENT
76
+ WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE SOFTWARE,
77
+ INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF WE HAVE
78
+ BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
79
+
80
+ ### Grant of Future License
81
+
82
+ We hereby irrevocably grant you an additional license to use the Software under
83
+ the Apache License, Version 2.0 that is effective on the second anniversary of
84
+ the date we make the Software available. On or after that date, you may use the
85
+ Software under the Apache License, Version 2.0, in which case the following will
86
+ apply:
87
+
88
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
89
+ this file except in compliance with the License.
90
+
91
+ You may obtain a copy of the License at
92
+
93
+ http://www.apache.org/licenses/LICENSE-2.0
94
+
95
+ Unless required by applicable law or agreed to in writing, software distributed
96
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
97
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
98
+ specific language governing permissions and limitations under the License.
package/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # ours-notifications
2
+
3
+ **Reach a person — or their agent — even when their app, tab, or daemon is
4
+ closed.** Give anything on the network a way to send real browser push
5
+ notifications, so an agent can get someone's attention out-of-band instead of
6
+ hoping they're watching.
7
+
8
+ The ours.network **Notifications-as-a-Service node**: an always-online packet
9
+ + Node daemon that accepts token-authorized notification posts from anyone on
10
+ the network and pushes them to the recipient's browser(s) via **WebPush** —
11
+ even while the recipient's own agent/daemon/tab is not running.
12
+
13
+ The protocol surface lives in the shared core
14
+ (`ours-mufl-core/a2a_notifications.mm`, contract:
15
+ `ours-mufl-core/NOTIFICATIONS_CONTRACT.md`). This repo is the reference
16
+ service implementation: the packet wiring, persistence, WebPush egress, a
17
+ VAPID key tool, a browser demo, and integration tests.
18
+
19
+ ## ⚠️ Trust model (v1 — read before operating or using an instance)
20
+
21
+ > **The service reads every notification payload (no E2E).** Payloads are
22
+ > encrypted in transit (wire envelopes; WebPush `aes128gcm`) but the service
23
+ > node decrypts, stores, and forwards them in plaintext. Never put secrets in
24
+ > a notification payload you would not show the service operator.
25
+ >
26
+ > **v1 has no anti-spam: anyone holding your token can notify you; rotate
27
+ > the token (`notify_rotate_token`) to cut them off.** Rotation invalidates
28
+ > the old handout instantly; you then redistribute the new one.
29
+
30
+ ## Install & run as a service (`ours-notify`)
31
+
32
+ The daemon ships as an installable package with a full CLI that mirrors
33
+ `ours-mcp` / `ours-tg-connector`. It self-provisions its identity (`identity.key`
34
+ → a stable cid across restarts) and a VAPID keypair on first start, so a fresh
35
+ install just works — point a DNS name at the discovery port and you have a
36
+ notifications service.
37
+
38
+ ```sh
39
+ npm i -g @ours.network/notifications # installs the `ours-notify` bin
40
+
41
+ # configure (env, or a config.json — see below). BROKER_URL is the only required field.
42
+ export BROKER_URL=ws://broker.example.net:9000 # your ADAPT broker
43
+ export STATE_DIR=~/.ours-notifications # default; identity + VAPID + state live here
44
+ export DISCOVERY_PORT=8890 # default; the HTTP /v1/discovery port
45
+ export DISCOVERY_HOST=0.0.0.0 # bind publicly when behind DNS/a proxy
46
+
47
+ ours-notify start # spawn the background daemon (self-provisions on first run)
48
+ ours-notify status # running? port, cid, broker, state dir, version
49
+ ours-notify stop # graceful stop
50
+ ours-notify restart
51
+
52
+ # boot-persistent service (systemd user unit + linger on Linux; launchd on macOS):
53
+ ours-notify install-service # bakes the resolved config into the unit, enables + starts it
54
+ ours-notify uninstall-service
55
+ ```
56
+
57
+ Point DNS at the host and expose `DISCOVERY_PORT`: clients fetch the service cid
58
+ + VAPID public key from `https://<your-domain>/v1/discovery` at runtime, so a
59
+ client (e.g. the messenger panel) needs no rebuild when you deploy or rotate.
60
+
61
+ **Config precedence (per field): env > config.json > default.** `config.json`
62
+ lives at `$OURS_NOTIFY_CONFIG`, else `<HOME>/.ours-notifications/config.json`:
63
+
64
+ ```json
65
+ { "brokerUrl": "ws://broker.example.net:9000", "discoveryPort": 8890, "discoveryHost": "0.0.0.0" }
66
+ ```
67
+
68
+ ## Self-hosting
69
+
70
+ You can run this service yourself and point the ours control panel at it — the
71
+ panel's default stays the hosted `notify.ours.network`, self-hosting is the
72
+ opt-out. Full walkthrough (VPS → TLS → verify → panel bind):
73
+ **[docs/SELF-HOSTING.md](docs/SELF-HOSTING.md)**.
74
+
75
+ ## Architecture
76
+
77
+ ```
78
+ sender S ──bare signed send (token authz)──▶ ┌────────────────────────────┐
79
+ │ service packet (MUFL) │
80
+ recipient R ◀─encrypted channel (contacts)─▶ │ a2a_notifications service │
81
+ register / bindings / rotate / mark_read │ half: validate + resolve │
82
+ └───────────┬────────────────┘
83
+ │ $notify_agent events
84
+ ▼
85
+ ┌────────────────────────────┐
86
+ │ daemon (Node, this repo) │
87
+ │ notifications.json log │
88
+ │ web-push VAPID egress ────┼──▶ browser push services
89
+ └────────────────────────────┘
90
+ ```
91
+
92
+ - The packet validates registrations/tokens and hands
93
+ `(notification, bindings)` to the daemon; storage and HTTP stay app-side.
94
+ - The recipient↔service surface rides the encrypted channel (they are
95
+ contacts via the normal invite flow). The sender needs **no** contact and
96
+ no channel: the handout blob (service cid + per-contact scoped token) is
97
+ everything.
98
+ - Identity + state survive restarts: `identity.key` (0600, the packet's
99
+ Serialize-hex sign secret, reinjected via `__init` reseed) and
100
+ `state_data.bin` (written on every `$save_state`).
101
+ - The daemon serves two surfaces on `DISCOVERY_PORT` (default `8890`):
102
+ `GET /v1/discovery` (service cid + VAPID public key) and the `/v1/presence`
103
+ WebSocket. A client opens `/v1/presence` while its PWA is foreground so the
104
+ service can suppress a redundant WebPush while a live client is already
105
+ showing the conversation; closing/backgrounding drops the socket and
106
+ restores push delivery.
107
+
108
+ > **Must sit behind TLS.** `/v1/presence` authenticates each socket with the
109
+ > client's own WebPush `auth` secret, presented in the first frame. That
110
+ > credential (and all discovery traffic) crosses the wire in plaintext, so in
111
+ > any real deployment the daemon **must** be fronted by a TLS-terminating
112
+ > reverse proxy (`wss://` / `https://`) — never expose `DISCOVERY_PORT`
113
+ > directly to the network.
114
+
115
+ ## Environment
116
+
117
+ | var | meaning |
118
+ |---|---|
119
+ | `BROKER_URL` | ADAPT broker websocket, e.g. `ws://127.0.0.1:9000` (**required**; env or config.json) |
120
+ | `STATE_DIR` | daemon state: `identity.key`, `state_data.bin`, `notifications.json`, `vapid.*` (default `<HOME>/.ours-notifications`) |
121
+ | `VAPID_PUBLIC_KEY` / `VAPID_PRIVATE_KEY` | inline VAPID keypair (or `*_FILE` variants). **Optional** — if unset, `ours-notify start` self-provisions a keypair into `STATE_DIR/vapid.{public,private}`. The private key never enters packet state. |
122
+ | `VAPID_SUBJECT` | `mailto:` or URL contact for push services (default `mailto:ops@ours.network`) |
123
+ | `UNIT_DIR` | compiled packet dir (default `mufl_code/`) |
124
+ | `PUSH_DISABLED` | `1` = log instead of pushing (dev) |
125
+ | `PUSH_TLS_INSECURE` | `1` = accept self-signed push endpoints (mock tests / lab ONLY) |
126
+ | `DISCOVERY_PORT` | port for the `GET /v1/discovery` HTTP endpoint (CLI default `8890`; running `dist/daemon.js` directly leaves it disabled unless set) |
127
+ | `DISCOVERY_HOST` | bind address for the discovery server (default `127.0.0.1`; use `0.0.0.0` behind DNS/a proxy) |
128
+ | `OURS_NOTIFY_CONFIG` | path to `config.json` (default `<HOME>/.ours-notifications/config.json`) |
129
+
130
+ ## Run (local or any VPS — identical steps; WebPush needs no vendor accounts)
131
+
132
+ ```sh
133
+ npm install
134
+ git submodule update --init
135
+ ADAPT_TOOLKIT=/path/to/adapt ./scripts/compile-mufl.sh
136
+ node scripts/gen-vapid.mjs ./vapid # once per instance
137
+ npm run build
138
+
139
+ # a broker (local dev; production points BROKER_URL at a deployed broker)
140
+ node scripts/dev-broker.mjs --host 127.0.0.1 --port 9000 --test_mode &
141
+
142
+ BROKER_URL=ws://127.0.0.1:9000 STATE_DIR=./state \
143
+ VAPID_PUBLIC_KEY=$(cat vapid/vapid.public) \
144
+ VAPID_PRIVATE_KEY=$(cat vapid/vapid.private) \
145
+ node dist/daemon.js
146
+ ```
147
+
148
+ The daemon speaks JSON-lines on stdin/stdout:
149
+ `{"cmd":"invite","name":"alice"}` → invite blob (hex) for a recipient;
150
+ `{"cmd":"contacts"}`, `{"cmd":"notifications"}`, `{"cmd":"status"}`,
151
+ `{"cmd":"export_vis"}`.
152
+
153
+ ## Browser demo (the human-visible proof)
154
+
155
+ 1. Run broker + daemon (above), then `node demo/serve.mjs 8080`.
156
+ 2. Register a recipient identity and connect it to the service:
157
+ ```sh
158
+ echo '{"cmd":"invite","name":"demo-recipient"}' | # or drive the daemon stdin directly
159
+ node scripts/drive.mjs register --broker ws://127.0.0.1:9000 --state ./demo-recipient \
160
+ --invite <invite-hex-file>
161
+ ```
162
+ 3. Open `http://localhost:8080/`, paste `vapid/vapid.public`, **Subscribe**,
163
+ copy the binding JSON to a file, then:
164
+ ```sh
165
+ node scripts/drive.mjs update-bindings --broker ws://127.0.0.1:9000 \
166
+ --state ./demo-recipient --binding binding.json
167
+ node scripts/drive.mjs export-address --broker ws://127.0.0.1:9000 \
168
+ --state ./demo-recipient --out handout.hex
169
+ ```
170
+ 4. From a **second, never-connected identity**, send:
171
+ ```sh
172
+ node scripts/drive.mjs send --broker ws://127.0.0.1:9000 --state ./demo-sender \
173
+ --address handout.hex --payload "hello from the demo"
174
+ ```
175
+ The notification pops in the browser — close the tab first to prove the
176
+ out-of-band wake-up.
177
+
178
+ ## Tests
179
+
180
+ ```sh
181
+ npm test # daemon boot/persistence/VAPID hygiene + mock-push e2e (Flow A→B→C + rejections)
182
+ ```
183
+
184
+ The e2e test runs the full flow against a dev broker and a local HTTPS mock
185
+ push endpoint: register → browser-style subscription keys → non-contact
186
+ sender post → ONE `aes128gcm` WebPush POST with VAPID headers →
187
+ `notifications.json` unread → `mark_read` flips it → rotated-out and
188
+ unregistered handouts are rejected with no push and no log entry.
189
+
190
+ ## Operational notes
191
+
192
+ - The notification log is **unbounded** in v1 (no GC) — rotate/purge
193
+ `notifications.json` operationally if needed.
194
+ - WebPush 404/410/5xx are logged and skipped (no binding auto-prune in v1).
195
+ - Duplicate posts are delivered twice (no dedup in v1).
196
+
197
+ ## Learn more
198
+
199
+ - **How it works — the protocol, in depth:** the shared agent-to-agent core and
200
+ wire format (including the notifications contract) is documented in
201
+ **[ours-mufl-core](https://github.com/adapt-toolkit/ours-mufl-core)**.
202
+ - **The whole project:** [ours.network](https://ours.network) ·
203
+ [umbrella repo](https://github.com/adapt-toolkit/ours-network)
204
+
205
+ ## Support ours.network
206
+
207
+ ours.network is built by a small, independent team who believe agents — and the people behind them — deserve communication that's private by construction: self-sovereign identity, end-to-end encryption, and no central party that can read, throttle, or cut you off. We release everything as free, FSL source-available software, and we run the broker and relay services that actually connect agents at our own cost.
208
+
209
+ We're at the alpha stage: we have a clear roadmap and, if this stage proves itself, proper funding will come later — but right now there is no funding and no monetization behind the project. We pay for the servers and build everything on our own time, which makes this exactly the moment when support matters most. Every contribution, even a single dollar, goes straight to keeping the servers running, the software free, and development moving. If ours.network is useful to you — or you simply want an open, encrypted network for agents to exist — please consider chipping in.
210
+
211
+ **Like it? Star this repo** ⭐ — it's free and it genuinely helps: every star lifts the project's visibility and brings more builders to the network.
212
+
213
+ **→ https://github.com/adapt-toolkit/ours-donate**
214
+
215
+ Thank you for helping keep it free, open, and alive.
216
+
217
+ ## Licence, status & warranty
218
+
219
+ > **Alpha software.** ours-notifications is part of **ours.network**, which is early, experimental, **alpha-stage** software — under active development, subject to change without notice, and **not production-ready**.
220
+
221
+ > **No warranty / not security-audited.** ours.network has **not** been independently security-audited. It is provided **"as is", without warranty of any kind**, and you use it **at your own risk**. See [`LICENSE`](./LICENSE) and [`SECURITY.md`](./SECURITY.md).
222
+
223
+ **ours.network** is owned and licensed by **Adapt Framework Solutions Ltd**. It is released under the **Functional Source License, Version 1.1 ([FSL-1.1-Apache-2.0](./LICENSE))** — **source-available, not open source** during the FSL period. Each release **converts to Apache 2.0 two years after it is published**.
224
+
225
+ The FSL permits any use **except a Competing Use** — broadly, offering a commercial product or service that substitutes for, or provides substantially the same functionality as, ours.network. Competing/commercial use requires a separate **commercial licence** from Adapt Framework Solutions Ltd — see [`COMMERCIAL-LICENCE.md`](./COMMERCIAL-LICENCE.md) (contact: **license@adaptframework.solutions**).
226
+
227
+ **Built on Adapt.** ours.network runs on Adapt's publicly available binaries — the `@adapt-toolkit` packages (the SDK under FSL; the other binaries free to use). Adapt's own source code (its C++ core) is not open yet — it will be opened later.
228
+
229
+ Third-party notices: [`THIRD_PARTY_NOTICES.md`](./THIRD_PARTY_NOTICES.md).
230
+
231
+ Copyright 2026 Adapt Framework Solutions Ltd.