serverless-ircd 0.3.0 → 0.5.0
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.
- package/.github/workflows/ci.yml +2 -2
- package/.github/workflows/deploy-aws.yml +1 -3
- package/.github/workflows/deploy-cf-tcp.yml +87 -0
- package/.github/workflows/deploy-cf.yml +1 -1
- package/.node-version +1 -0
- package/.nvmrc +1 -0
- package/CHANGELOG.md +349 -18
- package/README.md +132 -30
- package/apps/aws-stack/README.md +6 -5
- package/apps/aws-stack/bin/aws.ts +7 -0
- package/apps/aws-stack/package.json +4 -4
- package/apps/aws-stack/src/aws-stack.ts +150 -10
- package/apps/aws-stack/tests/stack.test.ts +145 -4
- package/apps/cf-tcp-container/Dockerfile +69 -0
- package/apps/cf-tcp-container/package.json +34 -0
- package/apps/cf-tcp-container/src/config-loader.ts +145 -0
- package/apps/cf-tcp-container/src/container-do.ts +38 -0
- package/apps/cf-tcp-container/src/container-server.ts +363 -0
- package/apps/cf-tcp-container/src/main.ts +77 -0
- package/apps/cf-tcp-container/src/persistence.ts +144 -0
- package/apps/cf-tcp-container/src/worker.ts +41 -0
- package/apps/cf-tcp-container/terraform/provider.tf +24 -0
- package/apps/cf-tcp-container/terraform/spectrum.tf +81 -0
- package/apps/cf-tcp-container/tests/config-loader.test.ts +217 -0
- package/apps/cf-tcp-container/tests/container-server.test.ts +465 -0
- package/apps/cf-tcp-container/tests/persistence.test.ts +227 -0
- package/apps/cf-tcp-container/tests/tls-e2e.test.ts +275 -0
- package/apps/cf-tcp-container/tsconfig.build.json +17 -0
- package/apps/cf-tcp-container/tsconfig.test.json +15 -0
- package/apps/cf-tcp-container/vitest.config.ts +26 -0
- package/apps/cf-tcp-container/wrangler.toml +63 -0
- package/apps/cf-worker/package.json +1 -1
- package/apps/cf-worker/wrangler.test.toml +6 -0
- package/apps/cf-worker/wrangler.toml +28 -2
- package/apps/local-cli/package.json +1 -1
- package/apps/local-cli/src/config-loader.ts +10 -0
- package/apps/local-cli/src/server.ts +149 -24
- package/apps/local-cli/tests/e2e.test.ts +1 -1
- package/apps/local-cli/tests/ws-subprotocol.test.ts +257 -0
- package/package.json +14 -10
- package/packages/aws-adapter/package.json +3 -3
- package/packages/aws-adapter/src/account-store.ts +1 -1
- package/packages/aws-adapter/src/admission.ts +74 -0
- package/packages/aws-adapter/src/aws-runtime.ts +75 -4
- package/packages/aws-adapter/src/config-loader.ts +32 -0
- package/packages/aws-adapter/src/dynamo-account-store.ts +35 -96
- package/packages/aws-adapter/src/handlers/connect.ts +96 -9
- package/packages/aws-adapter/src/handlers/default.ts +98 -7
- package/packages/aws-adapter/src/handlers/index.ts +109 -4
- package/packages/aws-adapter/src/handlers/nlb-stream.ts +490 -0
- package/packages/aws-adapter/src/handlers/ping-checker.ts +1 -1
- package/packages/aws-adapter/src/index.ts +8 -0
- package/packages/aws-adapter/src/serialize.ts +11 -1
- package/packages/aws-adapter/src/stats.ts +80 -0
- package/packages/aws-adapter/tests/account-store-dynamo.test.ts +45 -34
- package/packages/aws-adapter/tests/account-store.test.ts +19 -20
- package/packages/aws-adapter/tests/admission.test.ts +70 -0
- package/packages/aws-adapter/tests/aws-harness.ts +13 -1
- package/packages/aws-adapter/tests/aws-integration.test.ts +1 -1
- package/packages/aws-adapter/tests/aws-runtime.test.ts +61 -0
- package/packages/aws-adapter/tests/config-loader.test.ts +20 -0
- package/packages/aws-adapter/tests/connect.test.ts +174 -0
- package/packages/aws-adapter/tests/disconnect-fanout.test.ts +47 -40
- package/packages/aws-adapter/tests/gone-exception.test.ts +31 -26
- package/packages/aws-adapter/tests/handlers.test.ts +302 -53
- package/packages/aws-adapter/tests/nlb-stream.test.ts +480 -0
- package/packages/aws-adapter/tests/ping-checker.test.ts +34 -29
- package/packages/aws-adapter/tests/stats.test.ts +317 -0
- package/packages/aws-adapter/tests/sweeper.test.ts +25 -18
- package/packages/aws-adapter/tests/transactions.test.ts +25 -20
- package/packages/cf-adapter/package.json +5 -1
- package/packages/cf-adapter/src/cf-runtime.ts +68 -5
- package/packages/cf-adapter/src/channel-do.ts +2 -2
- package/packages/cf-adapter/src/config-loader.ts +33 -0
- package/packages/cf-adapter/src/connection-do.ts +278 -85
- package/packages/cf-adapter/src/d1-account-store.ts +198 -0
- package/packages/cf-adapter/src/env.ts +54 -11
- package/packages/cf-adapter/src/index.ts +11 -8
- package/packages/cf-adapter/src/registry-do.ts +22 -3
- package/packages/cf-adapter/src/sharding.ts +1 -2
- package/packages/cf-adapter/src/stats.ts +65 -0
- package/packages/cf-adapter/tests/cf-harness.ts +12 -2
- package/packages/cf-adapter/tests/cf-integration.test.ts +6 -5
- package/packages/cf-adapter/tests/cf-runtime.test.ts +38 -2
- package/packages/cf-adapter/tests/channel-do.test.ts +2 -2
- package/packages/cf-adapter/tests/config-loader.test.ts +22 -0
- package/packages/cf-adapter/tests/connection-do-channel-registration.test.ts +37 -0
- package/packages/cf-adapter/tests/connection-do-no-batching-reservation.test.ts +52 -0
- package/packages/cf-adapter/tests/connection-do-sasl-d1.test.ts +166 -0
- package/packages/cf-adapter/tests/connection-do-ws-spec-contract.test.ts +289 -0
- package/packages/cf-adapter/tests/connection-do-ws-subprotocol.test.ts +184 -0
- package/packages/cf-adapter/tests/connection-do.test.ts +27 -2
- package/packages/cf-adapter/tests/d1-account-store.test.ts +226 -0
- package/packages/cf-adapter/tests/raw-modules.d.ts +11 -0
- package/packages/cf-adapter/tests/registry-do.test.ts +4 -4
- package/packages/cf-adapter/tests/sharding.test.ts +1 -1
- package/packages/cf-adapter/tests/stats.test.ts +120 -0
- package/packages/cf-adapter/tests/worker/main.ts +15 -8
- package/packages/cf-adapter/tests/worker/stubs/channel-stub.ts +2 -2
- package/packages/cf-adapter/tests/worker/stubs/registry-stub.ts +8 -2
- package/packages/cf-adapter/wrangler.test.toml +15 -0
- package/packages/in-memory-runtime/package.json +1 -1
- package/packages/in-memory-runtime/src/in-memory-runtime.ts +39 -0
- package/packages/in-memory-runtime/tests/in-memory-runtime.test.ts +259 -0
- package/packages/irc-core/package.json +6 -1
- package/packages/irc-core/scripts/generate-build-info.mjs +31 -0
- package/packages/irc-core/src/admission.ts +16 -15
- package/packages/irc-core/src/caps/capabilities.ts +24 -3
- package/packages/irc-core/src/cloak.ts +1 -1
- package/packages/irc-core/src/commands/cap.ts +8 -1
- package/packages/irc-core/src/commands/index.ts +17 -0
- package/packages/irc-core/src/commands/invite.ts +2 -4
- package/packages/irc-core/src/commands/ison.ts +61 -0
- package/packages/irc-core/src/commands/isupport.ts +6 -2
- package/packages/irc-core/src/commands/kick.ts +2 -4
- package/packages/irc-core/src/commands/kill.ts +127 -0
- package/packages/irc-core/src/commands/list.ts +1 -1
- package/packages/irc-core/src/commands/lusers.ts +204 -0
- package/packages/irc-core/src/commands/mode.ts +4 -8
- package/packages/irc-core/src/commands/names.ts +3 -5
- package/packages/irc-core/src/commands/part.ts +2 -4
- package/packages/irc-core/src/commands/quit.ts +12 -0
- package/packages/irc-core/src/commands/registration.ts +18 -12
- package/packages/irc-core/src/commands/rehash.ts +119 -0
- package/packages/irc-core/src/commands/sasl.ts +72 -9
- package/packages/irc-core/src/commands/server-info.ts +129 -0
- package/packages/irc-core/src/commands/setname.ts +109 -0
- package/packages/irc-core/src/commands/stats.ts +152 -0
- package/packages/irc-core/src/commands/topic.ts +2 -4
- package/packages/irc-core/src/commands/trace.ts +137 -0
- package/packages/irc-core/src/commands/userhost.ts +84 -0
- package/packages/irc-core/src/commands/wallops.ts +118 -0
- package/packages/irc-core/src/commands/whowas.ts +113 -0
- package/packages/irc-core/src/config.ts +65 -0
- package/packages/irc-core/src/credential-hashing.ts +124 -0
- package/packages/irc-core/src/effects.ts +33 -30
- package/packages/irc-core/src/index.ts +3 -0
- package/packages/irc-core/src/ports.ts +360 -12
- package/packages/irc-core/src/protocol/numerics.ts +48 -11
- package/packages/irc-core/src/protocol/outbound.ts +20 -3
- package/packages/irc-core/src/types.ts +46 -2
- package/packages/irc-core/src/ws-framing.ts +132 -0
- package/packages/irc-core/src/ws-subprotocol.ts +66 -0
- package/packages/irc-core/tests/account-store.test.ts +45 -2
- package/packages/irc-core/tests/admission.test.ts +18 -0
- package/packages/irc-core/tests/caps/capabilities.test.ts +4 -3
- package/packages/irc-core/tests/commands/cap.test.ts +33 -1
- package/packages/irc-core/tests/commands/ison.test.ts +166 -0
- package/packages/irc-core/tests/commands/kill.test.ts +243 -0
- package/packages/irc-core/tests/commands/lusers.test.ts +368 -0
- package/packages/irc-core/tests/commands/mode.test.ts +57 -0
- package/packages/irc-core/tests/commands/quit.test.ts +69 -2
- package/packages/irc-core/tests/commands/registration.test.ts +151 -6
- package/packages/irc-core/tests/commands/rehash.test.ts +171 -0
- package/packages/irc-core/tests/commands/sasl.test.ts +118 -10
- package/packages/irc-core/tests/commands/server-info.test.ts +274 -0
- package/packages/irc-core/tests/commands/setname.test.ts +225 -0
- package/packages/irc-core/tests/commands/stats.test.ts +294 -0
- package/packages/irc-core/tests/commands/tagmsg.test.ts +9 -35
- package/packages/irc-core/tests/commands/trace.test.ts +282 -0
- package/packages/irc-core/tests/commands/userhost.test.ts +264 -0
- package/packages/irc-core/tests/commands/wallops.test.ts +231 -0
- package/packages/irc-core/tests/commands/whowas.test.ts +312 -0
- package/packages/irc-core/tests/config.test.ts +95 -1
- package/packages/irc-core/tests/credential-hashing.test.ts +170 -0
- package/packages/irc-core/tests/dropped-s2s-and-obsolete-verbs.test.ts +90 -0
- package/packages/irc-core/tests/effects.test.ts +14 -27
- package/packages/irc-core/tests/nick-history-store.test.ts +162 -0
- package/packages/irc-core/tests/numerics.test.ts +102 -0
- package/packages/irc-core/tests/outbound.test.ts +51 -0
- package/packages/irc-core/tests/ports.test.ts +22 -0
- package/packages/irc-core/tests/raw-modules.d.ts +11 -0
- package/packages/irc-core/tests/stats-store.test.ts +222 -0
- package/packages/irc-core/tests/types.test.ts +35 -1
- package/packages/irc-core/tests/ws-framing.test.ts +213 -0
- package/packages/irc-core/tests/ws-subprotocol.test.ts +111 -0
- package/packages/irc-core/tsconfig.build.json +1 -1
- package/packages/irc-core/tsconfig.test.json +1 -1
- package/packages/irc-server/package.json +1 -1
- package/packages/irc-server/src/actor.ts +393 -16
- package/packages/irc-server/src/dispatch.ts +1 -3
- package/packages/irc-server/src/index.ts +10 -2
- package/packages/irc-server/src/routing.ts +15 -0
- package/packages/irc-server/src/runtime.ts +31 -0
- package/packages/irc-server/src/transport.ts +104 -0
- package/packages/irc-server/tests/actor.test.ts +1489 -4
- package/packages/irc-server/tests/dispatch.test.ts +37 -17
- package/packages/irc-server/tests/raw-modules.d.ts +11 -0
- package/packages/irc-server/tests/routing.test.ts +5 -0
- package/packages/irc-server/tests/runtime.test.ts +7 -0
- package/packages/irc-server/tests/transport.test.ts +230 -0
- package/packages/irc-test-support/package.json +1 -1
- package/packages/irc-test-support/src/harness.ts +44 -9
- package/packages/irc-test-support/src/in-memory-harness.ts +73 -9
- package/packages/irc-test-support/src/index.ts +3 -0
- package/packages/irc-test-support/src/scenarios.ts +141 -3
- package/packages/irc-test-support/tests/in-memory-harness.test.ts +2 -1
- package/packages/irc-test-support/tests/in-memory-scenarios.test.ts +23 -9
- package/pnpm-workspace.yaml +10 -1
- package/tools/ci-hardening/package.json +1 -1
- package/tools/package.json +9 -0
- package/tools/seed-aws-accounts.ts +5 -6
- package/tools/seed-cf-accounts.ts +107 -0
- package/tools/tcp-ws-forwarder/package.json +1 -1
- package/tools/tcp-ws-forwarder/src/forwarder.ts +57 -9
- package/tools/tcp-ws-forwarder/tests/forwarder.test.ts +34 -1
- package/tools/tcp-ws-forwarder/tests/framing.test.ts +65 -1
- package/docs/ADR-001-pure-reducers-and-effect-system.md +0 -74
- package/docs/ADR-002-location-of-authority.md +0 -82
- package/docs/ADR-003-durable-object-sharding.md +0 -93
- package/docs/ADR-004-dynamodb-schema.md +0 -96
- package/docs/ADR-005-wss-only-transport-v1.md +0 -83
- package/docs/ADR-006-sasl-mechanism-scope.md +0 -86
- package/docs/ADR-007-deterministic-ports.md +0 -82
- package/docs/ADR-008-monorepo-tooling.md +0 -60
- package/docs/AWS-Adapter-Architecture.md +0 -496
- package/docs/AWS-Deployment.md +0 -1186
- package/docs/Cloudflare-Deployment-Guide.md +0 -660
- package/docs/Home.md +0 -11
- package/docs/Observability.md +0 -87
- package/docs/PlanIRCv3Websocket.md +0 -489
- package/docs/PlanWebClient.md +0 -451
- package/docs/Release-Process.md +0 -443
package/.github/workflows/ci.yml
CHANGED
|
@@ -39,7 +39,7 @@ jobs:
|
|
|
39
39
|
- name: Setup Node
|
|
40
40
|
uses: actions/setup-node@v4
|
|
41
41
|
with:
|
|
42
|
-
node-version:
|
|
42
|
+
node-version: 24
|
|
43
43
|
cache: pnpm
|
|
44
44
|
|
|
45
45
|
- name: Install dependencies
|
|
@@ -112,7 +112,7 @@ jobs:
|
|
|
112
112
|
- name: Setup Node
|
|
113
113
|
uses: actions/setup-node@v4
|
|
114
114
|
with:
|
|
115
|
-
node-version:
|
|
115
|
+
node-version: 24
|
|
116
116
|
cache: pnpm
|
|
117
117
|
|
|
118
118
|
- name: Install dependencies
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: deploy-cf-tcp
|
|
2
|
+
|
|
3
|
+
# Cloudflare TCP+TLS deploy pipeline (Spectrum + Container origin).
|
|
4
|
+
#
|
|
5
|
+
# Deploys the IRC TCP container origin (apps/cf-tcp-container) to Cloudflare
|
|
6
|
+
# Containers and applies the Spectrum TLS config (terraform). Spectrum
|
|
7
|
+
# terminates TLS on :6697 and forwards plaintext TCP to the container.
|
|
8
|
+
#
|
|
9
|
+
# This pipeline runs alongside deploy-cf.yml (the WebSocket path). The two
|
|
10
|
+
# are independent: a deployment can enable either or both transports.
|
|
11
|
+
#
|
|
12
|
+
# Secrets (configure under repo Settings → Secrets and variables → Actions):
|
|
13
|
+
# CLOUDFLARE_API_TOKEN Spectrum/Containers API token.
|
|
14
|
+
# CLOUDFLARE_ACCOUNT_ID Account ID for the target zone.
|
|
15
|
+
# CF_ZONE_ID Zone ID for the Spectrum hostname.
|
|
16
|
+
# CF_TCP_ORIGIN_ADDRESS Hostname/IP of the container origin.
|
|
17
|
+
|
|
18
|
+
on:
|
|
19
|
+
push:
|
|
20
|
+
branches: [main]
|
|
21
|
+
paths:
|
|
22
|
+
- 'apps/cf-tcp-container/**'
|
|
23
|
+
- '.github/workflows/deploy-cf-tcp.yml'
|
|
24
|
+
workflow_dispatch:
|
|
25
|
+
|
|
26
|
+
concurrency:
|
|
27
|
+
group: cf-tcp-staging
|
|
28
|
+
cancel-in-progress: false
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
deploy-staging:
|
|
32
|
+
name: deploy cf-tcp staging
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
timeout-minutes: 15
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout
|
|
37
|
+
uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- name: Setup pnpm
|
|
40
|
+
uses: pnpm/action-setup@v4
|
|
41
|
+
|
|
42
|
+
- name: Setup Node
|
|
43
|
+
uses: actions/setup-node@v4
|
|
44
|
+
with:
|
|
45
|
+
node-version: 24
|
|
46
|
+
cache: pnpm
|
|
47
|
+
|
|
48
|
+
- name: Install dependencies
|
|
49
|
+
run: pnpm install --frozen-lockfile
|
|
50
|
+
|
|
51
|
+
- name: Build workspace
|
|
52
|
+
run: pnpm build
|
|
53
|
+
|
|
54
|
+
- name: Typecheck
|
|
55
|
+
run: pnpm typecheck
|
|
56
|
+
|
|
57
|
+
- name: Test
|
|
58
|
+
run: pnpm --filter '@serverless-ircd/cf-tcp-container' test
|
|
59
|
+
|
|
60
|
+
- name: Deploy container to staging
|
|
61
|
+
working-directory: apps/cf-tcp-container
|
|
62
|
+
env:
|
|
63
|
+
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
64
|
+
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
65
|
+
run: wrangler deploy --env staging
|
|
66
|
+
|
|
67
|
+
- name: Apply Spectrum TLS config
|
|
68
|
+
working-directory: apps/cf-tcp-container/terraform
|
|
69
|
+
env:
|
|
70
|
+
TF_VAR_zone_id: ${{ secrets.CF_ZONE_ID }}
|
|
71
|
+
TF_VAR_origin_address: ${{ secrets.CF_TCP_ORIGIN_ADDRESS }}
|
|
72
|
+
TF_VAR_hostname: irc-staging.example.com
|
|
73
|
+
run: |
|
|
74
|
+
terraform init
|
|
75
|
+
terraform apply -auto-approve
|
|
76
|
+
|
|
77
|
+
- name: Smoke e2e (irc+tls)
|
|
78
|
+
if: ${{ vars.CF_TCP_SMOKE_HOST != '' }}
|
|
79
|
+
env:
|
|
80
|
+
SMOKE_HOST: ${{ vars.CF_TCP_SMOKE_HOST }}
|
|
81
|
+
SMOKE_PORT: '6697'
|
|
82
|
+
run: |
|
|
83
|
+
# Minimal smoke: connect over TLS, register, join, privmsg, quit.
|
|
84
|
+
# Uses openssl s_client for the TLS handshake + IRC line exchange.
|
|
85
|
+
echo "NICK smoke\r\nUSER smoke 0 * :Smoke\r\nQUIT :smoke\r\n" | \
|
|
86
|
+
timeout 10 openssl s_client -connect "${SMOKE_HOST}:${SMOKE_PORT}" -quiet 2>/dev/null | \
|
|
87
|
+
grep -q "001" && echo "SMOKE PASS" || (echo "SMOKE FAIL" && exit 1)
|
package/.node-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
24
|
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
24
|
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,339 @@ For the release process itself — versioning policy, pre-release checklist,
|
|
|
10
10
|
cutting a tag, rolling back — see [`docs/release.md`](docs/release.md).
|
|
11
11
|
Cross-reference `progress.md` / `tickets.md` for per-ticket detail.
|
|
12
12
|
|
|
13
|
+
## [0.5.0] - 2026-08-02
|
|
14
|
+
|
|
15
|
+
The headline is **protocol completion**: the deferred IRC verbs land
|
|
16
|
+
(Phase 11), and the S2S / obsolete RFC 2812 verbs are **formally
|
|
17
|
+
dropped** rather than left "deferred". With this release every standard
|
|
18
|
+
IRC verb a modern client expects is implemented — the only remaining
|
|
19
|
+
`421 ERR_UNKNOWNCOMMAND` paths are the deliberately-unimplemented S2S
|
|
20
|
+
and obsolete verbs. The roadmap's 0.x protocol surface is complete;
|
|
21
|
+
what remains is the load/compat sweep (10k-connection load test +
|
|
22
|
+
client compatibility matrix) and the required-`serverName` config gate.
|
|
23
|
+
|
|
24
|
+
### Added — Deferred IRC verbs (`@serverless-ircd/irc-core`, `@serverless-ircd/irc-server`)
|
|
25
|
+
|
|
26
|
+
Six Phase 11 tickets light up the remaining command surface. Each ships
|
|
27
|
+
a pure reducer, an actor route case (no more `421`), new numerics in
|
|
28
|
+
`protocol/numerics.ts`, and unit + actor coverage. (The remaining two
|
|
29
|
+
Phase 11 tickets are drops — see below.)
|
|
30
|
+
|
|
31
|
+
- **`KILL`** (oper-gated force-disconnect): `KILL <nick>
|
|
32
|
+
<comment>` resolves the target via the nick registry + a live
|
|
33
|
+
connection fetch (mirroring WHOIS), checks the oper gate (`481
|
|
34
|
+
ERR_NOPRIVILEGES`), and emits a `Disconnect` effect carrying the
|
|
35
|
+
classic `Killed (<oper> (<comment>))` reason. Peer `QUIT` fanout in
|
|
36
|
+
the target's shared channels happens via the runtime's existing
|
|
37
|
+
`disconnect` path. Missing params → `461`; unknown nick → `401`; an
|
|
38
|
+
oper may `KILL` themselves (RFC-permitted).
|
|
39
|
+
**Platform asymmetry:** on Cloudflare the `disconnect` RPC closes the
|
|
40
|
+
target DO's socket immediately; on AWS a `$default` Lambda invocation
|
|
41
|
+
cannot close a *remote* APIGW WebSocket, so the target's
|
|
42
|
+
live socket only closes on its next `$disconnect` / sweeper cycle —
|
|
43
|
+
the QUIT fanout to peers still fires. The reducer is identical; the
|
|
44
|
+
difference is the bound runtime's `disconnect` semantics.
|
|
45
|
+
- **`REHASH`** (oper-gated config reload): emits `382
|
|
46
|
+
RPL_REHASHING :<source>` and re-fetches `ServerConfig` from the
|
|
47
|
+
adapter's bound source via a new `IrcRuntime.reloadConfig()` port
|
|
48
|
+
method. The refreshed value swaps into the actor's live config
|
|
49
|
+
reference so subsequent commands observe it (rotated oper passwords,
|
|
50
|
+
new MOTD source, etc.). On reload failure the previous config stays
|
|
51
|
+
in effect and a graceful error-suffixed `382` follows — the oper is
|
|
52
|
+
**not** disconnected (a bad store read must never sever a live link).
|
|
53
|
+
Already-open connections keep their negotiated caps and registration;
|
|
54
|
+
transport/TLS reload requires a redeploy.
|
|
55
|
+
- **`LUSERS` + `STATS`** (network statistics): backed by a
|
|
56
|
+
new async `ServerStats` port (`getStats(): Promise<ServerStatsSnapshot>`)
|
|
57
|
+
and an `InMemoryStats` reference impl. `LUSERS` emits the full
|
|
58
|
+
`251`–`255` sequence (only the non-zero counts, per RFC) plus the
|
|
59
|
+
optional `265` / `266` local/global counts. `STATS <query>` supports
|
|
60
|
+
the `u` (uptime, `242 RPL_STATSUPTIME`) and `l` (link info,
|
|
61
|
+
`211 RPL_STATSLINKINFO`) letters; unknown letters get the
|
|
62
|
+
charybdis-style empty body terminated by `219 RPL_ENDOFSTATS`. A
|
|
63
|
+
`<server>` argument that does not match the local server (case-
|
|
64
|
+
insensitive) yields `402 ERR_NOSUCHSERVER` (single-server network —
|
|
65
|
+
S2S aggregation is a PLAN non-goal). The `computeStatsSnapshot`
|
|
66
|
+
helper centralizes the oper/invisible/unknown classification so each
|
|
67
|
+
adapter's backend only has to gather raw counts.
|
|
68
|
+
- **`TRACE`** (routing diagnostics): in a single-server
|
|
69
|
+
serverless IRCd `TRACE` collapses to a local-server line + the
|
|
70
|
+
`262 RPL_ENDOFTRACE` terminator. Per-connection `204
|
|
71
|
+
RPL_TRACEOPERATOR` / `205 RPL_TRACEUSER` detail is **oper-gated** —
|
|
72
|
+
non-opers see only the server line + `262` (no enumeration of `+i`
|
|
73
|
+
users they don't share a channel with). `TRACE <server>` where
|
|
74
|
+
`<server>` is not the local server → `402`.
|
|
75
|
+
- **`WALLOPS`** (oper broadcast): `WALLOPS :<message>` is
|
|
76
|
+
oper-only to send (modern ircd convention — non-oper → `481`);
|
|
77
|
+
delivery fans out to every connection whose `+w` user mode is set via
|
|
78
|
+
a new `BroadcastWallops` effect interpreted by the runtime's
|
|
79
|
+
`broadcastWallops` method (global cross-connection fanout, not
|
|
80
|
+
channel-scoped). The originator is always excluded (skip-self,
|
|
81
|
+
matching NOTICE/PRIVMSG semantics). Empty message → `461`. The `+w`
|
|
82
|
+
user mode was already accepted by `MODE` and advertised in `004
|
|
83
|
+
RPL_MYINFO`; this lights up the consumer.
|
|
84
|
+
- **`SETNAME`** (realname change): `SETNAME :<realname>`
|
|
85
|
+
updates `state.realname` so a subsequent `WHOIS` reflects the new
|
|
86
|
+
value in `311 RPL_WHOISUSER`. No broadcast is emitted in v1 (there
|
|
87
|
+
is no standard IRCv3 cap for relaying a realname change — a
|
|
88
|
+
`draft/setname` relay is a documented follow-up). Empty/missing
|
|
89
|
+
realname → `461`; the registration-time realname length cap applies.
|
|
90
|
+
|
|
91
|
+
### Changed — S2S & obsolete verbs formally dropped (`@serverless-ircd/irc-core`)
|
|
92
|
+
|
|
93
|
+
The remaining two Phase 11 tickets convert the "deferred" framing into
|
|
94
|
+
an explicit **drop**. There is no behaviour change on the wire — the verbs
|
|
95
|
+
already returned `421 ERR_UNKNOWNCOMMAND` — but the framing, comments,
|
|
96
|
+
and reserved numerics are cleaned up so the codebase no longer carries
|
|
97
|
+
dead scaffolding.
|
|
98
|
+
|
|
99
|
+
- **S2S verbs** (`CONNECT`, `SQUIT`, `LINKS`): dropped as a PLAN
|
|
100
|
+
non-goal (single-server serverless IRCd; no mesh to connect, split,
|
|
101
|
+
or list). The now-unused numerics `RPL_LINKS (364)`,
|
|
102
|
+
`RPL_ENDOFLINKS (365)`, and `ERR_CANTKILLSERVER (483)` are removed
|
|
103
|
+
from `numerics.ts` and its auto-derived `numericToName` reverse map.
|
|
104
|
+
`ERR_NOSUCHSERVER (402)` is retained — `LUSERS` / `STATS` / `TRACE`
|
|
105
|
+
use it for remote-server gating.
|
|
106
|
+
- **Obsolete RFC 2812 verbs** (`SERVICE`, `SUMMON`, `USERS`): dropped
|
|
107
|
+
(never widely implemented; no modern client uses them). The now-unused
|
|
108
|
+
numerics `RPL_YOURESERVICE (383)`, `ERR_NOSUCHSERVICE (408)`,
|
|
109
|
+
`ERR_SUMMONDISABLED (445)`, and `ERR_USERSDISABLED (446)` are removed.
|
|
110
|
+
- The `actor.ts` default-branch triage comment was rewritten: the
|
|
111
|
+
six verbs are documented as **deliberately unimplemented** rather
|
|
112
|
+
than "deferred".
|
|
113
|
+
- Source-level regression guards
|
|
114
|
+
(`packages/irc-core/tests/dropped-s2s-and-obsolete-verbs.test.ts`)
|
|
115
|
+
and a behaviour guard in `actor.test.ts` (the verbs still emit
|
|
116
|
+
`421`) pin the drop so the numerics or the "deferred" framing cannot
|
|
117
|
+
creep back in.
|
|
118
|
+
|
|
119
|
+
### Added — Runtime ports for the new verbs
|
|
120
|
+
|
|
121
|
+
- **`ServerStats` port** (`packages/irc-core/src/ports.ts`): async
|
|
122
|
+
`getStats()` returning `ServerStatsSnapshot` (users / invisible /
|
|
123
|
+
opers / unknown / channels / servers / local+global conn counts /
|
|
124
|
+
uptime anchor). Asynchronous because the aggregation crosses every
|
|
125
|
+
connection and channel — it cannot be pre-loaded into a synchronous
|
|
126
|
+
view the way MOTD or a credential table can. Each adapter implements
|
|
127
|
+
it against its authoritative store; `InMemoryStats` is the reference
|
|
128
|
+
impl. The `computeStatsSnapshot` helper holds the shared
|
|
129
|
+
classification logic (oper / invisible / unknown).
|
|
130
|
+
- **`reloadConfig()` on `IrcRuntime`** (`packages/irc-server/src/runtime.ts`):
|
|
131
|
+
request/response port method the `REHASH` route calls to re-fetch
|
|
132
|
+
`ServerConfig` from the adapter's bound source (CF: KV/secret env;
|
|
133
|
+
AWS: Secrets Manager/SSM env; local-cli: the config file/options).
|
|
134
|
+
Modelled as a runtime method rather than a fire-and-forget effect
|
|
135
|
+
because the refreshed value must come back to the actor.
|
|
136
|
+
|
|
137
|
+
### ⚠️ Migration required
|
|
138
|
+
|
|
139
|
+
- **For adapter authors wiring the new ports.** `ServerStats` and
|
|
140
|
+
`reloadConfig` are optional at the type level (the actor falls back
|
|
141
|
+
to a zero-count snapshot when no `ServerStats` is bound, and
|
|
142
|
+
`REHASH` still emits `382` even if `reloadConfig` rejects — the
|
|
143
|
+
previous config is retained). To surface real counts and live
|
|
144
|
+
reloads, each adapter wires its own backend. No Durable-Object
|
|
145
|
+
persisted-state schema change (`PERSISTED_STATE_VERSION` stays `1`);
|
|
146
|
+
code rollback across this release is safe.
|
|
147
|
+
- No toolchain change. Node ≥ 24 / pnpm 11 (from v0.4.0) still apply.
|
|
148
|
+
|
|
149
|
+
### Known limitations
|
|
150
|
+
|
|
151
|
+
- Same as v0.4.0's transport limits: the **CF TCP path requires
|
|
152
|
+
Cloudflare Spectrum (Enterprise tier)** plus a stateful Container
|
|
153
|
+
origin; the **AWS TCP path** uses NLB + Lambda streaming and is
|
|
154
|
+
subject to Lambda idle-timeout / stream-duration limits. The
|
|
155
|
+
WebSocket path remains the zero-extra-deps default.
|
|
156
|
+
- **mTLS (for SASL `EXTERNAL`) requires a custom domain + uploaded
|
|
157
|
+
CA/trust-store** on both platforms and is not enabled by default.
|
|
158
|
+
- `serverName` still defaults to the `irc.example.com` placeholder when
|
|
159
|
+
an adapter config omits it (pending).
|
|
160
|
+
- `STATS` ships the `u` + `l` query letters; the full RFC matrix
|
|
161
|
+
(`k`, `K`, `q`, `g`, `x`, `z`, …) is intentionally out of scope for
|
|
162
|
+
v1 — unknown letters get the charybdis-style empty body + `219`.
|
|
163
|
+
- Load testing (10k concurrent connections) and the client
|
|
164
|
+
compatibility sweep (WeeChat / HexChat / IRCCloud / TheLounge)
|
|
165
|
+
remain pending.
|
|
166
|
+
- **Local coverage instrumentation on the Cloudflare-backed packages
|
|
167
|
+
(`@serverless-ircd/cf-adapter`, `@serverless-ircd/cf-worker`) is
|
|
168
|
+
incompatible with the current vitest toolchain.** `@vitest/coverage-v8`
|
|
169
|
+
v4.1.x imports `node:inspector/promises`, which the
|
|
170
|
+
`@cloudflare/vitest-pool-workers` (workerd) test pool cannot resolve.
|
|
171
|
+
The packages' test suites themselves pass (cf-adapter 185/185,
|
|
172
|
+
cf-worker 3/3); only `pnpm coverage` fails to load the coverage
|
|
173
|
+
module under the workerd pool. This is a documented [vitest-pool-workers
|
|
174
|
+
known issue](https://developers.cloudflare.com/workers/testing/vitest-integration/known-issues/#module-resolution)
|
|
175
|
+
and is expected to resolve with an upstream `@vitest/coverage-v8` or
|
|
176
|
+
pool-workers release. No production code is affected; CI behavior
|
|
177
|
+
depends on its installed versions.
|
|
178
|
+
|
|
179
|
+
### Security
|
|
180
|
+
|
|
181
|
+
- None. No vulnerabilities have been reported or fixed in this release.
|
|
182
|
+
The dropped S2S / obsolete verbs and their reserved numerics carried
|
|
183
|
+
no reachable code path; their removal reduces surface area but fixes
|
|
184
|
+
no defect.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## [0.4.0] - 2026-07-31
|
|
189
|
+
|
|
190
|
+
The headline is **dual transport**: both adapters now speak a real
|
|
191
|
+
`irc+tls :6697` (TLS-over-TCP) surface for stock IRC clients in
|
|
192
|
+
production — not just the local CLI — alongside the WebSocket path. This
|
|
193
|
+
lands **SASL `EXTERNAL` via mTLS**, the **remaining standard IRC verbs**
|
|
194
|
+
(WHOWAS, VERSION, TIME, ADMIN, INFO, USERHOST, ISON), a **Cloudflare
|
|
195
|
+
D1-backed SASL account store**, config-driven server identity, and a
|
|
196
|
+
**Node 24 / pnpm 11** toolchain. Phase 7 (TLS hardening & raw TCP) is
|
|
197
|
+
complete.
|
|
198
|
+
|
|
199
|
+
### Added — Dual transport: WebSocket + `irc+tls :6697`
|
|
200
|
+
|
|
201
|
+
The wss-only transport decision (ADR-005) is superseded by **ADR-009**
|
|
202
|
+
(dual transport). The shared `ConnectionActor` now drives either
|
|
203
|
+
transport through a generalized seam; the parser/reducer/dispatch
|
|
204
|
+
pipeline is unchanged.
|
|
205
|
+
|
|
206
|
+
- **Transport seam** (`@serverless-ircd/irc-server`,
|
|
207
|
+
`@serverless-ircd/irc-core`): the `\r\n` line-framing is extracted into
|
|
208
|
+
a `Transport` abstraction. `ConnectionActor` accepts a
|
|
209
|
+
`WsTextFrameTransport` (one message per WS frame, prior behavior) or a
|
|
210
|
+
`TcpByteStreamTransport` (stateful `\r\n` framing across chunks with
|
|
211
|
+
partial-line buffering). Both produce identical reducer invocations.
|
|
212
|
+
- **Cloudflare TCP+TLS** (`@serverless-ircd/cf-tcp-container`): a new
|
|
213
|
+
workspace app — **Cloudflare Spectrum** terminates TLS at the edge and
|
|
214
|
+
forwards plaintext TCP to a stateful **Container** origin running the
|
|
215
|
+
IRC core. Ships a `Dockerfile`, config loader, deploy pipeline
|
|
216
|
+
(`.github/workflows/deploy-cf-tcp.yml`), and root
|
|
217
|
+
`deploy:cf-tcp:staging` / `deploy:cf-tcp:prod` scripts.
|
|
218
|
+
- **AWS TCP+TLS** (`@serverless-ircd/aws-adapter`, `@serverless-ircd/aws-stack`):
|
|
219
|
+
a **Network Load Balancer** with a `tls` listener terminates TLS and
|
|
220
|
+
invokes a **Lambda streaming function** (`nlb-stream.ts`) as the target.
|
|
221
|
+
Connection identity is derived from NLB flow metadata; bidirectional
|
|
222
|
+
traffic flows over the Lambda response stream, reusing `AwsRuntime`.
|
|
223
|
+
CDK constructs for NLB + target group + ACM cert are added.
|
|
224
|
+
- **Transport-parametrized contract suite** (`@serverless-ircd/irc-test-support`):
|
|
225
|
+
every scenario now runs across a `Transport` dimension
|
|
226
|
+
(in-memory+WS, in-memory+TCP, …), with TCP-specific framing scenarios
|
|
227
|
+
(chunk boundaries, mixed `\r\n`/`\n` line endings, partial sends).
|
|
228
|
+
- **Docs**: `docs/Cloudflare-TCP-Deployment.md` and
|
|
229
|
+
`docs/AWS-TCP-Deployment.md` — end-to-end :6697 deployment guides
|
|
230
|
+
(prerequisites, mTLS trust-store setup, cost/ops caveats).
|
|
231
|
+
|
|
232
|
+
### Added — SASL `EXTERNAL` via mTLS (`@serverless-ircd/irc-core`, adapters)
|
|
233
|
+
|
|
234
|
+
- **mTLS support**: an `MtlsIdentityProvider` port in `irc-core` feeds
|
|
235
|
+
the verified client-certificate subject into `AccountStore`. Cloudflare
|
|
236
|
+
uses API Shield mTLS (uploaded CA pool); AWS uses API Gateway
|
|
237
|
+
custom-domain mTLS (PEM trust store, subject in the `$connect` event).
|
|
238
|
+
Identity is plumbed via a port — no cloud deps in `irc-core`.
|
|
239
|
+
- **`EXTERNAL` now authenticates** (was a stubbed `904 ERR_SASLFAIL` in
|
|
240
|
+
v0.2.0): `AUTHENTICATE EXTERNAL` against a bound provider succeeds with
|
|
241
|
+
`900 RPL_LOGGEDIN` / `903 RPL_SASLSUCCESS` when the cert maps to an
|
|
242
|
+
account.
|
|
243
|
+
- **mTLS-conditional advertisement**: the `sasl` cap value and
|
|
244
|
+
`908 ERR_SASLMECHS` are now driven by whether an mTLS provider is bound
|
|
245
|
+
— `PLAIN` only by default, `PLAIN,EXTERNAL` when one is. `AUTHENTICATE
|
|
246
|
+
EXTERNAL` without mTLS returns `908` (mechanism not available) instead
|
|
247
|
+
of the misleading `904`. Operators enable EXTERNAL by configuring edge
|
|
248
|
+
mTLS — no code change required.
|
|
249
|
+
|
|
250
|
+
### Added — Remaining IRC query verbs (`@serverless-ircd/irc-core`)
|
|
251
|
+
|
|
252
|
+
- **`WHOWAS`**: a nick-history store (port + in-memory reference impl)
|
|
253
|
+
records `(nick, connId, username, hostname, signoffTime)` on QUIT /
|
|
254
|
+
NICK-change and purges past a TTL. `WHOWAS <nick>{,<nick>} [<count>]`
|
|
255
|
+
queries it — `314 RPL_WHOWASUSER` per match, `369 RPL_ENDOFWHOWAS`
|
|
256
|
+
terminator, `406 ERR_WASNOSUCHNICK` when no match.
|
|
257
|
+
- **`VERSION`** (`351`), **`TIME`** (`391`, uses the injected `Clock`),
|
|
258
|
+
**`ADMIN`** (`256`/`257`/`258`), **`INFO`** (`371`/`374`),
|
|
259
|
+
**`USERHOST`** (`302`), **`ISON`** (`303`) — each a reducer + a route
|
|
260
|
+
case with spec-correct numerics. Completes the standard query-verb set.
|
|
261
|
+
|
|
262
|
+
### Added — Server identity from config (`@serverless-ircd/irc-core`)
|
|
263
|
+
|
|
264
|
+
- The `002` / `003` / `004` registration replies now reflect
|
|
265
|
+
`ServerConfig.serverVersion` / `createdAt` — the hardcoded
|
|
266
|
+
`'0.1.0'` / `'Phase 1'` placeholders are gone. A build step
|
|
267
|
+
(`scripts/generate-build-info.mjs`) bakes the package version and a
|
|
268
|
+
build timestamp into `RPL_CREATED` (`003`) when the config omits them.
|
|
269
|
+
|
|
270
|
+
### Added — Cloudflare D1-backed SASL account store (`@serverless-ircd/cf-adapter`, `@serverless-ircd/irc-core`)
|
|
271
|
+
|
|
272
|
+
- Brings the CF adapter to parity with the AWS `DynamoAccountStore`. A
|
|
273
|
+
persistent `AccountStore` pre-loads scrypt-hashed rows from a new
|
|
274
|
+
**D1** database (`ACCOUNTS_DB` binding) at `ConnectionDO`
|
|
275
|
+
construction.
|
|
276
|
+
- **Shared scrypt hashing**: `hashAccountCredential` /
|
|
277
|
+
`verifyHashedPassword` are extracted to `irc-core` so both adapters use
|
|
278
|
+
one implementation (never plaintext).
|
|
279
|
+
- **Table-then-env precedence**: when the D1 table has rows it is
|
|
280
|
+
authoritative; when empty or unreachable the adapter falls back to the
|
|
281
|
+
`SASL_ACCOUNTS` env-var seed, preserving current behavior.
|
|
282
|
+
- **`tools/seed-cf-accounts.ts`**: provisioning CLI that scrypt-hashes
|
|
283
|
+
`username:password` pairs into the D1 `accounts` table (re-run
|
|
284
|
+
overwrites the prior row).
|
|
285
|
+
|
|
286
|
+
### Added — AWS max-clients admission (`@serverless-ircd/aws-adapter`)
|
|
287
|
+
|
|
288
|
+
- `$connect` now enforces `serverConfig.maxClients` (was a reserved
|
|
289
|
+
no-op — `void params.serverConfig;`). Connections over the cap are
|
|
290
|
+
rejected at accept time, matching the Cloudflare admission gate.
|
|
291
|
+
|
|
292
|
+
### Changed
|
|
293
|
+
|
|
294
|
+
- **Toolchain**: bumped from Node ≥ 20 / pnpm 9 to **Node ≥ 24 / pnpm
|
|
295
|
+
11** (aligns the Lambda and Cloudflare Workers runtimes). Re-run
|
|
296
|
+
`corepack enable` to pick up the pinned pnpm.
|
|
297
|
+
- `@serverless-ircd/irc-core`: the request/response lookup `Effect`
|
|
298
|
+
variants (`LookupNick`, `GetConnectionInfo`, `GetChannelSnapshot`) are
|
|
299
|
+
removed from `effects.ts` and `dispatch` — they were dead scaffolding
|
|
300
|
+
with no producer or consumer.
|
|
301
|
+
- `@serverless-ircd/cf-adapter`: the dead channel-registration loop in
|
|
302
|
+
`ConnectionDO.webSocketMessage` and the reserved outbound-batching
|
|
303
|
+
field are removed (the latter was a never-wired optimization).
|
|
304
|
+
|
|
305
|
+
### ⚠️ Migration required
|
|
306
|
+
|
|
307
|
+
- **Cloudflare: new D1 binding for SASL accounts.** To persist SASL
|
|
308
|
+
accounts, create the D1 database and add the `ACCOUNTS_DB` binding
|
|
309
|
+
(default + staging) to `wrangler.toml`:
|
|
310
|
+
```bash
|
|
311
|
+
wrangler d1 create serverless-ircd-accounts
|
|
312
|
+
wrangler d1 execute serverless-ircd-accounts --command \
|
|
313
|
+
"CREATE TABLE IF NOT EXISTS accounts (account TEXT PRIMARY KEY, algorithm TEXT NOT NULL, salt TEXT NOT NULL, hash TEXT NOT NULL)"
|
|
314
|
+
```
|
|
315
|
+
**No action is required to keep working** — when the D1 table is empty
|
|
316
|
+
or unreachable the adapter falls back to the `SASL_ACCOUNTS` env-var
|
|
317
|
+
seed. There is **no Durable-Object persisted-state schema change**
|
|
318
|
+
(`PERSISTED_STATE_VERSION` stays `1`); code rollback across this
|
|
319
|
+
release is safe.
|
|
320
|
+
- **Local toolchain**: Node ≥ 24 / pnpm 11 is now required. Re-run
|
|
321
|
+
`corepack enable`.
|
|
322
|
+
|
|
323
|
+
### Known limitations
|
|
324
|
+
|
|
325
|
+
- The **CF TCP path requires Cloudflare Spectrum (Enterprise tier)** plus
|
|
326
|
+
a stateful Container origin; the **AWS TCP path** uses NLB + Lambda
|
|
327
|
+
streaming and is subject to Lambda idle-timeout / stream-duration
|
|
328
|
+
limits. The WebSocket path remains the zero-extra-deps default.
|
|
329
|
+
- **mTLS (for SASL `EXTERNAL`) requires a custom domain + uploaded
|
|
330
|
+
CA/trust-store** on both platforms and is not enabled by default.
|
|
331
|
+
- Oper-gated verbs (`KILL`, `REHASH`, `CONNECT`, `SQUIT`, `TRACE`,
|
|
332
|
+
`WALLOPS`, `SETNAME`, …) still return `421 ERR_UNKNOWNCOMMAND`.
|
|
333
|
+
- `serverName` still defaults to the `irc.example.com` placeholder when
|
|
334
|
+
an adapter config omits it (pending).
|
|
335
|
+
|
|
336
|
+
### Security
|
|
337
|
+
|
|
338
|
+
- SASL `EXTERNAL` no longer returns a misleading `904 ERR_SASLFAIL` when
|
|
339
|
+
mTLS isn't configured — it returns `908 ERR_SASLMECHS` and the
|
|
340
|
+
mechanism is not advertised until a trust store is bound. SASL
|
|
341
|
+
credentials remain scrypt-hashed only (never plaintext), now via a
|
|
342
|
+
single shared implementation across both adapters.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
13
346
|
## [0.3.0] - 2026-07-25
|
|
14
347
|
|
|
15
348
|
### Added — Operator authentication (`@serverless-ircd/irc-core`)
|
|
@@ -378,31 +711,29 @@ manual per `docs/release.md` §8.3.
|
|
|
378
711
|
|
|
379
712
|
### Known limitations
|
|
380
713
|
|
|
381
|
-
- **No AWS adapter.**
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
the only deployable platform in 0.1.0.
|
|
714
|
+
- **No AWS adapter.** The CDK stack, APIGW WebSocket handlers, DynamoDB
|
|
715
|
+
transactions, EventBridge timers, deploy pipeline, and deployment doc
|
|
716
|
+
are pending. Cloudflare is the only deployable platform in 0.1.0.
|
|
385
717
|
- **No SASL.** `CAP sasl` is advertised in the capability list but
|
|
386
718
|
`AUTHENTICATE` is not wired into the dispatcher. Plain-text password
|
|
387
|
-
authentication via `PASS` is also not enforced
|
|
388
|
-
- **No flood control.** A token-bucket wrapper
|
|
389
|
-
|
|
719
|
+
authentication via `PASS` is also not enforced.
|
|
720
|
+
- **No flood control.** A token-bucket wrapper is pending. Misbehaving
|
|
721
|
+
clients can send unbounded commands.
|
|
390
722
|
- **No server-password enforcement, rate limits, cloaking, or oper
|
|
391
|
-
credentials
|
|
723
|
+
credentials.**
|
|
392
724
|
- **No config loader.** Server name, network name, MOTD, channel
|
|
393
|
-
prefixes, max clients, oper creds are hardcoded defaults
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
`[vars].MOTD_LINES`.
|
|
725
|
+
prefixes, max clients, oper creds are hardcoded defaults. The
|
|
726
|
+
`MOTD.txt` file at the repo root is informational only; the live MOTD
|
|
727
|
+
is compiled into the Worker from `[vars].MOTD_LINES`.
|
|
397
728
|
- **No CI coverage gate.** Coverage is computed and uploaded as an
|
|
398
|
-
artifact, but no threshold is enforced
|
|
729
|
+
artifact, but no threshold is enforced. Inspect
|
|
399
730
|
`packages/*/coverage/` before deploying.
|
|
400
731
|
- **No TLS / raw TCP transport.** v1 is WebSocket text frames only.
|
|
401
|
-
TLS-hardened and `irc+tls` transports are 0.x work
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
732
|
+
TLS-hardened and `irc+tls` transports are 0.x work. Stock TCP IRC
|
|
733
|
+
clients reach the server through the local `tcp-ws-forwarder` bridge.
|
|
734
|
+
- **No `chathistory` playback.** Chat-history playback is pending;
|
|
735
|
+
clients that request backlog on JOIN will see an empty batch or no
|
|
736
|
+
response.
|
|
406
737
|
|
|
407
738
|
### Security
|
|
408
739
|
|