instar 1.3.370 → 1.3.372
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/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +139 -4
- package/dist/commands/server.js.map +1 -1
- package/dist/core/CommitmentMutation.d.ts +141 -0
- package/dist/core/CommitmentMutation.d.ts.map +1 -0
- package/dist/core/CommitmentMutation.js +326 -0
- package/dist/core/CommitmentMutation.js.map +1 -0
- package/dist/core/MeshRpc.d.ts +12 -0
- package/dist/core/MeshRpc.d.ts.map +1 -1
- package/dist/core/MeshRpc.js +9 -0
- package/dist/core/MeshRpc.js.map +1 -1
- package/dist/core/PoolActivityView.d.ts +87 -0
- package/dist/core/PoolActivityView.d.ts.map +1 -0
- package/dist/core/PoolActivityView.js +146 -0
- package/dist/core/PoolActivityView.js.map +1 -0
- package/dist/server/AgentServer.d.ts +8 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +1 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +10 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +135 -4
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +47 -47
- package/src/data/state-coherence-registry.json +24 -0
- package/upgrades/1.3.371.md +62 -0
- package/upgrades/1.3.372.md +37 -0
- package/upgrades/side-effects/commitment-mutation-p15b.md +70 -0
- package/upgrades/side-effects/pool-activity-view-p4.md +54 -0
- package/upgrades/side-effects/reflex-placement-fallback.md +57 -0
package/dist/server/routes.js
CHANGED
|
@@ -4997,12 +4997,40 @@ export function createRoutes(ctx) {
|
|
|
4997
4997
|
// Read-only cross-topic index: every topic with intent state + its current focus +
|
|
4998
4998
|
// high-specificity tags + whether a session is live on it. Signal-only; never gates.
|
|
4999
4999
|
// 503 when the index is unavailable (no stateDir / init failed).
|
|
5000
|
-
router.get('/parallel-work/activities', (
|
|
5000
|
+
router.get('/parallel-work/activities', async (req, res) => {
|
|
5001
5001
|
if (!ctx.parallelActivityIndex) {
|
|
5002
5002
|
res.status(503).json({ error: 'parallel-activity index unavailable (no stateDir or init failed)' });
|
|
5003
5003
|
return;
|
|
5004
5004
|
}
|
|
5005
5005
|
const activities = ctx.parallelActivityIndex.activities();
|
|
5006
|
+
// P4 (POOL-WIDE-PARALLEL-WORK-SPEC §3): ?scope=pool composes the local
|
|
5007
|
+
// rows with replica-derived remote rows (LOCAL replica files — no peer
|
|
5008
|
+
// fan-out; an offline peer's last-replicated streams still answer).
|
|
5009
|
+
// Default scope stays byte-identical; a dark replica layer degrades the
|
|
5010
|
+
// pool scope to local rows only (200, never a new 503).
|
|
5011
|
+
if (req.query.scope === 'pool') {
|
|
5012
|
+
try {
|
|
5013
|
+
const poolMod = await import('../core/PoolActivityView.js');
|
|
5014
|
+
const readerMod = await import('../core/CoherenceJournalReader.js');
|
|
5015
|
+
const view = poolMod.buildPoolActivityView({
|
|
5016
|
+
ownMachineId: ctx.meshSelfId ?? 'local',
|
|
5017
|
+
local: activities,
|
|
5018
|
+
reader: new readerMod.CoherenceJournalReader({ stateDir: ctx.config.stateDir }),
|
|
5019
|
+
});
|
|
5020
|
+
res.json({
|
|
5021
|
+
scope: 'pool',
|
|
5022
|
+
count: view.rows.length,
|
|
5023
|
+
runningCount: view.rows.filter((a) => a.running).length,
|
|
5024
|
+
activities: view.rows,
|
|
5025
|
+
pool: view.pool,
|
|
5026
|
+
});
|
|
5027
|
+
return;
|
|
5028
|
+
}
|
|
5029
|
+
catch (err) {
|
|
5030
|
+
res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
|
|
5031
|
+
return;
|
|
5032
|
+
}
|
|
5033
|
+
}
|
|
5006
5034
|
res.json({
|
|
5007
5035
|
count: activities.length,
|
|
5008
5036
|
runningCount: activities.filter((a) => a.running).length,
|
|
@@ -13965,6 +13993,19 @@ export function createRoutes(ctx) {
|
|
|
13965
13993
|
res.status(404).json({ error: 'CommitmentTracker not configured' });
|
|
13966
13994
|
return;
|
|
13967
13995
|
}
|
|
13996
|
+
// P1.5b §3.4 owner-routing (replica-targeted beacon-field PATCH forwards).
|
|
13997
|
+
{
|
|
13998
|
+
const pOrigin = typeof req.query.origin === 'string' ? req.query.origin : undefined;
|
|
13999
|
+
const pRoute = await resolveCommitmentRoute(req.params.id, pOrigin);
|
|
14000
|
+
if (pRoute === 'ambiguous') {
|
|
14001
|
+
res.status(409).json({ error: `Commitment id ${req.params.id} is ambiguous across machines — retry with ?origin=<machineId>` });
|
|
14002
|
+
return;
|
|
14003
|
+
}
|
|
14004
|
+
if (typeof pRoute === 'object') {
|
|
14005
|
+
await forwardMutation(res, pRoute.forward.owner, mutatePayload(req, pRoute.forward.owner, 'patch-beacon', req.body ?? {}));
|
|
14006
|
+
return;
|
|
14007
|
+
}
|
|
14008
|
+
}
|
|
13968
14009
|
const existing = ctx.commitmentTracker.get(req.params.id);
|
|
13969
14010
|
if (!existing) {
|
|
13970
14011
|
res.status(404).json({ error: `Commitment ${req.params.id} not found` });
|
|
@@ -14071,11 +14112,79 @@ export function createRoutes(ctx) {
|
|
|
14071
14112
|
* came back with the promised update," separate from `verified` which means
|
|
14072
14113
|
* "config state is as promised."
|
|
14073
14114
|
*/
|
|
14074
|
-
|
|
14115
|
+
/**
|
|
14116
|
+
* P1.5b §3.4 — owner-routing decision for a mutation route. Returns:
|
|
14117
|
+
* 'local' → the record is OWN (or the layer is dark): mutate locally.
|
|
14118
|
+
* {forward} → the record lives ONLY in a replica: forward to its owner.
|
|
14119
|
+
* 'ambiguous' → a bare id matches own AND replica rows (409, §3.1).
|
|
14120
|
+
* 'absent' → nowhere in the merged view (404 falls through to local).
|
|
14121
|
+
*/
|
|
14122
|
+
async function resolveCommitmentRoute(id, origin) {
|
|
14123
|
+
if (!ctx.commitmentReplicaStore || !ctx.commitmentTracker)
|
|
14124
|
+
return 'local';
|
|
14125
|
+
const syncMod = await import('../core/CommitmentsSync.js');
|
|
14126
|
+
const rows = syncMod.mergeCommitmentViews({
|
|
14127
|
+
ownMachineId: ctx.meshSelfId ?? 'local',
|
|
14128
|
+
own: ctx.commitmentTracker.getAll(),
|
|
14129
|
+
replicas: ctx.commitmentReplicaStore.allReplicas(),
|
|
14130
|
+
});
|
|
14131
|
+
const resolved = syncMod.resolveBareId(rows, id, origin);
|
|
14132
|
+
if (resolved === 'ambiguous')
|
|
14133
|
+
return 'ambiguous';
|
|
14134
|
+
if (resolved === null)
|
|
14135
|
+
return 'absent';
|
|
14136
|
+
if (resolved.viewSource === 'own')
|
|
14137
|
+
return 'local';
|
|
14138
|
+
return { forward: { owner: resolved.originMachineId } };
|
|
14139
|
+
}
|
|
14140
|
+
/** Shared forward path: verdict → mapped response; queued → honest 202. */
|
|
14141
|
+
async function forwardMutation(res, owner, payload) {
|
|
14142
|
+
if (!ctx.forwardCommitmentMutate) {
|
|
14143
|
+
res.status(409).json({
|
|
14144
|
+
error: `Commitment ${payload.id} lives on ${owner} and cross-machine mutation is not enabled here`,
|
|
14145
|
+
});
|
|
14146
|
+
return;
|
|
14147
|
+
}
|
|
14148
|
+
const r = await ctx.forwardCommitmentMutate(owner, payload);
|
|
14149
|
+
if (r.kind === 'queued') {
|
|
14150
|
+
res.status(202).json({ queued: true, owner, reason: r.reason, opKey: payload.opKey });
|
|
14151
|
+
return;
|
|
14152
|
+
}
|
|
14153
|
+
const v = r.outcome;
|
|
14154
|
+
if (v.verdict === 'applied' || v.verdict === 'idempotent-noop') {
|
|
14155
|
+
res.json({ delivered: payload.op === 'deliver' ? true : undefined, op: payload.op, id: payload.id, owner, verdict: v.verdict, status: v.status, ...(v.staleObservation ? { staleObservation: true } : {}) });
|
|
14156
|
+
return;
|
|
14157
|
+
}
|
|
14158
|
+
res.status(v.verdict === 'not-found' ? 404 : 409).json({ error: `owner verdict: ${v.verdict}`, owner, status: v.status });
|
|
14159
|
+
}
|
|
14160
|
+
function mutatePayload(req, origin, op, args) {
|
|
14161
|
+
return {
|
|
14162
|
+
origin,
|
|
14163
|
+
id: req.params.id,
|
|
14164
|
+
op,
|
|
14165
|
+
...(args ? { args } : {}),
|
|
14166
|
+
opKey: randomUUID(),
|
|
14167
|
+
requestedAt: new Date().toISOString(),
|
|
14168
|
+
callerMachineId: ctx.meshSelfId ?? 'local',
|
|
14169
|
+
...(typeof req.query.observedStatus === 'string' ? { observedStatus: req.query.observedStatus } : {}),
|
|
14170
|
+
};
|
|
14171
|
+
}
|
|
14172
|
+
router.post('/commitments/:id/deliver', async (req, res) => {
|
|
14075
14173
|
if (!ctx.commitmentTracker) {
|
|
14076
14174
|
res.status(404).json({ error: 'CommitmentTracker not configured' });
|
|
14077
14175
|
return;
|
|
14078
14176
|
}
|
|
14177
|
+
const origin = typeof req.query.origin === 'string' ? req.query.origin : undefined;
|
|
14178
|
+
const route = await resolveCommitmentRoute(req.params.id, origin);
|
|
14179
|
+
if (route === 'ambiguous') {
|
|
14180
|
+
res.status(409).json({ error: `Commitment id ${req.params.id} is ambiguous across machines — retry with ?origin=<machineId>` });
|
|
14181
|
+
return;
|
|
14182
|
+
}
|
|
14183
|
+
if (typeof route === 'object') {
|
|
14184
|
+
const { deliveryMessageId } = req.body ?? {};
|
|
14185
|
+
await forwardMutation(res, route.forward.owner, mutatePayload(req, route.forward.owner, 'deliver', deliveryMessageId ? { deliveryMessageId } : undefined));
|
|
14186
|
+
return;
|
|
14187
|
+
}
|
|
14079
14188
|
const { deliveryMessageId } = req.body ?? {};
|
|
14080
14189
|
const updated = ctx.commitmentTracker.deliver(req.params.id, deliveryMessageId);
|
|
14081
14190
|
if (!updated) {
|
|
@@ -14084,7 +14193,7 @@ export function createRoutes(ctx) {
|
|
|
14084
14193
|
}
|
|
14085
14194
|
res.json({ delivered: true, id: updated.id, commitment: updated });
|
|
14086
14195
|
});
|
|
14087
|
-
router.post('/commitments/:id/withdraw', (req, res) => {
|
|
14196
|
+
router.post('/commitments/:id/withdraw', async (req, res) => {
|
|
14088
14197
|
if (!ctx.commitmentTracker) {
|
|
14089
14198
|
res.status(404).json({ error: 'CommitmentTracker not configured' });
|
|
14090
14199
|
return;
|
|
@@ -14094,6 +14203,17 @@ export function createRoutes(ctx) {
|
|
|
14094
14203
|
res.status(400).json({ error: 'reason is required' });
|
|
14095
14204
|
return;
|
|
14096
14205
|
}
|
|
14206
|
+
// P1.5b §3.4 owner-routing (replica-targeted withdraw forwards).
|
|
14207
|
+
const wOrigin = typeof req.query.origin === 'string' ? req.query.origin : undefined;
|
|
14208
|
+
const wRoute = await resolveCommitmentRoute(req.params.id, wOrigin);
|
|
14209
|
+
if (wRoute === 'ambiguous') {
|
|
14210
|
+
res.status(409).json({ error: `Commitment id ${req.params.id} is ambiguous across machines — retry with ?origin=<machineId>` });
|
|
14211
|
+
return;
|
|
14212
|
+
}
|
|
14213
|
+
if (typeof wRoute === 'object') {
|
|
14214
|
+
await forwardMutation(res, wRoute.forward.owner, mutatePayload(req, wRoute.forward.owner, 'withdraw', { reason }));
|
|
14215
|
+
return;
|
|
14216
|
+
}
|
|
14097
14217
|
const success = ctx.commitmentTracker.withdraw(req.params.id, reason);
|
|
14098
14218
|
if (!success) {
|
|
14099
14219
|
res.status(404).json({ error: `Commitment ${req.params.id} not found or already resolved` });
|
|
@@ -14109,11 +14229,22 @@ export function createRoutes(ctx) {
|
|
|
14109
14229
|
* event. No-op (404) for commitments that aren't paused or are in a terminal
|
|
14110
14230
|
* status.
|
|
14111
14231
|
*/
|
|
14112
|
-
router.post('/commitments/:id/resume', (req, res) => {
|
|
14232
|
+
router.post('/commitments/:id/resume', async (req, res) => {
|
|
14113
14233
|
if (!ctx.commitmentTracker) {
|
|
14114
14234
|
res.status(404).json({ error: 'CommitmentTracker not configured' });
|
|
14115
14235
|
return;
|
|
14116
14236
|
}
|
|
14237
|
+
// P1.5b §3.4 owner-routing (replica-targeted resume forwards).
|
|
14238
|
+
const rOrigin = typeof req.query.origin === 'string' ? req.query.origin : undefined;
|
|
14239
|
+
const rRoute = await resolveCommitmentRoute(req.params.id, rOrigin);
|
|
14240
|
+
if (rRoute === 'ambiguous') {
|
|
14241
|
+
res.status(409).json({ error: `Commitment id ${req.params.id} is ambiguous across machines — retry with ?origin=<machineId>` });
|
|
14242
|
+
return;
|
|
14243
|
+
}
|
|
14244
|
+
if (typeof rRoute === 'object') {
|
|
14245
|
+
await forwardMutation(res, rRoute.forward.owner, mutatePayload(req, rRoute.forward.owner, 'resume'));
|
|
14246
|
+
return;
|
|
14247
|
+
}
|
|
14117
14248
|
const updated = ctx.commitmentTracker.resume(req.params.id);
|
|
14118
14249
|
if (!updated) {
|
|
14119
14250
|
res.status(404).json({ error: `Commitment ${req.params.id} not found, not paused, or in terminal status` });
|