@orchestraworks/cli 0.5.1 → 0.5.3

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.
Files changed (112) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/api/compute-provider-check.d.ts +29 -0
  3. package/dist/cli/api/compute-provider-check.js +207 -0
  4. package/dist/cli/api/tail.d.ts +66 -0
  5. package/dist/cli/api/tail.js +564 -0
  6. package/dist/cli/main.d.ts +5 -1
  7. package/dist/cli/main.js +22 -0
  8. package/dist/constructs/agent.d.ts +10 -0
  9. package/dist/constructs/agent.js +39 -4
  10. package/dist/constructs/environment.d.ts +29 -1
  11. package/dist/constructs/environment.js +28 -1
  12. package/dist/constructs/skill.d.ts +6 -1
  13. package/dist/constructs/skill.js +21 -2
  14. package/dist/engine/reconcile.js +15 -1
  15. package/dist/generated/cli-commands.json +876 -1
  16. package/dist/generated/managed-skills.d.ts +2 -0
  17. package/dist/generated/managed-skills.js +13 -0
  18. package/dist/index.d.ts +1 -1
  19. package/docs/REFERENCE.md +21 -1
  20. package/node_modules/@orchestraworks/client/dist/esm/models/ApiKey.d.ts +6 -0
  21. package/node_modules/@orchestraworks/client/dist/esm/models/ApiKey.js +2 -0
  22. package/node_modules/@orchestraworks/client/dist/esm/models/ComputeProvider.d.ts +3 -3
  23. package/node_modules/@orchestraworks/client/dist/esm/models/CreateApiKeyRequest.d.ts +7 -1
  24. package/node_modules/@orchestraworks/client/dist/esm/models/CreateApiKeyRequest.js +2 -0
  25. package/node_modules/@orchestraworks/client/dist/esm/models/CreateEnvironmentRequest.d.ts +13 -0
  26. package/node_modules/@orchestraworks/client/dist/esm/models/CreateEnvironmentRequest.js +5 -0
  27. package/node_modules/@orchestraworks/client/dist/esm/models/Environment.d.ts +13 -0
  28. package/node_modules/@orchestraworks/client/dist/esm/models/Environment.js +5 -0
  29. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentHook.d.ts +38 -0
  30. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentHook.js +45 -0
  31. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentHooks.d.ts +39 -0
  32. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentHooks.js +44 -0
  33. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentHooksRequest.d.ts +39 -0
  34. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentHooksRequest.js +44 -0
  35. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentProvisionSpec.d.ts +2 -1
  36. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentProvisionSpecRequest.d.ts +2 -1
  37. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentSnapshot.d.ts +19 -0
  38. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentSnapshot.js +7 -0
  39. package/node_modules/@orchestraworks/client/dist/esm/models/Machine.d.ts +7 -1
  40. package/node_modules/@orchestraworks/client/dist/esm/models/Machine.js +2 -0
  41. package/node_modules/@orchestraworks/client/dist/esm/models/UpdateEnvironmentRequest.d.ts +13 -0
  42. package/node_modules/@orchestraworks/client/dist/esm/models/UpdateEnvironmentRequest.js +5 -0
  43. package/node_modules/@orchestraworks/client/dist/esm/models/index.d.ts +3 -0
  44. package/node_modules/@orchestraworks/client/dist/esm/models/index.js +3 -0
  45. package/node_modules/@orchestraworks/client/dist/models/ApiKey.d.ts +6 -0
  46. package/node_modules/@orchestraworks/client/dist/models/ApiKey.js +2 -0
  47. package/node_modules/@orchestraworks/client/dist/models/ComputeProvider.d.ts +3 -3
  48. package/node_modules/@orchestraworks/client/dist/models/CreateApiKeyRequest.d.ts +7 -1
  49. package/node_modules/@orchestraworks/client/dist/models/CreateApiKeyRequest.js +2 -0
  50. package/node_modules/@orchestraworks/client/dist/models/CreateEnvironmentRequest.d.ts +13 -0
  51. package/node_modules/@orchestraworks/client/dist/models/CreateEnvironmentRequest.js +5 -0
  52. package/node_modules/@orchestraworks/client/dist/models/Environment.d.ts +13 -0
  53. package/node_modules/@orchestraworks/client/dist/models/Environment.js +5 -0
  54. package/node_modules/@orchestraworks/client/dist/models/EnvironmentHook.d.ts +38 -0
  55. package/node_modules/@orchestraworks/client/dist/models/EnvironmentHook.js +52 -0
  56. package/node_modules/@orchestraworks/client/dist/models/EnvironmentHooks.d.ts +39 -0
  57. package/node_modules/@orchestraworks/client/dist/models/EnvironmentHooks.js +51 -0
  58. package/node_modules/@orchestraworks/client/dist/models/EnvironmentHooksRequest.d.ts +39 -0
  59. package/node_modules/@orchestraworks/client/dist/models/EnvironmentHooksRequest.js +51 -0
  60. package/node_modules/@orchestraworks/client/dist/models/EnvironmentProvisionSpec.d.ts +2 -1
  61. package/node_modules/@orchestraworks/client/dist/models/EnvironmentProvisionSpecRequest.d.ts +2 -1
  62. package/node_modules/@orchestraworks/client/dist/models/EnvironmentSnapshot.d.ts +19 -0
  63. package/node_modules/@orchestraworks/client/dist/models/EnvironmentSnapshot.js +7 -0
  64. package/node_modules/@orchestraworks/client/dist/models/Machine.d.ts +7 -1
  65. package/node_modules/@orchestraworks/client/dist/models/Machine.js +2 -0
  66. package/node_modules/@orchestraworks/client/dist/models/UpdateEnvironmentRequest.d.ts +13 -0
  67. package/node_modules/@orchestraworks/client/dist/models/UpdateEnvironmentRequest.js +5 -0
  68. package/node_modules/@orchestraworks/client/dist/models/index.d.ts +3 -0
  69. package/node_modules/@orchestraworks/client/dist/models/index.js +3 -0
  70. package/node_modules/@orchestraworks/client/package.json +1 -1
  71. package/package.json +4 -4
  72. package/skills/orchestra/SKILL.md +167 -42
  73. package/skills/orchestra-fdk/SKILL.md +112 -545
  74. package/skills/orchestra-fdk/references/authoring.md +130 -3
  75. package/skills/orchestra-fdk/references/environment.md +352 -43
  76. package/skills/orchestra-fdk/references/integrations/analytics.md +18 -0
  77. package/skills/orchestra-fdk/references/integrations/ci-cd.md +20 -0
  78. package/skills/orchestra-fdk/references/integrations/cloud.md +19 -0
  79. package/skills/orchestra-fdk/references/integrations/code-repo.md +76 -0
  80. package/skills/orchestra-fdk/references/integrations/databases.md +22 -0
  81. package/skills/orchestra-fdk/references/integrations/dependencies.md +29 -0
  82. package/skills/orchestra-fdk/references/integrations/design.md +18 -0
  83. package/skills/orchestra-fdk/references/integrations/feature-flags.md +19 -0
  84. package/skills/orchestra-fdk/references/integrations/incident.md +29 -0
  85. package/skills/orchestra-fdk/references/integrations/issue-tracker.md +65 -0
  86. package/skills/orchestra-fdk/references/integrations/knowledge-base.md +43 -0
  87. package/skills/orchestra-fdk/references/integrations/messaging.md +38 -0
  88. package/skills/orchestra-fdk/references/integrations/observability.md +36 -0
  89. package/skills/orchestra-fdk/references/integrations/secrets-managers.md +25 -0
  90. package/skills/orchestra-fdk/references/integrations/support-desk.md +31 -0
  91. package/skills/orchestra-fdk/references/phases/0-start.md +62 -0
  92. package/skills/orchestra-fdk/references/phases/1-discover.md +111 -0
  93. package/skills/orchestra-fdk/references/phases/2-plan.md +157 -0
  94. package/skills/orchestra-fdk/references/phases/3-connect.md +99 -0
  95. package/skills/orchestra-fdk/references/phases/4-build.md +159 -0
  96. package/skills/orchestra-fdk/references/phases/5-prove.md +107 -0
  97. package/skills/orchestra-fdk/references/phases/6-handover.md +42 -0
  98. package/skills/orchestra-fdk/references/troubleshooting.md +128 -0
  99. package/templates/bug-fix/agents/bugfix.md +1 -1
  100. package/templates/bug-fix/main.ts +1 -1
  101. package/templates/engineering-team/README.md +45 -181
  102. package/templates/engineering-team/agents/engineer-agent.md +10 -7
  103. package/templates/engineering-team/agents/manager-agent.md +23 -120
  104. package/templates/engineering-team/inputs.json +1 -3
  105. package/templates/engineering-team/lib/environment.ts +10 -90
  106. package/templates/engineering-team/lib/inputs.ts +5 -97
  107. package/templates/engineering-team/lib/setup.sh +5 -5
  108. package/templates/engineering-team/main.ts +22 -69
  109. package/templates/todo-factory/agents/bugfix.md +1 -1
  110. package/templates/todo-factory/main.ts +1 -1
  111. package/templates/engineering-team/agents/engineer-bare.md +0 -22
  112. package/templates/engineering-team/onboarding/create-score-metrics.sh +0 -33
@@ -20,6 +20,7 @@ exports.EnvironmentSnapshotFromJSONTyped = EnvironmentSnapshotFromJSONTyped;
20
20
  exports.EnvironmentSnapshotToJSON = EnvironmentSnapshotToJSON;
21
21
  exports.EnvironmentSnapshotToJSONTyped = EnvironmentSnapshotToJSONTyped;
22
22
  const EnvironmentIngressPolicy_1 = require("./EnvironmentIngressPolicy");
23
+ const EnvironmentHooks_1 = require("./EnvironmentHooks");
23
24
  const EnvironmentVolumeMount_1 = require("./EnvironmentVolumeMount");
24
25
  const EnvironmentEgressPolicy_1 = require("./EnvironmentEgressPolicy");
25
26
  const EnvironmentDisk_1 = require("./EnvironmentDisk");
@@ -90,6 +91,9 @@ function EnvironmentSnapshotFromJSONTyped(json, ignoreDiscriminator) {
90
91
  'keepAliveWhenIdle': json['keepAliveWhenIdle'],
91
92
  'ttl': json['ttl'] == null ? undefined : json['ttl'],
92
93
  'shutdownGracePeriodSeconds': json['shutdownGracePeriodSeconds'] == null ? undefined : json['shutdownGracePeriodSeconds'],
94
+ 'workingDirectory': json['workingDirectory'] == null ? undefined : json['workingDirectory'],
95
+ 'hooks': json['hooks'] == null ? undefined : (0, EnvironmentHooks_1.EnvironmentHooksFromJSON)(json['hooks']),
96
+ 'setupTimeoutSeconds': json['setupTimeoutSeconds'] == null ? undefined : json['setupTimeoutSeconds'],
93
97
  };
94
98
  }
95
99
  function EnvironmentSnapshotToJSON(json) {
@@ -119,5 +123,8 @@ function EnvironmentSnapshotToJSONTyped(value, ignoreDiscriminator = false) {
119
123
  'keepAliveWhenIdle': value['keepAliveWhenIdle'],
120
124
  'ttl': value['ttl'],
121
125
  'shutdownGracePeriodSeconds': value['shutdownGracePeriodSeconds'],
126
+ 'workingDirectory': value['workingDirectory'],
127
+ 'hooks': (0, EnvironmentHooks_1.EnvironmentHooksToJSON)(value['hooks']),
128
+ 'setupTimeoutSeconds': value['setupTimeoutSeconds'],
122
129
  };
123
130
  }
@@ -43,11 +43,17 @@ export interface Machine {
43
43
  */
44
44
  environmentId: string;
45
45
  /**
46
- * Compute registration key this machine launched on
46
+ * The internal registration key this machine launched on, for operators; computeProviderId names the compute provider
47
47
  * @type {string}
48
48
  * @memberof Machine
49
49
  */
50
50
  computeProviderKey: string;
51
+ /**
52
+ * The compute provider this machine runs on: cprov_orchestra on hosted compute, or the self-hosted record whose Launcher runs it. Absent on a customer's own enrolled machine
53
+ * @type {string}
54
+ * @memberof Machine
55
+ */
56
+ computeProviderId?: string;
51
57
  /**
52
58
  * Compute-provider instance id
53
59
  * @type {string}
@@ -105,6 +105,7 @@ function MachineFromJSONTyped(json, ignoreDiscriminator) {
105
105
  'organizationId': json['organizationId'],
106
106
  'environmentId': json['environmentId'],
107
107
  'computeProviderKey': json['computeProviderKey'],
108
+ 'computeProviderId': json['computeProviderId'] == null ? undefined : json['computeProviderId'],
108
109
  'computeProviderInstanceId': json['computeProviderInstanceId'] == null ? undefined : json['computeProviderInstanceId'],
109
110
  'status': json['status'],
110
111
  'reason': json['reason'] == null ? undefined : json['reason'],
@@ -141,6 +142,7 @@ function MachineToJSONTyped(value, ignoreDiscriminator = false) {
141
142
  'organizationId': value['organizationId'],
142
143
  'environmentId': value['environmentId'],
143
144
  'computeProviderKey': value['computeProviderKey'],
145
+ 'computeProviderId': value['computeProviderId'],
144
146
  'computeProviderInstanceId': value['computeProviderInstanceId'],
145
147
  'status': value['status'],
146
148
  'reason': value['reason'],
@@ -13,6 +13,7 @@ import type { EnvironmentIngressPolicy } from './EnvironmentIngressPolicy';
13
13
  import type { EnvironmentPlatformRequest } from './EnvironmentPlatformRequest';
14
14
  import type { EnvironmentEgressPolicy } from './EnvironmentEgressPolicy';
15
15
  import type { EnvironmentProvisionSpecRequest } from './EnvironmentProvisionSpecRequest';
16
+ import type { EnvironmentHooksRequest } from './EnvironmentHooksRequest';
16
17
  /**
17
18
  *
18
19
  * @export
@@ -49,6 +50,18 @@ export interface UpdateEnvironmentRequest {
49
50
  * @memberof UpdateEnvironmentRequest
50
51
  */
51
52
  provisionSpec?: EnvironmentProvisionSpecRequest;
53
+ /**
54
+ * The absolute folder every conversation's agent starts in, on every kind: a path starting with / on linux and macos, and a drive or UNC path on windows, at most 1024 characters. A machine keeps the value it was created with. The worker creates the folder when it is missing, owned by the account the agent runs as, and an agent placement whose folder cannot be created or entered fails. Absent, the agent starts in the worker's own folder for its harness. On an update, absent leaves the stored value and an empty one clears it.
55
+ * @type {string}
56
+ * @memberof UpdateEnvironmentRequest
57
+ */
58
+ workingDirectory?: string;
59
+ /**
60
+ * Scripts the worker runs at points of a machine's and an agent's life. onStartMachine and onStartAgent are built; onStartSession, onStopSession, onStopAgent and onStopMachine are reserved. On an update, an absent object or member leaves the stored hook.
61
+ * @type {EnvironmentHooksRequest}
62
+ * @memberof UpdateEnvironmentRequest
63
+ */
64
+ hooks?: EnvironmentHooksRequest;
52
65
  /**
53
66
  * Labels: the customer's key-to-value tags; the platform reads no key. Merged into the stored labels as a JSON Merge Patch: absent leaves them, a key with a string sets it, a key with null removes it, and null removes them all
54
67
  * @type {{ [key: string]: string | null; }}
@@ -22,6 +22,7 @@ const EnvironmentIngressPolicy_1 = require("./EnvironmentIngressPolicy");
22
22
  const EnvironmentPlatformRequest_1 = require("./EnvironmentPlatformRequest");
23
23
  const EnvironmentEgressPolicy_1 = require("./EnvironmentEgressPolicy");
24
24
  const EnvironmentProvisionSpecRequest_1 = require("./EnvironmentProvisionSpecRequest");
25
+ const EnvironmentHooksRequest_1 = require("./EnvironmentHooksRequest");
25
26
  /**
26
27
  * Check if a given object implements the UpdateEnvironmentRequest interface.
27
28
  */
@@ -41,6 +42,8 @@ function UpdateEnvironmentRequestFromJSONTyped(json, ignoreDiscriminator) {
41
42
  'egressPolicy': json['egressPolicy'] == null ? undefined : (0, EnvironmentEgressPolicy_1.EnvironmentEgressPolicyFromJSON)(json['egressPolicy']),
42
43
  'ingressPolicy': json['ingressPolicy'] == null ? undefined : (0, EnvironmentIngressPolicy_1.EnvironmentIngressPolicyFromJSON)(json['ingressPolicy']),
43
44
  'provisionSpec': json['provisionSpec'] == null ? undefined : (0, EnvironmentProvisionSpecRequest_1.EnvironmentProvisionSpecRequestFromJSON)(json['provisionSpec']),
45
+ 'workingDirectory': json['workingDirectory'] == null ? undefined : json['workingDirectory'],
46
+ 'hooks': json['hooks'] == null ? undefined : (0, EnvironmentHooksRequest_1.EnvironmentHooksRequestFromJSON)(json['hooks']),
44
47
  'labels': json['labels'] == null ? undefined : json['labels'],
45
48
  };
46
49
  }
@@ -57,6 +60,8 @@ function UpdateEnvironmentRequestToJSONTyped(value, ignoreDiscriminator = false)
57
60
  'egressPolicy': (0, EnvironmentEgressPolicy_1.EnvironmentEgressPolicyToJSON)(value['egressPolicy']),
58
61
  'ingressPolicy': (0, EnvironmentIngressPolicy_1.EnvironmentIngressPolicyToJSON)(value['ingressPolicy']),
59
62
  'provisionSpec': (0, EnvironmentProvisionSpecRequest_1.EnvironmentProvisionSpecRequestToJSON)(value['provisionSpec']),
63
+ 'workingDirectory': value['workingDirectory'],
64
+ 'hooks': (0, EnvironmentHooksRequest_1.EnvironmentHooksRequestToJSON)(value['hooks']),
60
65
  'labels': value['labels'],
61
66
  };
62
67
  }
@@ -124,6 +124,9 @@ export * from './Environment';
124
124
  export * from './EnvironmentDisk';
125
125
  export * from './EnvironmentDiskMount';
126
126
  export * from './EnvironmentEgressPolicy';
127
+ export * from './EnvironmentHook';
128
+ export * from './EnvironmentHooks';
129
+ export * from './EnvironmentHooksRequest';
127
130
  export * from './EnvironmentIngressPolicy';
128
131
  export * from './EnvironmentMount';
129
132
  export * from './EnvironmentPlatform';
@@ -142,6 +142,9 @@ __exportStar(require("./Environment"), exports);
142
142
  __exportStar(require("./EnvironmentDisk"), exports);
143
143
  __exportStar(require("./EnvironmentDiskMount"), exports);
144
144
  __exportStar(require("./EnvironmentEgressPolicy"), exports);
145
+ __exportStar(require("./EnvironmentHook"), exports);
146
+ __exportStar(require("./EnvironmentHooks"), exports);
147
+ __exportStar(require("./EnvironmentHooksRequest"), exports);
145
148
  __exportStar(require("./EnvironmentIngressPolicy"), exports);
146
149
  __exportStar(require("./EnvironmentMount"), exports);
147
150
  __exportStar(require("./EnvironmentPlatform"), exports);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestraworks/client",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Orchestra public API TypeScript client",
5
5
  "author": "Living Computers",
6
6
  "repository": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestraworks/cli",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "type": "module",
5
5
  "description": "The Orchestra command line.",
6
6
  "license": "Apache-2.0",
@@ -109,13 +109,13 @@
109
109
  },
110
110
  "dependencies": {
111
111
  "@agentclientprotocol/sdk": "1.3.0",
112
- "@orchestraworks/client": "0.5.1",
113
- "@orchestraworks/worker": "0.0.136",
112
+ "@orchestraworks/client": "0.5.3",
113
+ "@orchestraworks/worker": "0.0.138",
114
114
  "commander": "^14.0.0",
115
115
  "liquidjs": "^10.28.0"
116
116
  },
117
117
  "optionalDependencies": {
118
- "@orchestraworks/local": "0.0.136"
118
+ "@orchestraworks/local": "0.0.138"
119
119
  },
120
120
  "bundleDependencies": [
121
121
  "@orchestraworks/client"
@@ -63,7 +63,7 @@ in a project may point at its own project or the shared space; a row in the shar
63
63
  shared space. So a shared agent takes items from every project, and an agent in a project takes items only
64
64
  from that project.
65
65
 
66
- **In the starter.** The organization has no project. Each of the five agents starts with `agent-worker`. The
66
+ **In the starter.** The organization has no project. Each of the four agents starts with `agent-worker`. The
67
67
  Manager Agent is then given `agent-manager`, because it works in every pipeline and changes the Engineer
68
68
  Agents.
69
69
 
@@ -78,7 +78,11 @@ Agents.
78
78
  claude, codex, pi, script, custom; fixed at create); docs/architecture/agent-skills-and-runtime-manifest.md:250-302
79
79
  (modelSettings; a running turn keeps its model, the next turn takes the new one);
80
80
  docs/architecture/agent-runtime-images.md:3 (one image carries the four harnesses). Starter: the kit branch's
81
- cli/templates/engineering-team/main.ts. -->
81
+ cli/templates/engineering-team/main.ts. Script agents: docs/architecture/api.md:1362-1368 (the five harness
82
+ values), :1398 (no model settings on script or custom); docs/architecture/agent-skills-and-runtime-manifest.md
83
+ § SCRIPT command and input (program from instructions, input on stdin, no skills); agent-runtime-images.md:862-872
84
+ (bash on Linux, PowerShell on Windows); docs/architecture/events-and-triggers.md:146-154 (a schedule trigger
85
+ targets a pipeline); factory/main.ts, the archivist (schedule, pipeline, assign rule, script agent). -->
82
86
 
83
87
  **What it is.** An *agent* is a worker with a name, standing *instructions*, one environment, a harness, a
84
88
  model, and the skills and files it uses. The *harness* is the coding program that runs the agent on a machine:
@@ -89,9 +93,34 @@ model the harness calls, set in the agent's model settings.
89
93
  the model gateway when its model settings turn the gateway on (section 7). Work reaches it as sessions (section
90
94
  8), most often started by assigning it a work item (section 10).
91
95
 
92
- **In the starter.** The Manager Agent, Engineer Agent lg and Engineer Agent bare run `claude` on
93
- `claude-opus-5-5`. Engineer Agent md runs `codex` on `gpt-6.1-sol`, and Engineer Agent sm runs `codex` on
94
- `gpt-6-luna`. Engineer Agent bare takes only the Bootstrap's baseline replays.
96
+ **In the starter.** The Manager Agent and Engineer Agent lg run `claude` on `claude-opus-5-5`. Engineer
97
+ Agent md runs `codex` on `gpt-6.1-sol`, and Engineer Agent sm runs `codex` on `gpt-6-luna`. Work goes to
98
+ Engineer Agent lg first. Engineer Agent sm and md get work only once a person says a kind of work may go
99
+ to them.
100
+
101
+ **The harnesses.** `harness` is set once, when the agent is created.
102
+
103
+ | Harness | Runs | Model |
104
+ |---|---|---|
105
+ | `claude` | Claude Code | Yes, from the agent's model settings |
106
+ | `codex` | Codex | Yes, from the agent's model settings |
107
+ | `pi` | The pi coding agent | Yes, from the agent's model settings |
108
+ | `script` | The agent's instructions, as a shell program: Bash on Linux, PowerShell on Windows | No |
109
+ | `custom` | Nothing: the machine runs the customer's own image, and the platform starts no harness | No |
110
+
111
+ **A `script` agent** is for deterministic work that needs no model judgment: pulling data from Pendo or
112
+ another analytics source into the platform's custom metrics (`orchestra metrics write-value`), joining data
113
+ across systems, a scheduled sync, or a docs archive run. Its instructions are the program. Each turn's text
114
+ reaches the program on its standard input. It starts like any agent:
115
+
116
+ - a work item assigned to it, by a person or by a workflow rule;
117
+ - a trigger on a connection's events, with the agent as the target;
118
+ - a schedule: a trigger on a 5-field UTC cron makes a work item in a pipeline, and a rule assigns the item
119
+ to the agent. A schedule trigger targets a pipeline, never an agent directly.
120
+
121
+ A `script` agent cannot use skills or model settings (the platform refuses both with a 400), and it cannot
122
+ judge, read or write prose the way a model does. A turn runs its whole program again, so the program must be
123
+ safe to run twice. It is billed as an agent: **Settings › Plan & usage** shows the plan.
95
124
 
96
125
  **Cannot yet.**
97
126
  - Change an agent's harness after it is created. Make a new agent instead.
@@ -137,12 +166,24 @@ disks on Windows). -->
137
166
  ports, settings and network rules. A *machine* is one live computer made from it, where an agent works. A
138
167
  machine carries one agent.
139
168
 
140
- - *Size.* CPU and memory, from a fixed ladder: 0.5, 1, 2, 4, 8, 16 or 32 CPU, with 2 GB of memory per CPU.
141
- - *Image.* The disk the machine starts from. The stock image is Debian with Node 22, Java 21 and 25, git,
142
- Docker with Compose, `gh` and `acli`, and all four harnesses.
169
+ - *Runtime* (`platform.runtime`). `microvm` (the default) or `vm`, with the operating system and the
170
+ architecture. It is fixed when the environment is created. To change it, make a new environment.
171
+ - *Size.* CPU and memory, with 2 GB of memory per CPU. A `microvm` takes 0.5, 1, 2, 4, 8, 16 or 32 CPU. A
172
+ Linux `vm` takes 2, 4 or 8 CPU. A Windows `vm` takes 4 or 8 CPU.
173
+ - *Image.* The disk the machine starts from. The stock `microvm` image is Debian with Node 24, Java 21 and
174
+ 25, Python 3, a C and C++ build toolchain, git, `jq`, Docker with Compose and Buildx, the worker and all
175
+ four harnesses. The agent installs any other tool it needs. The orchestra-fdk skill's
176
+ `references/environment.md`, section 5, has each operating system's image.
143
177
  - *Setup script.* A script that runs once, as root, on each new machine, before the agent arrives and before
144
- any code is cloned. Bash on Linux, PowerShell on Windows. At most 64 KiB, stopped after 10 minutes. A failed
145
- script fails the machine. Its output is kept as is, so it must never print a secret.
178
+ any code is cloned. Bash on Linux, PowerShell on Windows. At most 64 KiB. After 10 minutes the worker
179
+ kills it with every process it started, and the machine fails. A failed script fails the machine. Its
180
+ output is kept as is, so it must never print a secret. A process the script starts in the background keeps
181
+ running after the script ends, until the machine stops. Write the script so that it can run again on a
182
+ new machine, over a `/home` that already has files.
183
+ - *Network edge certificate.* The edge re-signs each HTTPS answer with its own certificate authority. The
184
+ worker adds it to the machine's trust store, and points `NODE_EXTRA_CA_CERTS`, `SSL_CERT_FILE`,
185
+ `REQUESTS_CA_BUNDLE` and `GIT_SSL_CAINFO` at its file for the setup script and the harness. A tool with a
186
+ certificate list of its own, such as Git for Windows, needs that file added.
146
187
  - *Settings* (`env`). Plain values set on every machine. They are stored and shown in plain text, so a key
147
188
  never goes here (section 6).
148
189
  - *Ports.* Each declared port gets a *machine endpoint*, a web address that only signed-in members of the
@@ -151,16 +192,31 @@ machine carries one agent.
151
192
  - *Working folder* (`workingDirectory`). Not released yet: a folder where the harness starts every
152
193
  conversation. Today the agent clones or uses its code under `/work` in its own first turn, as the
153
194
  starter's agents do.
154
- - *Lifetime.* A conversation lets go of its machine 5 minutes after its last turn, and a machine lives at
155
- most 2 hours, unless the environment sets other values.
195
+ - *Lifetime.* Three values in the environment's `provisionSpec`, in seconds:
196
+ - `ttlAfterIdle`, 300 by default. A conversation lets go of its machine this long after its last turn.
197
+ The machine then stops within about one more minute. Work the harness itself runs in the background,
198
+ such as a background shell, holds the machine until it ends.
199
+ - `keepAliveWhenIdle`, false by default. `true` turns the idle stop off.
200
+ - `ttl`, 7200 (2 hours) by default. The most a machine lives, counted from its creation, idle, running or
201
+ stopped. The plan can make it shorter. A turn still running at that time is stopped.
202
+ - *What a stop does.* It depends on where the machine runs:
203
+ - Hosted Linux, `microvm` and `vm`: the machine is deleted. A `/home` volume stays. The next turn gets a
204
+ new machine, which runs the setup script again.
205
+ - Hosted Windows `vm`, and a VM that a Launcher runs: the machine is *parked*. The VM stops and keeps its
206
+ disk. The next turn, or a new conversation of the same agent, starts the same VM. The setup script does
207
+ not run again. After `ttl` the machine is deleted, and the next turn gets a new one.
208
+ - A stop ends every process on the machine. An install the agent left running outside the harness, or one
209
+ the setup script started, is killed. Run a long install in the turn itself.
210
+ - The kit cannot declare the three values yet. Set them with `orchestra environments update <slug> --body
211
+ @timers.json`, where the file holds `{"provisionSpec":{"ttl":<seconds>}}` and the others you change. An
212
+ apply sends none of the three, so it keeps the values you set.
156
213
 
157
214
  **How it relates.** An agent names one environment. A change to the image, size, setup script, settings or
158
215
  disks reaches only machines made after the change. A change to the network rules is different: it reaches
159
216
  running machines too (section 5).
160
217
 
161
218
  **In the starter.** Four environments: `manager-work-lg` and `engineer-work-lg` at 32 CPU, `engineer-work-md`
162
- at 16, `engineer-work-sm` at 2. Engineer Agent bare uses `engineer-work-lg` with Engineer Agent lg; each agent
163
- still gets its own machines. Each uses the stock image, starts Docker in `lib/setup.sh`, and keeps Docker's
219
+ at 16, `engineer-work-sm` at 2. Each uses the stock image, starts Docker in `lib/setup.sh`, and keeps Docker's
164
220
  data on its own disk.
165
221
 
166
222
  **Can.**
@@ -173,6 +229,13 @@ data on its own disk.
173
229
  team owns and the Orchestra runtime image as its base, which is handed over by hand.
174
230
  - macOS machines that Orchestra launches. A Mac works only as the team's own enrolled machine (section 18).
175
231
  - Extra disks on Windows or on an enrolled machine.
232
+ - A launched Windows machine on Windows 11, or on any version other than Windows Server 2025. A customer's
233
+ Windows image must carry our
234
+ worker, installed as our Windows runtime assembly installs it (`install-vm-runtime.ps1`, which ends with
235
+ `orchestra install --role image --yes`). A plain captured Windows VM does not register.
236
+ - Not released yet: a one-command installer that turns a customer's own Windows image into one Orchestra can
237
+ run. What such an image carries today: the orchestra-fdk skill's `references/environment.md`, "Windows in
238
+ three stages", stage 2.
176
239
  - Not proven yet: the 32 CPU size on production capacity. If an lg machine waits a long time for room, tell the
177
240
  Orchestra team.
178
241
 
@@ -186,8 +249,8 @@ rules); docs/architecture/egress.md:59 (the machine's shim holds no policy cache
186
249
  cli/src/constructs/environment.ts:231 (deny rules default to priority 900), allowAll, denyAll, allow, deny,
187
250
  routeModelsViaGateway, bearer, basic, header, inject; cli/templates/bug-fix/image/setup.sh (the Docker start);
188
251
  support.atlassian.com/bitbucket-cloud/docs/using-api-tokens (Bearer for the API, Basic with
189
- x-bitbucket-api-token-auth for git). Starter: the kit branch's cli/templates/engineering-team/README.md
190
- "Commissioning". -->
252
+ x-bitbucket-api-token-auth for git). Starter: cli/templates/engineering-team/README.md, "Every
253
+ machine". -->
191
254
 
192
255
  **What it's for.** The agent works as if it had full access. Control lives outside the machine, at the network
193
256
  edge: which sites a machine may reach, and which keys are added on the way. The agent never holds those keys.
@@ -204,13 +267,12 @@ unless you set one, so it wins over the open default and over the usual allow ru
204
267
  reaches every machine at once, machines already running included, from their next request.
205
268
 
206
269
  **How it relates.** An allow rule can add a secret to matching requests (section 6). Calls to the Orchestra
207
- platform itself skip these rules: the agent's role decides them (section 1). So a machine blocked from Bitbucket
208
- still downloads a file through `orchestra files get-content`.
270
+ platform itself skip these rules: the agent's role decides them (section 1). So a machine blocked from the
271
+ code host still downloads a file through `orchestra files get-content`.
209
272
 
210
- **In the starter.** Every machine is open, and adds the gateway key on the model gateway's host. The Manager
211
- Agent's machine adds the Bitbucket and Jira tokens. The Engineer Agents' machines deny Bitbucket and the Jira
212
- site until *commissioning*, when they start real work: then `access: "tokens"` in `main.ts` swaps the deny rules
213
- for the token rules. Apply that change only when no replay is running, because it reaches running machines.
273
+ **In the starter.** Every machine is open to every host, and adds the gateway key on the model gateway's
274
+ host. The starter connects no code host or tracker. A rule added for one later still adds its key: the open
275
+ default allows a host only when no rule matches it.
214
276
 
215
277
  **Can.** Deny rules by host, path and method; keys added as `Bearer <secret>`, `Basic <secret>`, the bare
216
278
  secret in any header, or a full header recipe; Basic auth formed from a user name and a secret
@@ -235,8 +297,7 @@ edge*.
235
297
  **How it relates.** A secret works only through a network rule (section 5). Never put a key in an
236
298
  environment's settings or in instructions: the machine's processes read every setting.
237
299
 
238
- **In the starter.** The gateway key's secret, and once connected, the Bitbucket token (twice: once for the API,
239
- once for git) and the Jira token.
300
+ **In the starter.** The gateway key's secret only.
240
301
 
241
302
  **Can.** A secret's value comes from a shell variable at apply (`fromEnv`), from a hidden prompt at apply on a
242
303
  terminal (`fromCommandLine`), or from a gateway key the platform mints (`fromGatewayKey`).
@@ -265,7 +326,10 @@ network rules carry the option (sections 2 and 5).
265
326
  are plain text.
266
327
  - *Codex.* A personal access token, made by a ChatGPT Business or Enterprise member, or a separate ChatGPT
267
328
  sign-in kept on a `/home` volume that every machine using it shares. A Codex sign-in stays off the model
268
- gateway, which refuses its requests with `model_not_found`.
329
+ gateway, which refuses its requests with `model_not_found`. The Codex sign-in goes in the
330
+ `ORCHESTRA_WORKER_CODEX_` variables in the environment's `env`, in plain text. The worker writes them into
331
+ Codex's own sign-in file and passes none of them on (the orchestra-fdk skill's `references/authoring.md`,
332
+ "The subscription variables").
269
333
 
270
334
  **An Orchestra account, through the model gateway.** The model gateway is a hosted service at
271
335
  `models.orchestraworks.ai`. One endpoint reaches OpenAI, Anthropic and open models. A *gateway key* is a key
@@ -288,13 +352,11 @@ subscription or its own key turns it off. For plan questions, send the person to
288
352
  in the console.
289
353
 
290
354
  **In the starter.** The code as written uses the model gateway: one key, `model-gateway`, and the gateway rule
291
- on every environment. A subscription or an own key needs an edit, as the orchestra-fdk skill's step 6 says.
355
+ on every environment. A subscription or an own key needs an edit, as the orchestra-fdk skill's phase 2 says.
292
356
 
293
357
  **Cannot yet.**
294
358
  - A gateway route without the rule on the environment. An environment declared in code keeps only what it
295
359
  declares, so the rule must be on every environment.
296
- - Not released yet: the worker settings that put a Codex sign-in on a machine. Until they are, a `codex`
297
- agent uses the model gateway or an OpenAI API key.
298
360
 
299
361
  ## 8. Session and turn
300
362
 
@@ -315,7 +377,7 @@ message. Interrupt stops the running turn, not the conversation.
315
377
  **How it relates.** Assigning an agent a work item starts its session on the item, or wakes its open one
316
378
  (section 10). A trigger can also start one (section 12). Each turn runs on a machine (section 4).
317
379
 
318
- **In the starter.** Assigning "Set up" to the Manager Agent starts its session. `orchestra sessions wait <session id>` waits
380
+ **In the starter.** Assigning an item to the Manager Agent starts its session. `orchestra sessions wait <session id>` waits
319
381
  for the turn to end. The console shows the same session.
320
382
 
321
383
  ## 9. Pipeline and stage
@@ -335,8 +397,9 @@ conditions an item must meet to enter it (`requires`), such as a passed check.
335
397
  **How it relates.** Work items live in pipelines (section 10). Workflow rules act on one pipeline's items
336
398
  (section 11). A trigger can create items in a pipeline (section 12).
337
399
 
338
- **In the starter.** Four pipelines: Onboarding (`onbd`), Bugs (`bug`), Features (`feat`) and Support (`supp`).
339
- An item may move from any stage to any other, for now.
400
+ **In the starter.** Three pipelines: Bugs (`bug`), Features (`feat`) and Support (`supp`). An item may move
401
+ from any stage to any other, for now. An agent moves an item to its review stage when it needs a person: In
402
+ review in Bugs and Features, Waiting on requester in Support.
340
403
 
341
404
  **Rule.** The platform refuses to delete a pipeline that still has open items, or that a trigger or workflow
342
405
  names. Close or move the items and remove those first.
@@ -361,8 +424,8 @@ and a stage's conditions can read them.
361
424
  **How it relates.** An item's sessions are listed on it (section 8). An agent can be asked about an item without
362
425
  taking it over (`work-items message`). Rules and judges act on items (section 11).
363
426
 
364
- **In the starter.** The Set up and Bootstrap items in Onboarding. In the Bootstrap, the Manager Agent creates
365
- Replay items and assigns them to Engineer Agent lg and Engineer Agent bare.
427
+ **In the starter.** A person creates an item and assigns it to the Manager Agent. The Manager Agent triages
428
+ it, puts the code bundle's file id in it, and assigns it to an Engineer Agent.
366
429
 
367
430
  **Cannot yet.** Declare items in the factory code. Create them with `orchestra work-items create`.
368
431
 
@@ -404,7 +467,7 @@ conversation.
404
467
  **How it relates.** It listens through a connection (section 17), and makes items (section 10) or sessions
405
468
  (section 8).
406
469
 
407
- **In the starter.** None yet. A tracker listener comes after commissioning.
470
+ **In the starter.** None yet. A tracker listener, which turns each new issue into an item, comes later.
408
471
 
409
472
  **Cannot yet.** A tracker board that sends no events makes no items. Confirm events reach the platform before
410
473
  switching a listener on.
@@ -431,8 +494,9 @@ Not released yet: managed skills that a new agent's list carries by default (`in
431
494
  carry work between agents.
432
495
 
433
496
  **In the starter.** The Manager Agent uploads each git
434
- bundle as a file, and the Engineer Agent answers with a patch file. The Bootstrap writes a codebase skill, and
435
- commissioning adds it to the Engineer Agents.
497
+ bundle as a file, and the Engineer Agent answers with a patch file. The Manager Agent makes a codebase skill
498
+ and names its slug. The team names that skill in `main.ts` for the Engineer Agents, or the next apply takes
499
+ it away.
436
500
 
437
501
  ## 14. Plan
438
502
 
@@ -497,6 +561,8 @@ each part at length. What follows is only what a reader needs to run a command s
497
561
  - **Nouns and verbs.** `orchestra <noun> <verb>`. Nouns match the API's paths, such as `agents`, `work-items`
498
562
  and `sessions`. The usual verbs are `list`, `get`, `create`, `update` and `delete`; a command keeps its own
499
563
  verb, such as `work-items assign`. `orchestra sessions wait <session id>` waits for a turn to end.
564
+ `orchestra sessions tail <session id>` prints each item of the session as it is saved, and
565
+ `--until-settled` stops it when the turn ends.
500
566
  - **Output.** `--output json` prints the API's answer as it is on stdout, with key values masked. Read the field
501
567
  you need from its place:
502
568
  - A list answers a page: `{"data":[…],"page":1,"limit":20,"total":42}`. The rows are in `data`.
@@ -554,18 +620,27 @@ the kit's reference, `docs/REFERENCE.md`, section 7, "Connections, triggers, and
554
620
 
555
621
  - Cannot yet: Bitbucket OAuth without an OAuth consumer the organization registers first.
556
622
  - Cannot yet: git over `bitbucket.org` through the Bitbucket connection. It adds its credential only on
557
- `api.bitbucket.org`, so git still needs the token rule.
558
- - In the starter: none. For the first run, personal tokens are enough. Connections and listeners come later.
623
+ `api.bitbucket.org`, so git needs a Secret and its own rule on `bitbucket.org`.
624
+ - In the starter: none. The first run needs no integration. The orchestra-fdk skill's
625
+ `references/integrations/` files say how to add each one.
559
626
 
560
627
  ## 18. The team's own machines and network
561
628
 
562
629
  <!-- Sources, on develop at 19459f9ebb: docs/architecture/compute-plane.md:134-166 (an enrolled machine: no
563
630
  network rules; which environments go there is the operator's choice); docs/architecture/api.md:1191 (enrolled
564
631
  kind); cli/src/constructs/environment.ts (the kit always sends provisionSpec, so it cannot declare an enrolled
565
- environment); no Launcher code or document on develop; docs/architecture/local-agent-runtime.md (the local
632
+ environment); on this branch: cli/src/constructs/compute-provider.ts and environment.ts (`computeProvider`),
633
+ docs/architecture/compute-plane.md:529-600 (three Launcher targets, all amd64; allow-only network rules; no
634
+ edge proxy in front of a Launcher machine; the gallery and runtime images), launcher/README.md and
635
+ launcher/deploy/azure/main.bicep (the Azure template, the public Launcher image); docs/architecture/local-agent-runtime.md (the local
566
636
  environment, its outpost kinds; no privileged machine launch); on develop at 09a3758669,
567
637
  local/launch/modelkey.go (model key carriers per harness, the gateway address variable) and
568
- worker/facts/families.json (how each harness takes the gateway address). -->
638
+ worker/facts/families.json (how each harness takes the gateway address); on develop at f62fad1481,
639
+ agents/runtime/assembly/common/placeholder-env (the images' placeholder ANTHROPIC_API_KEY),
640
+ LauncherProperties.kt (the gallery images at Versions/latest), launcher/config/config.go (Dsv5 default);
641
+ worker/facts/families.json (the ORCHESTRA_WORKER_ names), worker/service/manager_windows.go (SfdkWorker),
642
+ infra/packer/azure-windows-runtime.pkr.hcl (the startup task), launcher/cloud/cloud.go (the VM tags);
643
+ the proven list is the test run of 2026-10-05. -->
569
644
 
570
645
  - Can: enroll the team's own Mac, Linux or Windows machine with the worker (`orchestra outpost`, `orchestra worker
571
646
  enroll`). It runs agents, and its ports can still be shown as machine endpoints.
@@ -573,8 +648,58 @@ worker/facts/families.json (how each harness takes the gateway address). -->
573
648
  token rules do not work there, and the agent needs its own model sign-in and tokens on that machine. Which
574
649
  environments go to enrolled machines is set by the Orchestra team, not in code, and the kit cannot declare an
575
650
  enrolled environment.
576
- - Cannot yet: reach a private network (a VPN or the team's own cloud) from Orchestra's machines.
577
- - Cannot yet: the *Launcher*, which would run machines inside the team's own cloud, and Azure.
651
+ - Cannot yet: reach a private network (a VPN or the team's own cloud) from Orchestra's hosted machines. A
652
+ Launcher (below) runs the machines inside the team's own Azure network instead.
653
+ - Can: the *Launcher* on Azure. It is a program the team runs in their own Azure subscription, from our
654
+ public image `orchestraworks.azurecr.io/launcher:0.1.0` and the template in `launcher/deploy/azure`. It
655
+ starts the machines of every environment that names its record. Declare the record with `ComputeProvider`
656
+ (its `azure` block names the subscriptions and, for pods, the AKS cluster's OIDC issuer), and name it in
657
+ the environment's `computeProvider`. It runs three kinds of machine, all amd64:
658
+ - `linux-vm`, for an environment with `{ os: "linux", runtime: "vm" }`: an Azure VM, parked when idle;
659
+ - `windows-vm`, for `{ os: "windows", runtime: "vm" }`: an Azure Windows VM, parked when idle;
660
+ - `kata-pod`, for `{ os: "linux", runtime: "microvm" }`: a Kata pod on the team's AKS cluster, deleted
661
+ when idle.
662
+ - Cannot yet, on a Launcher machine: a key added at the edge. No network edge of ours stands in front of
663
+ it, so its network rules may only allow. Not released yet: our network edge for machines in the team's
664
+ own network.
665
+ - Credentials on a Launcher machine are the team's to manage on the machine. The platform delivers none.
666
+ - The model sign-in goes in the worker service's own environment: `ORCHESTRA_WORKER_CLAUDE_OAUTH_TOKEN`
667
+ for a Claude subscription token; `ANTHROPIC_API_KEY` for an Anthropic API key or an Orchestra gateway
668
+ key, which replaces our image's placeholder; `ORCHESTRA_WORKER_OPENAI_API_KEY` or
669
+ `ORCHESTRA_WORKER_CODEX_PERSONAL_ACCESS_TOKEN` for `codex`. On Windows, that is the `SfdkWorker`
670
+ service's `Environment` registry value.
671
+ - With a gateway key, keep the agent's model gateway on. The platform sets the gateway address.
672
+ - Other tokens, such as git, a package feed or an Azure DevOps personal access token: the team's own boot
673
+ step sets them, for example from their Key Vault with a managed identity on the VM.
674
+ - The worker reads its environment when its service starts. The boot step runs before the worker starts,
675
+ or restarts the worker service after. On our Windows image, the startup task `orchestra-azure-userdata`
676
+ starts `SfdkWorker`.
677
+ - Never put a token in `provisionSpec.env` (`env` in the kit). The platform stores it, an environment
678
+ read returns it, and it travels in plain text in the VM's startup data.
679
+ - The Launcher attaches no managed identity to the VMs it creates. The tags `orchestra-launcher` (the
680
+ record's id) and `orchestra-machine` (the machine's id) let the team's automation find them. Not
681
+ released yet: a managed identity attached when the Launcher creates a VM.
682
+ - Proven on Orchestra's test environment with a new Launcher 0.1.0, a team's own Windows image and the
683
+ `Dsv6` size family:
684
+ - A `claude` turn ran. It reached the model through an Orchestra gateway key, with no network edge.
685
+ - The worker registered about 1 minute 46 seconds after the VM was created.
686
+ - The first turn included a harness install of about 60 seconds, on an image without the harness.
687
+ - A parked VM resumed, the same VM, in about 2 minutes.
688
+ - With `ttlAfterIdle` at 300 seconds, the VM parked about 8 minutes after the last turn, not the 6 that
689
+ section 4 gives.
690
+ - Standby capacity gave a new conversation a ready machine, and its turn started in 3.5 seconds.
691
+ - Can: our public Azure community gallery images, version 0.0.136, both Gen2, on SCSI or NVMe sizes:
692
+ - `/CommunityGalleries/orchestraworks-881a796f-0a84-4be1-af80-0a38564a406a/Images/runtime-win/Versions/0.0.136`
693
+ - `/CommunityGalleries/orchestraworks-881a796f-0a84-4be1-af80-0a38564a406a/Images/runtime-linux/Versions/0.0.136`
694
+
695
+ A Launcher VM environment that names no image boots the matching one at `Versions/latest`. Name the
696
+ `0.0.136` id as the environment's image to pin it.
697
+ - The Launcher's VM targets use the `Dsv5` size family by default. A subscription with no `Dsv5` capacity
698
+ names a family it has, such as `Dsv4` or `Dsv6`, as `vmSizeFamily` on each VM target in the Launcher's
699
+ settings (`targets` in the deploy template). The Launcher README lists the families it accepts.
700
+ - Not released yet: the Launcher on AWS.
701
+ - Can: when a Launcher does not work, run `orchestra compute-providers check <id-or-slug>` first. It shows
702
+ whether the Launcher polls, its protocol, its health and why each target failed, and exits 1 on a failure.
578
703
  - Can: the local environment (`orchestra local`), a local copy of the platform on the developer's own
579
704
  computer, stands up an environment and proves it in three milestones: the whole stack up, validation the
580
705
  way a person uses it, then the tests; one agent turn runs after validation. It starts machines whatever network