@agentxm/workspace-operations 0.29.2 → 0.30.1

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.
@@ -11,8 +11,8 @@
11
11
  * @experimental This API is unstable and may change without notice.
12
12
  * @packageDocumentation
13
13
  */
14
- export { BlockingClassSchema, defaultOperationPresentation, operationPresentation, presentationOf, ArtifactMechanismSchema, ConfirmableConsentSchema, OperationPreconditionSchema, PlanPolicyIdSchema, PlanPolicyIds, PlanRiskConditionSchema, } from "./plan/plan.js";
15
- export type { ArtifactMechanism, BlockingClass, CompletedJobStep, ConfirmableConsent, ErrorJobStep, ExecutedJob, ExecutedPlan, Job, JobStepArtifact, JobStepArtifactSource, JobStepArtifactTarget, JobStepResult, Operation, OperationPrecondition, OperationPresentation, Plan, PlanExecutionCapabilities, PlanPolicyId, PlanRiskCondition, PlannedJobStep, ReadyJobStep, RegistryLifecycleEvidence, UnitBlocking, WarnJobStep, } from "./plan/plan.js";
14
+ export { BlockingClassSchema, defaultOperationPresentation, operationPresentation, presentationOf, ArtifactMechanismSchema, PackMembershipDeltaSchema, ConfirmableConsentSchema, OperationPreconditionSchema, PlanPolicyIdSchema, PlanPolicyIds, PlanRiskConditionSchema, } from "./plan/plan.js";
15
+ export type { ArtifactMechanism, BlockingClass, CompletedJobStep, ConfirmableConsent, ErrorJobStep, ExecutedJob, ExecutedPlan, Job, JobStepArtifact, PackMembershipDelta, JobStepArtifactSource, JobStepArtifactTarget, JobStepArtifactReference, JobStepResult, Operation, OperationPrecondition, OperationPresentation, Plan, PlanExecutionCapabilities, PlanPolicyId, PlanRiskCondition, PlannedJobStep, ReadyJobStep, RegistryLifecycleEvidence, UnitBlocking, WarnJobStep, } from "./plan/plan.js";
16
16
  export { AtomicityClassSchema, OperationOutcomeSchema, OperationPhaseSchema, UnitDispositionSchema, UnitStateSchema, countUnitStates, declaredAtomicity, deriveOperationOutcome, executedUnits, makeOperationResolution, plannedUnits, unitIdOf, unitsByStableIdentity, } from "./plan/operation-resolution.js";
17
17
  export type { AtomicityClass, MakeOperationResolutionArgs, OperationAtomicity, OperationBlock, OperationFootprintEntry, OperationInterruption, OperationOutcome, OperationPhase, OperationRecovery, OperationResolution, ResolvedUnit, UnitDisposition, UnitState, UnitStateCounts, } from "./plan/operation-resolution.js";
18
18
  export { OperationJournal, appendResolvedUnit, appendStartedUnit, recordJournalPhase, getOperationJournal, makeOperationJournal, recordOperationJournal, updateOperationJournal, type OperationJournalService, type OperationJournalState, } from "./plan/operation-journal.js";
package/dist/src/index.js CHANGED
@@ -12,7 +12,7 @@
12
12
  * @packageDocumentation
13
13
  */
14
14
  // Plan types
15
- export { BlockingClassSchema, defaultOperationPresentation, operationPresentation, presentationOf, ArtifactMechanismSchema, ConfirmableConsentSchema, OperationPreconditionSchema, PlanPolicyIdSchema, PlanPolicyIds, PlanRiskConditionSchema, } from "./plan/plan.js";
15
+ export { BlockingClassSchema, defaultOperationPresentation, operationPresentation, presentationOf, ArtifactMechanismSchema, PackMembershipDeltaSchema, ConfirmableConsentSchema, OperationPreconditionSchema, PlanPolicyIdSchema, PlanPolicyIds, PlanRiskConditionSchema, } from "./plan/plan.js";
16
16
  // Operation resolution — the single value every plan-family command
17
17
  // terminates with, with its pure outcome derivations.
18
18
  export { AtomicityClassSchema, OperationOutcomeSchema, OperationPhaseSchema, UnitDispositionSchema, UnitStateSchema, countUnitStates, declaredAtomicity, deriveOperationOutcome, executedUnits, makeOperationResolution, plannedUnits, unitIdOf, unitsByStableIdentity, } from "./plan/operation-resolution.js";
@@ -23,9 +23,9 @@ export type OperationHandler<Op, R = never> = (op: Op) => Effect.Effect<JobStepR
23
23
  /**
24
24
  * Apply a plan by iterating jobs and executing step run closures.
25
25
  *
26
- * Any readiness error gates the complete plan before execution. At runtime,
27
- * jobs use ordered fail-fast execution by default. A job may explicitly opt
28
- * into best-effort execution for independent siblings; failures still block
26
+ * Readiness errors in ordered jobs gate the complete plan. A job may explicitly
27
+ * opt into best-effort execution for independent siblings, including siblings
28
+ * blocked during preparation. Runtime failures still block
29
29
  * all subsequent jobs.
30
30
  *
31
31
  * Never fails — catches StepFailure and converts to error results.
@@ -36,19 +36,9 @@ const stepEvidence = (step) => ({
36
36
  const executeStep = (step) => {
37
37
  switch (step.readiness) {
38
38
  case "error":
39
- return Effect.succeed({
40
- ...(step.key === undefined ? {} : { key: step.key }),
41
- ...stepEvidence(step),
42
- label: step.label,
43
- result: {
44
- result: "error",
45
- message: step.errorMessage,
46
- error: new StepFailure({
47
- category: "internal",
48
- detail: step.errorMessage,
49
- }),
50
- },
51
- });
39
+ return Effect.succeed(blockStep(step, step.errorMessage, {
40
+ class: "precondition-unmet",
41
+ }));
52
42
  case "ready":
53
43
  return step.run.pipe(Effect.map((result) => ({
54
44
  ...(step.key === undefined ? {} : { key: step.key }),
@@ -202,7 +192,8 @@ const executeDependencyAwareJob = (job, observeStart, observeStep) => Effect.gen
202
192
  export const applyPlan = (plan, options) => Effect.gen(function* () {
203
193
  const observeStep = options?.onStepCompleted ?? (() => Effect.void);
204
194
  const observeStart = options?.onStepStarted ?? (() => Effect.void);
205
- const hasReadinessError = plan.jobs.some((job) => job.steps.some((step) => step.readiness === "error"));
195
+ const hasReadinessError = plan.jobs.some((job) => job.executionPolicy !== "best-effort" &&
196
+ job.steps.some((step) => step.readiness === "error"));
206
197
  // Any job with an error blocks every later job; the fact travels in a
207
198
  // `Ref` because it crosses the job traversal's iteration boundary.
208
199
  const blocked = yield* Ref.make(false);
@@ -6,8 +6,14 @@ import * as Option from "effect/Option";
6
6
  import { CandidateFingerprintFailed } from "./errors.js";
7
7
  const collectArtifactPaths = (plan) => plan.jobs.flatMap((job) => job.steps.flatMap((step) => {
8
8
  if (step.artifact === undefined)
9
- return [];
10
- return [step.artifact.path, ...(step.artifact.targets ?? []).map((target) => target.path)];
9
+ return step.materialPaths ?? [];
10
+ return [
11
+ ...(step.materialPaths ?? []),
12
+ step.artifact.path,
13
+ ...(step.artifact.targets ?? []).map((target) => target.path),
14
+ ...(step.artifact.references ?? []).map((reference) => reference.path),
15
+ ...(step.artifact.managedRegions ?? []).map((region) => region.path),
16
+ ];
11
17
  }));
12
18
  const resolveMaterialPaths = (plan, settingsPath, lockPath, baseDir, path) => Array.from(new Set([settingsPath, lockPath, ...(plan.materialPaths ?? []), ...collectArtifactPaths(plan)].map((candidate) => path.resolve(baseDir, candidate)))).sort();
13
19
  const fingerprintPath = (target, label, fs, path) => Effect.gen(function* () {
@@ -57,6 +63,7 @@ const planIdentity = (plan, baseDir, path) => JSON.stringify({
57
63
  steps: job.steps.map((step) => ({
58
64
  key: step.key,
59
65
  dependsOn: step.dependsOn,
66
+ materialPaths: step.materialPaths,
60
67
  label: step.label,
61
68
  readiness: step.readiness,
62
69
  artifact: step.artifact,
@@ -76,6 +76,24 @@ export interface Operation<TName extends string, TArgs> {
76
76
  }
77
77
  export declare const ArtifactMechanismSchema: Schema.Literals<readonly ["symlink", "copy"]>;
78
78
  export type ArtifactMechanism = typeof ArtifactMechanismSchema.Type;
79
+ /** Resolved manifest changes; null denotes an absent dependency. */
80
+ export declare const PackMembershipDeltaSchema: Schema.Struct<{
81
+ readonly pack: Schema.String;
82
+ readonly members: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
83
+ readonly member: Schema.String;
84
+ readonly before: Schema.Null;
85
+ readonly after: Schema.String;
86
+ }>, Schema.Struct<{
87
+ readonly member: Schema.String;
88
+ readonly before: Schema.String;
89
+ readonly after: Schema.Null;
90
+ }>, Schema.Struct<{
91
+ readonly member: Schema.String;
92
+ readonly before: Schema.String;
93
+ readonly after: Schema.String;
94
+ }>]>>;
95
+ }>;
96
+ export type PackMembershipDelta = typeof PackMembershipDeltaSchema.Type;
79
97
  export interface JobStepArtifact {
80
98
  readonly path: string;
81
99
  readonly scope: "project" | "user";
@@ -86,9 +104,12 @@ export interface JobStepArtifact {
86
104
  readonly previousVersion?: string;
87
105
  readonly fileCount?: number;
88
106
  readonly targets?: ReadonlyArray<JobStepArtifactTarget>;
107
+ /** Observed retained, absent, or unresolved state; these are not write targets. */
108
+ readonly references?: ReadonlyArray<JobStepArtifactReference>;
89
109
  readonly agentOutcomes?: ReadonlyArray<ConfiguredAgentOutcome>;
90
110
  readonly source?: JobStepArtifactSource;
91
111
  readonly managedRegions?: ReadonlyArray<JobStepManagedRegion>;
112
+ readonly packMembership?: PackMembershipDelta;
92
113
  /** Registry lifecycle evidence captured when the candidate was resolved. */
93
114
  readonly registryLifecycle?: {
94
115
  readonly deprecation: DeprecationView;
@@ -99,10 +120,20 @@ export interface JobStepManagedRegion {
99
120
  readonly path: string;
100
121
  readonly owner: string;
101
122
  }
123
+ export interface JobStepArtifactReference {
124
+ readonly path: string;
125
+ readonly state: "retained" | "absent" | "unknown";
126
+ readonly reason: string;
127
+ readonly unitId?: string;
128
+ readonly owner?: string;
129
+ }
102
130
  export interface JobStepArtifactTarget {
103
131
  readonly path: string;
104
132
  readonly change: ArtifactChange;
105
133
  readonly agentIds?: ReadonlyArray<string>;
134
+ readonly unitId?: string;
135
+ readonly owner?: string;
136
+ readonly entryName?: string;
106
137
  }
107
138
  export interface JobStepArtifactSource {
108
139
  readonly type: string;
@@ -135,6 +166,8 @@ export type JobStepResult<Output = never> = {
135
166
  export interface ReadyJobStep<Requirements = never, Output = never> {
136
167
  readonly key?: string;
137
168
  readonly dependsOn?: ReadonlyArray<string>;
169
+ /** Read-only inputs fingerprinted with this step, distinct from its write footprint. */
170
+ readonly materialPaths?: ReadonlyArray<string>;
138
171
  readonly readiness: "ready";
139
172
  readonly label: string;
140
173
  readonly message?: string;
@@ -147,6 +180,8 @@ export interface ReadyJobStep<Requirements = never, Output = never> {
147
180
  export interface WarnJobStep<Requirements = never, Output = never> {
148
181
  readonly key?: string;
149
182
  readonly dependsOn?: ReadonlyArray<string>;
183
+ /** Read-only inputs fingerprinted with this step, distinct from its write footprint. */
184
+ readonly materialPaths?: ReadonlyArray<string>;
150
185
  readonly readiness: "warn";
151
186
  readonly warnMessage: string;
152
187
  readonly label: string;
@@ -159,6 +194,8 @@ export interface WarnJobStep<Requirements = never, Output = never> {
159
194
  export interface ErrorJobStep {
160
195
  readonly key?: string;
161
196
  readonly dependsOn?: ReadonlyArray<string>;
197
+ /** Read-only inputs fingerprinted with this step, distinct from its write footprint. */
198
+ readonly materialPaths?: ReadonlyArray<string>;
162
199
  readonly readiness: "error";
163
200
  readonly errorMessage: string;
164
201
  readonly label: string;
@@ -184,7 +221,8 @@ export interface Job<Requirements = never, Output = never> {
184
221
  readonly concurrency: "unbounded" | number;
185
222
  /**
186
223
  * Defaults to ordered fail-fast execution. Use `best-effort` only when every
187
- * sibling step is independent; a failure still blocks subsequent jobs.
224
+ * sibling step is independent, including readiness failures; a failure still
225
+ * blocks subsequent jobs.
188
226
  */
189
227
  readonly executionPolicy?: JobExecutionPolicy;
190
228
  }
@@ -72,6 +72,15 @@ export const PlanRiskConditionSchema = Schema.Union([
72
72
  // Step result types
73
73
  // -----------------------------------------------------------------------------
74
74
  export const ArtifactMechanismSchema = Schema.Literals(["symlink", "copy"]);
75
+ /** Resolved manifest changes; null denotes an absent dependency. */
76
+ export const PackMembershipDeltaSchema = Schema.Struct({
77
+ pack: Schema.String,
78
+ members: Schema.Array(Schema.Union([
79
+ Schema.Struct({ member: Schema.String, before: Schema.Null, after: Schema.String }),
80
+ Schema.Struct({ member: Schema.String, before: Schema.String, after: Schema.Null }),
81
+ Schema.Struct({ member: Schema.String, before: Schema.String, after: Schema.String }),
82
+ ])),
83
+ });
75
84
  /** Presentation for an operation on one extension type (or extensions generally). */
76
85
  export const operationPresentation = (verb, type) => ({
77
86
  verb,
@@ -108,7 +108,10 @@ const outcomesFor = (ws, provider, configuredAgents, operation, state) => {
108
108
  /** The readiness blockers a plan's error steps contribute beyond declared conditions. */
109
109
  const readinessBlockersOf = (plan) => {
110
110
  const declaredConditionIds = new Set((plan.riskConditions ?? []).map((condition) => condition.id));
111
- return plan.jobs.flatMap((job) => job.steps.flatMap((step) => step.readiness === "error"
111
+ const hasRunnable = plan.jobs.some((job) => job.steps.some((step) => step.readiness !== "error"));
112
+ return plan.jobs
113
+ .filter((job) => !hasRunnable || job.executionPolicy !== "best-effort")
114
+ .flatMap((job) => job.steps.flatMap((step) => step.readiness === "error"
112
115
  ? (step.blockingConditionIds ?? []).length > 0 &&
113
116
  (step.blockingConditionIds ?? []).every((id) => declaredConditionIds.has(id))
114
117
  ? []
@@ -193,7 +196,10 @@ export const resolveExecutionCandidate = Effect.fn("resolveExecutionCandidate")(
193
196
  const candidatePlan = candidate.plan;
194
197
  const operations = candidate.configuredAgentOperations;
195
198
  const configuredAgents = operations.length === 0 ? [] : yield* ws.getConfiguredAgents();
196
- const readiness = scanPlanReadiness(candidatePlan);
199
+ const readiness = scanPlanReadiness({
200
+ ...candidatePlan,
201
+ jobs: candidatePlan.jobs.filter((job) => job.executionPolicy !== "best-effort"),
202
+ });
197
203
  const readinessBlockers = readinessBlockersOf(candidatePlan);
198
204
  const riskConditions = candidatePlan.riskConditions ?? [];
199
205
  const atomicity = declaredAtomicity(candidatePlan);
package/package.json CHANGED
@@ -4,36 +4,33 @@
4
4
  "url": "https://github.com/agentxm/axm/issues"
5
5
  },
6
6
  "dependencies": {
7
- "@agentxm/extension-model": "^0.29.2",
8
- "@agentxm/extension-resolution": "^0.29.2",
9
- "@agentxm/registry-protocol": "^0.29.2",
10
- "@agentxm/workspace-state": "^0.29.2",
11
- "@agentxm/workspace-transactions": "^0.29.2",
7
+ "@agentxm/extension-model": "^0.30.1",
8
+ "@agentxm/extension-resolution": "^0.30.1",
9
+ "@agentxm/registry-protocol": "^0.30.1",
10
+ "@agentxm/workspace-state": "^0.30.1",
11
+ "@agentxm/workspace-transactions": "^0.30.1",
12
12
  "effect": "4.0.0-rc.115"
13
13
  },
14
14
  "description": "AXM workspace operations: plans, execution candidates, closure execution, and operation resolutions for the axm CLI. Unstable and unsupported — use the axm.sh CLI.",
15
15
  "devDependencies": {
16
- "@agentxm/specification-metadata": "^0.29.2",
16
+ "@agentxm/specification-metadata": "^0.30.1",
17
17
  "@effect/platform-node": "4.0.0-rc.115",
18
18
  "@effect/vitest": "4.0.0-rc.115",
19
19
  "@typescript/native": "npm:typescript@^7.0.2",
20
20
  "typescript": "npm:@typescript/typescript6@^6.0.2",
21
- "vitest": "^5.0.0",
22
- "yaml": "^2.9.0"
21
+ "vitest": "^5.0.0"
23
22
  },
24
23
  "engines": {
25
24
  "node": ">=22.19.0"
26
25
  },
27
26
  "exports": {
28
27
  ".": {
29
- "axm-source": "./src/index.ts",
30
- "default": "./dist/src/index.js",
31
- "types": "./dist/src/index.d.ts"
28
+ "types": "./dist/src/index.d.ts",
29
+ "default": "./dist/src/index.js"
32
30
  },
33
31
  "./testing": {
34
- "axm-source": "./src/testing.ts",
35
- "default": "./dist/src/testing.js",
36
- "types": "./dist/src/testing.d.ts"
32
+ "types": "./dist/src/testing.d.ts",
33
+ "default": "./dist/src/testing.js"
37
34
  }
38
35
  },
39
36
  "files": [
@@ -56,5 +53,5 @@
56
53
  },
57
54
  "sideEffects": false,
58
55
  "type": "module",
59
- "version": "0.29.2"
56
+ "version": "0.30.1"
60
57
  }