You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/ADRs/0038-universal-harness-access.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -338,7 +338,7 @@ harnesses:
338
338
339
339
**Rationale:** Lock files provide dependency pinning (reproducible builds), transitive closure visibility (auditability), and automated updates (tools can rewrite lock files when dependencies change). Similar to `package-lock.json` in npm.
340
340
341
-
**Lock file workflow:** `fullsend lock <harness>` resolves all dependencies, generates/updates the lock file. `fullsend run <harness>` prefers lock file entries if present, warns if lock file is stale (resource hash doesn't match).
341
+
**Lock file workflow:** `fullsend lock <harness>` (or `fullsend lock --all`) resolves all dependencies, generates/updates the lock file. `fullsend run <harness>` prefers lock file entries if present, warns if lock file is stale (resource hash doesn't match).
Copy file name to clipboardExpand all lines: docs/plans/adr-0045-forge-portable-harness-phase2.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -92,7 +92,7 @@ PRs 1, 2, 3, 5 can start in parallel. PR 4 depends on PR 3 (needs the base URL b
92
92
- For each file, calls `LoadRaw(path)` (unmarshal only, no validation)
93
93
- Extracts `h.Role` and `h.Slug`; skips files where both are empty (not harness identity files, or legacy harnesses without role/slug)
94
94
- Returns sorted by `Role` for deterministic output
95
-
- Errors on individual files are collected and returned as a multi-error (one bad YAML file should not prevent discovery of others). This partial-result semantic is intentional: discovery is a read-only inventory operation where returning what we can find is more useful than failing entirely. Contrast with `lock --all` (PR 5), which uses all-or-nothing semantics because writing an incomplete lock file would silently leave some dependencies unpinned.
95
+
- Errors on individual files are collected and returned as a multi-error (one bad YAML file should not prevent discovery of others). This partial-result semantic is intentional: discovery is a read-only inventory operation where returning what we can find is more useful than failing entirely. `lock --all` (PR 5)uses similar partial-progress semantics: successfully resolved harnesses are saved before returning the error, so they don't need to be re-resolved on retry.
96
96
- Does NOT resolve `base:` chains -- reads only the top-level `role`/`slug` from each file. This is correct because generated wrappers set `role`/`slug` at the top level (not inherited from base).
97
97
98
98
**Create `internal/harness/discover_test.go`:**
@@ -317,14 +317,14 @@ The `HarnessWrappersLayer` maintains this mapping. A helper function `harnessNam
317
317
318
318
**Modify `internal/cli/lock.go`:**
319
319
320
-
- Change `cobra.ExactArgs(1)` to `cobra.MaximumNArgs(1)` -- accept zero or one positional argument
320
+
- Change `cobra.ExactArgs(1)` to `cobra.RangeArgs(0, 1)` -- accept zero or one positional argument
321
321
- Add `--all` bool flag
322
322
- Validation:
323
323
- `--all`and a positional argument are mutually exclusive -> error
324
324
- Neither `--all` nor a positional argument -> error with usage hint
325
325
- When `--all` is set:
326
326
1. Glob `filepath.Join(absFullsendDir, "harness", "*.yaml")` and `*.yml` to get all harness files. Uses `filepath.Glob` directly rather than `DiscoverAgents` to avoid coupling lock to the discover API -- lock only needs filenames, not role/slug.
327
-
2. For each harness file found, run the existing lock logic (load, resolve, hash, record in lockfile). If any individual file fails to parse, the entire `lock --all` invocation fails with no partial lock file written (all-or-nothing semantics, matching the single-file lock behavior).
327
+
2. For each harness file found, run the existing lock logic (load, resolve, hash, record in lockfile). If any individual file fails, previously resolved harnesses are saved to the lock file (partial-progress semantics) so they don't need to be re-resolved on retry. The error message includes the failing harness name.
328
328
3. Write the combined lock file once at the end with all harness entries.
@@ -338,7 +338,7 @@ The `HarnessWrappersLayer` maintains this mapping. A helper function `harnessNam
338
338
- `--all`with no harness files -> warning, empty lock file
339
339
- `--all`with multiple harnesses -> all locked, lock file contains entries for each
340
340
- `--all`with one harness having URL base, others local-only -> only URL-bearing harnesses get lock entries (or all get entries with empty deps -- follow existing convention)
341
-
- `--all`with one harness failing to parse -> error with harness name in message, no partial lock file written (all-or-nothing)
341
+
- `--all`with one harness failing to parse -> error with harness name in message, partial progress saved for already-resolved harnesses
342
342
343
343
**After merge:** `fullsend lock --all` locks every harness in the directory. Combined with PR 4's wrapper generation, running `fullsend lock --all` after install pins all base URLs in `lock.yaml`.
0 commit comments