@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
@@ -0,0 +1,111 @@
1
+ # Phase 1: Discover
2
+
3
+ **Goal:** you know what to build: a new factory or a new environment, what the codebase needs to run, and
4
+ which services the agents must reach. You write it down before any factory code exists.
5
+
6
+ Write every finding into `<codebase>/../orchestra-factory-notes.md`, one line for each item, with the file,
7
+ page or command that shows it.
8
+
9
+ ## 1. Read the account: a new factory or a new environment
10
+
11
+ An organization usually holds one factory, or none yet. Read what it holds before you ask the developer
12
+ anything. These commands only read. `--all-pages` follows every page, and prints the rows as one array:
13
+
14
+ ```bash
15
+ npx --package @orchestraworks/cli orchestra agents list --all-pages --output json
16
+ npx --package @orchestraworks/cli orchestra environments list --all-pages --output json
17
+ npx --package @orchestraworks/cli orchestra pipelines list --all-pages --output json
18
+ npx --package @orchestraworks/cli orchestra workflows list --all-pages --output json
19
+ npx --package @orchestraworks/cli orchestra connections list --output json
20
+ ```
21
+
22
+ A row that an apply made carries the label `sfdk.managedBy`, whose value is the factory's name.
23
+
24
+ 1. Infer what the developer most likely wants:
25
+ - *No agents and no pipelines:* the account is empty. Infer **a new factory**.
26
+ - *Rows labeled with a factory name:* a factory exists. Infer **a new environment for that factory**,
27
+ such as another repository, a bigger machine, or a machine of the team's own.
28
+ - *Rows with no label:* someone made them by hand or with the CLI. Infer a new factory. If a row's slug
29
+ is one the starter declares, such as `manager-agent`, the apply updates that row. Say so in phase 2.
30
+ 2. Tell the developer what you found, in one or two sentences, for example: "This organization already has
31
+ the factory `factory`, with the agents Manager Agent, Engineer Agent lg, md and sm."
32
+ 3. Ask once, with your question tool, with the inferred choice first and marked as the recommendation.
33
+
34
+ **A new factory.** Go on with section 2.
35
+
36
+ The starters build one factory per organization. When the organization already holds a factory and the
37
+ developer wants another one, make a separate organization for it:
38
+
39
+ 1. Create it: `npx --package @orchestraworks/cli orchestra organizations create --name "<name>"`. Read
40
+ `organizations create --help` for its other flags. When the command refuses, the developer creates the
41
+ organization in the console at `https://app.orchestraworks.ai`.
42
+ 2. Sign in to it as phase 0 says, with `--org <the new organization>`.
43
+ 3. Start this phase again, in the new organization.
44
+
45
+ **A new environment for the existing factory.** Do not run `orchestra fdk init` in phase 4. Edit the factory
46
+ that exists instead:
47
+
48
+ 1. Find the existing factory's folder: the folder with `fdk.json` and `main.ts`. Ask the developer where it
49
+ is when it is not on this computer.
50
+ 2. Load the factory's inputs, the same way every earlier apply loaded them. The engineering-team starter
51
+ reads `~/.config/orchestra/tokens.env`; the bug-fix starter reads `~/.config/orchestra/fdk-inputs.env`.
52
+ Load the file with `set -a; . <file>; set +a`, and never print it. Ask the developer when the file is not
53
+ there. An apply without these inputs removes the token rules the factory has now.
54
+ 3. With the inputs loaded, run `npm install` and `npx orchestra fdk diff` in that folder. It must be a clean
55
+ diff before you edit anything. If it is not, show the changes to the developer and ask what to keep.
56
+ 4. Then read the repository (section 2) for the new environment only. Phase 2 plans the new environment and
57
+ the agent that works on it, and phase 4 adds them to the existing code.
58
+
59
+ ## 2. Read the repository
60
+
61
+ Read the codebase before you write any factory code. The factory must match it, and the machines most of
62
+ all. Note each item:
63
+
64
+ - **The operating system it builds and runs on.** These mean Windows: a `.sln` or `.csproj` that targets
65
+ .NET Framework, WinForms, WPF or IIS, PowerShell build scripts, or `windows-latest` in CI.
66
+ - **The runtime it needs.** A kernel feature, a GPU, nested virtualization, an Android emulator, or a tool
67
+ for another operating system, such as Xcode, means a full virtual machine or the team's own machine.
68
+ - The languages and toolchains, with their versions: `global.json`, `.nvmrc`, `.tool-versions`, the CI's
69
+ setup steps.
70
+ - The build and test commands, from the CI file first, then the README and the build scripts.
71
+ - The package feeds, private ones included: `nuget.config`, `.npmrc`, `pip.conf`, a feed in the CI file.
72
+ - The services it needs, such as a database or a queue: a compose file, test containers, connection
73
+ settings.
74
+ - Docker use: a `Dockerfile`, a compose file, Testcontainers.
75
+ - The repository size: `du -sh <codebase>` and `git -C <codebase> count-objects -vH`.
76
+ - The code host and the tracker: the remote URL (`git -C <codebase> remote get-url origin`), and links in
77
+ the README, the branch names or the CI file.
78
+
79
+ These are facts for the later phases. Ask the developer only what the files cannot answer.
80
+
81
+ ## 3. Name each service, by category and provider
82
+
83
+ For each outside service the agents need, name its category and its provider. Each category has one file in
84
+ `../integrations/`:
85
+
86
+ | Category | File | Examples |
87
+ |---|---|---|
88
+ | Code host | `code-repo.md` | GitHub, Bitbucket, GitLab, Azure DevOps |
89
+ | Tracker | `issue-tracker.md` | Jira, Linear, GitHub Issues, Azure Boards |
90
+ | Knowledge base | `knowledge-base.md` | Notion, Confluence, Guru |
91
+ | Chat | `messaging.md` | Slack, Microsoft Teams |
92
+ | Package registries | `dependencies.md` | npm, PyPI, NuGet, Maven |
93
+ | CI and CD | `ci-cd.md` | GitHub Actions, Azure Pipelines, Jenkins, CircleCI |
94
+ | Observability | `observability.md` | Sentry, Datadog, New Relic, Grafana |
95
+ | Support desk | `support-desk.md` | Zendesk, Intercom, Freshdesk |
96
+ | Design | `design.md` | Figma |
97
+ | Cloud | `cloud.md` | AWS, Azure, Google Cloud |
98
+ | Databases | `databases.md` | A staging database or a read replica |
99
+ | Secrets managers | `secrets-managers.md` | 1Password, Vault, Azure Key Vault |
100
+ | Incidents | `incident.md` | PagerDuty, Opsgenie |
101
+ | Analytics | `analytics.md` | Pendo, Mixpanel, Amplitude |
102
+ | Feature flags | `feature-flags.md` | LaunchDarkly, Split, Unleash, ConfigCat |
103
+
104
+ Infer each one from the codebase and the connections list. Then tell the developer what you found, and ask
105
+ once, with your question tool, which code host, which tracker and which other services the agents need.
106
+ Put your inference first, marked as the recommendation. No provider is a default.
107
+
108
+ ## Exit check
109
+
110
+ `orchestra-factory-notes.md` has a line for each item in sections 2 and 3, or says the item does not apply,
111
+ and it records the answer to section 1: a new factory, or a new environment for a named factory.
@@ -0,0 +1,157 @@
1
+ # Phase 2: Plan
2
+
3
+ **Goal:** the developer approves what you will build, before anything reaches the platform. You plan from
4
+ the starter and from the finding of phase 1, the environment first.
5
+
6
+ ## 1. Choose the starter
7
+
8
+ Ask one question, with these three choices:
9
+
10
+ - **An engineering team (your real repository).** Recommended.
11
+ - **A todo app sample.** A small public app, `orchestraworks/todo-app`, for a quick first success.
12
+ - **I already have a factory.ts.**
13
+
14
+ For a new environment in an existing factory, skip this question: you change the factory that exists.
15
+
16
+ Read the starter before you change it. It ships in the kit's package, two folders above this skill's folder.
17
+ Select the Claude Code link that exists, resolve it, then go up two:
18
+ `skill_link=.claude/skills/orchestra-fdk; [ -e "$skill_link" ] || skill_link=~/.claude/skills/orchestra-fdk; cat "$(realpath "$skill_link")/../../templates/engineering-team/README.md"`
19
+ (use `.agents/skills/orchestra-fdk` and `~/.agents/skills/orchestra-fdk` for Codex). Read its `main.ts`,
20
+ `lib/environment.ts`, `lib/inputs.ts`, `lib/setup.sh` and `agents/` in the same folder. The README says what
21
+ the starter declares, and why.
22
+
23
+ The starter declares no integration: no code host, no tracker, no connection and no provider Secret. It
24
+ applies and runs with only the model route, and the first work is created by hand. Phase 3 adds a private
25
+ package feed the build needs before phase 4, and the other services of phase 1 after the first run works.
26
+
27
+ ## 2. Adapt the starter, the environment first
28
+
29
+ Change the plan to match the notes of phase 1. Write each change into `orchestra-factory-notes.md` with its
30
+ reason, such as "Windows VM, because the solution targets .NET Framework 4.8".
31
+
32
+ - *The operating system.* A Windows codebase needs a Windows virtual machine. The starter declares Linux
33
+ only, so plan these hand edits in `lib/environment.ts` and the files beside it:
34
+ - set `platform: { os: "windows", arch: "amd64", runtime: "vm" }`;
35
+ - map every size to `"4"` or `"8"`, because a Windows machine takes 4 or 8 CPU;
36
+ - remove `disks`, because a Windows machine takes no extra disks, and use a folder on its own disk, such
37
+ as `C:\work`, in place of `/work`;
38
+ - replace `lib/setup.sh` with a PowerShell `.ps1` script;
39
+ - Docker there runs Windows containers only, and only for administrators.
40
+
41
+ Plan Windows in three stages, in this order, and show the developer all three
42
+ (`../environment.md`, section 5, "Windows in three stages"):
43
+ 1. Start on hosted Windows with our image. The setup script installs what fits in its 10 minutes. The
44
+ rest goes in the agent's first turn, and the parked machine keeps it until `ttl` deletes the machine
45
+ (the orchestra skill, section 4, "Lifetime"). This proves the factory works.
46
+ 2. Then move to the team's own Windows image, with their toolchain installed, through a compute provider
47
+ in their cloud. Machines start with everything installed, and their licenses stay in their image. The
48
+ compute provider runs on Azure. Not released yet: on AWS.
49
+ 3. Then keep machines ready with `standbyCapacity` on the agent, so a conversation starts at once.
50
+
51
+ `../environment.md`, section 5, has the rest.
52
+ - *The runtime.* `microvm` for most Linux code. `vm` for Windows, an Android device or a kernel of its own.
53
+ The team's own machine (`host`) for a Mac. `../environment.md`, section 5, "The machine's runtime".
54
+ - *The toolchain and the setup.* The versions the notes name, and the codebase's dependencies.
55
+ - *The size.* Match what the team's CI uses for the same work. Sizes are 2 GB of memory per CPU.
56
+ - *The network.* Egress starts open on every machine, and the first run adds only the model route's key and
57
+ the key of any private package feed the build needs.
58
+ - *The agents' text.* Where the build or test commands, or the work folder, differ from what `agents/*.md`
59
+ says, plan to change those lines. Keep the Attribution section at the top of each agent's instructions,
60
+ and start every new agent's instructions with it (`../authoring.md`, "Every agent's instructions start
61
+ with an Attribution section").
62
+ - *A `script` agent.* Where a step needs no model judgment, such as a scheduled sync or a data pull, plan a
63
+ `script` agent. It runs a shell program and no model. The orchestra skill, section 2, says what it can and
64
+ cannot do.
65
+
66
+ ## 3. The model route
67
+
68
+ ### The private token file
69
+
70
+ A subscription or an own key needs a token, and so does each service phase 3 connects later. Tokens come
71
+ from one file. Ask the developer to make a file only they can read, outside the codebase:
72
+
73
+ ```bash
74
+ mkdir -p ~/.config/orchestra && touch ~/.config/orchestra/tokens.env && chmod 600 ~/.config/orchestra/tokens.env
75
+ ```
76
+
77
+ They add one line for each token, filled in by them, such as `ORCHESTRA_FDK_GITHUB_TOKEN=...`. Never ask for
78
+ a token in the chat, never print one, and never write one into a file in `<codebase>` or `<factory>`. Load
79
+ the file into a command's shell without printing it: `set -a; . ~/.config/orchestra/tokens.env; set +a`.
80
+
81
+ ### The routes
82
+
83
+ Each agent needs a way to reach its AI model. There are three equal options. The developer uses the one
84
+ that matches what they already have. Ask which they have, with your question tool, or infer it from what is
85
+ set up, such as an existing factory's model Secret or `ModelProviderKey`. For plan questions, send the
86
+ developer to **Settings › Plan & usage** in the console.
87
+
88
+ **A Claude or Codex subscription.** The developer signs in a real terminal on their own computer. Run from
89
+ your shell, its browser step hangs. You never read or copy the value.
90
+
91
+ - *Claude.* `claude setup-token` prints a long-lived token. The developer saves it in the private file as
92
+ `ORCHESTRA_FDK_CLAUDE_CODE_OAUTH_TOKEN`. The factory stores it as a Secret, and the network edge adds it to
93
+ calls to `api.anthropic.com`. The machine holds only a placeholder token and an empty API key. Declare the
94
+ Claude sign-in recipe from `../authoring.md`, "Secrets are recipes, never values". Never put the token in
95
+ the environment's settings: they are stored and shown in plain text.
96
+ - *Codex.* A personal access token, which begins `at-`. A ChatGPT Business or Enterprise member makes it at
97
+ `chatgpt.com/admin/access-tokens`, when the workspace owner allows it. Or a separate ChatGPT sign-in:
98
+ `CODEX_HOME=<dir> codex login`, never a copy of the developer's own `~/.codex` sign-in. A separate sign-in
99
+ must live on a `/home` volume that every machine using it shares, because each renewal replaces the
100
+ sign-in. Keep a Codex sign-in off the model gateway: the gateway refuses its requests with
101
+ `model_not_found`. The sign-in goes in the `ORCHESTRA_WORKER_CODEX_` variables in the environment's `env`,
102
+ and the worker writes it into Codex's own sign-in file (`../authoring.md`, "The subscription variables").
103
+ The worker reads them from its own environment: on a hosted machine, from `env`; on an enrolled machine,
104
+ from the environment the worker runs with. `env` is stored and shown in plain text.
105
+
106
+ An agent on a subscription turns the model gateway off: remove `enableModelGateway: true` from its model
107
+ settings.
108
+
109
+ **An Orchestra account, through the model gateway.** One endpoint reaches OpenAI, Anthropic and open
110
+ models. `orchestra model-configs` sets which providers serve a model and in which order, and
111
+ `orchestra model-aliases` gives a model the organization's own name. The organization can add its own
112
+ provider key to the gateway as a `ModelProviderKey` (orchestra skill, section 7). The starter's code uses
113
+ this option as written, so it needs no edit.
114
+
115
+ **Their own provider API key.** The key is a Secret that the network edge adds to calls straight to the
116
+ provider, with no gateway in between. For Anthropic: `api.anthropic.com → x-api-key: <SECRET>`. For OpenAI:
117
+ `api.openai.com → Authorization: Bearer <SECRET>`. Read the key from a variable such as
118
+ `ORCHESTRA_FDK_ANTHROPIC_API_KEY`, and turn `enableModelGateway` off for the agent.
119
+
120
+ ## 4. Show the plan
121
+
122
+ Show two tables. Under each table, give each change from the starter with its reason, from the notes.
123
+
124
+ **Agents.** One row for each agent. Name no machine here.
125
+
126
+ | Agent | Description | Model (harness) | Skills | Access |
127
+ |---|---|---|---|---|
128
+ | Manager Agent | Triages each item, gives it the code, and assigns it. | `claude-opus-5-5` (`claude`) | The codebase skill, once it exists | The model route. The code host and tracker once phase 3 connects them. Roles `agent-worker` and `agent-manager`. |
129
+
130
+ Fill in the rows from the plan, not from this example. *Access* names the services the agent reaches and the
131
+ roles it holds. Each new agent gets `agent-worker`: its own sessions, and reads, with no change to
132
+ triggers. The Manager Agent also needs `agent-manager`, which a person grants by hand in phase 4. It can
133
+ change agents, pipelines, work items and workflows.
134
+
135
+ **Working environment.** One row for each agent.
136
+
137
+ | Agent | Size (CPU and memory) | Arch (OS and runtime) | Network |
138
+ |---|---|---|---|
139
+ | Manager Agent | 32 CPU, 64 GB | Linux amd64, `microvm` | Open. The model gateway key is added at the network edge. |
140
+
141
+ Then explain the rest in plain words, from the orchestra skill. Say what each idea is for first, then what
142
+ it is:
143
+
144
+ - *Pipelines* hold the work items: sections 9 and 10. Show each pipeline's name, item prefix and stages.
145
+ An item can move from any stage to any other. An agent moves an item to its review stage when it needs a
146
+ person.
147
+ - *The model route* of section 3, and what it changes in the starter.
148
+ - *What phase 5 proves:* the app runs on an agent's machine, and one small real item goes end to end.
149
+
150
+ Ask the developer, with your question tool, whether they approve the plan or want changes. Answer each
151
+ question. Change the plan until they approve it.
152
+
153
+ ## Exit check
154
+
155
+ The developer said yes to the two tables, the model route and the changes, and `orchestra-factory-notes.md`
156
+ holds each change with its reason. For a subscription or an own key, the token file exists with mode 600
157
+ (`stat`). Do not read its contents.
@@ -0,0 +1,99 @@
1
+ # Phase 3: Connect
2
+
3
+ **Goal:** the agents can reach each service the developer chose to connect, on the developer's behalf. The
4
+ developer gives the access. You make sure egress is open.
5
+
6
+ **When.** A first run needs no optional integration: the starter applies and runs with only the model route.
7
+ But the build may need a private service, such as a private package feed (phase 1, "The package feeds"). The
8
+ machine cannot install the code without it, so phase 5 cannot pass. On a first run, the factory folder does
9
+ not exist yet: phase 4 writes it. So here, only prepare each feed's credential, from
10
+ `../integrations/dependencies.md`: the developer writes its token into the private token file (section 2,
11
+ step 1). Then go to phase 4. It writes the Secret and the rule into `lib/environment.ts` after `init`, and
12
+ checks the access after the apply. When the build needs nothing private, skip this
13
+ phase. After phase 5 passes, come back and connect the code host, the tracker and the other services found in
14
+ phase 1, one at a time. Ask the developer which ones to connect now.
15
+
16
+ The developer gives access in one of two ways, and egress stays open:
17
+
18
+ - **A Secret** for a credential. The developer writes the token into the private token file (phase 2,
19
+ "The private token file"). The apply stores it as a Secret, and the network edge adds it to each matching
20
+ request. No agent and no person sees it.
21
+ - **An env value** for a setting that is not secret, such as a site address. It goes in the environment's
22
+ `ENV` in `lib/environment.ts`. Env values are stored and shown in plain text, so a token never goes there.
23
+
24
+ Egress starts open: the starter uses `EgressPolicy.allowAll()`. Add no allow rule only to reach a host. Add
25
+ the rule that adds a credential, and the open policy does the rest. Tightening is a later step, after the
26
+ factory works (`../environment.md`, section 5, "Network").
27
+
28
+ ## 1. Read the integration file
29
+
30
+ For each service the developer chose, read its row and its section in the matching file in
31
+ `../integrations/`. Each file starts with a short section on how to give access, then one table:
32
+
33
+ | Provider | Access | Scopes | Check command |
34
+ |---|---|---|---|
35
+
36
+ - *Access* is a recipe, `host → header: value`, or a platform connection by its catalog key.
37
+ - *Scopes* is what the token needs, no more.
38
+ - *Check command* is one HTTPS call the agent runs on its machine, with no credential in it: the edge adds
39
+ it. A `200` alone does not prove the access. Some providers answer `200` without a credential, such as a
40
+ public repository, or `200` with a failure in the body, such as Slack's `"ok":false` or a GraphQL
41
+ `errors` list. So the check passes only when the answer shows the provider's success value: the token's
42
+ own user, the private resource, or the success field the row names.
43
+
44
+ The agent installs or uses whatever client it prefers. The edge adds the credential to that client's
45
+ requests too, so no client needs a token of its own.
46
+
47
+ ## 2. Give the access
48
+
49
+ For each service, read the *Access* cell of its row. Do steps 1 and 2 only for a `host → header` recipe,
50
+ which a Secret backs. A platform connection, such as Slack, Microsoft Teams or the GitHub App, takes no token
51
+ file and no Secret: declare the connection in `main.ts` and add its rule, as its file says. For Slack and
52
+ Microsoft Teams, the apply prints the link the developer opens to authorize it (phase 4, section 3). For any
53
+ other OAuth connection, the apply prints no link: the connection stays `NEEDS_ATTENTION`. Read its link with
54
+ `npx orchestra connections get <slug> --output json`, at `auth.authorizationUrl`, and give it to the developer.
55
+
56
+ 1. Ask the developer to make the token on the vendor's page, with the scopes in the row. They add it to the
57
+ private token file as `ORCHESTRA_FDK_<SERVICE>_TOKEN`. Never ask for it in the chat.
58
+ 2. Write the recipe as one Secret and one credential rule in `lib/environment.ts`, on every environment that
59
+ needs it, as the next table says. The starter's `declareKeys` holds the Secrets, and its egress policy
60
+ holds the rules after `EgressPolicy.allowAll()`. Put any env value in `ENV`.
61
+ 3. Where events should make work, such as a new issue, declare the platform connection and a `Trigger` in
62
+ `main.ts`. The integration file names the connection's catalog key and its events. The orchestra skill,
63
+ sections 12 and 17, says what a trigger and a connection are.
64
+ 4. Apply as phase 4 says: synth, diff, the developer's yes, then apply, with the token file loaded.
65
+ 5. Ask the agent to run the row's check command on its machine, or run it yourself in a session.
66
+
67
+ ### From a recipe to code
68
+
69
+ | Recipe value | Secret value | Binding |
70
+ |---|---|---|
71
+ | `Bearer <SECRET>` | `SecretValue.fromEnv("<VAR>")` | `bearer("Authorization", secret)` |
72
+ | `Basic <user>:<SECRET>` | `SecretValue.basicAuth("<user>", SecretValue.fromEnv("<VAR>"))` | `basic("Authorization", secret)` |
73
+ | `<SECRET>` alone, in any header | `SecretValue.fromEnv("<VAR>")` | `header("<Header>", secret)` |
74
+ | Any other shape, such as `Token token=<SECRET>` | `SecretValue.fromEnv("<VAR>")` | `inject(secret, { headers: [{ name: "<header>", value: "Token token=${secret}" }] })` |
75
+
76
+ ```ts
77
+ const sentry = new Secret(factory, "sentry-token", { value: SecretValue.fromEnv("ORCHESTRA_FDK_SENTRY_TOKEN") });
78
+ // in the environment's egress, after EgressPolicy.allowAll():
79
+ .allow("sentry", { hosts: ["sentry.io"], priority: 300, credential: bearer("Authorization", sentry) })
80
+ ```
81
+
82
+ Two Secret rules on one host with one priority are a tie: the first declared wins. When two such rules share
83
+ a host, give each its own `paths`, or give the narrower one a higher priority. A platform connection adds its
84
+ own rule: `.allow(<connection>)`, or `.applyPreset(<connection>.egressPolicy())` where its file says so.
85
+
86
+ Two platform connections of one provider in one environment, such as two GitHub installations, are
87
+ different. Keep their rules at equal priority, and set `attributeConnection: true` on the agent target of
88
+ each trigger that starts their sessions. Or put the two connections in separate environments. A higher
89
+ priority on one rule sends that connection's key on every request to the host, also for a session of the
90
+ other connection.
91
+
92
+ ## Exit check
93
+
94
+ Every service the developer chose to connect has its access: a Secret from the private token file, an env
95
+ value, or a platform connection the developer authorized. Its check command, run from an agent's machine,
96
+ shows the provider's success value. Every environment keeps `EgressPolicy.allowAll()`.
97
+
98
+ On a first run, the check is smaller: each private feed's token is in the private token file. Phase 4 checks
99
+ the access after its apply.
@@ -0,0 +1,159 @@
1
+ # Phase 4: Build
2
+
3
+ **Goal:** the platform matches the plan the developer approved in phase 2, with the access of phase 3.
4
+
5
+ A *clean diff* is a `npx orchestra fdk diff` that creates, updates and deletes no agent, environment or
6
+ pipeline. While a token or key is loaded, each Secret it fills shows `value-write-pending` on every diff, even
7
+ right after an apply. That is expected, and a clean diff may show it.
8
+
9
+ **Load the token file before every diff and every apply, a repair apply included,** once the factory reads
10
+ any token from it. A Secret declared with `SecretValue.fromEnv` takes its value from the shell at apply, so an
11
+ apply without the variable cannot write it, and code that declares a rule only when its token is set drops
12
+ that rule.
13
+
14
+ ## 1. Write the factory
15
+
16
+ For a new environment in an existing factory, skip this section: edit that factory's folder (phase 1).
17
+
18
+ 1. Make a new, empty folder beside the codebase: `<codebase>/../orchestra-factory`. Call it `<factory>`. Do
19
+ not install the kit in it before point 2.
20
+ 2. In `<factory>`, write the starter the developer chose in phase 2:
21
+
22
+ ```bash
23
+ npx --package @orchestraworks/cli orchestra fdk init --template engineering-team
24
+ ```
25
+
26
+ For the todo app sample, use `--template todo-factory`. It works on the public `orchestraworks/todo-app`.
27
+ For their own `factory.ts`, copy their folder into `<factory>` instead. It needs `fdk.json` and a
28
+ `"type": "module"` package.
29
+
30
+ Run `init` in the new, empty folder, with no kit installed there: the starter brings its own
31
+ `package.json`. It writes `README.md`, `main.ts`, `inputs.json`, `package.json`, `fdk.json`,
32
+ `tsconfig.json`, `agents/` and `lib/`. It overwrites nothing. If a file is in the way, it writes nothing
33
+ and names it.
34
+ 3. In `<factory>`, run `npm install`. From now on, run `npx orchestra` in `<factory>`.
35
+
36
+ ## 2. Edit it to the plan
37
+
38
+ 1. Make each change of phase 2, the environment first, and the model route's change. On a first run, also
39
+ write the Secret and the rule of each private feed phase 3 prepared (phase 3, section 2, step 2).
40
+ 2. Fill in `<factory>/inputs.json`: `repositoryUrl`, the repository's HTTPS address, and
41
+ `repositoryDefaultBranch` (`git -C <codebase> symbolic-ref refs/remotes/origin/HEAD`). Both may stay
42
+ empty. Then the Manager Agent takes the address from each item. When the remote is an SSH address, such
43
+ as `git@<host>:<org>/<repo>.git`, write its HTTPS form, `https://<host>/<org>/<repo>.git`. Azure DevOps
44
+ is different: `https://dev.azure.com/<organization>/<project>/_git/<repo>`. A hosted
45
+ machine cannot reach SSH ports, and the network edge adds a credential to HTTPS requests only.
46
+ 3. Run `npm run typecheck`, then `npx orchestra fdk synth`, with the token file loaded if the factory reads
47
+ one. The local proof builds its environment and agent from `fdk.out/plan.json`, which synth writes.
48
+ 4. Prove the machine on this computer with `../environment.md`, sections 1 to 6. It writes what worked into
49
+ the setup script and the environment code. Come back here after its section 6, and synth again in
50
+ section 3 below.
51
+
52
+ On a first run, the factory declares the model route and any private package feed the build needs: no code
53
+ host, no tracker and no connection. Phase 3 adds them later, with this same synth, diff, approve and apply.
54
+
55
+ ## 3. Synth, diff, approve, apply
56
+
57
+ 1. Load the token file, if the factory reads one. Run `npm run typecheck`, then `npx orchestra fdk synth`.
58
+ Read `fdk.out/warnings.json`, and fix each warning or tell the developer why it stays.
59
+ 2. Run `npx orchestra fdk diff`. It changes nothing.
60
+ 3. Show the developer the change list in plain words: the agents, the environments, the Secrets, the rules,
61
+ the connections and the pipelines. State each change with its reason. Say what the developer must do in
62
+ the browser: an install link or an authorize link (phase 3, section 2, says where each one comes from).
63
+ 4. Ask them to approve it, with your question tool.
64
+ 5. On a yes, and only then, run the apply, with the token file loaded if the factory reads one:
65
+
66
+ ```bash
67
+ npx orchestra fdk apply --require-approval never
68
+ ```
69
+
70
+ The flag is needed because your shell has no terminal to type "y" at. It is safe only after the
71
+ developer approved the same change list.
72
+ 6. When the apply prints an install or authorize link, give it to the developer. When it says a connection
73
+ needs attention and prints no link, read the link with `npx orchestra connections get <slug> --output json`,
74
+ at `auth.authorizationUrl`. A GitHub App install link
75
+ is shown once. Add `--install-timeout 0` to the same approved apply, so it stops at the link rather than
76
+ waiting. When the developer says the app is installed or the consent is given, run the same apply again.
77
+ If a link was lost, add `--remint-install-links`: it revokes the old link and prints a new one.
78
+ 7. On a first run with a private feed, check its access now. Ask an agent to run the feed's check command
79
+ from `../integrations/dependencies.md` on its machine, or run it yourself in a session. It must return
80
+ the private package, not an error or a sign-in page.
81
+
82
+ An organization on the `individual` plan cannot store a key or add one at the network edge, so the apply
83
+ stops with a plan error. Tell the developer, and point them to **Settings › Plan & usage** in the console.
84
+
85
+ ## 4. The steps the code cannot declare
86
+
87
+ **Grant the Manager Agent the `agent-manager` role**, for the whole organization. An agent starts with only
88
+ `agent-worker`. `<factory>/README.md`, "After apply: steps the code cannot declare", holds the commands. The
89
+ role list you send replaces the old one, so keep every entry it has now. Ask the developer to approve: "Give
90
+ the Manager Agent the agent-manager role in the whole organization?" On a yes, send the update with
91
+ `--require-approval never`. Then `npx orchestra organization-memberships get <membership id>` lists both
92
+ roles.
93
+
94
+ ## The fast path: one bug in a GitHub repository
95
+
96
+ `orchestra fdk init` without `--template` writes the bug-fix starter: one agent that takes a bug as its first
97
+ message and answers with a pull request and a report. Take this path when the developer wants one bug fixed
98
+ in a GitHub repository. Do phases 0 and 1 first. Then:
99
+
100
+ 1. Make a new folder beside the codebase, `<codebase>/../orchestra-factory`, called `<factory>`. In it, run
101
+ `npm init -y`, then `npm install @orchestraworks/cli`.
102
+ 2. Write the starter. `<owner>/<name>` is the GitHub repository. Add `--model-key anthropic` or
103
+ `--model-key openai` only when the organization brings its own model key to the model gateway.
104
+
105
+ ```bash
106
+ npx orchestra fdk init --repository <owner>/<name>
107
+ ```
108
+
109
+ 3. Run `npm install`, then `npm run typecheck`. Both must pass.
110
+ 4. Fill in `<factory>/skills/codebase/SKILL.md` with how the codebase installs, tests and starts, and the
111
+ services it needs. When the codebase has an `AGENTS.md` or `CLAUDE.md`, write one line naming it instead.
112
+ 5. Set the shell inputs. `main.ts` reads them, and `init` printed each with what it is. They come with the
113
+ hand-over note: `ORCHESTRA_FDK_IMAGE_REPOSITORY`, `ORCHESTRA_FDK_RUNTIME_IMAGE`,
114
+ `ORCHESTRA_FDK_MODEL_GATEWAY_HOST`, `ORCHESTRA_FDK_IMAGE_PULL_ACCESS_KEY_ID` and
115
+ `ORCHESTRA_FDK_IMAGE_PULL_SECRET_ACCESS_KEY`, plus `ORCHESTRA_FDK_ANTHROPIC_API_KEY` or
116
+ `ORCHESTRA_FDK_OPENAI_API_KEY` with `--model-key`. Ask the developer to write them into a file only they
117
+ can read, and load it in each command that runs `orchestra`:
118
+ `set -a; . ~/.config/orchestra/fdk-inputs.env; set +a`. Docker on this computer must also be signed in
119
+ to the image registry, with the details in the same note.
120
+ 6. Run `npx orchestra fdk diff` and show the developer the change list. On their yes, run
121
+ `npx orchestra fdk apply --require-approval never --install-timeout 0`. It builds and pushes the image,
122
+ prints a GitHub App install link, and stops without waiting. Give the link to the developer, and ask them
123
+ to say when the app is installed. Then run the same apply again.
124
+ 7. Send the bug. The agent's id is `<factory name>-bugfix`, where the factory name is the one `init` printed:
125
+
126
+ ```bash
127
+ npx orchestra sessions start --agent-id <factory name>-bugfix --content '[{"type":"text","text":"<the bug, as the reporter wrote it>"}]' --output json
128
+ ```
129
+
130
+ `--content` is a JSON array of content blocks, never plain text. Escape each `"` in the bug text as `\"`, and write no `'` in it.
131
+ The answer is `{"session":{…},"firstItem":{…}}`. The session id is `.session.id`.
132
+ 8. Wait for the turn to end, in the foreground, with one blocking command:
133
+
134
+ ```bash
135
+ npx orchestra sessions wait <session id> --timeout 540
136
+ ```
137
+
138
+ Do not start the wait in the background and end your turn. A headless agent exits when its turn ends,
139
+ and the waiting command goes with it. `--timeout 540` ends the wait before a ten-minute command limit.
140
+ When it times out, it prints the session's last status and exits non-zero: run the same command again.
141
+ 9. `sessions wait` shows no progress. To see what the agent did, read the conversation's items:
142
+ `npx orchestra sessions list-items <session id> --output json`. The rows are in `data`. The developer
143
+ can watch the same session live in the console at `https://app.orchestraworks.ai`, or in a terminal
144
+ with `npx orchestra sessions tail <session id>`, which prints each item as it is saved.
145
+
146
+ The fast path ends when the session's status is `COMPLETE`, and its last message names the pull request and
147
+ the report.
148
+
149
+ ## Exit check
150
+
151
+ A second `npx orchestra fdk diff`, with the same shell, is a clean diff, each private feed answers its check
152
+ command (section 3, step 7), and these list every agent and environment of the plan:
153
+
154
+ ```bash
155
+ npx orchestra agents list --all-pages --output json
156
+ npx orchestra environments list --all-pages --output json
157
+ ```
158
+
159
+ If the check fails, read `../troubleshooting.md`, "`fdk diff` shows something you did not expect".
@@ -0,0 +1,107 @@
1
+ # Phase 5: Prove
2
+
3
+ **Goal:** the customer's app runs on an agent's machine in the cloud, and a person can reach it. Only then
4
+ does one small real work item go end to end.
5
+
6
+ Spinning up the app is the most important part of this phase. An agent can fix, test or show the code only
7
+ when its machine can build and run it.
8
+
9
+ ## 1. The app runs on a machine
10
+
11
+ The starter cannot declare items, and its setup script runs before the code is on the machine. So the first
12
+ item, Set up, created by hand, asks the Manager Agent to get the code, install it and start the app on its
13
+ own machine. No code host connection is needed. The code reaches the machine one of two ways:
14
+
15
+ - *A public repository:* the agent clones it from its HTTPS address. Egress is open.
16
+ - *A private repository:* cut a git bundle on this computer, outside the codebase, and upload it as a File.
17
+ Name the file id in the item. The agent downloads it with `orchestra files get-content` and clones from it.
18
+
19
+ ```bash
20
+ git -C <codebase> bundle create <codebase>/../orchestra-setup.bundle <default branch>
21
+ npx orchestra files create --file <codebase>/../orchestra-setup.bundle --output json
22
+ ```
23
+
24
+ 1. Create Set up in the Features pipeline:
25
+
26
+ ```bash
27
+ npx orchestra work-items create --pipeline features --title "Set up" --description "<the Set up message>" --output json
28
+ ```
29
+
30
+ The description says:
31
+ - Clone the repository under `/work`, at the tip of the default branch: from its public address, or from
32
+ the bundle `Code bundle: <file id>`.
33
+ - Install the dependencies with the internet.
34
+ - Write the app's own settings files, such as `.env.local`, from what `../environment.md` found. Use local
35
+ or test values only. Note in the report any setting or log that names a production or live host, and
36
+ continue.
37
+ - Start the whole stack with the project's own scripts, and load its seed data.
38
+ - Check it the way a person uses it: call the API and check real answers; for a web UI, sign in as a
39
+ local test user and do one real business operation. Make one smoke request to each app port on the
40
+ machine, such as `curl -fsS http://127.0.0.1:<port>/`.
41
+ - Report the machine endpoint of each app port, each command, its result and its time.
42
+ - Then run the unit, functional and end-to-end tests. Report which ran, which could not, and whether they
43
+ match the team's CI. The tests do not decide Done: the app running does.
44
+ - Prove that an Engineer Agent can run the tests from a git bundle of the same commit.
45
+ 2. Start it: `npx orchestra work-items assign <item id> --agent-id manager-agent`. Assigning starts the
46
+ Manager Agent's conversation on the item, and a machine starts for it.
47
+ For a new environment in an existing factory, the existing Manager Agent runs on its own environment, so
48
+ it proves nothing about the new one. Assign Set up to the agent you added on the new environment instead:
49
+ `--agent-id <new agent slug>`. Use the same agent in section 4.
50
+ 3. Watch it: `npx orchestra work-items get <id> --output json` lists the item's `sessions`. Run
51
+ `npx orchestra sessions wait <session id> --timeout 540` in the foreground, and run it again when it times
52
+ out. The developer can watch the same session in the console at `https://app.orchestraworks.ai`.
53
+
54
+ ## 2. A person can reach the app
55
+
56
+ 1. Find the machine and its endpoints:
57
+
58
+ ```bash
59
+ npx orchestra machines list --environment-id <environment id> --output json
60
+ npx orchestra machines get <machine id> --output json
61
+ ```
62
+
63
+ Each declared port has an entry in `endpoints`, with its `url` once the machine is `RUNNING`. Only
64
+ signed-in members of the organization can open it. A port that is not declared has no endpoint: add it to
65
+ `PORTS` in `lib/environment.ts` and apply as phase 4 says. The apply reaches only machines made after it,
66
+ so then add the endpoint to the running machine:
67
+ `npx orchestra machines create-endpoint <machine id> --port <port> --output json`.
68
+ 2. Prove it is reachable. Open the `url` with a browser tool in a browser signed in to Orchestra, and take a
69
+ screenshot of the app's page. Or ask the developer to open it, and to confirm what they see. The Set up
70
+ report's smoke requests are the second proof.
71
+ 3. An app with no web address, such as an Android app, is a screen on the machine. Show it with a *machine
72
+ view*: a live stream of that screen, which the developer opens from the machine's page in the console.
73
+ `npx orchestra machines list-views <machine id> --output json` lists the views.
74
+
75
+ When a step fails, fix it in the environment. Go back to `../environment.md`, prove the fix on this computer,
76
+ and apply it as phase 4 says. Then assign the item again to wake the agent. Note the time before you assign.
77
+ The session can still show the last turn's `COMPLETE`, and then `sessions wait` returns at once. So run
78
+ `npx orchestra sessions get <session id> --output json` first, and wait only once its `lastActiveAt` is later
79
+ than that time. `../troubleshooting.md` names each failure.
80
+
81
+ ## 3. Name the codebase skill
82
+
83
+ When the Manager Agent makes a codebase skill, it names the skill's slug. Add
84
+ `skills: [Skill.fromSlug(factory, "<skill slug>")]` to Engineer Agent sm, md and lg in `main.ts`, as
85
+ `<factory>/README.md`, "After apply", says. Apply as phase 4 says. Without this line, the next apply takes the
86
+ skill away.
87
+
88
+ ## 4. One small real item, end to end
89
+
90
+ Only after the app is reachable:
91
+
92
+ 1. Ask the developer for one small, real bug or feature. Create it by hand in Bugs or Features with
93
+ `npx orchestra work-items create`, and assign it to the Manager Agent, or to the new agent for a new
94
+ environment in an existing factory (section 1). For a private repository, name a
95
+ new bundle of the default branch in the item, as in section 1.
96
+ 2. The description asks for two things beside the fix:
97
+ - the change: a pull request once phase 3 has connected the code host, or until then a patch uploaded as a
98
+ File, which the developer applies and pushes;
99
+ - a report page that shows the change running on the machine: screenshots from the machine endpoint or
100
+ the machine view, and the test result. The agent publishes it as an artifact with
101
+ `orchestra artifacts create`, and names its link in the item.
102
+ 3. Wait as in section 1. Read the report with the developer.
103
+
104
+ ## Exit check
105
+
106
+ The app is reachable at a machine endpoint or a machine view, with a screenshot or a smoke request as proof,
107
+ and the first real item has its change, as a pull request or a patch, and a report page.