instar 1.3.371 → 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 +108 -3
- 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/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 +106 -3
- 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.372.md +37 -0
- package/upgrades/side-effects/commitment-mutation-p15b.md +70 -0
package/dist/server/routes.js
CHANGED
|
@@ -13993,6 +13993,19 @@ export function createRoutes(ctx) {
|
|
|
13993
13993
|
res.status(404).json({ error: 'CommitmentTracker not configured' });
|
|
13994
13994
|
return;
|
|
13995
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
|
+
}
|
|
13996
14009
|
const existing = ctx.commitmentTracker.get(req.params.id);
|
|
13997
14010
|
if (!existing) {
|
|
13998
14011
|
res.status(404).json({ error: `Commitment ${req.params.id} not found` });
|
|
@@ -14099,11 +14112,79 @@ export function createRoutes(ctx) {
|
|
|
14099
14112
|
* came back with the promised update," separate from `verified` which means
|
|
14100
14113
|
* "config state is as promised."
|
|
14101
14114
|
*/
|
|
14102
|
-
|
|
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) => {
|
|
14103
14173
|
if (!ctx.commitmentTracker) {
|
|
14104
14174
|
res.status(404).json({ error: 'CommitmentTracker not configured' });
|
|
14105
14175
|
return;
|
|
14106
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
|
+
}
|
|
14107
14188
|
const { deliveryMessageId } = req.body ?? {};
|
|
14108
14189
|
const updated = ctx.commitmentTracker.deliver(req.params.id, deliveryMessageId);
|
|
14109
14190
|
if (!updated) {
|
|
@@ -14112,7 +14193,7 @@ export function createRoutes(ctx) {
|
|
|
14112
14193
|
}
|
|
14113
14194
|
res.json({ delivered: true, id: updated.id, commitment: updated });
|
|
14114
14195
|
});
|
|
14115
|
-
router.post('/commitments/:id/withdraw', (req, res) => {
|
|
14196
|
+
router.post('/commitments/:id/withdraw', async (req, res) => {
|
|
14116
14197
|
if (!ctx.commitmentTracker) {
|
|
14117
14198
|
res.status(404).json({ error: 'CommitmentTracker not configured' });
|
|
14118
14199
|
return;
|
|
@@ -14122,6 +14203,17 @@ export function createRoutes(ctx) {
|
|
|
14122
14203
|
res.status(400).json({ error: 'reason is required' });
|
|
14123
14204
|
return;
|
|
14124
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
|
+
}
|
|
14125
14217
|
const success = ctx.commitmentTracker.withdraw(req.params.id, reason);
|
|
14126
14218
|
if (!success) {
|
|
14127
14219
|
res.status(404).json({ error: `Commitment ${req.params.id} not found or already resolved` });
|
|
@@ -14137,11 +14229,22 @@ export function createRoutes(ctx) {
|
|
|
14137
14229
|
* event. No-op (404) for commitments that aren't paused or are in a terminal
|
|
14138
14230
|
* status.
|
|
14139
14231
|
*/
|
|
14140
|
-
router.post('/commitments/:id/resume', (req, res) => {
|
|
14232
|
+
router.post('/commitments/:id/resume', async (req, res) => {
|
|
14141
14233
|
if (!ctx.commitmentTracker) {
|
|
14142
14234
|
res.status(404).json({ error: 'CommitmentTracker not configured' });
|
|
14143
14235
|
return;
|
|
14144
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
|
+
}
|
|
14145
14248
|
const updated = ctx.commitmentTracker.resume(req.params.id);
|
|
14146
14249
|
if (!updated) {
|
|
14147
14250
|
res.status(404).json({ error: `Commitment ${req.params.id} not found, not paused, or in terminal status` });
|