seam-code 0.3.0__tar.gz → 0.5.0__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.
Files changed (533) hide show
  1. seam_code-0.5.0/.github/CODEOWNERS +3 -0
  2. seam_code-0.5.0/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  3. seam_code-0.5.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  4. seam_code-0.5.0/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
  5. seam_code-0.5.0/.github/PULL_REQUEST_TEMPLATE.md +24 -0
  6. seam_code-0.5.0/.github/dependabot.yml +23 -0
  7. seam_code-0.5.0/.github/workflows/ci.yml +52 -0
  8. seam_code-0.5.0/.github/workflows/explorer-visual.yml +66 -0
  9. seam_code-0.5.0/.github/workflows/no-egress.yml +147 -0
  10. seam_code-0.5.0/.github/workflows/release.yml +197 -0
  11. seam_code-0.5.0/.github/workflows/seam-index.yml +161 -0
  12. {seam_code-0.3.0 → seam_code-0.5.0}/.gitignore +7 -2
  13. seam_code-0.5.0/AGENTS.md +33 -0
  14. seam_code-0.5.0/CHANGELOG.md +134 -0
  15. {seam_code-0.3.0 → seam_code-0.5.0}/CLAUDE.md +536 -136
  16. seam_code-0.5.0/CODE_OF_CONDUCT.md +39 -0
  17. seam_code-0.5.0/CONTRIBUTING.md +101 -0
  18. {seam_code-0.3.0 → seam_code-0.5.0}/DISCOVERY.md +1 -1
  19. {seam_code-0.3.0 → seam_code-0.5.0}/IMPLEMENTATION_PLAN.md +1 -1
  20. seam_code-0.5.0/Makefile +127 -0
  21. seam_code-0.5.0/PKG-INFO +572 -0
  22. seam_code-0.5.0/README.md +527 -0
  23. seam_code-0.5.0/SECURITY.md +57 -0
  24. {seam_code-0.3.0 → seam_code-0.5.0}/TECH_STACK.md +0 -1
  25. seam_code-0.5.0/benchmarks/semantic_ann_scale.py +565 -0
  26. seam_code-0.5.0/benchmarks/semantic_recall.py +498 -0
  27. seam_code-0.5.0/benchmarks/soak.py +158 -0
  28. seam_code-0.5.0/benchmarks/trace_loop.py +336 -0
  29. {seam_code-0.3.0 → seam_code-0.5.0}/docs/ARCHITECTURE.md +157 -15
  30. {seam_code-0.3.0 → seam_code-0.5.0}/docs/CONCEPTS.md +104 -9
  31. {seam_code-0.3.0 → seam_code-0.5.0}/docs/CONFIGURATION.md +48 -2
  32. {seam_code-0.3.0 → seam_code-0.5.0}/docs/CONTRACT.md +1 -1
  33. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/001-python-over-typescript.md +1 -1
  34. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/002-sqlite-storage.md +1 -1
  35. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/003-heuristic-execution-flows.md +1 -1
  36. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/005-phase0-language-scope.md +1 -1
  37. seam_code-0.5.0/docs/agent-answerability-benchmark.md +137 -0
  38. {seam_code-0.3.0 → seam_code-0.5.0}/docs/api-contracts/mcp-tools.yaml +821 -30
  39. {seam_code-0.3.0 → seam_code-0.5.0}/docs/architecture.html +16 -10
  40. seam_code-0.5.0/docs/assets/demo.tape +56 -0
  41. seam_code-0.5.0/docs/assets/seam-demo.gif +0 -0
  42. seam_code-0.5.0/docs/assets/seam-hero.png +0 -0
  43. {seam_code-0.3.0 → seam_code-0.5.0}/docs/benchmark.md +1 -1
  44. {seam_code-0.3.0 → seam_code-0.5.0}/docs/competitive-benchmark.md +30 -33
  45. {seam_code-0.3.0 → seam_code-0.5.0}/docs/database/schema.sql +145 -12
  46. seam_code-0.5.0/docs/docs-grounding-architecture.md +181 -0
  47. seam_code-0.5.0/docs/graph-search-recipes.md +69 -0
  48. seam_code-0.5.0/docs/prd/agent-answerability-benchmark.md +348 -0
  49. seam_code-0.5.0/docs/prd/graph-search-recipes.md +106 -0
  50. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase1-core.md +3 -3
  51. seam_code-0.5.0/docs/prd/phase11-codebase-memory-roadmap.md +168 -0
  52. seam_code-0.5.0/docs/prd/phase11-explorer-3d-constellation-polish.md +266 -0
  53. seam_code-0.5.0/docs/prd/phase11-explorer-cleanup.md +216 -0
  54. seam_code-0.5.0/docs/prd/phase11-explorer-phase-b.md +404 -0
  55. seam_code-0.5.0/docs/prd/phase11-explorer-phase-c.md +308 -0
  56. seam_code-0.5.0/docs/prd/phase11-explorer-phase-d.md +226 -0
  57. seam_code-0.5.0/docs/prd/phase11-explorer-redesign.md +171 -0
  58. seam_code-0.5.0/docs/prd/phase11-explorer-topology-visual-qa.md +293 -0
  59. seam_code-0.5.0/docs/prd/phase11-p1-1-seam-schema.md +419 -0
  60. seam_code-0.5.0/docs/prd/phase11-p1-4-seam-architecture.md +371 -0
  61. seam_code-0.5.0/docs/prd/phase11-p2-1-3d-constellation-reference.md +757 -0
  62. seam_code-0.5.0/docs/prd/phase11-p2-1-3d-constellation.md +260 -0
  63. seam_code-0.5.0/docs/prd/phase11-p2-2-explorer-upgrades.md +422 -0
  64. seam_code-0.5.0/docs/prd/phase11-p3-1-route-nodes-http-calls.md +298 -0
  65. seam_code-0.5.0/docs/prd/phase11-p3-2-config-resource-links.md +406 -0
  66. seam_code-0.5.0/docs/prd/phase11-p3-3-test-edges.md +273 -0
  67. seam_code-0.5.0/docs/prd/phase11-p3-4-raises-exception-edges.md +340 -0
  68. seam_code-0.5.0/docs/prd/phase11-p5-1-npm-shim.md +217 -0
  69. seam_code-0.5.0/docs/prd/phase11-p5-2-release-hardening.md +123 -0
  70. seam_code-0.5.0/docs/prd/phase11-p5-3-installer-write-scope-audit.md +126 -0
  71. seam_code-0.5.0/docs/prd/phase11-p5-4-no-egress-proof.md +111 -0
  72. seam_code-0.5.0/docs/prd/phase11-p5-5-diagnostics-soak.md +129 -0
  73. seam_code-0.5.0/docs/prd/phase11-rfc-cross-repo-analysis.md +390 -0
  74. seam_code-0.5.0/docs/prd/phase11-rfc-graph-artifact-export-import.md +404 -0
  75. seam_code-0.5.0/docs/prd/phase11-rfc-hybrid-exact-type-resolution.md +426 -0
  76. seam_code-0.5.0/docs/prd/phase11-rfc-infra-graph-compose-dockerfile.md +513 -0
  77. seam_code-0.5.0/docs/prd/phase11-rfc-protocol-edges-http-calls.md +342 -0
  78. seam_code-0.5.0/docs/prd/seam-serve-auto-init.md +149 -0
  79. seam_code-0.5.0/docs/prd/ws6-1-trace-capture-loop.md +213 -0
  80. seam_code-0.5.0/docs/superpowers/plans/2026-07-01-3d-constellation-explorer.md +1195 -0
  81. seam_code-0.5.0/docs/superpowers/plans/review-2026-07-01/review-3d-constellation-explorer-2026-07-01.md +115 -0
  82. seam_code-0.5.0/docs/superpowers/runs/constellation-impl/implementation-notes.md +481 -0
  83. seam_code-0.5.0/docs/superpowers/runs/serve-auto-init/implementation-notes.md +225 -0
  84. seam_code-0.5.0/docs/superpowers/specs/2026-07-01-3d-constellation-explorer-design.md +183 -0
  85. seam_code-0.5.0/logs/engram-api.log +3 -0
  86. seam_code-0.5.0/pkg/npm/README.md +56 -0
  87. seam_code-0.5.0/pkg/npm/bin.js +66 -0
  88. seam_code-0.5.0/pkg/npm/lib/invocation.js +108 -0
  89. seam_code-0.5.0/pkg/npm/lib/invocation.test.js +138 -0
  90. seam_code-0.5.0/pkg/npm/package-lock.json +1631 -0
  91. seam_code-0.5.0/pkg/npm/package.json +31 -0
  92. {seam_code-0.3.0 → seam_code-0.5.0}/pyproject.toml +20 -6
  93. {seam_code-0.3.0 → seam_code-0.5.0}/seam/__init__.py +1 -1
  94. seam_code-0.5.0/seam/_web/assets/ConstellationTab-D7ASy9pv.js +4294 -0
  95. seam_code-0.5.0/seam/_web/assets/index-BmbgLrO-.js +270 -0
  96. seam_code-0.3.0/seam/_web/assets/index-GTKUhVyD.css → seam_code-0.5.0/seam/_web/assets/index-hKqjXbnV.css +1 -1
  97. {seam_code-0.3.0 → seam_code-0.5.0}/seam/_web/index.html +2 -2
  98. seam_code-0.5.0/seam/analysis/diagnostics.py +450 -0
  99. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/embeddings.py +116 -2
  100. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/flows.py +4 -2
  101. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/impact.py +23 -4
  102. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/testpaths.py +61 -4
  103. seam_code-0.5.0/seam/analysis/trace_capture.py +382 -0
  104. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/traversal.py +15 -2
  105. seam_code-0.5.0/seam/cli/architecture.py +121 -0
  106. seam_code-0.5.0/seam/cli/artifacts.py +238 -0
  107. seam_code-0.5.0/seam/cli/fetch.py +485 -0
  108. seam_code-0.5.0/seam/cli/file_sink.py +412 -0
  109. seam_code-0.5.0/seam/cli/graph_search.py +193 -0
  110. seam_code-0.5.0/seam/cli/grounding.py +136 -0
  111. {seam_code-0.3.0 → seam_code-0.5.0}/seam/cli/install.py +7 -4
  112. {seam_code-0.3.0 → seam_code-0.5.0}/seam/cli/main.py +988 -125
  113. seam_code-0.5.0/seam/cli/plan.py +160 -0
  114. {seam_code-0.3.0 → seam_code-0.5.0}/seam/cli/read.py +152 -8
  115. seam_code-0.5.0/seam/cli/schema.py +106 -0
  116. {seam_code-0.3.0 → seam_code-0.5.0}/seam/cli/serve.py +103 -25
  117. seam_code-0.5.0/seam/cli/snippet.py +115 -0
  118. seam_code-0.5.0/seam/cli/suspects.py +134 -0
  119. seam_code-0.5.0/seam/cli/workspace.py +377 -0
  120. {seam_code-0.3.0 → seam_code-0.5.0}/seam/config.py +219 -5
  121. seam_code-0.5.0/seam/eval/trace_derive.py +319 -0
  122. seam_code-0.5.0/seam/indexer/artifact.py +610 -0
  123. seam_code-0.5.0/seam/indexer/config_resources.py +703 -0
  124. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/db.py +254 -8
  125. seam_code-0.5.0/seam/indexer/docs.py +483 -0
  126. seam_code-0.5.0/seam/indexer/embedding_index.py +740 -0
  127. seam_code-0.5.0/seam/indexer/exceptions.py +201 -0
  128. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph.py +6 -0
  129. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_common.py +65 -2
  130. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_python.py +6 -3
  131. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_scope_infer.py +389 -51
  132. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_typescript.py +6 -3
  133. seam_code-0.5.0/seam/indexer/infra_resources.py +980 -0
  134. seam_code-0.5.0/seam/indexer/init_index.py +239 -0
  135. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/migrations.py +316 -1
  136. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/pipeline.py +99 -16
  137. seam_code-0.5.0/seam/indexer/readonly.py +23 -0
  138. seam_code-0.5.0/seam/indexer/rebase.py +218 -0
  139. seam_code-0.5.0/seam/indexer/routes.py +553 -0
  140. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/sync.py +18 -3
  141. seam_code-0.5.0/seam/indexer/test_edges.py +287 -0
  142. seam_code-0.5.0/seam/indexer/vec_index.py +246 -0
  143. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/__init__.py +6 -0
  144. seam_code-0.5.0/seam/installer/gemini.py +68 -0
  145. seam_code-0.5.0/seam/installer/vscode.py +69 -0
  146. seam_code-0.5.0/seam/installer/zed.py +76 -0
  147. seam_code-0.5.0/seam/query/architecture.py +1497 -0
  148. {seam_code-0.3.0 → seam_code-0.5.0}/seam/query/context.py +51 -0
  149. {seam_code-0.3.0 → seam_code-0.5.0}/seam/query/engine.py +4 -0
  150. seam_code-0.5.0/seam/query/graph_recipes.py +290 -0
  151. seam_code-0.5.0/seam/query/graph_search.py +951 -0
  152. seam_code-0.5.0/seam/query/grounding.py +367 -0
  153. seam_code-0.5.0/seam/query/layout.py +742 -0
  154. {seam_code-0.3.0 → seam_code-0.5.0}/seam/query/pack.py +152 -2
  155. seam_code-0.5.0/seam/query/pack_evidence.py +161 -0
  156. seam_code-0.5.0/seam/query/plan.py +571 -0
  157. seam_code-0.5.0/seam/query/schema.py +481 -0
  158. seam_code-0.5.0/seam/query/semantic.py +592 -0
  159. seam_code-0.5.0/seam/query/snippet.py +585 -0
  160. seam_code-0.5.0/seam/query/suspects.py +780 -0
  161. seam_code-0.5.0/seam/query/vec_extension.py +231 -0
  162. seam_code-0.5.0/seam/query/vector_store.py +591 -0
  163. {seam_code-0.3.0 → seam_code-0.5.0}/seam/server/graph_api.py +231 -30
  164. seam_code-0.5.0/seam/server/grounding_handler.py +52 -0
  165. {seam_code-0.3.0 → seam_code-0.5.0}/seam/server/mcp.py +411 -16
  166. seam_code-0.5.0/seam/server/suspects_handler.py +52 -0
  167. {seam_code-0.3.0 → seam_code-0.5.0}/seam/server/tools.py +281 -3
  168. {seam_code-0.3.0 → seam_code-0.5.0}/seam/server/trace_handler.py +3 -1
  169. {seam_code-0.3.0 → seam_code-0.5.0}/seam/server/web.py +172 -96
  170. seam_code-0.5.0/seam/server/web_architecture.py +81 -0
  171. seam_code-0.5.0/seam/server/web_graph_search.py +113 -0
  172. seam_code-0.5.0/seam/server/web_layout.py +150 -0
  173. seam_code-0.5.0/seam/server/web_schema.py +444 -0
  174. {seam_code-0.3.0 → seam_code-0.5.0}/seam/watcher/daemon.py +18 -3
  175. seam_code-0.5.0/seam/workspace/__init__.py +2 -0
  176. seam_code-0.5.0/seam/workspace/federation.py +635 -0
  177. seam_code-0.5.0/seam/workspace/registry.py +213 -0
  178. seam_code-0.5.0/tests/eval/answerability_harness.py +678 -0
  179. seam_code-0.5.0/tests/eval/answerability_report.py +80 -0
  180. seam_code-0.5.0/tests/eval/answerability_scenarios.json +305 -0
  181. seam_code-0.5.0/tests/eval/fixtures/docs/order-processing-prd.md +10 -0
  182. seam_code-0.5.0/tests/eval/test_answerability.py +202 -0
  183. seam_code-0.5.0/tests/integration/test_artifact_lifecycle.py +244 -0
  184. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_cli_e4_surface.py +6 -6
  185. seam_code-0.5.0/tests/integration/test_cli_impact_index_status.py +93 -0
  186. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_cli_impact_max_bytes.py +6 -6
  187. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_cli_json.py +26 -1
  188. seam_code-0.5.0/tests/integration/test_cli_version.py +29 -0
  189. seam_code-0.5.0/tests/integration/test_diagnostics_cli.py +112 -0
  190. seam_code-0.5.0/tests/integration/test_diagnostics_mcp.py +177 -0
  191. seam_code-0.5.0/tests/integration/test_diagnostics_watcher.py +111 -0
  192. seam_code-0.5.0/tests/integration/test_embedding_index_body.py +357 -0
  193. seam_code-0.5.0/tests/integration/test_embedding_index_comments.py +376 -0
  194. seam_code-0.5.0/tests/integration/test_fetch.py +687 -0
  195. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_flows_handler.py +2 -2
  196. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_impact_handler.py +27 -2
  197. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_impact_summary_parity.py +2 -2
  198. seam_code-0.5.0/tests/integration/test_install_cli.py +420 -0
  199. seam_code-0.5.0/tests/integration/test_installer_write_scope.py +845 -0
  200. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_lean_parity.py +13 -2
  201. seam_code-0.5.0/tests/integration/test_migration_v13.py +152 -0
  202. seam_code-0.5.0/tests/integration/test_migration_v14.py +179 -0
  203. seam_code-0.5.0/tests/integration/test_migration_v15.py +181 -0
  204. seam_code-0.5.0/tests/integration/test_npm_shim.py +228 -0
  205. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_pack_parity.py +33 -0
  206. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_phase5_read_layer.py +4 -4
  207. seam_code-0.5.0/tests/integration/test_scan_cap_unlimited.py +344 -0
  208. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_semantic_surfaces.py +13 -10
  209. seam_code-0.5.0/tests/integration/test_serve_cli.py +302 -0
  210. seam_code-0.5.0/tests/integration/test_soak_smoke.py +75 -0
  211. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_sync_cli.py +37 -0
  212. seam_code-0.5.0/tests/integration/test_sync_embeddings.py +615 -0
  213. seam_code-0.5.0/tests/integration/test_to_file.py +476 -0
  214. seam_code-0.5.0/tests/integration/test_trace_loop.py +466 -0
  215. seam_code-0.5.0/tests/integration/test_vector_store_fallback.py +315 -0
  216. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_watcher.py +12 -0
  217. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_web_api.py +299 -6
  218. seam_code-0.5.0/tests/integration/test_web_layout.py +74 -0
  219. seam_code-0.5.0/tests/integration/test_workspace_cli.py +376 -0
  220. seam_code-0.5.0/tests/support/__init__.py +1 -0
  221. seam_code-0.5.0/tests/support/actions_pin_audit.py +164 -0
  222. seam_code-0.5.0/tests/support/egress_audit.py +219 -0
  223. seam_code-0.5.0/tests/support/fs_audit.py +120 -0
  224. seam_code-0.5.0/tests/support/mcp_smoke.py +171 -0
  225. seam_code-0.5.0/tests/unit/__init__.py +0 -0
  226. seam_code-0.5.0/tests/unit/test_actions_pin_audit.py +260 -0
  227. seam_code-0.5.0/tests/unit/test_architecture_tool.py +523 -0
  228. seam_code-0.5.0/tests/unit/test_artifact.py +578 -0
  229. seam_code-0.5.0/tests/unit/test_config_resources.py +492 -0
  230. seam_code-0.5.0/tests/unit/test_diagnostics.py +486 -0
  231. seam_code-0.5.0/tests/unit/test_egress_audit.py +396 -0
  232. seam_code-0.5.0/tests/unit/test_embeddings_body.py +250 -0
  233. seam_code-0.5.0/tests/unit/test_embeddings_comments.py +278 -0
  234. seam_code-0.5.0/tests/unit/test_exception_edges.py +211 -0
  235. seam_code-0.5.0/tests/unit/test_file_sink.py +573 -0
  236. seam_code-0.5.0/tests/unit/test_fs_audit.py +257 -0
  237. seam_code-0.5.0/tests/unit/test_graph_api.py +965 -0
  238. seam_code-0.5.0/tests/unit/test_graph_search.py +596 -0
  239. seam_code-0.5.0/tests/unit/test_grounding.py +204 -0
  240. seam_code-0.5.0/tests/unit/test_hybrid_exact_type_resolution.py +126 -0
  241. seam_code-0.5.0/tests/unit/test_init_index.py +166 -0
  242. seam_code-0.5.0/tests/unit/test_installer.py +744 -0
  243. seam_code-0.5.0/tests/unit/test_layout.py +419 -0
  244. seam_code-0.5.0/tests/unit/test_outcome_signal.py +246 -0
  245. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_pack.py +131 -0
  246. seam_code-0.5.0/tests/unit/test_plan.py +389 -0
  247. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_query_engine.py +18 -0
  248. seam_code-0.5.0/tests/unit/test_rebase.py +434 -0
  249. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_review_fixes.py +8 -3
  250. seam_code-0.5.0/tests/unit/test_routes.py +531 -0
  251. seam_code-0.5.0/tests/unit/test_schema_tool.py +408 -0
  252. seam_code-0.5.0/tests/unit/test_scoped_embedding.py +721 -0
  253. seam_code-0.5.0/tests/unit/test_semantic_ann_bench_smoke.py +190 -0
  254. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_semantic_review_fixes.py +9 -6
  255. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_smoke.py +20 -0
  256. seam_code-0.5.0/tests/unit/test_snippet_tool.py +318 -0
  257. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_structure.py +4 -4
  258. seam_code-0.5.0/tests/unit/test_suspects.py +337 -0
  259. seam_code-0.5.0/tests/unit/test_test_edges.py +249 -0
  260. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_testpaths.py +106 -2
  261. seam_code-0.5.0/tests/unit/test_trace_capture.py +663 -0
  262. seam_code-0.5.0/tests/unit/test_trace_derive.py +393 -0
  263. seam_code-0.5.0/tests/unit/test_vec_extension.py +496 -0
  264. seam_code-0.5.0/tests/unit/test_vec_index.py +638 -0
  265. seam_code-0.5.0/tests/unit/test_vec_read_path.py +790 -0
  266. seam_code-0.5.0/tests/unit/test_vector_store.py +452 -0
  267. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_web_packaging.py +1 -1
  268. {seam_code-0.3.0 → seam_code-0.5.0}/uv.lock +25 -3
  269. seam_code-0.3.0/AGENTS.md +0 -101
  270. seam_code-0.3.0/Makefile +0 -59
  271. seam_code-0.3.0/PKG-INFO +0 -318
  272. seam_code-0.3.0/README.md +0 -276
  273. seam_code-0.3.0/benchmarks/semantic_recall.py +0 -298
  274. seam_code-0.3.0/docs/assets/seam-hero.png +0 -0
  275. seam_code-0.3.0/lessons.md +0 -108
  276. seam_code-0.3.0/memory/architecture/001-graph-model.md +0 -11
  277. seam_code-0.3.0/memory/decisions/001-language-python.md +0 -9
  278. seam_code-0.3.0/progress.txt +0 -862
  279. seam_code-0.3.0/seam/_web/assets/index-BL_tqprR.js +0 -216
  280. seam_code-0.3.0/seam/indexer/embedding_index.py +0 -183
  281. seam_code-0.3.0/seam/query/semantic.py +0 -339
  282. seam_code-0.3.0/tests/integration/test_install_cli.py +0 -160
  283. seam_code-0.3.0/tests/integration/test_serve_cli.py +0 -120
  284. seam_code-0.3.0/tests/unit/test_graph_api.py +0 -493
  285. seam_code-0.3.0/tests/unit/test_installer.py +0 -349
  286. {seam_code-0.3.0 → seam_code-0.5.0}/.env.example +0 -0
  287. {seam_code-0.3.0 → seam_code-0.5.0}/APP_FLOW.md +0 -0
  288. {seam_code-0.3.0 → seam_code-0.5.0}/BACKEND_STRUCTURE.md +0 -0
  289. {seam_code-0.3.0 → seam_code-0.5.0}/CONTEXT.md +0 -0
  290. {seam_code-0.3.0 → seam_code-0.5.0}/LICENSE +0 -0
  291. {seam_code-0.3.0 → seam_code-0.5.0}/PRD.md +0 -0
  292. {seam_code-0.3.0 → seam_code-0.5.0}/benchmarks/run_benchmark.py +0 -0
  293. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/004-watchdog-file-watcher.md +0 -0
  294. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/008-language-expansion.md +0 -0
  295. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/009-swift-support.md +0 -0
  296. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/010-frontend-explorer-architecture.md +0 -0
  297. {seam_code-0.3.0 → seam_code-0.5.0}/docs/adr/ADR-007-louvain-clustering.md +0 -0
  298. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase10-swift.md +0 -0
  299. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase1b-confidence.md +0 -0
  300. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase1b-go-rust.md +0 -0
  301. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase1b-qa-hardening.md +0 -0
  302. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase1b-seam-why.md +0 -0
  303. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase2-clustering.md +0 -0
  304. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase3-agent-interface.md +0 -0
  305. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase4-node-enrichment.md +0 -0
  306. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase5-import-resolution.md +0 -0
  307. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase6-context-pack.md +0 -0
  308. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase7-seam-sync.md +0 -0
  309. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase8-lean-output.md +0 -0
  310. {seam_code-0.3.0 → seam_code-0.5.0}/docs/prd/phase9-language-expansion.md +0 -0
  311. /seam_code-0.3.0/memory/learnings/.gitkeep → /seam_code-0.5.0/logs/engram-jobs.log +0 -0
  312. /seam_code-0.3.0/memory/patterns/.gitkeep → /seam_code-0.5.0/logs/engram-session-capture.log +0 -0
  313. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/__init__.py +0 -0
  314. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/affected.py +0 -0
  315. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/builtins.py +0 -0
  316. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/byte_budget.py +0 -0
  317. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/changes.py +0 -0
  318. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/cluster_naming.py +0 -0
  319. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/clustering.py +0 -0
  320. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/confidence.py +0 -0
  321. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/imports.py +0 -0
  322. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/imports_ext.py +0 -0
  323. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/imports_resolve.py +0 -0
  324. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/processes.py +0 -0
  325. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/relevance.py +0 -0
  326. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/rwr.py +0 -0
  327. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/staleness.py +0 -0
  328. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/steer.py +0 -0
  329. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/synthesis.py +0 -0
  330. {seam_code-0.3.0 → seam_code-0.5.0}/seam/analysis/synthesis_channels.py +0 -0
  331. {seam_code-0.3.0 → seam_code-0.5.0}/seam/cli/__init__.py +0 -0
  332. {seam_code-0.3.0 → seam_code-0.5.0}/seam/cli/output.py +0 -0
  333. {seam_code-0.3.0/seam/indexer → seam_code-0.5.0/seam/eval}/__init__.py +0 -0
  334. {seam_code-0.3.0/seam/query → seam_code-0.5.0/seam/indexer}/__init__.py +0 -0
  335. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/cluster_index.py +0 -0
  336. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/field_access.py +0 -0
  337. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/field_access_c_cpp.py +0 -0
  338. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/field_access_ext.py +0 -0
  339. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/field_access_ext2.py +0 -0
  340. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/field_access_go_rust.py +0 -0
  341. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/field_access_php_swift.py +0 -0
  342. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/field_access_ts.py +0 -0
  343. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_c.py +0 -0
  344. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_c_cpp.py +0 -0
  345. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_cpp.py +0 -0
  346. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_csharp.py +0 -0
  347. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_go.py +0 -0
  348. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_go_rust.py +0 -0
  349. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_java.py +0 -0
  350. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_java_csharp.py +0 -0
  351. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_php.py +0 -0
  352. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_ruby.py +0 -0
  353. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_rust.py +0 -0
  354. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_scope_infer_ext.py +0 -0
  355. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_scope_infer_ext2.py +0 -0
  356. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_swift.py +0 -0
  357. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/graph_swift_infer.py +0 -0
  358. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/parser.py +0 -0
  359. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/signatures.py +0 -0
  360. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/signatures_ext.py +0 -0
  361. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/synthesis_index.py +0 -0
  362. {seam_code-0.3.0 → seam_code-0.5.0}/seam/indexer/tokenize.py +0 -0
  363. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/claude.py +0 -0
  364. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/codex.py +0 -0
  365. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/core.py +0 -0
  366. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/cursor.py +0 -0
  367. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/guide.py +0 -0
  368. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/jsonfile.py +0 -0
  369. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/markdownfile.py +0 -0
  370. {seam_code-0.3.0 → seam_code-0.5.0}/seam/installer/tomlfile.py +0 -0
  371. {seam_code-0.3.0/seam/server → seam_code-0.5.0/seam/query}/__init__.py +0 -0
  372. {seam_code-0.3.0 → seam_code-0.5.0}/seam/query/clusters.py +0 -0
  373. {seam_code-0.3.0 → seam_code-0.5.0}/seam/query/comments.py +0 -0
  374. {seam_code-0.3.0 → seam_code-0.5.0}/seam/query/fts.py +0 -0
  375. {seam_code-0.3.0 → seam_code-0.5.0}/seam/query/names.py +0 -0
  376. {seam_code-0.3.0 → seam_code-0.5.0}/seam/query/structure.py +0 -0
  377. {seam_code-0.3.0/seam/watcher → seam_code-0.5.0/seam/server}/__init__.py +0 -0
  378. {seam_code-0.3.0 → seam_code-0.5.0}/seam/server/handler_common.py +0 -0
  379. {seam_code-0.3.0 → seam_code-0.5.0}/seam/server/impact_handler.py +0 -0
  380. {seam_code-0.3.0/tests → seam_code-0.5.0/seam/watcher}/__init__.py +0 -0
  381. {seam_code-0.3.0 → seam_code-0.5.0}/seam/watcher/__main__.py +0 -0
  382. {seam_code-0.3.0/tests/integration → seam_code-0.5.0/tests}/__init__.py +0 -0
  383. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/__init__.py +0 -0
  384. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/eval_report.py +0 -0
  385. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/fixtures/dispatcher.py +0 -0
  386. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/fixtures/interfaces.py +0 -0
  387. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/fixtures/pipeline.py +0 -0
  388. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/fixtures/utils.py +0 -0
  389. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/gen_golden.py +0 -0
  390. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/golden.json +0 -0
  391. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/recall_harness.py +0 -0
  392. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/test_metrics.py +0 -0
  393. {seam_code-0.3.0 → seam_code-0.5.0}/tests/eval/test_recall_regression.py +0 -0
  394. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.c +0 -0
  395. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.cpp +0 -0
  396. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.cs +0 -0
  397. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.go +0 -0
  398. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.java +0 -0
  399. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.php +0 -0
  400. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.py +0 -0
  401. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.rb +0 -0
  402. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.rs +0 -0
  403. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.swift +0 -0
  404. {seam_code-0.3.0 → seam_code-0.5.0}/tests/fixtures/sample.ts +0 -0
  405. {seam_code-0.3.0/tests/unit → seam_code-0.5.0/tests/integration}/__init__.py +0 -0
  406. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_affected_handler.py +0 -0
  407. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_changes.py +0 -0
  408. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_cli_read.py +0 -0
  409. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_cluster_index.py +0 -0
  410. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_clusters_handler.py +0 -0
  411. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_composition_holds_edges_go_rust_integration.py +0 -0
  412. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_composition_holds_edges_integration.py +0 -0
  413. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_composition_holds_edges_java_cs_cpp_ruby_php_integration.py +0 -0
  414. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_composition_holds_edges_swift_integration.py +0 -0
  415. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_embedding_index.py +0 -0
  416. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_field_access_integration_c_cpp.py +0 -0
  417. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_field_access_integration_go_rust.py +0 -0
  418. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_field_access_integration_java_csharp.py +0 -0
  419. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_field_access_integration_python_ts.py +0 -0
  420. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_field_access_integration_ruby_php_swift.py +0 -0
  421. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_flows_cli.py +0 -0
  422. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_impact_relevance.py +0 -0
  423. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_indexer.py +0 -0
  424. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_inheritance_impact.py +0 -0
  425. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_init_gitignore.py +0 -0
  426. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_mcp_error_contract.py +0 -0
  427. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_mcp_tools.py +0 -0
  428. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_migration_v12.py +0 -0
  429. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_migration_v5.py +0 -0
  430. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_migration_v6.py +0 -0
  431. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_migration_v7.py +0 -0
  432. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_migration_v9.py +0 -0
  433. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_no_mcp_profile.py +0 -0
  434. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_p4_barrel_reexport.py +0 -0
  435. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_pack_homonym.py +0 -0
  436. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_phase4_read_layer.py +0 -0
  437. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_phase5_e2e_homonym.py +0 -0
  438. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_phase5_import_promotion.py +0 -0
  439. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_qa_hardening_wiring.py +0 -0
  440. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_seam_why_handler.py +0 -0
  441. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_semantic_engine.py +0 -0
  442. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_staleness_banner.py +0 -0
  443. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_sync_clusters.py +0 -0
  444. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_synthesis_channels_integration.py +0 -0
  445. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_synthesis_integration.py +0 -0
  446. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_tier_a.py +0 -0
  447. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_tier_a_slice4.py +0 -0
  448. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_tier_b3.py +0 -0
  449. {seam_code-0.3.0 → seam_code-0.5.0}/tests/integration/test_trace_handler.py +0 -0
  450. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_affected.py +0 -0
  451. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_b5_infer_remaining_families.py +0 -0
  452. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_b6_instantiates_edges.py +0 -0
  453. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_bare_method_resolution.py +0 -0
  454. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_builtins.py +0 -0
  455. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_byte_budget.py +0 -0
  456. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_c_cpp.py +0 -0
  457. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_changes_partial.py +0 -0
  458. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_cluster_naming.py +0 -0
  459. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_clustering.py +0 -0
  460. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_clustering_migration.py +0 -0
  461. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_composition_holds_edges.py +0 -0
  462. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_composition_holds_edges_go_rust.py +0 -0
  463. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_composition_holds_edges_java_cs_cpp_ruby_php.py +0 -0
  464. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_composition_holds_edges_swift.py +0 -0
  465. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_confidence.py +0 -0
  466. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_confidence_global.py +0 -0
  467. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_confidence_phase5.py +0 -0
  468. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_db.py +0 -0
  469. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_embeddings.py +0 -0
  470. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_entry_score.py +0 -0
  471. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_field_access_c_cpp.py +0 -0
  472. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_field_access_go_rust.py +0 -0
  473. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_field_access_java_csharp.py +0 -0
  474. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_field_access_python.py +0 -0
  475. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_field_access_ruby_php.py +0 -0
  476. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_field_access_swift.py +0 -0
  477. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_field_access_typescript.py +0 -0
  478. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_flows.py +0 -0
  479. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_flows_global_confidence.py +0 -0
  480. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_fts.py +0 -0
  481. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_fts_tokenize.py +0 -0
  482. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_go_rust.py +0 -0
  483. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_graph.py +0 -0
  484. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_handler_provenance.py +0 -0
  485. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_hardening.py +0 -0
  486. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_impact.py +0 -0
  487. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_impact_default_production.py +0 -0
  488. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_impact_is_test.py +0 -0
  489. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_impact_max_bytes.py +0 -0
  490. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_impact_omit_null_candidate.py +0 -0
  491. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_impact_summary.py +0 -0
  492. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_imports.py +0 -0
  493. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_inheritance_edges.py +0 -0
  494. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_java_csharp.py +0 -0
  495. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_lean_output.py +0 -0
  496. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_names.py +0 -0
  497. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_output.py +0 -0
  498. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_p2_cluster_quality.py +0 -0
  499. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_pack_relevance_rank.py +0 -0
  500. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_param_uses_edges.py +0 -0
  501. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_parser.py +0 -0
  502. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_phase9_type_parity.py +0 -0
  503. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_pipeline_walk.py +0 -0
  504. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_processes.py +0 -0
  505. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_provenance_threading.py +0 -0
  506. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_query_clusters.py +0 -0
  507. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_receiver_b1.py +0 -0
  508. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_receiver_b2.py +0 -0
  509. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_receiver_b3.py +0 -0
  510. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_relevance.py +0 -0
  511. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_review_fixes_phase4.py +0 -0
  512. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_review_fixes_phase5.py +0 -0
  513. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_richer_edges.py +0 -0
  514. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_ruby_php.py +0 -0
  515. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_rwr.py +0 -0
  516. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_schema_packaging.py +0 -0
  517. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_scope_infer_b4.py +0 -0
  518. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_seam_why.py +0 -0
  519. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_semantic.py +0 -0
  520. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_semantic_hardening.py +0 -0
  521. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_signatures.py +0 -0
  522. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_staleness.py +0 -0
  523. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_steer.py +0 -0
  524. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_swift.py +0 -0
  525. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_symbol_uid.py +0 -0
  526. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_sync.py +0 -0
  527. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_synthesis_channels.py +0 -0
  528. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_synthesis_engine.py +0 -0
  529. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_synthesis_index.py +0 -0
  530. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_tokenize.py +0 -0
  531. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_tools_split_regression.py +0 -0
  532. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_traversal.py +0 -0
  533. {seam_code-0.3.0 → seam_code-0.5.0}/tests/unit/test_traversal_global_confidence.py +0 -0
@@ -0,0 +1,3 @@
1
+ # Default owner for everything in the repo.
2
+ # Required reviewer on every PR unless a more specific rule below matches.
3
+ * @Catafal
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: Bug report
3
+ about: Something isn't working as expected
4
+ labels: bug
5
+ ---
6
+
7
+ **Seam version** (`pip show seam-code` or `uv run seam --version`):
8
+
9
+ **Python version** (`python --version`):
10
+
11
+ **OS / platform**:
12
+
13
+ ---
14
+
15
+ ### What happened
16
+
17
+ <!-- Describe the unexpected behaviour. -->
18
+
19
+ ### What you expected
20
+
21
+ <!-- Describe what you expected to happen. -->
22
+
23
+ ### Steps to reproduce
24
+
25
+ ```bash
26
+ # Minimal sequence that triggers the bug
27
+ uv run seam init
28
+ uv run seam ...
29
+ ```
30
+
31
+ ### Relevant output
32
+
33
+ <!-- Paste error messages, stack traces, or `--json` output here. -->
34
+
35
+ ```
36
+ ```
37
+
38
+ ### Additional context
39
+
40
+ <!-- Any other details that might help (repo size, language mix, config knobs set). -->
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Question / discussion
4
+ url: https://github.com/Catafal/seam/discussions
5
+ about: Ask questions and discuss ideas in GitHub Discussions rather than opening an issue.
6
+ - name: Security vulnerability
7
+ url: https://github.com/Catafal/seam/security/advisories/new
8
+ about: Report security issues privately via GitHub's vulnerability reporting (not a public issue).
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an improvement or new capability
4
+ labels: enhancement
5
+ ---
6
+
7
+ ### Summary
8
+
9
+ <!-- One-sentence description of the feature. -->
10
+
11
+ ### Problem it solves
12
+
13
+ <!-- What's missing or painful today? -->
14
+
15
+ ### Proposed solution
16
+
17
+ <!-- How should it work? A CLI flag, a new MCP tool, a new language, etc. -->
18
+
19
+ ### Alternatives you've considered
20
+
21
+ <!-- Other approaches you thought of and why you're proposing this one. -->
22
+
23
+ ### Additional context
24
+
25
+ <!-- Relevant usage patterns, links to prior discussions, example commands. -->
@@ -0,0 +1,24 @@
1
+ ## Summary
2
+
3
+ <!-- What does this PR do? One paragraph is enough. Link the relevant issue if there is one. -->
4
+
5
+ Closes #
6
+
7
+ ## Changes
8
+
9
+ <!-- Bullet list of what changed and why. -->
10
+
11
+ -
12
+
13
+ ## Checklist
14
+
15
+ - [ ] `make gate` passes locally (`make lint && make typecheck && make test`)
16
+ - [ ] Tests added or updated for changed behaviour
17
+ - [ ] `CHANGELOG.md` updated under `## [Unreleased]`
18
+ - [ ] No new `os.getenv()` calls outside `seam/config.py`
19
+ - [ ] No new runtime network calls or external service dependencies
20
+ - [ ] Functions stay under 200 lines; files stay under 1000 lines
21
+
22
+ ## Notes for reviewers
23
+
24
+ <!-- Anything that needs special attention, known trade-offs, or follow-up work. -->
@@ -0,0 +1,23 @@
1
+ version: 2
2
+ updates:
3
+ # Python dependencies (uv / pyproject.toml).
4
+ - package-ecosystem: "pip"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ open-pull-requests-limit: 5
9
+ labels:
10
+ - "dependencies"
11
+ commit-message:
12
+ prefix: "deps"
13
+
14
+ # GitHub Actions used in CI + release workflows.
15
+ - package-ecosystem: "github-actions"
16
+ directory: "/"
17
+ schedule:
18
+ interval: "weekly"
19
+ labels:
20
+ - "dependencies"
21
+ - "ci"
22
+ commit-message:
23
+ prefix: "ci"
@@ -0,0 +1,52 @@
1
+ name: CI
2
+
3
+ # Mirror of `make gate` (lint + typecheck + test) so local and CI verification can never drift.
4
+ # Runs on every push to main and every pull request.
5
+ on:
6
+ push:
7
+ branches: [main]
8
+ pull_request:
9
+ branches: [main]
10
+
11
+ # Cancel superseded runs on the same ref to save CI minutes.
12
+ concurrency:
13
+ group: ci-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ gate:
21
+ name: gate (py${{ matrix.python-version }})
22
+ runs-on: ubuntu-latest
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ # pyproject requires-python = ">=3.12"; test the supported range.
27
+ python-version: ["3.12", "3.13"]
28
+
29
+ steps:
30
+ - name: Checkout
31
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
32
+
33
+ - name: Install uv
34
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
35
+ with:
36
+ enable-cache: true
37
+
38
+ - name: Set up Python ${{ matrix.python-version }}
39
+ run: uv python install ${{ matrix.python-version }}
40
+
41
+ - name: Install dependencies (dev group)
42
+ run: uv sync --dev --python ${{ matrix.python-version }}
43
+
44
+ # The three gate steps are split so a failure points at the exact stage.
45
+ - name: Lint (ruff)
46
+ run: uv run ruff check seam/ tests/
47
+
48
+ - name: Typecheck (mypy)
49
+ run: uv run mypy seam/ --ignore-missing-imports
50
+
51
+ - name: Test (pytest)
52
+ run: uv run pytest tests/ --tb=short -q
@@ -0,0 +1,66 @@
1
+ name: Explorer Visual QA
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ paths:
7
+ - "web/**"
8
+ - "seam/server/**"
9
+ - "seam/query/layout.py"
10
+ - "seam/cli/serve.py"
11
+ - ".github/workflows/explorer-visual.yml"
12
+ workflow_dispatch:
13
+
14
+ concurrency:
15
+ group: explorer-visual-${{ github.ref }}
16
+ cancel-in-progress: true
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ topology:
23
+ name: topology browser invariant
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - name: Checkout
27
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
28
+
29
+ - name: Install uv
30
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
31
+ with:
32
+ enable-cache: true
33
+
34
+ - name: Set up Python
35
+ run: uv python install 3.12
36
+
37
+ - name: Install Python dependencies
38
+ run: uv sync --extra web --dev --python 3.12
39
+
40
+ - name: Set up Node
41
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
42
+ with:
43
+ node-version: "22"
44
+ cache: npm
45
+ cache-dependency-path: web/package-lock.json
46
+
47
+ - name: Install web dependencies
48
+ run: npm ci
49
+ working-directory: web
50
+
51
+ - name: Install Chromium
52
+ run: npx playwright install --with-deps chromium
53
+ working-directory: web
54
+
55
+ - name: Run topology visual QA
56
+ run: npm run test:visual
57
+ working-directory: web
58
+
59
+ - name: Upload Playwright report
60
+ if: always()
61
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
62
+ with:
63
+ name: explorer-visual-report
64
+ path: |
65
+ web/playwright-report/
66
+ web/test-results/topology-visual/
@@ -0,0 +1,147 @@
1
+ name: No-Egress Proof
2
+
3
+ # WHY this workflow exists:
4
+ # Seam's contract is "zero outbound network connections" on its read path.
5
+ # This workflow proves it at the syscall level by running each Seam command
6
+ # (CLI + MCP server) under ``strace -f -e trace=connect``, then feeding the
7
+ # trace to ``tests/support/egress_audit.py``. Any AF_INET/AF_INET6 connect()
8
+ # to a non-loopback address fails the job immediately.
9
+ #
10
+ # WHY strace only (not eBPF / seccomp):
11
+ # strace is available on ubuntu-latest without extra setup; it intercepts
12
+ # connect() at the kernel boundary regardless of language/runtime/TLS wrapping.
13
+ # False-positive local connects (SQLite WAL, Unix sockets) are already
14
+ # classified as 'local' by egress_audit.py.
15
+ #
16
+ # WHY NOT the semantic extra:
17
+ # ``seam init --semantic`` downloads a ~67 MB model on first run — that IS
18
+ # a legitimate network call (model bootstrap, not a read-path egress).
19
+ # The no-egress contract applies to the READ path: init (graph only), search,
20
+ # context, impact, and the MCP server after a warm index.
21
+ #
22
+ # WHY NOT ``seam fetch``:
23
+ # ``seam fetch`` downloads a pre-built index artifact from a CI-published URL —
24
+ # another intentional SETUP-TIME network path, explicitly excluded from this proof.
25
+ # It is the team-shared-index provisioning download (WS4 S3), analogous to the
26
+ # model download above. Once the fetched index is on disk, every subsequent
27
+ # read command is offline. ``seam fetch`` is deliberately absent from the strace
28
+ # probes below; its egress is accepted and documented, not an oversight.
29
+ #
30
+ # WHY the ANN tier (WS2b ``sqlite-vec`` / SEAM_VEC_ANN) needs NO exclusion here:
31
+ # The sqlite-vec extension is an IN-PROCESS SQLite extension (a shared library
32
+ # loaded via conn.enable_load_extension). It makes ZERO network calls at any
33
+ # point — index build time, query time, or extension-load time. The ANN read
34
+ # path is: load extension → issue SQL KNN MATCH → return rows from the local DB.
35
+ # All I/O is to the local .seam/seam.db file; nothing touches the network.
36
+ # ANN activation therefore does NOT need to be excluded from the strace probes
37
+ # below — it is provably in-process and offline, unlike ``seam init --semantic``
38
+ # (model download) or ``seam fetch`` (artifact download).
39
+ #
40
+ # WHY ``set -euo pipefail``:
41
+ # Each strace command propagates the child's exit code. A crashed seam command
42
+ # would produce an empty trace, which egress_audit would pass — giving a false
43
+ # green. Under ``set -e`` the job fails on non-zero exit from the traced
44
+ # command before egress_audit even runs.
45
+
46
+ on:
47
+ push:
48
+ branches: [main]
49
+ pull_request:
50
+ branches: [main]
51
+
52
+ # Cancel superseded runs on the same ref to save CI minutes (mirrors ci.yml).
53
+ concurrency:
54
+ group: no-egress-${{ github.ref }}
55
+ cancel-in-progress: true
56
+
57
+ permissions:
58
+ contents: read
59
+
60
+ jobs:
61
+ no-egress:
62
+ name: no-egress syscall audit
63
+ runs-on: ubuntu-latest
64
+
65
+ steps:
66
+ - name: Checkout
67
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
68
+
69
+ - name: Install uv
70
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
71
+ with:
72
+ enable-cache: true
73
+
74
+ - name: Set up Python
75
+ run: uv python install 3.12
76
+
77
+ - name: Install dependencies (server extra + dev group)
78
+ # server extra → mcp package needed for the MCP smoke driver.
79
+ # dev group → pytest, ruff, etc. (also ensures egress_audit is on PYTHONPATH).
80
+ # NO semantic extra — model downloads are legitimate network calls, not read-path egress.
81
+ run: uv sync --extra server --dev --python 3.12
82
+
83
+ - name: Install strace
84
+ run: sudo apt-get update -qq && sudo apt-get install -y strace
85
+
86
+ # Index a small fixture directory so every subsequent read command has data.
87
+ # tests/fixtures/ contains 11 sample source files (~129 symbols) — fast to index
88
+ # and guaranteed to exist in the repo.
89
+ - name: Index fixtures directory
90
+ run: |
91
+ set -euo pipefail
92
+ uv run seam init tests/fixtures/
93
+ echo "Index complete. Verifying index status:"
94
+ cd tests/fixtures && uv run seam status
95
+
96
+ # ── strace probes ────────────────────────────────────────────────────────
97
+ # Each step: run the command under strace, write a tracefile, then audit it.
98
+ # ``strace -f`` follows forked children so multi-process commands are covered.
99
+ # ``-e trace=connect`` captures ONLY connect() syscalls — the minimal filter.
100
+ # The tracefile name matches the step for easy identification in failure output.
101
+
102
+ - name: Probe — seam init (graph only, no --semantic)
103
+ run: |
104
+ set -euo pipefail
105
+ # Re-run init on the fixtures dir (idempotent). The first indexed run above
106
+ # already proved the path; this run is traced for the egress proof.
107
+ strace -f -e trace=connect -o /tmp/init.trace \
108
+ uv run seam init tests/fixtures/
109
+ uv run python -m tests.support.egress_audit /tmp/init.trace
110
+
111
+ - name: Probe — seam search
112
+ run: |
113
+ set -euo pipefail
114
+ cd tests/fixtures
115
+ strace -f -e trace=connect -o /tmp/search.trace \
116
+ uv run seam search "add"
117
+ uv run python -m tests.support.egress_audit /tmp/search.trace
118
+
119
+ - name: Probe — seam context
120
+ run: |
121
+ set -euo pipefail
122
+ cd tests/fixtures
123
+ strace -f -e trace=connect -o /tmp/context.trace \
124
+ uv run seam context add
125
+ uv run python -m tests.support.egress_audit /tmp/context.trace
126
+
127
+ - name: Probe — seam impact
128
+ run: |
129
+ set -euo pipefail
130
+ cd tests/fixtures
131
+ strace -f -e trace=connect -o /tmp/impact.trace \
132
+ uv run seam impact add
133
+ uv run python -m tests.support.egress_audit /tmp/impact.trace
134
+
135
+ - name: Probe — MCP stdio server (via mcp_smoke driver)
136
+ # The smoke driver spawns ``seam start tests/fixtures/`` as a stdio child,
137
+ # performs a full MCP handshake (initialize + list_tools), prints the tool
138
+ # count, and exits 0. strace -f follows the spawned server child so its
139
+ # connect() calls are captured in the same tracefile.
140
+ run: |
141
+ set -euo pipefail
142
+ strace -f -e trace=connect -o /tmp/start.trace \
143
+ uv run --extra server python -m tests.support.mcp_smoke tests/fixtures/
144
+ uv run python -m tests.support.egress_audit /tmp/start.trace
145
+
146
+ - name: All probes passed — no external connections detected
147
+ run: echo "No-egress proof complete. All connect() calls were local."
@@ -0,0 +1,197 @@
1
+ name: Release
2
+
3
+ # Build and publish `seam-code` to PyPI when a version tag is pushed.
4
+ # Auth uses PyPI Trusted Publishing (OIDC) — no API token anywhere.
5
+ # Tag a release with: git tag v0.3.1 && git push origin v0.3.1
6
+ on:
7
+ push:
8
+ tags:
9
+ - "v*"
10
+
11
+ # Least-privilege default for all jobs. Individual jobs override only what
12
+ # they specifically need (id-token:write for OIDC, contents:write for Release).
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ # ── Gate ────────────────────────────────────────────────────────────────────
18
+ # Mirror of `make gate` (ruff + mypy + pytest) on the minimum supported
19
+ # Python version. Every downstream job depends on this — a red build can
20
+ # never reach PyPI or the GitHub Release.
21
+ #
22
+ # WHY single Python (3.12): the smoke job already exercises 3.12 and 3.13
23
+ # against the built artifact; duplicating the matrix here doubles tag-push
24
+ # CI time for no additional signal.
25
+ gate:
26
+ name: gate
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - name: Checkout
30
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
31
+
32
+ - name: Install uv
33
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
34
+ with:
35
+ enable-cache: true
36
+
37
+ - name: Set up Python 3.12
38
+ run: uv python install 3.12
39
+
40
+ - name: Install dependencies (dev group)
41
+ run: uv sync --dev --python 3.12
42
+
43
+ # Three gate steps split so a failure points at the exact stage.
44
+ - name: Lint (ruff)
45
+ run: uv run ruff check seam/ tests/
46
+
47
+ - name: Typecheck (mypy)
48
+ run: uv run mypy seam/ --ignore-missing-imports
49
+
50
+ - name: Test (pytest)
51
+ run: uv run pytest tests/ -q
52
+
53
+ # ── Build ────────────────────────────────────────────────────────────────────
54
+ # Build the sdist + wheel; generate SHA-256 checksums OUTSIDE dist/ so the
55
+ # pypi-publish action only sees the wheel + sdist in its packages-dir.
56
+ # Two artifacts are uploaded:
57
+ # dist — wheel + sdist (consumed by smoke + publish)
58
+ # checksums — checksums.txt only (consumed by github-release)
59
+ build:
60
+ name: build distribution
61
+ needs: gate
62
+ runs-on: ubuntu-latest
63
+ steps:
64
+ - name: Checkout
65
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
66
+
67
+ - name: Install uv
68
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
69
+ with:
70
+ enable-cache: true
71
+
72
+ - name: Build sdist + wheel
73
+ run: uv build
74
+
75
+ # Write checksums to the repo root, NOT inside dist/.
76
+ # The pypi-publish action uploads everything under dist/ — a stray
77
+ # checksums.txt there would cause a publish error.
78
+ - name: Generate SHA-256 checksums (outside dist/)
79
+ run: cd dist && sha256sum *.whl *.tar.gz > ../checksums.txt
80
+
81
+ - name: Upload dist artifacts (wheel + sdist)
82
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
83
+ with:
84
+ name: dist
85
+ path: dist/
86
+
87
+ - name: Upload checksums artifact
88
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
89
+ with:
90
+ name: checksums
91
+ path: checksums.txt
92
+
93
+ # ── Smoke ────────────────────────────────────────────────────────────────────
94
+ # Install the built wheel into a CLEAN virtual environment on each supported
95
+ # Python version and verify `seam --help` exits 0.
96
+ #
97
+ # WHY /tmp/smoke-env: outside the workspace, so no accidental source-tree
98
+ # reads. uv manages the exact CPython version requested.
99
+ smoke:
100
+ name: smoke (py${{ matrix.python-version }})
101
+ needs: build
102
+ runs-on: ubuntu-latest
103
+ strategy:
104
+ matrix:
105
+ python-version: ["3.12", "3.13"]
106
+ steps:
107
+ - name: Download built distributions
108
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
109
+ with:
110
+ name: dist
111
+ path: dist/
112
+
113
+ - name: Install uv
114
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
115
+ with:
116
+ enable-cache: false # clean environment — no cached state
117
+
118
+ - name: Set up Python ${{ matrix.python-version }}
119
+ run: uv python install ${{ matrix.python-version }}
120
+
121
+ - name: Create clean virtual environment
122
+ run: uv venv /tmp/smoke-env --python ${{ matrix.python-version }}
123
+
124
+ - name: Install built wheel into clean environment
125
+ run: uv pip install --python /tmp/smoke-env/bin/python dist/*.whl
126
+
127
+ # `seam --version` reads the installed package metadata — this proves the
128
+ # binary is installed, importable from the wheel, AND reports the version
129
+ # that was just built (a stronger post-install assertion than --help).
130
+ - name: Verify seam binary is installed and reports its version
131
+ run: /tmp/smoke-env/bin/seam --version
132
+
133
+ # ── GitHub Release ───────────────────────────────────────────────────────────
134
+ # Create a GitHub Release for the pushed tag and attach the distributions
135
+ # plus checksums.txt. Uses the pre-installed `gh` CLI — no third-party
136
+ # action is needed, so the S1 SHA-pin audit gate is not widened.
137
+ #
138
+ # WHY contents:write scoped here only: the spec requires least-privilege on
139
+ # all other jobs. This is the only job that writes to the repo (releases).
140
+ github-release:
141
+ name: GitHub Release
142
+ needs: [gate, smoke]
143
+ runs-on: ubuntu-latest
144
+ permissions:
145
+ contents: write # required to create and upload assets to a GitHub Release
146
+ steps:
147
+ - name: Download built distributions
148
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
149
+ with:
150
+ name: dist
151
+ path: dist/
152
+
153
+ - name: Download checksums
154
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
155
+ with:
156
+ name: checksums
157
+ path: ./ # land checksums.txt in the working directory
158
+
159
+ - name: Create GitHub Release and attach artifacts
160
+ env:
161
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
162
+ run: |
163
+ # Strip the leading 'v' from the tag for the PyPI URL (v0.3.1 → 0.3.1).
164
+ VERSION="${GITHUB_REF_NAME#v}"
165
+ gh release create "$GITHUB_REF_NAME" \
166
+ dist/* \
167
+ checksums.txt \
168
+ --title "seam-code $GITHUB_REF_NAME" \
169
+ --notes "PyPI: https://pypi.org/project/seam-code/${VERSION}/" \
170
+ --repo "$GITHUB_REPOSITORY"
171
+
172
+ # ── Publish ──────────────────────────────────────────────────────────────────
173
+ # Publish to PyPI via Trusted Publishing (OIDC — no API token anywhere).
174
+ # Runs only after the gate AND the smoke matrix both pass.
175
+ # PEP 740 attestations are enabled so consumers can verify provenance.
176
+ publish:
177
+ name: publish to PyPI
178
+ needs: [gate, smoke]
179
+ runs-on: ubuntu-latest
180
+ # The OIDC environment PyPI Trusted Publishing is configured against.
181
+ environment:
182
+ name: pypi
183
+ url: https://pypi.org/project/seam-code/
184
+ permissions:
185
+ # Required for Trusted Publishing — mints the short-lived OIDC token.
186
+ id-token: write
187
+ steps:
188
+ - name: Download built distributions
189
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
190
+ with:
191
+ name: dist
192
+ path: dist/
193
+
194
+ - name: Publish to PyPI (Trusted Publishing + PEP 740 attestations)
195
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
196
+ with:
197
+ attestations: true