software-defence-factory 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # Factory skills
2
2
 
3
- These six original, portable skills are project-local Markdown. They require no AIOS installation. A harness must discover `.agents/skills` or receive the selected SKILL.md explicitly. The export command `node scripts/export-kit.mjs NEW_OUTPUT_DIRECTORY` stages these skills with the portable adoption kit. Copy the needed folders into a target repository under its own accepted instructions before dispatch. Do not overwrite its AGENTS.md.
3
+ These six original, portable skills are project-local Markdown. A harness must discover `.agents/skills` or receive the selected SKILL.md explicitly. The export command `node scripts/export-kit.mjs NEW_OUTPUT_DIRECTORY` stages these skills with the portable adoption kit. Copy the needed folders into a target repository under its own accepted instructions before dispatch. Do not overwrite its AGENTS.md.
4
4
 
5
5
  - [factory-triage](factory-triage/SKILL.md): Turn an incoming factory issue into a bounded disposition and capability request. Use before specification or implementation starts.
6
6
  - [factory-spec](factory-spec/SKILL.md): Write an implementable factory task with observable acceptance criteria, required capabilities and a bounded verification plan.
package/README.md CHANGED
@@ -1,27 +1,35 @@
1
- # Software & Defence Factory
1
+ # Factory
2
2
 
3
3
  A portable method and a local runtime for taking a scoped software task through implementation, checks, independent review and an explicit handoff.
4
4
 
5
- Developed by [Arcitai](https://github.com/arcitai). The CLI is **software-defence-factory**. It works with existing repositories, Codex, Pi or a configured executor. No personal context system is required.
5
+ Published by [Arcitai](https://github.com/arcitai). Invoke **factory** with your existing repositories, Codex, Pi or a configured executor. The npm package remains **software-defence-factory**; the compatibility executable `software-defence-factory` uses the same implementation, state and updater.
6
6
 
7
7
  ## Start here
8
8
 
9
9
  Install the published [npm package](https://www.npmjs.com/package/software-defence-factory). The CLI includes the dashboard; no source checkout is needed.
10
10
 
11
11
  ```sh
12
- npm install --global software-defence-factory
13
- software-defence-factory help
12
+ npm install --global software-defence-factory@latest
13
+ factory help
14
14
  ```
15
15
 
16
- For occasional use: `npx software-defence-factory@latest help`.
16
+ For occasional use: `npm exec --package=software-defence-factory@latest -- factory help`.
17
+
18
+ Starting with 0.11.1, the package provides both executable names. To upgrade an
19
+ older global installation, run
20
+ `npm install --global software-defence-factory@latest` to expose the new `factory`
21
+ executable. Private cached updates keep the old command working but do not add
22
+ global symlinks. Check `command -v factory` first; if it belongs to another tool,
23
+ keep the compatibility command or use the explicit `npm exec` invocation above.
24
+ Do not overwrite it with `--force`. See [installation compatibility](docs/npm.md).
17
25
 
18
26
  Choose the part you need:
19
27
 
20
28
  | Outcome | Command / guide |
21
29
  | --- | --- |
22
30
  | Set up an operator, worker and application | [Setup plan and acceptance checklist](docs/setup.md) |
23
- | Use the method with your existing agent | `software-defence-factory kit --output ./factory-kit` — exports a new staging directory |
24
- | Try the runtime without inference | `software-defence-factory demo` — Docker required; synthetic sample only |
31
+ | Use the method with your existing agent | `factory kit --output ./factory-kit` — exports a new staging directory |
32
+ | Try the runtime without inference | `factory demo` — Docker required; synthetic sample only |
25
33
  | Connect an existing repository | [Runtime quickstart](docs/quickstart.md) |
26
34
  | Understand installation and updates | [npm and npx](docs/npm.md) |
27
35
  | Restore a dashboard after boot or reconnect remotely | [Services and SSH tunnels](docs/services.md) |
@@ -41,7 +49,7 @@ The project dashboard has an **Inbox**, measured **Analytics**, **Agents**, **Sk
41
49
 
42
50
  The optional **defence** workflow accepts scoped incident evidence and produces a private, read-only draft. It does not monitor production or claim verified recovery. See [defence integration](docs/defence-integration.md).
43
51
 
44
- Start setup with `software-defence-factory foundation` and the [Factory Foundation plan](docs/setup.md). No AIOS installation is required.
52
+ Start setup with `factory foundation` and the [Factory Foundation plan](docs/setup.md).
45
53
 
46
54
  ## Repository map
47
55
 
@@ -55,8 +63,6 @@ Start setup with `software-defence-factory foundation` and the [Factory Foundati
55
63
  | `scripts/`, `tests/` | Packaging, qualification, release checks and behavioral tests |
56
64
  | `docs/` | Setup, architecture, recovery, proof and ownership |
57
65
 
58
- The current runtime replaces earlier prototypes. Their source and research remain in Git history; they are not part of the installed package.
59
-
60
66
  ## Contributing
61
67
 
62
68
  Requires Node 22.13+, npm and Git. Docker is needed only for integration qualification.
@@ -304,7 +304,10 @@ try {
304
304
  } else if(command==='kit') {
305
305
  if(!flags.output)throw new Error('kit requires --output NEW_DIRECTORY');
306
306
  await stream(process.execPath,[join(ROOT,'scripts/export-kit.mjs'),resolve(flags.output)]);
307
- } else if(['help','--help','-h'].includes(command))console.log(`Software & Defence Factory ${VERSION} (test release)
307
+ } else if(['help','--help','-h'].includes(command))console.log(`Factory ${VERSION} (test release)
308
+
309
+ Usage: factory <command> [options]
310
+ Compatibility executable: software-defence-factory (same runtime and state)
308
311
 
309
312
  kit --output NEW_DIRECTORY Export the portable method without a runtime
310
313
  demo Install and run a synthetic sample (no model key)
@@ -3,7 +3,7 @@
3
3
  The optional defence workflow receives a bounded incident record through:
4
4
 
5
5
  ```sh
6
- software-defence-factory incident --file /private/path/incident.json --state /private/state/my-app
6
+ factory incident --file /private/path/incident.json --state /private/state/my-app
7
7
  ```
8
8
 
9
9
  Use factory/examples/incident.json as the input schema example. Intake validates scope and evidence, records a digest and deduplicates the event identity. Evidence and reports remain in the private installation. Do not place customer findings in public issues or source control.
package/docs/npm.md CHANGED
@@ -4,24 +4,53 @@ Requires Node 22.13 or later. The method export needs no Docker. Running jobs
4
4
  also requires Git and a running Docker Engine or Docker Desktop on Linux/macOS.
5
5
 
6
6
  ```sh
7
- npm install --global software-defence-factory
8
- software-defence-factory help
7
+ npm install --global software-defence-factory@latest
8
+ factory help
9
9
  ```
10
10
 
11
11
  For a one-off invocation:
12
12
 
13
13
  ```sh
14
- npx software-defence-factory@latest help
14
+ npm exec --package=software-defence-factory@latest -- factory help
15
15
  ```
16
16
 
17
17
  Both commands use the same package. A development checkout is unnecessary.
18
- Use `software-defence-factory kit --output /new/staging/directory` to export the portable
18
+ Use `factory kit --output /new/staging/directory` to export the portable
19
19
  method. It refuses an existing destination and does not modify an app. Use
20
- `software-defence-factory init --repo /path/to/app --harness codex --check "npm ci && npm test"`
20
+ `factory init --repo /path/to/app --harness codex --check "npm ci && npm test"`
21
21
  only when configuring the optional local job runner. `init` does not start jobs,
22
22
  copy skills into the app, or copy account credentials. Runtime jobs receive the
23
23
  bundled policy and skills directly. Model access is configured separately.
24
24
 
25
+ ## Executable and package compatibility
26
+
27
+ Starting with 0.11.1, `factory` and `software-defence-factory` are bin aliases
28
+ for `bin/software-defence-factory.mjs`. They share one runtime, state and updater.
29
+ The npm package is still `software-defence-factory`, published by Arcitai from
30
+ `arcitai/software-and-defence-factory`. Release qualification is tracked in
31
+ [#61](https://github.com/arcitai/software-and-defence-factory/issues/61) and its linked delivery PRs.
32
+
33
+ An older global bootstrap upgraded through the private release cache keeps
34
+ working through `software-defence-factory`, including offline cached dispatch.
35
+ It does **not** gain a global `factory` symlink. To expose both bins with
36
+ 0.11.1 or later, stop and reconcile installations, check `command -v factory`, then run
37
+ `npm install --global software-defence-factory@latest`.
38
+ If that name belongs to another tool, keep the compatibility executable or use
39
+ `npm exec --package=software-defence-factory@latest -- factory ...`. Do not use
40
+ `--force` to replace another program. npm refuses a conflicting unrelated bin.
41
+ Both bin keys point to the same file; tarball tests cover explicit executable
42
+ selection through npm exec and npx. The syntax above avoids relying
43
+ on package-name inference. Never use `npx factory` or `npm install factory` for
44
+ this product.
45
+
46
+ The selected successor package is `factory-sd`, but account/OIDC prerequisites
47
+ and namespace cutover remain pending under [#61](https://github.com/arcitai/software-and-defence-factory/issues/61).
48
+ The issue records `factory` as owned by another project and `factory-sd` as a
49
+ registry 404 on 2026-09-26; availability is not a reservation. Before cutover,
50
+ verify replacement publishing trust, package/updater identity, Actions references,
51
+ redirects and an explicit idle/recoverable upgrade route. Reconcile ambiguous
52
+ external-write receipts without replaying them under a renamed repository.
53
+
25
54
  ## Persistent data
26
55
 
27
56
  The npm CLI stores private runtime data under
@@ -34,7 +63,9 @@ the npx cache, or your application repository.
34
63
  Source checkouts retain their existing `.factory/platform` and
35
64
  `.factory/demo-platform` defaults. Stop the old controller before moving an
36
65
  existing state directory. Update its `factory.json` repository path if necessary;
37
- start a fresh state directory for the native 0.3 runtime. Earlier engine journals are not automatically migrated; keep them separately as evidence.
66
+ retain existing jobs, configuration and evidence. Branding requires no state move
67
+ or migration. State/service/tunnel names, configured image IDs, update keys and
68
+ historical policy/record hashes remain unchanged.
38
69
 
39
70
  ## Automatic updates
40
71
 
@@ -50,10 +81,10 @@ and restores their prior running set without interrupting a job. See
50
81
  [services](services.md) for installation, maintenance recovery and limitations.
51
82
 
52
83
  ```sh
53
- software-defence-factory update --check
54
- software-defence-factory update
55
- software-defence-factory update --auto off
56
- software-defence-factory update --auto on
84
+ factory update --check
85
+ factory update
86
+ factory update --auto off
87
+ factory update --auto on
57
88
  ```
58
89
 
59
90
  Updates use npm with lifecycle scripts disabled and retain immutable releases
@@ -73,8 +104,8 @@ installation or retained attempt needs them.
73
104
 
74
105
  ## Protected evidence compatibility
75
106
 
76
- 0.10.0 recognizes version-1 execution profiles emitted by native **0.8.0,
77
- 0.9.0, 0.9.1 and 0.10.0**. This is an exact allowlist in
107
+ Factory 0.11.1 recognizes version-1 execution profiles emitted by native
108
+ **0.8.0, 0.9.0, 0.9.1, 0.10.0, 0.11.0 and 0.11.1**. This is an exact allowlist in
78
109
  `factory/execution-profile.mjs`, independent of the installed package version;
79
110
  it is not a semver range or an automatic promise for later releases. Unknown
80
111
  runtime strings, unknown profile formats and incomplete legacy acceptance
@@ -101,9 +132,9 @@ neither a reason to discard evidence nor proof of compatibility. Retain
101
132
  unsupported records unchanged and obtain fresh applicable evidence through the
102
133
  normal workflow; never repair them by editing private records or hashes.
103
134
 
104
- The 0.10.0 writer retains the same profile format and original-base, aggregate
105
- single-parent candidate/check/review/approval guarantees. Continuation adds
106
- separate provenance; it is not acceptance evidence. The audited 0.8.0, 0.9.0 and
135
+ Versions 0.11.0 and 0.11.1 use the same protected evidence writer and profile
136
+ format, with original-base, aggregate single-parent candidate/check/review/approval
137
+ guarantees. Continuation adds separate provenance; it is not acceptance evidence. The audited 0.8.0, 0.9.0 and
107
138
  0.9.1 writers remain supported only when their old records meet all current
108
139
  checks. For continuation specifically, the current completed review, successful
109
140
  Build/Verify, protected per-attempt artifacts, current policy and clean candidate
@@ -112,14 +143,10 @@ a checkpoint usable. Browser-disabled 0.8.0 records cannot satisfy a newly
112
143
  enabled browser policy. Missing or unsupported records stay unchanged and
113
144
  unavailable; no schema migration, profile relabeling or policy repair occurs.
114
145
 
115
- #71 shipped 0.9.0 through PR #81 and #84 shipped 0.9.1 through PR #85; both
116
- passed installed qualification, as reported by the lead. For this 0.10.0 slice,
117
- native Verify/Review remain required. The lead owns installed continuation,
118
- disposable protected PR/CI and desktop/narrow light/dark browser qualification
119
- on Z13. Controlled source fixtures do not supply that proof. New publication
120
- still requires the current remote target to equal the original accepted base;
121
- reviewed-candidate continuation preserves that baseline, while target refresh
122
- remains #72.
146
+ New publication still requires the current remote target to equal the original
147
+ accepted base; reviewed-candidate continuation preserves that baseline, while
148
+ target refresh remains #72. See [the verification map](https://github.com/arcitai/software-and-defence-factory/blob/main/docs/proof.md) for delivered
149
+ capabilities and the distinction between source checks and installed proof.
123
150
 
124
151
  ## Release flow
125
152
 
@@ -133,20 +160,27 @@ For a release, update both manifests with `npm version patch --no-git-tag-versio
133
160
  review the change, and push through the project's normal review flow. A code
134
161
  push without a version bump is tested but does not overwrite a published package.
135
162
 
136
- The first release is published by the maintainer. Then configure npm trusted
137
- publishing for GitHub owner `arcitai`, repository `software-and-defence-factory`,
138
- workflow filename `ci.yml`, with direct publishing enabled. Subsequent releases
139
- use short-lived OIDC authentication; no npm write token belongs in the repo or
140
- Z13. The source repository remains private, so npm cannot issue public source
141
- provenance for it. The public npm package contains an explicit runtime/method
163
+ The current trusted-publisher identity is npm package `software-defence-factory`,
164
+ GitHub owner `arcitai`, repository `software-and-defence-factory`,
165
+ workflow filename `ci.yml`. The workflow uses short-lived OIDC authentication.
166
+ The source repository is **public**, but the current workflow explicitly sets
167
+ `NPM_CONFIG_PROVENANCE=false`; OIDC authenticates publication and does not mean
168
+ this release emits npm provenance. No npm write token belongs in the repository
169
+ or agent jobs. The public npm package contains an explicit runtime/method
142
170
  allowlist, excluding operational state, account data and retired research. It includes the explicitly labelled synthetic runtime fixture used by demo and qualification.
143
171
 
144
- Set the GitHub repository variable `NPM_PUBLISH_ENABLED=true` only after that
145
- first publication and trusted-publisher binding are complete. Until then CI
146
- still builds and tests every change, while publishing is deliberately skipped.
172
+ Publication requires repository variable `NPM_PUBLISH_ENABLED=true` and the
173
+ matching npm account binding. Preserve the working identity until replacement
174
+ trust is verified. Changes must pass the normal protected PR/CI flow; do not
175
+ weaken protection or bypass merge checks.
147
176
  After a CLI update, restart a stopped dashboard with `up --state PATH` and refresh
148
177
  the browser to load the new bundled interface. Updates do not replace the code
149
178
  of a controller that is still running.
150
179
 
180
+ The installed native publisher refuses `.github/workflows` changes. Keep that
181
+ guard. Automated GitHub Releases, immutable tags, registry readback and recovery
182
+ after npm succeeds but Release creation fails remain a separate maintainer
183
+ delivery under [#61](https://github.com/arcitai/software-and-defence-factory/issues/61).
184
+
151
185
  References: [npm/npx](https://docs.npmjs.com/cli/v11/commands/npx/),
152
186
  [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/).
package/docs/ownership.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Ownership and provenance
2
2
 
3
- Software & Defence Factory is developed by Arcitai. Original CLI, native Node/SQLite runtime, container boundary, incident intake, updater, method and six skills are maintained in this repository under MIT.
3
+ Factory is developed by Arcitai. Original CLI, native Node/SQLite runtime, container boundary, incident intake, updater, method and six skills are maintained in this repository under MIT.
4
4
 
5
5
  The dashboard retains the selected third-party interface and interaction model, with modified branding and a factory-owned API integration. Its original copyright, source revision and permission notice are retained in [THIRD_PARTY_NOTICES.md](../THIRD_PARTY_NOTICES.md), together with notices for bundled UI components and fonts. Those notices are required source attribution, not runtime dependencies or product branding.
6
6
 
7
- The installed package includes no personal AIOS home, private owner memory or external agent plugin. A skill is an instruction, not a bundled browser, model subscription, provider account or security scanner. Codex/Pi are separately licensed tools included by the pinned Docker build; the operator supplies authorized inference access.
7
+ A skill is an instruction, not a bundled browser, model subscription, provider account or security scanner. Codex/Pi are separately licensed tools included by the pinned Docker build; the operator supplies authorized inference access.
8
8
 
9
- Earlier research and prototype implementations remain in Git history. Their historical evaluation claims do not establish qualification of the current runtime. Current evidence is recorded in [proof](proof.md).
9
+ Current verification boundaries are recorded in [proof](https://github.com/arcitai/software-and-defence-factory/blob/main/docs/proof.md).
@@ -2,18 +2,18 @@
2
2
 
3
3
  For a new execution host or remote operator, start with the [setup plan](setup.md).
4
4
 
5
- Install Node 22.13+, Git and Docker Engine/Desktop. Use an unprivileged account with Docker access. Install `software-defence-factory` through npm, or invoke the same package with npx. No factory source checkout is required.
5
+ Install Node 22.13+, Git and Docker Engine/Desktop. Use an unprivileged account with Docker access. Install `software-defence-factory` through npm, or use `npm exec --package=software-defence-factory@latest -- factory help`. No factory source checkout is required.
6
6
 
7
7
  ## Qualify a synthetic installation
8
8
 
9
9
  ```sh
10
- software-defence-factory demo
10
+ factory demo
11
11
  ```
12
12
 
13
13
  Open the printed localhost URL, inspect the sample task and its files, then approve the handoff. This changes only an isolated synthetic repository and makes no inference calls. Once the sample finishes:
14
14
 
15
15
  ```sh
16
- software-defence-factory qualify --state /absolute/path/printed/by/demo
16
+ factory qualify --state /absolute/path/printed/by/demo
17
17
  ```
18
18
 
19
19
  The qualification intentionally creates failed, cancelled and interrupted tasks. They are expected evidence of failure handling. Never point qualification at an application installation.
@@ -23,9 +23,9 @@ The qualification intentionally creates failed, cancelled and interrupted tasks.
23
23
  Commit an intentional, reviewed starting point in the application first. Jobs clone committed code only; uncommitted work stays in the source checkout.
24
24
 
25
25
  ```sh
26
- software-defence-factory init --repo /absolute/path/to/app --harness codex --check "npm ci && npm test" --source-ref main --state /private/state/my-app --port 7331
27
- software-defence-factory install --state /private/state/my-app
28
- software-defence-factory doctor --state /private/state/my-app
26
+ factory init --repo /absolute/path/to/app --harness codex --check "npm ci && npm test" --source-ref main --state /private/state/my-app --port 7331
27
+ factory install --state /private/state/my-app
28
+ factory doctor --state /private/state/my-app
29
29
  ```
30
30
 
31
31
  `init --source-ref` selects the configured default ref (`HEAD` when omitted). Each job resolves that ref, or an explicit `--source-ref` on `run`/`issue start`, in the configured repository and durably retains its commit before acknowledging admission. It records the canonical GitHub origin identity when available; the CLI and dashboard show the requested ref and resolved SHA. Task text and reference links do not select a repository, source ref or PR target.
@@ -71,8 +71,8 @@ container. Host loopback addresses do not automatically refer to the host from
71
71
  Docker. The package does not automatically expose Ollama or import models.
72
72
 
73
73
  ```sh
74
- software-defence-factory up --state /private/state/my-app
75
- software-defence-factory run --file task.md --source-ref main --state /private/state/my-app
74
+ factory up --state /private/state/my-app
75
+ factory run --file task.md --source-ref main --state /private/state/my-app
76
76
  ```
77
77
 
78
78
  A task should describe the accepted outcome, allowed scope and observable checks. The CLI also accepts `--issue https://github.com/owner/repo/issues/123` for an issue belonging to the configured origin; it uses the operator's existing gh access outside the job. The dashboard supports the same task workflow. Source text and links do not grant additional authority.
@@ -90,7 +90,7 @@ canonical GitHub origin and an explicit target while initializing the private
90
90
  installation:
91
91
 
92
92
  ```sh
93
- software-defence-factory init --repo /absolute/path/to/app --harness codex \
93
+ factory init --repo /absolute/path/to/app --harness codex \
94
94
  --check "npm ci && npm test" --source-ref main \
95
95
  --delivery-provider github \
96
96
  --delivery-repository https://github.com/OWNER/REPO \
@@ -109,7 +109,7 @@ After the ordinary check, independent review and operator approval complete,
109
109
  use **Publish accepted candidate as draft PR** in task details or run:
110
110
 
111
111
  ```sh
112
- software-defence-factory publish JOB_ID --state /private/state/my-app
112
+ factory publish JOB_ID --state /private/state/my-app
113
113
  ```
114
114
 
115
115
  Trusted publication requires protected per-run execution records for native
@@ -179,8 +179,8 @@ Build a compatible application image on the execution host, then select its exis
179
179
  local tag through the CLI:
180
180
 
181
181
  ```sh
182
- software-defence-factory install --image LOCAL_IMAGE_REF --state /private/state/my-app
183
- software-defence-factory doctor --state /private/state/my-app
182
+ factory install --image LOCAL_IMAGE_REF --state /private/state/my-app
183
+ factory doctor --state /private/state/my-app
184
184
  ```
185
185
 
186
186
  Selection resolves and retains the immutable image ID. It does not pull or build
@@ -228,5 +228,5 @@ is unnecessary for this CLI. Optional
228
228
  process settings are `SDF_AUTO_UPDATE=0` (skip automatic CLI update checks),
229
229
  `XDG_STATE_HOME`, `XDG_DATA_HOME` and `XDG_CONFIG_HOME` (user-owned state, release
230
230
  and service locations). They must be exported in the process environment.
231
- Legacy prototype names such as `FACTORY_WORKER_CONFIG`, `FACTORY_MODEL`, `PORT`
231
+ Unsupported environment variables such as `FACTORY_WORKER_CONFIG`, `FACTORY_MODEL`, `PORT`
232
232
  and `FACTORY_DEMO` are not supported. See [concepts](concepts.md).
package/docs/recovery.md CHANGED
@@ -51,7 +51,7 @@ verdict is `changes` or `blocked`, or at the normal approval gate. The CLI
51
51
  provides the same action:
52
52
 
53
53
  ```sh
54
- software-defence-factory revise JOB_ID --file /private/revision.md --state /private/state/project
54
+ factory revise JOB_ID --file /private/revision.md --state /private/state/project
55
55
  ```
56
56
 
57
57
  Feedback must be nonempty and at most 4,000 characters. It is accumulated in the
@@ -193,8 +193,8 @@ separately from integration or deployment.
193
193
  Inspect the same installation before recovery:
194
194
 
195
195
  ```sh
196
- software-defence-factory status --state /private/state/project
197
- software-defence-factory publish JOB_ID --state /private/state/project
196
+ factory status --state /private/state/project
197
+ factory publish JOB_ID --state /private/state/project
198
198
  ```
199
199
 
200
200
  After a lost response or controller restart, repeat `publish`. The controller
@@ -300,8 +300,8 @@ provider writes. Inspect the exact branch in GitHub, then use the task action
300
300
  the CLI:
301
301
 
302
302
  ```sh
303
- software-defence-factory status --state /private/state/project
304
- software-defence-factory abandon-delivery JOB_ID --branch-sha INSPECTED_SHA --state /private/state/project
303
+ factory status --state /private/state/project
304
+ factory abandon-delivery JOB_ID --branch-sha INSPECTED_SHA --state /private/state/project
305
305
  ```
306
306
 
307
307
  The controller checks the latest run, saved delivery identity, current branch
@@ -339,11 +339,11 @@ Use one explicit starting point for a current software review with a returned
339
339
 
340
340
  ```sh
341
341
  # Existing default: restore admitted source, discarding candidate code from the next Build.
342
- software-defence-factory revise JOB_ID --file feedback.md --state PATH
342
+ factory revise JOB_ID --file feedback.md --state PATH
343
343
  # Keep this job’s current immutable reviewed tree; keep its source/delivery baseline.
344
- software-defence-factory revise JOB_ID --file feedback.md --from reviewed-candidate --state PATH
344
+ factory revise JOB_ID --file feedback.md --from reviewed-candidate --state PATH
345
345
  # Existing source replacement: resolve and retain a deliberately different baseline.
346
- software-defence-factory revise JOB_ID --file feedback.md --source-ref REF --state PATH
346
+ factory revise JOB_ID --file feedback.md --source-ref REF --state PATH
347
347
  ```
348
348
 
349
349
  `--from admitted-source` names the default explicitly. `--from` and
package/docs/services.md CHANGED
@@ -10,9 +10,9 @@ root controller. macOS can still run a local controller with `up`.
10
10
  Configure and install a runtime using the [quickstart](quickstart.md), then:
11
11
 
12
12
  ```sh
13
- software-defence-factory stop --state /absolute/private/state
14
- software-defence-factory service install --state /absolute/private/state
15
- software-defence-factory service status --state /absolute/private/state
13
+ factory stop --state /absolute/private/state
14
+ factory service install --state /absolute/private/state
15
+ factory service status --state /absolute/private/state
16
16
  ```
17
17
 
18
18
  Installation enables and starts exactly this controller. It does not submit a
@@ -54,11 +54,11 @@ changes system-wide Docker, firewall or login configuration. Systemd retries
54
54
  startup every 15 seconds if Docker or the configured image is unavailable.
55
55
 
56
56
  ```sh
57
- software-defence-factory service stop --state /absolute/private/state
58
- software-defence-factory service start --state /absolute/private/state
59
- software-defence-factory service restart --state /absolute/private/state
60
- software-defence-factory service logs --state /absolute/private/state
61
- software-defence-factory service uninstall --state /absolute/private/state
57
+ factory service stop --state /absolute/private/state
58
+ factory service start --state /absolute/private/state
59
+ factory service restart --state /absolute/private/state
60
+ factory service logs --state /absolute/private/state
61
+ factory service uninstall --state /absolute/private/state
62
62
  ```
63
63
 
64
64
  `up` and `stop` detect a managed installation and use its service manager, so a
@@ -77,12 +77,12 @@ The remote dashboard must bind to loopback and the machines must be reachable
77
77
  (for example through an existing private VPN). Use a configured SSH alias:
78
78
 
79
79
  ```sh
80
- software-defence-factory tunnel install --host worker --port 7345
81
- software-defence-factory tunnel status --host worker --port 7345
82
- software-defence-factory tunnel logs --host worker --port 7345
83
- software-defence-factory tunnel stop --host worker --port 7345
84
- software-defence-factory tunnel start --host worker --port 7345
85
- software-defence-factory tunnel uninstall --host worker --port 7345
80
+ factory tunnel install --host worker --port 7345
81
+ factory tunnel status --host worker --port 7345
82
+ factory tunnel logs --host worker --port 7345
83
+ factory tunnel stop --host worker --port 7345
84
+ factory tunnel start --host worker --port 7345
85
+ factory tunnel uninstall --host worker --port 7345
86
86
  ```
87
87
 
88
88
  Visit `http://127.0.0.1:7345`. The local and remote ports are intentionally equal
@@ -101,10 +101,10 @@ not a Factory network dependency. No root LaunchDaemon is installed.
101
101
  ## Updating an always-running controller
102
102
 
103
103
  ```sh
104
- software-defence-factory service update
105
- software-defence-factory service updates --auto on
106
- software-defence-factory service updates --auto status
107
- software-defence-factory service updates --auto off
104
+ factory service update
105
+ factory service updates --auto on
106
+ factory service updates --auto status
107
+ factory service updates --auto off
108
108
  ```
109
109
 
110
110
  `service update` manages all registered controllers for the current user. It
package/docs/setup.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Factory Foundation: repository and execution setup
2
2
 
3
- The operator skill is available through `software-defence-factory foundation`.
3
+ The operator skill is available through `factory foundation`.
4
4
  See [Factory concepts](concepts.md) for host, worker, harness and agent roles.
5
5
 
6
- Use this plan for a new installation or when moving an existing Factory to a
6
+ Use this plan for a new installation or when moving an existing Factory to an
7
7
  execution host. Complete the applicable checkpoints in order and record the
8
8
  result in a **private** copy of the checklist below. The plan applies to any
9
- operator/worker names and any suitable private network; it requires no personal
10
- context system, particular VPN provider or Factory source checkout.
9
+ operator/worker names and any suitable private network. Install the npm package
10
+ on the execution host; a source checkout is unnecessary.
11
11
 
12
12
  The operator owns access and infrastructure choices. Factory maintainers own
13
13
  this plan and the linked command guides and update them with behavior changes.
@@ -32,9 +32,9 @@ installed package.
32
32
  One installation owns one repository and port. A synthetic qualification
33
33
  installation can provide a running dashboard while product controllers remain
34
34
  stopped. There is no multi-project controller or second scheduler hidden in
35
- this plan. Keep unrelated personal agent configuration on its existing host.
35
+ this plan.
36
36
 
37
- For method-only adoption, run `software-defence-factory kit --output NEW_DIRECTORY`
37
+ For method-only adoption, run `factory kit --output NEW_DIRECTORY`
38
38
  and follow [the adoption guide](../kit/README.md). The remaining host/runtime
39
39
  steps apply only when using Factory's optional controller.
40
40
 
@@ -75,9 +75,9 @@ work, and required host dependencies have a documented startup/recovery owner.
75
75
  ## 3. Install the package and qualify the runtime
76
76
 
77
77
  ```sh
78
- npm install --global software-defence-factory
79
- software-defence-factory --version
80
- software-defence-factory help
78
+ npm install --global software-defence-factory@latest
79
+ factory --version
80
+ factory help
81
81
  ```
82
82
 
83
83
  Use a user-writable npm prefix or the existing Node manager; do not turn the
@@ -90,9 +90,9 @@ Node executable available. See [installation and updates](npm.md).
90
90
  Use a **separate synthetic state and unused port** to exercise the runtime:
91
91
 
92
92
  ```sh
93
- software-defence-factory demo --state /private/state/runtime-proof --port 7345
93
+ factory demo --state /private/state/runtime-proof --port 7345
94
94
  # Inspect and finish the sample handoff before qualification.
95
- software-defence-factory qualify --state /private/state/runtime-proof
95
+ factory qualify --state /private/state/runtime-proof
96
96
  ```
97
97
 
98
98
  These commands deliberately create synthetic jobs, including failed/interrupted
@@ -124,9 +124,9 @@ Before admitting development work, establish:
124
124
  Configure a new installation using [the quickstart](quickstart.md):
125
125
 
126
126
  ```sh
127
- software-defence-factory init --repo /absolute/path/to/app --harness pi --check "npm ci && npm test" --state /private/state/my-app --port 7331
128
- software-defence-factory install --state /private/state/my-app
129
- software-defence-factory doctor --state /private/state/my-app
127
+ factory init --repo /absolute/path/to/app --harness pi --check "npm ci && npm test" --state /private/state/my-app --port 7331
128
+ factory install --state /private/state/my-app
129
+ factory doctor --state /private/state/my-app
130
130
  ```
131
131
 
132
132
  Replace the harness/check/paths with the accepted application profile. Plain
@@ -134,7 +134,7 @@ Replace the harness/check/paths with the accepted application profile. Plain
134
134
  it on the worker first and select its existing local tag instead:
135
135
 
136
136
  ```sh
137
- software-defence-factory install --image LOCAL_IMAGE_REF --state /private/state/my-app
137
+ factory install --image LOCAL_IMAGE_REF --state /private/state/my-app
138
138
  ```
139
139
 
140
140
  This command checks the local Docker daemon, records and retains the exact image
@@ -184,7 +184,7 @@ delivery for this installation, configure the exact canonical repository and
184
184
  target while initializing it, for example:
185
185
 
186
186
  ```sh
187
- software-defence-factory init --repo /absolute/path/to/app --harness pi \
187
+ factory init --repo /absolute/path/to/app --harness pi \
188
188
  --check "npm ci && npm test" --source-ref main \
189
189
  --delivery-provider github \
190
190
  --delivery-repository https://github.com/OWNER/REPO \
@@ -245,11 +245,11 @@ If queue ownership/state is uncertain, reconcile it before enabling autostart.
245
245
  On the Linux worker, select the state that should stay available:
246
246
 
247
247
  ```sh
248
- software-defence-factory stop --state /private/state/runtime-proof
249
- software-defence-factory service install --state /private/state/runtime-proof
250
- software-defence-factory service status --state /private/state/runtime-proof
251
- software-defence-factory service updates --auto on
252
- software-defence-factory service updates --auto status
248
+ factory stop --state /private/state/runtime-proof
249
+ factory service install --state /private/state/runtime-proof
250
+ factory service status --state /private/state/runtime-proof
251
+ factory service updates --auto on
252
+ factory service updates --auto status
253
253
  ```
254
254
 
255
255
  Follow [services](services.md) for user lingering, existing Docker group
@@ -261,8 +261,8 @@ for the intended account through the host's administrator.
261
261
  On the operator machine, stop any old manual tunnel, then:
262
262
 
263
263
  ```sh
264
- software-defence-factory tunnel install --host factory-worker --port 7345
265
- software-defence-factory tunnel status --host factory-worker --port 7345
264
+ factory tunnel install --host factory-worker --port 7345
265
+ factory tunnel status --host factory-worker --port 7345
266
266
  ```
267
267
 
268
268
  Use the actual selected dashboard port on both sides. macOS tunnels start at
@@ -36,8 +36,8 @@ browser_image="$(docker image inspect --format '{{.Id}}' software-defence-factor
36
36
  Run the readiness check from the selected installation:
37
37
 
38
38
  ```sh
39
- software-defence-factory web probe --state /private/state/project
40
- software-defence-factory doctor --state /private/state/project
39
+ factory web probe --state /private/state/project
40
+ factory doctor --state /private/state/project
41
41
  ```
42
42
 
43
43
  The probe runs a real headless Chromium click and result assertion in a bounded,
@@ -150,11 +150,11 @@ normal sample handoff, stop that controller, then run the exact qualification
150
150
  command with the already-built browser image ID:
151
151
 
152
152
  ```sh
153
- software-defence-factory demo --state /private/state/sdf-web-proof --port 7348
153
+ factory demo --state /private/state/sdf-web-proof --port 7348
154
154
  # Review and approve the synthetic demo task in its dashboard.
155
- software-defence-factory stop --state /private/state/sdf-web-proof
155
+ factory stop --state /private/state/sdf-web-proof
156
156
  browser_image="$(docker image inspect --format '{{.Id}}' software-defence-factory-playwright:1.63.0)"
157
- software-defence-factory qualify-web --state /private/state/sdf-web-proof --image "$browser_image"
157
+ factory qualify-web --state /private/state/sdf-web-proof --image "$browser_image"
158
158
  ```
159
159
 
160
160
  The installed command probes actual Chromium interaction, then runs a
package/docs/workflows.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Roles, skills and work
2
2
 
3
3
  Read [Factory concepts](concepts.md) for the shared vocabulary. Inspect the actual
4
- installation with `software-defence-factory definition --state PATH`, or its
4
+ installation with `factory definition --state PATH`, or its
5
5
  Agents, Skills and Definition pages. Both read the same effective catalog.
6
6
 
7
7
  Software follows **Implement → Check → Review → Accept & hand off**. Implement
@@ -87,18 +87,18 @@ GitHub projects, assignees and arbitrary issue form extensions are not applied.
87
87
  CLI equivalents (the selected controller must be running):
88
88
 
89
89
  ```sh
90
- software-defence-factory issue connection --state PATH
91
- software-defence-factory inbox --state PATH --page 1 --issue-state open
90
+ factory issue connection --state PATH
91
+ factory inbox --state PATH --page 1 --issue-state open
92
92
  # Explicit legacy execution-only JSON array:
93
- software-defence-factory inbox --state PATH --source factory
94
- software-defence-factory issue templates --state PATH
95
- software-defence-factory issue draft --state PATH --template bug-report.yml --sha TEMPLATE_SHA --file answers.json > draft.json
96
- software-defence-factory issue create --state PATH --draft draft.json --key release-board-fix-01
97
- software-defence-factory issue submissions --state PATH
98
- software-defence-factory issue recover --state PATH --key release-board-fix-01
93
+ factory inbox --state PATH --source factory
94
+ factory issue templates --state PATH
95
+ factory issue draft --state PATH --template bug-report.yml --sha TEMPLATE_SHA --file answers.json > draft.json
96
+ factory issue create --state PATH --draft draft.json --key release-board-fix-01
97
+ factory issue submissions --state PATH
98
+ factory issue recover --state PATH --key release-board-fix-01
99
99
  # Explicit execution, independent of creation:
100
- software-defence-factory issue start --state PATH --url URL --workflow software --brief-file operator.md
101
- software-defence-factory issue start --state PATH --file brief.md --title "Investigate supplied evidence" --workflow defence --source-ref main
100
+ factory issue start --state PATH --url URL --workflow software --brief-file operator.md
101
+ factory issue start --state PATH --file brief.md --title "Investigate supplied evidence" --workflow defence --source-ref main
102
102
  ```
103
103
 
104
104
  `--brief-file` is optional, UTF-8, at most 16000 characters and valid only with
@@ -7,11 +7,12 @@ import { effectiveInferenceProvider } from './model-environment.mjs';
7
7
  import { expectedWebStories, webPolicyHash } from './web-verification.mjs';
8
8
 
9
9
  // Audited v1 protected evidence writers: 0.8.0 (380f749), 0.9.0 (cdaadef),
10
- // 0.9.1, 0.10.0 and 0.11.0 (unchanged protected evidence writers). Deliberately independent of VERSION: a release bump is not
10
+ // 0.9.1, 0.10.0, 0.11.0 and 0.11.1 (unchanged protected evidence writers).
11
+ // Deliberately independent of VERSION: a release bump is not
11
12
  // evidence compatibility. Re-audit this list for every trust-relevant writer,
12
13
  // isolation or validation change; remove versions whose guarantees no longer
13
14
  // satisfy current policy. See docs/npm.md. This predicate alone grants no trust.
14
- const SUPPORTED_EXECUTION_RUNTIMES_V1 = new Set(['0.8.0', '0.9.0', '0.9.1', '0.10.0', '0.11.0']);
15
+ const SUPPORTED_EXECUTION_RUNTIMES_V1 = new Set(['0.8.0', '0.9.0', '0.9.1', '0.10.0', '0.11.0', '0.11.1']);
15
16
 
16
17
  export function isSupportedExecutionProfile(profile) {
17
18
  return profile?.version === 1 && SUPPORTED_EXECUTION_RUNTIMES_V1.has(profile.runtimeVersion);
@@ -111,7 +111,7 @@ function environment() {
111
111
  }
112
112
  export function serviceDefinition(state) {
113
113
  configAt(state);
114
- return systemdUnit({ description: 'Software & Defence Factory', argv: [process.execPath, join(ROOT, 'bin/software-defence-factory.mjs'), 'serve', '--state', state], directory: homedir(), environment: environment() });
114
+ return systemdUnit({ description: 'Factory', argv: [process.execPath, join(ROOT, 'bin/software-defence-factory.mjs'), 'serve', '--state', state], directory: homedir(), environment: environment() });
115
115
  }
116
116
  async function install(kind, state, flags) {
117
117
  userOnly();
@@ -145,7 +145,7 @@ async function install(kind, state, flags) {
145
145
  record.unit = `${id}.service`;
146
146
  record.file = process.platform === 'linux' ? join(userUnits, record.unit) : join(homedir(), 'Library/LaunchAgents', `${id}.plist`);
147
147
  record.log = join(records, `${id}.log`);
148
- const definition = process.platform === 'linux' ? systemdUnit({ description: `Software & Defence Factory ${kind}`, argv, directory: homedir(), environment: record.environment })
148
+ const definition = process.platform === 'linux' ? systemdUnit({ description: `Factory ${kind}`, argv, directory: homedir(), environment: record.environment })
149
149
  : launchAgent({ id, argv, directory: homedir(), log: record.log, environment: record.environment });
150
150
  if (existsSync(record.file)) throw new Error(`Refusing to overwrite an unregistered service: ${record.file}`);
151
151
  mkdirSync(dirname(record.file), { recursive: true, mode: 0o700 }); mkdirSync(records, { recursive: true, mode: 0o700 });
@@ -235,7 +235,7 @@ async function performUpdate(latest, download) {
235
235
  priorVersions.set(record.id, value); return value;
236
236
  }));
237
237
  if (runningVersions.some(value => !/^\d+\.\d+\.\d+$/.test(value || ''))) throw new Error('Cannot verify the runtime version of a managed controller');
238
- if (!newer(version, current) && runningVersions.every(value => !newer(version, value))) { console.log(`software-defence-factory ${current} is up to date.`); return; }
238
+ if (!newer(version, current) && runningVersions.every(value => !newer(version, value))) { console.log(`Factory ${current} is up to date.`); return; }
239
239
  const unowned = busyInstallations().filter(state => !live.some(record => record.state === state));
240
240
  if (unowned.length) throw new Error('Unmanaged controllers or executor fences block the update: ' + unowned.join(', '));
241
241
  // Reserve idle controllers before downloads. All mutating API actions are
@@ -289,7 +289,7 @@ function automaticUpdates(mode) {
289
289
  }
290
290
  if (existsSync(record)) { console.log('Scheduled updates are already installed.'); return; }
291
291
  if (existsSync(timer) || existsSync(service)) throw new Error('Refusing to overwrite an unregistered update unit');
292
- const serviceText = systemdUnit({ description: 'Software & Defence Factory idle update', argv: [process.execPath, launcher(), 'service', 'update'], directory: homedir(), environment: environment(), oneshot: true });
292
+ const serviceText = systemdUnit({ description: 'Factory idle update', argv: [process.execPath, launcher(), 'service', 'update'], directory: homedir(), environment: environment(), oneshot: true });
293
293
  const timerText = `[Unit]\nDescription=Check Factory updates daily when idle\n\n[Timer]\nOnCalendar=daily\nRandomizedDelaySec=1h\nPersistent=true\n\n[Install]\nWantedBy=timers.target\n`;
294
294
  mkdirSync(userUnits, { recursive: true, mode: 0o700 });
295
295
  writeFileSync(service, serviceText, { mode: 0o600 }); writeFileSync(timer, timerText, { mode: 0o600 });
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta name="color-scheme" content="dark" />
7
- <title>Software &amp; Defence Factory</title>
7
+ <title>Factory — Software &amp; Defence</title>
8
8
  <script type="module" crossorigin src="/assets/index-BUCK1R7u.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-BQZGHA6-.css">
10
10
  </head>
@@ -114,14 +114,14 @@ export async function bootstrap(args) {
114
114
  const latest = await latestVersion();
115
115
  if (explicit && args[1] === '--check') { console.log(JSON.stringify({ current: selectedVersion, latest, available: newer(latest, selectedVersion), automatic: preferences.enabled })); return 0; }
116
116
  if (newer(latest, selectedVersion)) {
117
- console.error(`Updating ${PACKAGE} ${selectedVersion} → ${latest}…`);
117
+ console.error(`Updating Factory (${PACKAGE}) ${selectedVersion} → ${latest}…`);
118
118
  installRelease(latest);
119
119
  // Downloads are immutable. A newly started controller keeps its version;
120
120
  // do not switch the next CLI process to a new release while it is active.
121
121
  if (busyInstallations().length) throw new Error('Update downloaded; activation deferred while an installation is running.');
122
122
  preferences.version = latest; save(preferencePath, preferences); selectedVersion = latest;
123
123
  }
124
- if (explicit) { console.log(`${PACKAGE} ${selectedVersion} is up to date. Runtime, credentials and jobs were preserved.`); return 0; }
124
+ if (explicit) { console.log(`Factory ${selectedVersion} is up to date. Runtime, credentials and jobs were preserved.`); return 0; }
125
125
  } catch (error) {
126
126
  if (explicit) throw error;
127
127
  // An offline registry must never prevent a local command from working.
package/kit/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Adopt the factory method
2
2
 
3
- Software & Defence Factory gives an existing app a shared method for development, security and review. Keep the app's architecture, code, CI, hosting and established instructions.
3
+ Factory gives an existing app a shared method for development, security and review. Keep the app's architecture, code, CI, hosting and established instructions.
4
4
 
5
5
  ## With the local runtime
6
6
 
@@ -8,7 +8,7 @@ Use the CLI's `init` and installation workflow. Jobs receive policy and the six
8
8
 
9
9
  ## With your existing agent
10
10
 
11
- Export a new staging directory with `software-defence-factory kit --output NEW_DIRECTORY`. Give that directory to the app's agent and ask it to adopt the relevant method on a branch:
11
+ Export a new staging directory with `factory kit --output NEW_DIRECTORY`. Give that directory to the app's agent and ask it to adopt the relevant method on a branch:
12
12
 
13
13
  > Read the app's instructions, architecture, tests and CI first. Apply the supplied factory method within its existing authority. Fill the installation record from the repository and known choices, merge intentionally, preserve existing files and report what was connected, tested or still missing. Start manually. Accounts, publishing and deployment follow my existing mandate.
14
14
 
package/kit/repository.md CHANGED
@@ -81,7 +81,7 @@ at the intended SHA until the current runtime has cloned it, and compare the
81
81
  candidate's recorded base before acceptance. Admission-time source snapshots are
82
82
  tracked separately in Factory #28; naming a SHA in task text does not pin it.
83
83
 
84
- Submit the selected issue with `software-defence-factory run --issue URL --state
84
+ Submit the selected issue with `factory run --issue URL --state
85
85
  PATH`, or submit a reviewed task file using `run --file`. Issue submission uses
86
86
  the operator's `gh` authentication and checks the issue against the configured
87
87
  origin. The dashboard and `issue create` can create a GitHub issue through the selected
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: factory-foundation
3
- description: Prepare or assess a repository and its execution host for Software & Defence Factory, including CI, access, harness configuration, services and a bounded qualification.
3
+ description: Prepare or assess a repository and its execution host for Factory, including CI, access, harness configuration, services and a bounded qualification.
4
4
  ---
5
5
 
6
6
  # Factory Foundation
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "software-defence-factory",
3
- "version": "0.11.0",
4
- "description": "Scoped software delivery and defence investigations with isolated jobs, evidence and review",
3
+ "version": "0.11.1",
4
+ "description": "Factory: scoped software delivery and defence investigations with isolated jobs, evidence and review",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "engines": {
8
8
  "node": ">=22.13.0"
9
9
  },
10
10
  "bin": {
11
+ "factory": "bin/software-defence-factory.mjs",
11
12
  "software-defence-factory": "bin/software-defence-factory.mjs"
12
13
  },
13
14
  "repository": {
@@ -30,7 +30,7 @@ if (args.length === 1 && args[0] === "--help") {
30
30
  // Repository-specific security contact links are deliberately not exported.
31
31
  // Read only the public kit allowlist, before creating anything at destination.
32
32
  const files = new Map([...sources].map(([target, source]) => [target, readFileSync(join(root, source))]));
33
- files.set("START-HERE.md", Buffer.from("# Software & Defence Factory kit\n\nRead [the adoption guide](.factory-kit/README.md). The kit folders start with a dot and may be hidden in your file browser. This is a staged package; no app, workflow or service has been configured.\n"));
33
+ files.set("START-HERE.md", Buffer.from("# Factory kit\n\nRead [the adoption guide](.factory-kit/README.md). The kit folders start with a dot and may be hidden in your file browser. This is a staged package; no app, workflow or service has been configured.\n"));
34
34
  let sourceRevision = null, sourceDirty = null;
35
35
  try {
36
36
  const git = (args) => execFileSync("git", args, { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();