projmux 0.14.2 → 0.15.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/README-ko.md +58 -114
- package/README.md +49 -110
- package/docs/agent-workflow.md +1420 -37
- package/docs/architecture.md +95 -70
- package/docs/assets/projmux-ai-attention-ko.gif +0 -0
- package/docs/assets/projmux-ai-attention.gif +0 -0
- package/docs/assets/projmux-overview-ko.gif +0 -0
- package/docs/assets/projmux-overview.gif +0 -0
- package/docs/assets/projmux-three-pane-workflow-ko.gif +0 -0
- package/docs/assets/projmux-three-pane-workflow.gif +0 -0
- package/docs/claude-coordination-endpoints.md +254 -0
- package/docs/cli-guide.md +283 -39
- package/docs/cli.md +2059 -56
- package/docs/codex-generation-pool.md +618 -0
- package/docs/codex-installed-compatibility.md +69 -0
- package/docs/codex-native-required-migration.md +98 -9
- package/docs/column-profiles.md +83 -0
- package/docs/configuration.md +43 -4
- package/docs/heterogeneous-dialogue-canary.md +339 -0
- package/docs/hooks.md +48 -15
- package/docs/npm-distribution.md +31 -0
- package/docs/operational-diagnostics.md +125 -0
- package/docs/pr-guideline.md +3 -2
- package/docs/replacement-contract.md +555 -0
- package/docs/session-restore.md +15 -5
- package/docs/settings-ia.md +5 -4
- package/docs/testing.md +12 -7
- package/docs/troubleshooting.md +19 -0
- package/docs/upgrading.md +48 -3
- package/npm/projmux.js +65 -0
- package/package.json +5 -5
|
@@ -332,6 +332,28 @@ support archives remain count-only for that file. The common journal is the
|
|
|
332
332
|
safe correlated source for watcher lifecycle and anomalous ingest
|
|
333
333
|
classification, while the bounded file retains detailed normal-state rows.
|
|
334
334
|
|
|
335
|
+
## Detached process SIGQUIT artifacts
|
|
336
|
+
|
|
337
|
+
The detached Codex lifecycle watcher and endpoint broker keep provider hooks
|
|
338
|
+
quiet and non-blocking: hook stdout and stderr are still discarded and hook
|
|
339
|
+
failure still cannot block the provider. For process-local deadlock diagnosis,
|
|
340
|
+
sending `SIGQUIT` to the exact projmux-owned `codex-broker-watch` or
|
|
341
|
+
`codex-broker serve` PID writes one artifact before retaining SIGQUIT's fatal,
|
|
342
|
+
non-zero exit behavior:
|
|
343
|
+
|
|
344
|
+
```text
|
|
345
|
+
${XDG_STATE_HOME:-$HOME/.local/state}/projmux/crash/codex-broker-watch-<pid>.sigquit.txt
|
|
346
|
+
${XDG_STATE_HOME:-$HOME/.local/state}/projmux/crash/codex-broker-serve-<pid>.sigquit.txt
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
The `crash` directory is mode `0700`, each file is mode `0600`, and publication
|
|
350
|
+
is bounded to 1 MiB and atomic. A dump that reaches the bound ends with an
|
|
351
|
+
explicit truncation marker. Normal startup creates no crash artifact or
|
|
352
|
+
append-style crash log. These files are local-only and are deliberately not
|
|
353
|
+
included in `diagnostics report`: goroutine stacks can contain absolute source
|
|
354
|
+
paths and other sensitive local data. Inspect and share them only as carefully
|
|
355
|
+
as any other local crash dump.
|
|
356
|
+
|
|
335
357
|
`PROJMUX_FOCUS_DEBUG` remains available with its existing one-line byte
|
|
336
358
|
contract. Focus diagnostics share its request classification seam, but do not
|
|
337
359
|
copy the debug line's raw target, session/window/pane, socket, client, source,
|
|
@@ -353,3 +375,106 @@ JSON schema version 2 and the bounded operations decoder are reused rather than
|
|
|
353
375
|
duplicated. AI ingest contributes count-only allowlisted source/result rows,
|
|
354
376
|
never raw legacy lines. Existing output files survive collisions and partial
|
|
355
377
|
temporary archives are removed.
|
|
378
|
+
|
|
379
|
+
## Install residue ledger
|
|
380
|
+
|
|
381
|
+
`make install` and `npm install` replace the executable on disk. Neither
|
|
382
|
+
replaces the image of a process that is already running, so every long-lived
|
|
383
|
+
projmux child — the Codex broker runtime, the lifecycle observers, the per-pane
|
|
384
|
+
supervisors — keeps executing the code it started with until it exits on its
|
|
385
|
+
own. The install reports success while most of the running fleet is still on
|
|
386
|
+
the previous build.
|
|
387
|
+
|
|
388
|
+
`projmux internal install-residue` is the census of exactly that. It is hidden
|
|
389
|
+
internal plumbing invoked by the installer, not a command to type: `make
|
|
390
|
+
install` runs it as its last step, and the npm bin wrapper runs it once on the
|
|
391
|
+
first interactive run after an install. It reads the process table, appends one
|
|
392
|
+
record, prints at most one notice, and always exits `0` — a diagnostic that can
|
|
393
|
+
fail the install it reports on is worse than no diagnostic.
|
|
394
|
+
|
|
395
|
+
The notice goes to **stderr** and is printed only when the census was taken and
|
|
396
|
+
found residual processes:
|
|
397
|
+
|
|
398
|
+
```
|
|
399
|
+
>> 24 projmux processes are still running the image this install replaced
|
|
400
|
+
supervisor 20 oldest 3h02m median 45m
|
|
401
|
+
lifecycle-observer 3 oldest 2h14m median 41m
|
|
402
|
+
broker-runtime 1 oldest 2h14m median 2h14m
|
|
403
|
+
They keep executing code from before this install until each one exits.
|
|
404
|
+
Recreating a pane moves that pane onto the installed build; the broker
|
|
405
|
+
follows when its last binding goes.
|
|
406
|
+
Recorded to ~/.local/state/projmux/install-residue.jsonl (17 installs, last 38m ago).
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
An install that reached the whole fleet prints nothing at all. A platform with
|
|
410
|
+
no readable process table (macOS, which has no `/proc/<pid>/exe`) also prints
|
|
411
|
+
nothing: the census cannot be taken there and the operator has no action
|
|
412
|
+
available, so a line at every install would be permanent noise. Both cases
|
|
413
|
+
still write a record.
|
|
414
|
+
|
|
415
|
+
### Ledger format
|
|
416
|
+
|
|
417
|
+
The path is `${XDG_STATE_HOME:-$HOME/.local/state}/projmux/install-residue.jsonl`,
|
|
418
|
+
resolved through the same `internal/config` layout as every other state file.
|
|
419
|
+
It is JSON Lines, appended one object per install, created `0600` in the
|
|
420
|
+
private state directory, and trimmed to approximately the newest 1000 records.
|
|
421
|
+
Every failure — an unresolvable state directory, an unwritable file — is
|
|
422
|
+
silent.
|
|
423
|
+
|
|
424
|
+
```json
|
|
425
|
+
{
|
|
426
|
+
"at": "2026-09-06T04:12:33Z",
|
|
427
|
+
"installer": "make",
|
|
428
|
+
"supported": true,
|
|
429
|
+
"observed": 41,
|
|
430
|
+
"replaced": 37,
|
|
431
|
+
"sinceLastInstallSeconds": 3612,
|
|
432
|
+
"roles": [
|
|
433
|
+
{"role":"supervisor","processes":22,"current":2,"replaced":20,
|
|
434
|
+
"replacedAgeSeconds":[610,1200,4300,8800]}
|
|
435
|
+
]
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
| field | meaning |
|
|
440
|
+
| --- | --- |
|
|
441
|
+
| `at` | when the census was taken, RFC3339 UTC |
|
|
442
|
+
| `installer` | the existing `PROJMUX_INSTALLER` value; `unknown` when unset |
|
|
443
|
+
| `supported` | whether this platform exposes a process table the census can be taken from |
|
|
444
|
+
| `observed` | projmux processes classified |
|
|
445
|
+
| `replaced` | how many of them run the image this install replaced |
|
|
446
|
+
| `sinceLastInstallSeconds` | gap to the previous record; absent on the first |
|
|
447
|
+
| `roles[].role` | `broker-runtime`, `lifecycle-observer`, `supervisor`, or `other` |
|
|
448
|
+
| `roles[].processes` / `current` / `replaced` | that role's census |
|
|
449
|
+
| `roles[].replacedAgeSeconds` | ascending age distribution of that role's residual processes, whole seconds |
|
|
450
|
+
| `roles[].replacedAgeCapped` | present when the 512-sample per-role bound was reached, so the distribution above is a prefix |
|
|
451
|
+
|
|
452
|
+
The record carries **no pid, no executable path, and no argv**, on the terminal
|
|
453
|
+
and in the file alike. Counts and durations are the whole of it; process
|
|
454
|
+
identity is exactly what the census is built not to record. A residual process
|
|
455
|
+
whose start time could not be read is still counted in `replaced` and
|
|
456
|
+
contributes no entry to `replacedAgeSeconds`, so that array can be shorter than
|
|
457
|
+
`replaced`.
|
|
458
|
+
|
|
459
|
+
Ages come from the modification time of `/proc/<pid>`, which the kernel stamps
|
|
460
|
+
at process creation and never moves. That is chosen over `/proc/<pid>/stat`
|
|
461
|
+
field 22 plus `/proc/stat` `btime` because it needs no `USER_HZ` assumption, no
|
|
462
|
+
boot-time read, and no parsing around the `comm` field, which is an executable
|
|
463
|
+
name in parentheses and may itself contain `)` and spaces.
|
|
464
|
+
|
|
465
|
+
### What the ledger is for
|
|
466
|
+
|
|
467
|
+
The ledger is the deliverable; the notice is a courtesy. An automatic
|
|
468
|
+
replacement of residual processes cannot be designed without a termination
|
|
469
|
+
condition for the drain, and these three fields are what such a condition is
|
|
470
|
+
derived from:
|
|
471
|
+
|
|
472
|
+
| field | the question it answers |
|
|
473
|
+
| --- | --- |
|
|
474
|
+
| `roles[].replaced` (per role) | what to make a replacement target |
|
|
475
|
+
| `roles[].replacedAgeSeconds` (the full sorted distribution, not a mean) | does a bounded drain finish in finite time, and what cutoff `T` covers which fraction |
|
|
476
|
+
| `at` + `sinceLastInstallSeconds` across records | how often this happens per install, hence whether a forced cutoff is needed at all |
|
|
477
|
+
|
|
478
|
+
A mean would destroy the second answer: twenty supervisors averaging forty
|
|
479
|
+
minutes says nothing about the one that outlives every plausible bound. That is
|
|
480
|
+
why the distribution is stored whole.
|
package/docs/pr-guideline.md
CHANGED
|
@@ -92,8 +92,9 @@ Notes:
|
|
|
92
92
|
`main` is governed by ruleset `main-protect`:
|
|
93
93
|
|
|
94
94
|
- Direct push to `main` is blocked. Even repository admin must use a PR.
|
|
95
|
-
- Required status
|
|
96
|
-
|
|
95
|
+
- Required status checks are the five CI job names `Format`, `Unit Tests`,
|
|
96
|
+
`NPM Packages`, `Integration Tests`, and `E2E Tests`. The aggregate `Test`
|
|
97
|
+
job is observed as the project-wide fan-in, but it is not ruleset-required.
|
|
97
98
|
- Admin bypass is `pull_request` mode — admin can self-merge without
|
|
98
99
|
approvals, but the PR itself is mandatory.
|
|
99
100
|
- Linear history is enforced. The merge methods exposed are
|