@tacuchi/agent-workflow-cli 20.26.0 → 21.1.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.md +2 -1
- package/dist/adapters/node-file-system.js +3 -0
- package/dist/adapters/node-file-system.js.map +1 -1
- package/dist/application/capability/compose.js +161 -0
- package/dist/application/capability/compose.js.map +1 -0
- package/dist/application/capability/descriptor-loader.js +109 -0
- package/dist/application/capability/descriptor-loader.js.map +1 -0
- package/dist/application/capability/design-handler.js +299 -0
- package/dist/application/capability/design-handler.js.map +1 -0
- package/dist/application/capability/dispatcher.js +312 -0
- package/dist/application/capability/dispatcher.js.map +1 -0
- package/dist/application/capability/durable-effect.js +220 -0
- package/dist/application/capability/durable-effect.js.map +1 -0
- package/dist/application/capability/installed-inventory.js +168 -0
- package/dist/application/capability/installed-inventory.js.map +1 -0
- package/dist/application/capability/readiness.js +204 -0
- package/dist/application/capability/readiness.js.map +1 -0
- package/dist/application/capability/resolution.js +264 -0
- package/dist/application/capability/resolution.js.map +1 -0
- package/dist/application/capability/wrapper.js +187 -0
- package/dist/application/capability/wrapper.js.map +1 -0
- package/dist/application/context/manifest.js +11 -5
- package/dist/application/context/manifest.js.map +1 -1
- package/dist/application/context/measure.js +5 -2
- package/dist/application/context/measure.js.map +1 -1
- package/dist/application/context/plan-service.js +6 -6
- package/dist/application/context/plan-service.js.map +1 -1
- package/dist/application/design/design-bundle-service.js +148 -0
- package/dist/application/design/design-bundle-service.js.map +1 -0
- package/dist/application/design/design-gate-service.js +246 -0
- package/dist/application/design/design-gate-service.js.map +1 -0
- package/dist/application/design/design-graph-service.js +85 -0
- package/dist/application/design/design-graph-service.js.map +1 -0
- package/dist/application/design/design-index-service.js +132 -0
- package/dist/application/design/design-index-service.js.map +1 -0
- package/dist/application/design/design-proposal-service.js +69 -0
- package/dist/application/design/design-proposal-service.js.map +1 -0
- package/dist/application/design/design-publish-service.js +756 -0
- package/dist/application/design/design-publish-service.js.map +1 -0
- package/dist/application/design/design-record-service.js +100 -0
- package/dist/application/design/design-record-service.js.map +1 -0
- package/dist/application/design/design-resolver-service.js +165 -0
- package/dist/application/design/design-resolver-service.js.map +1 -0
- package/dist/application/flow/advance.js +533 -0
- package/dist/application/flow/advance.js.map +1 -0
- package/dist/application/flow/flow-service.js +65 -0
- package/dist/application/flow/flow-service.js.map +1 -0
- package/dist/application/flow/run-projection.js +80 -0
- package/dist/application/flow/run-projection.js.map +1 -0
- package/dist/application/flow/run-state-service.js +107 -0
- package/dist/application/flow/run-state-service.js.map +1 -0
- package/dist/application/flow/submit.js +423 -0
- package/dist/application/flow/submit.js.map +1 -0
- package/dist/application/resume-service.js +46 -14
- package/dist/application/resume-service.js.map +1 -1
- package/dist/application/self/install-skill.js +11 -0
- package/dist/application/self/install-skill.js.map +1 -1
- package/dist/application/self/uninstall.js +21 -0
- package/dist/application/self/uninstall.js.map +1 -1
- package/dist/application/semantic-operation/protocol.js +18 -12
- package/dist/application/semantic-operation/protocol.js.map +1 -1
- package/dist/application/semantic-operation/publish.js +56 -9
- package/dist/application/semantic-operation/publish.js.map +1 -1
- package/dist/application/skills-resolver-service.js +27 -6
- package/dist/application/skills-resolver-service.js.map +1 -1
- package/dist/application/status-service.js +5 -1
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/workline-index-service.js +6 -0
- package/dist/application/workline-index-service.js.map +1 -1
- package/dist/application/workspace-init-service.js +22 -2
- package/dist/application/workspace-init-service.js.map +1 -1
- package/dist/cli/commands/capability.js +182 -0
- package/dist/cli/commands/capability.js.map +1 -0
- package/dist/cli/commands/designs.js +110 -0
- package/dist/cli/commands/designs.js.map +1 -0
- package/dist/cli/commands/flow.js +71 -0
- package/dist/cli/commands/flow.js.map +1 -0
- package/dist/cli/commands/index.js +6 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/resume.js +8 -0
- package/dist/cli/commands/resume.js.map +1 -1
- package/dist/cli/commands/skills.js +55 -2
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/status.js +50 -0
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/help-groups.js +9 -0
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/cli/parser.js +7 -0
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/tui/data/workflow-content.js +5 -0
- package/dist/cli/tui/data/workflow-content.js.map +1 -1
- package/dist/cli/tui/tabs/workflow-tab.js +5 -1
- package/dist/cli/tui/tabs/workflow-tab.js.map +1 -1
- package/dist/domain/capability/descriptor.js +553 -0
- package/dist/domain/capability/descriptor.js.map +1 -0
- package/dist/domain/capability/effects.js +90 -0
- package/dist/domain/capability/effects.js.map +1 -0
- package/dist/domain/capability/protocol.js +494 -0
- package/dist/domain/capability/protocol.js.map +1 -0
- package/dist/domain/contract-reader.js +84 -0
- package/dist/domain/contract-reader.js.map +1 -0
- package/dist/domain/design/adapter.js +161 -0
- package/dist/domain/design/adapter.js.map +1 -0
- package/dist/domain/design/artifact-body.js +223 -0
- package/dist/domain/design/artifact-body.js.map +1 -0
- package/dist/domain/design/artifact.js +750 -0
- package/dist/domain/design/artifact.js.map +1 -0
- package/dist/domain/design/baseline.js +359 -0
- package/dist/domain/design/baseline.js.map +1 -0
- package/dist/domain/design/capability.js +310 -0
- package/dist/domain/design/capability.js.map +1 -0
- package/dist/domain/design/closure.js +161 -0
- package/dist/domain/design/closure.js.map +1 -0
- package/dist/domain/design/direct.js +108 -0
- package/dist/domain/design/direct.js.map +1 -0
- package/dist/domain/design/external-send.js +65 -0
- package/dist/domain/design/external-send.js.map +1 -0
- package/dist/domain/design/governance.js +298 -0
- package/dist/domain/design/governance.js.map +1 -0
- package/dist/domain/design/identity.js +145 -0
- package/dist/domain/design/identity.js.map +1 -0
- package/dist/domain/design/manifest.js +552 -0
- package/dist/domain/design/manifest.js.map +1 -0
- package/dist/domain/design/maturity.js +305 -0
- package/dist/domain/design/maturity.js.map +1 -0
- package/dist/domain/design/naming.js +117 -0
- package/dist/domain/design/naming.js.map +1 -0
- package/dist/domain/design/offline.js +92 -0
- package/dist/domain/design/offline.js.map +1 -0
- package/dist/domain/design/profiles.js +212 -0
- package/dist/domain/design/profiles.js.map +1 -0
- package/dist/domain/design/projections.js +165 -0
- package/dist/domain/design/projections.js.map +1 -0
- package/dist/domain/design/proposal.js +234 -0
- package/dist/domain/design/proposal.js.map +1 -0
- package/dist/domain/design/reference.js +234 -0
- package/dist/domain/design/reference.js.map +1 -0
- package/dist/domain/design/render-bundle.js +0 -0
- package/dist/domain/design/render-bundle.js.map +1 -0
- package/dist/domain/design/rendition.js +472 -0
- package/dist/domain/design/rendition.js.map +1 -0
- package/dist/domain/design/retired.js +61 -0
- package/dist/domain/design/retired.js.map +1 -0
- package/dist/domain/design/revision.js +219 -0
- package/dist/domain/design/revision.js.map +1 -0
- package/dist/domain/design/secrets.js +86 -0
- package/dist/domain/design/secrets.js.map +1 -0
- package/dist/domain/design/sources.js +180 -0
- package/dist/domain/design/sources.js.map +1 -0
- package/dist/domain/design/validation.js +19 -0
- package/dist/domain/design/validation.js.map +1 -0
- package/dist/domain/design/visual-evidence.js +155 -0
- package/dist/domain/design/visual-evidence.js.map +1 -0
- package/dist/domain/design/yaml-subset.js +390 -0
- package/dist/domain/design/yaml-subset.js.map +1 -0
- package/dist/domain/flow/answer.js +459 -0
- package/dist/domain/flow/answer.js.map +1 -0
- package/dist/domain/flow/authority.js +2276 -0
- package/dist/domain/flow/authority.js.map +1 -0
- package/dist/domain/flow/authorization.js +62 -0
- package/dist/domain/flow/authorization.js.map +1 -0
- package/dist/domain/flow/directive.js +421 -0
- package/dist/domain/flow/directive.js.map +1 -0
- package/dist/domain/flow/rules.js +140 -0
- package/dist/domain/flow/rules.js.map +1 -0
- package/dist/domain/flow/run-state.js +317 -0
- package/dist/domain/flow/run-state.js.map +1 -0
- package/dist/domain/harnesses.js +21 -0
- package/dist/domain/harnesses.js.map +1 -1
- package/dist/domain/safe-path.js +23 -0
- package/dist/domain/safe-path.js.map +1 -0
- package/dist/domain/skills.js +26 -3
- package/dist/domain/skills.js.map +1 -1
- package/package.json +1 -1
- package/skills/w/SKILL.md +15 -13
- package/skills/w/artifacts/README.md +3 -4
- package/skills/w/artifacts/artifacts-core/CHECKPOINT.md +2 -2
- package/skills/w/commands/plan-exec.md +11 -5
- package/skills/w/commands/plan-new.md +6 -2
- package/skills/w/commands/plan-refine.md +6 -3
- package/skills/w/commands/quick.md +2 -2
- package/skills/w/commands/spec-new.md +2 -2
- package/skills/w/commands/spec-refine.md +1 -0
- package/skills/w/context/MANIFEST.json +57 -9
- package/skills/w/harness/HARNESS.md +20 -0
- package/skills/w/loops/CHASSIS.md +11 -20
- package/skills/w/loops/CODE-POLICIES.md +18 -9
- package/skills/w/loops/README.md +1 -1
- package/skills/w/loops/plan-exec-loop/LOOP.md +126 -62
- package/skills/w/loops/plan-new-loop/LOOP.md +71 -73
- package/skills/w/loops/plan-refine-loop/LOOP.md +20 -10
- package/skills/w/loops/quick-loop/LOOP.md +18 -26
- package/skills/w/loops/spec-refine-loop/LOOP.md +28 -30
- package/skills/w/modules/COMPACTION.md +2 -6
- package/skills/w/modules/DB-SCRIPTS-ONLY.md +2 -0
- package/skills/w/modules/DESIGN-REFERENCES.md +113 -0
- package/skills/w/modules/IDEATION-GATE.md +3 -3
- package/skills/w/modules/PERSIST-ROUTING.md +1 -0
- package/skills/w/modules/PLAN-EXECUTION-BATCHES.md +65 -0
- package/skills/w/modules/PLAN-INPUT.md +5 -3
- package/skills/w/modules/PLAN-REFINE-SPLIT.md +3 -1
- package/skills/w/modules/PLAN-SPLIT-GATE.md +7 -5
- package/skills/w/modules/PROMPT-CONTINUITY.md +3 -1
- package/skills/w/modules/SPEC-CHANGE-SHAPE.md +4 -4
- package/skills/w/roles/README.md +9 -5
- package/skills/w/roles/design/CONTRACT.md +80 -0
- package/skills/w/roles/design/ROLE.md +224 -0
- package/skills/w/schemas/capability-descriptor.schema.json +260 -0
- package/skills/w/schemas/design/design-baseline.v1.schema.json +71 -0
- package/skills/w/schemas/design/design-manifest.v1.schema.json +322 -0
- package/skills/w/schemas/design/design-render-bundle.v1.schema.json +191 -0
- package/skills/w/schemas/design/design-rendition.v1.schema.json +232 -0
- package/skills/w/schemas/design/design-review.v1.schema.json +72 -0
- package/skills/w/schemas/design/design-revocation.v1.schema.json +54 -0
- package/skills/w/schemas/design/ui-flow.v1.schema.json +211 -0
- package/skills/w/schemas/design/ui-screen.v1.schema.json +242 -0
- package/skills/w/artifacts/artifacts-design/SPEC.md +0 -42
- package/skills/w/modules/PLAN-DESIGN-SPECS.md +0 -12
- package/skills/w/modules/PLAN-REFINE-DESIGN-SPECS.md +0 -7
- package/skills/w/roles/ui-spec/ROLE.md +0 -147
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a stopped run looks like from OUTSIDE the conversation that stopped it.
|
|
3
|
+
*
|
|
4
|
+
* `resume` and `status` both answer "what is left and how does it continue", and
|
|
5
|
+
* a run standing at a boundary is the most precise answer either of them can
|
|
6
|
+
* give. They read it from HERE, once: two surfaces deriving "what is next" on
|
|
7
|
+
* their own would be the second authority this whole initiative exists to remove
|
|
8
|
+
* — and the one that matters most, because it is the one a person acts on.
|
|
9
|
+
*
|
|
10
|
+
* Read-only and fail-quiet by design: a session with no run is a legacy session
|
|
11
|
+
* (`null`, and the caller keeps its own answer), and a run whose state does not
|
|
12
|
+
* match its journey says so instead of projecting a boundary nobody can trust.
|
|
13
|
+
*/
|
|
14
|
+
import { journeyOfFlow } from "../../domain/flow/authority.js";
|
|
15
|
+
import { checkAgainstJourney } from "../../domain/flow/run-state.js";
|
|
16
|
+
import { resolveBoundary } from "./advance.js";
|
|
17
|
+
import { locateRun, readRun } from "./run-state-service.js";
|
|
18
|
+
export async function projectRun(fs, paths, folder) {
|
|
19
|
+
const read = await readRun(fs, locateRun(paths, folder));
|
|
20
|
+
if (!read.ok) {
|
|
21
|
+
// An absent run is the normal case for every session older than the engine;
|
|
22
|
+
// a refusal is not, and hiding it would let `resume` propose work over a state
|
|
23
|
+
// the engine will not touch.
|
|
24
|
+
if (read.failure.code === "FLOW_RUN_ABSENT")
|
|
25
|
+
return null;
|
|
26
|
+
return {
|
|
27
|
+
flow: "?",
|
|
28
|
+
boundary: "blocked",
|
|
29
|
+
transition: null,
|
|
30
|
+
title: null,
|
|
31
|
+
invocation: null,
|
|
32
|
+
command: `aw flow advance --session ${folder} --adopt`,
|
|
33
|
+
summary: `corrida ilegible (${read.failure.code}): ${read.failure.action}`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const journey = journeyOfFlow(read.state.flow);
|
|
37
|
+
const incoherent = checkAgainstJourney(read.state, journey);
|
|
38
|
+
if (incoherent !== null) {
|
|
39
|
+
return {
|
|
40
|
+
flow: read.state.flow,
|
|
41
|
+
boundary: "blocked",
|
|
42
|
+
transition: read.state.boundary,
|
|
43
|
+
title: null,
|
|
44
|
+
invocation: null,
|
|
45
|
+
command: `aw flow advance --session ${folder}`,
|
|
46
|
+
summary: `${incoherent.message} — ${incoherent.action}`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const resolved = resolveBoundary(read.state, journey);
|
|
50
|
+
const stopped = resolved.stopped;
|
|
51
|
+
if (stopped === null) {
|
|
52
|
+
return {
|
|
53
|
+
flow: read.state.flow,
|
|
54
|
+
boundary: "final",
|
|
55
|
+
transition: null,
|
|
56
|
+
title: null,
|
|
57
|
+
invocation: null,
|
|
58
|
+
command: `aw session-close --code ${folder}`,
|
|
59
|
+
summary: "el recorrido no tiene transiciones pendientes",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const invocation = resolved.action === null
|
|
63
|
+
? null
|
|
64
|
+
: [resolved.action.invocation.program, ...resolved.action.invocation.args].join(" ");
|
|
65
|
+
return {
|
|
66
|
+
flow: read.state.flow,
|
|
67
|
+
boundary: resolved.kind,
|
|
68
|
+
transition: stopped.id,
|
|
69
|
+
title: stopped.title,
|
|
70
|
+
invocation,
|
|
71
|
+
// At an execution boundary what continues the run is the invocation itself —
|
|
72
|
+
// anything else would send whoever resumes to re-derive the command from
|
|
73
|
+
// prose, which is exactly what the sealed action exists to prevent.
|
|
74
|
+
command: invocation ?? `aw flow advance --session ${folder}`,
|
|
75
|
+
summary: invocation === null
|
|
76
|
+
? `frontera ${resolved.kind} en ${stopped.id} — ${stopped.title}`
|
|
77
|
+
: `frontera execution en ${stopped.id} — ejecutá '${invocation}' y devolvé su salida real con 'aw flow submit --session ${folder}'`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=run-projection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-projection.js","sourceRoot":"","sources":["../../../src/application/flow/run-projection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading and writing the run state — the only place that touches the file.
|
|
3
|
+
*
|
|
4
|
+
* Two properties matter here and nothing else does:
|
|
5
|
+
*
|
|
6
|
+
* - **Serialized.** Every application takes the run's own lock (the
|
|
7
|
+
* `lock-service` that already exists — exclusive create, TTL, pid), re-reads
|
|
8
|
+
* the state INSIDE it and only then computes the next one. Two processes
|
|
9
|
+
* racing on one run cannot produce last-writer-wins: the second is told the
|
|
10
|
+
* lock is held and gets an action, it never overwrites applied transitions.
|
|
11
|
+
* - **All-or-nothing.** The next state is fully built, validated and sealed
|
|
12
|
+
* before the single write happens, so a failure halfway through leaves the
|
|
13
|
+
* previous state exactly as it was rather than a half-applied one.
|
|
14
|
+
*/
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { FLOW_RUN_STATE_FILE, parseRunState, serializeRunState, } from "../../domain/flow/run-state.js";
|
|
17
|
+
import { LockBusyError, acquireLock } from "../lock-service.js";
|
|
18
|
+
export function locateRun(paths, session) {
|
|
19
|
+
const dir = join(paths.cwdSessionsDir(), session);
|
|
20
|
+
return {
|
|
21
|
+
session,
|
|
22
|
+
dir,
|
|
23
|
+
statePath: join(dir, FLOW_RUN_STATE_FILE),
|
|
24
|
+
lockPath: join(dir, `${FLOW_RUN_STATE_FILE}.lock`),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Read the run state.
|
|
29
|
+
*
|
|
30
|
+
* `FLOW_RUN_ABSENT` is a first-class answer, not an error to swallow: a session
|
|
31
|
+
* opened before the engine existed has no state, and treating that as corruption
|
|
32
|
+
* would send a legacy run to a repair action it does not need. Its action is
|
|
33
|
+
* adoption.
|
|
34
|
+
*/
|
|
35
|
+
export async function readRun(fs, location) {
|
|
36
|
+
if (!(await fs.exists(location.statePath))) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
failure: {
|
|
40
|
+
code: "FLOW_RUN_ABSENT",
|
|
41
|
+
message: `la sesión '${location.session}' no tiene estado de corrida`,
|
|
42
|
+
action: "es una sesión legacy: adoptala con 'aw flow advance --session <código> --flow <flow> --adopt'",
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return parseRunState(await fs.readText(location.statePath));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Run one mutation under the run's lock and persist its result.
|
|
50
|
+
*
|
|
51
|
+
* The mutation receives the state as it is INSIDE the lock — never the copy the
|
|
52
|
+
* caller had — which is what makes this a compare-and-swap instead of a hopeful
|
|
53
|
+
* overwrite.
|
|
54
|
+
*/
|
|
55
|
+
export async function applyUnderLock(fs, location, mutate, options = {}) {
|
|
56
|
+
const { expectDigest, allowAbsent, ...lockOptions } = options;
|
|
57
|
+
await fs.mkdirp(location.dir);
|
|
58
|
+
let lock;
|
|
59
|
+
try {
|
|
60
|
+
lock = await acquireLock(location.lockPath, fs, lockOptions);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err instanceof LockBusyError) {
|
|
64
|
+
return {
|
|
65
|
+
ok: false,
|
|
66
|
+
failure: {
|
|
67
|
+
code: "FLOW_RUN_LOCKED",
|
|
68
|
+
message: `otra invocación tiene la corrida tomada (pid ${err.holder.pid} desde ${err.holder.ts})`,
|
|
69
|
+
action: "esperá a que termine y volvé a correr 'aw flow advance': no se pisan transiciones aplicadas",
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const current = await readRun(fs, location);
|
|
77
|
+
if (!current.ok) {
|
|
78
|
+
const absent = current.failure.code === "FLOW_RUN_ABSENT";
|
|
79
|
+
if (!absent || allowAbsent !== true)
|
|
80
|
+
return { ok: false, failure: current.failure };
|
|
81
|
+
}
|
|
82
|
+
const state = current.ok ? current.state : null;
|
|
83
|
+
if (expectDigest !== undefined && state?.digest !== expectDigest) {
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
failure: {
|
|
87
|
+
code: "FLOW_RUN_STALE",
|
|
88
|
+
message: "el estado de la corrida cambió después de emitirse la directiva",
|
|
89
|
+
action: "volvé a correr 'aw flow advance' y respondé sobre la frontera recalculada",
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const result = await mutate(state);
|
|
94
|
+
if (!result.ok)
|
|
95
|
+
return result;
|
|
96
|
+
if (result.persist === false)
|
|
97
|
+
return result;
|
|
98
|
+
// One write, after the next state is complete and sealed: nothing partial
|
|
99
|
+
// can be observed because nothing partial is ever written.
|
|
100
|
+
await fs.writeText(location.statePath, serializeRunState(result.state));
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
await lock.release();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=run-state-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-state-service.js","sourceRoot":"","sources":["../../../src/application/flow/run-state-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EACL,mBAAmB,EAGnB,aAAa,EACb,iBAAiB,GAClB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,aAAa,EAAoB,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUlF,MAAM,UAAU,SAAS,CAAC,KAAmB,EAAE,OAAe;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC;IAClD,OAAO;QACL,OAAO;QACP,GAAG;QACH,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC;QACzC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,mBAAmB,OAAO,CAAC;KACnD,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAAkB,EAAE,QAAyB;IACzE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QAC3C,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,cAAc,QAAQ,CAAC,OAAO,8BAA8B;gBACrE,MAAM,EACJ,+FAA+F;aAClG;SACF,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AAC9D,CAAC;AAyBD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAkB,EAClB,QAAyB,EACzB,MAA0F,EAC1F,UAAwB,EAAE;IAE1B,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;IAC9D,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAE9B,IAAI,IAA6C,CAAC;IAClD,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EAAE;oBACP,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,gDAAgD,GAAG,CAAC,MAAM,CAAC,GAAG,UAAU,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG;oBACjG,MAAM,EACJ,6FAA6F;iBAChG;aACF,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,iBAAiB,CAAC;YAC1D,IAAI,CAAC,MAAM,IAAI,WAAW,KAAK,IAAI;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QACtF,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAChD,IAAI,YAAY,KAAK,SAAS,IAAI,KAAK,EAAE,MAAM,KAAK,YAAY,EAAE,CAAC;YACjE,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EAAE;oBACP,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE,iEAAiE;oBAC1E,MAAM,EAAE,2EAA2E;iBACpF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,MAAM,CAAC;QAC9B,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK;YAAE,OAAO,MAAM,CAAC;QAC5C,0EAA0E;QAC1E,2DAA2D;QAC3D,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An answer comes back, and either it survives validation or nothing moves.
|
|
3
|
+
*
|
|
4
|
+
* The order of the checks is the contract, not an implementation detail:
|
|
5
|
+
*
|
|
6
|
+
* 1. **Resend first.** The attempt history is hydrated from the persisted state
|
|
7
|
+
* and consulted before anything else. A resend of an answer that was already
|
|
8
|
+
* applied quotes the seal of a boundary the run has since left, so judging
|
|
9
|
+
* staleness first would report "stale" for what is really "already applied" —
|
|
10
|
+
* and would tempt the sender into answering twice.
|
|
11
|
+
* 2. **Then the boundary in force.** Which shape is admissible comes from the
|
|
12
|
+
* boundary, never from a flag: the same `submit` answers a semantic boundary,
|
|
13
|
+
* a human one and an authorization one.
|
|
14
|
+
* 3. **Then apply.** Only a surviving answer becomes a transition, and only then
|
|
15
|
+
* does the run keep advancing until the next boundary. One surviving answer
|
|
16
|
+
* deliberately applies nothing: an approval over a step doctrine still owns
|
|
17
|
+
* grants the effect and leaves the run where it stands.
|
|
18
|
+
*
|
|
19
|
+
* Every rejection travels with `ok: true` inside the RECALCULATED directive,
|
|
20
|
+
* carrying its code, message and action — with `ok: false` the host never calls
|
|
21
|
+
* `renderHuman`, and a boundary nobody can see is a boundary that did not happen.
|
|
22
|
+
*/
|
|
23
|
+
import { AttemptLedger } from "../../domain/capability/protocol.js";
|
|
24
|
+
import { claimedSeal, parseFlowAnswer } from "../../domain/flow/answer.js";
|
|
25
|
+
import { actionOf, effectsOf, journeyOfFlow, } from "../../domain/flow/authority.js";
|
|
26
|
+
import { effectApprovalDigest } from "../../domain/flow/authorization.js";
|
|
27
|
+
import { PAUSE_LABEL, STOP_LABEL, stepOf, } from "../../domain/flow/directive.js";
|
|
28
|
+
import { applyTransition, checkAgainstJourney, withApproval, withAttempt, withBoundary, withObservation, } from "../../domain/flow/run-state.js";
|
|
29
|
+
import { semanticDigest } from "../semantic-operation/protocol.js";
|
|
30
|
+
import { resolveSessionTarget } from "../session-resolver.js";
|
|
31
|
+
import { actionDigest, advanceFlowRun, directiveFor, resolveBoundary, } from "./advance.js";
|
|
32
|
+
import { applyUnderLock, locateRun } from "./run-state-service.js";
|
|
33
|
+
export async function submitFlow(fs, paths, input) {
|
|
34
|
+
const resolution = await resolveSessionTarget(fs, paths, {
|
|
35
|
+
...(input.code !== undefined ? { code: input.code } : {}),
|
|
36
|
+
...(input.contextId !== undefined ? { contextId: input.contextId } : {}),
|
|
37
|
+
allowClosed: false,
|
|
38
|
+
bind: true,
|
|
39
|
+
});
|
|
40
|
+
if (resolution.outcome !== "resolved")
|
|
41
|
+
return { ok: false, session: resolution };
|
|
42
|
+
const location = locateRun(paths, resolution.session.folder);
|
|
43
|
+
const applied = await applyUnderLock(fs, location, (current) => {
|
|
44
|
+
if (current === null) {
|
|
45
|
+
return {
|
|
46
|
+
ok: false,
|
|
47
|
+
failure: {
|
|
48
|
+
code: "FLOW_RUN_ABSENT",
|
|
49
|
+
message: "no hay corrida que responder en esta sesión",
|
|
50
|
+
action: "adoptala primero con 'aw flow advance --flow <flow> --adopt'",
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return decide(current, input);
|
|
55
|
+
});
|
|
56
|
+
if (!applied.ok)
|
|
57
|
+
return { ok: false, failure: applied.failure };
|
|
58
|
+
return { ok: true, directive: applied.value };
|
|
59
|
+
}
|
|
60
|
+
function decide(state, input) {
|
|
61
|
+
const journey = journeyOfFlow(state.flow);
|
|
62
|
+
const incoherent = checkAgainstJourney(state, journey);
|
|
63
|
+
if (incoherent !== null)
|
|
64
|
+
return { ok: false, failure: incoherent };
|
|
65
|
+
const resolved = resolveBoundary(state, journey);
|
|
66
|
+
if (resolved.stopped === null) {
|
|
67
|
+
return reject(state, resolved, "el recorrido ya terminó: no hay frontera que responder", {
|
|
68
|
+
code: "FLOW_ANSWER_NOT_EXPECTED",
|
|
69
|
+
action: "no queda trabajo pendiente en este recorrido",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (state.boundary === null) {
|
|
73
|
+
return reject(state, resolved, "esta corrida todavía no se detuvo en ninguna frontera", {
|
|
74
|
+
code: "FLOW_ANSWER_NOT_EXPECTED",
|
|
75
|
+
action: "corré 'aw flow advance' primero: la frontera la emite el motor, no el llamador",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// The seal the payload CLAIMS keys the lookup, not the current one: a resend of
|
|
79
|
+
// an answer that was already applied quotes a boundary the run has left, and
|
|
80
|
+
// looking it up under today's seal would never find it. A forged seal buys
|
|
81
|
+
// nothing — matching a recorded attempt requires resending exactly what already
|
|
82
|
+
// ran, and a retry applies nothing.
|
|
83
|
+
const identity = attemptIdentity(state, input, claimedSeal(input.raw) ?? resolved.seal, resolved.stopped.id);
|
|
84
|
+
// 1 · Resend, before anything else.
|
|
85
|
+
const resend = resendCheck(state, resolved, identity);
|
|
86
|
+
if (resend !== null)
|
|
87
|
+
return resend;
|
|
88
|
+
// The action the run is waiting on is the one that was EMITTED, and the seal
|
|
89
|
+
// would already refuse a result about any other. What the persisted digest adds
|
|
90
|
+
// is the diagnosis: when the two differ, the invocation changed underneath a run
|
|
91
|
+
// in flight (a CLI upgraded mid-run), which is a different problem from a state
|
|
92
|
+
// that moved — and it has a different answer.
|
|
93
|
+
const drifted = actionDrift(state, resolved);
|
|
94
|
+
if (drifted !== null)
|
|
95
|
+
return drifted;
|
|
96
|
+
// 2 · The boundary in force decides what is admissible.
|
|
97
|
+
const admissible = admit(state, resolved, resolved.stopped, input, { journey, identity });
|
|
98
|
+
if ("decision" in admissible)
|
|
99
|
+
return admissible.decision;
|
|
100
|
+
const parsed = admissible;
|
|
101
|
+
// 3 · Apply: the answer is the INPUT to the CLI's decision, so what advances is
|
|
102
|
+
// the transition, never the sender's own verdict.
|
|
103
|
+
const granted = resolved.kind === "authorization" ? (resolved.authorization?.planned ?? []) : [];
|
|
104
|
+
const approved = granted.length > 0 ? withApproval(state, granted) : state;
|
|
105
|
+
// An approval NEVER applies a step by itself. Two reasons it must hold, and the
|
|
106
|
+
// second is the one this phase exists for: doctrine may still own the rule, or
|
|
107
|
+
// the step may be delegated — and an approval that applied a delegated
|
|
108
|
+
// transition would record the search, the write or the check as done because
|
|
109
|
+
// someone said the effect was allowed.
|
|
110
|
+
const holds = resolved.kind === "authorization" &&
|
|
111
|
+
(resolved.stopped.ownership !== "cli-owned" || actionOf(resolved.stopped) !== null);
|
|
112
|
+
return holds
|
|
113
|
+
? holdAfterApproval(approved, journey, identity)
|
|
114
|
+
: applyAndAdvance(approved, journey, resolved.stopped, identity, parsed.answer);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Everything that decides whether this payload may become a transition.
|
|
118
|
+
*
|
|
119
|
+
* Three refusals live together because they answer the same question — "is this
|
|
120
|
+
* an admissible answer to the boundary in force?" — and none of them writes:
|
|
121
|
+
* a payload the boundary's own contract rejects, a decline (a real answer that
|
|
122
|
+
* applies nothing), and an execution result that did not earn its transition.
|
|
123
|
+
*/
|
|
124
|
+
function admit(state, resolved, stopped, input, spent) {
|
|
125
|
+
const expectedApproval = resolved.kind === "authorization"
|
|
126
|
+
? effectApprovalDigest(stopped.id, resolved.authorization?.planned ?? [])
|
|
127
|
+
: null;
|
|
128
|
+
const parsed = parseFlowAnswer({
|
|
129
|
+
raw: input.raw,
|
|
130
|
+
boundary: resolved.kind,
|
|
131
|
+
decision: stopped,
|
|
132
|
+
seal: resolved.seal,
|
|
133
|
+
choices: resolved.choices,
|
|
134
|
+
approval: input.approval,
|
|
135
|
+
expectedApproval,
|
|
136
|
+
action: resolved.action,
|
|
137
|
+
});
|
|
138
|
+
if (!parsed.ok) {
|
|
139
|
+
// An answer the boundary refused IS an attempt spent: it is the exact event
|
|
140
|
+
// the chassis' cap counts. Recorded here and nowhere else — a resend, a
|
|
141
|
+
// decline and a pause are not failed tries at resolving the gap.
|
|
142
|
+
return {
|
|
143
|
+
decision: reject(state, resolved, parsed.failure.message, { code: parsed.failure.code, action: parsed.failure.action }, spent),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// The flow control is a real answer, and neither half applies anything. They
|
|
147
|
+
// are kept apart because the outcomes differ and the difference is the point:
|
|
148
|
+
// stopping ends the run here (`cancelled`), pausing keeps the very same
|
|
149
|
+
// boundary standing so the run picks it up after compacting (`needs_input`).
|
|
150
|
+
// Collapsing them would report a paused run as a cancelled one.
|
|
151
|
+
if (parsed.answer.choice === PAUSE_LABEL) {
|
|
152
|
+
return {
|
|
153
|
+
decision: reject(state, resolved, `'${PAUSE_LABEL}': la frontera queda en pie y la corrida retoma acá`, {
|
|
154
|
+
code: "FLOW_BOUNDARY_PAUSED",
|
|
155
|
+
action: "escribí el CHECKPOINT con 'aw checkpoint-write', compactá, y volvé con 'aw flow advance' a esta misma frontera",
|
|
156
|
+
outcome: "needs_input",
|
|
157
|
+
}),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (parsed.answer.choice === STOP_LABEL) {
|
|
161
|
+
return {
|
|
162
|
+
decision: reject(state, resolved, `'${STOP_LABEL}': el recorrido queda detenido en esta frontera`, {
|
|
163
|
+
code: "FLOW_BOUNDARY_DECLINED",
|
|
164
|
+
action: "reanudá con 'aw flow advance' cuando quieras retomar esta frontera",
|
|
165
|
+
outcome: "cancelled",
|
|
166
|
+
}),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// An execution result has to EARN the transition. Anything short of a completed
|
|
170
|
+
// run with its evidence and its whole effect keeps the boundary standing: the
|
|
171
|
+
// work stays pending, with the recovery the action declared.
|
|
172
|
+
if (resolved.kind === "execution") {
|
|
173
|
+
const verdict = executionVerdict(parsed.answer, resolved.action, effectsOf(stopped));
|
|
174
|
+
if (verdict !== null) {
|
|
175
|
+
return { decision: reject(state, resolved, verdict.message, verdict.detail, spent) };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return parsed;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Why this execution result does not apply the transition — or `null` when it does.
|
|
182
|
+
*
|
|
183
|
+
* Three verdicts, and each one is the answer to a way a run could claim work that
|
|
184
|
+
* never happened: an outcome that is not `completed` did not finish; evidence that
|
|
185
|
+
* is missing, failed or empty means nothing came back from the tool; and an effect
|
|
186
|
+
* ledger short of what the row declared means the invocation got partway. The
|
|
187
|
+
* recovery the action declared travels in every one of them, because a run stopped
|
|
188
|
+
* without a next step is the dead end this whole contract refuses.
|
|
189
|
+
*/
|
|
190
|
+
function executionVerdict(answer, action, declared) {
|
|
191
|
+
const result = answer.result;
|
|
192
|
+
if (result === null || action === null) {
|
|
193
|
+
return {
|
|
194
|
+
message: "la respuesta no trae el resultado de la invocación",
|
|
195
|
+
detail: {
|
|
196
|
+
code: "FLOW_RESULT_INVALID",
|
|
197
|
+
action: "devolvé el resultado real de la acción: outcome, invocación, validaciones y efectos",
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
if (result.outcome !== "completed") {
|
|
202
|
+
return {
|
|
203
|
+
message: `la invocación devolvió '${result.outcome}': la transición sigue pendiente`,
|
|
204
|
+
detail: {
|
|
205
|
+
code: "FLOW_EXECUTION_NOT_COMPLETED",
|
|
206
|
+
action: action.recovery,
|
|
207
|
+
outcome: result.outcome,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const missing = action.evidence.filter((id) => {
|
|
212
|
+
const found = result.validations.find((validation) => validation.id === id);
|
|
213
|
+
return found === undefined || !found.passed || (found.detail ?? "").trim().length === 0;
|
|
214
|
+
});
|
|
215
|
+
if (missing.length > 0) {
|
|
216
|
+
return {
|
|
217
|
+
message: `falta la evidencia real de ${missing.join(", ")}`,
|
|
218
|
+
detail: {
|
|
219
|
+
code: "FLOW_EVIDENCE_MISSING",
|
|
220
|
+
action: `devolvé cada validación exigida con 'passed' y su 'detail' — la salida de la herramienta, no una afirmación. ${action.recovery}`,
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
const applied = new Set(result.effects.applied);
|
|
225
|
+
const partial = declared.filter((effect) => !applied.has(effect));
|
|
226
|
+
if (partial.length > 0) {
|
|
227
|
+
return {
|
|
228
|
+
message: `la invocación declara completa pero no aplicó ${partial.join(", ")}`,
|
|
229
|
+
detail: {
|
|
230
|
+
code: "FLOW_EFFECT_PARTIAL",
|
|
231
|
+
action: action.recovery,
|
|
232
|
+
outcome: "needs_input",
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
// Completeness is not an outcome — it answers "does what came back cover what
|
|
237
|
+
// was asked?" — so an attempt that FINISHED can still hand back a partial
|
|
238
|
+
// output. Ignoring that here would let the run credit a search that returned
|
|
239
|
+
// half its matches as if it had returned all of them.
|
|
240
|
+
if (result.output?.completeness === "partial") {
|
|
241
|
+
return {
|
|
242
|
+
message: "la invocación terminó pero su salida declara cobertura parcial",
|
|
243
|
+
detail: {
|
|
244
|
+
code: "FLOW_EFFECT_PARTIAL",
|
|
245
|
+
action: action.recovery,
|
|
246
|
+
outcome: "needs_input",
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Whether the sealed action changed underneath a run that is standing on it.
|
|
254
|
+
*
|
|
255
|
+
* Only reachable when the persisted digest and the registry's current one differ —
|
|
256
|
+
* i.e. the build moved while the caller was executing. Saying so beats the generic
|
|
257
|
+
* staleness the seal would otherwise report, because the fix is different: nothing
|
|
258
|
+
* is wrong with the state, the invocation is simply no longer the one that ran.
|
|
259
|
+
*/
|
|
260
|
+
function actionDrift(state, resolved) {
|
|
261
|
+
const pending = state.pending_action;
|
|
262
|
+
if (pending === null || resolved.action === null)
|
|
263
|
+
return null;
|
|
264
|
+
if (pending.digest === actionDigest(resolved.action))
|
|
265
|
+
return null;
|
|
266
|
+
return reject(state, resolved, "la acción de esta frontera cambió después de emitirse: el resultado corresponde a otra invocación", {
|
|
267
|
+
code: "FLOW_ACTION_CHANGED",
|
|
268
|
+
action: "volvé a correr 'aw flow advance' para recibir la acción vigente y ejecutá esa antes de responder",
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Approving an effect is NOT deciding the step, and never executing it.
|
|
273
|
+
*
|
|
274
|
+
* The approval is recorded and the run stays exactly where it is: the recalculated
|
|
275
|
+
* boundary is the one for the SAME transition, so approving what a step exercises
|
|
276
|
+
* never doubles as deciding it. Applying here would let an approval smuggle in the
|
|
277
|
+
* step itself.
|
|
278
|
+
*
|
|
279
|
+
* On a DELEGATED transition the same hold, for the sharper reason: the approval
|
|
280
|
+
* authorizes the effect and the recalculated boundary becomes the `execution` one,
|
|
281
|
+
* which still has to come back with real output. "You may write this" and "this
|
|
282
|
+
* was written" are different facts, and only the second one advances a run.
|
|
283
|
+
*/
|
|
284
|
+
function holdAfterApproval(approved, journey, identity) {
|
|
285
|
+
const held = advanceFlowRun({ state: withAttempt(approved, identity), journey, applied: [] });
|
|
286
|
+
if (!held.ok)
|
|
287
|
+
return { ok: false, failure: held.failure };
|
|
288
|
+
return { ok: true, state: held.state, value: held.directive };
|
|
289
|
+
}
|
|
290
|
+
/** The answer survived: the transition applies and the run keeps advancing. */
|
|
291
|
+
function applyAndAdvance(approved, journey, stopped, identity, answer) {
|
|
292
|
+
// What the agent OBSERVED outlives the boundary it was asked at: a later rule
|
|
293
|
+
// reads these signals to apply its threshold. The verdict is not stored — it is
|
|
294
|
+
// derived from these on each read, so the two can never disagree.
|
|
295
|
+
let next = answer.signals.length > 0
|
|
296
|
+
? withObservation(approved, { transition: stopped.id, signals: answer.signals })
|
|
297
|
+
: approved;
|
|
298
|
+
next = applyTransition(next, stopped.id, effectsOf(stopped));
|
|
299
|
+
next = withAttempt(next, identity);
|
|
300
|
+
// The boundary follows the position, always: handing the engine a state whose
|
|
301
|
+
// boundary still names the transition just applied is exactly the incoherence
|
|
302
|
+
// `checkAgainstJourney` exists to refuse.
|
|
303
|
+
next = withBoundary(next, journey[next.applied.length]?.id ?? null);
|
|
304
|
+
const advanced = advanceFlowRun({ state: next, journey, applied: [stepOf(stopped)] });
|
|
305
|
+
if (!advanced.ok)
|
|
306
|
+
return { ok: false, failure: advanced.failure };
|
|
307
|
+
return { ok: true, state: advanced.state, value: advanced.directive };
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Whether this submission is a resend, judged by the ledger that already knows
|
|
311
|
+
* how.
|
|
312
|
+
*
|
|
313
|
+
* The persisted history is replayed through {@link AttemptLedger} rather than
|
|
314
|
+
* counted by hand, so its sequence and parent-linkage rules apply for free — and
|
|
315
|
+
* a history that cannot be replayed is itself a refusal, not something to work
|
|
316
|
+
* around. `null` means "a genuinely new attempt: carry on".
|
|
317
|
+
*
|
|
318
|
+
* A twin in the history is not enough, and the real walk of the closing tranche
|
|
319
|
+
* is what showed it. Since refusals started being persisted — and since the seal
|
|
320
|
+
* stopped moving when one is recorded, so that a caller's own refusal would not
|
|
321
|
+
* come back as staleness — resending a REFUSED answer looks exactly like
|
|
322
|
+
* resending an applied one. Both find their twin. Only one of them advanced
|
|
323
|
+
* anything, and answering the other with "this already applied" reports a run
|
|
324
|
+
* that is stuck as one that is done: `completed`, with the real cause (a mismatched
|
|
325
|
+
* approval, an invalid payload) replaced by a vague one, permanently, because
|
|
326
|
+
* every retry from then on gets the same reply.
|
|
327
|
+
*
|
|
328
|
+
* So the twin has to say which it was, and that fact is already in the state:
|
|
329
|
+
* the run moves past what it applies, so an attempt whose transition is not in
|
|
330
|
+
* `applied` never advanced anything. Derived rather than stored on the attempt,
|
|
331
|
+
* for the reason the registry gives everywhere it derives: two sources for one
|
|
332
|
+
* fact disagree eventually, and then the state is unusable.
|
|
333
|
+
*/
|
|
334
|
+
function resendCheck(state, resolved, identity) {
|
|
335
|
+
const ledger = new AttemptLedger();
|
|
336
|
+
for (const past of state.attempts) {
|
|
337
|
+
const replay = ledger.record(past);
|
|
338
|
+
if (!replay.ok)
|
|
339
|
+
return { ok: false, failure: replay.failure };
|
|
340
|
+
}
|
|
341
|
+
const verdict = ledger.record(identity);
|
|
342
|
+
if (!verdict.ok)
|
|
343
|
+
return { ok: false, failure: verdict.failure };
|
|
344
|
+
if (verdict.kind === "new")
|
|
345
|
+
return null;
|
|
346
|
+
// The TWIN's transition, not this submission's: the identity is built over the
|
|
347
|
+
// boundary in force, and a resent applied answer is being sent at the next one.
|
|
348
|
+
// What is being asked is whether the step the twin answered ever moved.
|
|
349
|
+
const twin = state.attempts.find((past) => past.invocation_id === identity.invocation_id &&
|
|
350
|
+
past.request_digest === identity.request_digest);
|
|
351
|
+
// The twin was refused: this is a retry of the same wrong answer, so it gets
|
|
352
|
+
// the same real diagnosis again and counts toward the cap, which is what
|
|
353
|
+
// eventually degrades the boundary instead of leaving the caller looping.
|
|
354
|
+
if (twin !== undefined && !state.applied.includes(twin.transition))
|
|
355
|
+
return null;
|
|
356
|
+
return reject(state, resolved, "esta respuesta ya se había aplicado: el recorrido no avanza dos veces", {
|
|
357
|
+
code: "FLOW_ANSWER_RESENT",
|
|
358
|
+
action: "la frontera vigente es la que devuelve esta directiva; contestá esa",
|
|
359
|
+
outcome: "completed",
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* A rejection, expressed as the recalculated directive.
|
|
364
|
+
*
|
|
365
|
+
* The state handed back is the one that was read: nothing is written on this
|
|
366
|
+
* path, and the caller can see that because the mutation returns `ok: false`
|
|
367
|
+
* only for invocation failures — a business rejection returns the state unchanged
|
|
368
|
+
* with its own outcome.
|
|
369
|
+
*/
|
|
370
|
+
function reject(state, resolved, message, detail, spent) {
|
|
371
|
+
// A refused answer is the one rejection that CHANGES the run: the attempt is
|
|
372
|
+
// recorded, so the boundary that has been tried to its cap degrades instead of
|
|
373
|
+
// being emitted again. The boundary is recalculated over that state, which is
|
|
374
|
+
// what turns the last refusal into the degradation rather than into an
|
|
375
|
+
// identical question with a different error string.
|
|
376
|
+
const after = spent === undefined ? state : withAttempt(state, spent.identity);
|
|
377
|
+
const now = spent === undefined ? resolved : resolveBoundary(after, spent.journey);
|
|
378
|
+
const built = directiveFor(after, now, [], {
|
|
379
|
+
// No outcome named ⇒ the boundary decides it: a finished journey reports
|
|
380
|
+
// `completed`, an open one `needs_input`. Hardcoding one here would let a
|
|
381
|
+
// rejection at the end of a run claim work is still pending.
|
|
382
|
+
...(detail.outcome === undefined ? {} : { outcome: detail.outcome }),
|
|
383
|
+
nextAction: `${message} — ${now.error?.action ?? detail.action}`,
|
|
384
|
+
});
|
|
385
|
+
if (!built.ok)
|
|
386
|
+
return { ok: false, failure: built.failure };
|
|
387
|
+
// Rewritten with the rejection's own code so the reason is machine-readable and
|
|
388
|
+
// not only prose in `next_action` — unless the recalculated boundary is itself
|
|
389
|
+
// blocked, in which case ITS cause is the actionable one: answering again is no
|
|
390
|
+
// longer a way forward, and reporting the payload's error would suggest it is.
|
|
391
|
+
const directive = {
|
|
392
|
+
...built.directive,
|
|
393
|
+
error: now.error ?? { code: detail.code, message, action: detail.action },
|
|
394
|
+
};
|
|
395
|
+
return { ok: true, state: after, value: directive, persist: spent !== undefined };
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* The attempt this submission is, in the terms `AttemptLedger` already validates.
|
|
399
|
+
*
|
|
400
|
+
* `invocation_id` is the boundary's seal: stable while the run stands there, and
|
|
401
|
+
* different the moment the state moves — which is exactly the identity a resend
|
|
402
|
+
* has to match. Reusing the ledger instead of counting by hand is the point: its
|
|
403
|
+
* sequence and parent-linkage rules come for free.
|
|
404
|
+
*/
|
|
405
|
+
function attemptIdentity(state, input, seal, transition) {
|
|
406
|
+
const digest = semanticDigest({ payload: input.raw, approval: input.approval });
|
|
407
|
+
const prior = state.attempts.filter((past) => past.invocation_id === seal);
|
|
408
|
+
const twin = prior.find((past) => past.request_digest === digest);
|
|
409
|
+
const attempt = twin?.attempt ?? prior.length + 1;
|
|
410
|
+
const parent = attempt === 1
|
|
411
|
+
? null
|
|
412
|
+
: (prior.find((past) => past.attempt === attempt - 1)?.request_digest ?? null);
|
|
413
|
+
return {
|
|
414
|
+
invocation_id: seal,
|
|
415
|
+
attempt,
|
|
416
|
+
request_digest: digest,
|
|
417
|
+
parent_request_digest: parent,
|
|
418
|
+
// The seal moves with the state; the transition does not while the run
|
|
419
|
+
// stands there. It is what the cap counts over.
|
|
420
|
+
transition,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
//# sourceMappingURL=submit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../../../src/application/flow/submit.ts"],"names":[],"mappings":"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"}
|