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 +4 -4
- data/CHANGELOG.md +8 -0
- data/docs/planning/BACKLOG.md +10 -5
- data/docs/planning/bugfix-and-security/AGENTS.md +5 -0
- data/docs/planning/bugfix-and-security/IMPLEMENTATION_PLAN.md +4 -4
- data/docs/planning/bugfix-and-security/assessment.md +94 -0
- data/docs/planning/next-round-brief.md +22 -19
- data/docs/planning/test-coverage-gaps/AGENTS.md +317 -0
- data/docs/planning/test-coverage-gaps/IMPLEMENTATION_PLAN.md +29 -0
- data/lib/appydave/tools/dam/sync_from_ssd.rb +1 -1
- data/lib/appydave/tools/version.rb +1 -1
- data/package.json +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9e0809dc40e0f4940381134c70a57833d755df47f01f8e327a04b278e4d87c5a
|
|
4
|
+
data.tar.gz: a1aa1d00b87481b371edda22ed5f7f0fa63a895358002cbc330b4d4e8cbf1ae8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
data/docs/planning/BACKLOG.md
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
# Project Backlog — AppyDave Tools
|
|
2
2
|
|
|
3
|
-
**Last updated**: 2026-03-19 (
|
|
4
|
-
**Total**:
|
|
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:
|
|
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
|
|
4
|
+
**Updated:** 2026-03-19 (after bugfix-and-security assessment)
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
## Recommended Next Campaign:
|
|
8
|
+
## Recommended Next Campaign: test-coverage-gaps
|
|
9
9
|
|
|
10
10
|
### Goal
|
|
11
11
|
|
|
12
|
-
|
|
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
|
|
16
|
+
Quality audit after bugfix-and-security found:
|
|
17
17
|
|
|
18
|
-
1. **
|
|
19
|
-
2. **
|
|
20
|
-
3. **
|
|
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. **
|
|
25
|
-
2. **
|
|
26
|
-
3. **
|
|
27
|
-
|
|
28
|
-
|
|
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,
|
|
35
|
+
**Extend** — same stack, same patterns, test-only work. Inherit AGENTS.md.
|
|
36
36
|
|
|
37
|
-
### Pre-Campaign
|
|
37
|
+
### Pre-Campaign Notes
|
|
38
38
|
|
|
39
|
-
|
|
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 →
|
|
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
|
|
data/package.json
CHANGED
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.
|
|
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
|