@primafuture/systemd-tasks 1.0.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/CHANGELOG.md +31 -0
- package/LICENSE +15 -0
- package/README.md +250 -0
- package/THIRD_PARTY_NOTICES.md +1101 -0
- package/dist/index.cjs +13315 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +316 -0
- package/dist/index.d.ts +316 -0
- package/dist/index.mjs +13311 -0
- package/dist/index.mjs.map +1 -0
- package/docs/implementation-decisions.md +323 -0
- package/package.json +63 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# Implementation decisions and evidence
|
|
2
|
+
|
|
3
|
+
## Maintainer-approved platform amendment
|
|
4
|
+
|
|
5
|
+
During the published socket-fdx migration, the maintainer explicitly selected
|
|
6
|
+
**Node 24.13.0+, Linux x64, glibc 2.28+** as this version's supported runtime.
|
|
7
|
+
This decision supersedes the original broader Node 24+/Linux wording for platform
|
|
8
|
+
support only. The original `IMPLEMENTATION.md` and `specification.md` were used
|
|
9
|
+
unchanged during implementation and independent review, then removed at the
|
|
10
|
+
maintainer's request when preparing version 1.0.0. All other requirements, including systemd 257+,
|
|
11
|
+
cgroup v2, lifecycle guarantees, and T01–T18, remain applicable.
|
|
12
|
+
|
|
13
|
+
## Feasibility checkpoint
|
|
14
|
+
|
|
15
|
+
The initial Node experiments ran on 2026-09-07 with Node 24.13.0, npm 11.16.0,
|
|
16
|
+
systemd 257.9-0ubuntu2.4, Linux 6.17.0-14-generic, and the existing user manager.
|
|
17
|
+
The manager reported `degraded`; it was reachable and the isolated task scenarios
|
|
18
|
+
worked. No manager configuration, linger, permissions, or existing service was changed.
|
|
19
|
+
|
|
20
|
+
Reproduction commands from the project directory:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
node scripts/probe.mjs
|
|
24
|
+
node scripts/feasibility.mjs
|
|
25
|
+
node scripts/recovery-probe.mjs
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Each experiment creates unique `pf-systemd-tasks-*` identities. Its cleanup is
|
|
29
|
+
restricted to those exact task/retention pairs. Generated output stays inside the
|
|
30
|
+
project. `feasibility.mjs` launches separate Node clients and observers and sends
|
|
31
|
+
SIGKILL to the client after creation or stop acceptance. This is actual Node/D-Bus
|
|
32
|
+
integration, not a `systemd-run` wrapper test.
|
|
33
|
+
|
|
34
|
+
Observed before implementing the public API:
|
|
35
|
+
|
|
36
|
+
| Scenario | Observation |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| Literal argv, cwd, environment | Empty arguments, spaces, Unicode, quotes, `$`, and `%` survived direct `ExecStartEx` with `no-env-expand`. |
|
|
39
|
+
| Unix FD and binary output | Bytes `00 ff 80 0a` survived; the caller's FD remained open after acceptance and could then be closed. |
|
|
40
|
+
| Client death with file output | A service finished and wrote output after its Node client was SIGKILLed; a fresh Node observer recovered the result. |
|
|
41
|
+
| Success and application failure | Exit 0 and 7 remained observable after client death, with raw `success` and `exit-code` respectively. |
|
|
42
|
+
| Execution failure | Missing executable produced status 203 without entering the active state; an application deliberately returning 203 did enter it. Missing cwd produced status 200 without entering active. |
|
|
43
|
+
| Signal and runtime deadline | SIGKILL produced raw `signal`; a TERM-resistant task reached SIGKILL through the manager's runtime/stop timers and produced raw `timeout`. |
|
|
44
|
+
| Accepted stop followed by client death | The manager completed escalation without the requesting client. |
|
|
45
|
+
| Main exit and descendant cleanup | A detached (`setsid`) TERM-resistant descendant was gone before completion; main exit 0 remained available even though cleanup escalation produced raw `timeout`. |
|
|
46
|
+
| Lost application reply | A client abandoned its start promise and was killed after submission; lookup recovered the run, and an explicit colliding start was rejected. This is loss at the application boundary; precise wire loss is covered separately by injected transport tests. |
|
|
47
|
+
| Release and replacement | Releasing the pair allowed collection; an explicitly authorized experiment reusing the name received a different InvocationID. |
|
|
48
|
+
| Retention initialization failure | A missing retention executable prevented execution of the user command. The task had no InvocationID and no main exit evidence. |
|
|
49
|
+
|
|
50
|
+
An inactive unit with a pending start job is **not** complete. The experiment caught
|
|
51
|
+
this race; completion must also inspect the job and cgroup state. `Result=timeout`
|
|
52
|
+
alone cannot identify a runtime deadline: it can also describe stop or descendant
|
|
53
|
+
cleanup escalation. The API must preserve these distinctions without inventing causes.
|
|
54
|
+
|
|
55
|
+
## Retention mechanism
|
|
56
|
+
|
|
57
|
+
Create the task and auxiliary service in one `StartTransientUnit` request, using
|
|
58
|
+
job mode `fail`. The task has `Requires` and `After` dependencies on its uniquely
|
|
59
|
+
named retention service. The auxiliary service runs `/usr/bin/true` with
|
|
60
|
+
`Type=oneshot`, `RemainAfterExit=yes`, and `Before` referencing the task. Therefore
|
|
61
|
+
retention activation precedes task execution, and the active auxiliary service
|
|
62
|
+
keeps the task referenced after termination without a living helper process.
|
|
63
|
+
|
|
64
|
+
The task uses `Type=exec`, `ExitType=main`, `KillMode=control-group`, `Restart=no`,
|
|
65
|
+
and manager-owned stop/runtime timers. It does not use `RemainAfterExit` itself.
|
|
66
|
+
Release checks both identities and completion before removing retention. Failed
|
|
67
|
+
states must also be reset to permit garbage collection. Stop may replace pending
|
|
68
|
+
jobs to cancel a queued start; creation never uses replacement or restart.
|
|
69
|
+
|
|
70
|
+
This relies on the [systemd 257 dependency-based garbage collection contract](https://github.com/systemd/systemd/blob/v257/man/systemd.unit.xml)
|
|
71
|
+
and the [257 service lifecycle](https://github.com/systemd/systemd/blob/v257/src/core/service.c).
|
|
72
|
+
It does not provide persistence across manager restart or reboot, or protection
|
|
73
|
+
against another equally privileged process changing these units.
|
|
74
|
+
|
|
75
|
+
## Transport and native installation
|
|
76
|
+
|
|
77
|
+
The current transport is `dbus-next` 0.10.2 (MIT) with the published
|
|
78
|
+
`@primafuture/socket-fdx` 1.0.0 (ISC), installed under the direct npm alias
|
|
79
|
+
`usocket`. Its root export provides the compatible `USocket` constructor. No
|
|
80
|
+
installed dependency files or global prototypes are patched.
|
|
81
|
+
|
|
82
|
+
The following records the superseded feasibility candidates, not the current
|
|
83
|
+
runtime dependencies.
|
|
84
|
+
The originally requested `usocket` 0.3.0 failed to build: its node-gyp 7.1.2 reported
|
|
85
|
+
`Completion callback never invoked!` with Node 24.13.0 and Python 3.13.7. Because
|
|
86
|
+
that dependency is optional upstream, an apparently successful npm installation
|
|
87
|
+
silently omitted FD support. Connection must explicitly reject that condition.
|
|
88
|
+
|
|
89
|
+
`usocket` 1.0.3 built and transmitted descriptors using NAN 2.25.0 and node-gyp
|
|
90
|
+
12.4.0, with the host's Python 3.13.7, make, and C++ compiler. Python is a native
|
|
91
|
+
build prerequisite, not a runtime dependency of task execution. Version 1.1.0
|
|
92
|
+
also built, but its node-gyp 13 dependency declares a newer Node minimum than the
|
|
93
|
+
tested 24.13.0; it was not selected.
|
|
94
|
+
|
|
95
|
+
The build bundles the pinned JavaScript D-Bus implementation and its resolved
|
|
96
|
+
JavaScript dependencies, while leaving `usocket` as a pinned external runtime
|
|
97
|
+
dependency. This makes the selected native version effective in consumer projects:
|
|
98
|
+
npm overrides in a published dependency do not control the consumer's resolution.
|
|
99
|
+
The development override also selects xml2js 0.6.2 instead of the vulnerable older
|
|
100
|
+
release. Licensing notices accompany bundled dependencies. No D-Bus wire protocol
|
|
101
|
+
is implemented by this library.
|
|
102
|
+
|
|
103
|
+
The transport adapter must bound pending calls and explicitly destroy the native
|
|
104
|
+
socket at disconnect. It uses a small, documented set of pinned transport internals
|
|
105
|
+
for FD capability checks and abandoned-call cleanup. Upstream maintenance age,
|
|
106
|
+
native compatibility, and these internal hooks are maintenance risks. Connection
|
|
107
|
+
preflight awaits non-FD D-Bus replies before returning a usable client, so the
|
|
108
|
+
first FD-bearing request follows the daemon's completed Hello exchange.
|
|
109
|
+
|
|
110
|
+
The replacement ships a Linux x64/glibc 2.28+ prebuild and requires Node 24.13.0+.
|
|
111
|
+
It has no runtime dependencies or install hook. Its Node-API boundary also uses
|
|
112
|
+
libuv, so arbitrary future ABI compatibility is not assumed. This project's
|
|
113
|
+
consumer smoke installs with `--ignore-scripts` and no overrides, checks the actual
|
|
114
|
+
aliased package identity and loaded `.node` binary, and executes tasks using FDs.
|
|
115
|
+
|
|
116
|
+
## Environment and execution evidence
|
|
117
|
+
|
|
118
|
+
Before submission, read the manager environment and place inherited names absent
|
|
119
|
+
from the explicit map in `UnsetEnvironment`. Do not change the manager environment.
|
|
120
|
+
Systemd still supplies its own execution metadata. The experiment observed
|
|
121
|
+
`MANAGERPID`, `INVOCATION_ID`, `SYSTEMD_EXEC_PID`, `MEMORY_PRESSURE_WATCH`, and
|
|
122
|
+
`MEMORY_PRESSURE_WRITE`. This is not a byte-for-byte promise for the whole environment.
|
|
123
|
+
Concurrent external changes to manager configuration are outside the isolation
|
|
124
|
+
guarantee and must be documented.
|
|
125
|
+
|
|
126
|
+
Retained active-entry timestamps under `Type=exec`, main-exit fields, and raw
|
|
127
|
+
systemd results form the execution evidence. Numeric status 203 alone is not an
|
|
128
|
+
execution-failure classifier. If the manager never executed the main process,
|
|
129
|
+
the absence of an invocation and exit evidence remains explicit.
|
|
130
|
+
|
|
131
|
+
## Supported baseline
|
|
132
|
+
|
|
133
|
+
V1 requires Node 24.13.0+ on Linux x64 with glibc 2.28+,
|
|
134
|
+
a local user manager with systemd 257 or newer,
|
|
135
|
+
Unix FD negotiation, and a cgroup v2 hierarchy. Version 257 is a conservative
|
|
136
|
+
baseline for the experimentally verified mapping; older releases are not claimed.
|
|
137
|
+
Only the concrete versions recorded above have been exercised at this checkpoint.
|
|
138
|
+
|
|
139
|
+
## Final API and packaged verification
|
|
140
|
+
|
|
141
|
+
The frozen format is version 1. Intents include the normalized specification and
|
|
142
|
+
its SHA-256 fingerprint; references omit the specification and bind local UID,
|
|
143
|
+
machine ID, boot ID, bus ID, manager bus owner, and both service InvocationIDs.
|
|
144
|
+
An unavailable ID is null, never a wildcard for a later invocation. Manager changes
|
|
145
|
+
invalidate the connection; there is no implicit reconnect. Equal-privilege external
|
|
146
|
+
unit replacement remains a read/check/mutate race because the systemd methods
|
|
147
|
+
accept a unit name rather than an InvocationID precondition.
|
|
148
|
+
|
|
149
|
+
The build bundles 16 JavaScript packages and generates full attribution from the
|
|
150
|
+
actual source map. The pinned `socket-fdx` alias remains external. Both conditional
|
|
151
|
+
declaration branches are tested with strict NodeNext TypeScript consumers.
|
|
152
|
+
Installation is performed with scripts disabled. The smoke consumer has its own manifest and
|
|
153
|
+
node_modules under a fresh `.artifacts/package-smoke-*` directory, separate from
|
|
154
|
+
`src`, and imports only the installed tarball. A test-only CommonJS resolver guard
|
|
155
|
+
rejects absolute resolutions outside that consumer to exclude ancestor packages
|
|
156
|
+
(including optional `debug`/`supports-color` probes). Runtime require-cache checks
|
|
157
|
+
also reject dependency leakage. This is dependency isolation within the authorized
|
|
158
|
+
workspace, not a container or a second physical host.
|
|
159
|
+
|
|
160
|
+
The runtime artifacts import without a native connection. The unsupported-platform
|
|
161
|
+
smoke uses an injected `process.platform` value; no macOS or Windows execution is
|
|
162
|
+
claimed. The native package has no transitive runtime dependencies. Native ABI,
|
|
163
|
+
upstream maintenance, and reliance on pinned dbus-next internals require continued
|
|
164
|
+
maintenance and fresh packaged verification when upgrading.
|
|
165
|
+
|
|
166
|
+
Reproduce the final checks with:
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
npm run check
|
|
170
|
+
npm run test:integration
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The second command repeats the real lifecycle suite, including the crash matrix,
|
|
174
|
+
retention, immediate exits, and descriptor leak checks. The following table maps
|
|
175
|
+
all acceptance scenarios to concrete evidence. `unit/` and `integration/` paths
|
|
176
|
+
are relative to `__tests__` in the repository; those sources are not published.
|
|
177
|
+
|
|
178
|
+
| ID | Evidence | Boundary |
|
|
179
|
+
| --- | --- | --- |
|
|
180
|
+
| T01 | `integration/execution.test.ts`, `unit/validation.test.ts`: literal argv, cwd, explicit env, immutable serializable preparation | Real executable and local validation |
|
|
181
|
+
| T02 | `integration/execution.test.ts`: binary input/output, separate channels, 32 MiB direct file output; crash matrix exits 0 and 7 | Real FDs and bounded observed RSS; not an arbitrary-volume benchmark |
|
|
182
|
+
| T03 | `integration/execution.test.ts`, `unit/io.test.ts`, `integration/faults.test.ts`: missing exec/cwd, executable permissions, I/O failures, status 203 distinction | Real OS errors; explicit D-Bus permission rejection injected |
|
|
183
|
+
| T04 | `integration/execution.test.ts`, `unit/evidence.test.ts`: signal, runtime escalation, raw result classification | Real manager timers plus deterministic evidence classification |
|
|
184
|
+
| T05 | `integration/execution.test.ts`, `unit/evidence.test.ts`: setsid TERM-resistant descendant disappears before completion; unreadable/populated cleanup never reports complete | Real descendant/cgroup behavior; incomplete evidence injected |
|
|
185
|
+
| T06 | `integration/crash.test.ts`: submitting Node process SIGKILL, fresh Node observer, retained file output | Real processes, two rounds per retained outcome |
|
|
186
|
+
| T07 | `integration/crash.test.ts`, `unit/lifecycle.test.ts`: accepted stop followed by stopping-client SIGKILL; cancellation delivery stages | Real escalation; precise cancellation timing injected |
|
|
187
|
+
| T08 | `integration/crash.test.ts`, `integration/lifecycle.test.ts`: runtime deadline without client, local abort/timeout leaves task and other waiter alive | Real manager and concurrent clients |
|
|
188
|
+
| T09 | `integration/faults.test.ts`, `unit/lifecycle.test.ts`, `scripts/feasibility.mjs`: lost reply, late recovery, missing unit, auxiliary collision and initialization failure | Actual accepted task with reply loss injected at adapter boundary; real collisions/failure; absent-after-unknown simulated |
|
|
189
|
+
| T10 | `integration/crash.test.ts`: success, exit 7, exec failure, signal, timeout, stop retained until explicit release | Real client deaths and fresh observers; repeated matrix |
|
|
190
|
+
| T11 | `integration/lifecycle.test.ts`, `integration/faults.test.ts`, `unit/lifecycle.test.ts`, `unit/evidence.test.ts`: recreated name, stale IDs, collisions, manager mismatch, incomplete reference | Real replacement/collision; alternate manager identity injected |
|
|
191
|
+
| T12 | `integration/lifecycle.test.ts`, `unit/lifecycle.test.ts`: 25 FD-bearing tasks with multiple waiters, abort, snapshot race, pending job, actual overlapping stop/release and deferred stop acknowledgment/cancellation | Real repetition and overlapping calls plus deterministic event ordering |
|
|
192
|
+
| T13 | `integration/faults.test.ts`, `unit/lifecycle.test.ts`: lost reads/mutations, permission vs NoReply, disconnect with pending waits | Adapter failures injected around real calls and fake transport; no manager shutdown |
|
|
193
|
+
| T14 | `integration/execution.test.ts`, `integration/lifecycle.test.ts`, `integration/faults.test.ts`, `integration/pipes.test.ts`, `unit/io.test.ts`: borrowed ownership, repeated FD-bearing execution and manager rejection counts, partial-open leaks, descriptor cleanup after disconnect | Real descriptors, native transport, Linux /proc measurements |
|
|
194
|
+
| T15 | `integration/pipes.test.ts`, `integration/lifecycle.test.ts`, `unit/io.test.ts`: append/truncate, hard-link coalescing, error side effects, EPIPE and EOF | Real files, FIFO-backed Unix pipes, and execution failures |
|
|
195
|
+
| T16 | `integration/lifecycle.test.ts`, `integration/crash.test.ts`, `unit/lifecycle.test.ts`: refuse live release, repeat release, preserve logs, independent total deadline, preserve reset/stop acknowledgment across timeout | Real retention and deterministic delayed observations |
|
|
196
|
+
| T17 | `unit/validation.test.ts`, `unit/environment.test.ts`, `scripts/smoke.ts`: invalid inputs, retention prerequisites, native architecture/libc rejection, simulated unsupported platform | Pure validation, isolated filesystem/native-loader faults through public connect, and installed import/connect check |
|
|
197
|
+
| T18 | `scripts/smoke.ts`: npm tarball install without scripts or overrides, published alias/native binary identity, ESM/CJS binary execution and release, .mts/.cts consumer types, artifact allowlist | Real installed artifact with ancestor-module isolation |
|
|
198
|
+
|
|
199
|
+
The runnable examples also exercise basic execution, fsynced intent before start,
|
|
200
|
+
a separate recovery process, fsynced result before release, local wait timeout,
|
|
201
|
+
manager runtime timeout, and explicit stop escalation. Their task IDs and output
|
|
202
|
+
records are saved under `.artifacts/examples`.
|
|
203
|
+
|
|
204
|
+
## Explicit limitations of the evidence
|
|
205
|
+
|
|
206
|
+
Only Node 24.13.0 on Linux x86-64 and systemd 257.9 were run. Other Node minors,
|
|
207
|
+
architectures, distributions, kernel/controller combinations, newer systemd,
|
|
208
|
+
containers, restricted buses, and alternative native build toolchains are unverified.
|
|
209
|
+
The suite does not deliberately reboot the machine, stop/restart the user's manager,
|
|
210
|
+
change its environment, change linger, or change access policy. Manager restart,
|
|
211
|
+
bus loss, exact lost replies, and permission categories are represented by injected
|
|
212
|
+
boundaries where indicated above. Retention across actual manager shutdown is not
|
|
213
|
+
part of the contract. Cgroup escape by privileged code and hostile external changes
|
|
214
|
+
to owned units or I/O paths are outside the guarantee.
|
|
215
|
+
|
|
216
|
+
## Acceptance result — 2026-09-07
|
|
217
|
+
|
|
218
|
+
All T01–T18 scenarios above passed within their stated evidence boundaries.
|
|
219
|
+
`npm run check` completed with 28 unit tests and 30 real integration tests passing,
|
|
220
|
+
zero skipped tests, a successful dual-format build, and all packaged runtime/type
|
|
221
|
+
smoke checks passing. A separate repeat of the integration suite passed all 30 tests
|
|
222
|
+
again. All four runnable example entrypoints completed successfully. After cleanup,
|
|
223
|
+
no `pf-systemd-tasks-*` units remained loaded in the user manager. The complete
|
|
224
|
+
locked dependency audit reported zero known vulnerabilities at verification time;
|
|
225
|
+
that is a dated registry result, not a guarantee of absence of vulnerabilities.
|
|
226
|
+
|
|
227
|
+
## Independent review follow-up
|
|
228
|
+
|
|
229
|
+
The fresh review `2026-09-07_09-34-45` requested changes despite the passing baseline
|
|
230
|
+
suite. The original acceptance result above describes that baseline, not final
|
|
231
|
+
review approval. Two issues were confirmed:
|
|
232
|
+
|
|
233
|
+
- Connection preflight did not verify its fixed retention executable. `connect()`
|
|
234
|
+
now checks that `/usr/bin/true` resolves to a regular file with execute access,
|
|
235
|
+
reporting `UNSUPPORTED_ENVIRONMENT` before opening the bus. Three isolated
|
|
236
|
+
filesystem-fault tests exercise missing, non-regular, and non-executable cases
|
|
237
|
+
through the public `connect()` API without changing the host executable.
|
|
238
|
+
- Upstream `usocket@1.0.3` loses its FD array after a zero-byte native write. A
|
|
239
|
+
deterministic reproduction with two queued messages confirmed the missing FDs
|
|
240
|
+
on repeated drain attempts. The native loop also retains `msghdr.msg_control`
|
|
241
|
+
after clearing its local FD vector, permitting duplicate control payloads if a
|
|
242
|
+
single native call performs multiple successful partial sends.
|
|
243
|
+
|
|
244
|
+
The upstream dependency is now replaced by the independently implemented,
|
|
245
|
+
published `@primafuture/socket-fdx@1.0.0`. Its shipped
|
|
246
|
+
`docs/architecture-and-evidence.md` records F04/F05 native regressions: repeated
|
|
247
|
+
EAGAIN preserves descriptors, positive partial sends deliver them once, and an
|
|
248
|
+
independent receiver detects deliberately broken ancillary reuse as a negative
|
|
249
|
+
control. These are the dependency's recorded evidence, not tests rerun by this
|
|
250
|
+
consumer. This project verifies the published adapter through its own real systemd
|
|
251
|
+
integration and installed-package checks. The earlier patch draft is historical
|
|
252
|
+
only; no vendored patch or node_modules mutation is used.
|
|
253
|
+
|
|
254
|
+
The unused internal transport-version field was removed. Test callback comments
|
|
255
|
+
now describe their fixture boundary or the reason for an assertion, rather than
|
|
256
|
+
repeating the adjacent test title.
|
|
257
|
+
|
|
258
|
+
## Published socket-fdx migration verification
|
|
259
|
+
|
|
260
|
+
The initial migration used registry package `@primafuture/socket-fdx@0.1.0-rc.0` with integrity
|
|
261
|
+
`sha512-9BjkqES7Jx/SQvk8Gzpj0BRcKhJPh0kQHNi9SsAPr7vM3LuVIH8hsYLcHQihxRExi+AEQrM07buq0lWn4TNVQA==`.
|
|
262
|
+
`npm ls usocket --all` resolves both the direct runtime dependency and development
|
|
263
|
+
dbus-next dependency to that single alias. The old NAN/node-gyp runtime dependency
|
|
264
|
+
closure is removed. The package remains external to the D-Bus JavaScript bundle.
|
|
265
|
+
|
|
266
|
+
`npm run check` passed 31 unit tests and 30 integration tests, followed by the
|
|
267
|
+
dual-format build and installed runtime/type smoke. A preceding separate integration
|
|
268
|
+
run also passed all 30 tests. Consumer installation used no overrides and disabled
|
|
269
|
+
install scripts; both module formats loaded the shipped socket-fdx native binary
|
|
270
|
+
and completed real binary FD output and release. The production dependency audit
|
|
271
|
+
reported zero known vulnerabilities. These results use the host environment
|
|
272
|
+
recorded above; the dependency's wider build matrix is not a downstream verification
|
|
273
|
+
claim for this project. Independent review is a separate gate from these checks.
|
|
274
|
+
|
|
275
|
+
The continuation review identified native environment error misclassification and
|
|
276
|
+
gaps in T12/T14 coverage. Native platform, ABI, and missing-binary codes now map to
|
|
277
|
+
`UNSUPPORTED_ENVIRONMENT`; public connection tests inject architecture and libc
|
|
278
|
+
capabilities without modifying the host. Two deferred-reply tests overlap stop
|
|
279
|
+
and release through completion and cancellation, and a real manager test overlaps
|
|
280
|
+
stop-with-wait and release. The 25-iteration loop now sends real output descriptors
|
|
281
|
+
and checks output plus per-iteration FD counts, including execution failures.
|
|
282
|
+
Eight real FD-bearing requests rejected by the manager also return to the original
|
|
283
|
+
FD count; disconnect checks confirm release of each connection's bus socket.
|
|
284
|
+
The revised `npm run check` passed 36 unit tests, 32 integration tests, both builds,
|
|
285
|
+
and all isolated package smoke checks, with no skipped tests.
|
|
286
|
+
|
|
287
|
+
The maintainer then requested the stable published `@primafuture/socket-fdx@1.0.0`.
|
|
288
|
+
The direct alias and installed-artifact identity assertion now pin that version;
|
|
289
|
+
its registry integrity is
|
|
290
|
+
`sha512-ASACXfVCDTUV2UQYh/mjTJ0HEbFjEZYkmZSV9HxMJ1YGmWVRcflwNlS2q83ucWypSzDIfG+HgbE2pxzU6XI+fA==`.
|
|
291
|
+
The installed native binary and both JavaScript runtime entrypoints have identical
|
|
292
|
+
SHA-256 hashes to the reviewed release candidate. The native SHA-256 is
|
|
293
|
+
`9ca53cde1620155c96e91a836f450ee43a6d8dcb339050c39107c5a87ccd7ae1`.
|
|
294
|
+
Both development and runtime dependency branches resolve to the stable alias.
|
|
295
|
+
The full aggregate check was rerun against 1.0.0 and passed the same 36 unit and
|
|
296
|
+
32 integration tests, dual-format build, and all installed-artifact smoke checks.
|
|
297
|
+
The full locked dependency audit reported zero known vulnerabilities at that check.
|
|
298
|
+
|
|
299
|
+
A subsequent independent review found two additional defects. Release no longer
|
|
300
|
+
reuses a single-request transport budget for the entire multi-request sequence.
|
|
301
|
+
Its optional `ReleaseOptions` provide an independent total timeout (5000 ms by
|
|
302
|
+
default) and abort signal. Acknowledged reset and stop mutations retain accepted
|
|
303
|
+
delivery evidence if later observation times out; explicit absence remains a no-op.
|
|
304
|
+
Tests exercise individually timely reads whose sum exceeds the transport budget,
|
|
305
|
+
timeouts after reset/stop acknowledgment, and pre-submission cancellation.
|
|
306
|
+
|
|
307
|
+
Diagnostics now consume returned promises and thenables without awaiting them.
|
|
308
|
+
A separate child process under `--unhandled-rejections=strict` verifies delayed
|
|
309
|
+
sink rejection, rejecting thenables, and a never-settling observer, while accepted
|
|
310
|
+
task submission and disconnect still complete and no global rejection escapes.
|
|
311
|
+
The aggregate check after these fixes passed 41 unit tests, 32 real integration
|
|
312
|
+
tests, type checking, both distribution formats, and the isolated package smoke
|
|
313
|
+
with `ReleaseOptions` checked through both declaration branches.
|
|
314
|
+
|
|
315
|
+
Mixed release outcomes now retain a separate `acceptedCleanupMutations` count.
|
|
316
|
+
A later rejected/not-submitted step cannot overwrite earlier confirmed effects as
|
|
317
|
+
though the entire release were rejected. Later unknown delivery remains unknown,
|
|
318
|
+
while the count preserves preceding acknowledgments. Nine deterministic cases
|
|
319
|
+
cover rejection, non-submission, and uncertain delivery at each of the main reset,
|
|
320
|
+
retention reset, and retention stop boundaries. The unused raw object-path field
|
|
321
|
+
was removed; transport paths remain local to the D-Bus request that needs them.
|
|
322
|
+
The aggregate check passed 50 unit tests, 32 real integration tests, both builds,
|
|
323
|
+
and installed runtime/type verification including partial-cleanup error metadata.
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@primafuture/systemd-tasks",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "One-shot process tasks owned by the systemd user manager.",
|
|
6
|
+
"author": "PrimaFuture.cz s.r.o. <dev@primafuture.cz>",
|
|
7
|
+
"license": "ISC",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=24.13.0"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"usocket": "npm:@primafuture/socket-fdx@1.0.0"
|
|
13
|
+
},
|
|
14
|
+
"overrides": {
|
|
15
|
+
"dbus-next": {
|
|
16
|
+
"usocket": "$usocket",
|
|
17
|
+
"xml2js": "0.6.2"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "24.13.3",
|
|
22
|
+
"tsup": "8.5.0",
|
|
23
|
+
"tsx": "4.20.6",
|
|
24
|
+
"typescript": "5.9.3",
|
|
25
|
+
"dbus-next": "0.10.2"
|
|
26
|
+
},
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"main": "./dist/index.cjs",
|
|
29
|
+
"module": "./dist/index.mjs",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"import": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"default": "./dist/index.mjs"
|
|
36
|
+
},
|
|
37
|
+
"require": {
|
|
38
|
+
"types": "./dist/index.d.cts",
|
|
39
|
+
"default": "./dist/index.cjs"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"docs",
|
|
46
|
+
"README.md",
|
|
47
|
+
"CHANGELOG.md",
|
|
48
|
+
"LICENSE",
|
|
49
|
+
"THIRD_PARTY_NOTICES.md"
|
|
50
|
+
],
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup && tsx scripts/licenses.ts",
|
|
56
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.dev.json --noEmit",
|
|
57
|
+
"test": "node --import tsx --test --test-timeout=15000 __tests__/unit/*.test.ts",
|
|
58
|
+
"test:integration": "node --import tsx --test --test-concurrency=1 __tests__/integration/*.test.ts",
|
|
59
|
+
"smoke": "tsx scripts/smoke.ts",
|
|
60
|
+
"check": "npm run typecheck && npm test && npm run test:integration && npm run build && npm run smoke",
|
|
61
|
+
"prepublishOnly": "npm run check"
|
|
62
|
+
}
|
|
63
|
+
}
|