From 92479d697d781b50e774d93595644383c71d9c5c Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Wed, 30 Sep 2026 20:21:59 +0200 Subject: [PATCH] Record the layered src decision and the pdu-to-message edge --- AGENTS.md | 14 ++++++++------ docs/decisions.md | 7 +++++++ src/client/client.ts | 1 - src/server/server.ts | 1 - todo.md | 5 ++--- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2773f86..375ace7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,7 +49,7 @@ src/ unanswered-error.ts UnansweredError: it went out and no answer came back codec/ Bytes <-> PduObject commands.ts The 33 commands, their ids and ordered parameter lists - constants.ts consts + constsById, and the SMPP version constants + constants.ts consts + constsById, and the version that allows optional parameters encodings.ts GSM 03.38, LATIN1, UCS2, detection, data_coding resolution field-types.ts Wire types: int8/int16/int32/string/cstring/buffer/arrays framer.ts PduFramer: a byte stream cut into complete PDUs @@ -84,11 +84,12 @@ src/ server/server.ts server() -> { err, server }, server owns the listener + close() ``` -Imports point one way: `codec` ← `protocol` ← `messages` ← `session/` ← `client`/`server`, and -the root files sit beside that order; `codec` reaches outside itself only for `result.ts` and, from -`pdu.ts`, `message.ts`. The ways back up are the `Session` handed to `createSms()`, `HeldMessages` -and `IncomingRequests`, which call back into it, and to `OnRequest` and `onConnected` in -`options.ts`, all imported as a type only. +Imports point one way: `codec` ← `protocol` ← `messages` ← `session/` ← `client`/`server`, and the +root files sit beside that order. One edge runs against it: `codec/pdu.ts` reads `message.ts`, which +reads `protocol/udh.ts`, so moving `message.ts` into `protocol/` needs `pdu.ts` off it first. The +ways back up are the `Session` handed to `createSms()`, `HeldMessages` and `IncomingRequests`, which +call back into it, and to `OnRequest` and `onConnected` in `options.ts`, all imported as a type +only. **Parameter order is wire order.** The key order inside `cmds.*.params` is the order the fields are written to and read from the buffer. Never sort those alphabetically — the alphabetical-ordering @@ -317,6 +318,7 @@ this is not a changelog. `SendWindow` rather than extracted. - `SmppLog` is a five-method contract this library declares, not a dependency. - The TLS tests build their own self-signed certificate in DER +- `src/` is grouped by layer, and imports point down the layers. - `test/` stays flat, and a file there is named for the question it answers rather than for the module it covers. - CI tests on Linux only; `src/` keeps off what is known to break on macOS or Windows. diff --git a/docs/decisions.md b/docs/decisions.md index 3f16cd1..3828d92 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -795,6 +795,13 @@ rule and an index of the titles below. fail on every developer machine, and a committed key leaks in a public repository. Valid while the dev image has no openssl. +- **`src/` is grouped by layer, and imports point down the layers.** Maintainer's call, 2026-09-30, + building [plan 3](comprehension-rewrite/plan-3.md): `codec/`, `protocol/`, `messages/`, `session/`, + `client/`, `server/`, with the [map](../AGENTS.md#architecture) naming the direction. Serves goal + 8's reshapeable internals, which a reader has to find before reshaping: every comprehension panel + navigated by AGENTS.md's map rather than the flat tree it described. Rejected: `src/` flat until a + module has to move for another reason. + - **`test/` stays flat, and a file there is named for the question it answers rather than for the module it covers.** Architecture review, 2026-09-08, at 18 test files: what keeps that count honest is the naming rule rather than a tree — `operator-receipts.test.ts` holds a corpus defined by where diff --git a/src/client/client.ts b/src/client/client.ts index d2e36eb..4243441 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -41,7 +41,6 @@ export type ClientOptions = { username?: string; }; - function armConnectTimeout( sock: Socket, connectTimeout: number | false, diff --git a/src/server/server.ts b/src/server/server.ts index 392a4c4..2aa4f1f 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -50,7 +50,6 @@ export type ServerEvents = { session: [Session]; }; - /** A listener may return a promise: an `async` one that rejects is routed like one that throws. */ type ServerListener = (...args: ServerEvents[K]) => unknown; diff --git a/todo.md b/todo.md index d55c79f..f73b491 100644 --- a/todo.md +++ b/todo.md @@ -215,8 +215,7 @@ comprehension-panel scoring run over the whole project. Each round: - let no dimension drop, and record the four scores and the overall in this paragraph. Each chunk also closes the items further down that it absorbs, and its PR names them: `hold` and -`refusing`, `ASCII`, and the link that -dropped mid-rebind. +`refusing`, `ASCII`, and the link that dropped mid-rebind. Every chunk that changes the public API updates README's examples, MIGRATION.md, CHANGELOG.md, docs/decisions.md and the AGENTS.md map in its own PR, and deletes what it replaces; no old and new @@ -538,7 +537,7 @@ to the plan are [plan 3 §8](docs/comprehension-rewrite/plan-3.md#8-architecture Maintainer's ask, 2026-09-14; not started until asked. - [ ] **Count what is left of a budget one way in `leftOf()` and `LinkLife`.** Today they are one - concept counted twice. `idle-waiters.ts` reads what is left of a budget as `Math.max(1, + concept counted twice. `session/waiting.ts` reads what is left of a budget as `Math.max(1, deadline - now)`, because 0 means "forever" there; `link-life.ts` runs the same subtraction and calls `<= 0` expired. Neither is reachable from the other, so nothing can disagree today, but a reader who learns one and applies it to the other is wrong. A budget type both take