scout-essentials 1.8.7 → 1.9.0
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.
- checksums.yaml +4 -4
- data/.vimproject +26 -12
- data/README.md +83 -112
- data/VERSION +1 -1
- data/doc/Improvements.md +226 -0
- data/doc/StartHere.md +122 -0
- data/doc/developer/AnnotationSystem.md +184 -0
- data/doc/developer/Architecture.md +147 -0
- data/doc/developer/Configuration.md +238 -0
- data/doc/developer/CoreUtilities.md +265 -0
- data/doc/developer/DesignPrinciples.md +129 -0
- data/doc/developer/ErrorHandling.md +203 -0
- data/doc/developer/LockingAndConcurrency.md +157 -0
- data/doc/developer/PathResolution.md +200 -0
- data/doc/developer/PersistenceAndResources.md +119 -0
- data/doc/developer/StreamingModel.md +236 -0
- data/doc/user/AnnotatingData.md +202 -0
- data/doc/user/CachingResults.md +183 -0
- data/doc/user/CommandLineOptions.md +189 -0
- data/doc/user/Cookbook.md +211 -0
- data/doc/user/HandlingStreams.md +236 -0
- data/doc/user/LoggingAndProgress.md +158 -0
- data/doc/user/ProducingResources.md +177 -0
- data/doc/user/RemoteData.md +157 -0
- data/doc/user/RunningCommands.md +218 -0
- data/doc/user/WorkingWithFiles.md +217 -0
- data/lib/scout/cmd.rb +343 -40
- data/lib/scout/concurrent_stream.rb +14 -1
- data/lib/scout/indiferent_hash.rb +1 -1
- data/lib/scout/log/fingerprint.rb +13 -8
- data/lib/scout/log/progress/report.rb +1 -1
- data/lib/scout/log.rb +4 -1
- data/lib/scout/misc/digest.rb +6 -5
- data/lib/scout/misc/format.rb +24 -0
- data/lib/scout/named_array.rb +1 -1
- data/lib/scout/open/stream.rb +2 -2
- data/lib/scout/open/util.rb +8 -4
- data/lib/scout/open.rb +3 -3
- data/lib/scout/path/find.rb +3 -2
- data/lib/scout/persist.rb +14 -10
- data/lib/scout/resource/produce.rb +9 -1
- data/research/annotations-data-analysis.md +206 -0
- data/research/behavior-probes.md +1925 -0
- data/research/commands-streaming-analysis.md +272 -0
- data/research/design-philosophy-analysis.md +383 -0
- data/research/doc-audit-findings.md +294 -0
- data/research/ecosystem-attribution.md +118 -0
- data/research/implementation-inventory-core.md +1029 -0
- data/research/implementation-inventory-open.md +417 -0
- data/research/implementation-inventory-path-persist-resource.md +774 -0
- data/research/io-paths-analysis.md +228 -0
- data/research/persistence-resources-analysis.md +244 -0
- data/research/synthesis-report.md +80 -0
- data/scout-essentials.gemspec +37 -15
- data/test/scout/open/test_remote.rb +1 -2
- data/test/scout/test_cmd.rb +411 -0
- metadata +36 -14
- data/doc/Annotation.md +0 -352
- data/doc/CMD.md +0 -363
- data/doc/ConcurrentStream.md +0 -163
- data/doc/IndiferentHash.md +0 -240
- data/doc/Log.md +0 -235
- data/doc/NamedArray.md +0 -174
- data/doc/Open.md +0 -331
- data/doc/Path.md +0 -217
- data/doc/Persist.md +0 -214
- data/doc/Resource.md +0 -229
- data/doc/SimpleOPT.md +0 -236
- data/doc/TmpFile.md +0 -154
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Forensic doc audit of scout-essentials — final findings (durable report)
|
|
2
|
+
|
|
3
|
+
Audit target: `/bulk/mvazque2/git/scout-essentials` (gem v1.8.8, HEAD `a0324a4`).
|
|
4
|
+
Outcome: `doc/` fully rewritten (17 pages) + 5 new pages + `README.md` rewritten;
|
|
5
|
+
Critic final gate: **ACCEPT_WITH_NOTES** (notes applied).
|
|
6
|
+
This file is the retained summary. The full evidence trail (coverage matrix with
|
|
7
|
+
261 rows, 22 per-claim ledgers, 3 implementation inventories, 66 behavior probes,
|
|
8
|
+
ecosystem attribution, phase reports and critic gates) lives in
|
|
9
|
+
`research/doc_audit/`, `research/` and `tmp/critic/` — see
|
|
10
|
+
`research/doc_audit/resumption-reference.md` §2 for the index.
|
|
11
|
+
|
|
12
|
+
Disposition counts (coverage-matrix sections A–F, 238 rows): OK 3 · FIX 117 ·
|
|
13
|
+
EXPAND 67 · NEW_PAGE 27 · INTERNAL 6 · ELSEWHERE 13 · OUT_OF_SCOPE 6.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## (a) Major hallucinations discovered and corrected
|
|
18
|
+
|
|
19
|
+
59 confirmed false claims (coverage-matrix section E), grouped by theme:
|
|
20
|
+
|
|
21
|
+
**1. Invented APIs / nonexistent names (≈18).** Documented methods that do not
|
|
22
|
+
exist anywhere in `lib/` or the ecosystem: `Persist.lock(file){}` (API is
|
|
23
|
+
`Open.lock`), `Persist.save_job_run_info`, `CMD.add_tool` (real API
|
|
24
|
+
`CMD.tool(tool, claim, test, block, cmd)`), `Log.none` (only `Log::NONE`
|
|
25
|
+
exists), `TmpFile.tmp_dir` (real: `TmpFile.user_tmp`), `Path.map_order=`,
|
|
26
|
+
`Path#sync`, the `base[:results, :final]` `Path#[]` API, the `{PATH}` map
|
|
27
|
+
placeholder (exists only inside `Path.follow` rewriting), the `ANNOTATIONS`
|
|
28
|
+
constant (real: `@annotations` via `.annotations`), `MyMetadata.purge` (real:
|
|
29
|
+
`Annotation.purge`), `Log::Color`, `stream.join_callback <<` (real:
|
|
30
|
+
`add_callback`), `add_abort_callback`, `Open.pipe("a","b","c")` (takes no
|
|
31
|
+
args), `SOPT.get inputs: [...]`, `SOSOPT.input_descriptions` (typo),
|
|
32
|
+
`invert_grep` alone filtering at `Open.read` level, `deep_indifferent`.
|
|
33
|
+
|
|
34
|
+
**2. Inverted dependency graph (Architecture, 6+ rows).** Architecture.md had
|
|
35
|
+
ConcurrentStream above Open/Path/CMD (it is *required by* CMD and requires only
|
|
36
|
+
IndiferentHash), "Resource depends on Persist" / "produce acquires a Persist
|
|
37
|
+
lock" (no reference; the lock is `Open.lock` on `Resource#lock_dir`), "Open/CMD
|
|
38
|
+
depend on TmpFile" (TmpFile requires Open), and a phantom "extend `Log::Color`"
|
|
39
|
+
extension point. Rewritten from verified `require` edges.
|
|
40
|
+
|
|
41
|
+
**3. Wrong data types / return values (≈12).** `Persist.cache_dir`/`lock_dir`
|
|
42
|
+
"# => #<Path ...>" (both plain Strings), `find` "returns nil when nothing
|
|
43
|
+
resolves" (never nil — it falls through the map order), serialization types
|
|
44
|
+
`:array/:path/:file/:string_array` with invented semantics (rebuilt from
|
|
45
|
+
serialize.rb), `annotated_str.is_a?(MyAnnotation) # => false` (it is true),
|
|
46
|
+
`annotation_types.include?("MyAnnotation")` (entries are module objects),
|
|
47
|
+
`values.count` as a field accessor (plain `Array#count`), `zip` "propagates
|
|
48
|
+
annotations" (drops them), fabricated output "S003 (Human, Lua)" (prints
|
|
49
|
+
`(Human, Liver)`), "`Persist::Path` appends the serialization type to the
|
|
50
|
+
filename" (no suffix is ever appended).
|
|
51
|
+
|
|
52
|
+
**4. Fabricated semantics for real methods (≈15).** Abbreviated default
|
|
53
|
+
`map_order` (13 real entries), `persistence_path(name, :marshal)` positional
|
|
54
|
+
type (options-hash only), `save_drivers`/`load_drivers` as constants (accessor
|
|
55
|
+
hashes), `claim self.data.file` `self.`-prefixed paths and block-only
|
|
56
|
+
`claim do ... end` (type mandatory), "extend `Resource.produce` for new claim
|
|
57
|
+
types" (hard-coded `case`), `io.exit_status` reliable post-join (normally nil;
|
|
58
|
+
only `join_pids` sets it), CMD block "runs post-join" (accepted, never
|
|
59
|
+
invoked), progress bar "shows ETA" (elapsed + rate), `Log.debug "msg" do ... end`
|
|
60
|
+
"logs elapsed time" (lazy message evaluation), `with_obj_bar{|bar, item|}`
|
|
61
|
+
two-arg block (bar only), SOPT `=value` defaults and "`*` marks required"
|
|
62
|
+
(`*` = string-valued; `SOPT.require` enforces), `class MyPersist < Persist`
|
|
63
|
+
"wrong style" example (raises TypeError — Persist is a Module), "resources are
|
|
64
|
+
always released, even on error" (`TmpFile.with_file` leaks on raise), "always
|
|
65
|
+
pair method_missing with respond_to_missing?" (none in lib/), NamedArray "a
|
|
66
|
+
String with a name" / "NamedArray extends AnnotatedArray" (it does not),
|
|
67
|
+
**`dup` and `clone` both lose annotations — only `dup` loses; `clone` keeps
|
|
68
|
+
them** (clone copies the singleton class), "nested hashes are automatically
|
|
69
|
+
IndiferentHash" (plain Hash).
|
|
70
|
+
|
|
71
|
+
**5. Misdescribed streaming model (StreamingModel/HandlingStreams, 6+).** "CMD
|
|
72
|
+
creates paired stdout/stderr streams" (pairs are pipe ends; stderr is a thread),
|
|
73
|
+
"paired streams are joined on cleanup" (`join` never touches `@pair`), "Log
|
|
74
|
+
writes to the stream's paired stderr" (logfile/STDERR; per-stream capture is the
|
|
75
|
+
`std_err` attribute). Also the two synthesis-level artifacts: `Persist` is
|
|
76
|
+
*name*-based, not "content-addressed caching" (keys are names + option digests),
|
|
77
|
+
and `Open.read_stream`'s documented IO.select/Thread.pass loop was the **dead
|
|
78
|
+
first definition** (stream.rb:382-399); the effective method (stream.rb:401) is
|
|
79
|
+
a plain blocking read of exactly N bytes — same observable contract, corrected
|
|
80
|
+
in the final pass.
|
|
81
|
+
|
|
82
|
+
Top examples (doc:claim → actual): `find` nil-returns → never nil ·
|
|
83
|
+
`Persist.lock` → `Open.lock` · `save_drivers` constants → accessor hashes ·
|
|
84
|
+
paired stderr streams → pipe ends + stderr thread · `clone` loses annotations →
|
|
85
|
+
only `dup` does · invert_grep filters alone → no-op without `grep`.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## (b) Major omissions discovered and documented
|
|
90
|
+
|
|
91
|
+
From the 67 EXPAND rows and 27 NEW_PAGE rows.
|
|
92
|
+
|
|
93
|
+
**Five subsystems had no doc home at all** → new pages created:
|
|
94
|
+
1. `doc/developer/Configuration.md` — `Scout::Config` token-priority resolution
|
|
95
|
+
(`workflow`4 > `task`3 > `file`2 > `line`1; `key:` = 20 = lowest; explicit
|
|
96
|
+
`::N` wins), `etc/config` line format, `:env`/`env:VAR` values,
|
|
97
|
+
`with_config` snapshot/restore, `process_config`, no-mutex caveat.
|
|
98
|
+
2. `doc/developer/ErrorHandling.md` — 20-class exception taxonomy, control-flow
|
|
99
|
+
signals deriving from `Exception` not `StandardError` (`StopInsist`,
|
|
100
|
+
`DontClose`, `DontPersist`, `KeepLocked`, `KeepBar` — a bare `rescue =>` will
|
|
101
|
+
NOT catch them), `canfail`/`no_fail`, abort protocol.
|
|
102
|
+
3. `doc/developer/LockingAndConcurrency.md` — vendored `Lockfile` (Ara T. Howard
|
|
103
|
+
v2.1.8, modified; guarded `unless defined?`), `Open.lock`/`LockInterrupted`,
|
|
104
|
+
the **three distinct lock namespaces** (`Persist.lock_dir` + `.persist`
|
|
105
|
+
suffix; `Resource#lock_dir` with TmpFile-digest names;
|
|
106
|
+
`sensible_write_lock_dir`), KeepLocked streaming persistence, fork model,
|
|
107
|
+
thread-safety caveats.
|
|
108
|
+
4. `doc/developer/CoreUtilities.md` — TmpFile naming conventions (`·` U+00B7
|
|
109
|
+
per `/`, `PREFIX:`, `[key]`, `&F[m=<digest(value)>]` + `:md5` tail,
|
|
110
|
+
`MAX_FILE_LENGTH` 150), IndiferentHash instance protocol, Misc format/timespan/
|
|
111
|
+
digest/insist families, Hook (not auto-required), `NamedArray`/`Hook` explicit
|
|
112
|
+
require.
|
|
113
|
+
5. `doc/user/RemoteData.md` — `Open.remote?`/`ssh?`, wget cache (`var/cache/open-remote`,
|
|
114
|
+
digest over url+post data; no TTL), `:force` behaviour (raises OpenURLError,
|
|
115
|
+
does not touch cache), ssh/scp/rsync, `Open.wait` `LAST_TIME` rate limiter.
|
|
116
|
+
|
|
117
|
+
**Biggest in-page gaps (EXPAND) now filled:**
|
|
118
|
+
- `update:`/`check:` cache staleness invalidation (persist.rb:41-47) — the single
|
|
119
|
+
most useful persistence feature, previously entirely absent.
|
|
120
|
+
- `save_stderr` three shapes (commit `ee24c68`): `true` → `std_err`; a file path
|
|
121
|
+
(CMD opens/truncates, creates parent dirs, line-buffered so `tail -f` works);
|
|
122
|
+
any IO-like (written+flushed, never closed). Old docs only showed
|
|
123
|
+
`save_stderr: true`.
|
|
124
|
+
- TmpFile naming + `$HOME/tmp/scout/tmpfiles` root with `tmpdir=` override; the
|
|
125
|
+
three lock namespaces, previously conflated into one.
|
|
126
|
+
- Annotation mechanics: `setup` extends in place (same object unless frozen),
|
|
127
|
+
`@produced` tri-state latching on `Path#produce`, `serialize` → plain Hash,
|
|
128
|
+
Marshal round-trip, `dup` vs `clone`.
|
|
129
|
+
- `:memory` + `MEMORY_CACHE` + `Persist.memory("key", key:)`, `TRUE_STRINGS`
|
|
130
|
+
(13 spellings), `:serializer == :json` default, `Open.json`/`Open.yaml`
|
|
131
|
+
`find_with_extension` fallback (`:yaml` load may return a Psych AST node).
|
|
132
|
+
- Log: severity constants, `Log::LAST` protocol, `with_severity`, `fingerprint`,
|
|
133
|
+
`Log.logfile` no-arg call *resets* the logfile, `SCOUT_NOCOLOR == 'true'`
|
|
134
|
+
exact string, ProgressBar YAML resume, `percent == 100` when `max == 0`.
|
|
135
|
+
- SOPT: `*` = string-valued, `SOPT.require` enforcement, destructive `consume!`,
|
|
136
|
+
`## SYNOPSYS` (sic) header, partial `reset`.
|
|
137
|
+
- CMD: `CMD::Timeout`, `:in`/`:in_pipe`/`:post`/`:wait`/`:canfail`/
|
|
138
|
+
`:empty_inputs`/`:separator`, pipe-mode timeout via stream abort, default
|
|
139
|
+
stderr severity `Log::DEBUG`.
|
|
140
|
+
- Path: `find_all`/`glob_all`, `@where`/`@original`, `identify`, `relocate`,
|
|
141
|
+
`#read`/`#open` produce first but `#write` does not, `method_missing` segment
|
|
142
|
+
building (`Scout.etc`), explicit `require 'scout/named_array'`.
|
|
143
|
+
- Resource: `rake_dirs` + `ScoutRake.run` fork model, `share/software` +
|
|
144
|
+
`install_helpers`, `Resource.install`.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## (c) Important concepts that remain undocumented, with reasons
|
|
149
|
+
|
|
150
|
+
**Dead / unreachable code — documented as known limitations, not as API:**
|
|
151
|
+
- First `Open.read_stream` definition (stream.rb:382-399, IO.select/Thread.pass
|
|
152
|
+
loop) — shadowed by the second def at :401; never reachable.
|
|
153
|
+
- Dead `Open.read_stream` duplicate + commented-out `sort_stream` (stream.rb:442-444).
|
|
154
|
+
- `Open.append` instance method (dead); docs teach `mode: 'a'` instead.
|
|
155
|
+
- `Open.notify_write` is a silent no-op in an essentials-only install (`Misc.notify`/
|
|
156
|
+
`send_email` are not defined here — see (d)); noted, not taught.
|
|
157
|
+
- `Open.with_fifo` cannot clean a pre-existing path (`File.rm` NoMethodError) —
|
|
158
|
+
listed as a known limitation.
|
|
159
|
+
|
|
160
|
+
**Kept as INTERNAL footnotes (not user-facing guarantees):**
|
|
161
|
+
- `Scout::Config` legacy rbbt caller-token regexes (`file:`/`line:` frames rarely
|
|
162
|
+
filtered by scout code) — implementation residue; explaining them in user docs
|
|
163
|
+
would document dead parsing branches.
|
|
164
|
+
- `Scout::Config` has no mutex around the shared CACHE — recorded as a known gap
|
|
165
|
+
in LockingAndConcurrency rather than as behaviour to rely on.
|
|
166
|
+
- `Misc` double definitions (`counts` defined twice), `intersect_sorted_arrays`
|
|
167
|
+
mutating its args, `file_md5` fallback hashing the *path string* rather than
|
|
168
|
+
content — all noted as code-health items, none is a documented guarantee.
|
|
169
|
+
- `Persist::CONNECTIONS` registry — internal plumbing.
|
|
170
|
+
|
|
171
|
+
**OUT_OF_SCOPE (by design):**
|
|
172
|
+
- The stale gemspec doc manifest (lists 12 nonexistent `doc/*.md` files). This is
|
|
173
|
+
a maintenance task (`rake gemspec` regeneration), not a documentation issue;
|
|
174
|
+
left open and flagged rather than claimed fixed.
|
|
175
|
+
- Cross-repo surfaces that this repo must not teach (see (d)).
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## (d) Functionality previously attributed to this repo that is implemented elsewhere
|
|
180
|
+
|
|
181
|
+
From coverage-matrix section F + `research/ecosystem-attribution.md` (every row
|
|
182
|
+
verified by locating the defining line or the require/dependency edge, never by
|
|
183
|
+
name alone):
|
|
184
|
+
|
|
185
|
+
| concept | actually implemented in | key evidence |
|
|
186
|
+
|---|---|---|
|
|
187
|
+
| `TSV` class, `TSV::Dumper` | **scout-gear** | `GEAR/lib/scout/tsv.rb:17`, `tsv/dumper.rb:2` |
|
|
188
|
+
| `Annotation.tsv` / `Annotation.load_tsv` (hence the `:annotation` Persist serializer) | **scout-gear** (reopens essentials' Annotation) | `GEAR/lib/scout/tsv/annotation.rb:46,127`; essentials' serialize.rb:37-38,74-75 call it without requiring it → NoMethodError standalone |
|
|
189
|
+
| `Workflow` / `Task` / `Step` | **scout-gear** | `GEAR/lib/scout/workflow{,_task,_step}.rb` |
|
|
190
|
+
| `.info` Step blob format read by `Open.mtime` | **scout-gear** | essentials `open/final.rb:147-150` calls `Persist.load(info_file, Step::SERIALIZER)` — a gear constant, never required |
|
|
191
|
+
| Scheduler / HPC (SLURM/PBS/LFS/orchestrator) | **scout-gear**; **scout-camp** only adds cloud/terraform deployment (its bin loads gear's `bin/scout`) | `GEAR/.../deployment/scheduler/{slurm,pbs,lfs}.rb`; `CAMP/lib/scout-camp.rb` |
|
|
192
|
+
| `Misc.notify` / `Misc.send_email` | **legacy rbbt-util only** (no scout gem defines them) | `RU/lib/rbbt/util/misc/communication.rb:15,48` |
|
|
193
|
+
| `Bgzf` / bgzip path of `Open.bgunzip` | **legacy rbbt-util only** | `RU/lib/rbbt/util/misc/bgzf.rb:5` |
|
|
194
|
+
| `deep_indifferent` | **exists NOWHERE** (0 grep hits across essentials, gear, ai, rig, camp, rbbt-util 6.0.5) | ecosys #5 |
|
|
195
|
+
| CLI `bin/scout` / `scout_commands/` dispatch | **scout-gear** (+ per-gem command dirs) | `GEAR/bin/scout` |
|
|
196
|
+
| rbbt-util 6.0.5 `require_instead` shims (30 files redirecting rbbt requires onto scout files) | **rbbt-util**; direction UNVERIFIED at gemspec level | `RU/lib/rbbt/util/misc/indiferent_hash.rb` |
|
|
197
|
+
|
|
198
|
+
Genuinely local (for contrast): `ScoutRake`/`rake_dirs` (gear does not use it),
|
|
199
|
+
`Scout.etc` mechanism, `share/software` + `install_helpers`, Path/Resource/
|
|
200
|
+
Persist/Open/CMD/Log/SOPT/TmpFile/IndiferentHash/NamedArray/Misc/Annotation core,
|
|
201
|
+
vendored Lockfile, `Scout::Config`.
|
|
202
|
+
|
|
203
|
+
Dependency direction: scout-gear and scout-camp *declare* essentials;
|
|
204
|
+
scout-rig requires it in code but **omits the gemspec edge**; scout-ai reaches it
|
|
205
|
+
only transitively. Conversely essentials silently depends *upward* on gear types
|
|
206
|
+
(TSV, Step::SERIALIZER) and legacy rbbt-util methods for the items above — no
|
|
207
|
+
scout-family or rbbt-family runtime dependency is declared at all
|
|
208
|
+
(term-ansicolor, yaml, rake, listen only).
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## (e) Significant inter-document inconsistencies corrected
|
|
213
|
+
|
|
214
|
+
From the critic gates (`tmp/critic/gate1|gate2/report.md`, final
|
|
215
|
+
acceptance notes) and the phase-6 consistency audit:
|
|
216
|
+
|
|
217
|
+
- **invert_grep no-op example** (WorkingWithFiles) — the rewrite claimed
|
|
218
|
+
`Open.read(f, invert_grep: 'an')` filters lines; live probe shows it returns
|
|
219
|
+
the whole file (`invert_grep` only takes effect together with `grep`; the
|
|
220
|
+
underlying `Open.grep(io, 'an', true)` works). New regression caught by gate 1.
|
|
221
|
+
- **dup-vs-clone** — AnnotationSystem said *both* lose annotations; its own cited
|
|
222
|
+
probe shows `clone` **keeps** them (clone copies the singleton class). Gate 2.
|
|
223
|
+
- **`&F[match={:m=>1}]` naming shape** (CoreUtilities) — real shape is
|
|
224
|
+
`&F[m=c4ca4238a0b923820dcc509a6f75849b]:<md5-of-options>`; the value is
|
|
225
|
+
*digested*, not inspected, and a `:md5` tail is appended. Gate 2.
|
|
226
|
+
- **`tmp_for_file` arity** (CoreUtilities) — `tmp_for_file('/a/b/c', :prefix =>
|
|
227
|
+
'P')` raises NoMethodError (a Hash in the `tmp_options` slot); the runnable
|
|
228
|
+
form is `tmp_for_file('/a/b/c', {}, :prefix => 'P')`. Gate 2.
|
|
229
|
+
- **`save_job_run_info`** (Cookbook) — nonexistent API pointing at a page that
|
|
230
|
+
documents no such feature; sentence removed. Phase 6.
|
|
231
|
+
- **`TmpFile.tmp_dir`** (WorkingWithFiles) vs `TmpFile.user_tmp` (CoreUtilities)
|
|
232
|
+
— two pages disagreed, one referenced a nonexistent method; unified on
|
|
233
|
+
`user_tmp` (`$HOME/tmp/scout`). Phase 6.
|
|
234
|
+
- **`Log.none`** (LoggingAndProgress) — no such convenience method; ladder top
|
|
235
|
+
expressed via the `Log::NONE` constant. Phase 6.
|
|
236
|
+
- **Terminology anchors now enforced tree-wide** — "pipe ends" (never "paired
|
|
237
|
+
stdout/stderr streams"), `std_err` for the capture attribute, severity ladder
|
|
238
|
+
`DEBUG LOW MEDIUM HIGH INFO WARN ERROR NONE`, bare `claim` (never
|
|
239
|
+
`self.claim`), `find` never nil, drivers as accessor hashes.
|
|
240
|
+
- **Lock-dir examples** no longer hard-code a machine-specific home path
|
|
241
|
+
(`$HOME/.scout/tmp/{persist,produce,sensible_write}_locks`), while the literal
|
|
242
|
+
`·home·mvazque2·...probeD2` lock name is retained verbatim (it is actual
|
|
243
|
+
`TmpFile.tmp_for_file` output) and now annotated as a machine-specific example
|
|
244
|
+
value. Final pass.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## (f) Areas where the implementation is ambiguous and documentation remains uncertain
|
|
249
|
+
|
|
250
|
+
From `research/doc_audit/resumption-reference.md` §5 decisions and the
|
|
251
|
+
UNVERIFIED list:
|
|
252
|
+
|
|
253
|
+
- **AnnotatedArray Integer elements** — raise TypeError (`cm_aa2/3/4` probes);
|
|
254
|
+
annotated arrays require extendable elements. Documented as a requirement plus
|
|
255
|
+
an Improvements-style note; arguably a bug.
|
|
256
|
+
- **`AnnotatedArray#each_with_index` without a block** — NoMethodError. Treated
|
|
257
|
+
as a bug; explicitly not promised in the docs.
|
|
258
|
+
- **IndiferentHash `"false"` coercion asymmetry** — `string2hash`/`parse_options`
|
|
259
|
+
never coerce `"false"` to `false` (P20), while `Scout::Config.get` does.
|
|
260
|
+
Documented as-is and flagged as a bug candidate.
|
|
261
|
+
- **rbbt-util dependency direction** — `require_instead` shims clearly *consume*
|
|
262
|
+
scout files, but rbbt-util 6.0.5's installed tree has no readable gemspec, so
|
|
263
|
+
the declared edge is UNVERIFIED. Kept flagged in Architecture's table.
|
|
264
|
+
- **NamedArray `key:` kwarg** — claimed, but the signature is `*args` with no
|
|
265
|
+
kwarg handling; the claim was dropped rather than resolved.
|
|
266
|
+
- **Log severity env/file precedence** — both sources are real; resolved by probe
|
|
267
|
+
(environment variables override the config file) and documented with that order.
|
|
268
|
+
- **Persist driver registry naming** — resolved: the accessor-hash form
|
|
269
|
+
(`Persist.save_drivers` / `Persist.load_drivers`) is what the code uses;
|
|
270
|
+
documented accordingly.
|
|
271
|
+
- **`ConcurrentStreamProcessFailed` clobber** — the exception carries
|
|
272
|
+
`concurrent_stream => nil` in practice; documented as an unreliable attribute.
|
|
273
|
+
- **`Open.wgrep` / `Open.rgrep` claims** — nonexistent; removed from the docs.
|
|
274
|
+
- **`NamedArray` `key:` kwarg and Camp "job arrays"** — both remain UNVERIFIED in
|
|
275
|
+
the research record (see `research/ecosystem-attribution.md` §UNVERIFIED).
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Post-audit state
|
|
280
|
+
|
|
281
|
+
- 22 doc files delivered (17 rewritten + 5 NEW_PAGE); README.md rewritten and
|
|
282
|
+
gate-verified (all links resolve, getting-started snippet executable,
|
|
283
|
+
abstractions table traced live).
|
|
284
|
+
- `doc/Improvements.md` deliberately **untouched** — it is a bug/improvement log,
|
|
285
|
+
not documentation; its `deep_indifferent` guidance stays as a historical entry.
|
|
286
|
+
- Critic final verdict ACCEPT_WITH_NOTES; the three optional notes were applied:
|
|
287
|
+
HandlingStreams `read_stream` mechanism sentence (stream.rb:401), README
|
|
288
|
+
test-count parenthetical (49 files = 47 test files, one of which
|
|
289
|
+
`test/scout/log/test_color.rb` is empty, + 2 `test_helper.rb`, one defining
|
|
290
|
+
`TestMiscHelper`), and machine-specific-value annotations on the two remaining
|
|
291
|
+
`/home/mvazque2` strings.
|
|
292
|
+
- Open maintenance items (not docs): regenerate the gemspec doc manifest;
|
|
293
|
+
decide the fate of the untracked `test/scout/test_cmd_save_stderr.rb`.
|
|
294
|
+
- Nothing committed; `research/doc_audit/` retained pending user confirmation.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Phase 3 — Cross-repo ecosystem attribution (scout-essentials)
|
|
2
|
+
|
|
3
|
+
Date: 2026-02 (audit working copy)
|
|
4
|
+
Audit target: `/bulk/mvazque2/git/scout-essentials` (defines the `Scout` namespace).
|
|
5
|
+
|
|
6
|
+
## Evidence sources
|
|
7
|
+
|
|
8
|
+
| Repo | Where examined | Status |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| scout-essentials | `/bulk/mvazque2/git/scout-essentials` (worktree, VERSION 1.8.8) + installed gem `scout-essentials-1.8.8` | LOCAL, authoritative |
|
|
11
|
+
| scout-gear | installed gem `~/.rvm/gems/ruby-3.3.1/gems/scout-gear-10.12.2` (also 10.11.x, 10.12.1) | LOCAL (gem copy); the `/bulk/mvazque2/git/scout-gear` worktree is only bound for `tmp/` in this sandbox, so gem copies were used |
|
|
12
|
+
| scout-ai | installed gem `scout-ai-1.2.6` (gemspec stub says 1.2.5) | LOCAL (gem copy); worktree similarly `tmp/`-only |
|
|
13
|
+
| scout-rig | installed gem `scout-rig-0.2.6` | LOCAL (gem copy only) |
|
|
14
|
+
| scout-camp | installed gem `scout-camp-0.2.0` | LOCAL (gem copy only) |
|
|
15
|
+
| rbbt-util | installed gem `rbbt-util-6.0.5` | LOCAL (relevant for the refactor shim layer) |
|
|
16
|
+
|
|
17
|
+
Method: every attribution below was verified by locating the defining
|
|
18
|
+
`class`/`module` line, or the `require`/`add_runtime_dependency` edge — never by
|
|
19
|
+
name alone. File paths are gem paths; `SE = /bulk/mvazque2/git/scout-essentials`,
|
|
20
|
+
`GEAR = ~/.rvm/gems/ruby-3.3.1/gems/scout-gear-10.12.2`,
|
|
21
|
+
`AI = .../scout-ai-1.2.6`, `RIG = .../scout-rig-0.2.6`,
|
|
22
|
+
`CAMP = .../scout-camp-0.2.0`, `RU = .../rbbt-util-6.0.5`.
|
|
23
|
+
|
|
24
|
+
## Attribution table
|
|
25
|
+
|
|
26
|
+
| # | Concept | Implementing repo | Evidence (file:line) | Classification | Notes |
|
|
27
|
+
|---|---|---|---|---|---|
|
|
28
|
+
| 1 | `TSV` class | **scout-gear** | `GEAR/lib/scout/tsv.rb:17 module TSV` (required by `GEAR/lib/scout-gear.rb:2 require_relative 'scout/tsv'`) | PROVIDED_BY_DEPENDENCY (w.r.t. essentials) | Not present anywhere in `SE/lib`. essentials' `lib/scout-essentials.rb` never requires `scout/tsv` — hence the standalone `NameError`s in the P-probes. |
|
|
29
|
+
| 1b | `TSV::Dumper` | **scout-gear** | `GEAR/lib/scout/tsv/dumper.rb:2 class Dumper` (inside `module TSV`) | PROVIDED_BY_DEPENDENCY | The `when TSV::Dumper` branch that `SE`'s produce code tests can only be reached with scout-gear loaded. |
|
|
30
|
+
| 2 | `Annotation.tsv` / `Annotation.load_tsv` | **scout-gear** | `GEAR/lib/scout/tsv/annotation.rb:46 def self.tsv(objs, *fields)`; `:127 def self.load_tsv_values(id, values, *fields)` (also referenced at `:158`) | PROVIDED_BY_DEPENDENCY (reverse dependency: gear reopens essentials' Annotation module) | `SE/lib/scout/persist/serialize.rb:37-38` (`Annotation.tsv(content, :all).to_s`) and `:74-75` (`Annotation.load_tsv(TSV.open(serialized))`) call methods that only exist once scout-gear's `scout/tsv/annotation.rb` is loaded. → **CONSUMED_OR_INTEGRATED_HERE** for the caller side. The `:annotation` Persist serializer in essentials is therefore only functional inside the full scout stack. |
|
|
31
|
+
| 3 | `Workflow` / `Task` / `Step` / Job machinery | **scout-gear** | `GEAR/lib/scout/workflow.rb:17 module Workflow`; `GEAR/lib/scout/workflow/task.rb:8 module Task`; `GEAR/lib/scout/workflow/step.rb:16 class Step`; entry chain `GEAR/lib/scout.rb → require 'workflow-scout' → require 'scout-gear' + require 'scout/workflow'` | NOT_IMPLEMENTED_IN_ESSENTIALS / PROVIDED_BY_DEPENDENCY | Confirms the P-inventory: `SE` defines none of these. |
|
|
32
|
+
| 3b | `.info` file format read by `Open.mtime` | **scout-gear** | `GEAR/lib/scout/workflow/step.rb:6 SERIALIZER = Scout::Config.get(:serializer, :step_info, ...)`; `GEAR/lib/scout/workflow/step/info.rb:7 def info_file`, `:16 def self.load_info` | CONSUMED_OR_INTEGRATED_HERE | `SE/lib/scout/open/final.rb:147-150` reads `<file>.info` and calls `Persist.load(info_file, Step::SERIALIZER)[:]` — it hard-depends on scout-gear's `Step::SERIALIZER` constant while never requiring scout-gear. Same silent-coupling pattern as #2. |
|
|
33
|
+
| 4 | Scheduler / HPC / orchestration (SLURM, PBS, LFS, orchestrator rules, job arrays, `scout camp`) | **scout-gear** (SLURM/PBS/LFS/orchestrator) + **scout-camp** (infra provisioning) | SLURM: `GEAR/lib/scout/workflow/deployment/scheduler/slurm.rb:4 module SLURM` (sibling files `job.rb`, `lfs.rb`, `pbs.rb`); orchestrator: `GEAR/lib/scout/workflow/deployment/orchestrator/rules.rb:220` reads `Scout.etc.batch[...]`; camp: `CAMP/lib/scout-camp.rb`, `CAMP/lib/scout/{offsite,terraform_dsl,aws,render}.rb`, `CAMP/bin/scout-camp` (ends `load Scout.bin.scout.find`), `CAMP/scout_commands/{find,glob,offsite,sync,terraform}` | NOT_IMPLEMENTED_IN_ESSENTIALS | No scheduler/HPC/SLURM/camp code or docs exist in scout-essentials (grep over `SE/lib` and `SE/doc` returns nothing). Note `CAMP`'s HPC/scheduler layer itself is **thin** — `scout-camp`'s gemspec runtime deps are scout-essentials + aws-sdk-s3 + sinatra + terraform + mimemagic + omniauth (no scout-gear edge), and its bin simply loads scout-gear's `bin/scout`; the SLURM/PBS/orchestrator logic lives in gear. |
|
|
34
|
+
| 5 | `deep_indifferent` | **NOWHERE (in this ecosystem snapshot)** | grep `def deep_indifferent` across all installed scout gems + rbbt-util-6.0.5/lib → 0 hits. Only textual mention: `SE/doc/Improvements.md:85-89` ("deep_indifferent must be called explicitly") and the AnnotatingData ledger citing `Misc.deep_indifferent` | NOT_FOUND | `SE/lib/scout/misc.rb` requires only format/insist/digest/filesystem/monitor/system/helper/matching/math — no `misc/indiferent_hash` and no such method. `SE/lib/scout/indiferent_hash.rb` has `deep_merge` (line 21) but no `deep_indifferent`. rbbt-util 6.0.5's `lib/rbbt/util/misc/indiferent_hash.rb` is a **refactor shim**: `Rbbt.require_instead 'scout/indiferent_hash'`, i.e. it points *back* at essentials, so it cannot be the implementation either. Doc claim that this is available behavior is **stale/hallucinated**; only nested *access* works, and only incidentally (ledger C17). |
|
|
35
|
+
| 6 | `Misc.notify` / `Misc.send_email` | **rbbt-util (legacy), not scout-gear/ai/rig/camp/essentials** | `RU/lib/rbbt/util/misc/communication.rb:15 def self.notify`, `:29 def self.send_email_old`, `:48 def self.send_email` | CONSUMED_OR_INTEGRATED_HERE (implicit, no require) | `SE/lib/scout/open/util.rb:89-99` (`Open.notify_write`) calls `Misc.notify` / `Misc.send_email`; `SE/lib/scout/misc.rb` does not require any communication module, and no scout gem defines these. In an essentials-only install these are `NoMethodError`s (rescued by `rescue` in `notify_write`). rbbt-util's communication.rb is **not** a shim (it contains the real implementation), unlike its other files. So the definitions survive only in the legacy rbbt-util gem, outside the Scout stack proper. |
|
|
36
|
+
| 7 | `Bgzf` (bgzip/bgzf decompression) | **rbbt-util (legacy)** | `RU/lib/rbbt/util/misc/bgzf.rb:5 module Bgzf` (used at `:24`) | CONSUMED_OR_INTEGRATED_HERE (implicit, no require) | `SE/lib/scout/open/util.rb:35 Bgzf.setup stream` (in `Open.bgunzip`) references a constant that no scout gem defines. rbbt-util's `lib/rbbt/tsv/util.rb:112` even has the Bgzf branch commented out. Same pattern as #6: works only when legacy rbbt-util happens to be loaded. |
|
|
37
|
+
| 8 | `ScoutRake` / `rake_dirs` | **scout-essentials** | `SE/lib/scout/resource/produce/rake.rb:5 class Rake::FileTask` patch, `:25 module ScoutRake`, `def self.run`; `rake_dirs` registry in `SE/lib/scout/resource/produce.rb` (claim → `@rake_dirs[path]`), consumed at `produce.rb:127 when :rake` | IMPLEMENTED_IN_ESSENTIALS | Genuinely local. `rake` is a declared runtime dep (`SE/scout-essentials.gemspec:174`). scout-gear does NOT use `rake_dirs`/`ScoutRake` (0 hits in `GEAR/lib`), so this is currently essentials-only plumbing consumed by end-user Resource claims. |
|
|
38
|
+
| 8b | `Scout.etc` / `etc` path convention | **scout-essentials** (mechanism) — consumed by all | mechanism: `SE/lib/scout/resource/scout.rb:9 Path.load_path_maps(Scout.etc["path_maps"])` + `SE/lib/scout/config.rb:29 Path.setup("etc").config.find_all...`; `etc` is not a hard-coded map — `Path.method_missing` (`SE/lib/scout/path.rb:44-53`) + `Resource#method_missing` (`SE/lib/scout/resource.rb:69`) turn `Scout.etc`/`Scout.share` into path-joins resolved through the map registry (`SE/lib/scout/path/find.rb:84-100` path_maps incl. `:user => "{HOME}/.{PKGDIR}/..."`) | IMPLEMENTED_IN_ESSENTIALS | Downstream consumers confirmed: `AI/lib/scout-ai.rb:1-9`, `RIG/lib/scout-rig.rb:1-4`, `CAMP/lib/scout-camp.rb:1-9` all do `require 'scout' + require 'scout/path' + require 'scout/resource'` then `Path.add_path :<self>_lib, ...`; gear reads `Scout.etc.batch[...]` (`GEAR/.../orchestrator/rules.rb:220`). |
|
|
39
|
+
| 8c | `Scout.share.software` / `share/software` + `install_helpers` | **scout-essentials** (convention + assets) | `SE/lib/scout/resource.rb:7,16 require_relative 'resource/software'`; `SE/lib/scout/resource/software.rb:4 File.expand_path(Scout.share.software.install_helpers.find(:lib))`, `:7 def self.install(...)`; assets shipped in `SE/share/software/install_helpers`; software claim branch `SE/lib/scout/resource/produce.rb:138-141` (`self.root.software`, `Resource.install`, `set_software_env`) | IMPLEMENTED_IN_ESSENTIALS | scout-rig contains **no** `software`/`share/software` references (0 hits in `RIG/lib` + Rakefile), so the "rig relationship" is only the generic `Path`/`Resource` integration above, not a software-install one. |
|
|
40
|
+
| 9 | `Scout` module default resource (`Resource.default_resource = Scout`, pkgdir `scout`) | **scout-essentials** | `SE/lib/scout/resource/scout.rb:1-10` (`module Scout; extend Resource; self.pkgdir='scout'`; `Resource.default_resource = Scout`); `Path.default_pkgdir` `SE/lib/scout/path.rb:10-15` | IMPLEMENTED_IN_ESSENTIALS | `Scout.version` is the only thing scout-gear adds (`GEAR/lib/scout.rb:4-7`). |
|
|
41
|
+
| 10 | CLI binary (`scout`) and `scout_commands/` dispatch | **scout-gear** (bin) — plus per-gem command dirs | `GEAR/bin/scout` (loads scout_commands: alias, batch, cat, doc, entity, find, glob, kb, log, purge, rbbt, resource, system, template, update, workflow); `CAMP/bin/scout-camp` ends with `load Scout.bin.scout.find`; `CAMP/scout_commands/{find,glob,offsite,sync,terraform}`; `AI/bin/scout-ai` + `AI/scout_commands/{agent,llm,workflow}` | NOT_IMPLEMENTED_IN_ESSENTIALS | Matches inventory: essentials ships no bin/ and no scout_commands/. |
|
|
42
|
+
| 11 | IndiferentHash, Path.find/path_maps, Log, SOPT/SimpleOpt, CMD, Persist, Resource claims, Open, TmpFile, Annotation (core), NamedArray, Config | **scout-essentials** | `SE/lib/scout-essentials.rb` require list; per-file definitions in `SE/lib/scout/{indiferent_hash,path,log,simple_opt,cmd,persist,resource,open,tmpfile,annotation,named_array,config}.rb` (verified in Phase 1/2 inventories and re-checked here) | IMPLEMENTED_IN_ESSENTIALS | — |
|
|
43
|
+
|
|
44
|
+
## Dependency graph
|
|
45
|
+
|
|
46
|
+
### What scout-essentials depends on (runtime)
|
|
47
|
+
|
|
48
|
+
From `SE/scout-essentials.gemspec:172-175`:
|
|
49
|
+
`term-ansicolor`, `yaml`, `rake`, `listen`. Dev deps: shoulda, rdoc, juwelier.
|
|
50
|
+
|
|
51
|
+
That is: **no scout-family or rbbt-family runtime dependency at all.**
|
|
52
|
+
Everything scout-flavoured it touches (TSV, Step::SERIALIZER, Annotation.tsv,
|
|
53
|
+
Misc.notify/send_email, Bgzf) is reached *implicitly* without a require or a
|
|
54
|
+
gemspec edge — the "phantom integrations" documented above.
|
|
55
|
+
|
|
56
|
+
### Who depends on scout-essentials
|
|
57
|
+
|
|
58
|
+
Verified from installed gemspecs (grep `add_runtime_dependency`):
|
|
59
|
+
|
|
60
|
+
- **scout-gear** — yes. `GEAR/scout-gear.gemspec: add_runtime_dependency scout-essentials (>= 0)` (also in 10.11.6, 10.11.10, 10.12.1). Code edge too: `GEAR/lib/scout-gear.rb:1 require 'scout-essentials'`.
|
|
61
|
+
- **scout-camp** — yes. `CAMP/scout-camp.gemspec: add_runtime_dependency scout-essentials (>= 0)`; `CAMP/lib/scout-camp.rb:1-3 require 'scout'/'scout/path'/'scout/resource'` (which resolve to essentials' files, e.g. `SE/lib/scout/path.rb`, `SE/lib/scout/resource.rb`, `SE/lib/scout/resource/scout.rb`).
|
|
62
|
+
- **scout-rig** — **no scout-essentials edge in its gemspec** (`RIG/scout-rig.gemspec` runtime deps: `pycall` only), but **code-level dependency**: `RIG/lib/scout-rig.rb:1-4` requires `'scout'`, `'scout/path'`, `'scout/resource'` and calls `Path.caller_lib_dir`, `Path.add_path`; `RIG/lib/scout/python/paths.rb:26 add_paths(Scout.python.find_all)` uses essentials' Path machinery (and `RIG/lib/scout/workflow/python.rb:1 require 'scout/workflow'` needs scout-gear). So rig is a *declared* transitive consumer at best — the gemspec simply omits the constraint.
|
|
63
|
+
- **scout-ai** — **directly depends on scout-rig** (`AI/scout-ai.gemspec` runtime deps: scout-rig, ruby-openai, ollama-ai, ruby-mcp-client, hnswlib) and *transitively* on essentials via rig's runtime requires and via `AI/lib/scout-ai.rb:1-3 require 'scout'/'scout/path'/'scout/resource'` (0 direct mentions of scout-gear/scout-essentials in its gemspec). Its bin delegates to gear's CLI (`AI/bin/scout-ai`).
|
|
64
|
+
- **rbbt-util 6.0.5** — reverse-compat consumer: `RU/lib/rbbt/util/misc/indiferent_hash.rb` and 29 other files are two-line `Rbbt.require_instead 'scout/<path>'` shims redirecting rbbt requires onto essentials/gear files (`scout/persist/tsv`, `scout/resource`, `scout/workflow/step`, `scout/semaphore`, `scout/tmpfile`, `scout/tsv`, `scout/work_queue`, ...). Note this shim set targets the *whole* Scout stack, not only essentials, and rbbt-util's own gemspec is not readable at the audited path (gemspec file absent in the installed tree) → dependency *direction* for rbbt-util UNVERIFIED at gemspec level (see below).
|
|
65
|
+
|
|
66
|
+
### Graph summary
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
term-ansicolor/yaml/rake/listen
|
|
70
|
+
▲
|
|
71
|
+
scout-essentials (Scout namespace core: Path, Open, Log, Persist, CMD,
|
|
72
|
+
▲ ▲ ▲ Resource/claims, Annotation core, IndiferentHash, SOPT…)
|
|
73
|
+
│ │ │ (runtime requires; rig/camp also declare the gemspec edge,
|
|
74
|
+
│ │ │ rig's gemspec omits it)
|
|
75
|
+
│ │ └────────────── scout-camp ──(bin loads)──► bin/scout (gear)
|
|
76
|
+
│ └──── requires ──── scout-rig ──(gemspec dep)─► scout-ai
|
|
77
|
+
└─ gemspec+require ───── scout-gear (TSV, Workflow/Task/Step, HPC/
|
|
78
|
+
scheduler, CLI bin/scout, scout_commands)
|
|
79
|
+
▲
|
|
80
|
+
└── loaded by CAMP/bin, AI/bin
|
|
81
|
+
|
|
82
|
+
legacy rbbt-util 6.0.5 ── require_instead shims ──► scout-essentials/gear
|
|
83
|
+
(and keeps the only surviving definitions of Misc.notify/send_email, Bgzf)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### "Foundation of Scout and Scout-AI" — verdict
|
|
87
|
+
|
|
88
|
+
`SE/doc/StartHere.md:3-5` says essentials "is the foundation upon which Scout
|
|
89
|
+
and Scout-AI ... are built". As a **dependency-graph statement**:
|
|
90
|
+
|
|
91
|
+
- **TRUE for scout-gear ("Scout")** — direct gemspec + `require 'scout-essentials'` edge; gear builds TSV/Workflow/Step/HPC on top of it.
|
|
92
|
+
- **TRUE for scout-camp** — direct gemspec edge.
|
|
93
|
+
- **ONLY INDIRECTLY TRUE for scout-rig** — required in code, missing from rig's gemspec (omitted dependency).
|
|
94
|
+
- **TRUE for scout-ai ("Scout-AI")** — as a *transitive* dependency via scout-rig + its own `require 'scout'`; scout-ai has **no direct** dependency declaration on essentials.
|
|
95
|
+
|
|
96
|
+
So the claim is substantively correct but imprecise: essentials is the
|
|
97
|
+
namespace/foundation layer of the *whole* family, yet scout-ai (and rig) reach it
|
|
98
|
+
without declaring it, and several essentials features are themselves only
|
|
99
|
+
completable by scout-gear (see misattributions).
|
|
100
|
+
|
|
101
|
+
## Claims in scout-essentials docs that misattribute functionality
|
|
102
|
+
|
|
103
|
+
1. **Persist `:annotation` serializer presented as working** (`SE/lib/scout/persist/serialize.rb:37-38, 74-75`; documented in the data/persistence doc pages): the `Annotation.tsv` / `Annotation.load_tsv` / `TSV.open` it invokes are implemented in **scout-gear** (`GEAR/lib/scout/tsv/annotation.rb:46,127`; `GEAR/lib/scout/tsv.rb:17`), not in essentials, and are never required. Correcting attribution: *scout-gear*; standalone essentials raises `NoMethodError`/`NameError`.
|
|
104
|
+
2. **`Resource#produce` `:proc` / `:csv` claim types documented as usable** (`SE/lib/scout/resource/produce.rb`, branches testing `when TSV` / `when TSV::Dumper` before `when nil`, and `:csv` → "Not implemented yet"): the `TSV`/`TSV::Dumper` constants come from **scout-gear** (`GEAR/lib/scout/tsv.rb:17`, `GEAR/lib/scout/tsv/dumper.rb:2`). With gear absent, nil-returning procs crash with `NameError`. Correcting attribution: integration point with *scout-gear*, not an essentials feature.
|
|
105
|
+
3. **`Open.mtime` documented as a plain file-metadata helper**: `SE/lib/scout/open/final.rb:147-150` parses `<file>.info` with `Step::SERIALIZER` — `Step` and that constant are defined in **scout-gear** (`GEAR/lib/scout/workflow/step.rb:6,16`). Correcting attribution: essentials *reads* a **scout-gear Step** file format; the format is owned by gear.
|
|
106
|
+
4. **`Misc.notify` / `Misc.send_email` implied to exist** (`SE/lib/scout/open/util.rb:89-99` `Open.notify_write`): implemented only in **legacy rbbt-util** (`RU/lib/rbbt/util/misc/communication.rb:15,48`); no scout gem defines them. Correcting attribution: rbbt-util, and it is *not* a declared dependency of essentials.
|
|
107
|
+
5. **`Bgzf` / `Open.bgunzip` implied to work** (`SE/lib/scout/open/util.rb:35`): `Bgzf` is defined only in **legacy rbbt-util** (`RU/lib/rbbt/util/misc/bgzf.rb:5`). Correcting attribution: rbbt-util, undeclared.
|
|
108
|
+
6. **`deep_indifferent` (and the "call it explicitly" guidance)** — `SE/doc/Improvements.md:85-89`, plus the AnnotatingData ledger's `Misc.deep_indifferent` reference: **no implementation exists** in any audited repo (0 grep hits for `def deep_indifferent` across essentials, gear, ai, rig, camp, rbbt-util 6.0.5). Not merely misattributed — **NOT_FOUND**. The nested-IndiferentHash claim in the user docs (ledger C17) is correspondingly wrong.
|
|
109
|
+
7. **"Foundation upon which Scout and Scout-AI are built"** (`SE/doc/StartHere.md:5`): correct in substance (see verdict) but should be qualified — scout-ai depends on it only *transitively* (via scout-rig, whose own gemspec omits the essentials edge), and essentials itself silently *depends upward* on scout-gear types (TSV, Step) and legacy rbbt-util methods for items 1-5.
|
|
110
|
+
8. **Scheduler/HPC/"scout camp" style orchestration** — no essentials doc makes this claim (grep found none), but for completeness of the attribution ledger: all such functionality is in **scout-gear** (`workflow/deployment/scheduler/{slurm,pbs,lfs}.rb`, `orchestrator/`) with **scout-camp** adding cloud/offsite/terraform layers; nothing of it lives in essentials.
|
|
111
|
+
|
|
112
|
+
## UNVERIFIED items
|
|
113
|
+
|
|
114
|
+
- **rbbt-util dependency direction (gemspec level)** — `rbbt-util-6.0.5`'s installed tree has no readable gemspec at the audited path, so I could not confirm whether rbbt-util *declares* scout-essentials/scout-gear as runtime deps (the `require_instead` shim mechanism suggests intent, but the edge is UNVERIFIED).
|
|
115
|
+
- **`rake_dirs` external consumers** — verified essentials implements it and gear does not use it; whether any *user* workflow repos use `:rake` claims could not be checked (outside audited set).
|
|
116
|
+
- **`NamedArray#setup` `key:` kwarg semantics** (ledger C13) — orthogonal to attribution, still unresolved in Phase 2; not re-attempted here.
|
|
117
|
+
- **Camp "job arrays"** — I located SLURM/PBS/LFS in gear and the camp command dirs (`offsite/sync/terraform`); I did not exhaustively enumerate every camp subcommand or array-job helper, so any *specific* "job array" implementation claim in camp remains UNVERIFIED.
|
|
118
|
+
- **GitHub/upstream repositories** — Scout-Camp and Scout-Rig were NOT present as local git worktrees in this sandbox (only their installed gem copies), so file:line citations for them are from gems, which may lag their git heads. Marked as gem-snapshot evidence above.
|