appydave-tools 0.76.13 → 0.76.14
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 +7 -0
- data/docs/planning/BACKLOG.md +4 -4
- data/docs/planning/batch-a-features/AGENTS.md +408 -0
- data/docs/planning/batch-a-features/IMPLEMENTATION_PLAN.md +37 -0
- data/docs/planning/env-dead-code-cleanup/AGENTS.md +24 -14
- data/docs/planning/env-dead-code-cleanup/IMPLEMENTATION_PLAN.md +3 -3
- data/docs/planning/env-dead-code-cleanup/assessment.md +88 -0
- data/docs/planning/library-boundary-cleanup/AGENTS.md +24 -5
- data/lib/appydave/tools/version.rb +1 -1
- data/package.json +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2c6c57202f05dffc3f46f1d929522ed55200a85d91ac427d831a2c9e77558693
|
|
4
|
+
data.tar.gz: ec9250e733a5ec31bef797f83c24c77f535e3ac9753954cab7f6e45c66bf7fca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 933c28cc9392d407254f320529e3c6166648579794fa1b13fb2fc956bebc4900ccf4048eb97f3230a40ebee2d1ebce45b5588effebb5a05fe3c5e516270655d0
|
|
7
|
+
data.tar.gz: 381302acfc146d12aed9ebb5ee1e9e26de4b0d7c111e2b0c7883e4936bb4b5673e33617ec1c49fc515e89ad2d088acb7a583cc6ed862e946d0265160b917d30a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [0.76.13](https://github.com/appydave/appydave-tools/compare/v0.76.12...v0.76.13) (2026-03-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* remove redundant smoke-test from s3_scan_command_spec; fix RSpec/RepeatedExample CI rubocop offense ([5711e4e](https://github.com/appydave/appydave-tools/commit/5711e4e62d6ab648fc2a93fae32453095a00d4ca))
|
|
7
|
+
|
|
1
8
|
## [0.76.12](https://github.com/appydave/appydave-tools/compare/v0.76.11...v0.76.12) (2026-03-19)
|
|
2
9
|
|
|
3
10
|
|
data/docs/planning/BACKLOG.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Project Backlog — AppyDave Tools
|
|
2
2
|
|
|
3
|
-
**Last updated**: 2026-03-
|
|
4
|
-
**Total**: 40 | Pending:
|
|
3
|
+
**Last updated**: 2026-03-20 (env-dead-code-cleanup campaign complete)
|
|
4
|
+
**Total**: 40 | Pending: 7 | Done: 32 | Deferred: 0 | Rejected: 0
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
- [ ] B009 — UX: progress indicators for dam operations > 5s | Priority: low
|
|
16
16
|
- [ ] B010 — UX: auto-adjust dam table column widths to terminal width | Priority: low
|
|
17
17
|
- [ ] B020 — Arch: split S3Operations (1,030 lines, mixed I/O + logic) | Priority: low (now unblocked)
|
|
18
|
-
- [ ] B038 — Cleanup: remove ENV['BRAND_PATH'] dead code from bin/dam (10 assignments, never read in lib/) | Priority: low
|
|
19
|
-
- [ ] B039 — Tests: strengthen s3_scan_command_spec data-value assertions + remove LocalSyncStatus stub | Priority: low
|
|
20
18
|
|
|
21
19
|
---
|
|
22
20
|
|
|
@@ -52,6 +50,8 @@
|
|
|
52
50
|
- [x] B035 — Fix: remove ENV['BRAND_PATH'] side effect from S3ArgParser; return brand_path: in result hash | Completed: library-boundary-cleanup (2026-03-19), v0.76.9
|
|
53
51
|
- [x] B036 — Tests: rebuild S3ScanCommand spec from D to B (10 behaviour examples) | Completed: library-boundary-cleanup (2026-03-19), v0.76.10
|
|
54
52
|
- [x] B037 — Tests: LocalSyncStatus :partial, local_file_count, Zone.Identifier exclusion, unknown format | Completed: library-boundary-cleanup (2026-03-19), v0.76.11
|
|
53
|
+
- [x] B038 — Cleanup: remove ENV['BRAND_PATH'] dead code from bin/dam (10 assignments) | Completed: env-dead-code-cleanup (2026-03-20), v0.76.13
|
|
54
|
+
- [x] B039 — Tests: strengthen s3_scan_command_spec field assertions + remove LocalSyncStatus stub | Completed: env-dead-code-cleanup (2026-03-20), v0.76.12
|
|
55
55
|
|
|
56
56
|
---
|
|
57
57
|
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# AGENTS.md — AppyDave Tools / batch-a-features campaign
|
|
2
|
+
|
|
3
|
+
> Self-contained operational knowledge. You receive only this file + your work unit prompt.
|
|
4
|
+
> Inherited from: env-dead-code-cleanup (2026-03-20)
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Project Overview
|
|
9
|
+
|
|
10
|
+
**Stack:** Ruby 3.4.2, Bundler 2.6.2, RSpec, RuboCop, semantic-release CI/CD.
|
|
11
|
+
**Baseline:** 860 examples, 0 failures, 86.44% line coverage, v0.76.13
|
|
12
|
+
**Commits:** `kfeat "message"` for new features (minor bump), `kfix "message"` for fixes (patch bump). Never `git commit` directly.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## ⚠️ kfix/kfeat Staging Behaviour
|
|
17
|
+
|
|
18
|
+
`kfix` and `kfeat` run `git add .` internally — they stage EVERYTHING in the working tree.
|
|
19
|
+
|
|
20
|
+
**Before calling kfix/kfeat:**
|
|
21
|
+
```bash
|
|
22
|
+
git status # confirm ONLY your intended files are modified
|
|
23
|
+
git diff # review the actual changes
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If unintended files appear:
|
|
27
|
+
```bash
|
|
28
|
+
git stash -- path/to/unintended/file # stash specific file
|
|
29
|
+
git checkout -- path/to/file # discard unintended change
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Then call kfix/kfeat once the tree is clean.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Build & Run Commands
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
eval "$(rbenv init -)"
|
|
40
|
+
|
|
41
|
+
RUBYOPT="-W0" bundle exec rspec # Full suite (860 examples baseline)
|
|
42
|
+
bundle exec rspec spec/path/to/file_spec.rb # Single file
|
|
43
|
+
bundle exec rubocop --format clang # Lint (must be 0 offenses)
|
|
44
|
+
|
|
45
|
+
kfeat "add feature description" # new feature — minor version bump
|
|
46
|
+
kfix "fix description" # fix/improvement — patch version bump
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Directory Structure
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
bin/
|
|
55
|
+
gpt_context.rb GPT context CLI — target of B001
|
|
56
|
+
dam DAM CLI (VatCLI) — target of B009
|
|
57
|
+
lib/appydave/tools/
|
|
58
|
+
gpt_context/
|
|
59
|
+
options.rb Options struct — add show_tokens field (B001)
|
|
60
|
+
file_collector.rb Builds content string from glob patterns
|
|
61
|
+
output_handler.rb Writes content to clipboard/file
|
|
62
|
+
dam/
|
|
63
|
+
project_listing.rb Table display for dam list — target of B010
|
|
64
|
+
brand_resolver.rb Brand name transforms (appydave ↔ v-appydave)
|
|
65
|
+
config.rb Brand path resolution
|
|
66
|
+
project_resolver.rb Project name resolution
|
|
67
|
+
spec/
|
|
68
|
+
appydave/tools/dam/
|
|
69
|
+
brand_resolution_integration_spec.rb NEW — target of B012
|
|
70
|
+
support/
|
|
71
|
+
dam_filesystem_helpers.rb Shared context for DAM specs
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## B001 — gpt-context-token-counting
|
|
77
|
+
|
|
78
|
+
**Files:** `lib/appydave/tools/gpt_context/options.rb`, `bin/gpt_context.rb`
|
|
79
|
+
|
|
80
|
+
### What to build
|
|
81
|
+
|
|
82
|
+
Add a `--tokens` / `-t` flag. When set, after collecting content, print an estimated token count to `$stderr` (so it doesn't pollute the content going to clipboard/file).
|
|
83
|
+
|
|
84
|
+
**Token estimation:** `(content.length / 4.0).ceil` — industry-standard approximation for English/code (4 chars ≈ 1 token).
|
|
85
|
+
|
|
86
|
+
### Step 1 — options.rb
|
|
87
|
+
|
|
88
|
+
Add `show_tokens` to the Struct:
|
|
89
|
+
```ruby
|
|
90
|
+
Options = Struct.new(
|
|
91
|
+
:include_patterns,
|
|
92
|
+
:exclude_patterns,
|
|
93
|
+
:format,
|
|
94
|
+
:line_limit,
|
|
95
|
+
:debug,
|
|
96
|
+
:output_target,
|
|
97
|
+
:working_directory,
|
|
98
|
+
:prompt,
|
|
99
|
+
:show_tokens, # ADD THIS
|
|
100
|
+
keyword_init: true
|
|
101
|
+
) do
|
|
102
|
+
def initialize(**args)
|
|
103
|
+
super
|
|
104
|
+
# existing defaults...
|
|
105
|
+
self.show_tokens ||= false # ADD THIS
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Step 2 — bin/gpt_context.rb
|
|
111
|
+
|
|
112
|
+
Add the CLI flag (after the `-p` option block, before the separator):
|
|
113
|
+
```ruby
|
|
114
|
+
opts.on('-t', '--tokens', 'Show estimated token count after collecting context') do
|
|
115
|
+
options.show_tokens = true
|
|
116
|
+
end
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
After `content = gatherer.build` and before `output_handler = ...`, add:
|
|
120
|
+
```ruby
|
|
121
|
+
if options.show_tokens
|
|
122
|
+
token_estimate = (content.length / 4.0).ceil
|
|
123
|
+
char_count = content.length
|
|
124
|
+
$stderr.puts ''
|
|
125
|
+
$stderr.puts '── Token Estimate ──────────────────────────'
|
|
126
|
+
$stderr.puts " Characters : #{char_count.to_s.rjust(10)}"
|
|
127
|
+
$stderr.puts " Tokens (~4c): #{token_estimate.to_s.rjust(10)}"
|
|
128
|
+
$stderr.puts ''
|
|
129
|
+
if token_estimate > 200_000
|
|
130
|
+
$stderr.puts ' ⚠️ WARNING: Exceeds 200k tokens — may not fit most LLM context windows'
|
|
131
|
+
elsif token_estimate > 100_000
|
|
132
|
+
$stderr.puts ' ⚠️ NOTICE: Exceeds 100k tokens — check your LLM context limit'
|
|
133
|
+
end
|
|
134
|
+
$stderr.puts '────────────────────────────────────────────'
|
|
135
|
+
$stderr.puts ''
|
|
136
|
+
end
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Done when B001 is complete
|
|
140
|
+
- `bundle exec rspec spec/appydave/tools/gpt_context/` → all pass
|
|
141
|
+
- Check if options_spec.rb needs a new example for `show_tokens` default — add one if it tests other defaults
|
|
142
|
+
- `bundle exec rubocop --format clang` → 0 offenses
|
|
143
|
+
- `RUBYOPT="-W0" bundle exec rspec` → 860+ examples, 0 failures
|
|
144
|
+
- Commit: `kfeat "add --tokens flag to gpt_context for estimated token count output"`
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## B009 — dam-progress-indicators
|
|
149
|
+
|
|
150
|
+
**File:** `bin/dam` only.
|
|
151
|
+
|
|
152
|
+
### What to build
|
|
153
|
+
|
|
154
|
+
Add human-readable progress messages before and after long-running S3 operations. These operations can take 30s–5min with no feedback currently.
|
|
155
|
+
|
|
156
|
+
### Commands to update
|
|
157
|
+
|
|
158
|
+
**s3_up_command** — wrap the upload:
|
|
159
|
+
```ruby
|
|
160
|
+
def s3_up_command(args)
|
|
161
|
+
options = Appydave::Tools::Dam::S3ArgParser.parse_s3(args, 's3-up')
|
|
162
|
+
s3_ops = Appydave::Tools::Dam::S3Operations.new(options[:brand], options[:project])
|
|
163
|
+
verb = options[:dry_run] ? '🔍 Dry run:' : '⬆️ Uploading'
|
|
164
|
+
puts "#{verb} #{options[:project]} (#{options[:brand]}) → S3..."
|
|
165
|
+
s3_ops.upload(dry_run: options[:dry_run])
|
|
166
|
+
rescue StandardError => e
|
|
167
|
+
# existing rescue
|
|
168
|
+
end
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**s3_down_command:**
|
|
172
|
+
```ruby
|
|
173
|
+
puts "⬇️ Downloading #{options[:project]} (#{options[:brand]}) from S3..."
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**s3_status_command:**
|
|
177
|
+
```ruby
|
|
178
|
+
puts "🔍 Checking S3 status for #{options[:project]} (#{options[:brand]})..."
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**archive_command:**
|
|
182
|
+
```ruby
|
|
183
|
+
puts "📦 Archiving #{options[:project]} (#{options[:brand]}) to SSD..."
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**sync_ssd_command** (brand-level, not project):
|
|
187
|
+
```ruby
|
|
188
|
+
puts "🔄 Syncing #{brand_arg} from SSD..."
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Read `bin/dam` carefully to find the exact method structure and rescue blocks before making changes. Add the `puts` line immediately after the `options =` assignment and before the `s3_ops =` instantiation.
|
|
192
|
+
|
|
193
|
+
### Done when B009 is complete
|
|
194
|
+
- `RUBYOPT="-W0" bundle exec rspec` → 860 examples, 0 failures (no new specs — bin/dam is untested by spec)
|
|
195
|
+
- `bundle exec rubocop --format clang` → 0 offenses
|
|
196
|
+
- Commit: `kfix "add progress indicators to dam S3 commands"`
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## B010 — dam-column-widths
|
|
201
|
+
|
|
202
|
+
**File:** `lib/appydave/tools/dam/project_listing.rb` only.
|
|
203
|
+
|
|
204
|
+
### What to build
|
|
205
|
+
|
|
206
|
+
Replace hardcoded separator line lengths with terminal-width detection. Also add path truncation for the PATH column.
|
|
207
|
+
|
|
208
|
+
### Step 1 — add terminal_width helper
|
|
209
|
+
|
|
210
|
+
Add a private class method:
|
|
211
|
+
```ruby
|
|
212
|
+
def self.terminal_width
|
|
213
|
+
IO.console&.winsize&.last || 120
|
|
214
|
+
rescue StandardError
|
|
215
|
+
120
|
|
216
|
+
end
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
You'll need `require 'io/console'` — add it at the top of the file (after `# frozen_string_literal: true`):
|
|
220
|
+
```ruby
|
|
221
|
+
require 'io/console'
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Step 2 — replace hardcoded separator lengths
|
|
225
|
+
|
|
226
|
+
Currently the file has multiple `puts '-' * N` lines with hardcoded widths (133, 122, 189, 200, etc.).
|
|
227
|
+
|
|
228
|
+
Replace each with `puts '-' * [terminal_width, N].min` where N is the original value. This prevents the separator from overflowing narrow terminals while still using the full width on wide ones.
|
|
229
|
+
|
|
230
|
+
grep for `'-'` in project_listing.rb to find all occurrences.
|
|
231
|
+
|
|
232
|
+
### Step 3 — add path truncation helper
|
|
233
|
+
|
|
234
|
+
```ruby
|
|
235
|
+
def self.truncate_path(path, max_width = 35)
|
|
236
|
+
return path if path.nil? || path.length <= max_width
|
|
237
|
+
"...#{path[-(max_width - 3)..]}"
|
|
238
|
+
end
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Replace `shorten_path(data[:path])` calls with `truncate_path(shorten_path(data[:path]), 35)` where the format string uses `%-35s`.
|
|
242
|
+
|
|
243
|
+
### Done when B010 is complete
|
|
244
|
+
- `RUBYOPT="-W0" bundle exec rspec spec/appydave/tools/dam/project_listing_spec.rb` → all pass
|
|
245
|
+
- `RUBYOPT="-W0" bundle exec rspec` → 860+ examples, 0 failures
|
|
246
|
+
- `bundle exec rubocop --format clang` → 0 offenses
|
|
247
|
+
- Commit: `kfix "terminal-width-aware separator lines and path truncation in project_listing"`
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## B012 — brand-resolution-integration-tests
|
|
252
|
+
|
|
253
|
+
**File:** `spec/appydave/tools/dam/brand_resolution_integration_spec.rb` (new file)
|
|
254
|
+
|
|
255
|
+
### What to build
|
|
256
|
+
|
|
257
|
+
Integration tests that exercise the BrandResolver → Config → ProjectResolver chain end-to-end using the shared filesystem context.
|
|
258
|
+
|
|
259
|
+
```ruby
|
|
260
|
+
# frozen_string_literal: true
|
|
261
|
+
|
|
262
|
+
require 'spec_helper'
|
|
263
|
+
|
|
264
|
+
RSpec.describe 'Brand resolution integration' do
|
|
265
|
+
include_context 'with vat filesystem and brands', brands: %w[appydave voz]
|
|
266
|
+
|
|
267
|
+
before do
|
|
268
|
+
FileUtils.mkdir_p(File.join(appydave_path, 'b65-test-project'))
|
|
269
|
+
FileUtils.mkdir_p(File.join(appydave_path, 'b66-another-project'))
|
|
270
|
+
FileUtils.mkdir_p(File.join(voz_path, 'boy-baker'))
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
describe 'BrandResolver → Config.brand_path' do
|
|
274
|
+
it 'resolves appydave shortcut to correct path' do
|
|
275
|
+
path = Appydave::Tools::Dam::Config.brand_path('appydave')
|
|
276
|
+
expect(path).to eq(appydave_path)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
it 'resolves voz shortcut to correct path' do
|
|
280
|
+
path = Appydave::Tools::Dam::Config.brand_path('voz')
|
|
281
|
+
expect(path).to eq(voz_path)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
it 'raises BrandNotFoundError for unknown brand' do
|
|
285
|
+
expect { Appydave::Tools::Dam::Config.brand_path('nonexistent') }
|
|
286
|
+
.to raise_error(Appydave::Tools::Dam::BrandNotFoundError)
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
describe 'BrandResolver.expand' do
|
|
291
|
+
it 'expands appydave to v-appydave' do
|
|
292
|
+
expect(Appydave::Tools::Dam::BrandResolver.expand('appydave')).to eq('v-appydave')
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
it 'expands voz to v-voz' do
|
|
296
|
+
expect(Appydave::Tools::Dam::BrandResolver.expand('voz')).to eq('v-voz')
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
describe 'ProjectResolver.resolve' do
|
|
301
|
+
it 'resolves short name b65 to full project name' do
|
|
302
|
+
result = Appydave::Tools::Dam::ProjectResolver.resolve('appydave', 'b65')
|
|
303
|
+
expect(result).to eq('b65-test-project')
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
it 'resolves exact project name' do
|
|
307
|
+
result = Appydave::Tools::Dam::ProjectResolver.resolve('voz', 'boy-baker')
|
|
308
|
+
expect(result).to eq('boy-baker')
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
it 'raises ProjectNotFoundError for missing project' do
|
|
312
|
+
expect { Appydave::Tools::Dam::ProjectResolver.resolve('appydave', 'b99') }
|
|
313
|
+
.to raise_error(Appydave::Tools::Dam::ProjectNotFoundError)
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
describe 'ProjectResolver.detect_from_pwd' do
|
|
318
|
+
it 'detects brand and project from a project directory' do
|
|
319
|
+
Dir.chdir(File.join(appydave_path, 'b65-test-project')) do
|
|
320
|
+
brand, project = Appydave::Tools::Dam::ProjectResolver.detect_from_pwd
|
|
321
|
+
expect(brand).to eq('appydave')
|
|
322
|
+
expect(project).to eq('b65-test-project')
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it 'returns nil when run outside any known brand directory' do
|
|
327
|
+
Dir.chdir('/tmp') do
|
|
328
|
+
brand, project = Appydave::Tools::Dam::ProjectResolver.detect_from_pwd
|
|
329
|
+
expect(brand).to be_nil
|
|
330
|
+
expect(project).to be_nil
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Read `project_resolver.rb` and `brand_resolver.rb` before writing** to confirm method signatures.
|
|
338
|
+
|
|
339
|
+
**Note:** The shared context mocks `SettingsConfig#video_projects_root` to return `projects_root`, so `Config.brand_path` calls will resolve to the temp filesystem. `instance_double` is NOT needed here — use the real classes against the mocked filesystem.
|
|
340
|
+
|
|
341
|
+
### Done when B012 is complete
|
|
342
|
+
- `bundle exec rspec spec/appydave/tools/dam/brand_resolution_integration_spec.rb` → all pass
|
|
343
|
+
- `RUBYOPT="-W0" bundle exec rspec` → 866+ examples, 0 failures
|
|
344
|
+
- `bundle exec rubocop --format clang` → 0 offenses
|
|
345
|
+
- Commit: `kfix "add brand resolution integration spec covering BrandResolver, Config, ProjectResolver chain"`
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Success Criteria (Every Work Unit)
|
|
350
|
+
|
|
351
|
+
- [ ] `RUBYOPT="-W0" bundle exec rspec` → 860+ examples, 0 failures
|
|
352
|
+
- [ ] `bundle exec rubocop --format clang` → 0 offenses
|
|
353
|
+
- [ ] Coverage ≥ 86.44%
|
|
354
|
+
- [ ] Working tree clean before calling kfix/kfeat (git status check)
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Reference Patterns
|
|
359
|
+
|
|
360
|
+
### Shared Context for DAM Specs
|
|
361
|
+
|
|
362
|
+
```ruby
|
|
363
|
+
include_context 'with vat filesystem and brands', brands: %w[appydave voz]
|
|
364
|
+
# Provides: temp_folder, projects_root, appydave_path, voz_path
|
|
365
|
+
# SettingsConfig#video_projects_root mocked → projects_root
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### instance_double — Always Full Constant
|
|
369
|
+
|
|
370
|
+
```ruby
|
|
371
|
+
instance_double(Appydave::Tools::Configuration::Models::BrandsConfig) # ✅
|
|
372
|
+
instance_double('BrandsConfig') # ❌ fails CI
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Typed Exceptions
|
|
376
|
+
|
|
377
|
+
```ruby
|
|
378
|
+
raise Appydave::Tools::Dam::BrandNotFoundError.new(brand, available, suggestions)
|
|
379
|
+
raise Appydave::Tools::Dam::ProjectNotFoundError, 'message'
|
|
380
|
+
raise Appydave::Tools::Dam::UsageError, 'message'
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## Anti-Patterns to Avoid
|
|
386
|
+
|
|
387
|
+
- ❌ `exit 1` in library code — use typed exceptions
|
|
388
|
+
- ❌ `instance_double('StringForm')` — fails CI on Ubuntu
|
|
389
|
+
- ❌ Multiple `before` blocks in same context — merge them (RSpec/ScatteredSetup)
|
|
390
|
+
- ❌ `$?` for subprocess status — use `$CHILD_STATUS`
|
|
391
|
+
- ❌ `format_bytes` — use `FileHelper.format_size`
|
|
392
|
+
- ❌ Inline brand transforms — use BrandResolver
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Learnings
|
|
397
|
+
|
|
398
|
+
### From env-dead-code-cleanup (2026-03-20)
|
|
399
|
+
|
|
400
|
+
- **kfix runs `git add .` internally.** Clean the working tree before calling kfix. Check `git status` first.
|
|
401
|
+
- **`instance_double` string form fails CI on Ubuntu.** Always use full constant.
|
|
402
|
+
- **`not_to raise_error` is a weak assertion.** Prefer field-value or method-spy assertions.
|
|
403
|
+
|
|
404
|
+
### From library-boundary-cleanup (2026-03-20)
|
|
405
|
+
|
|
406
|
+
- **`exit 1` in library code → use typed exceptions.** VatCLI rescue blocks catch StandardError.
|
|
407
|
+
- **Config.brands needs separate mock** from shared filesystem context.
|
|
408
|
+
- **S3ScanCommand#scan_all rescues per-brand** — per-brand failures are isolated.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# IMPLEMENTATION_PLAN.md — batch-a-features
|
|
2
|
+
|
|
3
|
+
**Goal**: Four independent improvements batched into one parallel wave: token counting for gpt_context, progress indicators for dam S3 commands, terminal-width-aware column separators, and brand resolution integration tests.
|
|
4
|
+
**Started**: 2026-03-20
|
|
5
|
+
**Target**: All 4 complete, 860+ examples passing, rubocop 0 offenses
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
- Total: 4 | Complete: 0 | In Progress: 4 | Pending: 0 | Failed: 0
|
|
9
|
+
|
|
10
|
+
## Pending
|
|
11
|
+
|
|
12
|
+
## In Progress
|
|
13
|
+
- [~] B001 — gpt-context-token-counting — Add --tokens flag to gpt_context; print estimated token count + threshold warnings
|
|
14
|
+
- [~] B009 — dam-progress-indicators — Add before/after progress messages to s3_up, s3_down, s3_status, archive, sync_ssd in bin/dam
|
|
15
|
+
- [~] B010 — dam-column-widths — Terminal-width-aware separator lines + path truncation in project_listing.rb
|
|
16
|
+
- [~] B012 — brand-resolution-integration-tests — Integration spec covering brand→project resolution chain end-to-end
|
|
17
|
+
|
|
18
|
+
## Complete
|
|
19
|
+
|
|
20
|
+
## Failed / Needs Retry
|
|
21
|
+
|
|
22
|
+
## Notes & Decisions
|
|
23
|
+
|
|
24
|
+
### Wave Plan
|
|
25
|
+
All 4 work units touch different files — run in parallel, one wave.
|
|
26
|
+
|
|
27
|
+
| WU | Files |
|
|
28
|
+
|----|-------|
|
|
29
|
+
| B001 | `lib/gpt_context/options.rb`, `bin/gpt_context.rb` |
|
|
30
|
+
| B009 | `bin/dam` |
|
|
31
|
+
| B010 | `lib/dam/project_listing.rb` |
|
|
32
|
+
| B012 | `spec/appydave/tools/dam/brand_resolution_integration_spec.rb` (new) |
|
|
33
|
+
|
|
34
|
+
### kfix hygiene
|
|
35
|
+
kfix runs `git add .` internally. Ensure working tree contains ONLY intended files before calling kfix.
|
|
36
|
+
The other agents' in-progress changes will NOT appear in your working tree (each agent works independently).
|
|
37
|
+
Safe to call kfix once your specific files are the only changes present.
|
|
@@ -17,22 +17,32 @@
|
|
|
17
17
|
|
|
18
18
|
## ⚠️ Pre-Commit Check (Mandatory Every Commit)
|
|
19
19
|
|
|
20
|
+
`kfix` and `kfeat` run `git add .` internally — they stage EVERYTHING in the working tree unconditionally. You cannot selectively stage files.
|
|
21
|
+
|
|
22
|
+
**The only safe approach: ensure the working tree contains ONLY your intended changes before calling kfix.**
|
|
23
|
+
|
|
20
24
|
```bash
|
|
21
|
-
git status
|
|
25
|
+
git status # What files are modified/untracked?
|
|
26
|
+
git diff # What are the actual changes?
|
|
22
27
|
```
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
If unintended files appear (e.g. planning docs, other specs):
|
|
30
|
+
- `git stash -- path/to/file` to temporarily stash a specific file
|
|
31
|
+
- OR `git checkout -- path/to/file` to discard an unintended change
|
|
32
|
+
- OR `git clean -n` to preview, then `git clean -f path/to/file` for untracked files
|
|
25
33
|
|
|
34
|
+
Once the working tree contains ONLY the files you intended to change, call:
|
|
26
35
|
```bash
|
|
27
|
-
|
|
28
|
-
git add bin/dam
|
|
29
|
-
kfix "..."
|
|
30
|
-
|
|
31
|
-
# Wrong — stages everything including planning files:
|
|
32
|
-
git add .
|
|
36
|
+
kfix "your message here"
|
|
33
37
|
```
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
kfix/kfeat then:
|
|
40
|
+
1. `git add .` — stages everything (working tree must be clean of unintended files)
|
|
41
|
+
2. `git commit -m "fix: ..."` — commits
|
|
42
|
+
3. `git pull` + `git push` — syncs and pushes
|
|
43
|
+
4. Waits for CI (`gh run watch`) — blocks until green or red
|
|
44
|
+
5. On success: `git pull` again to pick up semantic-release version bump + CHANGELOG
|
|
45
|
+
6. Prints the new version tag
|
|
36
46
|
|
|
37
47
|
---
|
|
38
48
|
|
|
@@ -104,7 +114,7 @@ After removing, also check if `options[:brand_path]` was the ONLY use of `option
|
|
|
104
114
|
- `grep -n "BRAND_PATH" bin/dam` → 0 results
|
|
105
115
|
- `RUBYOPT="-W0" bundle exec rspec` → 861 examples, 0 failures
|
|
106
116
|
- `bundle exec rubocop --format clang` → 0 offenses
|
|
107
|
-
- `git status` clean (
|
|
117
|
+
- `git status` clean (working tree contains ONLY bin/dam changes before calling kfix)
|
|
108
118
|
|
|
109
119
|
**Commit:** `kfix "remove ENV BRAND_PATH dead code from bin/dam (10 assignments, never read in lib)"`
|
|
110
120
|
|
|
@@ -153,7 +163,7 @@ FileUtils.mkdir_p(File.join(appydave_path, 'b65-test-project', 's3-staging'))
|
|
|
153
163
|
- `bundle exec rspec spec/appydave/tools/dam/s3_scan_command_spec.rb` → all pass
|
|
154
164
|
- `RUBYOPT="-W0" bundle exec rspec` → 861 examples, 0 failures (count unchanged — no new specs)
|
|
155
165
|
- `bundle exec rubocop --format clang` → 0 offenses
|
|
156
|
-
- `git status` clean (
|
|
166
|
+
- `git status` clean (working tree contains ONLY the spec file changes before calling kfix)
|
|
157
167
|
|
|
158
168
|
**Commit:** `kfix "strengthen s3_scan_command_spec field assertions; remove LocalSyncStatus stub"`
|
|
159
169
|
|
|
@@ -164,7 +174,7 @@ FileUtils.mkdir_p(File.join(appydave_path, 'b65-test-project', 's3-staging'))
|
|
|
164
174
|
- [ ] `RUBYOPT="-W0" bundle exec rspec` — 861+ examples, 0 failures
|
|
165
175
|
- [ ] `bundle exec rubocop --format clang` — 0 offenses
|
|
166
176
|
- [ ] Line coverage ≥ 86.43%
|
|
167
|
-
- [ ] `git status` clean
|
|
177
|
+
- [ ] `git status` clean (working tree contains ONLY intended changes before calling kfix)
|
|
168
178
|
|
|
169
179
|
---
|
|
170
180
|
|
|
@@ -201,7 +211,7 @@ raise Appydave::Tools::Dam::UsageError, 'Usage: dam s3-up <brand> <project>'
|
|
|
201
211
|
|
|
202
212
|
## Anti-Patterns to Avoid
|
|
203
213
|
|
|
204
|
-
- ❌ `
|
|
214
|
+
- ❌ Calling `kfix`/`kfeat` with unintended files in the working tree — clean the tree first, then call kfix
|
|
205
215
|
- ❌ `exit 1` in library code — use typed exceptions (already fixed in library-boundary-cleanup)
|
|
206
216
|
- ❌ `ENV['BRAND_PATH'] =` in any file — confirmed dead, being removed in B038
|
|
207
217
|
- ❌ `instance_double('StringForm')` — use full constant always
|
|
@@ -216,7 +226,7 @@ raise Appydave::Tools::Dam::UsageError, 'Usage: dam s3-up <brand> <project>'
|
|
|
216
226
|
### From library-boundary-cleanup (2026-03-20)
|
|
217
227
|
|
|
218
228
|
- **`instance_double` string form fails CI on Ubuntu.** Always use full constant: `instance_double(Fully::Qualified::ClassName)`.
|
|
219
|
-
-
|
|
229
|
+
- **Dirty working tree + kfix = accidental staging.** `kfix` runs `git add .` internally — it stages everything. Ensure the working tree contains ONLY intended changes before calling kfix.
|
|
220
230
|
- **`ENV['BRAND_PATH']` in bin/dam is dead code.** 10 assignments, 0 reads. Being removed in B038.
|
|
221
231
|
- **VatCLI rescue blocks catch DamError correctly.** `UsageError < DamError < StandardError` — all 17 rescue blocks catch it without modification.
|
|
222
232
|
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
**Target**: Both items complete; 861+ examples passing; rubocop 0 offenses; no regressions
|
|
6
6
|
|
|
7
7
|
## Summary
|
|
8
|
-
- Total: 2 | Complete:
|
|
8
|
+
- Total: 2 | Complete: 2 | In Progress: 0 | Pending: 0 | Failed: 0
|
|
9
9
|
|
|
10
10
|
## Pending
|
|
11
11
|
|
|
12
12
|
## In Progress
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
13
|
+
- [x] B038 — remove-env-dead-code — All 10 ENV['BRAND_PATH'] assignments removed from bin/dam; 0 cascade removals (options still used for other keys). CI fix needed: git add . staged s3_scan_command_spec.rb with pre-existing RSpec/RepeatedExample offense — fixed via second commit. 860 examples, 0 failures. Commits: 5c11027, 5711e4e.
|
|
14
|
+
- [x] B039 — strengthen-s3-scan-spec — Field-value assertions on both not_to be_empty checks; LocalSyncStatus stub removed (runs for real against fixture filesystem, returns :no_files). 861 examples, 0 failures. v0.76.12. Commit: 7f1fc5a.
|
|
15
15
|
|
|
16
16
|
## Complete
|
|
17
17
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Assessment: env-dead-code-cleanup
|
|
2
|
+
|
|
3
|
+
**Campaign**: env-dead-code-cleanup
|
|
4
|
+
**Date**: 2026-03-20 → 2026-03-20
|
|
5
|
+
**Results**: 2 complete, 0 failed
|
|
6
|
+
**Final version**: v0.76.13 (from v0.76.11 baseline)
|
|
7
|
+
**Quality audits**: code-quality-audit ✅ | test-quality-audit ✅
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Results Summary
|
|
12
|
+
|
|
13
|
+
| Work Unit | Description | Result | Version |
|
|
14
|
+
|-----------|-------------|--------|---------|
|
|
15
|
+
| B038 | remove-env-dead-code | ✅ Complete | v0.76.12/13 |
|
|
16
|
+
| B039 | strengthen-s3-scan-spec | ✅ Complete | v0.76.12 |
|
|
17
|
+
|
|
18
|
+
**Test baseline:** 861 → 860 examples (net -1: one redundant smoke test removed), 0 failures, 86.44% line coverage
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## What Worked Well
|
|
23
|
+
|
|
24
|
+
1. **Both work units ran in parallel with zero conflicts.** `bin/dam` and `spec/...` are non-overlapping. Wave 1 parallel pattern continues to be reliable for this type of work.
|
|
25
|
+
|
|
26
|
+
2. **ENV removal was surgically clean.** All 10 assignments were isolated lines with no downstream reads — each method is 1 line shorter and more readable. Code audit confirmed 0 orphaned variables.
|
|
27
|
+
|
|
28
|
+
3. **Test grade lifted from B to B+.** Field-value assertions now catch wrong values, not just non-empty. LocalSyncStatus runs for real (via fixture filesystem) and is verified with a method spy. Stronger than before without over-specifying.
|
|
29
|
+
|
|
30
|
+
4. **Code audit: zero concerns.** 0 rubocop offenses, 0 remaining dead code, library boundaries respected everywhere.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## What Didn't Work
|
|
35
|
+
|
|
36
|
+
1. **B038 agent used `git add .` again** — the fourth campaign in a row with this issue. It staged `s3_scan_command_spec.rb` which had a pre-existing `RSpec/RepeatedExample` offense on CI. Required a second fix commit. The AGENTS.md warning is prominent but agents keep ignoring it.
|
|
37
|
+
|
|
38
|
+
**Root cause:** The `kfix` alias may itself be running `git add .` internally, or agents are running `git add .` before `kfix`. Need to investigate whether `kfix` pre-stages, and if so, update AGENTS.md to reflect that.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Key Learnings — Application
|
|
43
|
+
|
|
44
|
+
1. **`ENV['BRAND_PATH']` is fully gone.** `grep -rn "BRAND_PATH" bin/ lib/ spec/` → 0 results. Any future S3 operations get `brand_path` through proper parameter passing.
|
|
45
|
+
|
|
46
|
+
2. **`not_to raise_error` is a weak assertion.** It only verifies no exception — it says nothing about correctness. Replace with field-value or method-spy assertions whenever possible.
|
|
47
|
+
|
|
48
|
+
3. **LocalSyncStatus integration test pattern:** Use `allow(Config).to receive(:project_path).and_return(appydave_path)` + `FileUtils.mkdir_p(staging_dir)` to let LocalSyncStatus run for real without deep mocking.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Key Learnings — Ralph Loop
|
|
53
|
+
|
|
54
|
+
1. **`git add .` persists across agents despite AGENTS.md warnings.** The warning is not working. Options for next campaign:
|
|
55
|
+
- Investigate whether `kfix` itself stages all files (check its shell implementation)
|
|
56
|
+
- Add explicit `git add <specific-file>` to commit instructions in AGENTS.md rather than relying on agents to remember not to use `git add .`
|
|
57
|
+
|
|
58
|
+
2. **Small 2-WU parallel campaigns are very efficient.** Planning took ~5 minutes (brief already written), build ran in one wave, audits confirmed clean. This is the right pattern for closing audit findings.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Code Quality Audit Findings
|
|
63
|
+
|
|
64
|
+
**Grade: APPROVED / Production-ready**
|
|
65
|
+
- 0 BRAND_PATH references anywhere in codebase
|
|
66
|
+
- All removal sites clean — no orphaned variables
|
|
67
|
+
- 0 rubocop offenses in bin/dam
|
|
68
|
+
- 860/860 tests pass, 86.44% coverage
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Test Quality Audit Findings
|
|
73
|
+
|
|
74
|
+
**Grade: B+ (improvement from B)**
|
|
75
|
+
- Field-value assertions are not tautological — catch mutations to file_count, total_bytes, last_modified
|
|
76
|
+
- LocalSyncStatus spy verifies correct arguments passed (not just that it doesn't raise)
|
|
77
|
+
- Removed test was genuinely redundant — no coverage loss
|
|
78
|
+
- Appropriate layer separation: S3ScanCommand spec tests orchestration; LocalSyncStatus spec tests computation
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Suggestions for Next Campaign
|
|
83
|
+
|
|
84
|
+
1. **Investigate `kfix` staging behaviour** — check whether the alias runs `git add .` or `git add -A` before committing. If so, update AGENTS.md to use `git add <file> && kfix` pattern explicitly.
|
|
85
|
+
|
|
86
|
+
2. **Next major work:** B020 (split S3Operations, 1,030 lines) — now the cleanest next step. Library boundaries are solid, dead code is gone, test suite is at B+.
|
|
87
|
+
|
|
88
|
+
3. **B007 (parallelism)** follows B020 — do not attempt before S3Operations is split.
|
|
@@ -19,13 +19,32 @@
|
|
|
19
19
|
|
|
20
20
|
## ⚠️ Pre-Commit Check (Mandatory Every Commit)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
`kfix` and `kfeat` run `git add .` internally — they stage EVERYTHING in the working tree unconditionally. You cannot selectively stage files.
|
|
23
|
+
|
|
24
|
+
**The only safe approach: ensure the working tree contains ONLY your intended changes before calling kfix.**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git status # What files are modified/untracked?
|
|
28
|
+
git diff # What are the actual changes?
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If unintended files appear (e.g. planning docs, other specs):
|
|
32
|
+
- `git stash -- path/to/file` to temporarily stash a specific file
|
|
33
|
+
- OR `git checkout -- path/to/file` to discard an unintended change
|
|
34
|
+
- OR `git clean -n` to preview, then `git clean -f path/to/file` for untracked files
|
|
35
|
+
|
|
36
|
+
Once the working tree contains ONLY the files you intended to change, call:
|
|
23
37
|
```bash
|
|
24
|
-
|
|
38
|
+
kfix "your message here"
|
|
25
39
|
```
|
|
26
|
-
Confirm ONLY the files you intentionally changed are staged. If unexpected files appear, run `git diff` to investigate before proceeding. Never commit files you didn't intentionally change.
|
|
27
40
|
|
|
28
|
-
|
|
41
|
+
kfix/kfeat then:
|
|
42
|
+
1. `git add .` — stages everything (working tree must be clean of unintended files)
|
|
43
|
+
2. `git commit -m "fix: ..."` — commits
|
|
44
|
+
3. `git pull` + `git push` — syncs and pushes
|
|
45
|
+
4. Waits for CI (`gh run watch`) — blocks until green or red
|
|
46
|
+
5. On success: `git pull` again to pick up semantic-release version bump + CHANGELOG
|
|
47
|
+
6. Prints the new version tag
|
|
29
48
|
|
|
30
49
|
---
|
|
31
50
|
|
|
@@ -648,7 +667,7 @@ end
|
|
|
648
667
|
### From library-boundary-cleanup (2026-03-20)
|
|
649
668
|
|
|
650
669
|
- **`instance_double` string form fails CI on Ubuntu.** Always use full constant: `instance_double(Fully::Qualified::ClassName)`. String form passes locally but Ubuntu CI enforces constant lookup. A CI failure after a green local run is almost always this.
|
|
651
|
-
-
|
|
670
|
+
- **Dirty working tree + kfix = accidental staging.** `kfix` runs `git add .` internally — it stages everything. Ensure the working tree contains ONLY intended changes before calling kfix. Three prior campaigns have been burned by this.
|
|
652
671
|
- **`ENV['BRAND_PATH']` in bin/dam is dead code.** 10 assignments in bin/dam, 0 reads in lib/. S3Operations receives brand_path as a constructor parameter. Tracked as B038 for cleanup.
|
|
653
672
|
|
|
654
673
|
### From extract-vat-cli (2026-03-19)
|
data/package.json
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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.14
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cruwys
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -297,11 +297,14 @@ files:
|
|
|
297
297
|
- docs/guides/tools/youtube-manager.md
|
|
298
298
|
- docs/planning/AGENTS.md
|
|
299
299
|
- docs/planning/BACKLOG.md
|
|
300
|
+
- docs/planning/batch-a-features/AGENTS.md
|
|
301
|
+
- docs/planning/batch-a-features/IMPLEMENTATION_PLAN.md
|
|
300
302
|
- docs/planning/bugfix-and-security/AGENTS.md
|
|
301
303
|
- docs/planning/bugfix-and-security/IMPLEMENTATION_PLAN.md
|
|
302
304
|
- docs/planning/bugfix-and-security/assessment.md
|
|
303
305
|
- docs/planning/env-dead-code-cleanup/AGENTS.md
|
|
304
306
|
- docs/planning/env-dead-code-cleanup/IMPLEMENTATION_PLAN.md
|
|
307
|
+
- docs/planning/env-dead-code-cleanup/assessment.md
|
|
305
308
|
- docs/planning/extract-vat-cli/AGENTS.md
|
|
306
309
|
- docs/planning/extract-vat-cli/IMPLEMENTATION_PLAN.md
|
|
307
310
|
- docs/planning/extract-vat-cli/assessment.md
|