appydave-tools 0.76.1 → 0.76.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2700178e0f8e7fa1ddbd046cb78af4a0a340f2e8770637a2f3b30229e9f76179
4
- data.tar.gz: c5c3f8094e988cc77849f27d1126c3839825d231c06b8bb63d3410cfdfe72179
3
+ metadata.gz: 9e0809dc40e0f4940381134c70a57833d755df47f01f8e327a04b278e4d87c5a
4
+ data.tar.gz: a1aa1d00b87481b371edda22ed5f7f0fa63a895358002cbc330b4d4e8cbf1ae8
5
5
  SHA512:
6
- metadata.gz: e11cda4ffd9a0a555c15ae613e94b31aa7f508ba473ccc89d31a48d399f9b603204faa4018bea222f9640205b5d73a557b992acf3be94c926bdbeea494baedb5
7
- data.tar.gz: 4af0c479f1aeb82cc32dd06d8d954910fff6e9a4a2f785d2969a284fc9a55874a56ed71e1600be9c26b5ad3792a67be98105a9003b82c8d835eb0bd8a7d323cf
6
+ metadata.gz: 8ef02094f475fc3df1b6b346158dce9596cbc4898c4a5da60e573ae48ddb8ff10663d2b19be0da582adea9b47597a14926e7e55358d33e742762d8cf7b53bf6f
7
+ data.tar.gz: 1c96b7e36178f5f0ec3426934a88686fb23e19d890858c1825264bb3a33e67d6054ed520cd4157ff60906f468a91cd25d2c319696b6a1ae936baaca8a013f627
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [0.76.1](https://github.com/appydave/appydave-tools/compare/v0.76.0...v0.76.1) (2026-03-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * align SyncFromSsd#determine_range with ManifestGenerator format; add specs ([3f8cb37](https://github.com/appydave/appydave-tools/commit/3f8cb37a78bd3d9720eace21cf1abbbca285cd66))
7
+ * remove unconditional ssl_verify_peer: false from S3 clients; keep env override ([f49efb1](https://github.com/appydave/appydave-tools/commit/f49efb1c4a97ba904f3f3fc7d4292139a5e6c3fd))
8
+
1
9
  # [0.76.0](https://github.com/appydave/appydave-tools/compare/v0.75.0...v0.76.0) (2026-03-19)
2
10
 
3
11
 
@@ -1,27 +1,29 @@
1
1
  # Project Backlog — AppyDave Tools
2
2
 
3
- **Last updated**: 2026-03-19 (fr2-gpt-context-help assessment + 3 new items from quality audit)
4
- **Total**: 23 | Pending: 16 | Done: 7 | Deferred: 0 | Rejected: 0
3
+ **Last updated**: 2026-03-19 (bugfix-and-security assessment + 4 new items from quality audit)
4
+ **Total**: 27 | Pending: 17 | Done: 10 | Deferred: 0 | Rejected: 0
5
5
 
6
6
  ---
7
7
 
8
8
  ## Pending
9
9
 
10
10
  ### High Priority
11
+ - [ ] B024 — Tests: add configure_ssl_options unit tests to s3_operations_spec + share_operations_spec (protects B017 security fix) | Priority: high
11
12
  - [ ] B015 — BUG-2: FileCollector uses FileUtils.cd without ensure (process dir not restored on exception) | Priority: high
12
- - [ ] B016 — BUG-3: ManifestGenerator + SyncFromSsd produce incompatible SSD range strings (data integrity) | Priority: high
13
13
  - [x] B006 — BUG-1: Jump CLI get/remove key lookup | Completed: verified fixed 2026-03-19, regression spec added
14
- - [ ] B017 — Security: ssl_verify_peer disabled unconditionally in S3Operations + ShareOperations | Priority: high
15
14
 
16
15
  ### Medium Priority
17
- - [ ] B021 — Fix: gpt_context no-args guard checks format.nil? which is always false (dead condition) | Priority: medium
18
16
  - [ ] B022 — Tests: expand cli_spec.rb with functional tests (-i, -e, -f, -o flags, exit codes) | Priority: medium
17
+ - [ ] B026 — Tests: add determine_range edge cases (b00, b9, a40) to sync_from_ssd_spec + manifest_generator_spec | Priority: medium
18
+ - [ ] B027 — Tests: strengthen gpt_context no-args spec to verify file collection actually stops | Priority: medium
19
19
  - [ ] B023 — Tests: add file_collector_spec coverage for JSON format, aider format, error paths | Priority: medium
20
20
  - [ ] B018 — Tests: add specs for Jump Commands::Remove, Commands::Add, Commands::Update | Priority: medium
21
21
  - [ ] B019 — Fix: remove debug puts @working_directory from gpt_context/file_collector.rb | Priority: medium
22
22
  - [ ] B001 — FR-1: GPT Context token counting | Priority: medium
23
23
  - [ ] B012 — Arch: add integration tests for brand resolution end-to-end | Priority: medium
24
24
 
25
+ - [ ] B025 — Fix: stale comment in sync_from_ssd.rb line 173 (says 60-69, should say b50-b99) | Priority: low
26
+
25
27
  ### Low Priority
26
28
  - [ ] B007 — Performance: parallel git/S3 status checks for dam list | Priority: low
27
29
  - [ ] B008 — Performance: cache git/S3 status with 5-min TTL | Priority: low
@@ -40,6 +42,9 @@
40
42
  - [x] B013 — Arch: Extract GitHelper module (90 lines duplication) | Completed: dam-enhancement-sprint (Jan 2025)
41
43
  - [x] B014 — Arch: Create BrandResolver to centralize brand transformation | Completed: dam-enhancement-sprint (Jan 2025)
42
44
  - [x] B002 — FR-2: GPT Context AI-friendly help system | Completed: fr2-gpt-context-help (2026-03-19)
45
+ - [x] B016 — BUG-3: ManifestGenerator + SyncFromSsd incompatible SSD range strings | Completed: bugfix-and-security (2026-03-19)
46
+ - [x] B017 — Security: ssl_verify_peer disabled unconditionally in S3Operations + ShareOperations + S3Scanner | Completed: bugfix-and-security (2026-03-19)
47
+ - [x] B021 — Fix: gpt_context no-args guard had dead format.nil? condition | Completed: bugfix-and-security (2026-03-19)
43
48
 
44
49
  ---
45
50
 
@@ -308,6 +308,11 @@ include_context 'with vat filesystem and brands', brands: %w[appydave]
308
308
  - `ssl_verify_peer: false` is not safe for AWS — HTTPS alone doesn't prevent MITM without peer verification
309
309
  - ManifestGenerator `determine_range` is the canonical format; SyncFromSsd must match it
310
310
 
311
+ ### From bugfix-and-security (2026-03-19)
312
+ - **`options.format` defaults to `'tree,content'`** in GptContext::Options — not `'content'`. It is never nil. Do not use `options.format.nil?` as a guard.
313
+ - **Use `$CHILD_STATUS` not `$?` in specs** — RuboCop flags `$?` as a special global variable. Use `$CHILD_STATUS` (from the English module, auto-available in RSpec) for exit status assertions.
314
+ - **`exit` with no code exits 0** — Ruby's bare `exit` call produces exit status 0. Write specs accordingly.
315
+
311
316
  ### From fr2-gpt-context-help (2026-03-19)
312
317
  - `opts.on_tail` vs `opts.on` matters for option ordering in OptionParser
313
318
  - Subprocess specs (`ruby #{script} --flag`) are correct for CLI integration tests
@@ -5,16 +5,16 @@
5
5
  **Target**: All 3 fixes committed; tests pass; rubocop clean; no regressions
6
6
 
7
7
  ## Summary
8
- - Total: 3 | Complete: 0 | In Progress: 3 | Pending: 0 | Failed: 0
8
+ - Total: 3 | Complete: 3 | In Progress: 0 | Pending: 0 | Failed: 0
9
9
 
10
10
  ## Pending
11
11
 
12
12
  ## In Progress
13
- - [~] fix-b017-ssl — Remove unconditional ssl_verify_peer: false from s3_operations.rb, share_operations.rb, s3_scanner.rb
14
- - [~] fix-b016-range — Align SyncFromSsd#determine_range to ManifestGenerator format; update sync_from_ssd_spec.rb; add manifest_generator_spec.rb coverage
15
- - [~] fix-b021-guard — Remove options.format.nil? from gpt_context.rb:115 guard; add/update spec for no-args behaviour
16
13
 
17
14
  ## Complete
15
+ - [x] fix-b017-ssl — ssl_verify_peer: false removed from s3_operations.rb, share_operations.rb, s3_scanner.rb. s3_operations_spec stub updated. 755 examples, 0 failures. v0.76.0 published.
16
+ - [x] fix-b021-guard — Removed dead format.nil? condition (format defaults to 'tree,content', never nil). Added no-args spec asserting exit 0 + error message. Used $CHILD_STATUS not $? (rubocop). 755 examples, 0 failures.
17
+ - [x] fix-b016-range — SyncFromSsd#determine_range aligned to ManifestGenerator format (any letter, 50-number ranges). Updated 4 unit specs + 4 integration path assertions in sync_from_ssd_spec. Added 4 new specs to manifest_generator_spec. 759 examples, 0 failures. v0.76.1 published.
18
18
 
19
19
  ## Failed / Needs Retry
20
20
 
@@ -0,0 +1,94 @@
1
+ # Assessment: bugfix-and-security
2
+
3
+ **Campaign**: bugfix-and-security
4
+ **Date**: 2026-03-19 → 2026-03-19
5
+ **Results**: 3 complete, 0 failed
6
+ **Version shipped**: v0.76.1
7
+ **Quality audit**: code-quality-audit + test-quality-audit run post-campaign
8
+
9
+ ---
10
+
11
+ ## Results Summary
12
+
13
+ | Work Unit | Status | Notes |
14
+ |-----------|--------|-------|
15
+ | fix-b017-ssl | ✅ Complete | ssl_verify_peer: false removed from s3_operations.rb, share_operations.rb, s3_scanner.rb. ENV escape hatch preserved. s3_operations_spec stub updated. |
16
+ | fix-b016-range | ✅ Complete | SyncFromSsd#determine_range now matches ManifestGenerator (letter prefix, 50-number ranges). 4 unit specs + 4 integration path assertions updated. 4 new specs added to manifest_generator_spec. |
17
+ | fix-b021-guard | ✅ Complete | Dead `&& options.format.nil?` condition removed. format defaults to 'tree,content', never nil. No-args spec added. Used $CHILD_STATUS not $? (rubocop requirement). |
18
+
19
+ **Test baseline:** 754 → 759 examples (+5). Coverage: 84.92% → 85.0%.
20
+
21
+ ---
22
+
23
+ ## What Worked Well
24
+
25
+ - **Parallel wave was clean.** 3 independent fixes in 3 different files — no conflicts, all completed without intervention.
26
+ - **B016 agent caught integration test debt.** sync_from_ssd_spec had 4 integration path assertions using the old `60-69` format. Agent found and fixed all of them without being told. A lesser agent would have only updated the unit tests and left the integration tests broken.
27
+ - **B021 agent discovered accurate default.** `options.format` defaults to `'tree,content'` (not `'content'` as AGENTS.md said). Corrected understanding.
28
+ - **$CHILD_STATUS vs $?.** Rubocop flags `$?` — must use `$CHILD_STATUS`. Captured in AGENTS.md learnings during campaign.
29
+ - **s3_scanner.rb surprise.** Brief only mentioned 2 files for B017, but grep found a third (s3_scanner.rb with inline ssl_verify_peer, no env guard). Agent fixed it correctly.
30
+
31
+ ---
32
+
33
+ ## What Didn't Work
34
+
35
+ **Critical: B017 SSL fix has no regression test (Grade C+ from test audit).**
36
+ The most important security fix in the campaign — removing unconditional `ssl_verify_peer: false` — is unprotected. `configure_ssl_options` is not tested in isolation. If someone accidentally adds `ssl_verify_peer: false` unconditionally back, all tests would still pass. This is the #1 priority for the next campaign.
37
+
38
+ **B016 determine_range has edge case gaps.**
39
+ Tests cover b40, b65, b99, boy-baker. Missing: b00 (boundary), b9 (single digit), a40 (non-b letter prefix). The regex `/^([a-z])(\d+)/` handles all of these correctly, but if the regex ever changes, these gaps won't catch it.
40
+
41
+ **cli_spec no-args test is shallow (Grade D+).**
42
+ Verifies the message is printed and exit is 0. Does not verify that file collection actually stops — if the guard is removed and replaced with something that prints the message but continues, the spec would still pass.
43
+
44
+ **Stale comment in sync_from_ssd.rb.**
45
+ Line 173 still says `b65 → 60-69 range` (old format). Code is correct; comment is wrong. 1-line fix.
46
+
47
+ ---
48
+
49
+ ## Key Learnings — Application
50
+
51
+ - **`options.format` defaults to `'tree,content'`** — not `'content'`. Any guard checking `format.nil?` is dead. Updated AGENTS.md.
52
+ - **`$CHILD_STATUS` not `$?`** — Rubocop Special/GlobalVars cop flags `$?`. Use `$CHILD_STATUS` (English module, auto-available in RSpec). Updated AGENTS.md.
53
+ - **`exit` with no code exits 0** in Ruby — specs asserting exit status for "no-args" path should expect 0.
54
+ - **Grep the full codebase before writing the brief** — B017 brief named 2 files; actual codebase had 3. Always grep for the pattern before writing work unit scope.
55
+ - **Integration path assertions in specs** — when changing a path-construction algorithm, search specs for the old path strings, not just the method name. Agent found 4 integration assertions that grep on method name alone would miss.
56
+
57
+ ---
58
+
59
+ ## Key Learnings — Ralph Loop
60
+
61
+ - **Parallel waves are fast when fixes are independent.** All 3 agents ran simultaneously, completed in one wave, zero coordination needed. Right call.
62
+ - **Quality audit surfaced a critical gap the code audit didn't.** Code looks correct (A grade). But test audit showed the SSL fix has no regression protection — an entirely separate risk dimension.
63
+ - **Brief scope can undercount files.** Next time, grep before writing the brief, not just inspect known files.
64
+
65
+ ---
66
+
67
+ ## New Backlog Items from Quality Audit
68
+
69
+ - **B024** — Tests: add `configure_ssl_options` unit tests to s3_operations_spec and share_operations_spec — verify empty hash on default path, ssl_verify_peer: false on ENV override path | Priority: **high** (protects B017 fix)
70
+ - **B025** — Fix: stale comment in sync_from_ssd.rb line 173 (says 60-69, should say b50-b99) | Priority: **low**
71
+ - **B026** — Tests: add determine_range edge cases (b00, b9, a40) to sync_from_ssd_spec and manifest_generator_spec | Priority: **medium**
72
+ - **B027** — Tests: strengthen gpt_context no-args spec to verify file collection actually stops (not just message printed) | Priority: **medium**
73
+
74
+ ---
75
+
76
+ ## Suggestions for Next Campaign
77
+
78
+ **Recommended next campaign: `test-coverage-gaps`**
79
+
80
+ Priority order:
81
+ 1. **B024** — configure_ssl_options unit tests (high — protects the security fix)
82
+ 2. **B022** — expand cli_spec with functional tests (-i, -e, -f, -o flags, exit codes)
83
+ 3. **B026** — determine_range edge cases
84
+ 4. **B027** — gpt_context no-args guard behavioral test
85
+ 5. **B018** — Jump Commands layer specs (Remove/Add/Update)
86
+ 6. **B025** — stale comment fix (bundle with B026, same file)
87
+ 7. **B023** — file_collector_spec: JSON, aider, error paths
88
+
89
+ These are all test-only changes (except B025 which is a 1-line comment fix) — agents can run in parallel safely.
90
+
91
+ **AGENTS.md updates for next campaign:**
92
+ - Add: "configure_ssl_options test pattern: use ClimateControl gem or stub ENV to test conditional SSL logic"
93
+ - Add: "determine_range edge cases: b00, single-digit b9, non-b letter a40 — always test boundaries"
94
+ - Add: "gpt_context no-args test: verify file collection does NOT proceed, not just message output"
@@ -1,39 +1,42 @@
1
1
  # Next Round Brief
2
2
 
3
3
  **Created:** 2026-03-19
4
- **Updated:** 2026-03-19 (after fr2-gpt-context-help assessment)
4
+ **Updated:** 2026-03-19 (after bugfix-and-security assessment)
5
5
 
6
6
  ---
7
7
 
8
- ## Recommended Next Campaign: bugfix-and-security
8
+ ## Recommended Next Campaign: test-coverage-gaps
9
9
 
10
10
  ### Goal
11
11
 
12
- Fix two BLOCKER-level bugs (B016, B017) and one dead-code guard (B021) before building any new S3 or archive features.
12
+ Protect the B017 SSL security fix with a regression test, expand functional test coverage across gpt_context CLI and DAM range logic, and add the missing Jump Commands layer specs.
13
13
 
14
14
  ### Background
15
15
 
16
- Quality audit after fr2-gpt-context-help surfaced these as blockers:
16
+ Quality audit after bugfix-and-security found:
17
17
 
18
- 1. **B017** — `ssl_verify_peer: false` hardcoded unconditionally in `S3Operations` and `ShareOperations`. Removes MITM protection on all S3 operations including credential transmission. Must fix before any S3 feature work.
19
- 2. **B016** — `ManifestGenerator.determine_range` returns `"b50-b99"` format; `SyncFromSsd.determine_range` returns `"60-69"` format. Incompatible SSD path construction means projects can be silently missed during archive/restore. Must fix before any archive feature work.
20
- 3. **B021** — `bin/gpt_context.rb` line 115 guard checks `options.format.nil?` as third AND condition. `format` defaults to `'content'` in Options — never nil. Dead condition; guard can only fire on include/exclude emptiness. 5-minute fix.
18
+ 1. **B024** — `configure_ssl_options` has zero unit tests. The B017 SSL fix (removing unconditional `ssl_verify_peer: false`) has no regression protection. If reverted, all tests still pass. Must fix.
19
+ 2. **B022** — `cli_spec.rb` only tests `--help`, `--version`, no-args. No functional tests for `-i`, `-e`, `-f`, `-o`. Core behaviour untested at CLI level.
20
+ 3. **B026** — `determine_range` tests narrow (b40, b65, b99 only). Missing: b00, b9, a40. Both sync_from_ssd_spec and manifest_generator_spec need these.
21
+ 4. **B027** — gpt_context no-args spec only checks output string. Does not verify file collection stops.
22
+ 5. **B018** — Jump Commands (Remove/Add/Update) — zero dedicated specs.
23
+ 6. **B025** — Stale comment sync_from_ssd.rb line 173 (says 60-69, should say b50-b99).
21
24
 
22
- ### Suggested Work Units
25
+ ### Suggested Work Units (parallel — all test-only except B025)
23
26
 
24
- 1. **Fix B017** — Remove `ssl_verify_peer: false` from `S3Operations` and `ShareOperations`. No env flag needed AWS SDK handles SSL correctly by default.
25
- 2. **Fix B016** — Align range string format between `ManifestGenerator` and `SyncFromSsd`. Read actual SSD folder structure on disk first to determine which format matches reality; update the other to match.
26
- 3. **Fix B021** — Remove `&& options.format.nil?` from guard at `bin/gpt_context.rb:115`. Update or add spec to verify no-args behavior.
27
-
28
- ### Optional (bundle if small)
29
-
30
- - **B018** — Jump Commands layer specs (Remove/Add/Update) — no code changes, just test coverage
31
- - **B022** — Expand cli_spec.rb with functional tests for -i, -e, -f, -o flags
27
+ 1. **fix-b024-ssl-tests** — Add `configure_ssl_options` unit tests to s3_operations_spec and share_operations_spec. Verify empty hash on default path; `{ssl_verify_peer: false}` when ENV override set. Stub ENV directly (`allow(ENV).to receive(:[]).with('AWS_SDK_RUBY_SKIP_SSL_VERIFICATION').and_return('true')`).
28
+ 2. **fix-b022-cli-tests** — Add functional subprocess tests to cli_spec.rb for -i, -e, -f, -o flags. Write to Tempfile, verify content. Use `Dir.mktmpdir` and clean up after.
29
+ 3. **fix-b026-b025-range-tests** — Add edge cases (b00, b9, a40) to sync_from_ssd_spec and manifest_generator_spec. Fix stale comment sync_from_ssd.rb line 173 while in the file.
30
+ 4. **fix-b027-noargs-test** — Strengthen no-args spec: `expect(Appydave::Tools::GptContext::FileCollector).not_to receive(:new)` when no patterns given.
31
+ 5. **fix-b018-jump-specs** Add spec files for Jump Commands::Remove, Commands::Add, Commands::Update. Read existing Jump CLI spec first for setup pattern. Use JumpTestLocations + `with jump filesystem` context.
32
32
 
33
33
  ### Mode Recommendation
34
34
 
35
- **Extend** — stack, patterns, and quality gates known. Inherit AGENTS.md.
35
+ **Extend** — same stack, same patterns, test-only work. Inherit AGENTS.md.
36
36
 
37
- ### Pre-Campaign Blockers: None
37
+ ### Pre-Campaign Notes
38
38
 
39
- All three fixes are standalone. B016 requires reading SSD disk structure before writing code (per AGENTS.md: read actual files before designing data shapes).
39
+ - Check if `climate_control` gem is in Gemfile before using ClimateControl use direct ENV stubbing if not available
40
+ - For B022 functional tests: subprocess writes to file, assert content includes `# file:` headers
41
+ - For B027: stub at the class level, not instance — `expect(described_class).not_to receive(:new)`
42
+ - For B018: read `spec/appydave/tools/jump/` existing specs before writing new command specs
@@ -0,0 +1,317 @@
1
+ # AGENTS.md — test-coverage-gaps
2
+
3
+ > Inherited from bugfix-and-security AGENTS.md. Self-contained.
4
+ > Last updated: 2026-03-19
5
+
6
+ ---
7
+
8
+ ## Project Overview
9
+
10
+ **What:** Ruby gem providing CLI productivity tools for AppyDave's YouTube content creation workflow.
11
+ **Stack:** Ruby 3.4.2, Bundler 2.6.2, RSpec, RuboCop, semantic-release CI/CD.
12
+ **This campaign:** Test-only gap closure. No lib/ production code changes except 1-line comment fix (B025).
13
+ **Commits:** Always use `kfix` — never `git commit`.
14
+
15
+ ---
16
+
17
+ ## Build & Run Commands
18
+
19
+ ```bash
20
+ eval "$(rbenv init -)"
21
+
22
+ RUBYOPT="-W0" bundle exec rspec # All tests
23
+ bundle exec rspec spec/appydave/tools/dam/s3_operations_spec.rb
24
+ bundle exec rspec spec/appydave/tools/dam/share_operations_spec.rb
25
+ bundle exec rspec spec/appydave/tools/dam/sync_from_ssd_spec.rb
26
+ bundle exec rspec spec/appydave/tools/dam/manifest_generator_spec.rb
27
+ bundle exec rspec spec/appydave/tools/gpt_context/cli_spec.rb
28
+ bundle exec rspec spec/appydave/tools/jump/ # All jump specs
29
+ bundle exec rubocop --format clang
30
+ ```
31
+
32
+ **Baseline:** 759 examples, 0 failures, 85.0% line coverage
33
+
34
+ ---
35
+
36
+ ## Directory Structure
37
+
38
+ ```
39
+ lib/appydave/tools/dam/
40
+ s3_operations.rb configure_ssl_options method (~line 102) — READ ONLY
41
+ share_operations.rb configure_ssl_options method (~line 89) — READ ONLY
42
+ sync_from_ssd.rb determine_range (~line 185); stale comment line 173 — FIX COMMENT
43
+ manifest_generator.rb determine_range (~line 332) — READ ONLY
44
+ jump/
45
+ commands/
46
+ remove.rb READ ONLY — write spec for this
47
+ add.rb READ ONLY — write spec for this (may be called create.rb or set.rb)
48
+ update.rb READ ONLY — write spec for this
49
+ spec/appydave/tools/dam/
50
+ s3_operations_spec.rb ADD configure_ssl_options tests
51
+ share_operations_spec.rb ADD configure_ssl_options tests
52
+ sync_from_ssd_spec.rb ADD determine_range edge cases
53
+ manifest_generator_spec.rb ADD determine_range edge cases
54
+ spec/appydave/tools/gpt_context/
55
+ cli_spec.rb ADD functional tests (-i, -e, -f, -o)
56
+ spec/appydave/tools/jump/
57
+ commands/
58
+ remove_spec.rb CREATE THIS
59
+ add_spec.rb CREATE THIS (check actual filename first)
60
+ update_spec.rb CREATE THIS (check actual filename first)
61
+ spec/support/
62
+ jump_test_helpers.rb Reference for shared context
63
+ jump_test_locations.rb Reference for test fixture data
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Work Unit Details
69
+
70
+ ### fix-b024-ssl-tests
71
+
72
+ **Goal:** Protect the B017 security fix. `configure_ssl_options` must have unit tests verifying:
73
+ 1. Default path returns `{}` (no ssl_verify_peer key at all)
74
+ 2. ENV override path returns `{ ssl_verify_peer: false }`
75
+
76
+ **Check Gemfile first** — if `climate_control` is present, use it. Otherwise, stub ENV directly:
77
+
78
+ ```ruby
79
+ # Direct ENV stub (works without climate_control)
80
+ describe '#configure_ssl_options' do
81
+ subject(:ssl_options) { s3_ops.send(:configure_ssl_options) }
82
+
83
+ context 'when AWS_SDK_RUBY_SKIP_SSL_VERIFICATION is not set' do
84
+ before { allow(ENV).to receive(:[]).and_call_original }
85
+ before { allow(ENV).to receive(:[]).with('AWS_SDK_RUBY_SKIP_SSL_VERIFICATION').and_return(nil) }
86
+
87
+ it 'returns empty hash (SSL verification enabled by default)' do
88
+ expect(ssl_options).to eq({})
89
+ end
90
+
91
+ it 'does not include ssl_verify_peer key' do
92
+ expect(ssl_options).not_to have_key(:ssl_verify_peer)
93
+ end
94
+ end
95
+
96
+ context 'when AWS_SDK_RUBY_SKIP_SSL_VERIFICATION is "true"' do
97
+ before { allow(ENV).to receive(:[]).and_call_original }
98
+ before { allow(ENV).to receive(:[]).with('AWS_SDK_RUBY_SKIP_SSL_VERIFICATION').and_return('true') }
99
+
100
+ it 'returns ssl_verify_peer: false' do
101
+ expect(ssl_options).to eq({ ssl_verify_peer: false })
102
+ end
103
+ end
104
+ end
105
+ ```
106
+
107
+ Read the existing spec to find how `s3_ops` subject is set up. Add these examples within the existing describe block structure. Same pattern for `share_operations_spec.rb`.
108
+
109
+ **Commit:** `kfix "add configure_ssl_options unit tests to protect B017 security fix"`
110
+
111
+ ---
112
+
113
+ ### fix-b022-cli-tests
114
+
115
+ **Goal:** Functional subprocess tests for gpt_context CLI. Test that the actual flags work end-to-end.
116
+
117
+ **Pattern — write to Tempfile, verify content:**
118
+
119
+ ```ruby
120
+ describe '-i include pattern' do
121
+ it 'collects files matching the include pattern' do
122
+ Dir.mktmpdir do |tmpdir|
123
+ # Create a test file
124
+ File.write(File.join(tmpdir, 'test.rb'), '# test content')
125
+ outfile = File.join(tmpdir, 'output.txt')
126
+
127
+ `ruby #{script} -i '*.rb' -b #{tmpdir} -o #{outfile} 2>&1`
128
+
129
+ expect(File.read(outfile)).to include('# file: test.rb')
130
+ end
131
+ end
132
+ end
133
+
134
+ describe '-e exclude pattern' do
135
+ it 'excludes files matching the exclude pattern' do
136
+ Dir.mktmpdir do |tmpdir|
137
+ File.write(File.join(tmpdir, 'keep.rb'), '# keep')
138
+ File.write(File.join(tmpdir, 'exclude.rb'), '# exclude')
139
+ outfile = File.join(tmpdir, 'output.txt')
140
+
141
+ `ruby #{script} -i '*.rb' -e 'exclude.rb' -b #{tmpdir} -o #{outfile} 2>&1`
142
+
143
+ content = File.read(outfile)
144
+ expect(content).to include('# file: keep.rb')
145
+ expect(content).not_to include('# file: exclude.rb')
146
+ end
147
+ end
148
+ end
149
+
150
+ describe '-f format' do
151
+ it 'outputs tree format when -f tree specified' do
152
+ Dir.mktmpdir do |tmpdir|
153
+ File.write(File.join(tmpdir, 'test.rb'), '# test')
154
+ outfile = File.join(tmpdir, 'output.txt')
155
+
156
+ `ruby #{script} -i '*.rb' -f tree -b #{tmpdir} -o #{outfile} 2>&1`
157
+
158
+ expect(File.read(outfile)).to include('test.rb')
159
+ end
160
+ end
161
+ end
162
+ ```
163
+
164
+ Note: `-b` sets the base directory, `-o` writes to file. Read the existing cli_spec.rb first for the `script` let binding.
165
+
166
+ **Commit:** `kfix "add functional CLI tests for -i -e -f -o flags to cli_spec"`
167
+
168
+ ---
169
+
170
+ ### fix-b026-b025-range-tests
171
+
172
+ **Goal:** Add edge case tests for `determine_range` + fix 1-line stale comment.
173
+
174
+ **In `sync_from_ssd_spec.rb`** — add to the existing `describe '#determine_range'` block:
175
+ ```ruby
176
+ it 'determines range for boundary b00' do
177
+ range = sync_from_ssd.send(:determine_range, 'b00-first-project')
178
+ expect(range).to eq('b00-b49')
179
+ end
180
+
181
+ it 'determines range for single-digit b9' do
182
+ range = sync_from_ssd.send(:determine_range, 'b9-project')
183
+ expect(range).to eq('b00-b49')
184
+ end
185
+
186
+ it 'determines range for non-b letter prefix a40' do
187
+ range = sync_from_ssd.send(:determine_range, 'a40-test-project')
188
+ expect(range).to eq('a00-a49')
189
+ end
190
+ ```
191
+
192
+ **In `manifest_generator_spec.rb`** — add same 3 examples to the `describe '#determine_range'` block.
193
+
194
+ **In `sync_from_ssd.rb` line 173** — update comment:
195
+ ```ruby
196
+ # Determine local destination path (archived structure)
197
+ # Extract range from project ID (e.g., b65 → b50-b99 range)
198
+ ```
199
+ (Was: `b65 → 60-69 range`)
200
+
201
+ **Commit:** `kfix "add determine_range edge cases and fix stale comment"`
202
+
203
+ ---
204
+
205
+ ### fix-b027-noargs-test
206
+
207
+ **Goal:** Strengthen the no-args gpt_context spec to verify file collection stops — not just message output.
208
+
209
+ The subprocess approach can't easily stub FileCollector. Use a stronger output assertion instead:
210
+
211
+ ```ruby
212
+ describe 'no arguments' do
213
+ it 'prints an error message when no patterns provided' do
214
+ output = `ruby #{script} 2>&1`
215
+ expect(output).to include('No options provided')
216
+ expect($CHILD_STATUS.exitstatus).to eq(0)
217
+ end
218
+
219
+ it 'does not produce file content output when no patterns provided' do
220
+ output = `ruby #{script} 2>&1`
221
+ expect(output).not_to include('# file:')
222
+ expect(output).not_to include('clipboard')
223
+ end
224
+ end
225
+ ```
226
+
227
+ The second test verifies file collection output markers are absent — catches regressions where the guard is removed but the script continues to run.
228
+
229
+ Read existing cli_spec.rb first — update the existing no-args describe block rather than adding a duplicate.
230
+
231
+ **Commit:** `kfix "strengthen gpt_context no-args spec to verify collection does not proceed"`
232
+
233
+ ---
234
+
235
+ ### fix-b018-jump-specs
236
+
237
+ **Goal:** Add dedicated unit specs for Jump Commands::Remove, Commands::Add (or Create), Commands::Update.
238
+
239
+ **Step 1:** Read the source files first:
240
+ ```
241
+ lib/appydave/tools/jump/commands/
242
+ ```
243
+ List what files exist — the command names may differ from Remove/Add/Update.
244
+
245
+ **Step 2:** Read an existing jump spec (e.g., `spec/appydave/tools/jump/`) for setup patterns.
246
+
247
+ **Step 3:** For each command, create a spec file covering:
248
+ - Happy path: command executes with valid key
249
+ - `--force` guard: command without --force prompts/refuses where applicable
250
+ - Not-found path: key does not exist — shows suggestion or error
251
+ - Error codes / output messages
252
+
253
+ **Pattern (based on jump_test_helpers.rb):**
254
+ ```ruby
255
+ # frozen_string_literal: true
256
+
257
+ RSpec.describe Appydave::Tools::Jump::Commands::Remove do
258
+ include_context 'with jump filesystem'
259
+
260
+ describe '#run' do
261
+ context 'when location exists' do
262
+ before { setup_jump_config([JumpTestLocations.ad_tools]) }
263
+
264
+ it 'removes the location with --force' do
265
+ # ...
266
+ end
267
+
268
+ it 'refuses to remove without --force' do
269
+ # ...
270
+ end
271
+ end
272
+
273
+ context 'when location does not exist' do
274
+ it 'shows not-found error' do
275
+ # ...
276
+ end
277
+ end
278
+ end
279
+ end
280
+ ```
281
+
282
+ **Commit:** `kfix "add dedicated specs for Jump Commands Remove Add Update"`
283
+
284
+ ---
285
+
286
+ ## Success Criteria
287
+
288
+ - [ ] `RUBYOPT="-W0" bundle exec rspec` — 759+ examples, 0 failures
289
+ - [ ] `bundle exec rubocop --format clang` — 0 offenses
290
+ - [ ] Line coverage stays ≥ 85.0%
291
+ - [ ] `configure_ssl_options` default path verified to NOT include ssl_verify_peer
292
+ - [ ] All new spec files start with `# frozen_string_literal: true`
293
+ - [ ] No `require 'spec_helper'` in new spec files (auto-required)
294
+
295
+ ---
296
+
297
+ ## Anti-Patterns to Avoid
298
+
299
+ - ❌ Do NOT use `$?` in specs — use `$CHILD_STATUS` (rubocop)
300
+ - ❌ Do NOT use `options.format.nil?` — format defaults to 'tree,content', never nil
301
+ - ❌ Do NOT mock internal DAM classes — use shared filesystem context
302
+ - ❌ Do NOT require spec_helper explicitly
303
+ - ❌ Do NOT modify production lib/ code (except 1-line comment fix in sync_from_ssd.rb)
304
+ - ❌ Do NOT use `puts` in lib/ — use `warn` for warnings
305
+
306
+ ---
307
+
308
+ ## Learnings (inherited)
309
+
310
+ - **`$CHILD_STATUS` not `$?`** — rubocop Special/GlobalVars cop
311
+ - **`exit` with no code exits 0** — specs asserting no-args exit should expect 0
312
+ - **`options.format` defaults to `'tree,content'`** — never nil
313
+ - **Grep full codebase before writing scope** — actual files may differ from brief
314
+ - **Integration path assertions** — when changing path algorithms, search specs for old path strings
315
+ - **BrandResolver is critical path** — all dam commands flow through it
316
+ - **`Regexp.last_match` reset by `.sub()`** — capture groups before string transformation
317
+ - **Dependency injection for path validators** — required for CI compatibility in Jump tests
@@ -0,0 +1,29 @@
1
+ # IMPLEMENTATION_PLAN.md — test-coverage-gaps
2
+
3
+ **Goal**: Close critical test gaps: protect B017 SSL fix, expand gpt_context CLI coverage, range edge cases, Jump Commands specs
4
+ **Started**: 2026-03-19
5
+ **Target**: All gaps addressed; 759+ examples passing; rubocop clean; no regressions
6
+
7
+ ## Summary
8
+ - Total: 5 | Complete: 0 | In Progress: 5 | Pending: 0 | Failed: 0
9
+
10
+ ## Pending
11
+
12
+ ## In Progress
13
+ - [~] fix-b024-ssl-tests — Add configure_ssl_options unit tests to s3_operations_spec + share_operations_spec
14
+ - [~] fix-b022-cli-tests — Add functional subprocess tests to gpt_context cli_spec.rb (-i, -e, -f, -o)
15
+ - [~] fix-b018-jump-specs — Add specs for Jump Commands::Remove, Add, Update
16
+
17
+ ## Complete
18
+ - [x] fix-b027-noargs-test — Added second no-args example: verifies output does NOT include '# file:' or 'clipboard'. 766 examples, 0 failures. Note: B024 agent had RSpec/ScatteredSetup rubocop issue (multiple before hooks) — fixed in subsequent commit.
19
+ - [x] fix-b026-b025-range-tests — Edge cases (b00, b9, a40) added to sync_from_ssd_spec + manifest_generator_spec. Stale comment fixed in sync_from_ssd.rb:173. ⚠️ CI ISSUE: cli_spec.rb:39 failing — 'not_to include clipboard' assertion is fragile (no-args output may mention clipboard on some platforms). B022 agent touching cli_spec.rb may resolve this.
20
+
21
+ ## Failed / Needs Retry
22
+
23
+ ## Notes & Decisions
24
+ - All 5 work units are independent — parallel wave
25
+ - Test-only campaign except B025 (1-line comment fix in sync_from_ssd.rb)
26
+ - ENV stubbing: use allow(ENV).to receive(:[]) — check Gemfile for climate_control first
27
+ - B022 functional tests: write to Tempfile, verify # file: headers in output
28
+ - B027: stub GptContext::FileCollector at class level before subprocess call won't work — use integration assertion instead (verify output does NOT contain file collection output)
29
+ - B018: read existing jump CLI spec before writing command-layer specs
@@ -170,7 +170,7 @@ module Appydave
170
170
  return { skipped: 1, files: 0, bytes: 0, reason: 'Flat folder exists (stale manifest?)' } if Dir.exist?(flat_path)
171
171
 
172
172
  # Determine local destination path (archived structure)
173
- # Extract range from project ID (e.g., b65 → 60-69 range)
173
+ # Extract range from project ID (e.g., b65 → b50-b99 range)
174
174
  range = determine_range(project_id)
175
175
  local_dir = File.join(brand_path, 'archived', range, project_id)
176
176
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Appydave
4
4
  module Tools
5
- VERSION = '0.76.1'
5
+ VERSION = '0.76.2'
6
6
  end
7
7
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.76.1",
3
+ "version": "0.76.2",
4
4
  "description": "AppyDave YouTube Automation Tools",
5
5
  "scripts": {
6
6
  "release": "semantic-release"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appydave-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.76.1
4
+ version: 0.76.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
@@ -299,10 +299,13 @@ files:
299
299
  - docs/planning/BACKLOG.md
300
300
  - docs/planning/bugfix-and-security/AGENTS.md
301
301
  - docs/planning/bugfix-and-security/IMPLEMENTATION_PLAN.md
302
+ - docs/planning/bugfix-and-security/assessment.md
302
303
  - docs/planning/fr2-gpt-context-help/AGENTS.md
303
304
  - docs/planning/fr2-gpt-context-help/IMPLEMENTATION_PLAN.md
304
305
  - docs/planning/fr2-gpt-context-help/assessment.md
305
306
  - docs/planning/next-round-brief.md
307
+ - docs/planning/test-coverage-gaps/AGENTS.md
308
+ - docs/planning/test-coverage-gaps/IMPLEMENTATION_PLAN.md
306
309
  - docs/specs/fr-002-gpt-context-help-system.md
307
310
  - docs/specs/fr-003-jump-location-tool.md
308
311
  - docs/specs/zsh-history-tool.md