autonomous-sdlc-harness 0.2.0 → 0.4.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.
Files changed (78) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +0 -0
  3. package/dist/commands/docs.js +2 -1
  4. package/dist/commands/docs.js.map +1 -1
  5. package/dist/commands/doctor.js +56 -6
  6. package/dist/commands/doctor.js.map +1 -1
  7. package/dist/commands/init.js +107 -20
  8. package/dist/commands/init.js.map +1 -1
  9. package/dist/config/check.js +11 -4
  10. package/dist/config/check.js.map +1 -1
  11. package/dist/config/model.js +25 -0
  12. package/dist/config/model.js.map +1 -1
  13. package/dist/core/defaultBranchPush.js +26 -0
  14. package/dist/core/defaultBranchPush.js.map +1 -0
  15. package/dist/core/git.js +61 -0
  16. package/dist/core/git.js.map +1 -1
  17. package/dist/core/paths.js +22 -2
  18. package/dist/core/paths.js.map +1 -1
  19. package/dist/core/prompt.js +6 -2
  20. package/dist/core/prompt.js.map +1 -1
  21. package/dist/core/writer.js +2 -0
  22. package/dist/core/writer.js.map +1 -1
  23. package/dist/doctor/checks.js +482 -73
  24. package/dist/doctor/checks.js.map +1 -1
  25. package/dist/generators/githubWorkflows.js +66 -0
  26. package/dist/generators/githubWorkflows.js.map +1 -0
  27. package/dist/generators/notifications.js +105 -19
  28. package/dist/generators/notifications.js.map +1 -1
  29. package/dist/generators/outerLoopScripts.js +17 -3
  30. package/dist/generators/outerLoopScripts.js.map +1 -1
  31. package/dist/generators/permissionProfile.js +141 -21
  32. package/dist/generators/permissionProfile.js.map +1 -1
  33. package/dist/generators/projectSettings.js +2 -1
  34. package/dist/generators/projectSettings.js.map +1 -1
  35. package/dist/generators/repoRoot.js +23 -4
  36. package/dist/generators/repoRoot.js.map +1 -1
  37. package/dist/generators/stateDir.js +9 -3
  38. package/dist/generators/stateDir.js.map +1 -1
  39. package/dist/machine/paths.js +4 -1
  40. package/dist/machine/paths.js.map +1 -1
  41. package/dist/remote/githubActions.js +86 -0
  42. package/dist/remote/githubActions.js.map +1 -0
  43. package/dist/retrieval/queryLog.js +6 -4
  44. package/dist/retrieval/queryLog.js.map +1 -1
  45. package/dist/retrieval/runtime.js +46 -33
  46. package/dist/retrieval/runtime.js.map +1 -1
  47. package/dist/retrieval/search.js +21 -10
  48. package/dist/retrieval/search.js.map +1 -1
  49. package/dist/retrieval/server.js +1 -1
  50. package/dist/retrieval/setup.js +2 -1
  51. package/dist/retrieval/setup.js.map +1 -1
  52. package/package.json +2 -2
  53. package/templates/README.md +3 -2
  54. package/templates/claude/context/conventions.md +1 -1
  55. package/templates/claude/context/layer.md +1 -1
  56. package/templates/claude/push-notify.env.example +7 -2
  57. package/templates/claude/settings.autonomous.json +1 -1
  58. package/templates/github/workflows/harness-resume.yml +124 -0
  59. package/templates/github/workflows/harness-run.yml +446 -0
  60. package/templates/repo/gitignore +11 -1
  61. package/templates/scripts/README.md +1 -1
  62. package/templates/scripts/autonomous-watcher.sh +1296 -169
  63. package/templates/scripts/flow-walker.sh +629 -0
  64. package/templates/scripts/flows/task_plan_writing.graph.json +192 -0
  65. package/templates/scripts/lib/flow-walker-gates.sh +165 -0
  66. package/templates/scripts/lib/harness-run-lib.sh +595 -18
  67. package/templates/scripts/remote-run.sh +1784 -0
  68. package/templates/scripts/restart-watcher.sh +21 -1
  69. package/templates/scripts/run-test-suite.sh +182 -0
  70. package/templates/scripts/scratch-run.sh +2 -1
  71. package/templates/state-dir/README-root.md +1 -1
  72. package/templates/state-dir/autonomous_logs/README.md +2 -2
  73. package/templates/state-dir/improvement_observations/README.md +2 -0
  74. package/templates/state-dir/scratch/README.md +1 -1
  75. package/templates/state-dir/test_fix_plan_reviews/README.md +9 -0
  76. package/templates/state-dir/test_fix_plans/README.md +9 -0
  77. package/templates/state-dir/test_fix_point_reviews/README.md +9 -0
  78. package/templates/state-dir/test_run_logs/README.md +11 -0
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * How the docs-retrieval packages reach this CLI: the optional peer set, the machine cache paths the
3
3
  * runtime installation and the model weights live at, the one predicate for "is the runtime
4
- * installed?", the loader and the entry resolver.
4
+ * installed?", the predicate for which peers this installation cannot resolve from its own location,
5
+ * the loader and the entry resolver.
5
6
  *
6
7
  * **The rule this module exists to enforce: a retrieval package is loaded only by a dynamic `import()`
7
8
  * in this module, and only on a path that retrieves.** The packages are optional peers
@@ -15,12 +16,17 @@
15
16
  * location. So `init` installs the peers and this CLI, at its own version, into
16
17
  * {@link retrievalRuntimeDir}, and nothing in this package resolves a peer against a second base.
17
18
  *
18
- * **The declared mirror.** `cli/templates/scripts/docs-search-server.sh` is the one mirror of three
19
- * literals this module owns — {@link RETRIEVAL_CACHE_DIRNAME}, {@link RETRIEVAL_RUNTIME_DIRNAME} and
20
- * {@link RUNTIME_CLI_RELATIVE} — spelled there as the path
21
- * `$(hr_cache_dir)/retrieval/runtime/node_modules/autonomous-sdlc-harness/dist/cli.js`, which it
22
- * `exec`s. `hr_cache_dir` itself mirrors `machineCacheDir()`, declared in `machine/paths.ts` →
23
- * choice 2. A change to any of the three literals is an edit to that script in the same change; a
19
+ * **The declared mirrors.** Two files outside the package spell literals this module owns:
20
+ * - `cli/templates/scripts/docs-search-server.sh` mirrors all three — {@link RETRIEVAL_CACHE_DIRNAME},
21
+ * {@link RETRIEVAL_RUNTIME_DIRNAME} and {@link RUNTIME_CLI_RELATIVE} — as the path
22
+ * `$(hr_cache_dir)/retrieval/runtime/node_modules/autonomous-sdlc-harness/dist/cli.js`, which it
23
+ * `exec`s. `hr_cache_dir` itself mirrors `machineCacheDir()`, declared in `machine/paths.ts` →
24
+ * choice 2.
25
+ * - `cli/templates/github/workflows/harness-run.yml` mirrors {@link RETRIEVAL_CACHE_DIRNAME} in the
26
+ * `actions/cache` path `${XDG_CACHE_HOME:-$HOME/.cache}/autonomous-sdlc-harness/retrieval`, in both
27
+ * the `run` and the `warm` job; its prefix mirrors `machineCacheDir()`, declared in the same choice.
28
+ *
29
+ * A change to a mirrored literal is an edit to every file that mirrors it, in the same change; a
24
30
  * mirror this header does not declare is a defect (`.claude/context/conventions.md` →
25
31
  * `## Configuration is the source of truth…`, the persisted-key bullet).
26
32
  */
@@ -28,7 +34,7 @@ import { existsSync } from 'node:fs';
28
34
  import { dirname, join } from 'node:path';
29
35
  import { HarnessError, internal } from '../core/errors.js';
30
36
  import { isJsonObject, readJsonFile } from '../core/json.js';
31
- import { packageRoot } from '../core/paths.js';
37
+ import { ownManifest, ownManifestString, packageRoot } from '../core/paths.js';
32
38
  import { machineCacheDir } from '../machine/paths.js';
33
39
  /** The directory under `machineCacheDir()` every retrieval artifact lives in. */
34
40
  export const RETRIEVAL_CACHE_DIRNAME = 'retrieval';
@@ -48,21 +54,6 @@ export function retrievalRuntimeDir() {
48
54
  export function retrievalModelCacheDir() {
49
55
  return join(machineCacheDir(), RETRIEVAL_CACHE_DIRNAME, RETRIEVAL_MODELS_DIRNAME);
50
56
  }
51
- /** This package's own manifest, which a packaging fault alone can make unreadable. */
52
- function ownManifest() {
53
- const manifestPath = join(packageRoot(), 'package.json');
54
- const manifest = readJsonFile(manifestPath);
55
- if (!isJsonObject(manifest))
56
- throw internal(`this CLI's own manifest could not be read at ${manifestPath}`);
57
- return manifest;
58
- }
59
- /** A string field of this package's own manifest. */
60
- export function ownManifestString(key) {
61
- const value = ownManifest()[key];
62
- if (typeof value !== 'string' || value === '')
63
- throw internal(`this CLI's own manifest carries no ${key}`);
64
- return value;
65
- }
66
57
  /**
67
58
  * Every `peerDependencies` entry of this package's own manifest whose `peerDependenciesMeta` marks it
68
59
  * optional. The manifest is the single declaration of the set; no package name is typed here.
@@ -140,6 +131,37 @@ export async function loadRetrievalModule(specifier) {
140
131
  throw new HarnessError(`docs retrieval needs the optional package ${name}, which this installation cannot load. Run \`npx autonomous-sdlc-harness init\` in a repository with docs.retrieval on: it installs the package into ${retrievalRuntimeDir()}, and the retrieval commands run from that installation`);
141
132
  }
142
133
  }
134
+ /**
135
+ * The name of every {@link retrievalPeers} entry `import.meta.resolve` throws on, in manifest order.
136
+ * Any throw counts — a missing module, a package-path error, a resolve hook's refusal. It resolves
137
+ * and loads nothing.
138
+ *
139
+ * It resolves from this module's own location, the base {@link loadRetrievalModule}'s `import()`
140
+ * resolves from, so an empty answer means the loader finds every peer.
141
+ *
142
+ * It is **not** the answer to "is the runtime installed?" — that is {@link retrievalRuntimeState}'s,
143
+ * and `doctor`'s `retrieval-dependencies` deliberately does not consult this one
144
+ * (`cli/src/doctor/checks.ts` → `RETRIEVAL_DEPENDENCIES_CHECK`'s doc comment).
145
+ *
146
+ * Call it only on a retrieval path: a resolve hook sees `import.meta.resolve` too.
147
+ *
148
+ * Consumers: {@link retrievalCliEntry} and, outside the package, the docs-retrieval eval's refusal —
149
+ * `evals/docs-retrieval/index-build.mjs` → `assertRealModelsAreAvailable` and
150
+ * `evals/docs-retrieval/check-floor.mjs` → `checkFloor`.
151
+ */
152
+ export function unresolvedRetrievalPeers() {
153
+ return retrievalPeers()
154
+ .filter(({ name }) => {
155
+ try {
156
+ import.meta.resolve(name);
157
+ return false;
158
+ }
159
+ catch {
160
+ return true;
161
+ }
162
+ })
163
+ .map(({ name }) => name);
164
+ }
143
165
  /**
144
166
  * The CLI entry a non-serving retrieval child process runs: this installation's `dist/cli.js` when
145
167
  * `import.meta.resolve` succeeds for every peer (resolution only), otherwise the runtime's entry when
@@ -154,16 +176,7 @@ export async function loadRetrievalModule(specifier) {
154
176
  * `retrieval-index` probe).
155
177
  */
156
178
  export function retrievalCliEntry() {
157
- const resolvesHere = retrievalPeers().every(({ name }) => {
158
- try {
159
- import.meta.resolve(name);
160
- return true;
161
- }
162
- catch {
163
- return false;
164
- }
165
- });
166
- if (resolvesHere)
179
+ if (unresolvedRetrievalPeers().length === 0)
167
180
  return { entry: join(packageRoot(), 'dist', 'cli.js'), source: 'this-installation' };
168
181
  const runtimeEntry = join(retrievalRuntimeDir(), RUNTIME_CLI_RELATIVE);
169
182
  return existsSync(runtimeEntry) ? { entry: runtimeEntry, source: RETRIEVAL_RUNTIME_DIRNAME } : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/retrieval/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/retrieval/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAC;AAEnD,kFAAkF;AAClF,MAAM,CAAC,MAAM,yBAAyB,GAAG,SAAS,CAAC;AAEnD,0EAA0E;AAC1E,MAAM,wBAAwB,GAAG,QAAQ,CAAC;AAE1C,wEAAwE;AACxE,MAAM,CAAC,MAAM,oBAAoB,GAAG,kDAAkD,CAAC;AAEvF,gFAAgF;AAChF,MAAM,4BAA4B,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAE5E,8FAA8F;AAC9F,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,CAAC,eAAe,EAAE,EAAE,uBAAuB,EAAE,yBAAyB,CAAC,CAAC;AACrF,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,eAAe,EAAE,EAAE,uBAAuB,EAAE,wBAAwB,CAAC,CAAC;AACpF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,sBAAsB,CAAC,CAAC;IAC9C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SACzB,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE;QACjB,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1D,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC3D,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,+FAA+F;AAC/F,SAAS,iBAAiB,CAAC,OAAe;IACxC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,4BAA4B,EAAE,cAAc,CAAC,CAAC,CAAC;QAC3F,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,IAAI,OAAO,KAAK,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;QACjG,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,cAAc,EAAE,EAAE,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC/D,CAAC;AAED,iGAAiG;AACjG,SAAS,SAAS,CAAC,SAAiB;IAClC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7F,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAI,SAAiB;IAC5D,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACzD,MAAM,QAAQ,CAAC,qCAAqC,SAAS,2CAA2C,CAAC,CAAC;IAC5G,CAAC;IACD,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAM,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAAsC,EAAE,IAAI,KAAK,sBAAsB;YAAE,MAAM,KAAK,CAAC;QAC1F,MAAM,IAAI,YAAY,CACpB,6CAA6C,IAAI,wJAAwJ,mBAAmB,EAAE,yDAAyD,CACxR,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO,cAAc,EAAE;SACpB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1B,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB;IAG/B,IAAI,wBAAwB,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAClI,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,EAAE,EAAE,oBAAoB,CAAC,CAAC;IACvE,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3G,CAAC"}
@@ -4,11 +4,13 @@
4
4
  * both read.
5
5
  *
6
6
  * **The rule this module exists to enforce: only `fused-rerank` abstains, and only below
7
- * {@link ABSTAIN_SCORE_THRESHOLD}, calibrated against the measured reranker distribution** — that
7
+ * {@link ABSTAIN_SCORE_THRESHOLD}** — that
8
8
  * constant's own doc comment carries the value and points at the record of how it was chosen. The
9
9
  * reranker's score is the one this module treats as calibrated; the `lexical`, `vector` and `fused`
10
- * scores are rank-derived and uncalibrated, so those modes never abstain. Every store access goes
11
- * through the {@link DocStore} methods; this module holds no SQL.
10
+ * scores are rank-derived and uncalibrated, so those modes never abstain. The score abstention tests
11
+ * is reported on the result whether or not it abstained, so the calibration can observe the
12
+ * distribution it cuts. Every store access goes through the {@link DocStore} methods; this module
13
+ * holds no SQL.
12
14
  */
13
15
  import { HarnessError } from '../core/errors.js';
14
16
  /** The reciprocal-rank-fusion constant: a hit at rank `r` contributes `1 / (RRF_K + r)`. */
@@ -24,9 +26,9 @@ export const MAX_RESULTS = 20;
24
26
  /** The snippet length, before the `...` a cut appends. */
25
27
  const SNIPPET_CHARS = 240;
26
28
  /**
27
- * The best reranker score below which `fused-rerank` abstains, calibrated at `0.32` against the real
28
- * reranker's measured score distribution; `docs/retrieval-eval-results.md` → `## Threshold
29
- * calibration` holds how that value was chosen and on what, and is the only record of it.
29
+ * The best reranker score below which `fused-rerank` abstains. `docs/retrieval-eval-results.md` →
30
+ * `## Threshold calibration` holds how the value was chosen, the observed distributions it was
31
+ * re-tested on and what it costs, and is the only record of it.
30
32
  *
31
33
  * This module's own suite bounds the value from outside: the abstention cases of
32
34
  * `cli/test/docs-retrieval.test.mjs` run under the `stub-overlap` reranker, which scores a matching
@@ -71,6 +73,7 @@ function hitOf(chunk, score) {
71
73
  * Answers `query` in `mode`. `k` is clamped to `[1, MAX_RESULTS]`; an empty or whitespace-only query
72
74
  * is refused. Only `fused-rerank` abstains — on no candidates, or a best reranker score below
73
75
  * {@link ABSTAIN_SCORE_THRESHOLD}; the other modes' scores are uncalibrated and never abstain.
76
+ * `bestRerankScore` carries the score that comparison read, abstention or not, and no renderer reads it.
74
77
  */
75
78
  export async function searchDocs(options) {
76
79
  const { store, embedder, reranker, query, mode } = options;
@@ -86,19 +89,27 @@ export async function searchDocs(options) {
86
89
  if (mode !== 'fused-rerank') {
87
90
  const top = fused.slice(0, k);
88
91
  const chunks = await store.getChunks(top.map(([id]) => id));
89
- return { abstained: false, hits: chunks.map((chunk) => hitOf(chunk, scores.get(chunk.id) ?? 0)) };
92
+ return {
93
+ abstained: false,
94
+ hits: chunks.map((chunk) => hitOf(chunk, scores.get(chunk.id) ?? 0)),
95
+ bestRerankScore: null,
96
+ };
90
97
  }
91
98
  const candidates = await store.getChunks(fused.slice(0, RERANK_CANDIDATES).map(([id]) => id));
92
99
  if (candidates.length === 0)
93
- return { abstained: true, hits: [] };
100
+ return { abstained: true, hits: [], bestRerankScore: null };
94
101
  const rerankScores = await reranker.score(query, candidates.map((chunk) => (chunk.heading === '' ? chunk.body : `${chunk.heading}\n${chunk.body}`)));
95
102
  const reranked = candidates
96
103
  .map((chunk, index) => ({ chunk, score: rerankScores[index] ?? 0 }))
97
104
  .sort((a, b) => b.score - a.score);
98
105
  const best = reranked[0]?.score ?? 0;
99
106
  if (best < ABSTAIN_SCORE_THRESHOLD)
100
- return { abstained: true, hits: [] };
101
- return { abstained: false, hits: reranked.slice(0, k).map(({ chunk, score }) => hitOf(chunk, score)) };
107
+ return { abstained: true, hits: [], bestRerankScore: best };
108
+ return {
109
+ abstained: false,
110
+ hits: reranked.slice(0, k).map(({ chunk, score }) => hitOf(chunk, score)),
111
+ bestRerankScore: best,
112
+ };
102
113
  }
103
114
  /**
104
115
  * {@link ABSTAIN_MESSAGE} alone on an abstention; otherwise two lines per hit, `n. ref (score s)` and
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/retrieval/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/retrieval/search.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * **The rule this module exists to enforce: the server's name, its tool's name and the permission
6
6
  * string built from them are a wire.** `plugin/agents/*.md` quotes {@link SEARCH_TOOL_PERMISSION} in
7
- * ten `tools:` allowlists, and the two CLI templates that register the server for an adopter carry
7
+ * eleven `tools:` allowlists, and the two CLI templates that register the server for an adopter carry
8
8
  * {@link DOCS_SERVER_NAME}, so renaming any of the three is an edit to every one of those files.
9
9
  *
10
10
  * **The tool's output is document text**, which an agent must treat as untrusted data rather than as
@@ -23,8 +23,9 @@
23
23
  import { execFileSync } from 'node:child_process';
24
24
  import { mkdirSync } from 'node:fs';
25
25
  import { join } from 'node:path';
26
+ import { ownManifestString } from '../core/paths.js';
26
27
  import { modelFilesPresent, RETRIEVAL_STUB_ENV, stubModelsSelected } from './models.js';
27
- import { ownManifestString, retrievalCliEntry, retrievalModelCacheDir, retrievalPeers, retrievalRuntimeDir, retrievalRuntimeState, RUNTIME_CLI_RELATIVE, } from './runtime.js';
28
+ import { retrievalCliEntry, retrievalModelCacheDir, retrievalPeers, retrievalRuntimeDir, retrievalRuntimeState, RUNTIME_CLI_RELATIVE, } from './runtime.js';
28
29
  /** Both child processes may take minutes on a cold cache. */
29
30
  const STEP_TIMEOUT_MS = 900000;
30
31
  const REMEDY = 're-run `npx autonomous-sdlc-harness init`; `npx autonomous-sdlc-harness doctor` reports what is missing';
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/retrieval/setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/retrieval/setup.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autonomous-sdlc-harness",
3
- "version": "0.2.0",
3
+ "version": "0.4.1",
4
4
  "description": "The outer loop of the autonomous SDLC harness: init, doctor, config and daemon management for the harness Claude Code plugin, plus opt-in local docs retrieval.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "firu-daniel",
@@ -13,7 +13,7 @@
13
13
  "scripts": {
14
14
  "build": "tsc -p tsconfig.json",
15
15
  "pretest": "npm run build",
16
- "test": "node --test",
16
+ "test": "node --test --test-timeout=1800000",
17
17
  "prepublishOnly": "npm run build"
18
18
  },
19
19
  "peerDependencies": {
@@ -9,7 +9,8 @@ The generator templates `init` copies into an adopted repository. Nothing here i
9
9
  | `githooks/` | the configured `githooksDir` |
10
10
  | `scripts/` | the configured `scriptsDir` |
11
11
  | `state-dir/` | the configured `stateDir` |
12
+ | `github/` | `.github/` in the adopter's repo — `workflows/harness-run.yml` and `workflows/harness-resume.yml`, written only when `execution.target` is `github-actions` |
12
13
 
13
- **Naming rule for the whole tree: a template whose adopter-side name begins with a dot is stored here without the dot.** `repo/gitignore` is written as `.gitignore`, `repo/mcp.json` as `.mcp.json`, and the `claude/` subtree lands at `.claude/`; `init` adds the dot when it writes. The rule is load-bearing twice over — a real `.gitignore` inside this repository would be honoured by git and could silently exclude files that are meant to ship, and npm rewrites a packaged `.gitignore` to `.npmignore` on publish, so a dot-named template does not survive the wire.
14
+ **Naming rule for the whole tree: a template whose adopter-side name begins with a dot is stored here without the dot.** `repo/gitignore` is written as `.gitignore`, `repo/mcp.json` as `.mcp.json`, and the `claude/` subtree lands at `.claude/` and the `github/` subtree at `.github/`; `init` adds the dot when it writes. The rule is load-bearing twice over — a real `.gitignore` inside this repository would be honoured by git and could silently exclude files that are meant to ship, and npm rewrites a packaged `.gitignore` to `.npmignore` on publish, so a dot-named template does not survive the wire.
14
15
 
15
- A template whose adopter-side home is none of the five above is new information for the item that adds it: give it a sixth subdirectory rather than forcing it into one of these.
16
+ A template whose adopter-side home is none of the six above is new information for the item that adds it: give it a seventh subdirectory rather than forcing it into one of these.
@@ -10,7 +10,7 @@
10
10
  - How a change flows through those layers, and which direction a dependency is allowed to point.
11
11
  - The order files are created in when a feature is added, so a half-built feature is still a coherent tree.
12
12
  - Where a new responsibility goes when it fits no file that already exists.
13
- - Logging, error handling, and the testing bar a change clears before it counts as done.
13
+ - Logging, error handling, and the testing bar a change clears before it counts as done — including **the one command that runs a single test file on its own**, or the statement that this project has none. The harness runs the full test command once per Run gates phase, never per change, so a unit that wrote a test runs only that file, through this command. Where the test wrapper's line accepts a path, `bash <scriptsDir>/test.sh <file>` is the command to name, because it is already allow-listed.
14
14
  - **The commit-message policy**, which is the whole of what the committer agent reads from this document: the subject-prefix vocabulary a caller draws its prefix from, whether the first word after the prefix is capitalized, the subject-length cap, the fixed-form subjects the flow emits, and the attribution-trailer policy: whether a trailer naming the agent as an author is required, forbidden or optional. The harness takes no position on that trailer, because the rule is actively reversed between projects: some forbid one outright, others require it on every agent-assisted commit, and unanswered here it has no default to fall back on. **The fixed-form subjects are derived here, never copied from a list** — run ``grep -rnE '(chore|feat|fix|refactor|docs|test): [A-Za-z][^"'"'"'`]*(<branch>|\$branch|\$\{branch\}|<entry-id>|K passing)' "${CLAUDE_PLUGIN_ROOT}" <scripts_dir>``, substituting `<scripts_dir>` with this repository's `scriptsDir` value from `harness.config.json` before running it, and write the policy so that **every** subject that command emits is exempt from the capitalisation rule and from the subject-length cap — **minus two classes the probe reaches but no commit point owns**: a subject the surrounding text tells the flow **not** to emit (its own line says it is forbidden), and a subject quoted as a worked example by a guard, a verification document or a prose restatement of another home's string. A subject with no emitting home is not a fixed form; check the line the probe emitted before exempting it. Each exempted subject is passed byte-for-byte by the commit point that owns it, so a policy that re-cases or truncates one breaks that commit point. `review_plan_file` and `ui_test_pass` are the committer's own commit modes and the dispatching flow files quote both, so changing either one is a two-file edit; the flow's other commit points own theirs the same way. The probe reaches **branch-scoped** subjects only — its alternation requires a `<branch>` / `$branch` / `${branch}` / `<entry-id>` / `K passing` token — so a fixed subject carrying none of them falls outside it, and widening the probe is part of the cost of adding one. **Per commit class, which prefix a commit of that class takes** — the vocabulary above names the set, this names the selection, and a policy giving only the set leaves a caller nothing to read: answer it for every class the flows commit in, at minimum a commit **fixing existing work**, the class the review-fix loops commit in, and a commit **adding new work**, the class a story task's commit falls in; and answer as well whether **any class carries no prefix at all, and which class that is**, which is what the committer's `commit_prefix` argument spells as the literal `none`. Designate by class and never by file kind — the classes are the flows', the tokens are yours.
15
15
  - **How this project stays in step with its reference implementation, if it has one** — which behaviour must match it exactly, which parts may deviate and why, and how a review finding cites the source it compared against. A project with a single implementation says so here and leaves `phases.parity` off; the section is optional, not missing.
16
16
 
@@ -9,7 +9,7 @@
9
9
  - What this layer is responsible for and — just as usefully — what it is not, so a task that has drifted into it is recognisable.
10
10
  - What it may depend on, and which direction a dependency between layers is allowed to point.
11
11
  - Naming and file-layout rules that apply inside it.
12
- - What "done" means here: the tests to write, the checks to run, the bar a review holds the change to.
12
+ - What "done" means here: the tests to write, the checks to run, the bar a review holds the change to — including **the one command that runs a single test file of this layer on its own**, or the statement that this layer has none. The harness runs the full test command once per Run gates phase, never per change, so a unit that wrote a test runs only that file, through this command. Where the test wrapper's line accepts a path, `bash <scriptsDir>/test.sh <file>` is the command to name, because it is already allow-listed.
13
13
 
14
14
  **One generic example — the shape a rule takes here**
15
15
 
@@ -12,8 +12,13 @@
12
12
  # carrying settings over from an earlier runner, rename the keys — the reader recognises
13
13
  # these spellings and no others.
14
14
 
15
- # Where a run posts its notifications: any endpoint that accepts an HTTP POST.
16
- # Leave it empty to send none.
15
+ # Where a run posts its notifications: the full http:// or https:// URL of any endpoint
16
+ # that accepts an HTTP POST. Leave it empty to send none.
17
+ # For ntfy with no server of your own: install the ntfy app, create a topic there and
18
+ # write https://ntfy.sh/<your-topic> here. The topic name works like a password —
19
+ # anyone who knows it can read and send these notifications.
20
+ # This file is sourced by a shell, so a URL containing shell characters such as `&`
21
+ # must be single-quoted: HARNESS_PUSH_URL='https://…?a=1&b=2'.
17
22
  HARNESS_PUSH_URL=
18
23
 
19
24
  # Optional. A local command run in addition to the POST — a desktop notifier, a chat
@@ -7,7 +7,7 @@
7
7
  "ONE COMMAND PER ENTRY, NEVER A COMPOUND: a single `mkdir && cp && rm` block is refused where each of those commands succeeds on its own, because the joined string matches no entry. Keep every entry a single command.",
8
8
  "THE CHECKOUT AND ITS SIBLING WORKTREES BOTH: every file glob and every wrapper path is listed for {{repoRoot}} and for the sibling pattern {{worktreeGlob}} under {{workRoot}}. A run in a second working copy that matches neither does not fail loudly - it silently skips whatever phase needed the path. A single-checkout repository simply has no sibling for the second entry to match, which costs nothing.",
9
9
  "EVERY WRAPPER IN {{scriptsDir}} IS LISTED IN ALL THREE FORMS A CALLER MAY USE: the repo-relative invocation `commands.*` holds and an agent runs verbatim from the repository root, its repo-root-absolute twin for a caller that resolves the path first, and its sibling-worktree twin. Listing only one form leaves the other two matching neither `allow` nor `deny`, which is the stall this profile exists to prevent. THE DEPLOY WRAPPER IS ONE OF THEM, SO ITS THREE FORMS ARE IN `allow` HERE AND AGAIN IN `ask` BELOW: `ask` is evaluated before `allow` and returns first, so the ask is what a deploy hits and the allow rows never decide it. Deleting the `ask` deploy rows as duplicates therefore leaves a deploy an unattended run makes on its own - remove deploy from both blocks or from neither.",
10
- "THE OUTER-LOOP SCRIPTS AN AGENT RUNS ARE LISTED THE SAME THREE WAYS, AND THE REST GET NOTHING: `autonomous-sdlc-harness init` writes a second family of scripts into {{scriptsDir}} whose bodies ship fixed and read `harness.config.json` at run time rather than carrying a command line of yours. Only the ones a dispatched agent is itself the thing that runs are listed here, and they are in `allow` rather than `ask` because they sit on the unattended commit path, where an `ask` is evaluated first and parks the run with nothing to answer it. The run watcher, the worktree tooling and the cleanup sweep are started by the watcher process or by you, and they carry no entry on purpose: one would hand a dispatched agent a path to a branch deletion or a daemon restart. The docs-retrieval server launcher carries no entry either, for a different reason: the agent runner starts it from `.mcp.json` when docs.retrieval is on, never a dispatched agent's Bash call, and the one tool it serves, `search_docs` on the `harness-docs` server, is granted by the retrieval fragment's entry for it instead. Adding an entry for one of them is a decision to let an agent run it - make it deliberately, in the same three forms as everything else here.",
10
+ "THE OUTER-LOOP SCRIPTS AN AGENT RUNS ARE LISTED THE SAME THREE WAYS, AND THE REST GET NOTHING: `autonomous-sdlc-harness init` writes a second family of scripts into {{scriptsDir}} whose bodies ship fixed and read `harness.config.json` at run time rather than carrying a command line of yours. Only the ones a dispatched agent or the orchestrating session is itself the thing that runs are listed here - the orchestrating session runs two of them, the flow walker `flow-walker.sh` and the test-suite runner `run-test-suite.sh` - and they are in `allow` rather than `ask` because they sit on the unattended commit, planning or gate-run path, where an `ask` is evaluated first and parks the run with nothing to answer it. The run watcher, the worktree tooling and the cleanup sweep are started by the watcher process or by you, and `remote-run.sh` by the watcher, the remote job or you; they carry no entry on purpose: one would hand a dispatched agent a path to a branch deletion, a daemon restart or a remote run dispatch. The docs-retrieval server launcher carries no entry either, for a different reason: the agent runner starts it from `.mcp.json` when docs.retrieval is on, never a dispatched agent's Bash call, and the one tool it serves, `search_docs` on the `harness-docs` server, is granted by the retrieval fragment's entry for it instead. Adding an entry for one of them is a decision to let an agent run it - make it deliberately, in the same three forms as everything else here.",
11
11
  "THE PACKAGE MANAGER, THE BUILD AND THE DEPENDENCY INSTALL ARE DELIBERATELY NOT ALLOW-LISTED: `commands.build` and `commands.depInstall` are raw command lines with no wrapper, because they are run by a person or by the outer loop rather than by an agent, and granting an agent a package manager grants it every script that package manager can run. An adopter who wants one of them agent-run adds a wrapper script for it and one literal entry here, in the same three forms as the wrappers above. That stance leaves an ad-hoc probe a route, and it needs no entry here either - the next paragraph is that route, and the trade it makes rather than an exception it satisfies.",
12
12
  "THE PROBE ROUTE GRANTS AN INTERPRETER AT ONE REMOVE, AND IT IS BROADER THAN THE GRANT ABOVE REFUSES, NOT NARROWER: an ad-hoc probe or a mutation check is written into the run-artifact tree's `scratch/` directory and run through `bash {{scriptsDir}}/scratch-run.sh`, an outer-loop script whose three forms are already listed above. It runs a FILE from that one directory rather than a string on the command line, which fences WHICH FILE runs and nothing about what that file does: the file is one the agent composed a tool call earlier, it runs with the session's own privileges, and it reaches everything the `deny` floor below, the `ask` list below and the plugin guard's own deny list withhold from a COMMAND STRING. The trade is deliberate and is recorded here rather than left to be discovered: the alternative is a run with no permitted way to execute anything, which silently downgrades a verification claim from executed to reasoned. What still holds for a subprocess is the `pre-push` git hook, because git runs it however git was invoked. Removing the route means deleting `scratch-run.sh`'s `agentInvocable` row in the generator and adding its basename to the plugin guard's deny list - both, since either alone leaves it reachable.",
13
13
  "CREATING A FILE AND CHANGING ONE ARE TWO DIFFERENT GRANTS: `Edit` covers a change to a file that already exists, `Write` covers creating one - and almost every artifact a run produces is a new file, from a plan to a review to a ledger entry to whatever source file an implementer adds. Dropping the `Write` pair therefore leaves the most common operation in the whole flow matching neither `allow` nor `deny`, which in print mode is a stall and not a refusal. `defaultMode` does not close that gap: its auto-accept is scoped to the session's own working directory, and the entry that matters most here is the sibling-worktree one.",
@@ -0,0 +1,124 @@
1
+ # harness-resume.yml — resumes usage-paused autonomous-sdlc-harness runs once
2
+ # their usage window has reset, with no local machine involved.
3
+ #
4
+ # WHO WRITES IT. `autonomous-sdlc-harness init`, only when harness.config.json's
5
+ # `execution.target` is `github-actions`. Written create-if-absent: from then on
6
+ # it is yours to tune, and a re-run of `init` keeps your copy.
7
+ #
8
+ # WHY A POLLER. A `schedule` trigger is a recurring cron read from the default
9
+ # branch, not a one-shot timer, so resuming at a recorded reset time means
10
+ # polling. Each tick runs `remote-run.sh poll`: it downloads each branch's
11
+ # newest `harness run` bundle and dispatches `resume: pause` for every
12
+ # usage-paused run whose recorded reset has passed.
13
+ #
14
+ # IT DISABLES ITSELF. When a tick leaves no run waiting, `poll` runs
15
+ # `gh workflow disable harness-resume.yml`; a job that ends on a usage pause
16
+ # re-enables it (`remote-run.sh continue`). Ticks are paid only during a pause.
17
+ # That also makes moot GitHub's disabling of scheduled workflows in a public
18
+ # repository after 60 days without activity.
19
+ #
20
+ # UNVERIFIED: whether GITHUB_TOKEN with `actions: write` may enable and disable
21
+ # a workflow. If it may not, the pausing job's `paused` notification says
22
+ # auto-resume is unavailable, and the run waits for
23
+ # /autonomous-sdlc-harness:branch-resume.
24
+ #
25
+ # THE INTERVAL IS YOURS TO EDIT. On a private repository every tick is billed
26
+ # at least one minute while the poller is enabled: `*/30` is up to 48 minutes a
27
+ # day, `*/15` up to 96, `0 * * * *` up to 24, each adding at most its interval
28
+ # to how late a run resumes after its reset. On a public repository the ticks
29
+ # cost nothing.
30
+ #
31
+ # WHAT IT READS.
32
+ # Secrets: HARNESS_PUSH_URL (optional notifications: the poller's own failed
33
+ # notice when it cannot resume a run).
34
+ # Variables: HARNESS_RUNNER, HARNESS_REMOTE_STOP (any value: the tick
35
+ # dispatches nothing), HARNESS_MAX_CHAIN (the automatic-dispatch limit),
36
+ # HARNESS_POLL_MAX_DISPATCH_FAILURES (failed re-dispatches of one paused
37
+ # run before the poller gives up on it; 3 when unset) and
38
+ # HARNESS_POLL_GIVE_UP_AFTER_MINUTES (minutes after the usage reset past
39
+ # which it gives up; 360 when unset).
40
+ # harness.config.json, at run time: `scriptsDir` and `stateDir`. No
41
+ # configured value is frozen into this file.
42
+ # The previous tick's `harness-poll-state` artifact, which `poll` downloads.
43
+ # The job's `actions: write` covers listing and downloading its own
44
+ # workflow's artifacts.
45
+ #
46
+ # WHAT IT WRITES. The `harness-poll-state` artifact: the failed-dispatch count
47
+ # `poll` carries to the next tick, kept 7 days.
48
+ #
49
+ # THE RULE EVERY EDIT KEEPS. Every GitHub expression has a space after its
50
+ # opening braces, and every value reaches a shell line through `env:`. `init`
51
+ # renders this file with the CLI's double-brace token renderer, which reads a
52
+ # letter straight after the braces as a token; this file carries no token.
53
+ #
54
+ # DECLARED MIRRORS — a rename on either side is an edit to both:
55
+ # cli/src/remote/githubActions.ts WORKFLOW_RESUME_FILE, HARNESS_RUNNER,
56
+ # HARNESS_REMOTE_STOP, HARNESS_PUSH_URL,
57
+ # POLL_STATE_ARTIFACT_NAME
58
+ # cli/src/config/model.ts DEFAULTS.scriptsDir, DEFAULTS.stateDir
59
+
60
+ name: harness-resume
61
+
62
+ on:
63
+ schedule:
64
+ - cron: '*/30 * * * *'
65
+ workflow_dispatch:
66
+
67
+ permissions:
68
+ contents: read
69
+ actions: write
70
+
71
+ defaults:
72
+ run:
73
+ shell: bash
74
+
75
+ jobs:
76
+ poll:
77
+ runs-on: ${{ vars.HARNESS_RUNNER || 'ubuntu-latest' }}
78
+ # A hand-dispatched tick overlapping a scheduled one would dispatch twice.
79
+ concurrency:
80
+ group: harness-resume
81
+ cancel-in-progress: false
82
+ env:
83
+ GH_TOKEN: ${{ github.token }}
84
+ HARNESS_REMOTE_STOP: ${{ vars.HARNESS_REMOTE_STOP }}
85
+ HARNESS_MAX_CHAIN: ${{ vars.HARNESS_MAX_CHAIN }}
86
+ HARNESS_POLL_MAX_DISPATCH_FAILURES: ${{ vars.HARNESS_POLL_MAX_DISPATCH_FAILURES }}
87
+ HARNESS_POLL_GIVE_UP_AFTER_MINUTES: ${{ vars.HARNESS_POLL_GIVE_UP_AFTER_MINUTES }}
88
+ HARNESS_REMOTE_SLUG: ${{ github.repository }}
89
+ HARNESS_PUSH_URL: ${{ secrets.HARNESS_PUSH_URL }}
90
+ steps:
91
+ - name: Check out the default branch
92
+ uses: actions/checkout@v4
93
+ with:
94
+ ref: ${{ github.event.repository.default_branch }}
95
+
96
+ - name: Read the configuration
97
+ run: |
98
+ missing=""
99
+ for tool in jq gh; do
100
+ command -v "$tool" >/dev/null 2>&1 || missing="$missing $tool"
101
+ done
102
+ if [ -n "$missing" ]; then
103
+ echo "::error::this runner lacks:$missing. Install them on the self-hosted runner, or use a GitHub-hosted one."
104
+ exit 1
105
+ fi
106
+ scripts_dir=$(jq -r '.scriptsDir // "scripts"' harness.config.json)
107
+ state_dir=$(jq -r '.stateDir // "sdlc-harness"' harness.config.json)
108
+ {
109
+ echo "SCRIPTS_DIR=${scripts_dir%/}"
110
+ echo "POLL_STATE_DIR=${state_dir%/}/autonomous_logs/poll_state/current"
111
+ } >> "$GITHUB_ENV"
112
+
113
+ - name: Resume the runs whose usage window has reset
114
+ run: bash "$SCRIPTS_DIR/remote-run.sh" poll
115
+
116
+ - name: Upload the poller state
117
+ if: always() && env.POLL_STATE_DIR != ''
118
+ uses: actions/upload-artifact@v4
119
+ with:
120
+ name: harness-poll-state
121
+ path: ${{ env.POLL_STATE_DIR }}
122
+ overwrite: true
123
+ if-no-files-found: ignore
124
+ retention-days: 7