docs: rewrite AGENTS.md against the current service - #574
Merged
Merged
Conversation
AGENTS.md had drifted ~6 months. Verified every claim against the code: 139 were still accurate, 34 were wrong, and 54 load-bearing facts were absent. Structural drift the old file missed entirely: - a fifth Lambda (channel_api — WebSocket device pairing), a fifth API Gateway (API Gateway v2 WebSocket), and a fifth DynamoDB table (ffsync-channel) - the whole Smithy -> pydantic codegen pipeline - models moved from dataclasses-json (no longer a dependency) to generated pydantic v2 - device endpoints are implemented, not stubs - react-router v8, uv-managed tools/, no CDK profile, dashboard-only monitoring Added, with each mechanism verified rather than asserted: - src/shared/generated/ is git-ignored and required — a fresh clone cannot import, test or type-check until scripts/codegen.sh runs (promoted to a Critical Rule, since the failure looks like a broken repo) - a stale generated/ is invisible to every gate: no hook, no checksum, no CI diff, and no committed copy to diff against. CI regenerates from clean checkouts, so drift can only ever exist locally - TTL is not an access check — DynamoDB deletion lags 48h, so 6 sites re-check expiry in code; trusting TTL alone leaves expired sessions valid for two days - the 100% coverage gate fires on subset runs, so `pytest -k` exits 1 even when every selected test passes - decorated handlers must be `-> Response[Any]`; a bare `-> Response` passes mypy and import, then raises PydanticSchemaGenerationError on first request - `except A, B:` is valid PEP 758 on 3.14 — do not "fix" it; Black targets py314 and strips the parens back off - every push to mainline deploys to production - root `npm test` deletes frontend/dist/; DEFAULT_TABLE_PROPS is spread last so per-table overrides are silently discarded; REST APIs set disableExecuteApiEndpoint so only custom domains work Three code issues found while verifying are documented but not fixed here: DeviceManager.get_devices does an unpaginated full-table scan, the Profile Lambda's auth-table grant is read-only so any added write fails only at runtime, and bso.smithy:27 documents `modified` as milliseconds where the code uses seconds.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AGENTS.mdhad drifted ~6 months. I verified every claim in it against the code: 139 were still accurate, 34 were wrong, and 54 load-bearing facts were missing. That ~80% accuracy rate is what made it risky rather than merely dated — it reads as authoritative, and the wrong fifth was concentrated in the parts that changed most recently.Structural drift the old file missed entirely
channel_api— WebSocket device pairing), a fifth API Gateway (API Gateway v2 WebSocket atwss://channel.…), and a fifth DynamoDB table (ffsync-channel-<stage>)dataclasses-json— no longer a dependency at all — to generated pydantic v2react-routerv8 (doc said v7),tools/is uv-managed (requirements.txtis gone),cdk.jsonsets no profile, monitoring is dashboard-only with no alarmsAdded — each mechanism verified, not asserted
src/shared/generated/is git-ignored and required. A fresh clone cannot import, test, or type-check until./scripts/codegen.shruns. Promoted to a Critical Rule, because the failure (ModuleNotFoundError) looks like a broken repo rather than a missing build step.generated/is invisible to every gate. It imports, type-checks, lints and passes all 958 tests. There is no pre-commit hook, no checksum, no CI step diffing regenerated output, and no committed copy to diff against. CI regenerates from clean checkouts, so it is correct-by-construction and structurally blind to local drift — the one environment that can be wrong is the only one nobody checks.expiryin code. Trusting TTL alone leaves expired sessions valid for two days, and no test would catch it.pytest -k <pattern>exits1even when every selected test passes.-> Response[Any]. A bare-> Responsepasses decoration, mypy and import, then raisesPydanticSchemaGenerationErroron the first real request.except A, B:is valid PEP 758 on 3.14 — do not "fix" it by adding parentheses; Black targets py314 and strips them back off.mainlinedeploys to production.npm testdeletesfrontend/dist/;...DEFAULT_TABLE_PROPSis spread last so per-table overrides are silently discarded; REST APIs setdisableExecuteApiEndpointso only custom domains work.Method
Six parallel verifiers each owned specific sections and were required to cite
file:line; a separate auditor then fact-checked the rewrite and found 11 errors in it, which are fixed here. Commands were confirmed by execution rather than inference —uv run mypy,uv run pytest, and the Gradle +SMITHY_BUILD_DIRcodegen path were all actually run.Code issues found while verifying — documented, not fixed here
Worth separate follow-ups:
DeviceManager.get_devicesdoes an unpaginated full-tablescanof the auth table, so device lists truncate past 1 MB. (The scan itself is justified —UserCollectionsIndexis the only GSI in the stack — but the missing pagination is not.)grantReadData), so any write added to a Profile route fails only at runtime withAccessDeniedException; stubbed DynamoDB means tests cannot catch it.smithy/models/storage/bso.smithy:27documents BSOmodifiedas "milliseconds since epoch" where the code uses seconds; the wrong description propagates into the generated model.Docs-only change — no code, no CI impact.