amazon-dynamodb-tools / bulk_executor
AGENTS.md182 starsChanged 5 months agoApache-2.0View on GitHub
Operating manual for AI agents working in this directory. CLAUDE.md is a committed symlink to AGENTS.md (mode 120000), so tools that look for either name read the same content. Always edit AGENTS.md — never replace the symlink with a copy, or the two silently drift. Always use the Makefile: Never invoke pytest with --cov=python_modules. The two source roots are server/src and client/src — coverage flags must use those paths. ai_lint/ holds AI-driven checks for invariants that are easy to verify…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository2 other files it gives its agents.
The file
We split this AGENTS.md into the rules it gives an agent
10 rules. About 0 are common, 7 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 24
Always use the Makefile:
- Very specific: line 34
Never invoke pytest with --cov=python_modules.
- Very specific: line 42
Read every ai_lint/rules/*.md.
- Distinctive: line 66
Instead, refresh all three in their own dedicated badge-refresh PR (touching only README.md), done occasionally when someone wants the …
- Distinctive: line 68
When you do a refresh PR:
- Distinctive: line 91
Do not mock the function under test — only its dependencies.
- Distinctive: line 92
Don't add fixtures unless shared across 3+ tests.
- Very specific: line 104
When you find an uncovered line that's only reachable through a source bug (e.g.
- Distinctive: line 111
Use the pre-refactor source code from git history when writing the standalone tests.
- Distinctive: line 115
Currently none: All six entries this table once held were resolved under #298 (#310, #311, #312, #313, #314).
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md — bulk_executor
Operating manual for AI agents working in this directory.
Layout
server/src/ Glue-job-side code (runs on Spark workers)
client/src/ CLI-side code (runs on developer machines)
tests/server/ Mirrors server/src/ tree
tests/client/ Mirrors client/src/ tree
Makefile Single source of truth for test commands
pytest.ini Root config; sets pythonpath so both src trees resolve
AGENTS.md This file — the operating manual
CLAUDE.md Committed symlink to AGENTS.md; one file, two namesCLAUDE.md is a committed symlink to AGENTS.md (mode 120000), so tools that
look for either name read the same content. Always edit AGENTS.md — never replace
the symlink with a copy, or the two silently drift.
Running tests
Always use the Makefile:
make install # First time only; creates .venv
make test # All tests + coverage summary
make test-server # Server-side only
make test-client # Client-side only
make coverage # Full term-missing coverage reportNever invoke pytest with --cov=python_modules. The two source roots are server/src and client/src — coverage flags must use those paths.
AI lint (on-demand, agent-run)
ai_lint/ holds AI-driven checks for invariants that are easy to verify by reading code but very hard to express as a deterministic unit test (e.g. "the README, the role-creation code, and the custom-role validator must all agree on the Glue job's IAM permissions"; "every command that touches DynamoDB must be rate limited").
There is no runner — you (the agent) are the engine. When the user asks to "run the AI lint" (or names a specific rule):
- Read every
ai_lint/rules/*.md. Each file is one rule: the invariant, where to look, and how to report. - For each rule, inspect the current code with your normal tools — glob/grep/read. Rules that say "discover the verbs" mean it: enumerate live so newly added code is covered; never work from a stale hard-coded list.
- Report per-rule findings, and state what you verified even when clean (so a pass is trustworthy).
This is advisory — never a merge gate, never part of make test. A false alarm is feedback, not failure: if a finding turns out fine, tighten the rule's .md so the next run is sharper. Add a rule by dropping a new rules/<name>.md (one per file keeps merges clean). See ai_lint/README.md.
End-to-end tests (real AWS — opt-in)
make test is offline (awsglue/pyspark mocked). The e2e suites are separate, hit real Glue + DynamoDB, and never run under make test:
make test-e2e-connector # count/find/sql/load via the live DynamoDB connector
make test-e2e-commands # fill/update/delete/copy/diff against transient tables
make test-e2e-security # documented bootstrap IAM policy actually bootstrapsBefore touching the e2e harness, read tests/e2e/AGENTS.md — it documents the invariants (real-AWS guardrails, the transient-table contract, the shared-Glue-job hazard, what makes a smoke trustworthy vs false-green). The e2e tests require AWS credentials and a one-time ./bulk bootstrap; they cost real money and run real Glue jobs (~2 min each), so do not run them in tight loops.
Updating the badges in README.md
The top of README.md carries three badges (test count, line coverage, branch coverage). They are static — not auto-generated by CI.
Do NOT update the badges inside a feature/fix/test PR. Lines 3-5 of README.md are a single hot spot that every PR would touch, so bumping them per-PR guarantees merge conflicts — and because PRs merge in an unpredictable order, the numbers a PR writes are stale by the time it lands anyway. Leave README.md out of your change entirely; slightly-stale badges are fine and expected.
Instead, refresh all three in their own dedicated badge-refresh PR (touching only README.md), done occasionally when someone wants the numbers current — never wired into a substantive change.
When you do a refresh PR:
- Run
make test(the full offline suite — nottest-client,test-server, or any e2e target; e2e never counts toward the badges). Read the final lines for<N> passed,LINE COVERAGE: <X>%,BRANCH COVERAGE: <Y>%. Use<N> passedverbatim — do not add skipped tests to it. The numbers come from this fresh run, never from the badge's current value or a "+N" bump. Also do not use the percentages printed bymake test-client/make test-server/make coverage— only the fullmake testtotals feed the badges. - Edit lines 3-5 of
README.md. URL-encode%as%25and spaces as%20. - Pick a color:
brightgreenfor ≥90%,greenfor ≥75%,yellowfor ≥60%,orangefor ≥45%,redbelow.
Example (illustrative format only — always use your own fresh make test numbers, not these):


Writing tests
Mirror tests/server/test_fill.py — it is the canonical pattern.
- pytest, never unittest.
- Multi-line module docstring at the top naming each function/branch the file covers.
- Group related tests in
Test<FunctionName>classes. - Test names:
test_<what>_<when>_<expects>. - Mock external deps with
unittest.mock.patch/MagicMock. Usemonkeypatchfor env vars,tmp_pathfor filesystem,capsys/caplogfor stdout/log assertions. - Do not mock the function under test — only its dependencies.
- Don't add fixtures unless shared across 3+ tests.
conftest patterns
tests/server/conftest.py mocks awsglue and pyspark modules globally before collection, so any server-side test can import a verb without those packages installed. If you need a real subclass of pyspark.AccumulatorParam, use the _AccumulatorParamStub already defined there.
tests/server/fill/conftest.py stubs faker because multi_entity_relationship.py imports it at module load. Apply the same pattern (pre-collection module stubbing) when a source file's top-level imports require a heavy optional dependency.
Coverage rules
- Project target: ≥99% line, ≥96% branch.
- Never modify source code to chase coverage. Tests-only PRs must change zero files outside
tests/, the Makefile,pytest.ini,.gitignore. (Do not touchREADME.mdbadges here either — see "Updating the badges".) Document any unreachable branches in the PR description and move on. - When you find an uncovered line that's only reachable through a source bug (e.g. a regex group typo, dead
elif), do not "cover" it — note the bug in the PR description. Fixes land in a separate source-only PR.
PR splitting rule
Tests-only PRs and source-refactor PRs must stand independently on main. Never stack one on the other. If you find tests that depend on an unmerged source change, either:
- Hold those tests for a follow-up PR that lands after the source PR, or
- Use the pre-refactor source code from
githistory when writing the standalone tests.
Known unfixed source bugs
Currently none. All six entries this table once held were resolved under #298 (#310, #311, #312, #313, #314). If you add one, follow the shape below plus three rules the old list taught the hard way:
- Verify an entry before acting on it. One of the six described a bug that did
not exist: it claimed an
ifshould be anelifbecause theelseswallowedExpiredTokenException, butexit()raisesSystemExit, so the first branch always terminated first. It sat here for months. - Check whether the code is even reachable. Another described dead code in a module nothing imported -- the fix was deletion. A third described a log-merging bug that instrumenting a real run proved unreachable: across 318 captured driver events, including a deliberately split 400KB line, it never triggered once.
- Name the function, not the line. That first entry pointed at
386-392, which by then was a different function entirely.
Entries here are excluded from coverage chasing -- document an unreachable branch in the PR description and move on rather than contorting a test to reach it.
| File / symbol | Bug |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

