@junghanacs/entwurf 0.12.8 → 0.12.9
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/AGENTS.md +4 -4
- package/CHANGELOG.md +20 -1
- package/DELIVERY.md +1 -1
- package/README.md +122 -10
- package/demo/README.md +2 -2
- package/docs/setup-clean-host.md +14 -3
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +9 -15
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +12 -12
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-fact-provider.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +5 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn-production.js +8 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +15 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +483 -34
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-hook.js +8 -3
- package/mcp/entwurf-bridge/dist/scripts/agy-imprint.js +14 -2
- package/mcp/entwurf-bridge/dist/scripts/meta-bridge-fresh-cut.js +155 -29
- package/mcp/entwurf-bridge/src/index.ts +10 -12
- package/package.json +7 -7
- package/pi-extensions/entwurf-control.ts +12 -12
- package/pi-extensions/lib/acp/models.ts +12 -12
- package/pi-extensions/lib/entwurf-fact-provider.ts +9 -2
- package/pi-extensions/lib/entwurf-v2-production.ts +8 -2
- package/pi-extensions/lib/entwurf-v2-spawn-production.ts +8 -2
- package/pi-extensions/lib/meta-sender-identity.ts +15 -5
- package/pi-extensions/lib/meta-session.ts +526 -38
- package/pi-extensions/meta-bridge-hook.ts +8 -2
- package/run.sh +30 -26
- package/scripts/agy-imprint.ts +15 -1
- package/scripts/check-acp-session-reuse.ts +1 -1
- package/scripts/check-acp-session-store.ts +3 -3
- package/scripts/check-agy-sender-identity.ts +83 -0
- package/scripts/check-entwurf-control-rpc.ts +2 -2
- package/scripts/check-entwurf-fact-provider.ts +9 -1
- package/scripts/check-entwurf-facts.ts +1 -1
- package/scripts/check-entwurf-mailbox-guard.ts +6 -2
- package/scripts/check-entwurf-resume-args.ts +6 -6
- package/scripts/check-entwurf-session-identity.ts +7 -6
- package/scripts/check-entwurf-v2-production.ts +4 -2
- package/scripts/check-entwurf-v2-spawn-production.ts +2 -2
- package/scripts/check-fresh-cut-gate.sh +305 -4
- package/scripts/check-meta-identity-consumers.ts +501 -1
- package/scripts/check-meta-listing.ts +91 -9
- package/scripts/check-meta-receiver-marker.ts +54 -0
- package/scripts/check-model-lock.ts +1 -1
- package/scripts/meta-bridge-fresh-cut.ts +164 -28
- package/scripts/pi_settings_io.py +65 -0
- package/scripts/register-pi-package.py +183 -37
- package/scripts/register-pi-provider.py +68 -10
- package/scripts/smoke-acp-socket-citizen-live.ts +2 -2
- package/scripts/smoke-meta-install-state.sh +1 -1
- package/scripts/smoke-pi-attach.ts +7 -2
- package/scripts/smoke-user-scope-citizen.sh +177 -0
|
@@ -35,7 +35,7 @@ import { buildResumePiArgs } from "./entwurf-resume-args.ts";
|
|
|
35
35
|
import type { LockClaim } from "./entwurf-v2-lock.ts";
|
|
36
36
|
import { releaseLock } from "./entwurf-v2-lock.ts";
|
|
37
37
|
import type { SpawnBgPlan, SpawnBgResumeDeps, SpawnedChild } from "./entwurf-v2-spawn.ts";
|
|
38
|
-
import {
|
|
38
|
+
import { readAddressableMetaIdentity } from "./meta-session.ts";
|
|
39
39
|
import { inspectControlSocketPath, type LstatLike, mapInspectionToLiveness } from "./socket-discovery.ts";
|
|
40
40
|
import { probeSocketLiveness, type SocketLiveness } from "./socket-probe.ts";
|
|
41
41
|
|
|
@@ -120,13 +120,19 @@ export interface LaunchIdentity {
|
|
|
120
120
|
* record remembers whose it is — a mismatch means the transcriptPath is stale or
|
|
121
121
|
* foreign, and resuming it would put a turn into a different being's session).
|
|
122
122
|
*
|
|
123
|
+
* That check is per-record, and per-record is not enough: the v2 lock domain is keyed on
|
|
124
|
+
* GARDEN ID, so two records sharing one `nativeSessionId` would each pass their own
|
|
125
|
+
* integrity check and resume the SAME transcript concurrently under two different locks.
|
|
126
|
+
* Hence {@link readAddressableMetaIdentity} rather than the plain targeted read (#52) —
|
|
127
|
+
* a resume is exactly the moment a record stops being data and becomes an address.
|
|
128
|
+
*
|
|
123
129
|
* Everything else is unchanged authority: readSessionIdentity (first model_change) for
|
|
124
130
|
* provider/model/cwd, getEntwurfExplicitExtensions for bridge re-injection (#29 fail-fast).
|
|
125
131
|
* Throws on anything that makes a resume impossible; each throw becomes the watcher's
|
|
126
132
|
* `spawn-start-failed` (no child to watch → release), never a silent no-op.
|
|
127
133
|
*/
|
|
128
134
|
export function resolveResumeLaunchIdentity(plan: SpawnBgPlan): LaunchIdentity {
|
|
129
|
-
const record =
|
|
135
|
+
const record = readAddressableMetaIdentity(plan.sessionId);
|
|
130
136
|
if (record.backend !== "pi") {
|
|
131
137
|
throw new Error(
|
|
132
138
|
`entwurf-v2-spawn-production: ${plan.sessionId} is a ${record.backend} citizen — spawn-bg resume is the pi rail.`,
|
|
@@ -16,8 +16,13 @@
|
|
|
16
16
|
* remains compatibility for an MCP host wrapper; the hook never writes a blind grandparent
|
|
17
17
|
* marker because that may be the long-lived login shell.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* Three guards make a marker an IDENTITY rather than a hint, and a candidate is only trusted
|
|
20
|
+
* after ALL of them pass:
|
|
21
|
+
* 0. a PLAUSIBLE owner (isPlausibleOwnerPid, shared with both writers and the generation cut):
|
|
22
|
+
* pid <= 1 cannot own a session, and guard 1 cannot catch it — for as long as the host
|
|
23
|
+
* is up, init IS still the very process the marker named. This is a rule about the
|
|
24
|
+
* marker's CLAIM, not about the owner's state, which is why it is asked first and is
|
|
25
|
+
* not opt-out (#53 A).
|
|
21
26
|
* 1. pid + start-key (readMetaSenderMarker): the owner is still the very process that wrote it,
|
|
22
27
|
* so a dead session's pid, reused by something else, cannot inherit its garden-id.
|
|
23
28
|
* 2. the backing meta-record: the record store is the authority — a marker whose record was
|
|
@@ -32,6 +37,7 @@
|
|
|
32
37
|
*/
|
|
33
38
|
|
|
34
39
|
import {
|
|
40
|
+
isPlausibleOwnerPid,
|
|
35
41
|
type MetaBackend,
|
|
36
42
|
type MetaIdentity,
|
|
37
43
|
type MetaSenderMarker,
|
|
@@ -148,9 +154,13 @@ export function resolveTrustedMetaSenderIdentity(opts: ResolveTrustedMetaSenderO
|
|
|
148
154
|
const marker = readMetaSenderMarker({ markerPath: opts.markerPath });
|
|
149
155
|
if (marker) markers.push(marker);
|
|
150
156
|
} else {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
// The candidate filter asks the same question the marker readers ask — CAN this
|
|
158
|
+
// pid own a session — so it uses the same predicate rather than a second `> 0`
|
|
159
|
+
// literal. The default set is only the bridge's parent and grandparent, so init
|
|
160
|
+
// enters it just when the native host itself was reparented (a detached/daemonized
|
|
161
|
+
// Claude): narrow, but reachable, and a candidate that cannot be an owner has no
|
|
162
|
+
// business reaching the read at all (#53 A).
|
|
163
|
+
const ownerPids = (opts.ownerPids ?? [process.ppid, parentPid(process.ppid) ?? 0]).filter(isPlausibleOwnerPid);
|
|
154
164
|
for (const ownerPid of [...new Set(ownerPids)]) {
|
|
155
165
|
for (const backend of META_SENDER_BACKENDS) {
|
|
156
166
|
const marker = readMetaSenderMarker({ backend, ownerPid, sendersDir: opts.sendersDir });
|