finlet 0.0.1__tar.gz
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.
- finlet-0.0.1/.claude/rules/api-routes.md +41 -0
- finlet-0.0.1/.claude/rules/core-engine.md +42 -0
- finlet-0.0.1/.claude/rules/dashboard.md +37 -0
- finlet-0.0.1/.claude/rules/database.md +40 -0
- finlet-0.0.1/.claude/rules/deploy-ops.md +32 -0
- finlet-0.0.1/.claude/rules/file-ownership.md +17 -0
- finlet-0.0.1/.claude/rules/leaderboard.md +36 -0
- finlet-0.0.1/.claude/rules/marketplace.md +46 -0
- finlet-0.0.1/.claude/rules/mcp-server.md +33 -0
- finlet-0.0.1/.claude/rules/plugins.md +39 -0
- finlet-0.0.1/.claude/rules/testing.md +40 -0
- finlet-0.0.1/.claude/skills/add-order-type/SKILL.md +54 -0
- finlet-0.0.1/.claude/skills/api-conventions/SKILL.md +50 -0
- finlet-0.0.1/.claude/skills/audit/SKILL.md +483 -0
- finlet-0.0.1/.claude/skills/brainstorm/eval.md +34 -0
- finlet-0.0.1/.claude/skills/brainstorm/skill.md +162 -0
- finlet-0.0.1/.claude/skills/dashboard-conventions/SKILL.md +26 -0
- finlet-0.0.1/.claude/skills/dashboard-dev/SKILL.md +53 -0
- finlet-0.0.1/.claude/skills/db-migration/SKILL.md +69 -0
- finlet-0.0.1/.claude/skills/debate/eval.md +36 -0
- finlet-0.0.1/.claude/skills/debate/skill.md +141 -0
- finlet-0.0.1/.claude/skills/dep-audit/SKILL.md +39 -0
- finlet-0.0.1/.claude/skills/deploy/SKILL.md +51 -0
- finlet-0.0.1/.claude/skills/deploy-status/SKILL.md +36 -0
- finlet-0.0.1/.claude/skills/doc-architecture/SKILL.md +43 -0
- finlet-0.0.1/.claude/skills/exec-plan/eval.md +39 -0
- finlet-0.0.1/.claude/skills/exec-plan/skill.md +302 -0
- finlet-0.0.1/.claude/skills/explain-engine/SKILL.md +22 -0
- finlet-0.0.1/.claude/skills/finlet-conventions/SKILL.md +46 -0
- finlet-0.0.1/.claude/skills/fix-issue/SKILL.md +55 -0
- finlet-0.0.1/.claude/skills/hygiene-audit/SKILL.md +305 -0
- finlet-0.0.1/.claude/skills/incident/SKILL.md +63 -0
- finlet-0.0.1/.claude/skills/launch-review/SKILL.md +150 -0
- finlet-0.0.1/.claude/skills/new-endpoint/SKILL.md +78 -0
- finlet-0.0.1/.claude/skills/new-mcp-tool/SKILL.md +70 -0
- finlet-0.0.1/.claude/skills/new-plugin/SKILL.md +53 -0
- finlet-0.0.1/.claude/skills/new-plugin/template.py +111 -0
- finlet-0.0.1/.claude/skills/ops-runbook/SKILL.md +19 -0
- finlet-0.0.1/.claude/skills/plan-features/eval.md +35 -0
- finlet-0.0.1/.claude/skills/plan-features/skill.md +247 -0
- finlet-0.0.1/.claude/skills/plugin-conventions/SKILL.md +66 -0
- finlet-0.0.1/.claude/skills/plugin-health/SKILL.md +42 -0
- finlet-0.0.1/.claude/skills/review-pr/SKILL.md +53 -0
- finlet-0.0.1/.claude/skills/test-all/SKILL.md +52 -0
- finlet-0.0.1/.claude/skills/test-api/SKILL.md +22 -0
- finlet-0.0.1/.claude/skills/test-engine/SKILL.md +22 -0
- finlet-0.0.1/.claude/skills/test-leaderboard/SKILL.md +17 -0
- finlet-0.0.1/.claude/skills/ui-flow/SKILL.md +218 -0
- finlet-0.0.1/.claude/skills/ui-flow-mcp/SKILL.md +804 -0
- finlet-0.0.1/.claudeignore +5 -0
- finlet-0.0.1/.github/workflows/deploy.yml +231 -0
- finlet-0.0.1/.github/workflows/ingest-daily.yml +107 -0
- finlet-0.0.1/.github/workflows/ingest-prices.yml +58 -0
- finlet-0.0.1/.github/workflows/pypi-publish.yml +126 -0
- finlet-0.0.1/.gitignore +49 -0
- finlet-0.0.1/.hypothesis/constants/0026488b3886b292 +4 -0
- finlet-0.0.1/.hypothesis/constants/018dddbac9502c11 +4 -0
- finlet-0.0.1/.hypothesis/constants/01b7c4d7b8f33b82 +4 -0
- finlet-0.0.1/.hypothesis/constants/01bd0c3e9b7cf3c4 +4 -0
- finlet-0.0.1/.hypothesis/constants/0251270e0ccee68a +4 -0
- finlet-0.0.1/.hypothesis/constants/027671957e5bb614 +4 -0
- finlet-0.0.1/.hypothesis/constants/0319ab1dfcf60986 +4 -0
- finlet-0.0.1/.hypothesis/constants/04ccb47a36103605 +4 -0
- finlet-0.0.1/.hypothesis/constants/05b65d3860f0fb2d +4 -0
- finlet-0.0.1/.hypothesis/constants/070b88979336d33e +4 -0
- finlet-0.0.1/.hypothesis/constants/0779e2926351bcc8 +4 -0
- finlet-0.0.1/.hypothesis/constants/07d6a22a03d142fa +4 -0
- finlet-0.0.1/.hypothesis/constants/0854fd3d9f6133b7 +4 -0
- finlet-0.0.1/.hypothesis/constants/0865cd8c9ccec950 +4 -0
- finlet-0.0.1/.hypothesis/constants/0901a76b2c9c5b69 +4 -0
- finlet-0.0.1/.hypothesis/constants/090a3bc43e9ffb6f +4 -0
- finlet-0.0.1/.hypothesis/constants/0a8217a66462ed9c +4 -0
- finlet-0.0.1/.hypothesis/constants/0aff5f4a12456575 +4 -0
- finlet-0.0.1/.hypothesis/constants/0c56c79af6dc7a3e +4 -0
- finlet-0.0.1/.hypothesis/constants/0d33d4e997451efe +4 -0
- finlet-0.0.1/.hypothesis/constants/0edd201537724401 +4 -0
- finlet-0.0.1/.hypothesis/constants/0f18ffcd932c5c7b +4 -0
- finlet-0.0.1/.hypothesis/constants/0f446ab0dd69c640 +4 -0
- finlet-0.0.1/.hypothesis/constants/0fd4fd8ddf35bb02 +4 -0
- finlet-0.0.1/.hypothesis/constants/10a739ba1f8c80c6 +4 -0
- finlet-0.0.1/.hypothesis/constants/10a92c521f520329 +4 -0
- finlet-0.0.1/.hypothesis/constants/10faa2bc8e50cac9 +4 -0
- finlet-0.0.1/.hypothesis/constants/112e50a22d78623a +4 -0
- finlet-0.0.1/.hypothesis/constants/1382e804f17245fa +4 -0
- finlet-0.0.1/.hypothesis/constants/14446e905380b027 +4 -0
- finlet-0.0.1/.hypothesis/constants/148efc7f4ceaa0f9 +4 -0
- finlet-0.0.1/.hypothesis/constants/15e52623cacfa61c +4 -0
- finlet-0.0.1/.hypothesis/constants/1617a9a09948393f +4 -0
- finlet-0.0.1/.hypothesis/constants/1704b0e72c369686 +4 -0
- finlet-0.0.1/.hypothesis/constants/1730c163a7d0beb5 +4 -0
- finlet-0.0.1/.hypothesis/constants/18d0867b4cb62eab +4 -0
- finlet-0.0.1/.hypothesis/constants/18eba934185b70d3 +4 -0
- finlet-0.0.1/.hypothesis/constants/1aac09d4dd8d5039 +4 -0
- finlet-0.0.1/.hypothesis/constants/1abd17b5430ed4cc +4 -0
- finlet-0.0.1/.hypothesis/constants/1acc6335e3023503 +4 -0
- finlet-0.0.1/.hypothesis/constants/1c77a3aef7c18877 +4 -0
- finlet-0.0.1/.hypothesis/constants/1c83eb1498916c4d +4 -0
- finlet-0.0.1/.hypothesis/constants/1cd6334c119e790c +4 -0
- finlet-0.0.1/.hypothesis/constants/1ce492fad1bb1bff +4 -0
- finlet-0.0.1/.hypothesis/constants/1e1803a8e8857c8f +4 -0
- finlet-0.0.1/.hypothesis/constants/1fa374f9e4c0835b +4 -0
- finlet-0.0.1/.hypothesis/constants/20dd09f33c601b11 +4 -0
- finlet-0.0.1/.hypothesis/constants/20e8e8efb308c6b7 +4 -0
- finlet-0.0.1/.hypothesis/constants/210dbcf7554324b8 +4 -0
- finlet-0.0.1/.hypothesis/constants/213ead04ca481b7e +4 -0
- finlet-0.0.1/.hypothesis/constants/2181e7249df4b5f9 +4 -0
- finlet-0.0.1/.hypothesis/constants/21c58ddd6be42eaf +4 -0
- finlet-0.0.1/.hypothesis/constants/224a6a420d7e62ec +4 -0
- finlet-0.0.1/.hypothesis/constants/22b2088f6f979bc6 +4 -0
- finlet-0.0.1/.hypothesis/constants/230ccb5245968257 +4 -0
- finlet-0.0.1/.hypothesis/constants/2368aa4004093377 +4 -0
- finlet-0.0.1/.hypothesis/constants/23a7c00a0fd2d8d9 +4 -0
- finlet-0.0.1/.hypothesis/constants/23aca454ba0c9e37 +4 -0
- finlet-0.0.1/.hypothesis/constants/2415119ac91e7eb4 +4 -0
- finlet-0.0.1/.hypothesis/constants/245c7589bc89d31c +4 -0
- finlet-0.0.1/.hypothesis/constants/24aab0f80776ca3a +4 -0
- finlet-0.0.1/.hypothesis/constants/25bf0f00ca6117ba +4 -0
- finlet-0.0.1/.hypothesis/constants/275ecb5fa14af4d6 +4 -0
- finlet-0.0.1/.hypothesis/constants/2851bebf700e65ed +4 -0
- finlet-0.0.1/.hypothesis/constants/28ce8ad06a05a839 +4 -0
- finlet-0.0.1/.hypothesis/constants/291e584dfc7b3c67 +4 -0
- finlet-0.0.1/.hypothesis/constants/29859b3decc973fb +4 -0
- finlet-0.0.1/.hypothesis/constants/29998a4e8ba95be0 +4 -0
- finlet-0.0.1/.hypothesis/constants/2a82ff3c0819f0ad +4 -0
- finlet-0.0.1/.hypothesis/constants/2a91462d642f1c5f +4 -0
- finlet-0.0.1/.hypothesis/constants/2b5160418840c2c5 +4 -0
- finlet-0.0.1/.hypothesis/constants/2c925c96f80b346d +4 -0
- finlet-0.0.1/.hypothesis/constants/2dd434375eedf3af +4 -0
- finlet-0.0.1/.hypothesis/constants/30199006474de16a +4 -0
- finlet-0.0.1/.hypothesis/constants/30c2c54f3e78235c +4 -0
- finlet-0.0.1/.hypothesis/constants/3200eaa2972d281d +4 -0
- finlet-0.0.1/.hypothesis/constants/329324d012913d90 +4 -0
- finlet-0.0.1/.hypothesis/constants/33725d4bc97943da +4 -0
- finlet-0.0.1/.hypothesis/constants/34689365256bb340 +4 -0
- finlet-0.0.1/.hypothesis/constants/34e2b92df2c5e903 +4 -0
- finlet-0.0.1/.hypothesis/constants/34e9855e643992df +4 -0
- finlet-0.0.1/.hypothesis/constants/34f1de95d94a18bb +4 -0
- finlet-0.0.1/.hypothesis/constants/34fe752699c4852e +4 -0
- finlet-0.0.1/.hypothesis/constants/35bdaebcb3cc05dd +4 -0
- finlet-0.0.1/.hypothesis/constants/36b573aa637f23ef +4 -0
- finlet-0.0.1/.hypothesis/constants/3803a7865d123769 +4 -0
- finlet-0.0.1/.hypothesis/constants/3887fe9b4bd79627 +4 -0
- finlet-0.0.1/.hypothesis/constants/38fb751046fb9440 +4 -0
- finlet-0.0.1/.hypothesis/constants/3918b10286b4472d +4 -0
- finlet-0.0.1/.hypothesis/constants/39508bbc90cf920c +4 -0
- finlet-0.0.1/.hypothesis/constants/3a9973dfe6a040e8 +4 -0
- finlet-0.0.1/.hypothesis/constants/3b8942b949793f8e +4 -0
- finlet-0.0.1/.hypothesis/constants/3c16c53699ed324f +4 -0
- finlet-0.0.1/.hypothesis/constants/3d48765e559278ca +4 -0
- finlet-0.0.1/.hypothesis/constants/3e23f6cf9f2a17f9 +4 -0
- finlet-0.0.1/.hypothesis/constants/3e46af599dafcb7a +4 -0
- finlet-0.0.1/.hypothesis/constants/3e47707885c1b671 +4 -0
- finlet-0.0.1/.hypothesis/constants/3ed457bb7d4ca8f4 +4 -0
- finlet-0.0.1/.hypothesis/constants/3f45ebaf01e9259e +4 -0
- finlet-0.0.1/.hypothesis/constants/410dc405a621a4c8 +4 -0
- finlet-0.0.1/.hypothesis/constants/4154740ffabe283a +4 -0
- finlet-0.0.1/.hypothesis/constants/41b40013b6271def +4 -0
- finlet-0.0.1/.hypothesis/constants/41c1a3a62a7a482f +4 -0
- finlet-0.0.1/.hypothesis/constants/422fcf046e1ea121 +4 -0
- finlet-0.0.1/.hypothesis/constants/4318a14ff97c5f3d +4 -0
- finlet-0.0.1/.hypothesis/constants/43a67e26a72477b5 +4 -0
- finlet-0.0.1/.hypothesis/constants/440c2faad879f402 +4 -0
- finlet-0.0.1/.hypothesis/constants/44f6f00310d19d57 +4 -0
- finlet-0.0.1/.hypothesis/constants/451669222330c37a +4 -0
- finlet-0.0.1/.hypothesis/constants/45e01253b2ce283c +4 -0
- finlet-0.0.1/.hypothesis/constants/46531c93e0639941 +4 -0
- finlet-0.0.1/.hypothesis/constants/46b9faedaa2f7d40 +4 -0
- finlet-0.0.1/.hypothesis/constants/4831095bd7bb7797 +4 -0
- finlet-0.0.1/.hypothesis/constants/4890c2e126bfe794 +4 -0
- finlet-0.0.1/.hypothesis/constants/48ddb90bb1b22692 +4 -0
- finlet-0.0.1/.hypothesis/constants/4914d3d2727c5eca +4 -0
- finlet-0.0.1/.hypothesis/constants/4b2b4135f29d522a +4 -0
- finlet-0.0.1/.hypothesis/constants/4b3953025a120a3b +4 -0
- finlet-0.0.1/.hypothesis/constants/4b954a82c1d3dff5 +4 -0
- finlet-0.0.1/.hypothesis/constants/4c15614705534b85 +4 -0
- finlet-0.0.1/.hypothesis/constants/4c81bfa4587dd812 +4 -0
- finlet-0.0.1/.hypothesis/constants/4c85c75892555b5b +4 -0
- finlet-0.0.1/.hypothesis/constants/4ce9d212fbe07d19 +4 -0
- finlet-0.0.1/.hypothesis/constants/4cf99ca2c4189b47 +4 -0
- finlet-0.0.1/.hypothesis/constants/4d05cddcbbdf5452 +4 -0
- finlet-0.0.1/.hypothesis/constants/4e203778ee7e452b +4 -0
- finlet-0.0.1/.hypothesis/constants/4f183f02aac48037 +4 -0
- finlet-0.0.1/.hypothesis/constants/5049aa5ba5580619 +4 -0
- finlet-0.0.1/.hypothesis/constants/508becf687ff7e0e +4 -0
- finlet-0.0.1/.hypothesis/constants/50b791c150ee298a +4 -0
- finlet-0.0.1/.hypothesis/constants/50fd1881412ae221 +4 -0
- finlet-0.0.1/.hypothesis/constants/52941ce0ee646441 +4 -0
- finlet-0.0.1/.hypothesis/constants/52a22a627b37d616 +4 -0
- finlet-0.0.1/.hypothesis/constants/52ae9f2c5ab163a4 +4 -0
- finlet-0.0.1/.hypothesis/constants/52c983759dbcca19 +4 -0
- finlet-0.0.1/.hypothesis/constants/5313ecb0ed2d194e +4 -0
- finlet-0.0.1/.hypothesis/constants/545984445d5f221e +4 -0
- finlet-0.0.1/.hypothesis/constants/553f796f8fea20b4 +4 -0
- finlet-0.0.1/.hypothesis/constants/55a15e754bb7b8d9 +4 -0
- finlet-0.0.1/.hypothesis/constants/56adf5f382c0cf3e +4 -0
- finlet-0.0.1/.hypothesis/constants/56ba0ddc53083b9c +4 -0
- finlet-0.0.1/.hypothesis/constants/56fbbdc763722ee7 +4 -0
- finlet-0.0.1/.hypothesis/constants/56ff3ba75c5c9c51 +4 -0
- finlet-0.0.1/.hypothesis/constants/5735df66296deeb2 +4 -0
- finlet-0.0.1/.hypothesis/constants/57889d6ebc11fb8c +4 -0
- finlet-0.0.1/.hypothesis/constants/57fbf504801db54b +4 -0
- finlet-0.0.1/.hypothesis/constants/5838a050438834b0 +4 -0
- finlet-0.0.1/.hypothesis/constants/58e2c5dfef7d0927 +4 -0
- finlet-0.0.1/.hypothesis/constants/590118a7a8c18df7 +4 -0
- finlet-0.0.1/.hypothesis/constants/5a4a58550839deee +4 -0
- finlet-0.0.1/.hypothesis/constants/5abab1e0f48b6bfe +4 -0
- finlet-0.0.1/.hypothesis/constants/5b2c0fb37bbe68af +4 -0
- finlet-0.0.1/.hypothesis/constants/5c25e56003e57663 +4 -0
- finlet-0.0.1/.hypothesis/constants/5d4f5e90a8a20cd7 +4 -0
- finlet-0.0.1/.hypothesis/constants/5eeef3480766ba63 +4 -0
- finlet-0.0.1/.hypothesis/constants/5f08a4847069c433 +4 -0
- finlet-0.0.1/.hypothesis/constants/5f1192bc51300360 +4 -0
- finlet-0.0.1/.hypothesis/constants/5f2d0c323b18a500 +4 -0
- finlet-0.0.1/.hypothesis/constants/6064d42a769b5fdd +4 -0
- finlet-0.0.1/.hypothesis/constants/6386cc18eaa408be +4 -0
- finlet-0.0.1/.hypothesis/constants/63f40187705e94a5 +4 -0
- finlet-0.0.1/.hypothesis/constants/64073ebace01af93 +4 -0
- finlet-0.0.1/.hypothesis/constants/649898c8c310da38 +4 -0
- finlet-0.0.1/.hypothesis/constants/64fe3626e9e8657d +4 -0
- finlet-0.0.1/.hypothesis/constants/65151cdc99cb761d +4 -0
- finlet-0.0.1/.hypothesis/constants/6527bf3603e8ec26 +4 -0
- finlet-0.0.1/.hypothesis/constants/6533c25782c3dfbd +4 -0
- finlet-0.0.1/.hypothesis/constants/6542b70b848657a1 +4 -0
- finlet-0.0.1/.hypothesis/constants/65531e2e329b9952 +4 -0
- finlet-0.0.1/.hypothesis/constants/65d7f47dd2a121fe +4 -0
- finlet-0.0.1/.hypothesis/constants/694e4d58f752c81d +4 -0
- finlet-0.0.1/.hypothesis/constants/6a458ade6ccdf3c2 +4 -0
- finlet-0.0.1/.hypothesis/constants/6a5509d05930a347 +4 -0
- finlet-0.0.1/.hypothesis/constants/6ac577df908ecf57 +4 -0
- finlet-0.0.1/.hypothesis/constants/6ae28fd889c2f91c +4 -0
- finlet-0.0.1/.hypothesis/constants/6b8c553a1a718edb +4 -0
- finlet-0.0.1/.hypothesis/constants/6c18402ee90e5f23 +4 -0
- finlet-0.0.1/.hypothesis/constants/6d5580ca3161c6bb +4 -0
- finlet-0.0.1/.hypothesis/constants/6eb0e6c9a5cf254c +4 -0
- finlet-0.0.1/.hypothesis/constants/6f34bfbd703e1a67 +4 -0
- finlet-0.0.1/.hypothesis/constants/6f53694082112086 +4 -0
- finlet-0.0.1/.hypothesis/constants/7109f41d3d48ed85 +4 -0
- finlet-0.0.1/.hypothesis/constants/7186372c7f4cc96a +4 -0
- finlet-0.0.1/.hypothesis/constants/7198f18e19c69997 +4 -0
- finlet-0.0.1/.hypothesis/constants/71e1ede20548e604 +4 -0
- finlet-0.0.1/.hypothesis/constants/71ed7ec9d4e29fec +4 -0
- finlet-0.0.1/.hypothesis/constants/74da00357c014ab8 +4 -0
- finlet-0.0.1/.hypothesis/constants/76284ac1bc68f503 +4 -0
- finlet-0.0.1/.hypothesis/constants/7649a152910bae4a +4 -0
- finlet-0.0.1/.hypothesis/constants/76ab33585e671f0b +4 -0
- finlet-0.0.1/.hypothesis/constants/770b248b6fd84140 +4 -0
- finlet-0.0.1/.hypothesis/constants/77c7762a8edc4192 +4 -0
- finlet-0.0.1/.hypothesis/constants/77e8899a45ab4cfb +4 -0
- finlet-0.0.1/.hypothesis/constants/7837c0f349b50c8f +4 -0
- finlet-0.0.1/.hypothesis/constants/7870da3266f76340 +4 -0
- finlet-0.0.1/.hypothesis/constants/794c427941feb188 +4 -0
- finlet-0.0.1/.hypothesis/constants/7961e5230a78aa3b +4 -0
- finlet-0.0.1/.hypothesis/constants/79809e2f66e8b290 +4 -0
- finlet-0.0.1/.hypothesis/constants/79998a39f21ab427 +4 -0
- finlet-0.0.1/.hypothesis/constants/7a1a7fceeb23e400 +4 -0
- finlet-0.0.1/.hypothesis/constants/7a31c751a4c6ab18 +4 -0
- finlet-0.0.1/.hypothesis/constants/7ac2f0bcd0a690a5 +4 -0
- finlet-0.0.1/.hypothesis/constants/7cb1aa0ba578f78d +4 -0
- finlet-0.0.1/.hypothesis/constants/7d1fe85d709b9c27 +4 -0
- finlet-0.0.1/.hypothesis/constants/7d5452bfbb045ba9 +4 -0
- finlet-0.0.1/.hypothesis/constants/7ed6581739c68c9f +4 -0
- finlet-0.0.1/.hypothesis/constants/7f136a3f535167fc +4 -0
- finlet-0.0.1/.hypothesis/constants/7f8af675db341fa5 +4 -0
- finlet-0.0.1/.hypothesis/constants/7fc0adaa33fa7f3d +4 -0
- finlet-0.0.1/.hypothesis/constants/819f628ac24ce71b +4 -0
- finlet-0.0.1/.hypothesis/constants/81f46a6bdc2a5bc2 +4 -0
- finlet-0.0.1/.hypothesis/constants/828d0513249b4edf +4 -0
- finlet-0.0.1/.hypothesis/constants/82abcdafafe2d943 +4 -0
- finlet-0.0.1/.hypothesis/constants/83ef3bb0d28664ba +4 -0
- finlet-0.0.1/.hypothesis/constants/84c8383fb79ce984 +4 -0
- finlet-0.0.1/.hypothesis/constants/861ae640fd0bcfde +4 -0
- finlet-0.0.1/.hypothesis/constants/867bed6532ab1e83 +4 -0
- finlet-0.0.1/.hypothesis/constants/86ba50d226564088 +4 -0
- finlet-0.0.1/.hypothesis/constants/870edbaf033f917e +4 -0
- finlet-0.0.1/.hypothesis/constants/8790f7019564f234 +4 -0
- finlet-0.0.1/.hypothesis/constants/8859f71b0a3e2153 +4 -0
- finlet-0.0.1/.hypothesis/constants/89ace99dce35702e +4 -0
- finlet-0.0.1/.hypothesis/constants/8a5c998f323f32bf +4 -0
- finlet-0.0.1/.hypothesis/constants/8a663a179f7b2b32 +4 -0
- finlet-0.0.1/.hypothesis/constants/8a9e5d0b6bb2273f +4 -0
- finlet-0.0.1/.hypothesis/constants/8add43fc5a1458ef +4 -0
- finlet-0.0.1/.hypothesis/constants/8b56ac1be144f039 +4 -0
- finlet-0.0.1/.hypothesis/constants/8bcc60b7efa25fae +4 -0
- finlet-0.0.1/.hypothesis/constants/8cdef906b734ee4d +4 -0
- finlet-0.0.1/.hypothesis/constants/8d57f461c497e955 +4 -0
- finlet-0.0.1/.hypothesis/constants/923d38d4dc535d71 +4 -0
- finlet-0.0.1/.hypothesis/constants/92d9a25105a90285 +4 -0
- finlet-0.0.1/.hypothesis/constants/92ecde74afb3e4b1 +4 -0
- finlet-0.0.1/.hypothesis/constants/930220212648369a +4 -0
- finlet-0.0.1/.hypothesis/constants/93163db89fe6c7ee +4 -0
- finlet-0.0.1/.hypothesis/constants/949542dc6a9d27ea +4 -0
- finlet-0.0.1/.hypothesis/constants/94d3acb7fbbc1af8 +4 -0
- finlet-0.0.1/.hypothesis/constants/976212675f18c0cc +4 -0
- finlet-0.0.1/.hypothesis/constants/97eb2ac6577bc37d +4 -0
- finlet-0.0.1/.hypothesis/constants/984b283d24efc676 +4 -0
- finlet-0.0.1/.hypothesis/constants/9974f23debd8983d +4 -0
- finlet-0.0.1/.hypothesis/constants/99bd7dca07ec5306 +4 -0
- finlet-0.0.1/.hypothesis/constants/9b6201fc62387024 +4 -0
- finlet-0.0.1/.hypothesis/constants/9b756ad30339d0bb +4 -0
- finlet-0.0.1/.hypothesis/constants/9c1e14d86e563651 +4 -0
- finlet-0.0.1/.hypothesis/constants/9c8f8a2943259e65 +4 -0
- finlet-0.0.1/.hypothesis/constants/9d3faf6774987167 +4 -0
- finlet-0.0.1/.hypothesis/constants/9e17023358573d14 +4 -0
- finlet-0.0.1/.hypothesis/constants/9e92d01e171ad006 +4 -0
- finlet-0.0.1/.hypothesis/constants/9ee15969b4ac8f20 +4 -0
- finlet-0.0.1/.hypothesis/constants/9f62a5f0c7b8c6fc +4 -0
- finlet-0.0.1/.hypothesis/constants/9f8a672ad4fac03b +4 -0
- finlet-0.0.1/.hypothesis/constants/a056a8754cfb24c9 +4 -0
- finlet-0.0.1/.hypothesis/constants/a067ce1ed1c296c5 +4 -0
- finlet-0.0.1/.hypothesis/constants/a06c950c72d0f01e +4 -0
- finlet-0.0.1/.hypothesis/constants/a14b437841d5708f +4 -0
- finlet-0.0.1/.hypothesis/constants/a183837cae1fb916 +4 -0
- finlet-0.0.1/.hypothesis/constants/a1c07de6cf565d63 +4 -0
- finlet-0.0.1/.hypothesis/constants/a313d27afc72be5d +4 -0
- finlet-0.0.1/.hypothesis/constants/a40189342c946aeb +4 -0
- finlet-0.0.1/.hypothesis/constants/a586325ac986452e +4 -0
- finlet-0.0.1/.hypothesis/constants/a595ede5bde04df8 +4 -0
- finlet-0.0.1/.hypothesis/constants/a5c16b4aeae63872 +4 -0
- finlet-0.0.1/.hypothesis/constants/a6402a32466cd9be +4 -0
- finlet-0.0.1/.hypothesis/constants/a67aa3db2f5576c4 +4 -0
- finlet-0.0.1/.hypothesis/constants/a7df4f9ddadd0c70 +4 -0
- finlet-0.0.1/.hypothesis/constants/a83c90387715ff77 +4 -0
- finlet-0.0.1/.hypothesis/constants/a8610f97aea74998 +4 -0
- finlet-0.0.1/.hypothesis/constants/a8b2d38168f6d772 +4 -0
- finlet-0.0.1/.hypothesis/constants/a9122442374f2213 +4 -0
- finlet-0.0.1/.hypothesis/constants/aa80488de8d14841 +4 -0
- finlet-0.0.1/.hypothesis/constants/ab7e635e611fcdf9 +4 -0
- finlet-0.0.1/.hypothesis/constants/abcba78382304330 +4 -0
- finlet-0.0.1/.hypothesis/constants/abd831eaf66bd6da +4 -0
- finlet-0.0.1/.hypothesis/constants/acec9f62bfffa69c +4 -0
- finlet-0.0.1/.hypothesis/constants/ad8eb498b53c6a7f +4 -0
- finlet-0.0.1/.hypothesis/constants/ae497b6c802f212f +4 -0
- finlet-0.0.1/.hypothesis/constants/ae9a6dfaad1e27c6 +4 -0
- finlet-0.0.1/.hypothesis/constants/aef0b23908601c47 +4 -0
- finlet-0.0.1/.hypothesis/constants/b0699f22bb21e0cd +4 -0
- finlet-0.0.1/.hypothesis/constants/b091d2933120ac6c +4 -0
- finlet-0.0.1/.hypothesis/constants/b0daf59b8d5104c3 +4 -0
- finlet-0.0.1/.hypothesis/constants/b163dab0a10f18f9 +4 -0
- finlet-0.0.1/.hypothesis/constants/b1919ea3fb5224de +4 -0
- finlet-0.0.1/.hypothesis/constants/b22e06d40b321601 +4 -0
- finlet-0.0.1/.hypothesis/constants/b2b2f28f4a44bce4 +4 -0
- finlet-0.0.1/.hypothesis/constants/b2e7a677bd2f8fa0 +4 -0
- finlet-0.0.1/.hypothesis/constants/b305b6fee7ef5900 +4 -0
- finlet-0.0.1/.hypothesis/constants/b49c0ba620780ae8 +4 -0
- finlet-0.0.1/.hypothesis/constants/b68c21e267580fad +4 -0
- finlet-0.0.1/.hypothesis/constants/b6a00bc5075c9d55 +4 -0
- finlet-0.0.1/.hypothesis/constants/b72cd768b996df59 +4 -0
- finlet-0.0.1/.hypothesis/constants/b7339645e3441027 +4 -0
- finlet-0.0.1/.hypothesis/constants/b833bda0970d4443 +4 -0
- finlet-0.0.1/.hypothesis/constants/b845a513da41c06b +4 -0
- finlet-0.0.1/.hypothesis/constants/b89bcd3933b6aeba +4 -0
- finlet-0.0.1/.hypothesis/constants/b8c298b8aff733d5 +4 -0
- finlet-0.0.1/.hypothesis/constants/b9aee8b9d3049c88 +4 -0
- finlet-0.0.1/.hypothesis/constants/ba463733870df707 +4 -0
- finlet-0.0.1/.hypothesis/constants/bb1b4971358ce8db +4 -0
- finlet-0.0.1/.hypothesis/constants/bc0cd0bc25842398 +4 -0
- finlet-0.0.1/.hypothesis/constants/bc487b66c6490a7f +4 -0
- finlet-0.0.1/.hypothesis/constants/bc4abc0adbd2d2f4 +4 -0
- finlet-0.0.1/.hypothesis/constants/bce7d77dcc048d98 +4 -0
- finlet-0.0.1/.hypothesis/constants/bd5a63529eb1a7ce +4 -0
- finlet-0.0.1/.hypothesis/constants/bdd63180aad4ca73 +4 -0
- finlet-0.0.1/.hypothesis/constants/bec4ffa2221f0e08 +4 -0
- finlet-0.0.1/.hypothesis/constants/bef670571404a3ea +4 -0
- finlet-0.0.1/.hypothesis/constants/c0caffedc2dbe2cd +4 -0
- finlet-0.0.1/.hypothesis/constants/c1b172785defb964 +4 -0
- finlet-0.0.1/.hypothesis/constants/c1d3fabb0ee0019b +4 -0
- finlet-0.0.1/.hypothesis/constants/c278c167ec263bad +4 -0
- finlet-0.0.1/.hypothesis/constants/c3da050fb6cfb64b +4 -0
- finlet-0.0.1/.hypothesis/constants/c54d5645769abbfd +4 -0
- finlet-0.0.1/.hypothesis/constants/c5e7a388a66595f1 +4 -0
- finlet-0.0.1/.hypothesis/constants/c6a78fd9569568e4 +4 -0
- finlet-0.0.1/.hypothesis/constants/c708152209fc3b95 +4 -0
- finlet-0.0.1/.hypothesis/constants/c7d31eae36e869d4 +4 -0
- finlet-0.0.1/.hypothesis/constants/c805893a04a35c59 +4 -0
- finlet-0.0.1/.hypothesis/constants/c814308410d7fd12 +4 -0
- finlet-0.0.1/.hypothesis/constants/cb51ccebbfb9e1a5 +4 -0
- finlet-0.0.1/.hypothesis/constants/cba0f9982467eb01 +4 -0
- finlet-0.0.1/.hypothesis/constants/cbd472f8d1e6f0de +4 -0
- finlet-0.0.1/.hypothesis/constants/cd7b495071f1758f +4 -0
- finlet-0.0.1/.hypothesis/constants/cdced47911c78a57 +4 -0
- finlet-0.0.1/.hypothesis/constants/ce8fae0a1b8549db +4 -0
- finlet-0.0.1/.hypothesis/constants/cf0a241e11b7295d +4 -0
- finlet-0.0.1/.hypothesis/constants/cf0bf6f2aba8a7bf +4 -0
- finlet-0.0.1/.hypothesis/constants/cf6ce85de703d90c +4 -0
- finlet-0.0.1/.hypothesis/constants/d0630e4f98dc0653 +4 -0
- finlet-0.0.1/.hypothesis/constants/d23c2f96e6944ac5 +4 -0
- finlet-0.0.1/.hypothesis/constants/d3baa47206764f98 +4 -0
- finlet-0.0.1/.hypothesis/constants/d493c5bc0a695cbe +4 -0
- finlet-0.0.1/.hypothesis/constants/d624b129575d4fea +4 -0
- finlet-0.0.1/.hypothesis/constants/d65d5870f282e912 +4 -0
- finlet-0.0.1/.hypothesis/constants/d74cdb83714dc3bd +4 -0
- finlet-0.0.1/.hypothesis/constants/d821587dd0bf094d +4 -0
- finlet-0.0.1/.hypothesis/constants/d83fc29f76584ccc +4 -0
- finlet-0.0.1/.hypothesis/constants/d89d6795c3b6ce60 +4 -0
- finlet-0.0.1/.hypothesis/constants/d98a5fa8be97b25a +4 -0
- finlet-0.0.1/.hypothesis/constants/d9e739ab71cf736a +4 -0
- finlet-0.0.1/.hypothesis/constants/da1da7d3f7a180d6 +4 -0
- finlet-0.0.1/.hypothesis/constants/da39a3ee5e6b4b0d +4 -0
- finlet-0.0.1/.hypothesis/constants/dba0872ef327da18 +4 -0
- finlet-0.0.1/.hypothesis/constants/dc2d04ff4e15a2f9 +4 -0
- finlet-0.0.1/.hypothesis/constants/dccab7e8da1945ab +4 -0
- finlet-0.0.1/.hypothesis/constants/dcf3c876bd1bb42a +4 -0
- finlet-0.0.1/.hypothesis/constants/dd71b033c0c6a41a +4 -0
- finlet-0.0.1/.hypothesis/constants/dded8b04fa283b51 +4 -0
- finlet-0.0.1/.hypothesis/constants/de1a6c0bfbc0a5c5 +4 -0
- finlet-0.0.1/.hypothesis/constants/dea4b00ea72bd9e2 +4 -0
- finlet-0.0.1/.hypothesis/constants/e07b74cc1e478acb +4 -0
- finlet-0.0.1/.hypothesis/constants/e1ab4e317ac72865 +4 -0
- finlet-0.0.1/.hypothesis/constants/e259c46a155f44c5 +4 -0
- finlet-0.0.1/.hypothesis/constants/e2a9a1bfb042b77c +4 -0
- finlet-0.0.1/.hypothesis/constants/e3b81b9b68684f22 +4 -0
- finlet-0.0.1/.hypothesis/constants/e4ca392b8c3fe892 +4 -0
- finlet-0.0.1/.hypothesis/constants/e54403450d362ad1 +4 -0
- finlet-0.0.1/.hypothesis/constants/e6065259662bb52d +4 -0
- finlet-0.0.1/.hypothesis/constants/e699371218c02842 +4 -0
- finlet-0.0.1/.hypothesis/constants/e6a32c639c49556f +4 -0
- finlet-0.0.1/.hypothesis/constants/e6eeeb4684d75ac7 +4 -0
- finlet-0.0.1/.hypothesis/constants/e74da1792ef5ba6e +4 -0
- finlet-0.0.1/.hypothesis/constants/e96272f9631e08f8 +4 -0
- finlet-0.0.1/.hypothesis/constants/e96698fc6f421319 +4 -0
- finlet-0.0.1/.hypothesis/constants/e9fb4b4be3a9de2c +4 -0
- finlet-0.0.1/.hypothesis/constants/ea7e606bafcc3634 +4 -0
- finlet-0.0.1/.hypothesis/constants/eb6c1f427254d770 +4 -0
- finlet-0.0.1/.hypothesis/constants/ec19df4e7c62781c +4 -0
- finlet-0.0.1/.hypothesis/constants/ecc5734384f5ebbf +4 -0
- finlet-0.0.1/.hypothesis/constants/ed1da574a811c0ae +4 -0
- finlet-0.0.1/.hypothesis/constants/ed24874cbb8ce2c7 +4 -0
- finlet-0.0.1/.hypothesis/constants/ed7e4ecbd4f9c4b1 +4 -0
- finlet-0.0.1/.hypothesis/constants/eda43243bac720f3 +4 -0
- finlet-0.0.1/.hypothesis/constants/edad392919c04bbf +4 -0
- finlet-0.0.1/.hypothesis/constants/eee49c4d2a621759 +4 -0
- finlet-0.0.1/.hypothesis/constants/f03ac195336dc42e +4 -0
- finlet-0.0.1/.hypothesis/constants/f11d87acce513236 +4 -0
- finlet-0.0.1/.hypothesis/constants/f13044cdca416223 +4 -0
- finlet-0.0.1/.hypothesis/constants/f27a6809782da092 +4 -0
- finlet-0.0.1/.hypothesis/constants/f27d15dd52309d20 +4 -0
- finlet-0.0.1/.hypothesis/constants/f313437699024159 +4 -0
- finlet-0.0.1/.hypothesis/constants/f3a2cd00c4ed72e0 +4 -0
- finlet-0.0.1/.hypothesis/constants/f3c9d0b7eb5a5d38 +4 -0
- finlet-0.0.1/.hypothesis/constants/f4421bd16a91c240 +4 -0
- finlet-0.0.1/.hypothesis/constants/f44ade6e119444e2 +4 -0
- finlet-0.0.1/.hypothesis/constants/f44fcd8b8ae49942 +4 -0
- finlet-0.0.1/.hypothesis/constants/f4dce430a1547ab8 +4 -0
- finlet-0.0.1/.hypothesis/constants/f5d8553259f12920 +4 -0
- finlet-0.0.1/.hypothesis/constants/f67c1715f13db398 +4 -0
- finlet-0.0.1/.hypothesis/constants/f6b3d77d626f31bb +4 -0
- finlet-0.0.1/.hypothesis/constants/f6eec1dbb8de1b44 +4 -0
- finlet-0.0.1/.hypothesis/constants/f8aa606b71f4651b +4 -0
- finlet-0.0.1/.hypothesis/constants/f9d7115a611b1a13 +4 -0
- finlet-0.0.1/.hypothesis/constants/fab9bea975cb676d +4 -0
- finlet-0.0.1/.hypothesis/constants/fd9487dedf0d4598 +4 -0
- finlet-0.0.1/.hypothesis/constants/fdc4839e370beec3 +4 -0
- finlet-0.0.1/.hypothesis/constants/ff085a4f6cde3044 +4 -0
- finlet-0.0.1/.hypothesis/constants/ff306f079a4374fa +4 -0
- finlet-0.0.1/.hypothesis/constants/ff7c7c9a80ca5b77 +4 -0
- finlet-0.0.1/.mcp.json +8 -0
- finlet-0.0.1/.semgrepconfig.yml +41 -0
- finlet-0.0.1/=3.6 +1 -0
- finlet-0.0.1/=8.0 +1 -0
- finlet-0.0.1/CLAUDE.md +92 -0
- finlet-0.0.1/LICENSE +17 -0
- finlet-0.0.1/PKG-INFO +453 -0
- finlet-0.0.1/README.md +387 -0
- finlet-0.0.1/THIRD-PARTY-NOTICES +403 -0
- finlet-0.0.1/alembic.ini +45 -0
- finlet-0.0.1/audit_structure_report.md +340 -0
- finlet-0.0.1/dashboard/agent-guide.css +368 -0
- finlet-0.0.1/dashboard/agent-guide.html +488 -0
- finlet-0.0.1/dashboard/api-utils.js +407 -0
- finlet-0.0.1/dashboard/app.js +2384 -0
- finlet-0.0.1/dashboard/auth-guard.js +52 -0
- finlet-0.0.1/dashboard/auth.css +1152 -0
- finlet-0.0.1/dashboard/auth.html +544 -0
- finlet-0.0.1/dashboard/auth.js +1651 -0
- finlet-0.0.1/dashboard/billing.css +1083 -0
- finlet-0.0.1/dashboard/billing.html +458 -0
- finlet-0.0.1/dashboard/billing.js +782 -0
- finlet-0.0.1/dashboard/empty-states.js +217 -0
- finlet-0.0.1/dashboard/favicon.svg +4 -0
- finlet-0.0.1/dashboard/feedback.js +189 -0
- finlet-0.0.1/dashboard/index.html +593 -0
- finlet-0.0.1/dashboard/landing.css +795 -0
- finlet-0.0.1/dashboard/landing.html +330 -0
- finlet-0.0.1/dashboard/leaderboard-submit.js +440 -0
- finlet-0.0.1/dashboard/leaderboard.html +122 -0
- finlet-0.0.1/dashboard/leaderboard.js +428 -0
- finlet-0.0.1/dashboard/llms.txt +57 -0
- finlet-0.0.1/dashboard/marketplace.css +613 -0
- finlet-0.0.1/dashboard/marketplace.html +142 -0
- finlet-0.0.1/dashboard/marketplace.js +506 -0
- finlet-0.0.1/dashboard/mobile-nav.js +209 -0
- finlet-0.0.1/dashboard/onboarding.css +552 -0
- finlet-0.0.1/dashboard/onboarding.js +723 -0
- finlet-0.0.1/dashboard/security-telemetry.js +131 -0
- finlet-0.0.1/dashboard/settings.css +1174 -0
- finlet-0.0.1/dashboard/settings.html +616 -0
- finlet-0.0.1/dashboard/settings.js +1410 -0
- finlet-0.0.1/dashboard/setup.css +556 -0
- finlet-0.0.1/dashboard/setup.html +638 -0
- finlet-0.0.1/dashboard/shared-nav.js +389 -0
- finlet-0.0.1/dashboard/styles.css +3702 -0
- finlet-0.0.1/dashboard/trade-ticket.js +293 -0
- finlet-0.0.1/dashboard/vendor/lightweight-charts.standalone.production.js +7 -0
- finlet-0.0.1/deploy/.env.example +91 -0
- finlet-0.0.1/deploy/Caddyfile +22 -0
- finlet-0.0.1/deploy/RUNBOOK.md +500 -0
- finlet-0.0.1/deploy/aws/.terraform.lock.hcl +45 -0
- finlet-0.0.1/deploy/aws/backend.tf +12 -0
- finlet-0.0.1/deploy/aws/bootstrap-state.sh +34 -0
- finlet-0.0.1/deploy/aws/cloudwatch.tf +83 -0
- finlet-0.0.1/deploy/aws/iam-ingestor.tf +79 -0
- finlet-0.0.1/deploy/aws/main.tf +365 -0
- finlet-0.0.1/deploy/aws/outputs.tf +30 -0
- finlet-0.0.1/deploy/aws/user-data.sh +126 -0
- finlet-0.0.1/deploy/aws/variables.tf +35 -0
- finlet-0.0.1/deploy/aws/versions.tf +14 -0
- finlet-0.0.1/deploy/backup-sqlite.sh +100 -0
- finlet-0.0.1/deploy/deploy.sh +194 -0
- finlet-0.0.1/deploy/fail2ban/filter.d/finlet-api.conf +15 -0
- finlet-0.0.1/deploy/fail2ban/filter.d/finlet-auth.conf +14 -0
- finlet-0.0.1/deploy/fail2ban/jail.local +29 -0
- finlet-0.0.1/deploy/finlet-logrotate.conf +19 -0
- finlet-0.0.1/deploy/finlet-mcp.service +36 -0
- finlet-0.0.1/deploy/finlet.service +39 -0
- finlet-0.0.1/deploy/hooks/pre-push +56 -0
- finlet-0.0.1/deploy/rollback.sh +139 -0
- finlet-0.0.1/docs/ARCHITECTURE.md +1440 -0
- finlet-0.0.1/docs/CYBERSECURITY_READINESS_REPORT.md +370 -0
- finlet-0.0.1/docs/DATA_PIPELINE_HANDOFF.md +218 -0
- finlet-0.0.1/docs/DEV_TOOLS.md +190 -0
- finlet-0.0.1/docs/HANDOFF_SESSION_3.md +133 -0
- finlet-0.0.1/docs/HANDOFF_SESSION_4.md +103 -0
- finlet-0.0.1/docs/HYGIENE_AUDIT.md +156 -0
- finlet-0.0.1/docs/KNOWN_FAILURES.md +24 -0
- finlet-0.0.1/docs/LESSONS.md +115 -0
- finlet-0.0.1/docs/MARKETPLACE_ARCHITECTURE.md +548 -0
- finlet-0.0.1/docs/PRIVACY_POLICY.md +598 -0
- finlet-0.0.1/docs/REMAINING_TASKS.md +219 -0
- finlet-0.0.1/docs/SECURITY_EXECUTION_PLAN.md +738 -0
- finlet-0.0.1/docs/TERMS_OF_SERVICE.md +474 -0
- finlet-0.0.1/docs/V1_SCOPE.md +106 -0
- finlet-0.0.1/docs/audits/AUDIT_CODEX_2026-03-31.md +874 -0
- finlet-0.0.1/docs/brainstorms/AGENT_SETUP_GUIDE_EXECUTION_PLAN.md +411 -0
- finlet-0.0.1/docs/brainstorms/AGENT_SETUP_GUIDE_REQUIREMENTS.md +98 -0
- finlet-0.0.1/docs/brainstorms/AUTH_OVERHAUL_REQUIREMENTS.md +86 -0
- finlet-0.0.1/docs/brainstorms/BENCHMARK_FLOW_PLAN.md +431 -0
- finlet-0.0.1/docs/brainstorms/BENCHMARK_FLOW_REQUIREMENTS.md +102 -0
- finlet-0.0.1/docs/brainstorms/BENCHMARK_REPORTING_PLAN.md +400 -0
- finlet-0.0.1/docs/brainstorms/DATA_PIPELINE_CLEANUP_PLAN.md +266 -0
- finlet-0.0.1/docs/brainstorms/EXECUTION_PLAN.md +142 -0
- finlet-0.0.1/docs/brainstorms/LAUNCH_BLOCKERS_PLAN.md +290 -0
- finlet-0.0.1/docs/brainstorms/LAUNCH_BLOCKERS_REQUIREMENTS.md +63 -0
- finlet-0.0.1/docs/brainstorms/LAUNCH_READINESS_EXECUTION_PLAN.md +364 -0
- finlet-0.0.1/docs/brainstorms/P3_EXECUTION_PLAN.md +92 -0
- finlet-0.0.1/docs/brainstorms/PYPI_PUBLISH_PLAN.md +43 -0
- finlet-0.0.1/docs/brainstorms/SECURITY_ROADMAP.md +212 -0
- finlet-0.0.1/docs/brainstorms/WEBSITE_CORRECTNESS_PLAN.md +311 -0
- finlet-0.0.1/docs/brainstorms/audit_codex_REQUIREMENTS.md +233 -0
- finlet-0.0.1/docs/brainstorms/command_layer_jumpstart.md +430 -0
- finlet-0.0.1/docs/brainstorms/cybersecurity_case_studies.md +575 -0
- finlet-0.0.1/docs/brainstorms/data-collection-strategy.md +121 -0
- finlet-0.0.1/docs/brainstorms/finlet_launch_readiness_READINESS_REPORT.md +193 -0
- finlet-0.0.1/docs/brainstorms/finlet_security_brainstorm.md +419 -0
- finlet-0.0.1/docs/brainstorms/is_finlet_useful_READINESS_REPORT.md +417 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/API_AUTH_DASHBOARD_READINESS.md +576 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/CORE_ENGINE_READINESS.md +765 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/PLUGINS_INFRA_OPS_READINESS.md +508 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/api_arch_critic.md +90 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/api_code_defender.md +137 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/api_comp_critic.md +189 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/api_industry_defender.md +83 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/core_arch_critic.md +192 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/core_code_defender.md +215 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/core_comp_critic.md +185 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/core_industry_defender.md +83 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/infra_arch_critic.md +156 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/infra_code_defender.md +188 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/infra_comp_critic.md +127 -0
- finlet-0.0.1/docs/brainstorms/launch_debate/infra_industry_defender.md +92 -0
- finlet-0.0.1/docs/brainstorms/launch_hardening_REQUIREMENTS.md +68 -0
- finlet-0.0.1/docs/brainstorms/launch_readiness_READINESS_REPORT.md +378 -0
- finlet-0.0.1/docs/brainstorms/launch_readiness_r4_READINESS_REPORT.md +370 -0
- finlet-0.0.1/docs/brainstorms/launch_readiness_r5_READINESS_REPORT.md +152 -0
- finlet-0.0.1/docs/brainstorms/remaining_critical_high_REQUIREMENTS.md +41 -0
- finlet-0.0.1/docs/brainstorms/skill_eval_EXECUTION_PLAN.md +258 -0
- finlet-0.0.1/docs/brainstorms/skill_eval_REQUIREMENTS.md +44 -0
- finlet-0.0.1/docs/brainstorms/stripe_data_exposure.md +207 -0
- finlet-0.0.1/docs/brainstorms/stripe_resilience_patterns.md +285 -0
- finlet-0.0.1/docs/brainstorms/stripe_vs_finlet_synthesis.md +506 -0
- finlet-0.0.1/docs/brainstorms/ui_bugs_phase1_REQUIREMENTS.md +51 -0
- finlet-0.0.1/docs/decisions/benchmark-mock-duck-typing.md +28 -0
- finlet-0.0.1/docs/decisions/data-at-rest-encryption.md +61 -0
- finlet-0.0.1/docs/decisions/deploy-https-git-auth.md +111 -0
- finlet-0.0.1/docs/decisions/float-epsilon-threshold.md +71 -0
- finlet-0.0.1/docs/decisions/greenlet-explicit-dep.md +14 -0
- finlet-0.0.1/docs/decisions/limit-order-price-improvement.md +23 -0
- finlet-0.0.1/docs/decisions/mcp-auth-backward-compat.md +31 -0
- finlet-0.0.1/docs/decisions/mcp-auth-mandatory.md +40 -0
- finlet-0.0.1/docs/decisions/mcp-session-attribution.md +31 -0
- finlet-0.0.1/docs/decisions/order-processing-single-lock.md +69 -0
- finlet-0.0.1/docs/decisions/parquet-partitioning.md +42 -0
- finlet-0.0.1/docs/decisions/postgresql-migration.md +290 -0
- finlet-0.0.1/docs/decisions/price-close-timestamps.md +20 -0
- finlet-0.0.1/docs/decisions/reasoning-quality-score.md +26 -0
- finlet-0.0.1/docs/decisions/remove-hatch-wheel-whitelist.md +32 -0
- finlet-0.0.1/docs/decisions/session-status-guards.md +71 -0
- finlet-0.0.1/docs/decisions/yfinance-data-source.md +60 -0
- finlet-0.0.1/docs/handoffs/SESSION_3_DATA_LAKE_DEPLOY.md +326 -0
- finlet-0.0.1/docs/marketplace/ARCHITECTURE.md +745 -0
- finlet-0.0.1/docs/marketplace/COMPETITIVE_ANALYSIS.md +433 -0
- finlet-0.0.1/docs/marketplace/LEGAL_BRIEF.md +540 -0
- finlet-0.0.1/docs/planning/agent_teams_build_prompt.md +388 -0
- finlet-0.0.1/docs/planning/architecture_spec.md +806 -0
- finlet-0.0.1/docs/planning/testing-fixes-plan.md +477 -0
- finlet-0.0.1/docs/planning/wiring_team_prompt.md +227 -0
- finlet-0.0.1/docs/plans/AUTH_OVERHAUL_PLAN.md +434 -0
- finlet-0.0.1/docs/plans/BUG8_EXECUTION_PLAN.md +135 -0
- finlet-0.0.1/docs/plans/CRITICAL_E2E_FIX.md +123 -0
- finlet-0.0.1/docs/plans/DATA_LAKE_EXPANSION_PLAN.md +375 -0
- finlet-0.0.1/docs/plans/DATA_PIPELINE_SESSION_3_PLAN.md +321 -0
- finlet-0.0.1/docs/plans/EXEC_PLAN_CLOCK_MOBILE.md +214 -0
- finlet-0.0.1/docs/plans/EXEC_PLAN_E2E_FIXES.md +42 -0
- finlet-0.0.1/docs/plans/EXEC_PLAN_ENFORCER_CREDIBILITY.md +409 -0
- finlet-0.0.1/docs/plans/FIX_E2E_CI.md +48 -0
- finlet-0.0.1/docs/plans/HYGIENE_AUDIT.md +343 -0
- finlet-0.0.1/docs/plans/PHASE1_MAKE_IT_START_PLAN.md +266 -0
- finlet-0.0.1/docs/plans/PHASE3_HYGIENE_AUDIT.md +560 -0
- finlet-0.0.1/docs/plans/PHASE_A_PLAN.md +371 -0
- finlet-0.0.1/docs/plans/PHASE_B_PLAN.md +321 -0
- finlet-0.0.1/docs/plans/PHASE_C_PLAN.md +216 -0
- finlet-0.0.1/docs/plans/PHASE_D_PLAN.md +363 -0
- finlet-0.0.1/docs/plans/PRICING_TIER_UPDATE.md +164 -0
- finlet-0.0.1/docs/plans/UI_FLOW_PLAN.md +739 -0
- finlet-0.0.1/docs/plans/add_mcp_session_lifecycle_tools.md +218 -0
- finlet-0.0.1/docs/plans/debate_r2_fixes_EXECUTION_PLAN.md +163 -0
- finlet-0.0.1/docs/plans/debate_r3_fixes_EXECUTION_PLAN.md +183 -0
- finlet-0.0.1/docs/plans/debate_r4_fixes_EXECUTION_PLAN.md +291 -0
- finlet-0.0.1/docs/plans/e2e-flakiness-sweep.md +169 -0
- finlet-0.0.1/docs/plans/e2e_bugs_phase2.md +127 -0
- finlet-0.0.1/docs/plans/e2e_ux_testing_plan.md +782 -0
- finlet-0.0.1/docs/plans/fix_session_concurrency_bug.md +198 -0
- finlet-0.0.1/docs/plans/fix_trace_endpoint_leak.md +103 -0
- finlet-0.0.1/docs/plans/launch_hardening_EXECUTION_PLAN.md +241 -0
- finlet-0.0.1/docs/plans/r5_launch_fixes_EXECUTION_PLAN.md +261 -0
- finlet-0.0.1/docs/plans/r5_launch_fixes_v2_EXECUTION_PLAN.md +425 -0
- finlet-0.0.1/docs/plans/remaining_critical_high_EXECUTION_PLAN.md +186 -0
- finlet-0.0.1/docs/plans/session1_engine_safety.md +263 -0
- finlet-0.0.1/docs/plans/session1_mcp_quickwins.md +189 -0
- finlet-0.0.1/docs/plans/session1_plugin_resilience.md +244 -0
- finlet-0.0.1/docs/plans/session_launch_critical.md +281 -0
- finlet-0.0.1/docs/plans/tech_debt_cleanup.md +477 -0
- finlet-0.0.1/docs/plans/ui_bugs_phase1_EXECUTION_PLAN.md +114 -0
- finlet-0.0.1/docs/research/CONTEXT_AS_COGNITION.md +30 -0
- finlet-0.0.1/docs/skill-eval-results.md +81 -0
- finlet-0.0.1/docs/tasks/TASK-benchmark-runner.md +32 -0
- finlet-0.0.1/docs/tasks/TASK-continuous-clock.md +37 -0
- finlet-0.0.1/docs/tasks/TASK-price-infra.md +73 -0
- finlet-0.0.1/docs/tools/api-data.md +26 -0
- finlet-0.0.1/docs/tools/aws.md +35 -0
- finlet-0.0.1/docs/tools/devops.md +36 -0
- finlet-0.0.1/docs/tools/plugin-mgmt.md +23 -0
- finlet-0.0.1/docs/ui-improvement-checklist.md +314 -0
- finlet-0.0.1/finlet/__init__.py +0 -0
- finlet-0.0.1/finlet/api/__init__.py +1 -0
- finlet-0.0.1/finlet/api/app.py +519 -0
- finlet-0.0.1/finlet/api/auth.py +138 -0
- finlet-0.0.1/finlet/api/config_injection.py +106 -0
- finlet-0.0.1/finlet/api/deps.py +33 -0
- finlet-0.0.1/finlet/api/email_config.py +142 -0
- finlet-0.0.1/finlet/api/email_providers.py +261 -0
- finlet-0.0.1/finlet/api/email_service.py +327 -0
- finlet-0.0.1/finlet/api/email_templates/__init__.py +44 -0
- finlet-0.0.1/finlet/api/email_templates/auth.py +459 -0
- finlet-0.0.1/finlet/api/email_templates/base.py +217 -0
- finlet-0.0.1/finlet/api/email_templates/billing.py +362 -0
- finlet-0.0.1/finlet/api/email_templates/security.py +299 -0
- finlet-0.0.1/finlet/api/email_templates/session.py +85 -0
- finlet-0.0.1/finlet/api/idempotency.py +93 -0
- finlet-0.0.1/finlet/api/mfa/__init__.py +61 -0
- finlet-0.0.1/finlet/api/mfa/google.py +94 -0
- finlet-0.0.1/finlet/api/mfa/recovery.py +135 -0
- finlet-0.0.1/finlet/api/mfa/session.py +103 -0
- finlet-0.0.1/finlet/api/mfa/sms.py +133 -0
- finlet-0.0.1/finlet/api/mfa/totp.py +83 -0
- finlet-0.0.1/finlet/api/middleware.py +102 -0
- finlet-0.0.1/finlet/api/rate_limit/__init__.py +82 -0
- finlet-0.0.1/finlet/api/rate_limit/auth.py +198 -0
- finlet-0.0.1/finlet/api/rate_limit/core.py +105 -0
- finlet-0.0.1/finlet/api/rate_limit/plugin.py +133 -0
- finlet-0.0.1/finlet/api/rate_limit/session.py +103 -0
- finlet-0.0.1/finlet/api/rate_limit/trading.py +166 -0
- finlet-0.0.1/finlet/api/routes_admin.py +84 -0
- finlet-0.0.1/finlet/api/routes_auth_credentials.py +490 -0
- finlet-0.0.1/finlet/api/routes_auth_mfa.py +270 -0
- finlet-0.0.1/finlet/api/routes_auth_sessions.py +170 -0
- finlet-0.0.1/finlet/api/routes_billing.py +185 -0
- finlet-0.0.1/finlet/api/routes_clock.py +165 -0
- finlet-0.0.1/finlet/api/routes_csp.py +122 -0
- finlet-0.0.1/finlet/api/routes_email.py +233 -0
- finlet-0.0.1/finlet/api/routes_health.py +74 -0
- finlet-0.0.1/finlet/api/routes_leaderboard.py +124 -0
- finlet-0.0.1/finlet/api/routes_legal.py +180 -0
- finlet-0.0.1/finlet/api/routes_market.py +181 -0
- finlet-0.0.1/finlet/api/routes_marketplace_admin.py +212 -0
- finlet-0.0.1/finlet/api/routes_marketplace_compliance.py +374 -0
- finlet-0.0.1/finlet/api/routes_marketplace_onboarding.py +122 -0
- finlet-0.0.1/finlet/api/routes_marketplace_strategy.py +225 -0
- finlet-0.0.1/finlet/api/routes_metrics.py +135 -0
- finlet-0.0.1/finlet/api/routes_notifications.py +200 -0
- finlet-0.0.1/finlet/api/routes_portfolio.py +95 -0
- finlet-0.0.1/finlet/api/routes_session.py +180 -0
- finlet-0.0.1/finlet/api/routes_settings.py +195 -0
- finlet-0.0.1/finlet/api/routes_sse.py +200 -0
- finlet-0.0.1/finlet/api/routes_trade.py +170 -0
- finlet-0.0.1/finlet/api/schemas/__init__.py +309 -0
- finlet-0.0.1/finlet/api/schemas/auth_credentials.py +88 -0
- finlet-0.0.1/finlet/api/schemas/auth_mfa.py +47 -0
- finlet-0.0.1/finlet/api/schemas/auth_sessions.py +42 -0
- finlet-0.0.1/finlet/api/schemas/billing.py +90 -0
- finlet-0.0.1/finlet/api/schemas/clock.py +36 -0
- finlet-0.0.1/finlet/api/schemas/email.py +54 -0
- finlet-0.0.1/finlet/api/schemas/health.py +30 -0
- finlet-0.0.1/finlet/api/schemas/leaderboard.py +103 -0
- finlet-0.0.1/finlet/api/schemas/marketplace_admin.py +108 -0
- finlet-0.0.1/finlet/api/schemas/marketplace_developer.py +129 -0
- finlet-0.0.1/finlet/api/schemas/marketplace_onboarding.py +150 -0
- finlet-0.0.1/finlet/api/schemas/notifications.py +26 -0
- finlet-0.0.1/finlet/api/schemas/portfolio.py +88 -0
- finlet-0.0.1/finlet/api/schemas/session.py +73 -0
- finlet-0.0.1/finlet/api/schemas/settings.py +184 -0
- finlet-0.0.1/finlet/api/schemas/trade.py +23 -0
- finlet-0.0.1/finlet/api/security_alerts.py +23 -0
- finlet-0.0.1/finlet/api/security_middleware.py +348 -0
- finlet-0.0.1/finlet/api/serializers.py +36 -0
- finlet-0.0.1/finlet/api/services/__init__.py +0 -0
- finlet-0.0.1/finlet/api/services/clock_service.py +336 -0
- finlet-0.0.1/finlet/api/services/email_token_service.py +148 -0
- finlet-0.0.1/finlet/api/services/market_service.py +99 -0
- finlet-0.0.1/finlet/api/services/session_service.py +387 -0
- finlet-0.0.1/finlet/api/services/settings_service.py +364 -0
- finlet-0.0.1/finlet/api/services/trade_service.py +151 -0
- finlet-0.0.1/finlet/api/session_auth.py +39 -0
- finlet-0.0.1/finlet/api/state.py +36 -0
- finlet-0.0.1/finlet/auth/__init__.py +31 -0
- finlet-0.0.1/finlet/auth/deps.py +159 -0
- finlet-0.0.1/finlet/auth/mfa/__init__.py +62 -0
- finlet-0.0.1/finlet/auth/mfa/crypto.py +80 -0
- finlet-0.0.1/finlet/auth/mfa/exceptions.py +51 -0
- finlet-0.0.1/finlet/auth/mfa/google.py +171 -0
- finlet-0.0.1/finlet/auth/mfa/google_validate.py +97 -0
- finlet-0.0.1/finlet/auth/mfa/recovery.py +105 -0
- finlet-0.0.1/finlet/auth/mfa/recovery_utils.py +157 -0
- finlet-0.0.1/finlet/auth/mfa/session.py +106 -0
- finlet-0.0.1/finlet/auth/mfa/sms.py +136 -0
- finlet-0.0.1/finlet/auth/mfa/totp.py +320 -0
- finlet-0.0.1/finlet/auth/mfa/totp_utils.py +87 -0
- finlet-0.0.1/finlet/auth/mfa_crypto.py +15 -0
- finlet-0.0.1/finlet/auth/password.py +64 -0
- finlet-0.0.1/finlet/auth/security_alerts.py +138 -0
- finlet-0.0.1/finlet/auth/service.py +837 -0
- finlet-0.0.1/finlet/auth/session_auth.py +204 -0
- finlet-0.0.1/finlet/billing/__init__.py +1 -0
- finlet-0.0.1/finlet/billing/service.py +406 -0
- finlet-0.0.1/finlet/billing/stripe_config.py +105 -0
- finlet-0.0.1/finlet/billing/validators.py +58 -0
- finlet-0.0.1/finlet/billing/webhooks.py +184 -0
- finlet-0.0.1/finlet/cli.py +213 -0
- finlet-0.0.1/finlet/config.py +187 -0
- finlet-0.0.1/finlet/core/__init__.py +52 -0
- finlet-0.0.1/finlet/core/clock.py +416 -0
- finlet-0.0.1/finlet/core/enforcer.py +168 -0
- finlet-0.0.1/finlet/core/orders.py +202 -0
- finlet-0.0.1/finlet/core/portfolio.py +406 -0
- finlet-0.0.1/finlet/core/session.py +542 -0
- finlet-0.0.1/finlet/core/slippage.py +86 -0
- finlet-0.0.1/finlet/core/trace.py +162 -0
- finlet-0.0.1/finlet/db/__init__.py +75 -0
- finlet-0.0.1/finlet/db/auth_models.py +129 -0
- finlet-0.0.1/finlet/db/engine.py +339 -0
- finlet-0.0.1/finlet/db/leaderboard_models.py +92 -0
- finlet-0.0.1/finlet/db/leaderboard_persistence.py +278 -0
- finlet-0.0.1/finlet/db/migrations/__init__.py +1 -0
- finlet-0.0.1/finlet/db/migrations/env.py +141 -0
- finlet-0.0.1/finlet/db/migrations/global_versions/014_global_db_baseline.py +54 -0
- finlet-0.0.1/finlet/db/migrations/runner.py +223 -0
- finlet-0.0.1/finlet/db/migrations/script.py.mako +28 -0
- finlet-0.0.1/finlet/db/migrations/session_versions/013_session_db_baseline.py +162 -0
- finlet-0.0.1/finlet/db/migrations/versions/001_initial_schema.py +212 -0
- finlet-0.0.1/finlet/db/migrations/versions/002_add_subscriptions.py +50 -0
- finlet-0.0.1/finlet/db/migrations/versions/003_add_rate_limits.py +42 -0
- finlet-0.0.1/finlet/db/migrations/versions/004_add_mfa_fields.py +69 -0
- finlet-0.0.1/finlet/db/migrations/versions/005_add_user_settings.py +38 -0
- finlet-0.0.1/finlet/db/migrations/versions/006_add_session_fingerprinting.py +50 -0
- finlet-0.0.1/finlet/db/migrations/versions/007_add_key_rotation_fields.py +50 -0
- finlet-0.0.1/finlet/db/migrations/versions/008_add_session_tokens.py +48 -0
- finlet-0.0.1/finlet/db/migrations/versions/009_add_password_fields.py +38 -0
- finlet-0.0.1/finlet/db/migrations/versions/010_add_email_unique_constraint.py +60 -0
- finlet-0.0.1/finlet/db/migrations/versions/011_hash_session_tokens.py +76 -0
- finlet-0.0.1/finlet/db/migrations/versions/012_add_position_unique_constraint.py +67 -0
- finlet-0.0.1/finlet/db/models.py +179 -0
- finlet-0.0.1/finlet/db/persistence.py +473 -0
- finlet-0.0.1/finlet/db/session_models.py +91 -0
- finlet-0.0.1/finlet/errors.py +41 -0
- finlet-0.0.1/finlet/ingestion/__init__.py +21 -0
- finlet-0.0.1/finlet/ingestion/base.py +156 -0
- finlet-0.0.1/finlet/ingestion/s3_writer.py +335 -0
- finlet-0.0.1/finlet/ingestion/yfinance_provider.py +314 -0
- finlet-0.0.1/finlet/leaderboard/__init__.py +31 -0
- finlet-0.0.1/finlet/leaderboard/api_strategy.py +1015 -0
- finlet-0.0.1/finlet/leaderboard/benchmark_plugins.py +573 -0
- finlet-0.0.1/finlet/leaderboard/benchmark_state.py +376 -0
- finlet-0.0.1/finlet/leaderboard/benchmarks.py +122 -0
- finlet-0.0.1/finlet/leaderboard/fixtures.py +188 -0
- finlet-0.0.1/finlet/leaderboard/profiles.py +75 -0
- finlet-0.0.1/finlet/leaderboard/reporting.py +279 -0
- finlet-0.0.1/finlet/leaderboard/runner.py +271 -0
- finlet-0.0.1/finlet/leaderboard/scoring.py +198 -0
- finlet-0.0.1/finlet/leaderboard/service.py +286 -0
- finlet-0.0.1/finlet/logging.py +75 -0
- finlet-0.0.1/finlet/marketplace/__init__.py +1 -0
- finlet-0.0.1/finlet/marketplace/admin_service.py +300 -0
- finlet-0.0.1/finlet/marketplace/disclaimer_middleware.py +205 -0
- finlet-0.0.1/finlet/marketplace/disclaimers.py +294 -0
- finlet-0.0.1/finlet/marketplace/dmca.py +125 -0
- finlet-0.0.1/finlet/marketplace/geo_config.py +294 -0
- finlet-0.0.1/finlet/marketplace/geo_ip.py +147 -0
- finlet-0.0.1/finlet/marketplace/geo_middleware.py +318 -0
- finlet-0.0.1/finlet/marketplace/models.py +242 -0
- finlet-0.0.1/finlet/marketplace/onboarding_service.py +628 -0
- finlet-0.0.1/finlet/marketplace/persistence.py +352 -0
- finlet-0.0.1/finlet/marketplace/prohibited_claims.py +781 -0
- finlet-0.0.1/finlet/marketplace/review_compliance.py +301 -0
- finlet-0.0.1/finlet/marketplace/tax.py +333 -0
- finlet-0.0.1/finlet/marketplace/tax_forms.py +374 -0
- finlet-0.0.1/finlet/mcp/__init__.py +1 -0
- finlet-0.0.1/finlet/mcp/_instance.py +9 -0
- finlet-0.0.1/finlet/mcp/auth.py +60 -0
- finlet-0.0.1/finlet/mcp/server.py +651 -0
- finlet-0.0.1/finlet/mcp/tools_benchmark.py +206 -0
- finlet-0.0.1/finlet/mcp/tools_portfolio.py +130 -0
- finlet-0.0.1/finlet/mcp/tools_trading.py +115 -0
- finlet-0.0.1/finlet/metrics.py +80 -0
- finlet-0.0.1/finlet/plugins/__init__.py +39 -0
- finlet-0.0.1/finlet/plugins/base.py +472 -0
- finlet-0.0.1/finlet/plugins/cache.py +177 -0
- finlet-0.0.1/finlet/plugins/econ_fetchers.py +332 -0
- finlet-0.0.1/finlet/plugins/econ_plugin.py +349 -0
- finlet-0.0.1/finlet/plugins/econ_sources.py +154 -0
- finlet-0.0.1/finlet/plugins/edgar_plugin.py +215 -0
- finlet-0.0.1/finlet/plugins/finnhub_plugin.py +519 -0
- finlet-0.0.1/finlet/plugins/fred_plugin.py +427 -0
- finlet-0.0.1/finlet/plugins/fundamentals_plugin.py +430 -0
- finlet-0.0.1/finlet/plugins/news_plugin.py +429 -0
- finlet-0.0.1/finlet/plugins/price_plugin.py +516 -0
- finlet-0.0.1/finlet/plugins/sentiment_plugin.py +402 -0
- finlet-0.0.1/finlet/ssm.py +116 -0
- finlet-0.0.1/finlet/utils/__init__.py +0 -0
- finlet-0.0.1/finlet/utils/dates.py +45 -0
- finlet-0.0.1/finlet/utils/ids.py +8 -0
- finlet-0.0.1/finlet/utils/time.py +8 -0
- finlet-0.0.1/package-lock.json +75 -0
- finlet-0.0.1/package.json +5 -0
- finlet-0.0.1/pyproject.toml +167 -0
- finlet-0.0.1/requirements.lock +140 -0
- finlet-0.0.1/scripts/ingest_daily.py +314 -0
- finlet-0.0.1/scripts/ingest_edgar.py +1154 -0
- finlet-0.0.1/scripts/ingest_fred.py +715 -0
- finlet-0.0.1/scripts/ingest_fundamentals.py +493 -0
- finlet-0.0.1/scripts/ingest_news.py +604 -0
- finlet-0.0.1/scripts/ingest_prices.py +447 -0
- finlet-0.0.1/scripts/ingest_sectors.py +489 -0
- finlet-0.0.1/scripts/ingest_sentiment.py +860 -0
- finlet-0.0.1/scripts/ingest_yfinance_prices.py +903 -0
- finlet-0.0.1/scripts/run_bulk_scrape.sh +173 -0
- finlet-0.0.1/scripts/run_bull_run.py +193 -0
- finlet-0.0.1/scripts/ticker_lists/crypto_pairs.txt +60 -0
- finlet-0.0.1/scripts/ticker_lists/us_equities.txt +238 -0
- finlet-0.0.1/scripts/ticker_lists/us_etfs.txt +96 -0
- finlet-0.0.1/test-results/.last-run.json +85 -0
- finlet-0.0.1/test-results/tests-e2e-journey-01-landi-53571--errors-or-network-failures/error-context.md +87 -0
- finlet-0.0.1/test-results/tests-e2e-journey-01-landi-ebe86--with-all-required-elements/error-context.md +87 -0
- finlet-0.0.1/test-results/tests-e2e-journey-01-landi-fc8b5-gates-to-auth-page-and-back/error-context.md +87 -0
- finlet-0.0.1/test-results/tests-e2e-journey-02-signu-36e54-in-tab-is-active-by-default/error-context.md +132 -0
- finlet-0.0.1/test-results/tests-e2e-journey-02-signu-50973-low-switching-to-signup-tab/error-context.md +139 -0
- finlet-0.0.1/test-results/tests-e2e-journey-02-signu-85f34--and-weak-password-strength/error-context.md +139 -0
- finlet-0.0.1/test-results/tests-e2e-journey-02-signu-9dce1-rd-and-submits-successfully/error-context.md +139 -0
- finlet-0.0.1/test-results/tests-e2e-journey-02-signu-adf33-shows-all-validation-errors/error-context.md +139 -0
- finlet-0.0.1/test-results/tests-e2e-journey-03-login-4ac08-le-errors-during-login-flow/error-context.md +116 -0
- finlet-0.0.1/test-results/tests-e2e-journey-03-login-76fd0-n-and-redirect-to-dashboard/error-context.md +116 -0
- finlet-0.0.1/test-results/tests-e2e-journey-03-login-7a96b--password-shows-alert-error/error-context.md +116 -0
- finlet-0.0.1/test-results/tests-e2e-journey-03-login-9b76b-ion-shows-validation-errors/error-context.md +116 -0
- finlet-0.0.1/test-results/tests-e2e-journey-04-dashb-06772--present-with-correct-links/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-04-dashb-4cdca-session-selector-is-visible/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-04-dashb-6bccf-l-opens-and-creates-session/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-04-dashb-d651a-ctive-not-fallback-polling-/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-04-dashb-e9601-trols-freeze-step-play-stop/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-05-trade-294f7-de-button-auto-fills-fields/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-05-trade-66c53-sion-shows-validation-error/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-05-trade-beb2e-pens-and-shows-cash-balance/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-05-trade-d10cc-ure-price-data-is-available/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-05-trade-f4072-ify-it-appears-in-order-log/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-01d82-bar-sections-activates-each/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-11192-ge-API-Keys-section-renders/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-61953-h-profile-active-by-default/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-62818-gers-unsaved-changes-banner/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-83fbe-section-has-MFA-UI-elements/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-976a2--errors-or-network-failures/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-cada4-age-Plugins-section-renders/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-e3902-ion-has-all-required-fields/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-06-setti-ea107-correct-nav-and-breadcrumbs/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-0e024-as-all-required-form-fields/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-230ad-ailures-on-leaderboard-page/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-38947-er-submission-returns-focus/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-4052f-ge-calls-GET-v1-leaderboard/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-4ed17-idation-error-on-agent-name/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-8bb5f-rect-columns-or-empty-state/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-bee7e-s-agent-on-leaderboard-page/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-cb37b-enchmark-with-loading-state/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-f5f09-nav-breadcrumbs-and-content/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-07-leade-fd776--modal-opens-from-dashboard/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-18430-promo-code-elements-present/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-42c00--toast-container-is-present/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-5b15a-ayment-sections-are-present/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-5ecaa-n-is-marked-as-current-plan/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-67ae0--defaults-to-monthly-active/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-74084--errors-or-network-failures/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-8d601-correct-nav-and-breadcrumbs/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-d3c44-es-prices-and-shows-savings/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-fb88f-n-cards-render-with-buttons/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-08-billi-ffed2-ts-prices-and-hides-savings/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-09-mobil-7b958-overflow-at-mobile-viewport/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-09-mobil-7e7f1-opens-and-closes-nav-drawer/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-09-mobil-992e3-orrectly-at-mobile-viewport/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-09-mobil-abd82-er-links-navigate-correctly/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-09-mobil-e048a--errors-or-network-failures/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-10-authg-048d3-h-html-when-unauthenticated/error-context.md +180 -0
- finlet-0.0.1/test-results/tests-e2e-journey-10-authg-29d76-h-html-when-unauthenticated/error-context.md +180 -0
- finlet-0.0.1/test-results/tests-e2e-journey-10-authg-47ebe-s-NOT-redirect-public-page-/error-context.md +151 -0
- finlet-0.0.1/test-results/tests-e2e-journey-10-authg-6d220-s-NOT-redirect-public-page-/error-context.md +173 -0
- finlet-0.0.1/test-results/tests-e2e-journey-10-authg-a45d0-g-html-when-unauthenticated/error-context.md +145 -0
- finlet-0.0.1/test-results/tests-e2e-journey-10-authg-c0899-h-html-when-unauthenticated/error-context.md +178 -0
- finlet-0.0.1/test-results/tests-e2e-journey-10-authg-ef215-ticate-for-subsequent-tests/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-11-keybo-18560-ace-toggles-play-and-freeze/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-11-keybo-80891--focus-is-on-input-elements/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-11-keybo-83a65-owRight-triggers-clock-step/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-11-keybo-933f2--Escape-triggers-clock-stop/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-11-keybo-daa42-during-keyboard-interaction/error-context.md +143 -0
- finlet-0.0.1/test-results/tests-e2e-journey-12-forgo-9c91a-during-forgot-password-flow/error-context.md +151 -0
- finlet-0.0.1/test-results/tests-e2e-journey-12-forgo-dae21-ate-to-forgot-password-form/error-context.md +151 -0
- finlet-0.0.1/test-results/tests-e2e-journey-12-forgo-e5892-t-flow-requires-OTP-access-/error-context.md +151 -0
- finlet-0.0.1/test-results/tests-e2e-journey-12-forgo-ed757-dvance-to-code-entry-screen/error-context.md +151 -0
- finlet-0.0.1/test-results/tests-e2e-journey-12-forgo-f5a7a-ticate-for-subsequent-tests/error-context.md +151 -0
- finlet-0.0.1/test-results/tests-e2e-journey-13-cli-s-41067-int-requires-authentication/error-context.md +22 -0
- finlet-0.0.1/test-results/tests-e2e-journey-13-cli-s-488a2-health-endpoint-returns-200/error-context.md +22 -0
- finlet-0.0.1/test-results/tests-e2e-journey-13-cli-s-6859f-dpoint-rejects-GET-requests/error-context.md +22 -0
- finlet-0.0.1/test-results/tests-e2e-journey-13-cli-s-afd1d-ge-is-served-as-static-HTML/error-context.md +22 -0
- finlet-0.0.1/test-results/tests-e2e-journey-13-cli-s-b295e-ister-endpoint-accepts-POST/error-context.md +24 -0
- finlet-0.0.1/test-results/tests-e2e-journey-13-cli-s-e94e3-docs-are-accessible-at-docs/error-context.md +22 -0
- finlet-0.0.1/test-results/tests-e2e-journey-14-cli-s-a0f86-ycle-create-session-via-CLI/error-context.md +24 -0
- finlet-0.0.1/tests/__init__.py +0 -0
- finlet-0.0.1/tests/api/__init__.py +0 -0
- finlet-0.0.1/tests/api/_helpers.py +56 -0
- finlet-0.0.1/tests/api/conftest.py +122 -0
- finlet-0.0.1/tests/api/email_templates/__init__.py +0 -0
- finlet-0.0.1/tests/api/schemas/__init__.py +0 -0
- finlet-0.0.1/tests/api/services/__init__.py +0 -0
- finlet-0.0.1/tests/api/test_api_versioning.py +98 -0
- finlet-0.0.1/tests/api/test_auth.py +363 -0
- finlet-0.0.1/tests/api/test_auth_persistence.py +203 -0
- finlet-0.0.1/tests/api/test_auth_unit.py +68 -0
- finlet-0.0.1/tests/api/test_benchmark_progress.py +300 -0
- finlet-0.0.1/tests/api/test_bug8_limit_stop_fills.py +741 -0
- finlet-0.0.1/tests/api/test_clock.py +194 -0
- finlet-0.0.1/tests/api/test_clock_service.py +327 -0
- finlet-0.0.1/tests/api/test_clock_service_circuit.py +223 -0
- finlet-0.0.1/tests/api/test_config_injection.py +178 -0
- finlet-0.0.1/tests/api/test_cors.py +92 -0
- finlet-0.0.1/tests/api/test_e2e.py +796 -0
- finlet-0.0.1/tests/api/test_e2e_session_flow.py +380 -0
- finlet-0.0.1/tests/api/test_email_config.py +272 -0
- finlet-0.0.1/tests/api/test_email_service.py +672 -0
- finlet-0.0.1/tests/api/test_email_templates.py +538 -0
- finlet-0.0.1/tests/api/test_idempotency.py +193 -0
- finlet-0.0.1/tests/api/test_input_validation.py +408 -0
- finlet-0.0.1/tests/api/test_key_rotation.py +193 -0
- finlet-0.0.1/tests/api/test_leaderboard.py +210 -0
- finlet-0.0.1/tests/api/test_marketplace_gate.py +185 -0
- finlet-0.0.1/tests/api/test_mfa.py +854 -0
- finlet-0.0.1/tests/api/test_middleware_redaction.py +94 -0
- finlet-0.0.1/tests/api/test_password_auth_e2e.py +904 -0
- finlet-0.0.1/tests/api/test_plugin_health.py +160 -0
- finlet-0.0.1/tests/api/test_portfolio.py +63 -0
- finlet-0.0.1/tests/api/test_rate_limit_endpoints.py +354 -0
- finlet-0.0.1/tests/api/test_rate_limiting.py +306 -0
- finlet-0.0.1/tests/api/test_redirect_validation.py +63 -0
- finlet-0.0.1/tests/api/test_routes_auth.py +443 -0
- finlet-0.0.1/tests/api/test_routes_auth_credentials.py +587 -0
- finlet-0.0.1/tests/api/test_routes_billing.py +451 -0
- finlet-0.0.1/tests/api/test_routes_csp.py +88 -0
- finlet-0.0.1/tests/api/test_routes_email.py +506 -0
- finlet-0.0.1/tests/api/test_routes_market.py +304 -0
- finlet-0.0.1/tests/api/test_routes_marketplace_onboarding.py +958 -0
- finlet-0.0.1/tests/api/test_routes_metrics.py +153 -0
- finlet-0.0.1/tests/api/test_routes_mfa.py +849 -0
- finlet-0.0.1/tests/api/test_routes_settings.py +634 -0
- finlet-0.0.1/tests/api/test_security.py +380 -0
- finlet-0.0.1/tests/api/test_security_alerts.py +312 -0
- finlet-0.0.1/tests/api/test_security_hardening.py +260 -0
- finlet-0.0.1/tests/api/test_security_middleware.py +24 -0
- finlet-0.0.1/tests/api/test_security_phase1.py +387 -0
- finlet-0.0.1/tests/api/test_security_phase3.py +496 -0
- finlet-0.0.1/tests/api/test_serializers.py +121 -0
- finlet-0.0.1/tests/api/test_session_auth.py +476 -0
- finlet-0.0.1/tests/api/test_session_complete.py +68 -0
- finlet-0.0.1/tests/api/test_session_fingerprint.py +204 -0
- finlet-0.0.1/tests/api/test_session_isolation.py +105 -0
- finlet-0.0.1/tests/api/test_session_name.py +119 -0
- finlet-0.0.1/tests/api/test_sessions.py +100 -0
- finlet-0.0.1/tests/api/test_sse.py +419 -0
- finlet-0.0.1/tests/api/test_telemetry.py +141 -0
- finlet-0.0.1/tests/api/test_trace_persistence.py +156 -0
- finlet-0.0.1/tests/api/test_trade.py +348 -0
- finlet-0.0.1/tests/api/test_trade_service.py +355 -0
- finlet-0.0.1/tests/auth/__init__.py +0 -0
- finlet-0.0.1/tests/auth/test_password.py +91 -0
- finlet-0.0.1/tests/auth/test_service.py +945 -0
- finlet-0.0.1/tests/billing/__init__.py +0 -0
- finlet-0.0.1/tests/billing/test_billing_service.py +391 -0
- finlet-0.0.1/tests/conftest.py +147 -0
- finlet-0.0.1/tests/core/__init__.py +0 -0
- finlet-0.0.1/tests/core/conftest.py +65 -0
- finlet-0.0.1/tests/core/test_clock.py +583 -0
- finlet-0.0.1/tests/core/test_clock_step_integration.py +784 -0
- finlet-0.0.1/tests/core/test_continuous_clock.py +360 -0
- finlet-0.0.1/tests/core/test_enforcer.py +301 -0
- finlet-0.0.1/tests/core/test_orders.py +598 -0
- finlet-0.0.1/tests/core/test_portfolio.py +631 -0
- finlet-0.0.1/tests/core/test_property_based.py +535 -0
- finlet-0.0.1/tests/core/test_session.py +1052 -0
- finlet-0.0.1/tests/core/test_session_configure.py +189 -0
- finlet-0.0.1/tests/core/test_slippage.py +119 -0
- finlet-0.0.1/tests/core/test_trace.py +279 -0
- finlet-0.0.1/tests/db/__init__.py +0 -0
- finlet-0.0.1/tests/db/test_persistence.py +1499 -0
- finlet-0.0.1/tests/e2e/fixtures.ts +117 -0
- finlet-0.0.1/tests/e2e/global-setup.ts +218 -0
- finlet-0.0.1/tests/e2e/helpers.ts +41 -0
- finlet-0.0.1/tests/e2e/journey-01-landing.spec.ts +61 -0
- finlet-0.0.1/tests/e2e/journey-02-signup.spec.ts +113 -0
- finlet-0.0.1/tests/e2e/journey-03-login.spec.ts +90 -0
- finlet-0.0.1/tests/e2e/journey-04-dashboard.spec.ts +321 -0
- finlet-0.0.1/tests/e2e/journey-05-trade.spec.ts +244 -0
- finlet-0.0.1/tests/e2e/journey-06-settings.spec.ts +199 -0
- finlet-0.0.1/tests/e2e/journey-07-leaderboard.spec.ts +395 -0
- finlet-0.0.1/tests/e2e/journey-08-billing.spec.ts +230 -0
- finlet-0.0.1/tests/e2e/journey-09-mobile.spec.ts +185 -0
- finlet-0.0.1/tests/e2e/journey-10-authguard.spec.ts +154 -0
- finlet-0.0.1/tests/e2e/journey-11-keyboard.spec.ts +186 -0
- finlet-0.0.1/tests/e2e/journey-12-forgot-password.spec.ts +274 -0
- finlet-0.0.1/tests/e2e/journey-13-cli-serve.spec.ts +99 -0
- finlet-0.0.1/tests/e2e/journey-14-cli-session.spec.ts +141 -0
- finlet-0.0.1/tests/e2e/journey-15-cli-plugins.spec.ts +120 -0
- finlet-0.0.1/tests/e2e/playwright.config.ts +41 -0
- finlet-0.0.1/tests/e2e/test_benchmark_flow.py +754 -0
- finlet-0.0.1/tests/e2e/tsconfig.json +14 -0
- finlet-0.0.1/tests/e2e-ux-results/REPORT.md +74 -0
- finlet-0.0.1/tests/e2e-ux-results/batch2-j3-j4-j5-results.md +82 -0
- finlet-0.0.1/tests/e2e-ux-results/playwright-results.json +4236 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/01-landing-cta-click.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/01-landing-final.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/01-landing-initial.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/02-signup-filled.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/02-signup-initial.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/02-signup-redirect.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/02-signup-success.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/02-signup-tab.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/02-signup-validation-empty.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/02-signup-validation-invalid.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/03-login-initial.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/03-login-success.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/03-login-validation.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/03-login-wrong-pw.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/04-clock-freeze.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/04-clock-play.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/04-clock-step.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/04-clock-stop.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/04-dashboard-initial.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/04-session-created.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/04-session-filled.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/04-session-modal.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/05-order-log.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/05-positions.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/05-trade-filled.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/05-trade-pre.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/05-trade-submitted.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/05-trade-ticket-open.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/05-trade-validation.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-apikeys.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-initial.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-plugins.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-profile.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-section-api-keys.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-section-appearance.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-section-data-privacy.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-section-notifications.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-section-plugins.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-section-security.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-security.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-sidebar.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/06-settings-unsaved-banner.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/07-leaderboard-final.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/07-leaderboard-initial.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/07-leaderboard-modal-closed.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/07-leaderboard-result.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/07-leaderboard-submit-modal.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/07-leaderboard-submitting.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/07-leaderboard-validation.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/08-billing-annual.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/08-billing-initial.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/08-billing-monthly.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/09-mobile-auth.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/09-mobile-billing.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/09-mobile-dashboard.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/09-mobile-nav-closed.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/09-mobile-nav-open.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/10-authguard-dashboard.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/10-authguard-landing-ok.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/10-authguard-settings.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/11-kb-arrow-step.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/11-kb-escape-stop.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/11-kb-space-freeze.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/11-kb-space-play.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-code-sent.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-initial.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-login-new-pw.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-otp-entry.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-otp-limitation.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-step1.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-step2-code.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-step3.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/screenshots/12-forgot-step4-success.png +0 -0
- finlet-0.0.1/tests/e2e-ux-results/summary.json +23 -0
- finlet-0.0.1/tests/fixtures/scraper/stockanalysis_aapl.html +51 -0
- finlet-0.0.1/tests/fixtures/scraper/stockanalysis_aapl_live_v2.html +68 -0
- finlet-0.0.1/tests/ingestion/__init__.py +1 -0
- finlet-0.0.1/tests/ingestion/test_base.py +191 -0
- finlet-0.0.1/tests/ingestion/test_s3_writer.py +265 -0
- finlet-0.0.1/tests/ingestion/test_yfinance_provider.py +358 -0
- finlet-0.0.1/tests/leaderboard/__init__.py +0 -0
- finlet-0.0.1/tests/leaderboard/test_api_driven_strategy.py +379 -0
- finlet-0.0.1/tests/leaderboard/test_api_strategy.py +357 -0
- finlet-0.0.1/tests/leaderboard/test_benchmark_completion.py +681 -0
- finlet-0.0.1/tests/leaderboard/test_benchmark_enforcement.py +493 -0
- finlet-0.0.1/tests/leaderboard/test_benchmark_runner.py +640 -0
- finlet-0.0.1/tests/leaderboard/test_benchmark_state.py +519 -0
- finlet-0.0.1/tests/leaderboard/test_leaderboard.py +373 -0
- finlet-0.0.1/tests/leaderboard/test_leaderboard_persistence.py +281 -0
- finlet-0.0.1/tests/leaderboard/test_reporting.py +453 -0
- finlet-0.0.1/tests/marketplace/__init__.py +0 -0
- finlet-0.0.1/tests/marketplace/conftest.py +57 -0
- finlet-0.0.1/tests/marketplace/test_disclaimer_middleware.py +277 -0
- finlet-0.0.1/tests/marketplace/test_disclaimers.py +234 -0
- finlet-0.0.1/tests/marketplace/test_geo_config.py +186 -0
- finlet-0.0.1/tests/marketplace/test_geo_ip.py +94 -0
- finlet-0.0.1/tests/marketplace/test_geo_middleware.py +567 -0
- finlet-0.0.1/tests/marketplace/test_prohibited_claims.py +571 -0
- finlet-0.0.1/tests/marketplace/test_review_compliance.py +516 -0
- finlet-0.0.1/tests/marketplace/test_routes_compliance.py +417 -0
- finlet-0.0.1/tests/marketplace/test_tax.py +266 -0
- finlet-0.0.1/tests/marketplace/test_tax_forms.py +316 -0
- finlet-0.0.1/tests/mcp/__init__.py +0 -0
- finlet-0.0.1/tests/mcp/test_export_benchmark.py +270 -0
- finlet-0.0.1/tests/mcp/test_mcp_auth.py +431 -0
- finlet-0.0.1/tests/mcp/test_mcp_server.py +2353 -0
- finlet-0.0.1/tests/mcp/test_tools_benchmark.py +359 -0
- finlet-0.0.1/tests/plugins/__init__.py +0 -0
- finlet-0.0.1/tests/plugins/conftest.py +30 -0
- finlet-0.0.1/tests/plugins/test_async_thread.py +274 -0
- finlet-0.0.1/tests/plugins/test_cache.py +363 -0
- finlet-0.0.1/tests/plugins/test_circuit_breaker.py +390 -0
- finlet-0.0.1/tests/plugins/test_cross_source_enforcement.py +511 -0
- finlet-0.0.1/tests/plugins/test_econ_plugin.py +1164 -0
- finlet-0.0.1/tests/plugins/test_edgar_plugin.py +264 -0
- finlet-0.0.1/tests/plugins/test_edgar_resilience.py +268 -0
- finlet-0.0.1/tests/plugins/test_finnhub_plugin.py +899 -0
- finlet-0.0.1/tests/plugins/test_finnhub_resilience.py +325 -0
- finlet-0.0.1/tests/plugins/test_fred_plugin.py +381 -0
- finlet-0.0.1/tests/plugins/test_fred_resilience.py +362 -0
- finlet-0.0.1/tests/plugins/test_fundamentals_plugin.py +476 -0
- finlet-0.0.1/tests/plugins/test_integration.py +234 -0
- finlet-0.0.1/tests/plugins/test_new_plugin_registration.py +547 -0
- finlet-0.0.1/tests/plugins/test_news_plugin.py +634 -0
- finlet-0.0.1/tests/plugins/test_price_ceiling_enforcement.py +234 -0
- finlet-0.0.1/tests/plugins/test_price_plugin.py +667 -0
- finlet-0.0.1/tests/plugins/test_registry.py +155 -0
- finlet-0.0.1/tests/plugins/test_retry.py +434 -0
- finlet-0.0.1/tests/plugins/test_sentiment_plugin.py +420 -0
- finlet-0.0.1/tests/scripts/__init__.py +0 -0
- finlet-0.0.1/tests/scripts/conftest.py +25 -0
- finlet-0.0.1/tests/scripts/test_ingest_daily.py +411 -0
- finlet-0.0.1/tests/scripts/test_ingest_edgar.py +1037 -0
- finlet-0.0.1/tests/scripts/test_ingest_fred.py +550 -0
- finlet-0.0.1/tests/scripts/test_ingest_fundamentals.py +460 -0
- finlet-0.0.1/tests/scripts/test_ingest_news.py +426 -0
- finlet-0.0.1/tests/scripts/test_ingest_sectors.py +520 -0
- finlet-0.0.1/tests/scripts/test_ingest_sentiment.py +752 -0
- finlet-0.0.1/tests/scripts/test_ingest_yfinance_prices.py +855 -0
- finlet-0.0.1/tests/test_cli.py +24 -0
- finlet-0.0.1/uv.lock +3597 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "finlet/api/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API Route Rules
|
|
7
|
+
|
|
8
|
+
## FastAPI Patterns
|
|
9
|
+
- Each route file: `router = APIRouter(tags=[...])` — registered in app.py
|
|
10
|
+
- Request/response models as Pydantic `BaseModel` in the same route file
|
|
11
|
+
- Use `HTTPException` for errors with specific detail messages
|
|
12
|
+
- Thin route handlers — delegate business logic to core/domain modules
|
|
13
|
+
|
|
14
|
+
## Authentication
|
|
15
|
+
- All endpoints require `X-API-Key` via Bearer scheme (`require_api_key` dependency)
|
|
16
|
+
- `UserRecord`: id, email, tier, MFA status — injected via `Depends`
|
|
17
|
+
- Session ownership enforced via `get_user_session(session_id, user)` in deps.py
|
|
18
|
+
- Returns 404 for both missing AND unauthorized sessions (no info leakage)
|
|
19
|
+
- Registration rate-limited: 5/hour/IP
|
|
20
|
+
|
|
21
|
+
## Middleware Stack (ordered)
|
|
22
|
+
- `CorrelationIDMiddleware`: X-Request-ID binding to structlog context
|
|
23
|
+
- `SecurityHeadersMiddleware`: X-Frame-Options, CSP, HSTS, etc.
|
|
24
|
+
- `RequestSizeLimitMiddleware`: 413 for bodies > 1MB
|
|
25
|
+
- `CORSMiddleware`: configurable origins
|
|
26
|
+
- Marketplace: `GeoBlockMiddleware`, `DisclaimerInjectionMiddleware`
|
|
27
|
+
|
|
28
|
+
## State Management
|
|
29
|
+
- `state.py`: `get_sessions()`, `get_registry()`, `get_sessions_lock()`
|
|
30
|
+
- Sessions dict and plugin registry are module-level singletons
|
|
31
|
+
- App lifespan: init_engines -> load_all_keys -> load_all_sessions -> run_migrations
|
|
32
|
+
|
|
33
|
+
## Error Codes
|
|
34
|
+
- 404: missing/unauthorized sessions or orders
|
|
35
|
+
- 422: validation errors
|
|
36
|
+
- 429: rate limits (pass through plugin details with reset timing)
|
|
37
|
+
- 503: plugin unavailability
|
|
38
|
+
|
|
39
|
+
## General
|
|
40
|
+
- Use `structlog.get_logger()` for logging
|
|
41
|
+
- Async route handlers — no sync I/O
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "finlet/core/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Core Engine Rules
|
|
7
|
+
|
|
8
|
+
## Simulation Clock (clock.py)
|
|
9
|
+
- Three modes: FROZEN, STEPPING, CONTINUOUS — clock ONLY moves forward on explicit advance
|
|
10
|
+
- `freeze()`, `step(interval)`, `step_to(datetime)`, `play(speed)`, `get_time()`
|
|
11
|
+
- Market hours awareness: skip weekends/after-hours when configured
|
|
12
|
+
- All times stored in UTC — convert only for display
|
|
13
|
+
|
|
14
|
+
## Date Ceiling Enforcer (enforcer.py)
|
|
15
|
+
- Every plugin response passes through `DateCeilingEnforcer` — no exceptions
|
|
16
|
+
- Items with timestamps > ceiling are stripped; items without timestamps excluded by default
|
|
17
|
+
- Log stripped count internally but NEVER expose to the agent (leaks future data existence)
|
|
18
|
+
- `PluginResponse` model lives here, not in plugins
|
|
19
|
+
|
|
20
|
+
## Order System (orders.py)
|
|
21
|
+
- Types: MARKET, LIMIT, STOP with BUY/SELL sides
|
|
22
|
+
- Status flow: PENDING -> FILLED | CANCELLED | REJECTED
|
|
23
|
+
- `OrderBook` uses `asyncio.Lock()` to serialize submissions and fills
|
|
24
|
+
- v1: no slippage, no partial fills, no short selling, no commission
|
|
25
|
+
|
|
26
|
+
## Portfolio (portfolio.py)
|
|
27
|
+
- Tracks cash, positions (with avg_entry_price), realized/unrealized P&L
|
|
28
|
+
- Computed metrics: total_value, sharpe_ratio, max_drawdown, win_rate
|
|
29
|
+
- Equity curve: time series of `EquitySnapshot` for charting
|
|
30
|
+
- All mutations protected by `asyncio.Lock()` for concurrency safety
|
|
31
|
+
- Uses Pydantic `computed_field` for derived values
|
|
32
|
+
|
|
33
|
+
## Session (session.py)
|
|
34
|
+
- Lifecycle: CREATED -> ACTIVE -> PAUSED -> ACTIVE -> COMPLETED
|
|
35
|
+
- Each session owns: clock, portfolio, order book, trace log, user_id
|
|
36
|
+
- `SessionConfig`: start_time, end_time, initial_capital, universe, time_step
|
|
37
|
+
|
|
38
|
+
## General
|
|
39
|
+
- Async functions only — no sync I/O
|
|
40
|
+
- Use `structlog.get_logger()` for logging
|
|
41
|
+
- Pydantic models for all data structures
|
|
42
|
+
- One file per module
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "dashboard/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dashboard Rules
|
|
7
|
+
|
|
8
|
+
## Technology
|
|
9
|
+
- Vanilla HTML + JavaScript + CSS — no build step, no framework
|
|
10
|
+
- Served as static files by FastAPI
|
|
11
|
+
- TradingView Lightweight Charts (free, MIT) via CDN for price/equity curves
|
|
12
|
+
|
|
13
|
+
## Pages
|
|
14
|
+
- `index.html`: Main dashboard — session selector, overview, charts, tables
|
|
15
|
+
- `auth.html` + `auth.js` + `auth.css`: Authentication flow
|
|
16
|
+
- `leaderboard.html` + `leaderboard.js`: Leaderboard display
|
|
17
|
+
- `settings.html` + `settings.js` + `settings.css`: User settings
|
|
18
|
+
- `billing.html` + `billing.js` + `billing.css`: Billing/subscription
|
|
19
|
+
|
|
20
|
+
## Design
|
|
21
|
+
- Dark theme by default, CSS variables for theming
|
|
22
|
+
- Desktop-primary layout
|
|
23
|
+
- Polls session state every 2 seconds
|
|
24
|
+
|
|
25
|
+
## Dashboard Views
|
|
26
|
+
- Session selector: dropdown/sidebar listing sessions
|
|
27
|
+
- Overview panel: sim time, portfolio value, cash, P&L, clock controls
|
|
28
|
+
- Equity curve: portfolio value over sim time with buy-and-hold benchmark
|
|
29
|
+
- Positions table: open positions with color-coded P&L
|
|
30
|
+
- Order log: scrollable table with expandable reasoning
|
|
31
|
+
- Reasoning trace: timeline/feed of agent actions
|
|
32
|
+
- Plugin health: status cards per plugin
|
|
33
|
+
|
|
34
|
+
## API Integration
|
|
35
|
+
- All data fetched from FastAPI REST endpoints
|
|
36
|
+
- Bearer token auth via stored API key
|
|
37
|
+
- Error states shown to user with actionable messages
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "finlet/db/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Database Rules
|
|
7
|
+
|
|
8
|
+
## SQLModel + aiosqlite
|
|
9
|
+
- Models extend `SQLModel` with `table=True`
|
|
10
|
+
- Async engines via `create_async_engine` with `aiosqlite` driver
|
|
11
|
+
- WAL mode enabled on all connections via SQLAlchemy event listeners
|
|
12
|
+
- Engines created once at startup (`init_engines()`), cached, disposed on shutdown
|
|
13
|
+
|
|
14
|
+
## Database Layout
|
|
15
|
+
- Per-session: `~/.finlet/sessions/{session_id}/session.db`
|
|
16
|
+
- Global auth: `~/.finlet/auth.db` (users, API keys)
|
|
17
|
+
- Global leaderboard: in `~/.finlet/finlet.db`
|
|
18
|
+
- Marketplace: `~/.finlet/marketplace.db`
|
|
19
|
+
|
|
20
|
+
## Models (models.py)
|
|
21
|
+
- `SessionModel`, `OrderModel`, `PositionModel`, `PortfolioSnapshotModel`, `TraceEntryModel`
|
|
22
|
+
- `ApiKeyModel` for auth persistence
|
|
23
|
+
- `_utcnow()` helper for consistent UTC timestamps
|
|
24
|
+
- `_new_id()` via `uuid.uuid4()` for primary keys
|
|
25
|
+
|
|
26
|
+
## Persistence (persistence.py)
|
|
27
|
+
- Save after each mutation — no batching or background flushing
|
|
28
|
+
- `save_session()`, `load_all_sessions()`, `delete_session_db()`
|
|
29
|
+
- Uses `structlog.get_logger()` for logging
|
|
30
|
+
|
|
31
|
+
## Migrations (migrations/)
|
|
32
|
+
- Alembic-based, programmatic runner (no subprocess calls)
|
|
33
|
+
- `render_as_batch=True` always for SQLite compatibility
|
|
34
|
+
- Existing DBs without alembic_version are stamped at baseline
|
|
35
|
+
- `run_migrations()` called at app startup
|
|
36
|
+
- `migrate_session_db()` for lazy per-session migration
|
|
37
|
+
|
|
38
|
+
## General
|
|
39
|
+
- Async only — no sync database operations
|
|
40
|
+
- `asyncio.Lock` guards engine creation to prevent races
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "deploy/**"
|
|
4
|
+
- ".github/**"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Deploy & Ops Rules
|
|
8
|
+
|
|
9
|
+
## Infrastructure
|
|
10
|
+
- Systemd services: `finlet.service` (API), `finlet-mcp.service` (MCP)
|
|
11
|
+
- Caddy reverse proxy (Caddyfile)
|
|
12
|
+
- fail2ban integration for brute-force protection
|
|
13
|
+
- logrotate config for log management
|
|
14
|
+
- SQLite backup script (`backup-sqlite.sh`)
|
|
15
|
+
|
|
16
|
+
## Deployment Scripts
|
|
17
|
+
- `deploy.sh`: production deployment
|
|
18
|
+
- `rollback.sh`: rollback to previous version
|
|
19
|
+
- `RUNBOOK.md`: operational procedures
|
|
20
|
+
- `aws/user-data.sh`: cloud-init bootstrap (one-time server setup)
|
|
21
|
+
|
|
22
|
+
## CI/CD Pipeline (.github/workflows/)
|
|
23
|
+
- Pipeline order: ruff lint -> mypy type check -> pip-audit -> pytest -> deploy
|
|
24
|
+
- All checks must pass before deploy
|
|
25
|
+
|
|
26
|
+
## AWS
|
|
27
|
+
- AWS deployment configs in `deploy/aws/`
|
|
28
|
+
|
|
29
|
+
## Conventions
|
|
30
|
+
- Shell scripts must be POSIX-compatible where possible
|
|
31
|
+
- Always test rollback procedures when changing deploy scripts
|
|
32
|
+
- Security: no secrets in config files — use environment variables
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## File Ownership (Agent Teams)
|
|
7
|
+
- `finlet/core/` + `tests/core/` → engine
|
|
8
|
+
- `finlet/plugins/` + `tests/plugins/` → plugins
|
|
9
|
+
- `finlet/api/`, `finlet/mcp/`, `finlet/cli.py` + `tests/api/`, `tests/mcp/`, `tests/test_cli.py` → api
|
|
10
|
+
- `finlet/auth/` + `tests/auth/` → api (auth is L2, owned by api team)
|
|
11
|
+
- `finlet/billing/` + `tests/billing/` → api (billing is L2, owned by api team)
|
|
12
|
+
- `finlet/leaderboard/` + `tests/leaderboard/` → leaderboard
|
|
13
|
+
- `finlet/marketplace/` + `tests/marketplace/` → marketplace
|
|
14
|
+
- `dashboard/` → dashboard
|
|
15
|
+
- `finlet/db/`, `finlet/utils/`, `pyproject.toml`, `README.md` → infra
|
|
16
|
+
- `deploy/`, `.github/` → ops
|
|
17
|
+
- `docs/` → docs
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "finlet/leaderboard/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Leaderboard Rules
|
|
7
|
+
|
|
8
|
+
## Scoring (scoring.py)
|
|
9
|
+
- Composite score: 0.30*sharpe + 0.25*return + 0.25*(1-drawdown) + 0.20*consistency
|
|
10
|
+
- Consistency = 1 - (std_dev / mean) of per-scenario returns
|
|
11
|
+
- All values min-max normalized to [0,1] relative to all entries
|
|
12
|
+
|
|
13
|
+
## Benchmark Scenarios (benchmarks.py)
|
|
14
|
+
- Frozen dataclass `BenchmarkScenario`: id, name, time period, universe, capital
|
|
15
|
+
- 5 standard scenarios with default universe (AAPL, MSFT, etc.)
|
|
16
|
+
- Scenarios are immutable — never modify existing benchmarks
|
|
17
|
+
|
|
18
|
+
## Runner (runner.py)
|
|
19
|
+
- Executes all scenarios for a leaderboard submission
|
|
20
|
+
- Self-play mode: deterministic pseudo-prices (seeded random walk)
|
|
21
|
+
- Reproducible without real market data APIs
|
|
22
|
+
- Uses core Session, OrderBook, Portfolio directly
|
|
23
|
+
|
|
24
|
+
## Profiles (profiles.py)
|
|
25
|
+
- `AgentProfile` with `ScenarioScore` per benchmark
|
|
26
|
+
- Persisted to SQLite via leaderboard_persistence.py
|
|
27
|
+
|
|
28
|
+
## API Strategy (api_strategy.py)
|
|
29
|
+
- Drives agent strategies against the benchmark runner
|
|
30
|
+
|
|
31
|
+
## Rate Limits
|
|
32
|
+
- Benchmark submissions limited to 10/day/user to prevent abuse
|
|
33
|
+
|
|
34
|
+
## General
|
|
35
|
+
- Async functions where applicable
|
|
36
|
+
- Uses stdlib `logging` in runner (not structlog — legacy)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "finlet/marketplace/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Marketplace Rules
|
|
7
|
+
|
|
8
|
+
## Compliance-First Architecture
|
|
9
|
+
- All marketplace code must reference LEGAL_REQUISITES.md for requirements
|
|
10
|
+
- FTC, SEC, and state-level regulations govern marketplace behavior
|
|
11
|
+
- When in doubt, block/restrict rather than allow
|
|
12
|
+
|
|
13
|
+
## Geo-blocking (geo_middleware.py, geo_config.py, geo_ip.py)
|
|
14
|
+
- OFAC-sanctioned countries blocked — returns HTTP 451
|
|
15
|
+
- UK blocked (FCA risk)
|
|
16
|
+
- X-Forwarded-For trust: configure via FINLET_TRUSTED_PROXY_COUNT
|
|
17
|
+
- Exempt paths: health, docs, legal endpoints bypass geo-blocking
|
|
18
|
+
|
|
19
|
+
## Financial Disclaimers (disclaimer_middleware.py, disclaimers.py)
|
|
20
|
+
- Auto-injected into all /marketplace/* responses via middleware
|
|
21
|
+
- Platform-controlled — developers cannot remove or modify
|
|
22
|
+
- Context-aware: different disclaimers for listings, purchases, search, leaderboard
|
|
23
|
+
|
|
24
|
+
## Reviews (review_compliance.py)
|
|
25
|
+
- FTC Consumer Review Rule compliance (effective Oct 2024)
|
|
26
|
+
- Verified purchase required, no sentiment filtering, no self-reviews
|
|
27
|
+
- Sort by recency, not rating — admin can only hide for ToS violations
|
|
28
|
+
|
|
29
|
+
## Tax (tax.py, tax_forms.py)
|
|
30
|
+
- Stripe Tax API for sales tax calculation
|
|
31
|
+
- Tax shown before payment (FTC pre-purchase transparency)
|
|
32
|
+
- All Stripe calls async via httpx
|
|
33
|
+
|
|
34
|
+
## Models & Persistence
|
|
35
|
+
- SQLModel tables in `~/.finlet/marketplace.db`
|
|
36
|
+
- DeveloperProfile, OnboardingSteps, StrategyListing, etc.
|
|
37
|
+
- Stripe Connect for developer payouts
|
|
38
|
+
|
|
39
|
+
## Prohibited Claims (prohibited_claims.py)
|
|
40
|
+
- Automated scanning for SEC-violating claims in strategy descriptions
|
|
41
|
+
- Block guaranteed return claims, misleading performance statements
|
|
42
|
+
|
|
43
|
+
## General
|
|
44
|
+
- Use `structlog.get_logger()` for logging
|
|
45
|
+
- Async functions only
|
|
46
|
+
- Use Pydantic models for request/response validation
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "finlet/mcp/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MCP Server Rules
|
|
7
|
+
|
|
8
|
+
## FastMCP Patterns
|
|
9
|
+
- Single `server.py` using `FastMCP` from `mcp.server.fastmcp`
|
|
10
|
+
- Server name: "finlet" with descriptive instructions string
|
|
11
|
+
- Tools registered as decorated async functions
|
|
12
|
+
|
|
13
|
+
## Tool Registration
|
|
14
|
+
- Each tool has a clear description helping LLMs understand when to use it
|
|
15
|
+
- Include example parameter values in descriptions
|
|
16
|
+
- Tools: get_price_data, search_news, get_fundamentals, get_filings, get_economic_data
|
|
17
|
+
- Trading: submit_order, get_portfolio
|
|
18
|
+
- Clock: get_sim_time, advance_time, freeze_time
|
|
19
|
+
|
|
20
|
+
## Shared Logic
|
|
21
|
+
- Reuse state from `finlet.api.state` (get_sessions, get_registry)
|
|
22
|
+
- Reuse `DateCeilingEnforcer` from core — every data response is enforced
|
|
23
|
+
- Interval map: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w -> seconds
|
|
24
|
+
- `_get_session()` helper validates session exists
|
|
25
|
+
|
|
26
|
+
## Error Handling
|
|
27
|
+
- Return specific, actionable error messages (same standard as API/plugins)
|
|
28
|
+
- Plugin errors surfaced with rate limit details when applicable
|
|
29
|
+
|
|
30
|
+
## General
|
|
31
|
+
- Async functions only
|
|
32
|
+
- Use structlog for logging
|
|
33
|
+
- CLI entry point: `finlet mcp` starts server over stdio
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "finlet/plugins/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Plugin Rules
|
|
7
|
+
|
|
8
|
+
## DataPlugin Interface (base.py)
|
|
9
|
+
- All plugins extend `DataPlugin` ABC with: `initialize()`, `query()`, `health_check()`
|
|
10
|
+
- `plugin_type`: price | news | fundamentals | filings | economic
|
|
11
|
+
- `PluginRegistry` manages loading and routing queries by type
|
|
12
|
+
- `CircuitBreaker` per plugin prevents cascading failures (threshold=5, reset=60s)
|
|
13
|
+
|
|
14
|
+
## PluginResponse Format
|
|
15
|
+
- Return `PluginResponse` from `finlet.core.enforcer` — NOT a custom format
|
|
16
|
+
- Include: items, source, query_params, ceiling_applied, items_pre_filter, items_post_filter
|
|
17
|
+
- Include rate_limit_remaining and rate_limit_reset when applicable
|
|
18
|
+
|
|
19
|
+
## Date Ceiling Enforcer
|
|
20
|
+
- Every query receives `ceiling_time` — filter data to this boundary
|
|
21
|
+
- This is defense-in-depth: plugins filter AND the core enforcer re-filters
|
|
22
|
+
|
|
23
|
+
## Error Messages — MUST be specific and actionable
|
|
24
|
+
- Good: "Finnhub rate limit exceeded: 0/60 calls remaining, resets in 42 seconds"
|
|
25
|
+
- Bad: "API error"
|
|
26
|
+
- Good: "PricePlugin: No data available for ticker 'INVALID'. Check ticker symbol against supported universe"
|
|
27
|
+
- Bad: "Data not found"
|
|
28
|
+
|
|
29
|
+
## Built-in Plugins
|
|
30
|
+
- **price_plugin** (S3 Parquet via pyarrow + boto3): OHLCV from Databento DBEQ.BASIC + Quandl WIKI data lake
|
|
31
|
+
- **edgar_plugin** (edgartools): SEC filings. Filter by `filedAt <= ceiling`
|
|
32
|
+
- **fred_plugin** (fredapi): Economic data. Use ALFRED vintage dates for point-in-time accuracy
|
|
33
|
+
- **finnhub_plugin** (finnhub-python): News + fundamentals. 60 calls/min free tier
|
|
34
|
+
- **econ_plugin**: Economic indicators aggregation
|
|
35
|
+
|
|
36
|
+
## General
|
|
37
|
+
- Use `structlog.get_logger()` — not stdlib logging
|
|
38
|
+
- Use `httpx` for async HTTP calls
|
|
39
|
+
- Async functions only — no sync I/O
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "tests/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Testing Rules
|
|
7
|
+
|
|
8
|
+
## Framework
|
|
9
|
+
- pytest + pytest-asyncio
|
|
10
|
+
- Root conftest at `tests/conftest.py` — shared fixtures (opt-in, no autouse)
|
|
11
|
+
- Local conftest fixtures override root fixtures per pytest scoping rules
|
|
12
|
+
|
|
13
|
+
## Fixtures (from root conftest)
|
|
14
|
+
- `test_app`: TestClient with mocked lifespan (patches slow startup ops)
|
|
15
|
+
- `api_key` / `auth_headers`: creates API key + Bearer header for a test user
|
|
16
|
+
- `isolated_sessions`: clean session dict per test
|
|
17
|
+
- `mock_registry`: PluginRegistry with no real plugins
|
|
18
|
+
- `_run_async()`: helper to run async coroutines from sync test code
|
|
19
|
+
|
|
20
|
+
## Mocking
|
|
21
|
+
- Mock ALL external APIs — no real network calls in tests
|
|
22
|
+
- Mock plugin responses, not the enforcer (enforcer is part of the contract)
|
|
23
|
+
- Use `unittest.mock.patch` or `pytest-mock` for patching
|
|
24
|
+
|
|
25
|
+
## Edge Cases to Test
|
|
26
|
+
- Market hours boundaries (weekends, after-hours transitions)
|
|
27
|
+
- Order fills at price gaps
|
|
28
|
+
- Date ceiling enforcer stripping future data
|
|
29
|
+
- Portfolio metrics with no trades (division by zero guards)
|
|
30
|
+
- Session ownership checks (user A cannot access user B's session)
|
|
31
|
+
- Rate limit boundaries
|
|
32
|
+
|
|
33
|
+
## Conventions
|
|
34
|
+
- Test files mirror source structure: `tests/core/`, `tests/plugins/`, etc.
|
|
35
|
+
- One test file per source module
|
|
36
|
+
- Descriptive test names: `test_enforcer_strips_future_items`
|
|
37
|
+
- Use `pytest.raises` for expected exceptions
|
|
38
|
+
|
|
39
|
+
## CI Pipeline
|
|
40
|
+
- ruff lint -> mypy type check -> pip-audit -> pytest -> deploy
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-order-type
|
|
3
|
+
description: Scaffold a new order type in Finlet's trading engine. Use when the user wants to add a new order type like TRAILING_STOP, OCO, or BRACKET to the order system.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
argument-hint: <order-type-name>
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Add a New Order Type
|
|
9
|
+
|
|
10
|
+
Add a new order type `$ARGUMENTS` to Finlet's trading engine.
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
### 1. Add to OrderType enum
|
|
15
|
+
|
|
16
|
+
In `finlet/core/orders.py`, add the new type to the `OrderType` enum.
|
|
17
|
+
|
|
18
|
+
### 2. Implement fill logic
|
|
19
|
+
|
|
20
|
+
In the OrderBook class, add fill logic for the new order type:
|
|
21
|
+
- When does it trigger?
|
|
22
|
+
- What price does it fill at?
|
|
23
|
+
- What are the edge cases?
|
|
24
|
+
|
|
25
|
+
### 3. Add API route support
|
|
26
|
+
|
|
27
|
+
Update `finlet/api/routes_trade.py` to accept the new order type in request validation.
|
|
28
|
+
|
|
29
|
+
### 4. Add MCP tool support
|
|
30
|
+
|
|
31
|
+
Update `finlet/mcp/server.py` to document the new order type in the `submit_order` tool description.
|
|
32
|
+
|
|
33
|
+
### 5. Write tests
|
|
34
|
+
|
|
35
|
+
In `tests/core/test_orders.py`:
|
|
36
|
+
- Test order creation with new type
|
|
37
|
+
- Test fill conditions
|
|
38
|
+
- Test cancellation
|
|
39
|
+
- Test edge cases (price gaps, market hours boundaries)
|
|
40
|
+
|
|
41
|
+
### 6. Update documentation
|
|
42
|
+
|
|
43
|
+
If the new order type has non-obvious behavior, add a note to `docs/ARCHITECTURE.md` under the Order System section.
|
|
44
|
+
|
|
45
|
+
### 7. Verify
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pytest tests/core/test_orders.py tests/api/test_routes_trade.py -v
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Reference
|
|
52
|
+
|
|
53
|
+
- `finlet/core/orders.py` — OrderType enum, Order model, OrderBook
|
|
54
|
+
- `docs/ARCHITECTURE.md` — Order system specification
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-conventions
|
|
3
|
+
description: Finlet API development conventions and patterns. Applies when writing or modifying FastAPI routes, MCP tools, or CLI commands — covers authentication, session ownership, error responses, and route organization.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# API Development Conventions
|
|
8
|
+
|
|
9
|
+
These conventions apply when working on `finlet/api/`, `finlet/mcp/`, and `finlet/cli.py`.
|
|
10
|
+
|
|
11
|
+
## Authentication
|
|
12
|
+
- All endpoints require a valid `Authorization: Bearer <key>` header (FastAPI `HTTPBearer` scheme)
|
|
13
|
+
- Use the `require_api_key` dependency for protected endpoints; it validates the Bearer token and returns a `UserRecord`
|
|
14
|
+
- Use `optional_api_key` for public endpoints that gain features with auth
|
|
15
|
+
- API keys are 32-char hex tokens, SHA-256 hashed before storage, persisted to SQLite with in-memory cache
|
|
16
|
+
- Registration is rate-limited to 5 per hour per IP
|
|
17
|
+
- Session ownership is enforced — keys can only access their own sessions
|
|
18
|
+
|
|
19
|
+
## Route Organization
|
|
20
|
+
- One route file per resource domain: `routes_session.py`, `routes_clock.py`, etc.
|
|
21
|
+
- Each route file defines a FastAPI `APIRouter`
|
|
22
|
+
- Routers are registered in `finlet/api/app.py`
|
|
23
|
+
|
|
24
|
+
## Error Responses
|
|
25
|
+
- `422` — Validation errors (Pydantic)
|
|
26
|
+
- `404` — Missing sessions/orders
|
|
27
|
+
- `429` — Rate limits (pass through from plugins with reset timing)
|
|
28
|
+
- `503` — Plugin unavailability
|
|
29
|
+
|
|
30
|
+
## Session Ownership
|
|
31
|
+
- Every endpoint that accesses a session must verify ownership
|
|
32
|
+
- Use the dependency injection pattern from `finlet/api/deps.py`
|
|
33
|
+
- Never allow cross-user session access
|
|
34
|
+
|
|
35
|
+
## MCP Server
|
|
36
|
+
- Tools mirror REST API functionality
|
|
37
|
+
- Each tool has a clear description to help LLMs understand when to use it
|
|
38
|
+
- Include example parameter values in descriptions
|
|
39
|
+
- Tool names: `get_price_data`, `search_news`, `get_fundamentals`, `get_filings`, `get_economic_data`, `submit_order`, `get_portfolio`, `get_sim_time`, `advance_time`, `freeze_time`
|
|
40
|
+
|
|
41
|
+
## CLI (typer)
|
|
42
|
+
- `finlet serve` — Start API server + serve dashboard
|
|
43
|
+
- `finlet session create/list` — Session management
|
|
44
|
+
- `finlet plugins list/add` — Plugin management
|
|
45
|
+
- `finlet mcp` — Start MCP server over stdio
|
|
46
|
+
|
|
47
|
+
## Middleware
|
|
48
|
+
- Security middleware in `finlet/api/security_middleware.py`
|
|
49
|
+
- Rate limiting in `finlet/api/rate_limit.py`
|
|
50
|
+
- All middleware is async
|