appydave-tools 0.76.0 → 0.76.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/bin/gpt_context.rb +1 -1
- data/docs/planning/BACKLOG.md +6 -3
- data/docs/planning/bugfix-and-security/AGENTS.md +324 -0
- data/docs/planning/bugfix-and-security/IMPLEMENTATION_PLAN.md +26 -0
- data/docs/planning/fr2-gpt-context-help/IMPLEMENTATION_PLAN.md +2 -2
- data/docs/planning/fr2-gpt-context-help/assessment.md +70 -0
- data/docs/planning/next-round-brief.md +18 -34
- data/lib/appydave/tools/dam/s3_operations.rb +2 -10
- data/lib/appydave/tools/dam/s3_scanner.rb +1 -2
- data/lib/appydave/tools/dam/share_operations.rb +2 -10
- data/lib/appydave/tools/dam/sync_from_ssd.rb +9 -6
- 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: 2700178e0f8e7fa1ddbd046cb78af4a0a340f2e8770637a2f3b30229e9f76179
|
|
4
|
+
data.tar.gz: c5c3f8094e988cc77849f27d1126c3839825d231c06b8bb63d3410cfdfe72179
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e11cda4ffd9a0a555c15ae613e94b31aa7f508ba473ccc89d31a48d399f9b603204faa4018bea222f9640205b5d73a557b992acf3be94c926bdbeea494baedb5
|
|
7
|
+
data.tar.gz: 4af0c479f1aeb82cc32dd06d8d954910fff6e9a4a2f785d2969a284fc9a55874a56ed71e1600be9c26b5ad3792a67be98105a9003b82c8d835eb0bd8a7d323cf
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# [0.76.0](https://github.com/appydave/appydave-tools/compare/v0.75.0...v0.76.0) (2026-03-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* fix pre-existing rubocop offenses in bin/dam and split jump test helpers to avoid OneClassPerFile ([491b980](https://github.com/appydave/appydave-tools/commit/491b980c335b7e3d205a5368cd0a7b96e5b5a82f))
|
|
7
|
+
* remove debug puts and fix unguarded FileUtils.cd in FileCollector; close BUG-1 ([13d5f87](https://github.com/appydave/appydave-tools/commit/13d5f8793d5185cb9795cab86a5270726763c30e))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* add AI-friendly help system to GPT Context ([c0b8843](https://github.com/appydave/appydave-tools/commit/c0b884323654a248d660ea137712e7c0e5fc172c))
|
|
13
|
+
|
|
1
14
|
# [0.75.0](https://github.com/appydave/appydave-tools/compare/v0.74.1...v0.75.0) (2026-02-08)
|
|
2
15
|
|
|
3
16
|
|
data/bin/gpt_context.rb
CHANGED
|
@@ -112,7 +112,7 @@ OptionParser.new do |opts|
|
|
|
112
112
|
end
|
|
113
113
|
end.parse!
|
|
114
114
|
|
|
115
|
-
if options.include_patterns.empty? && options.exclude_patterns.empty?
|
|
115
|
+
if options.include_patterns.empty? && options.exclude_patterns.empty?
|
|
116
116
|
script_name = File.basename($PROGRAM_NAME, File.extname($PROGRAM_NAME))
|
|
117
117
|
|
|
118
118
|
puts 'No options provided to GPT Context. Please specify patterns to include or exclude.'
|
data/docs/planning/BACKLOG.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Project Backlog — AppyDave Tools
|
|
2
2
|
|
|
3
|
-
**Last updated**: 2026-03-19 (
|
|
4
|
-
**Total**:
|
|
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
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -10,11 +10,13 @@
|
|
|
10
10
|
### High Priority
|
|
11
11
|
- [ ] B015 — BUG-2: FileCollector uses FileUtils.cd without ensure (process dir not restored on exception) | Priority: high
|
|
12
12
|
- [ ] B016 — BUG-3: ManifestGenerator + SyncFromSsd produce incompatible SSD range strings (data integrity) | Priority: high
|
|
13
|
-
- [ ] B002 — FR-2: GPT Context AI-friendly help system | Priority: high
|
|
14
13
|
- [x] B006 — BUG-1: Jump CLI get/remove key lookup | Completed: verified fixed 2026-03-19, regression spec added
|
|
15
14
|
- [ ] B017 — Security: ssl_verify_peer disabled unconditionally in S3Operations + ShareOperations | Priority: high
|
|
16
15
|
|
|
17
16
|
### Medium Priority
|
|
17
|
+
- [ ] B021 — Fix: gpt_context no-args guard checks format.nil? which is always false (dead condition) | Priority: medium
|
|
18
|
+
- [ ] B022 — Tests: expand cli_spec.rb with functional tests (-i, -e, -f, -o flags, exit codes) | Priority: medium
|
|
19
|
+
- [ ] B023 — Tests: add file_collector_spec coverage for JSON format, aider format, error paths | Priority: medium
|
|
18
20
|
- [ ] B018 — Tests: add specs for Jump Commands::Remove, Commands::Add, Commands::Update | Priority: medium
|
|
19
21
|
- [ ] B019 — Fix: remove debug puts @working_directory from gpt_context/file_collector.rb | Priority: medium
|
|
20
22
|
- [ ] B001 — FR-1: GPT Context token counting | Priority: medium
|
|
@@ -37,6 +39,7 @@
|
|
|
37
39
|
- [x] B005 — NFR-2: Jump Claude Code Skill | Completed: 2025-12-14
|
|
38
40
|
- [x] B013 — Arch: Extract GitHelper module (90 lines duplication) | Completed: dam-enhancement-sprint (Jan 2025)
|
|
39
41
|
- [x] B014 — Arch: Create BrandResolver to centralize brand transformation | Completed: dam-enhancement-sprint (Jan 2025)
|
|
42
|
+
- [x] B002 — FR-2: GPT Context AI-friendly help system | Completed: fr2-gpt-context-help (2026-03-19)
|
|
40
43
|
|
|
41
44
|
---
|
|
42
45
|
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# AGENTS.md — bugfix-and-security
|
|
2
|
+
|
|
3
|
+
> Inherited from docs/planning/AGENTS.md + fr2-gpt-context-help campaign learnings.
|
|
4
|
+
> Self-contained — you receive only this file + your work unit prompt.
|
|
5
|
+
> Last updated: 2026-03-19
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Project Overview
|
|
10
|
+
|
|
11
|
+
**What:** Ruby gem providing CLI productivity tools for AppyDave's YouTube content creation workflow.
|
|
12
|
+
**Stack:** Ruby 3.4.2, Bundler 2.6.2, RSpec, RuboCop, semantic-release CI/CD.
|
|
13
|
+
**This campaign:** 3 independent bug fixes — security (B017), data integrity (B016), dead code (B021).
|
|
14
|
+
**Commits:** Always use `kfeat`/`kfix` — never `git commit`.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Build & Run Commands
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
eval "$(rbenv init -)"
|
|
22
|
+
|
|
23
|
+
# Run all tests
|
|
24
|
+
RUBYOPT="-W0" bundle exec rspec
|
|
25
|
+
|
|
26
|
+
# Run specific spec files
|
|
27
|
+
bundle exec rspec spec/appydave/tools/dam/s3_operations_spec.rb
|
|
28
|
+
bundle exec rspec spec/appydave/tools/dam/sync_from_ssd_spec.rb
|
|
29
|
+
bundle exec rspec spec/appydave/tools/dam/manifest_generator_spec.rb
|
|
30
|
+
bundle exec rspec spec/appydave/tools/gpt_context/cli_spec.rb
|
|
31
|
+
|
|
32
|
+
# Lint
|
|
33
|
+
bundle exec rubocop --format clang
|
|
34
|
+
|
|
35
|
+
# Commit (never use git commit directly)
|
|
36
|
+
kfix "description of what you fixed"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Baseline (2026-03-19):** 754 examples, 0 failures, 84.92% line coverage
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Directory Structure
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
lib/appydave/tools/dam/
|
|
47
|
+
s3_operations.rb B017 — configure_ssl_options method (~line 102)
|
|
48
|
+
share_operations.rb B017 — configure_ssl_options method (~line 89)
|
|
49
|
+
s3_scanner.rb B017 — inline ssl_verify_peer in Aws::S3::Client.new (~line 111)
|
|
50
|
+
sync_from_ssd.rb B016 — determine_range method (~line 185)
|
|
51
|
+
manifest_generator.rb B016 — determine_range method (~line 332) — canonical format
|
|
52
|
+
spec/appydave/tools/dam/
|
|
53
|
+
s3_operations_spec.rb Existing spec — do not break
|
|
54
|
+
share_operations_spec.rb Existing spec — do not break
|
|
55
|
+
sync_from_ssd_spec.rb B016 — update determine_range examples (~line 277)
|
|
56
|
+
manifest_generator_spec.rb B016 — add determine_range examples (currently none)
|
|
57
|
+
bin/gpt_context.rb B021 — guard at line 115
|
|
58
|
+
spec/appydave/tools/gpt_context/
|
|
59
|
+
cli_spec.rb B021 — add/update no-args spec
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Work Unit Details
|
|
65
|
+
|
|
66
|
+
### fix-b017-ssl
|
|
67
|
+
|
|
68
|
+
**Problem:** `ssl_verify_peer: false` is set unconditionally in 3 files, disabling MITM protection on all S3 operations including AWS credential transmission. The comment "safe for AWS S3" is incorrect — HTTPS encryption alone does not protect against a MITM attack without peer verification.
|
|
69
|
+
|
|
70
|
+
**Files to change:**
|
|
71
|
+
|
|
72
|
+
**1. `lib/appydave/tools/dam/s3_operations.rb` (~line 102):**
|
|
73
|
+
```ruby
|
|
74
|
+
# BEFORE:
|
|
75
|
+
def configure_ssl_options
|
|
76
|
+
if ENV['AWS_SDK_RUBY_SKIP_SSL_VERIFICATION'] == 'true'
|
|
77
|
+
puts '⚠️ WARNING: SSL verification is disabled (development mode)'
|
|
78
|
+
return { ssl_verify_peer: false }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Disable SSL peer verification to work around OpenSSL 3.4.x CRL checking issues
|
|
82
|
+
# This is safe for AWS S3 connections as we're still using HTTPS (encrypted connection)
|
|
83
|
+
{
|
|
84
|
+
ssl_verify_peer: false
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# AFTER:
|
|
89
|
+
def configure_ssl_options
|
|
90
|
+
return { ssl_verify_peer: false } if ENV['AWS_SDK_RUBY_SKIP_SSL_VERIFICATION'] == 'true'
|
|
91
|
+
|
|
92
|
+
{}
|
|
93
|
+
end
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**2. `lib/appydave/tools/dam/share_operations.rb` (~line 89):**
|
|
97
|
+
Same pattern as s3_operations.rb — same fix.
|
|
98
|
+
|
|
99
|
+
**3. `lib/appydave/tools/dam/s3_scanner.rb` (~line 111):**
|
|
100
|
+
```ruby
|
|
101
|
+
# BEFORE (inline in Aws::S3::Client.new):
|
|
102
|
+
Aws::S3::Client.new(
|
|
103
|
+
credentials: credentials,
|
|
104
|
+
region: brand_info.aws.region,
|
|
105
|
+
http_wire_trace: false,
|
|
106
|
+
ssl_verify_peer: false
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# AFTER:
|
|
110
|
+
Aws::S3::Client.new(
|
|
111
|
+
credentials: credentials,
|
|
112
|
+
region: brand_info.aws.region,
|
|
113
|
+
http_wire_trace: false
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Commit:** `kfix "remove unconditional ssl_verify_peer: false from S3 clients; keep env override"`
|
|
118
|
+
|
|
119
|
+
**Note on WARNING puts:** The original had `puts '⚠️ WARNING...'` in the env-guard branch. You may keep or remove it — if you keep it, ensure rubocop doesn't flag it (it shouldn't). If RuboCop complains about the `puts`, use `warn` instead.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### fix-b016-range
|
|
124
|
+
|
|
125
|
+
**Problem:** Two methods both named `determine_range` produce incompatible folder path strings:
|
|
126
|
+
- `ManifestGenerator#determine_range('b65')` → `"b50-b99"` (letter + 50-number range)
|
|
127
|
+
- `SyncFromSsd#determine_range('b65')` → `"60-69"` (no letter, 10-number range)
|
|
128
|
+
|
|
129
|
+
Both are used to construct `archived/[range]/[project_id]` paths. A project archived via SyncFromSsd lands in `archived/60-69/b65-project/`. ManifestGenerator then looks for it at `archived/b50-b99/b65-project/` — misses it (though glob fallback saves it in practice).
|
|
130
|
+
|
|
131
|
+
**ManifestGenerator format is canonical** — it handles any letter prefix (a*, b*, c*, ...) and uses 50-number ranges which are less granular and more stable.
|
|
132
|
+
|
|
133
|
+
**Fix: Update `SyncFromSsd#determine_range` to match ManifestGenerator's algorithm:**
|
|
134
|
+
|
|
135
|
+
```ruby
|
|
136
|
+
# lib/appydave/tools/dam/sync_from_ssd.rb
|
|
137
|
+
|
|
138
|
+
# BEFORE (~line 185):
|
|
139
|
+
def determine_range(project_id)
|
|
140
|
+
# FliVideo pattern: b40, b41, ... b99
|
|
141
|
+
if project_id =~ /^b(\d+)/
|
|
142
|
+
tens = (Regexp.last_match(1).to_i / 10) * 10
|
|
143
|
+
"#{tens}-#{tens + 9}"
|
|
144
|
+
else
|
|
145
|
+
'000-099'
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# AFTER (match ManifestGenerator exactly):
|
|
150
|
+
def determine_range(project_id)
|
|
151
|
+
if project_id =~ /^([a-z])(\d+)/
|
|
152
|
+
letter = Regexp.last_match(1)
|
|
153
|
+
number = Regexp.last_match(2).to_i
|
|
154
|
+
range_start = (number / 50) * 50
|
|
155
|
+
range_end = range_start + 49
|
|
156
|
+
format("#{letter}%02d-#{letter}%02d", range_start, range_end)
|
|
157
|
+
else
|
|
158
|
+
'000-099'
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Update `spec/appydave/tools/dam/sync_from_ssd_spec.rb` — the existing determine_range examples (~line 277) must be updated to the new format:**
|
|
164
|
+
|
|
165
|
+
```ruby
|
|
166
|
+
describe '#determine_range' do
|
|
167
|
+
it 'determines range for FliVideo pattern b40' do
|
|
168
|
+
range = sync_from_ssd.send(:determine_range, 'b40-test-project')
|
|
169
|
+
expect(range).to eq('b00-b49')
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it 'determines range for FliVideo pattern b65' do
|
|
173
|
+
range = sync_from_ssd.send(:determine_range, 'b65-guy-monroe')
|
|
174
|
+
expect(range).to eq('b50-b99')
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it 'determines range for FliVideo pattern b99' do
|
|
178
|
+
range = sync_from_ssd.send(:determine_range, 'b99-final-project')
|
|
179
|
+
expect(range).to eq('b50-b99')
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it 'returns default range for non-FliVideo pattern' do
|
|
183
|
+
range = sync_from_ssd.send(:determine_range, 'boy-baker')
|
|
184
|
+
expect(range).to eq('000-099')
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Add to `spec/appydave/tools/dam/manifest_generator_spec.rb` — currently zero specs for determine_range:**
|
|
190
|
+
|
|
191
|
+
Look at the existing manifest_generator_spec.rb for the describe block structure and shared context, then add:
|
|
192
|
+
```ruby
|
|
193
|
+
describe '#determine_range' do
|
|
194
|
+
it 'determines range for b40' do
|
|
195
|
+
range = manifest_generator.send(:determine_range, 'b40-test-project')
|
|
196
|
+
expect(range).to eq('b00-b49')
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it 'determines range for b65' do
|
|
200
|
+
range = manifest_generator.send(:determine_range, 'b65-guy-monroe')
|
|
201
|
+
expect(range).to eq('b50-b99')
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it 'determines range for b99' do
|
|
205
|
+
range = manifest_generator.send(:determine_range, 'b99-final-project')
|
|
206
|
+
expect(range).to eq('b50-b99')
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it 'returns default range for non-FliVideo pattern' do
|
|
210
|
+
range = manifest_generator.send(:determine_range, 'boy-baker')
|
|
211
|
+
expect(range).to eq('000-099')
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Read `manifest_generator_spec.rb` first to understand how the `manifest_generator` subject is set up before adding these examples.
|
|
217
|
+
|
|
218
|
+
**Commit:** `kfix "align SyncFromSsd#determine_range with ManifestGenerator format; add specs"`
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### fix-b021-guard
|
|
223
|
+
|
|
224
|
+
**Problem:** `bin/gpt_context.rb` line 115:
|
|
225
|
+
```ruby
|
|
226
|
+
if options.include_patterns.empty? && options.exclude_patterns.empty? && options.format.nil?
|
|
227
|
+
```
|
|
228
|
+
`options.format` defaults to `'content'` in the Options class — it is never nil. The third AND condition is always false, making the whole guard dead when only format is set. In practice the guard fires on empty include+exclude (which is the normal "no args" path), but the dead condition is confusing and could mask future bugs.
|
|
229
|
+
|
|
230
|
+
**Fix:** Remove `&& options.format.nil?` from line 115:
|
|
231
|
+
```ruby
|
|
232
|
+
# BEFORE:
|
|
233
|
+
if options.include_patterns.empty? && options.exclude_patterns.empty? && options.format.nil?
|
|
234
|
+
|
|
235
|
+
# AFTER:
|
|
236
|
+
if options.include_patterns.empty? && options.exclude_patterns.empty?
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Add/update spec in `spec/appydave/tools/gpt_context/cli_spec.rb`:**
|
|
240
|
+
|
|
241
|
+
Add a context for no-args behavior:
|
|
242
|
+
```ruby
|
|
243
|
+
describe 'no arguments' do
|
|
244
|
+
it 'exits with an error message when no patterns provided' do
|
|
245
|
+
output = `ruby #{script} 2>&1`
|
|
246
|
+
expect(output).to include('No options provided')
|
|
247
|
+
expect($?.exitstatus).to_not eq(0)
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Note: The script currently calls `exit` (no code) on this path — check the actual exit status. If it exits 0, adjust the expectation or leave exit code assertion out and just check the message.
|
|
253
|
+
|
|
254
|
+
**Commit:** `kfix "remove dead format.nil? guard in gpt_context no-args check"`
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Success Criteria
|
|
259
|
+
|
|
260
|
+
Every work unit must satisfy ALL before marking `[x]`:
|
|
261
|
+
|
|
262
|
+
- [ ] `RUBYOPT="-W0" bundle exec rspec` — 754+ examples, 0 failures
|
|
263
|
+
- [ ] `bundle exec rubocop --format clang` — 0 offenses
|
|
264
|
+
- [ ] Line coverage stays ≥ 84.92%
|
|
265
|
+
- [ ] All new `.rb` file additions start with `# frozen_string_literal: true`
|
|
266
|
+
- [ ] Commit uses `kfix` (not `git commit`)
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Anti-Patterns to Avoid
|
|
271
|
+
|
|
272
|
+
- ❌ Do NOT remove the `ENV['AWS_SDK_RUBY_SKIP_SSL_VERIFICATION']` dev escape hatch — only remove the unconditional fallback below it
|
|
273
|
+
- ❌ Do NOT mock S3 clients when testing ssl options — check what the existing specs do and follow the pattern
|
|
274
|
+
- ❌ Do NOT change ManifestGenerator#determine_range — it is the canonical implementation, SyncFromSsd is the one to fix
|
|
275
|
+
- ❌ Do NOT use `puts` in lib/ code without checking if it violates rubocop (use `warn` for warnings)
|
|
276
|
+
- ❌ Do NOT inline brand transformations — always use BrandResolver
|
|
277
|
+
- ❌ Do NOT use `require 'spec_helper'` in new spec files — auto-required via .rspec
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Mock Patterns
|
|
282
|
+
|
|
283
|
+
### S3 Tests — Check Existing Specs First
|
|
284
|
+
|
|
285
|
+
Before writing any new S3-related test, read the existing spec file for the class you're touching. The existing patterns use WebMock or stub the S3 client at a higher level. Do NOT add new S3 network stubs — just verify the existing test suite still passes after your change.
|
|
286
|
+
|
|
287
|
+
### DAM Filesystem Tests — Shared Context
|
|
288
|
+
|
|
289
|
+
```ruby
|
|
290
|
+
include_context 'with vat filesystem and brands', brands: %w[appydave]
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Quality Gates
|
|
296
|
+
|
|
297
|
+
- **Tests:** 754+ examples, 0 failures
|
|
298
|
+
- **Lint:** 0 rubocop offenses
|
|
299
|
+
- **Coverage:** ≥ 84.92%
|
|
300
|
+
- **Commit:** `kfix` only
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Learnings (inherited)
|
|
305
|
+
|
|
306
|
+
### From Three-Lens Audit (2026-03-19)
|
|
307
|
+
- `format.nil?` in gpt_context is always false — do not re-introduce
|
|
308
|
+
- `ssl_verify_peer: false` is not safe for AWS — HTTPS alone doesn't prevent MITM without peer verification
|
|
309
|
+
- ManifestGenerator `determine_range` is the canonical format; SyncFromSsd must match it
|
|
310
|
+
|
|
311
|
+
### From fr2-gpt-context-help (2026-03-19)
|
|
312
|
+
- `opts.on_tail` vs `opts.on` matters for option ordering in OptionParser
|
|
313
|
+
- Subprocess specs (`ruby #{script} --flag`) are correct for CLI integration tests
|
|
314
|
+
- Pre-conditions from prior commits — always verify live before planning
|
|
315
|
+
|
|
316
|
+
### From DAM Enhancement Sprint (Jan 2025)
|
|
317
|
+
- BrandResolver is the critical path — all dam commands flow through it
|
|
318
|
+
- `Regexp.last_match` is reset by `.sub()` calls — capture groups BEFORE any string transformation
|
|
319
|
+
- `Config.configure` is memoized — do not add new calls
|
|
320
|
+
- Table format() pattern: always use same format string for headers and data rows
|
|
321
|
+
|
|
322
|
+
### From Jump Location Tool (Dec 2025)
|
|
323
|
+
- Dependency injection for path validators required for CI compatibility
|
|
324
|
+
- Jump Commands layer has zero dedicated specs (B018 — scheduled separately)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# IMPLEMENTATION_PLAN.md — bugfix-and-security
|
|
2
|
+
|
|
3
|
+
**Goal**: Fix 3 blockers: ssl_verify_peer security hole (B017), range string mismatch (B016), dead format guard (B021)
|
|
4
|
+
**Started**: 2026-03-19
|
|
5
|
+
**Target**: All 3 fixes committed; tests pass; rubocop clean; no regressions
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
- Total: 3 | Complete: 0 | In Progress: 3 | Pending: 0 | Failed: 0
|
|
9
|
+
|
|
10
|
+
## Pending
|
|
11
|
+
|
|
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
|
+
|
|
17
|
+
## Complete
|
|
18
|
+
|
|
19
|
+
## Failed / Needs Retry
|
|
20
|
+
|
|
21
|
+
## Notes & Decisions
|
|
22
|
+
- All 3 fixes are independent — run as parallel agents in one wave
|
|
23
|
+
- B017: s3_scanner.rb has ssl_verify_peer inline with NO env guard — remove entirely. s3_operations.rb and share_operations.rb have env guard + unconditional fallback — keep env guard, remove unconditional fallback. Return {} (empty hash) instead.
|
|
24
|
+
- B016: ManifestGenerator format is canonical (letter+50-range, e.g. b50-b99). SyncFromSsd format is wrong (10-range, no letter, e.g. 60-69). Fix SyncFromSsd to match. ManifestGenerator#determine_range has zero specs — add them.
|
|
25
|
+
- B021: options.format defaults to 'content' in Options class — format.nil? is always false. Remove the third AND condition. Update cli_spec or add spec to verify no-args exits with message.
|
|
26
|
+
- Discovered: s3_scanner.rb also affected by B017 (not in original brief)
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
**Target**: `--help` shows structured sections; `--version` works; specs pass; rubocop clean
|
|
6
6
|
|
|
7
7
|
## Summary
|
|
8
|
-
- Total: 1 | Complete:
|
|
8
|
+
- Total: 1 | Complete: 1 | In Progress: 0 | Pending: 0 | Failed: 0
|
|
9
9
|
|
|
10
10
|
## Pending
|
|
11
11
|
|
|
12
12
|
## In Progress
|
|
13
|
-
- [~] fr2-gpt-context-help — Implement AI-friendly help system in bin/gpt_context.rb per docs/specs/fr-002-gpt-context-help-system.md
|
|
14
13
|
|
|
15
14
|
## Complete
|
|
15
|
+
- [x] fr2-gpt-context-help — Implement AI-friendly help system in bin/gpt_context.rb. 754 examples, 0 failures. v0.76.0 published. Also fixed pre-existing rubocop offenses in bin/dam and split jump_test_helpers (JumpTestLocations → own file).
|
|
16
16
|
|
|
17
17
|
## Failed / Needs Retry
|
|
18
18
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Assessment: fr2-gpt-context-help
|
|
2
|
+
|
|
3
|
+
**Campaign**: fr2-gpt-context-help
|
|
4
|
+
**Date**: 2026-03-19 → 2026-03-19
|
|
5
|
+
**Results**: 1 complete, 0 failed
|
|
6
|
+
**Version shipped**: v0.76.0
|
|
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
|
+
| B002 — FR-2 GPT Context help system | ✅ Complete | 754 examples, 0 failures. Also fixed pre-existing rubocop offenses in bin/dam and split JumpTestLocations into own file. |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## What Worked Well
|
|
20
|
+
|
|
21
|
+
- **Single-file scope held.** `bin/gpt_context.rb` only — no lib/ changes. Agent stayed in bounds.
|
|
22
|
+
- **Side-fixes landed cleanly.** Rubocop offenses in bin/dam (select/reject → partition) and JumpTestLocations split were caught and fixed without scope creep.
|
|
23
|
+
- **Test count and coverage improved.** 748 → 754 examples, 84.88% → 84.92% coverage.
|
|
24
|
+
- **Spec approach was correct.** subprocess integration testing (running the actual script) is the right pattern for CLI help/version tests.
|
|
25
|
+
- **Pre-conditions were pre-cleared.** B015 and B019 fixed in prior commit 13d5f87 meant agent could focus on FR-2 immediately.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## What Didn't Work
|
|
30
|
+
|
|
31
|
+
- **cli_spec.rb is too thin (Grade: C from test audit).** 4 tests only verify help text strings are present. No functional tests: `-i`, `-e`, `-f`, `-o` flags completely untested at CLI level. Creates false sense of security.
|
|
32
|
+
- **format.nil? guard is dead code.** `bin/gpt_context.rb` line 115 checks `options.format.nil?` as part of its "no options provided" guard. But `format` defaults to `'content'` in the Options class — it is never nil. The third AND condition is always false, meaning the guard can only trigger if both include_patterns AND exclude_patterns are empty AND format has somehow been set to nil (impossible via normal usage).
|
|
33
|
+
- **file_collector_spec missing formats.** JSON and aider format output paths in FileCollector have zero specs. Error cases also unprotected.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Key Learnings — Application
|
|
38
|
+
|
|
39
|
+
- **OptionParser `opts.on_tail` vs `opts.on` matters for ordering.** `--version` must be `opts.on` (not `on_tail`) to appear before `--help` in output. Anti-pattern documented in AGENTS.md.
|
|
40
|
+
- **format.nil? is a dead guard.** When Options class sets a default for `format`, the nil check in bin/gpt_context.rb line 115 is always false. Any "no args provided" guard must check `include_patterns.empty?` and `exclude_patterns.empty?` only.
|
|
41
|
+
- **Subprocess specs work but need functional assertions.** Using `\`ruby #{script} --flag\`` is correct for CLI integration testing, but tests must verify actual output content and exit codes — not just documentation strings.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Key Learnings — Ralph Loop
|
|
46
|
+
|
|
47
|
+
- **One work unit campaigns are fast.** 1 agent, 1 wave, done. No coordination overhead.
|
|
48
|
+
- **Pre-conditions from prior commits reduce campaign scope.** B015/B019 were in next-round-brief as work units but had already been fixed. Always verify pre-conditions live before writing the plan.
|
|
49
|
+
- **Quality audit caught 3 new backlog items.** B021 (format.nil? dead guard), B022 (cli_spec functional tests), B023 (file_collector JSON/aider/error specs). These were invisible without the audit.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Suggestions for Next Campaign
|
|
54
|
+
|
|
55
|
+
**Recommended next campaign: `bugfix-and-security` — B016, B017, B021**
|
|
56
|
+
|
|
57
|
+
Priority order:
|
|
58
|
+
1. **B017** — ssl_verify_peer: false (security BLOCKER — remove before adding any S3 features)
|
|
59
|
+
2. **B016** — ManifestGenerator vs SyncFromSsd range string mismatch (data integrity BLOCKER)
|
|
60
|
+
3. **B021** — fix format.nil? dead guard in gpt_context (5-minute fix, prevents silent failure)
|
|
61
|
+
|
|
62
|
+
Then schedule soon after:
|
|
63
|
+
- **B022** — expand cli_spec.rb with functional tests (-i, -e, -f, -o, exit codes)
|
|
64
|
+
- **B023** — file_collector_spec: add JSON, aider, error path coverage
|
|
65
|
+
- **B018** — Jump Commands layer specs (Remove/Add/Update)
|
|
66
|
+
|
|
67
|
+
**AGENTS.md updates needed for next campaign:**
|
|
68
|
+
- Add: "format.nil? in gpt_context is always false — do not use as a no-args guard"
|
|
69
|
+
- Add: "S3Operations ssl_verify_peer must be removed — see B017"
|
|
70
|
+
- Add: "ManifestGenerator and SyncFromSsd produce incompatible range strings — see B016 before touching SSD archive paths"
|
|
@@ -1,55 +1,39 @@
|
|
|
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 fr2-gpt-context-help assessment)
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
## Recommended Next Campaign:
|
|
8
|
+
## Recommended Next Campaign: bugfix-and-security
|
|
9
9
|
|
|
10
10
|
### Goal
|
|
11
11
|
|
|
12
|
-
Fix
|
|
12
|
+
Fix two BLOCKER-level bugs (B016, B017) and one dead-code guard (B021) before building any new S3 or archive features.
|
|
13
13
|
|
|
14
14
|
### Background
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Quality audit after fr2-gpt-context-help surfaced these as blockers:
|
|
17
17
|
|
|
18
|
-
1.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Both are ~5 minutes of work. Do them as the first commit of the FR-2 campaign.
|
|
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.
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
### Suggested Work Units
|
|
24
23
|
|
|
25
|
-
|
|
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.
|
|
26
27
|
|
|
27
|
-
###
|
|
28
|
+
### Optional (bundle if small)
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
3. **Implement FR-2** — Read `docs/specs/fr-002-gpt-context-help-system.md`. Option A from the spec (enhanced OptionParser with banner, separators, `--version`) is the correct approach. No changes to lib/ needed — this is a `bin/gpt_context.rb` enhancement.
|
|
32
|
-
4. **Verify BUG-1** — Run `bin/jump.rb get <key>` live. If broken: find actual failure site. If fixed: write regression spec for `Jump::Config#find` round-trip and close.
|
|
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
|
|
33
32
|
|
|
34
|
-
###
|
|
35
|
-
|
|
36
|
-
Neither fix requires architectural changes. FR-2 is contained to `bin/gpt_context.rb`. The Jump verification is read-only unless the bug is confirmed.
|
|
37
|
-
|
|
38
|
-
### What Agents Need to Know
|
|
39
|
-
|
|
40
|
-
- Read `docs/planning/AGENTS.md` — test/lint patterns, commit format, quality gates
|
|
41
|
-
- FR-2 spec: `docs/specs/fr-002-gpt-context-help-system.md`
|
|
42
|
-
- gpt_context source: `lib/appydave/tools/gpt_context/` + `bin/gpt_context.rb`
|
|
43
|
-
- Jump source: `lib/appydave/tools/jump/` (Config, Search, Commands/*)
|
|
44
|
-
- Jump tests: `spec/appydave/tools/jump/` + `spec/support/jump_test_helpers.rb`
|
|
45
|
-
- BUG-1 call chain: `CLI#run_get` → `Search#get` → `Config#find` → `locations.find { |loc| loc.key == key }`
|
|
46
|
-
|
|
47
|
-
### Also Schedule Soon (from audit)
|
|
33
|
+
### Mode Recommendation
|
|
48
34
|
|
|
49
|
-
|
|
50
|
-
- B017 — ssl_verify_peer: false in S3Operations (security — schedule next)
|
|
51
|
-
- B018 — Jump Commands layer specs (no specs for Remove/Add/Update)
|
|
35
|
+
**Extend** — stack, patterns, and quality gates known. Inherit AGENTS.md.
|
|
52
36
|
|
|
53
|
-
###
|
|
37
|
+
### Pre-Campaign Blockers: None
|
|
54
38
|
|
|
55
|
-
|
|
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).
|
|
@@ -100,17 +100,9 @@ module Appydave
|
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
def configure_ssl_options
|
|
103
|
-
|
|
104
|
-
if ENV['AWS_SDK_RUBY_SKIP_SSL_VERIFICATION'] == 'true'
|
|
105
|
-
puts '⚠️ WARNING: SSL verification is disabled (development mode)'
|
|
106
|
-
return { ssl_verify_peer: false }
|
|
107
|
-
end
|
|
103
|
+
return { ssl_verify_peer: false } if ENV['AWS_SDK_RUBY_SKIP_SSL_VERIFICATION'] == 'true'
|
|
108
104
|
|
|
109
|
-
|
|
110
|
-
# This is safe for AWS S3 connections as we're still using HTTPS (encrypted connection)
|
|
111
|
-
{
|
|
112
|
-
ssl_verify_peer: false
|
|
113
|
-
}
|
|
105
|
+
{}
|
|
114
106
|
end
|
|
115
107
|
|
|
116
108
|
public
|
|
@@ -87,17 +87,9 @@ module Appydave
|
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
def configure_ssl_options
|
|
90
|
-
|
|
91
|
-
if ENV['AWS_SDK_RUBY_SKIP_SSL_VERIFICATION'] == 'true'
|
|
92
|
-
puts '⚠️ WARNING: SSL verification is disabled (development mode)'
|
|
93
|
-
return { ssl_verify_peer: false }
|
|
94
|
-
end
|
|
90
|
+
return { ssl_verify_peer: false } if ENV['AWS_SDK_RUBY_SKIP_SSL_VERIFICATION'] == 'true'
|
|
95
91
|
|
|
96
|
-
|
|
97
|
-
# This is safe for AWS S3 connections as we're still using HTTPS (encrypted connection)
|
|
98
|
-
{
|
|
99
|
-
ssl_verify_peer: false
|
|
100
|
-
}
|
|
92
|
+
{}
|
|
101
93
|
end
|
|
102
94
|
|
|
103
95
|
public
|
|
@@ -181,14 +181,17 @@ module Appydave
|
|
|
181
181
|
sync_light_files(ssd_path, local_dir, dry_run: dry_run)
|
|
182
182
|
end
|
|
183
183
|
|
|
184
|
-
# Determine range folder for project (e.g., b65 →
|
|
184
|
+
# Determine range folder for project (e.g., b65 → b50-b99)
|
|
185
185
|
def determine_range(project_id)
|
|
186
|
-
# FliVideo pattern: b40,
|
|
187
|
-
if project_id =~ /^
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
# FliVideo/Modern pattern: b40, a82, etc.
|
|
187
|
+
if project_id =~ /^([a-z])(\d+)/
|
|
188
|
+
letter = Regexp.last_match(1)
|
|
189
|
+
number = Regexp.last_match(2).to_i
|
|
190
|
+
range_start = (number / 50) * 50
|
|
191
|
+
range_end = range_start + 49
|
|
192
|
+
format("#{letter}%02d-#{letter}%02d", range_start, range_end)
|
|
190
193
|
else
|
|
191
|
-
# Legacy pattern or unknown
|
|
194
|
+
# Legacy pattern or unknown
|
|
192
195
|
'000-099'
|
|
193
196
|
end
|
|
194
197
|
end
|
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.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cruwys
|
|
@@ -297,8 +297,11 @@ files:
|
|
|
297
297
|
- docs/guides/tools/youtube-manager.md
|
|
298
298
|
- docs/planning/AGENTS.md
|
|
299
299
|
- docs/planning/BACKLOG.md
|
|
300
|
+
- docs/planning/bugfix-and-security/AGENTS.md
|
|
301
|
+
- docs/planning/bugfix-and-security/IMPLEMENTATION_PLAN.md
|
|
300
302
|
- docs/planning/fr2-gpt-context-help/AGENTS.md
|
|
301
303
|
- docs/planning/fr2-gpt-context-help/IMPLEMENTATION_PLAN.md
|
|
304
|
+
- docs/planning/fr2-gpt-context-help/assessment.md
|
|
302
305
|
- docs/planning/next-round-brief.md
|
|
303
306
|
- docs/specs/fr-002-gpt-context-help-system.md
|
|
304
307
|
- docs/specs/fr-003-jump-location-tool.md
|