jobctrl 0.3.0__tar.gz → 0.4.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 (1358) hide show
  1. jobctrl-0.4.0/PKG-INFO +95 -0
  2. jobctrl-0.4.0/README.md +34 -0
  3. jobctrl-0.4.0/pyproject.toml +158 -0
  4. jobctrl-0.4.0/src/jobctrl/__init__.py +3 -0
  5. jobctrl-0.4.0/src/jobctrl/apply/activities.py +197 -0
  6. jobctrl-0.4.0/src/jobctrl/apply/auto_apply.py +201 -0
  7. jobctrl-0.4.0/src/jobctrl/apply/batch_outcome.py +45 -0
  8. jobctrl-0.4.0/src/jobctrl/apply/chrome.py +1635 -0
  9. jobctrl-0.4.0/src/jobctrl/apply/cover_letter_binding.py +98 -0
  10. jobctrl-0.4.0/src/jobctrl/apply/dashboard.py +249 -0
  11. jobctrl-0.4.0/src/jobctrl/apply/dispatch.py +35 -0
  12. jobctrl-0.4.0/src/jobctrl/apply/execution.py +383 -0
  13. jobctrl-0.4.0/src/jobctrl/apply/launcher.py +4414 -0
  14. jobctrl-0.4.0/src/jobctrl/apply/native_custody.py +161 -0
  15. jobctrl-0.4.0/src/jobctrl/apply/ownership.py +582 -0
  16. jobctrl-0.4.0/src/jobctrl/apply/process_birth.py +352 -0
  17. jobctrl-0.4.0/src/jobctrl/apply/workflow.py +261 -0
  18. jobctrl-0.4.0/src/jobctrl/cli.py +3965 -0
  19. jobctrl-0.4.0/src/jobctrl/company_briefing_cli.py +112 -0
  20. jobctrl-0.4.0/src/jobctrl/config.py +2108 -0
  21. jobctrl-0.4.0/src/jobctrl/contact/activities.py +214 -0
  22. jobctrl-0.4.0/src/jobctrl/contact/workflow.py +217 -0
  23. jobctrl-0.4.0/src/jobctrl/database.py +3842 -0
  24. jobctrl-0.4.0/src/jobctrl/digest.py +764 -0
  25. jobctrl-0.4.0/src/jobctrl/discovery/activities.py +859 -0
  26. jobctrl-0.4.0/src/jobctrl/discovery/execution_reconciliation.py +1506 -0
  27. jobctrl-0.4.0/src/jobctrl/discovery/job_url_import_workflow.py +1352 -0
  28. jobctrl-0.4.0/src/jobctrl/discovery/jobspy.py +2188 -0
  29. jobctrl-0.4.0/src/jobctrl/discovery/smartextract.py +1735 -0
  30. jobctrl-0.4.0/src/jobctrl/discovery/workday.py +892 -0
  31. jobctrl-0.4.0/src/jobctrl/discovery/workflow.py +723 -0
  32. jobctrl-0.4.0/src/jobctrl/domain/apply/event_privacy.py +62 -0
  33. jobctrl-0.4.0/src/jobctrl/domain/apply/process_manager.py +885 -0
  34. jobctrl-0.4.0/src/jobctrl/domain/apply/services.py +345 -0
  35. jobctrl-0.4.0/src/jobctrl/domain/apply/use_cases.py +716 -0
  36. jobctrl-0.4.0/src/jobctrl/domain/apply/value_objects.py +325 -0
  37. jobctrl-0.4.0/src/jobctrl/domain/compensation/classification.py +54 -0
  38. jobctrl-0.4.0/src/jobctrl/domain/contact/outreach.py +628 -0
  39. jobctrl-0.4.0/src/jobctrl/domain/contact/outreach_gates.py +137 -0
  40. jobctrl-0.4.0/src/jobctrl/domain/contact/outreach_use_cases.py +622 -0
  41. jobctrl-0.4.0/src/jobctrl/domain/contact/research.py +329 -0
  42. jobctrl-0.4.0/src/jobctrl/domain/contact/research_services.py +448 -0
  43. jobctrl-0.4.0/src/jobctrl/domain/contact/research_use_cases.py +207 -0
  44. jobctrl-0.4.0/src/jobctrl/domain/determinations.py +396 -0
  45. jobctrl-0.4.0/src/jobctrl/domain/discovery/posting_qualification.py +68 -0
  46. jobctrl-0.4.0/src/jobctrl/domain/discovery/use_cases.py +649 -0
  47. jobctrl-0.4.0/src/jobctrl/domain/enrichment/interpretation.py +125 -0
  48. jobctrl-0.4.0/src/jobctrl/domain/enrichment/page_interpretation.py +190 -0
  49. jobctrl-0.4.0/src/jobctrl/domain/enrichment/value_objects.py +220 -0
  50. jobctrl-0.4.0/src/jobctrl/domain/errors.py +133 -0
  51. jobctrl-0.4.0/src/jobctrl/domain/events/__init__.py +515 -0
  52. jobctrl-0.4.0/src/jobctrl/domain/events/apply.py +110 -0
  53. jobctrl-0.4.0/src/jobctrl/domain/events/contact.py +343 -0
  54. jobctrl-0.4.0/src/jobctrl/domain/events/discovery.py +332 -0
  55. jobctrl-0.4.0/src/jobctrl/domain/events/workflow.py +389 -0
  56. jobctrl-0.4.0/src/jobctrl/domain/exact_values.py +25 -0
  57. jobctrl-0.4.0/src/jobctrl/domain/interview/catalog.py +455 -0
  58. jobctrl-0.4.0/src/jobctrl/domain/materials/analysis.py +498 -0
  59. jobctrl-0.4.0/src/jobctrl/domain/materials/analyze_use_case.py +342 -0
  60. jobctrl-0.4.0/src/jobctrl/domain/materials/artifact_quality.py +102 -0
  61. jobctrl-0.4.0/src/jobctrl/domain/materials/claim_review_response.py +171 -0
  62. jobctrl-0.4.0/src/jobctrl/domain/materials/claim_verification.py +226 -0
  63. jobctrl-0.4.0/src/jobctrl/domain/materials/company_briefings.py +142 -0
  64. jobctrl-0.4.0/src/jobctrl/domain/materials/cover_letter_settings.py +35 -0
  65. jobctrl-0.4.0/src/jobctrl/domain/materials/editable_export.py +96 -0
  66. jobctrl-0.4.0/src/jobctrl/domain/materials/evidence_selection.py +203 -0
  67. jobctrl-0.4.0/src/jobctrl/domain/materials/generation.py +63 -0
  68. jobctrl-0.4.0/src/jobctrl/domain/materials/policy.py +769 -0
  69. jobctrl-0.4.0/src/jobctrl/domain/materials/quality.py +787 -0
  70. jobctrl-0.4.0/src/jobctrl/domain/materials/requirement_coverage.py +1394 -0
  71. jobctrl-0.4.0/src/jobctrl/domain/materials/resume_document.py +255 -0
  72. jobctrl-0.4.0/src/jobctrl/domain/materials/services.py +459 -0
  73. jobctrl-0.4.0/src/jobctrl/domain/materials/use_cases.py +4498 -0
  74. jobctrl-0.4.0/src/jobctrl/domain/operations/career_learning.py +78 -0
  75. jobctrl-0.4.0/src/jobctrl/domain/ports/apply.py +290 -0
  76. jobctrl-0.4.0/src/jobctrl/domain/ports/artifact_quality.py +51 -0
  77. jobctrl-0.4.0/src/jobctrl/domain/ports/claim_verification.py +90 -0
  78. jobctrl-0.4.0/src/jobctrl/domain/ports/contact.py +140 -0
  79. jobctrl-0.4.0/src/jobctrl/domain/ports/letter_reviews.py +39 -0
  80. jobctrl-0.4.0/src/jobctrl/domain/ports/llm.py +100 -0
  81. jobctrl-0.4.0/src/jobctrl/domain/ports/materials.py +506 -0
  82. jobctrl-0.4.0/src/jobctrl/domain/ports/politeness.py +274 -0
  83. jobctrl-0.4.0/src/jobctrl/domain/ports/resume_adversarial.py +69 -0
  84. jobctrl-0.4.0/src/jobctrl/domain/ports/scoring.py +142 -0
  85. jobctrl-0.4.0/src/jobctrl/domain/preparation/work_items.py +60 -0
  86. jobctrl-0.4.0/src/jobctrl/domain/profile/canonical_sources.py +87 -0
  87. jobctrl-0.4.0/src/jobctrl/domain/profile/search_targets.py +72 -0
  88. jobctrl-0.4.0/src/jobctrl/domain/profile/value_objects.py +694 -0
  89. jobctrl-0.4.0/src/jobctrl/domain/scoring/determination.py +136 -0
  90. jobctrl-0.4.0/src/jobctrl/domain/scoring/profile_impact.py +102 -0
  91. jobctrl-0.4.0/src/jobctrl/domain/scoring/requirement_fit.py +202 -0
  92. jobctrl-0.4.0/src/jobctrl/domain/scoring/services.py +518 -0
  93. jobctrl-0.4.0/src/jobctrl/domain/scoring/use_cases.py +1027 -0
  94. jobctrl-0.4.0/src/jobctrl/domain/scoring/value_objects.py +1383 -0
  95. jobctrl-0.4.0/src/jobctrl/enrichment/availability.py +1580 -0
  96. jobctrl-0.4.0/src/jobctrl/enrichment/detail.py +4949 -0
  97. jobctrl-0.4.0/src/jobctrl/infrastructure/analysis/antigravity_analysis_adapter.py +233 -0
  98. jobctrl-0.4.0/src/jobctrl/infrastructure/analysis/claude_analysis_adapter.py +337 -0
  99. jobctrl-0.4.0/src/jobctrl/infrastructure/analysis/codex_analysis_adapter.py +443 -0
  100. jobctrl-0.4.0/src/jobctrl/infrastructure/analysis/ensemble.py +305 -0
  101. jobctrl-0.4.0/src/jobctrl/infrastructure/apply/claude_code_cli.py +827 -0
  102. jobctrl-0.4.0/src/jobctrl/infrastructure/apply/email_sender.py +33 -0
  103. jobctrl-0.4.0/src/jobctrl/infrastructure/apply/local_chrome.py +91 -0
  104. jobctrl-0.4.0/src/jobctrl/infrastructure/apply_controls.py +331 -0
  105. jobctrl-0.4.0/src/jobctrl/infrastructure/apply_tools/mcp_server.py +889 -0
  106. jobctrl-0.4.0/src/jobctrl/infrastructure/career_learning.py +512 -0
  107. jobctrl-0.4.0/src/jobctrl/infrastructure/commit_notifications.py +80 -0
  108. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/automatic_refresh.py +673 -0
  109. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/classification_batch.py +119 -0
  110. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/interpretation.py +69 -0
  111. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/levels_fyi_public.py +763 -0
  112. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/refresh_control.py +73 -0
  113. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/refresh_state.py +588 -0
  114. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/sqlite_market_repository.py +1605 -0
  115. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/sqlite_repository.py +454 -0
  116. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/workflow.py +204 -0
  117. jobctrl-0.4.0/src/jobctrl/infrastructure/contact/offer_sources.py +203 -0
  118. jobctrl-0.4.0/src/jobctrl/infrastructure/contact/outreach_repository.py +619 -0
  119. jobctrl-0.4.0/src/jobctrl/infrastructure/contact/research_fetcher.py +440 -0
  120. jobctrl-0.4.0/src/jobctrl/infrastructure/contact/research_repository.py +539 -0
  121. jobctrl-0.4.0/src/jobctrl/infrastructure/determinations.py +377 -0
  122. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/archived_smart_posting.py +357 -0
  123. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/capture_recovery.py +227 -0
  124. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/execution_result_plan.py +132 -0
  125. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/posting_source_proposals.py +395 -0
  126. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/production_wiring.py +2257 -0
  127. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/result_budget.py +197 -0
  128. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/smart_postings.py +273 -0
  129. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/sqlite_execution_repository.py +335 -0
  130. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/sqlite_repository.py +1436 -0
  131. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/sqlite_search_unit_repository.py +895 -0
  132. jobctrl-0.4.0/src/jobctrl/infrastructure/enrichment/interpretation.py +84 -0
  133. jobctrl-0.4.0/src/jobctrl/infrastructure/enrichment/playwright_fetcher.py +629 -0
  134. jobctrl-0.4.0/src/jobctrl/infrastructure/enrichment/posting_sources.py +211 -0
  135. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/auth.py +311 -0
  136. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/client.py +351 -0
  137. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/feedback.py +728 -0
  138. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/privacy.py +74 -0
  139. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/windows_private_file.py +104 -0
  140. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/agent_runtime_antigravity.py +138 -0
  141. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/agent_runtime_claude.py +131 -0
  142. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/agent_runtime_codex.py +325 -0
  143. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/agent_runtime_pool.py +252 -0
  144. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/attempt_admission.py +23 -0
  145. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/codex_runtime_storage.py +166 -0
  146. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/codex_turn.py +210 -0
  147. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/codex_workspace.py +142 -0
  148. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/llm_client.py +978 -0
  149. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/model_catalog.py +275 -0
  150. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/provider_availability.py +90 -0
  151. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/provider_errors.py +349 -0
  152. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/task_instructions.py +15 -0
  153. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/__init__.py +52 -0
  154. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/accepted_export.py +193 -0
  155. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/accepted_export_api.py +109 -0
  156. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/artifact_writer.py +13 -0
  157. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/company_briefing_fetcher.py +48 -0
  158. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/company_briefings.py +375 -0
  159. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/cover_letter_files.py +86 -0
  160. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/cover_letter_policy.py +95 -0
  161. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/docx_export.py +150 -0
  162. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/html_resume_pdf.py +883 -0
  163. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/letter_reviews.py +198 -0
  164. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/manual_decline.py +149 -0
  165. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/playwright_html_pdf.py +171 -0
  166. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/screening_answers.py +446 -0
  167. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/sqlite_repository.py +1553 -0
  168. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/voice_adapter.py +221 -0
  169. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/legacy_to_v15_execute.py +117 -0
  170. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/schema_manifest.py +163 -0
  171. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/schema_v13.py +69 -0
  172. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/schema_v15.py +56 -0
  173. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/schema_v15.sql +137 -0
  174. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/v14_to_v15_execute.py +210 -0
  175. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/v14_to_v15_inplace.py +151 -0
  176. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/v15_activation.py +205 -0
  177. jobctrl-0.4.0/src/jobctrl/infrastructure/network/http_client.py +175 -0
  178. jobctrl-0.4.0/src/jobctrl/infrastructure/network/politeness.py +371 -0
  179. jobctrl-0.4.0/src/jobctrl/infrastructure/network/rate_limiter.py +213 -0
  180. jobctrl-0.4.0/src/jobctrl/infrastructure/network/url_safety.py +348 -0
  181. jobctrl-0.4.0/src/jobctrl/infrastructure/observability/llm_spans.py +241 -0
  182. jobctrl-0.4.0/src/jobctrl/infrastructure/preparation/sqlite_repository.py +80 -0
  183. jobctrl-0.4.0/src/jobctrl/infrastructure/preparation_recovery.py +682 -0
  184. jobctrl-0.4.0/src/jobctrl/infrastructure/process_ownership.py +598 -0
  185. jobctrl-0.4.0/src/jobctrl/infrastructure/profile/factory.py +90 -0
  186. jobctrl-0.4.0/src/jobctrl/infrastructure/profile/legacy_evidence.py +218 -0
  187. jobctrl-0.4.0/src/jobctrl/infrastructure/profile/legacy_evidence_recovery.py +85 -0
  188. jobctrl-0.4.0/src/jobctrl/infrastructure/profile/sqlite_repository.py +1100 -0
  189. jobctrl-0.4.0/src/jobctrl/infrastructure/projections/projection_builder.py +5197 -0
  190. jobctrl-0.4.0/src/jobctrl/infrastructure/projections/sqlite_projection_store.py +1359 -0
  191. jobctrl-0.4.0/src/jobctrl/infrastructure/rpc/enrichment_retry.py +46 -0
  192. jobctrl-0.4.0/src/jobctrl/infrastructure/rpc/handlers.py +1517 -0
  193. jobctrl-0.4.0/src/jobctrl/infrastructure/rpc/job_url_import_status.py +71 -0
  194. jobctrl-0.4.0/src/jobctrl/infrastructure/rpc/server.py +356 -0
  195. jobctrl-0.4.0/src/jobctrl/infrastructure/runtime_identity.py +240 -0
  196. jobctrl-0.4.0/src/jobctrl/infrastructure/scoring/criteria_provider.py +195 -0
  197. jobctrl-0.4.0/src/jobctrl/infrastructure/scoring/sqlite_repository.py +1053 -0
  198. jobctrl-0.4.0/src/jobctrl/infrastructure/setup_probes.py +987 -0
  199. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/activity_runtime_telemetry.py +384 -0
  200. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/concurrency.py +76 -0
  201. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/control.py +41 -0
  202. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/finalize.py +341 -0
  203. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/preparation_outcome_audit.py +495 -0
  204. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/registry.py +117 -0
  205. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/run_in_activity.py +580 -0
  206. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/worker.py +150 -0
  207. jobctrl-0.4.0/src/jobctrl/infrastructure/workflow_run_context.py +96 -0
  208. jobctrl-0.4.0/src/jobctrl/interview/activities.py +526 -0
  209. jobctrl-0.4.0/src/jobctrl/interview/workflow.py +189 -0
  210. jobctrl-0.4.0/src/jobctrl/legacy_evidence_cli.py +79 -0
  211. jobctrl-0.4.0/src/jobctrl/llm.py +816 -0
  212. jobctrl-0.4.0/src/jobctrl/llm_request_context.py +32 -0
  213. jobctrl-0.4.0/src/jobctrl/materials/activities.py +918 -0
  214. jobctrl-0.4.0/src/jobctrl/materials/executor.py +102 -0
  215. jobctrl-0.4.0/src/jobctrl/pipeline/automatic_preparation.py +1089 -0
  216. jobctrl-0.4.0/src/jobctrl/pipeline/current_policy_selectors.py +265 -0
  217. jobctrl-0.4.0/src/jobctrl/pipeline/preparation.py +1160 -0
  218. jobctrl-0.4.0/src/jobctrl/pipeline/retry.py +129 -0
  219. jobctrl-0.4.0/src/jobctrl/pipeline/runner.py +2882 -0
  220. jobctrl-0.4.0/src/jobctrl/pipeline/workflow.py +819 -0
  221. jobctrl-0.4.0/src/jobctrl/preparation/workflow.py +435 -0
  222. jobctrl-0.4.0/src/jobctrl/profile/workflow.py +169 -0
  223. jobctrl-0.4.0/src/jobctrl/provider_packs.py +701 -0
  224. jobctrl-0.4.0/src/jobctrl/resume_profile.py +450 -0
  225. jobctrl-0.4.0/src/jobctrl/runtime.py +384 -0
  226. jobctrl-0.4.0/src/jobctrl/scoring/activities.py +423 -0
  227. jobctrl-0.4.0/src/jobctrl/scoring/cover_letter.py +820 -0
  228. jobctrl-0.4.0/src/jobctrl/scoring/employer_analysis.py +160 -0
  229. jobctrl-0.4.0/src/jobctrl/scoring/material_lifecycle.py +69 -0
  230. jobctrl-0.4.0/src/jobctrl/scoring/scorer.py +1719 -0
  231. jobctrl-0.4.0/src/jobctrl/scoring/tailor.py +1681 -0
  232. jobctrl-0.4.0/src/jobctrl/source_proposals_cli.py +69 -0
  233. jobctrl-0.4.0/src/jobctrl/state.py +1593 -0
  234. jobctrl-0.4.0/src/jobctrl/wizard/init.py +571 -0
  235. jobctrl-0.4.0/src/jobctrl/workflow_specs.py +707 -0
  236. jobctrl-0.4.0/tests/activity_capacity_api_fixture.py +125 -0
  237. jobctrl-0.4.0/tests/apply_execution_fixture.py +30 -0
  238. jobctrl-0.4.0/tests/apply_late_settlement_probe.py +48 -0
  239. jobctrl-0.4.0/tests/apply_receipt_privacy_fixture.py +51 -0
  240. jobctrl-0.4.0/tests/apply_skip_restart_probe.py +40 -0
  241. jobctrl-0.4.0/tests/apply_stopped_owner_probe.py +41 -0
  242. jobctrl-0.4.0/tests/career_learning_fixture.py +183 -0
  243. jobctrl-0.4.0/tests/company_briefing_fixture.py +66 -0
  244. jobctrl-0.4.0/tests/compensation_fakes.py +271 -0
  245. jobctrl-0.4.0/tests/conftest.py +160 -0
  246. jobctrl-0.4.0/tests/cover_letter_pdf_probe.py +120 -0
  247. jobctrl-0.4.0/tests/determination_fakes.py +327 -0
  248. jobctrl-0.4.0/tests/email_approval_api_probe.py +103 -0
  249. jobctrl-0.4.0/tests/fixtures/enrichment_retry.sql +27 -0
  250. jobctrl-0.4.0/tests/fixtures/rescore_advice_probe.py +40 -0
  251. jobctrl-0.4.0/tests/fixtures/rpc_boundary_python.json +1 -0
  252. jobctrl-0.4.0/tests/gmail_feedback_rpc_fixture.py +101 -0
  253. jobctrl-0.4.0/tests/helpers/apply_batch_outcome_native.py +147 -0
  254. jobctrl-0.4.0/tests/helpers/apply_custody_native.py +119 -0
  255. jobctrl-0.4.0/tests/helpers/apply_execution_native.py +93 -0
  256. jobctrl-0.4.0/tests/helpers/apply_execution_ports.py +212 -0
  257. jobctrl-0.4.0/tests/helpers/apply_execution_retry_native.py +246 -0
  258. jobctrl-0.4.0/tests/helpers/apply_execution_temporal.py +165 -0
  259. jobctrl-0.4.0/tests/helpers/apply_session_fence_native.py +162 -0
  260. jobctrl-0.4.0/tests/legacy_evidence_fixture.py +41 -0
  261. jobctrl-0.4.0/tests/outreach_rpc_harness.py +85 -0
  262. jobctrl-0.4.0/tests/projection_cross_runtime_fixture.py +201 -0
  263. jobctrl-0.4.0/tests/smart_posting_fakes.py +111 -0
  264. jobctrl-0.4.0/tests/source_apply_scope_probe.py +160 -0
  265. jobctrl-0.4.0/tests/source_email_scope_probe.py +116 -0
  266. jobctrl-0.4.0/tests/source_scope_child_evidence.py +131 -0
  267. jobctrl-0.4.0/tests/temporal_env.py +82 -0
  268. jobctrl-0.4.0/tests/test_accepted_docx_export.py +328 -0
  269. jobctrl-0.4.0/tests/test_accepted_export_api.py +103 -0
  270. jobctrl-0.4.0/tests/test_activity_apply.py +293 -0
  271. jobctrl-0.4.0/tests/test_activity_connection_lifetime.py +269 -0
  272. jobctrl-0.4.0/tests/test_activity_control_executor_capacity.py +183 -0
  273. jobctrl-0.4.0/tests/test_activity_cover.py +67 -0
  274. jobctrl-0.4.0/tests/test_activity_executor_generation_capacity.py +363 -0
  275. jobctrl-0.4.0/tests/test_activity_runtime_telemetry.py +361 -0
  276. jobctrl-0.4.0/tests/test_agent_runtime_cleanup_privacy.py +129 -0
  277. jobctrl-0.4.0/tests/test_agent_runtime_codex.py +232 -0
  278. jobctrl-0.4.0/tests/test_agent_runtime_pool.py +304 -0
  279. jobctrl-0.4.0/tests/test_analysis_determinations.py +263 -0
  280. jobctrl-0.4.0/tests/test_analysis_retry_boundaries.py +227 -0
  281. jobctrl-0.4.0/tests/test_antigravity_adapter.py +345 -0
  282. jobctrl-0.4.0/tests/test_apply_approval_vocabulary.py +142 -0
  283. jobctrl-0.4.0/tests/test_apply_batch_crashes.py +509 -0
  284. jobctrl-0.4.0/tests/test_apply_batch_limits.py +245 -0
  285. jobctrl-0.4.0/tests/test_apply_browser_ownership.py +870 -0
  286. jobctrl-0.4.0/tests/test_apply_chrome_dry_run_guard.py +1359 -0
  287. jobctrl-0.4.0/tests/test_apply_chrome_endpoint_ownership.py +287 -0
  288. jobctrl-0.4.0/tests/test_apply_crash_custody.py +287 -0
  289. jobctrl-0.4.0/tests/test_apply_dashboard_isolation.py +158 -0
  290. jobctrl-0.4.0/tests/test_apply_endpoint_consumers.py +108 -0
  291. jobctrl-0.4.0/tests/test_apply_execution.py +484 -0
  292. jobctrl-0.4.0/tests/test_apply_launcher_ownership.py +698 -0
  293. jobctrl-0.4.0/tests/test_apply_log_artifact_registration.py +436 -0
  294. jobctrl-0.4.0/tests/test_apply_native_custody.py +141 -0
  295. jobctrl-0.4.0/tests/test_apply_prompt_builder.py +514 -0
  296. jobctrl-0.4.0/tests/test_apply_regressions.py +4916 -0
  297. jobctrl-0.4.0/tests/test_apply_runs_projection_from_events.py +688 -0
  298. jobctrl-0.4.0/tests/test_apply_saga.py +842 -0
  299. jobctrl-0.4.0/tests/test_apply_source_census_scope.py +198 -0
  300. jobctrl-0.4.0/tests/test_apply_source_lifetime.py +262 -0
  301. jobctrl-0.4.0/tests/test_apply_stopped_owner_recovery.py +168 -0
  302. jobctrl-0.4.0/tests/test_apply_tools_mcp_server.py +788 -0
  303. jobctrl-0.4.0/tests/test_apply_use_cases.py +659 -0
  304. jobctrl-0.4.0/tests/test_approved_material_recovery_ownership.py +135 -0
  305. jobctrl-0.4.0/tests/test_archived_smart_posting_temporal.py +128 -0
  306. jobctrl-0.4.0/tests/test_artifact_determinations.py +474 -0
  307. jobctrl-0.4.0/tests/test_audit_projection_parity.py +838 -0
  308. jobctrl-0.4.0/tests/test_auto_apply_reconciler.py +253 -0
  309. jobctrl-0.4.0/tests/test_automatic_compensation_refresh.py +358 -0
  310. jobctrl-0.4.0/tests/test_automatic_material_decline.py +212 -0
  311. jobctrl-0.4.0/tests/test_automatic_preparation.py +1076 -0
  312. jobctrl-0.4.0/tests/test_automatic_preparation_overlap.py +494 -0
  313. jobctrl-0.4.0/tests/test_automatic_preparation_temporal_qa.py +1475 -0
  314. jobctrl-0.4.0/tests/test_availability_model_budget.py +116 -0
  315. jobctrl-0.4.0/tests/test_baseline_accomplishment_retention.py +286 -0
  316. jobctrl-0.4.0/tests/test_binding_repair_feedback.py +218 -0
  317. jobctrl-0.4.0/tests/test_browser_capabilities.py +1285 -0
  318. jobctrl-0.4.0/tests/test_browser_rate_limit_recovery.py +252 -0
  319. jobctrl-0.4.0/tests/test_browser_request_headers.py +121 -0
  320. jobctrl-0.4.0/tests/test_browser_ua_propagation.py +420 -0
  321. jobctrl-0.4.0/tests/test_captured_posting_recovery.py +782 -0
  322. jobctrl-0.4.0/tests/test_career_learning.py +305 -0
  323. jobctrl-0.4.0/tests/test_claim_review_response.py +404 -0
  324. jobctrl-0.4.0/tests/test_claude_code_cli_adapter.py +936 -0
  325. jobctrl-0.4.0/tests/test_claude_terminal_failure.py +795 -0
  326. jobctrl-0.4.0/tests/test_codex_home_isolation.py +894 -0
  327. jobctrl-0.4.0/tests/test_codex_runtime_cleanup_privacy.py +950 -0
  328. jobctrl-0.4.0/tests/test_codex_runtime_storage.py +150 -0
  329. jobctrl-0.4.0/tests/test_codex_turn.py +137 -0
  330. jobctrl-0.4.0/tests/test_codex_workspace.py +158 -0
  331. jobctrl-0.4.0/tests/test_company_briefings.py +453 -0
  332. jobctrl-0.4.0/tests/test_compensation_benchmark_materialization.py +80 -0
  333. jobctrl-0.4.0/tests/test_compensation_classification_parallelism.py +185 -0
  334. jobctrl-0.4.0/tests/test_compensation_refresh_temporal.py +245 -0
  335. jobctrl-0.4.0/tests/test_compensation_source_outcomes.py +418 -0
  336. jobctrl-0.4.0/tests/test_compensation_v7_job_id.py +248 -0
  337. jobctrl-0.4.0/tests/test_contact_research_activity_heartbeat.py +80 -0
  338. jobctrl-0.4.0/tests/test_contact_research_e2e_fixture.py +278 -0
  339. jobctrl-0.4.0/tests/test_contact_research_inference.py +523 -0
  340. jobctrl-0.4.0/tests/test_contact_research_inference_temporal.py +196 -0
  341. jobctrl-0.4.0/tests/test_contact_research_workflow.py +2052 -0
  342. jobctrl-0.4.0/tests/test_cover_generation_repair.py +115 -0
  343. jobctrl-0.4.0/tests/test_cover_letter_opt_in.py +313 -0
  344. jobctrl-0.4.0/tests/test_cover_letter_review.py +256 -0
  345. jobctrl-0.4.0/tests/test_cover_reviewed_anchors.py +114 -0
  346. jobctrl-0.4.0/tests/test_dashboard_execution_policy.py +93 -0
  347. jobctrl-0.4.0/tests/test_database_initialization_race.py +499 -0
  348. jobctrl-0.4.0/tests/test_default_resume_fit.py +145 -0
  349. jobctrl-0.4.0/tests/test_dependabot_policy.py +38 -0
  350. jobctrl-0.4.0/tests/test_detail_page_frames.py +67 -0
  351. jobctrl-0.4.0/tests/test_detail_projection_job_id_contract.py +40 -0
  352. jobctrl-0.4.0/tests/test_digest_canonical_cli.py +807 -0
  353. jobctrl-0.4.0/tests/test_digest_cli.py +133 -0
  354. jobctrl-0.4.0/tests/test_digest_parity.py +579 -0
  355. jobctrl-0.4.0/tests/test_direct_material_attempt_fencing.py +336 -0
  356. jobctrl-0.4.0/tests/test_discover_reliability.py +3133 -0
  357. jobctrl-0.4.0/tests/test_discovery_execution_reconciliation.py +2653 -0
  358. jobctrl-0.4.0/tests/test_discovery_execution_result_plan.py +122 -0
  359. jobctrl-0.4.0/tests/test_discovery_family_result_budget.py +469 -0
  360. jobctrl-0.4.0/tests/test_discovery_limits.py +1387 -0
  361. jobctrl-0.4.0/tests/test_discovery_preparation_orchestration.py +630 -0
  362. jobctrl-0.4.0/tests/test_discovery_result_budget.py +385 -0
  363. jobctrl-0.4.0/tests/test_domain_event_parity.py +126 -0
  364. jobctrl-0.4.0/tests/test_domain_events.py +586 -0
  365. jobctrl-0.4.0/tests/test_employer_analysis_ensemble.py +715 -0
  366. jobctrl-0.4.0/tests/test_employer_analysis_leg_config.py +131 -0
  367. jobctrl-0.4.0/tests/test_enrichment_politeness_gate.py +1124 -0
  368. jobctrl-0.4.0/tests/test_enrichment_retry.py +308 -0
  369. jobctrl-0.4.0/tests/test_enrichment_url_safety.py +948 -0
  370. jobctrl-0.4.0/tests/test_enrichment_visible_capture.py +157 -0
  371. jobctrl-0.4.0/tests/test_exact_v7_apply_acquire_job_identity.py +1873 -0
  372. jobctrl-0.4.0/tests/test_exact_v7_schema.py +1523 -0
  373. jobctrl-0.4.0/tests/test_exact_v7_state_reset.py +285 -0
  374. jobctrl-0.4.0/tests/test_gmail_connector.py +559 -0
  375. jobctrl-0.4.0/tests/test_gmail_feedback.py +1087 -0
  376. jobctrl-0.4.0/tests/test_gmail_feedback_client_contract.py +356 -0
  377. jobctrl-0.4.0/tests/test_gmail_feedback_privacy.py +276 -0
  378. jobctrl-0.4.0/tests/test_gmail_feedback_scan_handler.py +85 -0
  379. jobctrl-0.4.0/tests/test_gmail_token_atomic.py +404 -0
  380. jobctrl-0.4.0/tests/test_gmail_token_windows_acl.py +222 -0
  381. jobctrl-0.4.0/tests/test_gmail_windows_acl_contract.py +195 -0
  382. jobctrl-0.4.0/tests/test_interpretation_citable_fields.py +143 -0
  383. jobctrl-0.4.0/tests/test_interview_determinations.py +343 -0
  384. jobctrl-0.4.0/tests/test_job_detail_authority.py +33 -0
  385. jobctrl-0.4.0/tests/test_job_list_projection.py +561 -0
  386. jobctrl-0.4.0/tests/test_job_url_import_status.py +116 -0
  387. jobctrl-0.4.0/tests/test_job_url_import_workflow.py +1405 -0
  388. jobctrl-0.4.0/tests/test_jobstreaming_source_result_budget.py +296 -0
  389. jobctrl-0.4.0/tests/test_jsonrpc_handlers.py +2839 -0
  390. jobctrl-0.4.0/tests/test_legacy_evidence_preservation.py +258 -0
  391. jobctrl-0.4.0/tests/test_legacy_evidence_recovery.py +223 -0
  392. jobctrl-0.4.0/tests/test_linkedin_guest_dialog.py +186 -0
  393. jobctrl-0.4.0/tests/test_llm_provider_routing.py +544 -0
  394. jobctrl-0.4.0/tests/test_llm_spans.py +378 -0
  395. jobctrl-0.4.0/tests/test_llm_spend_budget.py +200 -0
  396. jobctrl-0.4.0/tests/test_locale_variants_integration.py +586 -0
  397. jobctrl-0.4.0/tests/test_material_activity_recovery.py +447 -0
  398. jobctrl-0.4.0/tests/test_material_batch_attempt_fencing.py +421 -0
  399. jobctrl-0.4.0/tests/test_material_candidate_identity.py +85 -0
  400. jobctrl-0.4.0/tests/test_material_context_requirements.py +84 -0
  401. jobctrl-0.4.0/tests/test_material_evidence_selection.py +396 -0
  402. jobctrl-0.4.0/tests/test_material_executor_prerequisites.py +76 -0
  403. jobctrl-0.4.0/tests/test_material_override_retention.py +253 -0
  404. jobctrl-0.4.0/tests/test_material_render_publication.py +556 -0
  405. jobctrl-0.4.0/tests/test_material_review_history.py +224 -0
  406. jobctrl-0.4.0/tests/test_materials_review_constraints.py +107 -0
  407. jobctrl-0.4.0/tests/test_materials_use_cases.py +580 -0
  408. jobctrl-0.4.0/tests/test_model_catalog.py +165 -0
  409. jobctrl-0.4.0/tests/test_native_apply_readiness.py +94 -0
  410. jobctrl-0.4.0/tests/test_native_credentials.py +485 -0
  411. jobctrl-0.4.0/tests/test_numeric_literal_formats.py +30 -0
  412. jobctrl-0.4.0/tests/test_offer_outreach.py +339 -0
  413. jobctrl-0.4.0/tests/test_optional_extension.py +975 -0
  414. jobctrl-0.4.0/tests/test_otel_init.py +222 -0
  415. jobctrl-0.4.0/tests/test_outreach_repository_v7.py +336 -0
  416. jobctrl-0.4.0/tests/test_p1b_error_inversion.py +809 -0
  417. jobctrl-0.4.0/tests/test_packaged_browser_contract.py +22 -0
  418. jobctrl-0.4.0/tests/test_parallel_letter_reviews.py +474 -0
  419. jobctrl-0.4.0/tests/test_parallel_resume_reviews.py +330 -0
  420. jobctrl-0.4.0/tests/test_pdf_renderer_ports.py +1302 -0
  421. jobctrl-0.4.0/tests/test_pipeline_observability.py +214 -0
  422. jobctrl-0.4.0/tests/test_posted_compensation_source_fence.py +313 -0
  423. jobctrl-0.4.0/tests/test_posting_source_proposals.py +362 -0
  424. jobctrl-0.4.0/tests/test_posting_source_selection.py +134 -0
  425. jobctrl-0.4.0/tests/test_posting_sources.py +35 -0
  426. jobctrl-0.4.0/tests/test_preparation_availability_cache.py +132 -0
  427. jobctrl-0.4.0/tests/test_preparation_capture_reuse.py +251 -0
  428. jobctrl-0.4.0/tests/test_preparation_job_reader.py +152 -0
  429. jobctrl-0.4.0/tests/test_preparation_manual_decline.py +565 -0
  430. jobctrl-0.4.0/tests/test_preparation_outcome_audit.py +741 -0
  431. jobctrl-0.4.0/tests/test_preparation_score_cancellation.py +413 -0
  432. jobctrl-0.4.0/tests/test_preparation_score_material_block.py +256 -0
  433. jobctrl-0.4.0/tests/test_process_ownership_census.py +1475 -0
  434. jobctrl-0.4.0/tests/test_process_ownership_graceful.py +952 -0
  435. jobctrl-0.4.0/tests/test_process_ownership_scope_fence.py +136 -0
  436. jobctrl-0.4.0/tests/test_process_ownership_temporal.py +157 -0
  437. jobctrl-0.4.0/tests/test_projection_builder.py +1234 -0
  438. jobctrl-0.4.0/tests/test_provider_availability_recovery.py +293 -0
  439. jobctrl-0.4.0/tests/test_provider_packs.py +603 -0
  440. jobctrl-0.4.0/tests/test_provider_transient_recovery.py +101 -0
  441. jobctrl-0.4.0/tests/test_release_check.py +643 -0
  442. jobctrl-0.4.0/tests/test_release_workflow_topology.py +95 -0
  443. jobctrl-0.4.0/tests/test_remaining_determinations.py +305 -0
  444. jobctrl-0.4.0/tests/test_required_skill_categories.py +129 -0
  445. jobctrl-0.4.0/tests/test_requirement_fit_resolution.py +240 -0
  446. jobctrl-0.4.0/tests/test_requirement_led_tailoring.py +1525 -0
  447. jobctrl-0.4.0/tests/test_resume_html_migration.py +301 -0
  448. jobctrl-0.4.0/tests/test_resume_polish_policy.py +37 -0
  449. jobctrl-0.4.0/tests/test_resume_review_response_bounds.py +151 -0
  450. jobctrl-0.4.0/tests/test_rpc_learning_recommendations.py +433 -0
  451. jobctrl-0.4.0/tests/test_runtime_identity.py +259 -0
  452. jobctrl-0.4.0/tests/test_saved_default_model.py +109 -0
  453. jobctrl-0.4.0/tests/test_saved_posting_availability_runtime.py +1001 -0
  454. jobctrl-0.4.0/tests/test_saved_search_read_failure.py +395 -0
  455. jobctrl-0.4.0/tests/test_score_atomic_publication.py +534 -0
  456. jobctrl-0.4.0/tests/test_score_batch_ownership.py +502 -0
  457. jobctrl-0.4.0/tests/test_score_interview_binding.py +63 -0
  458. jobctrl-0.4.0/tests/test_score_profile_impact.py +480 -0
  459. jobctrl-0.4.0/tests/test_score_repository.py +1061 -0
  460. jobctrl-0.4.0/tests/test_score_saved_search_preflight.py +503 -0
  461. jobctrl-0.4.0/tests/test_score_source_fence.py +352 -0
  462. jobctrl-0.4.0/tests/test_score_staleness_publication.py +191 -0
  463. jobctrl-0.4.0/tests/test_score_use_cases.py +1392 -0
  464. jobctrl-0.4.0/tests/test_scorer.py +1625 -0
  465. jobctrl-0.4.0/tests/test_scoring_determinations.py +163 -0
  466. jobctrl-0.4.0/tests/test_scoring_eval_feedback.py +237 -0
  467. jobctrl-0.4.0/tests/test_screening_answers.py +656 -0
  468. jobctrl-0.4.0/tests/test_selected_board_wiring.py +224 -0
  469. jobctrl-0.4.0/tests/test_semantic_determinations.py +446 -0
  470. jobctrl-0.4.0/tests/test_semantic_storage.py +186 -0
  471. jobctrl-0.4.0/tests/test_setup_probes.py +781 -0
  472. jobctrl-0.4.0/tests/test_single_provider_analysis.py +91 -0
  473. jobctrl-0.4.0/tests/test_smart_posting_intake.py +354 -0
  474. jobctrl-0.4.0/tests/test_smartextract_discovery.py +672 -0
  475. jobctrl-0.4.0/tests/test_smartextract_resilience.py +127 -0
  476. jobctrl-0.4.0/tests/test_source_registry.py +530 -0
  477. jobctrl-0.4.0/tests/test_stage_runner_thread_safety.py +169 -0
  478. jobctrl-0.4.0/tests/test_tailor_judge_selection.py +99 -0
  479. jobctrl-0.4.0/tests/test_tailor_provenance_integration.py +1577 -0
  480. jobctrl-0.4.0/tests/test_tailor_retailor.py +854 -0
  481. jobctrl-0.4.0/tests/test_tailor_voice_audit_integration.py +974 -0
  482. jobctrl-0.4.0/tests/test_tailoring_artifact_boundary.py +225 -0
  483. jobctrl-0.4.0/tests/test_tailoring_ownership_race.py +532 -0
  484. jobctrl-0.4.0/tests/test_tailoring_policy_revisions.py +292 -0
  485. jobctrl-0.4.0/tests/test_tailoring_prompt_projection.py +70 -0
  486. jobctrl-0.4.0/tests/test_target_search_preferences.py +158 -0
  487. jobctrl-0.4.0/tests/test_temporal_concurrency.py +71 -0
  488. jobctrl-0.4.0/tests/test_temporal_env.py +209 -0
  489. jobctrl-0.4.0/tests/test_temporal_worker.py +108 -0
  490. jobctrl-0.4.0/tests/test_terminal_material_rejection.py +69 -0
  491. jobctrl-0.4.0/tests/test_v12_activation.py +298 -0
  492. jobctrl-0.4.0/tests/test_v14_v15_inplace.py +708 -0
  493. jobctrl-0.4.0/tests/test_v15_candidate_execution.py +137 -0
  494. jobctrl-0.4.0/tests/test_v15_lifecycle_revisions.py +122 -0
  495. jobctrl-0.4.0/tests/test_v7_cover_runtime.py +1041 -0
  496. jobctrl-0.4.0/tests/test_v7_score_runtime.py +627 -0
  497. jobctrl-0.4.0/tests/test_v7_tailor_runtime.py +2063 -0
  498. jobctrl-0.4.0/tests/test_voice_adapter.py +247 -0
  499. jobctrl-0.4.0/tests/test_workday_discovery.py +339 -0
  500. jobctrl-0.4.0/tests/test_worker_cooperative_shutdown.py +194 -0
  501. jobctrl-0.4.0/tests/test_worker_reconciler.py +582 -0
  502. jobctrl-0.4.0/tests/test_worker_trace_context.py +238 -0
  503. jobctrl-0.4.0/tests/test_workflow_apply.py +1028 -0
  504. jobctrl-0.4.0/tests/test_workflow_control_capacity.py +346 -0
  505. jobctrl-0.4.0/tests/test_workflow_discovery.py +1670 -0
  506. jobctrl-0.4.0/tests/test_workflow_finalize.py +433 -0
  507. jobctrl-0.4.0/tests/test_workflow_id_overlap.py +109 -0
  508. jobctrl-0.4.0/tests/test_workflow_job_pipeline.py +1731 -0
  509. jobctrl-0.4.0/tests/test_workflow_job_preparation.py +1252 -0
  510. jobctrl-0.4.0/tests/test_workflow_start_metadata.py +141 -0
  511. jobctrl-0.4.0/tests/workflow_determination_fakes.py +131 -0
  512. jobctrl-0.4.0/uv.lock +2376 -0
  513. jobctrl-0.3.0/PKG-INFO +0 -86
  514. jobctrl-0.3.0/README.md +0 -29
  515. jobctrl-0.3.0/pyproject.toml +0 -149
  516. jobctrl-0.3.0/src/jobctrl/__init__.py +0 -3
  517. jobctrl-0.3.0/src/jobctrl/apply/activities.py +0 -142
  518. jobctrl-0.3.0/src/jobctrl/apply/auto_apply.py +0 -188
  519. jobctrl-0.3.0/src/jobctrl/apply/chrome.py +0 -1400
  520. jobctrl-0.3.0/src/jobctrl/apply/dashboard.py +0 -224
  521. jobctrl-0.3.0/src/jobctrl/apply/launcher.py +0 -2881
  522. jobctrl-0.3.0/src/jobctrl/apply/workflow.py +0 -208
  523. jobctrl-0.3.0/src/jobctrl/cli.py +0 -3862
  524. jobctrl-0.3.0/src/jobctrl/config.py +0 -1879
  525. jobctrl-0.3.0/src/jobctrl/contact/activities.py +0 -180
  526. jobctrl-0.3.0/src/jobctrl/contact/workflow.py +0 -209
  527. jobctrl-0.3.0/src/jobctrl/database.py +0 -3621
  528. jobctrl-0.3.0/src/jobctrl/digest.py +0 -747
  529. jobctrl-0.3.0/src/jobctrl/discovery/activities.py +0 -805
  530. jobctrl-0.3.0/src/jobctrl/discovery/execution_reconciliation.py +0 -1488
  531. jobctrl-0.3.0/src/jobctrl/discovery/job_url_import_workflow.py +0 -1441
  532. jobctrl-0.3.0/src/jobctrl/discovery/jobspy.py +0 -2132
  533. jobctrl-0.3.0/src/jobctrl/discovery/smartextract.py +0 -1540
  534. jobctrl-0.3.0/src/jobctrl/discovery/workday.py +0 -854
  535. jobctrl-0.3.0/src/jobctrl/discovery/workflow.py +0 -713
  536. jobctrl-0.3.0/src/jobctrl/domain/apply/process_manager.py +0 -768
  537. jobctrl-0.3.0/src/jobctrl/domain/apply/services.py +0 -339
  538. jobctrl-0.3.0/src/jobctrl/domain/apply/use_cases.py +0 -687
  539. jobctrl-0.3.0/src/jobctrl/domain/apply/value_objects.py +0 -321
  540. jobctrl-0.3.0/src/jobctrl/domain/compensation/classification.py +0 -48
  541. jobctrl-0.3.0/src/jobctrl/domain/contact/outreach.py +0 -612
  542. jobctrl-0.3.0/src/jobctrl/domain/contact/outreach_gates.py +0 -131
  543. jobctrl-0.3.0/src/jobctrl/domain/contact/outreach_use_cases.py +0 -610
  544. jobctrl-0.3.0/src/jobctrl/domain/contact/research.py +0 -304
  545. jobctrl-0.3.0/src/jobctrl/domain/contact/research_services.py +0 -323
  546. jobctrl-0.3.0/src/jobctrl/domain/contact/research_use_cases.py +0 -164
  547. jobctrl-0.3.0/src/jobctrl/domain/determinations.py +0 -304
  548. jobctrl-0.3.0/src/jobctrl/domain/discovery/use_cases.py +0 -666
  549. jobctrl-0.3.0/src/jobctrl/domain/enrichment/interpretation.py +0 -115
  550. jobctrl-0.3.0/src/jobctrl/domain/enrichment/page_interpretation.py +0 -113
  551. jobctrl-0.3.0/src/jobctrl/domain/enrichment/value_objects.py +0 -215
  552. jobctrl-0.3.0/src/jobctrl/domain/errors.py +0 -78
  553. jobctrl-0.3.0/src/jobctrl/domain/events/__init__.py +0 -504
  554. jobctrl-0.3.0/src/jobctrl/domain/events/apply.py +0 -109
  555. jobctrl-0.3.0/src/jobctrl/domain/events/contact.py +0 -328
  556. jobctrl-0.3.0/src/jobctrl/domain/events/discovery.py +0 -317
  557. jobctrl-0.3.0/src/jobctrl/domain/events/workflow.py +0 -260
  558. jobctrl-0.3.0/src/jobctrl/domain/exact_values.py +0 -19
  559. jobctrl-0.3.0/src/jobctrl/domain/interview/catalog.py +0 -453
  560. jobctrl-0.3.0/src/jobctrl/domain/materials/analysis.py +0 -491
  561. jobctrl-0.3.0/src/jobctrl/domain/materials/analyze_use_case.py +0 -335
  562. jobctrl-0.3.0/src/jobctrl/domain/materials/artifact_quality.py +0 -80
  563. jobctrl-0.3.0/src/jobctrl/domain/materials/claim_verification.py +0 -165
  564. jobctrl-0.3.0/src/jobctrl/domain/materials/generation.py +0 -49
  565. jobctrl-0.3.0/src/jobctrl/domain/materials/policy.py +0 -760
  566. jobctrl-0.3.0/src/jobctrl/domain/materials/quality.py +0 -739
  567. jobctrl-0.3.0/src/jobctrl/domain/materials/requirement_coverage.py +0 -1368
  568. jobctrl-0.3.0/src/jobctrl/domain/materials/resume_document.py +0 -266
  569. jobctrl-0.3.0/src/jobctrl/domain/materials/services.py +0 -457
  570. jobctrl-0.3.0/src/jobctrl/domain/materials/use_cases.py +0 -4035
  571. jobctrl-0.3.0/src/jobctrl/domain/ports/apply.py +0 -224
  572. jobctrl-0.3.0/src/jobctrl/domain/ports/artifact_quality.py +0 -38
  573. jobctrl-0.3.0/src/jobctrl/domain/ports/claim_verification.py +0 -77
  574. jobctrl-0.3.0/src/jobctrl/domain/ports/contact.py +0 -125
  575. jobctrl-0.3.0/src/jobctrl/domain/ports/llm.py +0 -99
  576. jobctrl-0.3.0/src/jobctrl/domain/ports/materials.py +0 -470
  577. jobctrl-0.3.0/src/jobctrl/domain/ports/politeness.py +0 -260
  578. jobctrl-0.3.0/src/jobctrl/domain/ports/resume_adversarial.py +0 -32
  579. jobctrl-0.3.0/src/jobctrl/domain/ports/scoring.py +0 -142
  580. jobctrl-0.3.0/src/jobctrl/domain/preparation/work_items.py +0 -50
  581. jobctrl-0.3.0/src/jobctrl/domain/profile/canonical_sources.py +0 -63
  582. jobctrl-0.3.0/src/jobctrl/domain/profile/search_targets.py +0 -32
  583. jobctrl-0.3.0/src/jobctrl/domain/profile/value_objects.py +0 -691
  584. jobctrl-0.3.0/src/jobctrl/domain/scoring/determination.py +0 -105
  585. jobctrl-0.3.0/src/jobctrl/domain/scoring/requirement_fit.py +0 -196
  586. jobctrl-0.3.0/src/jobctrl/domain/scoring/services.py +0 -516
  587. jobctrl-0.3.0/src/jobctrl/domain/scoring/use_cases.py +0 -894
  588. jobctrl-0.3.0/src/jobctrl/domain/scoring/value_objects.py +0 -1357
  589. jobctrl-0.3.0/src/jobctrl/enrichment/availability.py +0 -1433
  590. jobctrl-0.3.0/src/jobctrl/enrichment/detail.py +0 -4908
  591. jobctrl-0.3.0/src/jobctrl/infrastructure/analysis/antigravity_analysis_adapter.py +0 -231
  592. jobctrl-0.3.0/src/jobctrl/infrastructure/analysis/claude_analysis_adapter.py +0 -266
  593. jobctrl-0.3.0/src/jobctrl/infrastructure/analysis/codex_analysis_adapter.py +0 -324
  594. jobctrl-0.3.0/src/jobctrl/infrastructure/analysis/ensemble.py +0 -249
  595. jobctrl-0.3.0/src/jobctrl/infrastructure/apply/claude_code_cli.py +0 -637
  596. jobctrl-0.3.0/src/jobctrl/infrastructure/apply/email_sender.py +0 -27
  597. jobctrl-0.3.0/src/jobctrl/infrastructure/apply/local_chrome.py +0 -88
  598. jobctrl-0.3.0/src/jobctrl/infrastructure/apply_tools/mcp_server.py +0 -866
  599. jobctrl-0.3.0/src/jobctrl/infrastructure/compensation/automatic_refresh.py +0 -580
  600. jobctrl-0.3.0/src/jobctrl/infrastructure/compensation/interpretation.py +0 -54
  601. jobctrl-0.3.0/src/jobctrl/infrastructure/compensation/levels_fyi_public.py +0 -659
  602. jobctrl-0.3.0/src/jobctrl/infrastructure/compensation/refresh_state.py +0 -541
  603. jobctrl-0.3.0/src/jobctrl/infrastructure/compensation/sqlite_market_repository.py +0 -1599
  604. jobctrl-0.3.0/src/jobctrl/infrastructure/compensation/sqlite_repository.py +0 -435
  605. jobctrl-0.3.0/src/jobctrl/infrastructure/compensation/workflow.py +0 -203
  606. jobctrl-0.3.0/src/jobctrl/infrastructure/contact/outreach_repository.py +0 -529
  607. jobctrl-0.3.0/src/jobctrl/infrastructure/contact/research_fetcher.py +0 -251
  608. jobctrl-0.3.0/src/jobctrl/infrastructure/contact/research_repository.py +0 -456
  609. jobctrl-0.3.0/src/jobctrl/infrastructure/determinations.py +0 -377
  610. jobctrl-0.3.0/src/jobctrl/infrastructure/discovery/capture_recovery.py +0 -109
  611. jobctrl-0.3.0/src/jobctrl/infrastructure/discovery/production_wiring.py +0 -2196
  612. jobctrl-0.3.0/src/jobctrl/infrastructure/discovery/sqlite_execution_repository.py +0 -331
  613. jobctrl-0.3.0/src/jobctrl/infrastructure/discovery/sqlite_repository.py +0 -1394
  614. jobctrl-0.3.0/src/jobctrl/infrastructure/discovery/sqlite_search_unit_repository.py +0 -879
  615. jobctrl-0.3.0/src/jobctrl/infrastructure/enrichment/interpretation.py +0 -80
  616. jobctrl-0.3.0/src/jobctrl/infrastructure/enrichment/playwright_fetcher.py +0 -424
  617. jobctrl-0.3.0/src/jobctrl/infrastructure/gmail/auth.py +0 -239
  618. jobctrl-0.3.0/src/jobctrl/infrastructure/gmail/client.py +0 -302
  619. jobctrl-0.3.0/src/jobctrl/infrastructure/gmail/feedback.py +0 -727
  620. jobctrl-0.3.0/src/jobctrl/infrastructure/llm/codex_turn.py +0 -181
  621. jobctrl-0.3.0/src/jobctrl/infrastructure/llm/llm_client.py +0 -910
  622. jobctrl-0.3.0/src/jobctrl/infrastructure/llm/model_catalog.py +0 -256
  623. jobctrl-0.3.0/src/jobctrl/infrastructure/llm/provider_errors.py +0 -275
  624. jobctrl-0.3.0/src/jobctrl/infrastructure/materials/__init__.py +0 -48
  625. jobctrl-0.3.0/src/jobctrl/infrastructure/materials/html_resume_pdf.py +0 -821
  626. jobctrl-0.3.0/src/jobctrl/infrastructure/materials/playwright_html_pdf.py +0 -158
  627. jobctrl-0.3.0/src/jobctrl/infrastructure/materials/screening_answers.py +0 -444
  628. jobctrl-0.3.0/src/jobctrl/infrastructure/materials/sqlite_repository.py +0 -1391
  629. jobctrl-0.3.0/src/jobctrl/infrastructure/materials/voice_adapter.py +0 -193
  630. jobctrl-0.3.0/src/jobctrl/infrastructure/migrations/schema_manifest.py +0 -156
  631. jobctrl-0.3.0/src/jobctrl/infrastructure/migrations/schema_v13.py +0 -106
  632. jobctrl-0.3.0/src/jobctrl/infrastructure/network/http_client.py +0 -152
  633. jobctrl-0.3.0/src/jobctrl/infrastructure/network/politeness.py +0 -320
  634. jobctrl-0.3.0/src/jobctrl/infrastructure/network/rate_limiter.py +0 -193
  635. jobctrl-0.3.0/src/jobctrl/infrastructure/network/url_safety.py +0 -331
  636. jobctrl-0.3.0/src/jobctrl/infrastructure/observability/llm_spans.py +0 -169
  637. jobctrl-0.3.0/src/jobctrl/infrastructure/preparation/sqlite_repository.py +0 -70
  638. jobctrl-0.3.0/src/jobctrl/infrastructure/preparation_recovery.py +0 -493
  639. jobctrl-0.3.0/src/jobctrl/infrastructure/profile/factory.py +0 -83
  640. jobctrl-0.3.0/src/jobctrl/infrastructure/profile/sqlite_repository.py +0 -1086
  641. jobctrl-0.3.0/src/jobctrl/infrastructure/projections/projection_builder.py +0 -5141
  642. jobctrl-0.3.0/src/jobctrl/infrastructure/projections/sqlite_projection_store.py +0 -1451
  643. jobctrl-0.3.0/src/jobctrl/infrastructure/rpc/handlers.py +0 -1319
  644. jobctrl-0.3.0/src/jobctrl/infrastructure/rpc/server.py +0 -354
  645. jobctrl-0.3.0/src/jobctrl/infrastructure/runtime_identity.py +0 -227
  646. jobctrl-0.3.0/src/jobctrl/infrastructure/scoring/criteria_provider.py +0 -170
  647. jobctrl-0.3.0/src/jobctrl/infrastructure/scoring/sqlite_repository.py +0 -815
  648. jobctrl-0.3.0/src/jobctrl/infrastructure/setup_probes.py +0 -985
  649. jobctrl-0.3.0/src/jobctrl/infrastructure/temporal/activity_runtime_telemetry.py +0 -378
  650. jobctrl-0.3.0/src/jobctrl/infrastructure/temporal/concurrency.py +0 -65
  651. jobctrl-0.3.0/src/jobctrl/infrastructure/temporal/finalize.py +0 -314
  652. jobctrl-0.3.0/src/jobctrl/infrastructure/temporal/registry.py +0 -116
  653. jobctrl-0.3.0/src/jobctrl/infrastructure/temporal/run_in_activity.py +0 -263
  654. jobctrl-0.3.0/src/jobctrl/infrastructure/temporal/worker.py +0 -105
  655. jobctrl-0.3.0/src/jobctrl/infrastructure/workflow_run_context.py +0 -87
  656. jobctrl-0.3.0/src/jobctrl/interview/activities.py +0 -518
  657. jobctrl-0.3.0/src/jobctrl/interview/workflow.py +0 -188
  658. jobctrl-0.3.0/src/jobctrl/llm.py +0 -810
  659. jobctrl-0.3.0/src/jobctrl/materials/activities.py +0 -850
  660. jobctrl-0.3.0/src/jobctrl/materials/executor.py +0 -90
  661. jobctrl-0.3.0/src/jobctrl/pipeline/automatic_preparation.py +0 -779
  662. jobctrl-0.3.0/src/jobctrl/pipeline/current_policy_selectors.py +0 -259
  663. jobctrl-0.3.0/src/jobctrl/pipeline/preparation.py +0 -1119
  664. jobctrl-0.3.0/src/jobctrl/pipeline/runner.py +0 -2792
  665. jobctrl-0.3.0/src/jobctrl/pipeline/workflow.py +0 -804
  666. jobctrl-0.3.0/src/jobctrl/preparation/workflow.py +0 -404
  667. jobctrl-0.3.0/src/jobctrl/profile/workflow.py +0 -168
  668. jobctrl-0.3.0/src/jobctrl/provider_packs.py +0 -690
  669. jobctrl-0.3.0/src/jobctrl/resume_profile.py +0 -416
  670. jobctrl-0.3.0/src/jobctrl/runtime.py +0 -363
  671. jobctrl-0.3.0/src/jobctrl/scoring/activities.py +0 -394
  672. jobctrl-0.3.0/src/jobctrl/scoring/cover_letter.py +0 -690
  673. jobctrl-0.3.0/src/jobctrl/scoring/employer_analysis.py +0 -155
  674. jobctrl-0.3.0/src/jobctrl/scoring/scorer.py +0 -1638
  675. jobctrl-0.3.0/src/jobctrl/scoring/tailor.py +0 -1530
  676. jobctrl-0.3.0/src/jobctrl/state.py +0 -1606
  677. jobctrl-0.3.0/src/jobctrl/wizard/init.py +0 -580
  678. jobctrl-0.3.0/src/jobctrl/workflow_specs.py +0 -705
  679. jobctrl-0.3.0/tests/compensation_fakes.py +0 -263
  680. jobctrl-0.3.0/tests/conftest.py +0 -135
  681. jobctrl-0.3.0/tests/determination_fakes.py +0 -253
  682. jobctrl-0.3.0/tests/fixtures/rpc_boundary_python.json +0 -1
  683. jobctrl-0.3.0/tests/projection_cross_runtime_fixture.py +0 -161
  684. jobctrl-0.3.0/tests/temporal_env.py +0 -63
  685. jobctrl-0.3.0/tests/test_activity_apply.py +0 -240
  686. jobctrl-0.3.0/tests/test_activity_connection_lifetime.py +0 -161
  687. jobctrl-0.3.0/tests/test_activity_cover.py +0 -62
  688. jobctrl-0.3.0/tests/test_activity_runtime_telemetry.py +0 -246
  689. jobctrl-0.3.0/tests/test_analysis_determinations.py +0 -232
  690. jobctrl-0.3.0/tests/test_antigravity_adapter.py +0 -331
  691. jobctrl-0.3.0/tests/test_apply_approval_vocabulary.py +0 -129
  692. jobctrl-0.3.0/tests/test_apply_chrome_dry_run_guard.py +0 -1340
  693. jobctrl-0.3.0/tests/test_apply_log_artifact_registration.py +0 -422
  694. jobctrl-0.3.0/tests/test_apply_prompt_builder.py +0 -514
  695. jobctrl-0.3.0/tests/test_apply_regressions.py +0 -1946
  696. jobctrl-0.3.0/tests/test_apply_runs_projection_from_events.py +0 -383
  697. jobctrl-0.3.0/tests/test_apply_saga.py +0 -776
  698. jobctrl-0.3.0/tests/test_apply_tools_mcp_server.py +0 -810
  699. jobctrl-0.3.0/tests/test_apply_use_cases.py +0 -638
  700. jobctrl-0.3.0/tests/test_artifact_determinations.py +0 -319
  701. jobctrl-0.3.0/tests/test_audit_projection_parity.py +0 -834
  702. jobctrl-0.3.0/tests/test_auto_apply_reconciler.py +0 -248
  703. jobctrl-0.3.0/tests/test_automatic_compensation_refresh.py +0 -191
  704. jobctrl-0.3.0/tests/test_automatic_preparation.py +0 -908
  705. jobctrl-0.3.0/tests/test_automatic_preparation_temporal_qa.py +0 -1324
  706. jobctrl-0.3.0/tests/test_browser_capabilities.py +0 -1272
  707. jobctrl-0.3.0/tests/test_browser_ua_propagation.py +0 -385
  708. jobctrl-0.3.0/tests/test_captured_posting_recovery.py +0 -158
  709. jobctrl-0.3.0/tests/test_claude_code_cli_adapter.py +0 -877
  710. jobctrl-0.3.0/tests/test_codex_home_isolation.py +0 -453
  711. jobctrl-0.3.0/tests/test_codex_turn.py +0 -76
  712. jobctrl-0.3.0/tests/test_compensation_benchmark_materialization.py +0 -76
  713. jobctrl-0.3.0/tests/test_compensation_v7_job_id.py +0 -143
  714. jobctrl-0.3.0/tests/test_contact_research_workflow.py +0 -572
  715. jobctrl-0.3.0/tests/test_dashboard_execution_policy.py +0 -93
  716. jobctrl-0.3.0/tests/test_detail_projection_job_id_contract.py +0 -51
  717. jobctrl-0.3.0/tests/test_digest_cli.py +0 -133
  718. jobctrl-0.3.0/tests/test_digest_parity.py +0 -524
  719. jobctrl-0.3.0/tests/test_discover_reliability.py +0 -3087
  720. jobctrl-0.3.0/tests/test_discovery_execution_reconciliation.py +0 -2529
  721. jobctrl-0.3.0/tests/test_discovery_limits.py +0 -1380
  722. jobctrl-0.3.0/tests/test_discovery_preparation_orchestration.py +0 -608
  723. jobctrl-0.3.0/tests/test_domain_event_parity.py +0 -121
  724. jobctrl-0.3.0/tests/test_domain_events.py +0 -565
  725. jobctrl-0.3.0/tests/test_employer_analysis_ensemble.py +0 -668
  726. jobctrl-0.3.0/tests/test_employer_analysis_leg_config.py +0 -126
  727. jobctrl-0.3.0/tests/test_employer_analysis_projection.py +0 -356
  728. jobctrl-0.3.0/tests/test_enrichment_politeness_gate.py +0 -1122
  729. jobctrl-0.3.0/tests/test_enrichment_url_safety.py +0 -696
  730. jobctrl-0.3.0/tests/test_exact_v7_apply_acquire_job_identity.py +0 -1053
  731. jobctrl-0.3.0/tests/test_exact_v7_schema.py +0 -1523
  732. jobctrl-0.3.0/tests/test_exact_v7_state_reset.py +0 -187
  733. jobctrl-0.3.0/tests/test_gmail_connector.py +0 -492
  734. jobctrl-0.3.0/tests/test_gmail_feedback.py +0 -1092
  735. jobctrl-0.3.0/tests/test_gmail_feedback_scan_handler.py +0 -69
  736. jobctrl-0.3.0/tests/test_interview_determinations.py +0 -341
  737. jobctrl-0.3.0/tests/test_job_list_projection.py +0 -620
  738. jobctrl-0.3.0/tests/test_job_url_import_workflow.py +0 -1207
  739. jobctrl-0.3.0/tests/test_jsonrpc_handlers.py +0 -2835
  740. jobctrl-0.3.0/tests/test_llm_provider_routing.py +0 -512
  741. jobctrl-0.3.0/tests/test_llm_spans.py +0 -217
  742. jobctrl-0.3.0/tests/test_llm_spend_budget.py +0 -199
  743. jobctrl-0.3.0/tests/test_locale_variants_integration.py +0 -586
  744. jobctrl-0.3.0/tests/test_material_activity_recovery.py +0 -365
  745. jobctrl-0.3.0/tests/test_materials_use_cases.py +0 -399
  746. jobctrl-0.3.0/tests/test_model_catalog.py +0 -154
  747. jobctrl-0.3.0/tests/test_native_credentials.py +0 -478
  748. jobctrl-0.3.0/tests/test_optional_extension.py +0 -955
  749. jobctrl-0.3.0/tests/test_otel_init.py +0 -170
  750. jobctrl-0.3.0/tests/test_outreach_repository_v7.py +0 -116
  751. jobctrl-0.3.0/tests/test_p1b_error_inversion.py +0 -658
  752. jobctrl-0.3.0/tests/test_pdf_renderer_ports.py +0 -1161
  753. jobctrl-0.3.0/tests/test_pipeline_observability.py +0 -202
  754. jobctrl-0.3.0/tests/test_preparation_job_reader.py +0 -118
  755. jobctrl-0.3.0/tests/test_projection_builder.py +0 -1238
  756. jobctrl-0.3.0/tests/test_provider_packs.py +0 -525
  757. jobctrl-0.3.0/tests/test_release_check.py +0 -632
  758. jobctrl-0.3.0/tests/test_release_workflow_topology.py +0 -64
  759. jobctrl-0.3.0/tests/test_remaining_determinations.py +0 -272
  760. jobctrl-0.3.0/tests/test_requirement_fit_resolution.py +0 -192
  761. jobctrl-0.3.0/tests/test_requirement_led_tailoring.py +0 -1496
  762. jobctrl-0.3.0/tests/test_resume_html_migration.py +0 -301
  763. jobctrl-0.3.0/tests/test_rpc_learning_recommendations.py +0 -397
  764. jobctrl-0.3.0/tests/test_runtime_identity.py +0 -243
  765. jobctrl-0.3.0/tests/test_saved_posting_availability_runtime.py +0 -920
  766. jobctrl-0.3.0/tests/test_score_repository.py +0 -818
  767. jobctrl-0.3.0/tests/test_score_use_cases.py +0 -1264
  768. jobctrl-0.3.0/tests/test_scorer.py +0 -1559
  769. jobctrl-0.3.0/tests/test_scoring_determinations.py +0 -163
  770. jobctrl-0.3.0/tests/test_scoring_eval_feedback.py +0 -191
  771. jobctrl-0.3.0/tests/test_screening_answers.py +0 -632
  772. jobctrl-0.3.0/tests/test_semantic_determinations.py +0 -246
  773. jobctrl-0.3.0/tests/test_semantic_storage.py +0 -183
  774. jobctrl-0.3.0/tests/test_setup_probes.py +0 -781
  775. jobctrl-0.3.0/tests/test_smartextract_discovery.py +0 -665
  776. jobctrl-0.3.0/tests/test_smartextract_resilience.py +0 -120
  777. jobctrl-0.3.0/tests/test_source_registry.py +0 -528
  778. jobctrl-0.3.0/tests/test_stage_runner_thread_safety.py +0 -147
  779. jobctrl-0.3.0/tests/test_tailor_provenance_integration.py +0 -1561
  780. jobctrl-0.3.0/tests/test_tailor_retailor.py +0 -844
  781. jobctrl-0.3.0/tests/test_tailor_voice_audit_integration.py +0 -942
  782. jobctrl-0.3.0/tests/test_tailoring_policy_revisions.py +0 -178
  783. jobctrl-0.3.0/tests/test_target_search_preferences.py +0 -155
  784. jobctrl-0.3.0/tests/test_temporal_concurrency.py +0 -52
  785. jobctrl-0.3.0/tests/test_temporal_env.py +0 -87
  786. jobctrl-0.3.0/tests/test_temporal_worker.py +0 -106
  787. jobctrl-0.3.0/tests/test_v12_activation.py +0 -266
  788. jobctrl-0.3.0/tests/test_v7_cover_runtime.py +0 -882
  789. jobctrl-0.3.0/tests/test_v7_score_runtime.py +0 -627
  790. jobctrl-0.3.0/tests/test_v7_tailor_runtime.py +0 -1950
  791. jobctrl-0.3.0/tests/test_voice_adapter.py +0 -212
  792. jobctrl-0.3.0/tests/test_workday_discovery.py +0 -339
  793. jobctrl-0.3.0/tests/test_worker_reconciler.py +0 -601
  794. jobctrl-0.3.0/tests/test_workflow_apply.py +0 -336
  795. jobctrl-0.3.0/tests/test_workflow_discovery.py +0 -1602
  796. jobctrl-0.3.0/tests/test_workflow_finalize.py +0 -326
  797. jobctrl-0.3.0/tests/test_workflow_id_overlap.py +0 -75
  798. jobctrl-0.3.0/tests/test_workflow_job_pipeline.py +0 -1689
  799. jobctrl-0.3.0/tests/test_workflow_job_preparation.py +0 -908
  800. jobctrl-0.3.0/tests/workflow_determination_fakes.py +0 -112
  801. jobctrl-0.3.0/uv.lock +0 -2032
  802. {jobctrl-0.3.0 → jobctrl-0.4.0}/.gitignore +0 -0
  803. {jobctrl-0.3.0 → jobctrl-0.4.0}/LICENSE +0 -0
  804. {jobctrl-0.3.0 → jobctrl-0.4.0}/NOTICE +0 -0
  805. {jobctrl-0.3.0 → jobctrl-0.4.0}/scripts/search_unit_concurrency_assessment.py +0 -0
  806. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/__main__.py +0 -0
  807. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/actions.py +0 -0
  808. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/apply/__init__.py +0 -0
  809. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/apply/origins.py +0 -0
  810. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/apply/prompt.py +0 -0
  811. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/apply/telemetry.py +0 -0
  812. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/assets/determinations/taxonomy.v1.json +0 -0
  813. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/assets/fonts/GEIST-LICENSE.txt +0 -0
  814. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/assets/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
  815. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/assets/fonts/geist-latin-wght-normal.woff2 +0 -0
  816. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/assets/interview/catalog.v1.json +0 -0
  817. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/browser_capabilities.py +0 -0
  818. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/config/employers.yaml +0 -0
  819. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/config/sites.yaml +0 -0
  820. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/contact/__init__.py +0 -0
  821. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/discovery/__init__.py +0 -0
  822. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/discovery/manual_capture_import.py +0 -0
  823. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/discovery/manual_capture_workflow.py +0 -0
  824. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/discovery/target_queries.py +0 -0
  825. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/__init__.py +0 -0
  826. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/apply/__init__.py +0 -0
  827. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/apply/aggregate.py +0 -0
  828. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/apply/entities.py +0 -0
  829. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/apply/form_mapping.py +0 -0
  830. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/apply/repeat_application.py +0 -0
  831. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/apply/role_equivalence.py +0 -0
  832. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/apply/screening_answers.py +0 -0
  833. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/apply/terminal_report.py +0 -0
  834. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/compensation/__init__.py +0 -0
  835. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/compensation/benchmarks.py +0 -0
  836. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/compensation/market.py +0 -0
  837. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/compensation/posted.py +0 -0
  838. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/contact/__init__.py +0 -0
  839. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/contact/aggregate.py +0 -0
  840. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/contact/source_policy.py +0 -0
  841. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/contact/use_cases.py +0 -0
  842. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/contact/value_objects.py +0 -0
  843. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/__init__.py +0 -0
  844. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/aggregate.py +0 -0
  845. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/execution.py +0 -0
  846. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/identity.py +0 -0
  847. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/scheduler.py +0 -0
  848. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/search_units.py +0 -0
  849. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/source_registry.py +0 -0
  850. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/value_objects.py +0 -0
  851. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/__init__.py +0 -0
  852. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/aggregate.py +0 -0
  853. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/entities.py +0 -0
  854. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/filter_override.py +0 -0
  855. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/services.py +0 -0
  856. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/snapshot_services.py +0 -0
  857. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/snapshot_set.py +0 -0
  858. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/snapshot_use_case.py +0 -0
  859. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/snapshot_value_objects.py +0 -0
  860. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/use_cases.py +0 -0
  861. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/events/base.py +0 -0
  862. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/events/enrichment.py +0 -0
  863. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/events/interview.py +0 -0
  864. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/events/materials.py +0 -0
  865. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/events/operations.py +0 -0
  866. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/events/orchestration.py +0 -0
  867. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/events/profile.py +0 -0
  868. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/events/scoring.py +0 -0
  869. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/extraction.py +0 -0
  870. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/feedback/__init__.py +0 -0
  871. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/feedback/message_interpretation.py +0 -0
  872. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/identifiers.py +0 -0
  873. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/interview/__init__.py +0 -0
  874. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/interview/evidence.py +0 -0
  875. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/interview/preparation.py +0 -0
  876. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/interview/question_generation.py +0 -0
  877. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/interview/use_cases.py +0 -0
  878. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/interview/value_objects.py +0 -0
  879. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/job_content_identity.py +0 -0
  880. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/job_snapshot.py +0 -0
  881. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/__init__.py +0 -0
  882. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/adversarial.py +0 -0
  883. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/aggregate.py +0 -0
  884. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/analysis_agreement.py +0 -0
  885. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/analysis_grounding.py +0 -0
  886. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/claim_grounding.py +0 -0
  887. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/coverage_audit.py +0 -0
  888. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/edit_intent.py +0 -0
  889. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/entities.py +0 -0
  890. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/locale_variants.py +0 -0
  891. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/provenance.py +0 -0
  892. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/provenance_builder.py +0 -0
  893. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/screening_answers.py +0 -0
  894. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/value_objects.py +0 -0
  895. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/materials/voice.py +0 -0
  896. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/operations/__init__.py +0 -0
  897. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/operations/evidence_map.py +0 -0
  898. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/operations/feedback.py +0 -0
  899. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/operations/learning.py +0 -0
  900. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/operations/projections.py +0 -0
  901. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/__init__.py +0 -0
  902. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/aggregate.py +0 -0
  903. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/repository.py +0 -0
  904. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/state_machine.py +0 -0
  905. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/use_cases.py +0 -0
  906. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline_types.py +0 -0
  907. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/__init__.py +0 -0
  908. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/analysis_agreement.py +0 -0
  909. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/artifact_generation.py +0 -0
  910. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/artifact_review.py +0 -0
  911. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/discovery.py +0 -0
  912. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/enrichment.py +0 -0
  913. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/events.py +0 -0
  914. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/feedback.py +0 -0
  915. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/job_interpretation.py +0 -0
  916. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/learning.py +0 -0
  917. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/retrieval.py +0 -0
  918. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/ports/watermark.py +0 -0
  919. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/preparation/__init__.py +0 -0
  920. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/profile/__init__.py +0 -0
  921. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/profile/aggregate.py +0 -0
  922. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/profile/interpretation.py +0 -0
  923. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/profile/ports.py +0 -0
  924. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/profile/required_bullet_coaching.py +0 -0
  925. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/profile/resume_extraction.py +0 -0
  926. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/profile/snapshot.py +0 -0
  927. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/profile/use_cases.py +0 -0
  928. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/rpc/__init__.py +0 -0
  929. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/rpc/messages.py +0 -0
  930. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/__init__.py +0 -0
  931. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/aggregate.py +0 -0
  932. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/eligibility.py +0 -0
  933. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/policy.py +0 -0
  934. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/retrieval.py +0 -0
  935. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/taxonomy.py +0 -0
  936. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/taxonomy_codes.py +0 -0
  937. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/domain/tenant.py +0 -0
  938. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/enrichment/__init__.py +0 -0
  939. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/enrichment/activities.py +0 -0
  940. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/enrichment/availability_workflow.py +0 -0
  941. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/__init__.py +0 -0
  942. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/__init__.py +0 -0
  943. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/gemini_schema.py +0 -0
  944. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/llm_analysis_synthesizer.py +0 -0
  945. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/prompts.py +0 -0
  946. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/strict_schema.py +0 -0
  947. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/apply/__init__.py +0 -0
  948. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/apply/form_mapping.py +0 -0
  949. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/apply_tools/__init__.py +0 -0
  950. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/captcha/__init__.py +0 -0
  951. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/captcha/capsolver.py +0 -0
  952. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/__init__.py +0 -0
  953. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/benchmark_ingestion.py +0 -0
  954. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/benchmark_lineage.py +0 -0
  955. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/benchmark_materialization.py +0 -0
  956. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/official_data.py +0 -0
  957. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/refresh.py +0 -0
  958. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/sqlite_benchmark_repository.py +0 -0
  959. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/contact/__init__.py +0 -0
  960. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/contact/sqlite_repository.py +0 -0
  961. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/__init__.py +0 -0
  962. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/ats_adapters.py +0 -0
  963. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/jobstreaming_gateway.py +0 -0
  964. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/listing_display.py +0 -0
  965. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/live_browser.py +0 -0
  966. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/recovery_manifest.py +0 -0
  967. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/sqlite_identity_resolver.py +0 -0
  968. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/sqlite_run_repository.py +0 -0
  969. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/__init__.py +0 -0
  970. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/execution_lease.py +0 -0
  971. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/linkedin_apply_resolver.py +0 -0
  972. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/page_interpretation.py +0 -0
  973. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/sqlite_repository.py +0 -0
  974. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/events/__init__.py +0 -0
  975. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/events/in_process_bus.py +0 -0
  976. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/events/watermark.py +0 -0
  977. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/gmail/__init__.py +0 -0
  978. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/gmail/mcp_server.py +0 -0
  979. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/interview/__init__.py +0 -0
  980. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/interview/sqlite_repository.py +0 -0
  981. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/job_locators.py +0 -0
  982. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/learning/__init__.py +0 -0
  983. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/learning/sqlite_repository.py +0 -0
  984. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/llm/__init__.py +0 -0
  985. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/bullet_provenance_repository.py +0 -0
  986. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/employer_analysis_repository.py +0 -0
  987. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/locale_variants.py +0 -0
  988. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/resume_html_migration.py +0 -0
  989. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/resume_style.py +0 -0
  990. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/unit_of_work.py +0 -0
  991. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/user_edit_review.py +0 -0
  992. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/voice_prompts.py +0 -0
  993. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/__init__.py +0 -0
  994. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/compensation_role_family_seed.py +0 -0
  995. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/identity_upcast.py +0 -0
  996. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v10_execute.py +0 -0
  997. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v11_execute.py +0 -0
  998. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v12_execute.py +0 -0
  999. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v13_execute.py +0 -0
  1000. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v14_execute.py +0 -0
  1001. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v9_execute.py +0 -0
  1002. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/resume_template_seed.py +0 -0
  1003. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v10.py +0 -0
  1004. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v10.sql +0 -0
  1005. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v11.py +0 -0
  1006. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v11.sql +0 -0
  1007. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v12.py +0 -0
  1008. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v12.sql +0 -0
  1009. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v13.sql +0 -0
  1010. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v14.py +0 -0
  1011. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v14.sql +0 -0
  1012. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v7.py +0 -0
  1013. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v7.sql +0 -0
  1014. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v8.py +0 -0
  1015. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v8.sql +0 -0
  1016. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v9.py +0 -0
  1017. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v9.sql +0 -0
  1018. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v10_to_v11_execute.py +0 -0
  1019. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v11_to_v12_execute.py +0 -0
  1020. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v12_activation.py +0 -0
  1021. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v12_to_v13_execute.py +0 -0
  1022. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v13_activation.py +0 -0
  1023. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v13_to_v14_execute.py +0 -0
  1024. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v14_activation.py +0 -0
  1025. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_apply_run_projections.py +0 -0
  1026. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_artifact_list_projections.py +0 -0
  1027. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_candidate.py +0 -0
  1028. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_contact_projections.py +0 -0
  1029. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_copy.py +0 -0
  1030. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_dashboard_projections.py +0 -0
  1031. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_duplicate_links.py +0 -0
  1032. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_events.py +0 -0
  1033. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_evidence_usage_projections.py +0 -0
  1034. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_execute.py +0 -0
  1035. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_job_detail_projections.py +0 -0
  1036. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_job_list_projections.py +0 -0
  1037. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_pipeline_step_projections.py +0 -0
  1038. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_plan.py +0 -0
  1039. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_population_steps.py +0 -0
  1040. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_preflight.py +0 -0
  1041. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_quiescence.py +0 -0
  1042. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_root.py +0 -0
  1043. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_score_keywords.py +0 -0
  1044. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_verify.py +0 -0
  1045. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_work_items.py +0 -0
  1046. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_workflow_run_projections.py +0 -0
  1047. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v8_execute.py +0 -0
  1048. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_dashboard_outcome_conversion.py +0 -0
  1049. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_dashboard_projection_rows.py +0 -0
  1050. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_evidence_usage_projection_rows.py +0 -0
  1051. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_job_list_projection_rows.py +0 -0
  1052. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_to_v8_execute.py +0 -0
  1053. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v8_to_v9_execute.py +0 -0
  1054. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v9_to_v10_execute.py +0 -0
  1055. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/__init__.py +0 -0
  1056. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/fetch_failures.py +0 -0
  1057. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/proxy.py +0 -0
  1058. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/public_http.py +0 -0
  1059. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/robots.py +0 -0
  1060. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/__init__.py +0 -0
  1061. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/adapter_spans.py +0 -0
  1062. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/enrichment_spans.py +0 -0
  1063. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/otel.py +0 -0
  1064. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/source_spans.py +0 -0
  1065. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/pipeline/__init__.py +0 -0
  1066. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/pipeline/sqlite_repository.py +0 -0
  1067. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/preflight.py +0 -0
  1068. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/preparation/__init__.py +0 -0
  1069. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/profile/__init__.py +0 -0
  1070. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/profile/interpretation.py +0 -0
  1071. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/profile/pdf_parser.py +0 -0
  1072. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/__init__.py +0 -0
  1073. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/fetch_failure.py +0 -0
  1074. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/location_normalization.py +0 -0
  1075. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/source_quality.py +0 -0
  1076. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/sqlite_feedback_signals.py +0 -0
  1077. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/rpc/__init__.py +0 -0
  1078. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/rpc/workflow_starter.py +0 -0
  1079. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/scoring/__init__.py +0 -0
  1080. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/scoring/keyword_normalization.py +0 -0
  1081. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/__init__.py +0 -0
  1082. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/cancellation_audit.py +0 -0
  1083. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/client.py +0 -0
  1084. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/durability_probe.py +0 -0
  1085. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/pipeline_step_lifecycle.py +0 -0
  1086. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/runtime_guard.py +0 -0
  1087. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/task_queue_observation.py +0 -0
  1088. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/task_queues.py +0 -0
  1089. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/interview/__init__.py +0 -0
  1090. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/llm_lanes.py +0 -0
  1091. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/materials/__init__.py +0 -0
  1092. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/model_defaults.py +0 -0
  1093. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/native_credentials.py +0 -0
  1094. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/operational_metrics.py +0 -0
  1095. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/pipeline/__init__.py +0 -0
  1096. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/pipeline/public_fetch_recovery.py +0 -0
  1097. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/preparation/__init__.py +0 -0
  1098. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/profile/__init__.py +0 -0
  1099. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/profile/activities.py +0 -0
  1100. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/profile/importer.py +0 -0
  1101. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/profile_import.py +0 -0
  1102. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/scoring/__init__.py +0 -0
  1103. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/scoring/eligibility_sql.py +0 -0
  1104. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/scoring/eval.py +0 -0
  1105. {jobctrl-0.3.0 → jobctrl-0.4.0}/src/jobctrl/wizard/__init__.py +0 -0
  1106. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/__init__.py +0 -0
  1107. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/availability_fixture.py +0 -0
  1108. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/availability_transports.py +0 -0
  1109. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/fixtures/discovery_barcelona_acceptance.json +0 -0
  1110. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/fixtures/hybrid_search_topk.json +0 -0
  1111. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/fixtures/required_bullet_rpc_probe.py +0 -0
  1112. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/fixtures/rpc_boundary.json +0 -0
  1113. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/fixtures/scoring_eval_cases.json +0 -0
  1114. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/fixtures/shipped_v6_schema.sql +0 -0
  1115. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/live_browser_helpers.py +0 -0
  1116. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/page_fakes.py +0 -0
  1117. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/politeness_helpers.py +0 -0
  1118. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/rpc_contract_probe.py +0 -0
  1119. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_actions.py +0 -0
  1120. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_activity_enrich.py +0 -0
  1121. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_activity_profile_import.py +0 -0
  1122. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_activity_score.py +0 -0
  1123. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_activity_tailor.py +0 -0
  1124. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_analyze_job_use_case.py +0 -0
  1125. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_application_url_authority.py +0 -0
  1126. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_apply_eligibility_checker.py +0 -0
  1127. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_apply_origin_policy.py +0 -0
  1128. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_apply_queue_selectors.py +0 -0
  1129. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_apply_run_aggregate.py +0 -0
  1130. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_apply_runs_table_dropped.py +0 -0
  1131. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_ats_adapters.py +0 -0
  1132. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_autonomous_agent_port.py +0 -0
  1133. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_browser_capabilities_rpc.py +0 -0
  1134. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_browser_capability_cli.py +0 -0
  1135. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_browser_port.py +0 -0
  1136. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_bullet_provenance.py +0 -0
  1137. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_bundled_runtime.py +0 -0
  1138. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_cancellation_audit.py +0 -0
  1139. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_capsolver_client.py +0 -0
  1140. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_claim_grounding.py +0 -0
  1141. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_codex_adapter_status.py +0 -0
  1142. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_compensation_audit_contract.py +0 -0
  1143. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_compensation_benchmark_repository.py +0 -0
  1144. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_compensation_benchmarks.py +0 -0
  1145. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_compensation_gateway_routing.py +0 -0
  1146. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_compensation_official_data.py +0 -0
  1147. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_compensation_refresh_cli.py +0 -0
  1148. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_compensation_refresh_state.py +0 -0
  1149. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_config_file_transactions.py +0 -0
  1150. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_contact_aggregate.py +0 -0
  1151. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_contact_projection_parity.py +0 -0
  1152. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_contact_provenance.py +0 -0
  1153. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_contact_repository.py +0 -0
  1154. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_contact_research_projection_parity.py +0 -0
  1155. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_contact_research_source_policy.py +0 -0
  1156. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_content_validator.py +0 -0
  1157. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_cover_requirements.py +0 -0
  1158. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_coverage_audit.py +0 -0
  1159. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_crawl_politeness_config.py +0 -0
  1160. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_criteria_provider.py +0 -0
  1161. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_dashboard_projection.py +0 -0
  1162. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_database_backup.py +0 -0
  1163. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_detail_page_fetcher.py +0 -0
  1164. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_enrichment_handoff.py +0 -0
  1165. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_execution_identity.py +0 -0
  1166. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_execution_lineage.py +0 -0
  1167. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_identity.py +0 -0
  1168. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_production_wiring.py +0 -0
  1169. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_scheduler_pr4.py +0 -0
  1170. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_search_unit_identity.py +0 -0
  1171. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_search_units.py +0 -0
  1172. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_discovery_transaction_lifecycle.py +0 -0
  1173. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_distribution_smoke_model.py +0 -0
  1174. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_doctor_diagnostics.py +0 -0
  1175. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_doctor_gmail_mcp.py +0 -0
  1176. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_doctor_langfuse.py +0 -0
  1177. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_doctor_llm_budget.py +0 -0
  1178. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_doctor_playwright.py +0 -0
  1179. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_doctor_temporal.py +0 -0
  1180. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_domain_types.py +0 -0
  1181. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_due_follow_up_projection_parity.py +0 -0
  1182. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_employer_analysis_model.py +0 -0
  1183. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_employer_analysis_repository.py +0 -0
  1184. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_aggregate.py +0 -0
  1185. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_detail_staleness.py +0 -0
  1186. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_events_pr3.py +0 -0
  1187. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_extractors.py +0 -0
  1188. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_lease_concurrency.py +0 -0
  1189. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_quarantine_gating.py +0 -0
  1190. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_queue_selectors.py +0 -0
  1191. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_repository.py +0 -0
  1192. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_snapshot_pr3.py +0 -0
  1193. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_enrichment_use_cases.py +0 -0
  1194. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_event_publication.py +0 -0
  1195. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_event_type_migration.py +0 -0
  1196. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_event_watermark.py +0 -0
  1197. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_evidence_interview_value_objects.py +0 -0
  1198. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_exact_v10_schema.py +0 -0
  1199. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_exact_v11_schema.py +0 -0
  1200. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_exact_v12_schema.py +0 -0
  1201. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_exact_v14_schema.py +0 -0
  1202. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_exact_v7_selector_job_identity.py +0 -0
  1203. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_exact_v8_schema.py +0 -0
  1204. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_exact_v9_schema.py +0 -0
  1205. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_feedback_signal_reader.py +0 -0
  1206. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_fetch_failure_projection.py +0 -0
  1207. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_fetch_surface_enforcement.py +0 -0
  1208. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_gateway_http_client.py +0 -0
  1209. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_gemini_schema.py +0 -0
  1210. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_gmail_feedback_v10_anchors.py +0 -0
  1211. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_gmail_mcp_config.py +0 -0
  1212. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_in_process_bus.py +0 -0
  1213. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_interview_catalog.py +0 -0
  1214. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_interview_catalog_packaging.py +0 -0
  1215. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_interview_persistence_v12.py +0 -0
  1216. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_interview_prep_generation.py +0 -0
  1217. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_job_aggregate.py +0 -0
  1218. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_job_application_locators.py +0 -0
  1219. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_job_repository.py +0 -0
  1220. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_jobspy_gateway_boundary.py +0 -0
  1221. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_jobstreaming_gateway.py +0 -0
  1222. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_jobstreaming_resumable_discovery.py +0 -0
  1223. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_jsonrpc_server.py +0 -0
  1224. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_keychain_credentials.py +0 -0
  1225. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_learning_recommendations.py +0 -0
  1226. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_legacy_to_v10_execute.py +0 -0
  1227. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_legacy_to_v11_execute.py +0 -0
  1228. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_legacy_to_v12_execute.py +0 -0
  1229. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_legacy_to_v9_execute.py +0 -0
  1230. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_levels_fyi_public.py +0 -0
  1231. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_linkedin_apply_resolver.py +0 -0
  1232. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_linkedin_authenticated_enrichment_retry.py +0 -0
  1233. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_live_browser_discovery.py +0 -0
  1234. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_live_worker_smoke_provider.py +0 -0
  1235. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_llm_analysis_synthesizer.py +0 -0
  1236. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_llm_client.py +0 -0
  1237. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_llm_defaults.py +0 -0
  1238. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_llm_no_credential_leakage.py +0 -0
  1239. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_llm_port.py +0 -0
  1240. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_locale_variants.py +0 -0
  1241. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_location_normalization.py +0 -0
  1242. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_manual_capture_workflow.py +0 -0
  1243. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_market_compensation_estimator.py +0 -0
  1244. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_market_compensation_repository.py +0 -0
  1245. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_materials_adversarial.py +0 -0
  1246. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_materials_aggregate.py +0 -0
  1247. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_materials_quality.py +0 -0
  1248. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_materials_queue_selectors.py +0 -0
  1249. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_materials_repository.py +0 -0
  1250. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_materials_repository_v7.py +0 -0
  1251. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_materials_unit_of_work.py +0 -0
  1252. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_operational_metrics.py +0 -0
  1253. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_outreach_draft_gates.py +0 -0
  1254. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_outreach_follow_up_derivation.py +0 -0
  1255. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_outreach_no_auto_send.py +0 -0
  1256. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_outreach_no_send_transport.py +0 -0
  1257. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_outreach_projection_parity.py +0 -0
  1258. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_outreach_thread_aggregate.py +0 -0
  1259. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_pipeline_repository.py +0 -0
  1260. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_pipeline_status_cli.py +0 -0
  1261. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_pipeline_step_events.py +0 -0
  1262. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_pipeline_step_lifecycle_emission.py +0 -0
  1263. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_pipeline_step_projection.py +0 -0
  1264. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_pipeline_use_cases.py +0 -0
  1265. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_politeness_gateway.py +0 -0
  1266. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_politeness_ports.py +0 -0
  1267. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_posted_compensation_repository.py +0 -0
  1268. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_posting_availability_rereview.py +0 -0
  1269. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_posting_availability_review.py +0 -0
  1270. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_preflight.py +0 -0
  1271. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_profile_aggregate.py +0 -0
  1272. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_profile_determinations.py +0 -0
  1273. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_profile_import.py +0 -0
  1274. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_profile_snapshot.py +0 -0
  1275. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_profile_use_cases.py +0 -0
  1276. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_public_destination_http.py +0 -0
  1277. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_public_fetch_recovery.py +0 -0
  1278. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_python_package_attribution.py +0 -0
  1279. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_render_resume_pdf_handler.py +0 -0
  1280. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_repeat_application_prevention.py +0 -0
  1281. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_repository_construction.py +0 -0
  1282. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_required_bullet_coaching.py +0 -0
  1283. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_resume_assembler.py +0 -0
  1284. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_rpc_cancel_run.py +0 -0
  1285. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_rpc_contract_boundary.py +0 -0
  1286. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_rpc_handlers_apply_workflow.py +0 -0
  1287. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_rpc_otel.py +0 -0
  1288. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_rpc_server_workflow_mode.py +0 -0
  1289. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_saved_edit_determinations.py +0 -0
  1290. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_saved_posting_availability.py +0 -0
  1291. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_schema_v7_packaging.py +0 -0
  1292. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_score_activity_recovery.py +0 -0
  1293. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_score_aggregate.py +0 -0
  1294. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_score_eligibility_stage_state.py +0 -0
  1295. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_score_queue_selectors.py +0 -0
  1296. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_scoring_eval.py +0 -0
  1297. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_scoring_policy.py +0 -0
  1298. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_screening_answers_integration.py +0 -0
  1299. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_search_unit_concurrency_assessment.py +0 -0
  1300. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_selected_apply_url_refresh.py +0 -0
  1301. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_setup_synthesis_auth.py +0 -0
  1302. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_source_quality_projection_pr4.py +0 -0
  1303. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_source_spans.py +0 -0
  1304. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_sqlite_learning_recommendations.py +0 -0
  1305. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_sqlite_profile_repository.py +0 -0
  1306. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_stage_state_machine.py +0 -0
  1307. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_state_dashboard.py +0 -0
  1308. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_state_legacy_parity.py +0 -0
  1309. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_state_machine_parity.py +0 -0
  1310. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_strict_schema.py +0 -0
  1311. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_task_queue_observation.py +0 -0
  1312. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_temporal_client.py +0 -0
  1313. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_temporal_registry.py +0 -0
  1314. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v10_to_v11_execute.py +0 -0
  1315. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_apply_run_projections.py +0 -0
  1316. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_artifact_list_projections.py +0 -0
  1317. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_candidate.py +0 -0
  1318. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_contact_projections_copy.py +0 -0
  1319. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_copy.py +0 -0
  1320. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_dashboard_projections.py +0 -0
  1321. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_duplicate_links.py +0 -0
  1322. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_event_copy.py +0 -0
  1323. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_evidence_usage_projections.py +0 -0
  1324. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_execute.py +0 -0
  1325. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_feedback_copy.py +0 -0
  1326. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_job_detail_projections.py +0 -0
  1327. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_job_list_projections.py +0 -0
  1328. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_pipeline_step_projections_copy.py +0 -0
  1329. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_plan.py +0 -0
  1330. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_population_steps.py +0 -0
  1331. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_preflight.py +0 -0
  1332. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_quiescence.py +0 -0
  1333. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_root_copy.py +0 -0
  1334. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_score_keywords.py +0 -0
  1335. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_verify.py +0 -0
  1336. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_work_items_copy.py +0 -0
  1337. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v7_workflow_run_projections_copy.py +0 -0
  1338. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v6_to_v8_execute.py +0 -0
  1339. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v7_dashboard_outcome_conversion.py +0 -0
  1340. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v7_dashboard_projection_rows.py +0 -0
  1341. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v7_evidence_usage_projection_rows.py +0 -0
  1342. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v7_job_list_projection_rows.py +0 -0
  1343. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v7_materials_selectors.py +0 -0
  1344. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v7_projection_builder_event_identity.py +0 -0
  1345. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v7_to_v8_execute.py +0 -0
  1346. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v8_to_v9_execute.py +0 -0
  1347. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_v9_to_v10_execute.py +0 -0
  1348. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_voice_payload.py +0 -0
  1349. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_workday_gateway_routing.py +0 -0
  1350. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_worker_heartbeat_loop.py +0 -0
  1351. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_workflow_durability_probe.py +0 -0
  1352. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_workflow_heavy_rpc_conversions.py +0 -0
  1353. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_workflow_run_context.py +0 -0
  1354. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_workflow_runs_projection_from_events.py +0 -0
  1355. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_workflow_starter_cache.py +0 -0
  1356. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/test_workspace_migration.py +0 -0
  1357. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/v6_feedback_fixture.py +0 -0
  1358. {jobctrl-0.3.0 → jobctrl-0.4.0}/tests/v6_migration_fixture.py +0 -0
jobctrl-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.5
2
+ Name: jobctrl
3
+ Version: 0.4.0
4
+ Summary: AI-powered end-to-end job application pipeline
5
+ Project-URL: Homepage, https://github.com/ebarti/JobCtrl
6
+ Project-URL: Repository, https://github.com/ebarti/JobCtrl
7
+ Project-URL: Issues, https://github.com/ebarti/JobCtrl/issues
8
+ Author: Eloi Barti
9
+ License-Expression: AGPL-3.0-only
10
+ Keywords: ai,apply,automation,job-application,job-search,resume
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Office/Business
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: agent-runtime-kit<0.6,>=0.5.4
20
+ Requires-Dist: beautifulsoup4>=4.12
21
+ Requires-Dist: certifi>=2026.10.19
22
+ Requires-Dist: click>=8.3.3
23
+ Requires-Dist: httpx>=0.24
24
+ Requires-Dist: jobstreaming==0.0.5
25
+ Requires-Dist: opentelemetry-api>=1.27
26
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27
27
+ Requires-Dist: opentelemetry-instrumentation-httpx>=0.48b0
28
+ Requires-Dist: opentelemetry-sdk>=1.27
29
+ Requires-Dist: pandas>=2.0
30
+ Requires-Dist: playwright>=1.40
31
+ Requires-Dist: publicsuffix2<3,>=2.20191221
32
+ Requires-Dist: pydantic>=2.10
33
+ Requires-Dist: pypdf>=6.14.2
34
+ Requires-Dist: python-dotenv>=1.0
35
+ Requires-Dist: pyyaml>=6.0
36
+ Requires-Dist: rich>=13.0
37
+ Requires-Dist: temporalio>=1.31
38
+ Requires-Dist: typer>=0.9.0
39
+ Requires-Dist: ua-generator>=2.1.7
40
+ Requires-Dist: websocket-client>=1.8
41
+ Provides-Extra: dev
42
+ Requires-Dist: build>=1.2; extra == 'dev'
43
+ Requires-Dist: cryptography>=50.0.0; extra == 'dev'
44
+ Requires-Dist: google-auth>=2.0; extra == 'dev'
45
+ Requires-Dist: hatchling==1.32.4; extra == 'dev'
46
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
47
+ Requires-Dist: pytest-randomly>=4.0; extra == 'dev'
48
+ Requires-Dist: pytest-timeout<3,>=2.4; extra == 'dev'
49
+ Requires-Dist: pytest-xdist<4,>=3.8; extra == 'dev'
50
+ Requires-Dist: pytest>=7.0; extra == 'dev'
51
+ Requires-Dist: python-docx<2,>=1.2; extra == 'dev'
52
+ Requires-Dist: ruff==0.17.1; extra == 'dev'
53
+ Provides-Extra: providers
54
+ Requires-Dist: claude-agent-sdk==0.2.121; extra == 'providers'
55
+ Requires-Dist: google-antigravity==0.1.2; extra == 'providers'
56
+ Requires-Dist: mcp>=1.28.1; extra == 'providers'
57
+ Requires-Dist: openai-codex-cli-bin==0.163.0; extra == 'providers'
58
+ Requires-Dist: openai-codex==0.163.0; extra == 'providers'
59
+ Requires-Dist: pyasn1>=0.6.4; extra == 'providers'
60
+ Description-Content-Type: text/markdown
61
+
62
+ # JobCtrl Automation Worker
63
+
64
+ This package contains JobCtrl's Python automation engine and CLI. It owns job
65
+ discovery, enrichment, scoring, tailoring, cover letters, PDF generation,
66
+ profile import, and local browser apply automation.
67
+
68
+ Use it from the repository root through `uv`:
69
+
70
+ ```bash
71
+ uv --project workers/automation run jobctrl doctor
72
+ uv --project workers/automation run jobctrl run
73
+ uv --project workers/automation run jobctrl worker
74
+ ```
75
+
76
+ The full local application is normally started from the repository root with
77
+ `corepack pnpm dev`, which runs Temporal, the TypeScript API, the React web app, and this
78
+ worker together.
79
+
80
+ Provider generation runs through `agent-runtime-kit`. The worker owns the
81
+ persistent async service and idle runtime cache; provider SDKs remain optional
82
+ source/runtime packs. See `docs/architecture/agent-runtime.md` for request
83
+ isolation, reuse, permissions and shutdown.
84
+
85
+ Useful docs:
86
+
87
+ - root `README.md` for the public overview and quick start;
88
+ - `docs/user/getting-started.md` for setup and local stack commands;
89
+ - `docs/user/configuration.md` for environment variables;
90
+ - `docs/architecture/` and `docs/architecture/pipeline/` for internal
91
+ runtime ownership.
92
+
93
+ Profile data, generated materials, browser state, logs, and SQLite databases
94
+ are sensitive local artifacts. Do not commit them or include them in public bug
95
+ reports.
@@ -0,0 +1,34 @@
1
+ # JobCtrl Automation Worker
2
+
3
+ This package contains JobCtrl's Python automation engine and CLI. It owns job
4
+ discovery, enrichment, scoring, tailoring, cover letters, PDF generation,
5
+ profile import, and local browser apply automation.
6
+
7
+ Use it from the repository root through `uv`:
8
+
9
+ ```bash
10
+ uv --project workers/automation run jobctrl doctor
11
+ uv --project workers/automation run jobctrl run
12
+ uv --project workers/automation run jobctrl worker
13
+ ```
14
+
15
+ The full local application is normally started from the repository root with
16
+ `corepack pnpm dev`, which runs Temporal, the TypeScript API, the React web app, and this
17
+ worker together.
18
+
19
+ Provider generation runs through `agent-runtime-kit`. The worker owns the
20
+ persistent async service and idle runtime cache; provider SDKs remain optional
21
+ source/runtime packs. See `docs/architecture/agent-runtime.md` for request
22
+ isolation, reuse, permissions and shutdown.
23
+
24
+ Useful docs:
25
+
26
+ - root `README.md` for the public overview and quick start;
27
+ - `docs/user/getting-started.md` for setup and local stack commands;
28
+ - `docs/user/configuration.md` for environment variables;
29
+ - `docs/architecture/` and `docs/architecture/pipeline/` for internal
30
+ runtime ownership.
31
+
32
+ Profile data, generated materials, browser state, logs, and SQLite databases
33
+ are sensitive local artifacts. Do not commit them or include them in public bug
34
+ reports.
@@ -0,0 +1,158 @@
1
+ [project]
2
+ name = "jobctrl"
3
+ version = "0.4.0"
4
+ description = "AI-powered end-to-end job application pipeline"
5
+ readme = "README.md"
6
+ license = "AGPL-3.0-only"
7
+ requires-python = ">=3.11"
8
+ authors = [{ name = "Eloi Barti" }]
9
+ keywords = ["job-search", "automation", "ai", "resume", "apply", "job-application"]
10
+ classifiers = [
11
+ "Development Status :: 4 - Beta",
12
+ "Environment :: Console",
13
+ "License :: OSI Approved :: GNU Affero General Public License v3",
14
+ "Programming Language :: Python :: 3.11",
15
+ "Programming Language :: Python :: 3.12",
16
+ "Programming Language :: Python :: 3.13",
17
+ "Topic :: Office/Business",
18
+ ]
19
+
20
+ dependencies = [
21
+ # Shared lifecycle, capability and process-reuse boundary for agent SDKs.
22
+ "agent-runtime-kit>=0.5.4,<0.6",
23
+ "certifi>=2026.10.19",
24
+ "typer>=0.9.0",
25
+ "click>=8.3.3",
26
+ "rich>=13.0",
27
+ "httpx>=0.24",
28
+ "websocket-client>=1.8",
29
+ "beautifulsoup4>=4.12",
30
+ "playwright>=1.40",
31
+ "python-dotenv>=1.0",
32
+ "pypdf>=6.14.2",
33
+ "pyyaml>=6.0",
34
+ "pandas>=2.0",
35
+ # 1.31 includes the cancellation/shield fix, while retaining activity
36
+ # cancellation details and run IDs used by enrichment ownership fencing.
37
+ "temporalio>=1.31",
38
+ "opentelemetry-api>=1.27",
39
+ "opentelemetry-sdk>=1.27",
40
+ "opentelemetry-exporter-otlp-proto-http>=1.27",
41
+ "opentelemetry-instrumentation-httpx>=0.48b0",
42
+ # Typed, concurrent job-board events plus resumable checkpoints. Pin the
43
+ # integration contract so JobCtrl's durable adapter changes deliberately.
44
+ "jobstreaming==0.0.5",
45
+ # Pydantic backs the canonical employer-analysis domain model
46
+ # (``domain/materials/analysis.py``) and is also pulled transitively by
47
+ # the agent SDKs below. Declared explicitly because the domain layer
48
+ # imports it directly.
49
+ "pydantic>=2.10",
50
+ # Gmail verification scopes derive sender domains from application URLs and
51
+ # need public-suffix-aware eTLD+1 parsing.
52
+ "publicsuffix2>=2.20191221,<3",
53
+ "ua-generator>=2.1.7",
54
+ ]
55
+
56
+ [project.optional-dependencies]
57
+ dev = [
58
+ "build>=1.2",
59
+ "cryptography>=50.0.0",
60
+ "google-auth>=2.0",
61
+ "hatchling==1.32.4",
62
+ "pytest>=7.0",
63
+ "pytest-asyncio>=0.23",
64
+ "pytest-randomly>=4.0",
65
+ "pytest-timeout>=2.4,<3",
66
+ "pytest-xdist>=3.8,<4",
67
+ "python-docx>=1.2,<2",
68
+ "ruff==0.17.1",
69
+ ]
70
+ providers = [
71
+ "claude-agent-sdk==0.2.121",
72
+ "mcp>=1.28.1",
73
+ "openai-codex==0.163.0",
74
+ "openai-codex-cli-bin==0.163.0",
75
+ "google-antigravity==0.1.2",
76
+ "pyasn1>=0.6.4",
77
+ ]
78
+
79
+ # Source checkouts keep the provider ensemble available on ordinary `uv sync`
80
+ # and `uv run`. Production payload builders use `--no-default-groups --no-dev`
81
+ # and acquire provider wheels separately through the signed provider-pack path.
82
+ [dependency-groups]
83
+ provider-runtime = [
84
+ "claude-agent-sdk==0.2.121",
85
+ "openai-codex==0.163.0",
86
+ "openai-codex-cli-bin==0.163.0",
87
+ "google-antigravity==0.1.2",
88
+ ]
89
+ release-build = ["build==1.6.1", "hatchling==1.32.4"]
90
+ # The always-on privacy gate uses only this locked tool slice; it must not
91
+ # resolve an independent floating pytest environment on every pull request.
92
+ release-check = ["pytest>=7.0"]
93
+
94
+ [project.scripts]
95
+ jobctrl = "jobctrl.cli:app"
96
+
97
+ [project.urls]
98
+ Homepage = "https://github.com/ebarti/JobCtrl"
99
+ Repository = "https://github.com/ebarti/JobCtrl"
100
+ Issues = "https://github.com/ebarti/JobCtrl/issues"
101
+
102
+ [build-system]
103
+ # Release builds run with --no-isolation, so both the build backend and the
104
+ # locked development environment must resolve this exact, audited backend.
105
+ requires = ["hatchling==1.32.4"]
106
+ build-backend = "hatchling.build"
107
+
108
+ [tool.hatch.build.targets.wheel]
109
+ packages = ["src/jobctrl"]
110
+
111
+ [tool.hatch.build]
112
+ artifacts = ["src/jobctrl/config/*.yaml", "src/jobctrl/assets/fonts/*", "src/jobctrl/assets/interview/*.json", "src/jobctrl/assets/determinations/*.json", "src/jobctrl/infrastructure/migrations/*.sql"]
113
+
114
+ [tool.hatch.build.targets.sdist.force-include]
115
+ "../../LICENSE" = "LICENSE"
116
+ "../../NOTICE" = "NOTICE"
117
+
118
+ [tool.ruff]
119
+ target-version = "py311"
120
+ line-length = 120
121
+
122
+ [tool.ruff.lint]
123
+ # Preserve the existing project policy across Ruff default-rule changes.
124
+ select = ["E4", "E7", "E9", "F"]
125
+
126
+ [tool.pytest.ini_options]
127
+ asyncio_mode = "strict"
128
+ tmp_path_retention_policy = "failed"
129
+ # "thread" dumps every thread's stack at the bound and hard-exits the process.
130
+ # "signal" raised only in the main thread and could not unwind a worker-pool
131
+ # thread blocked in a SQLite BEGIN IMMEDIATE wait, which wedged the lane for
132
+ # its whole job ceiling (run 32481181792, Python 3.11). faulthandler stays as
133
+ # the slightly later second-chance dump if pytest-timeout itself fails.
134
+ faulthandler_timeout = 240
135
+ timeout = 180
136
+ timeout_method = "thread"
137
+ markers = [
138
+ "core: hermetic tests that do not own a Temporal test server or migration fixture",
139
+ "migration: database migration and copy tests routed to memory-backed CI storage",
140
+ "system_browser: opt-in smoke requiring a real local system Chrome/Chromium; set JOBCTRL_RUN_SYSTEM_BROWSER_TESTS=1",
141
+ "temporal: tests whose file owns a Temporal WorkflowEnvironment lifecycle",
142
+ ]
143
+
144
+ [tool.pyright]
145
+ venvPath = "."
146
+ venv = ".venv"
147
+ extraPaths = ["src"]
148
+ include = ["src", "tests"]
149
+ pythonVersion = "3.11"
150
+
151
+ [tool.uv]
152
+ default-groups = ["provider-runtime"]
153
+
154
+ # Dependabot owns the rolling community-vetting delay. Keeping that delay here
155
+ # as a relative timestamp would make an unchanged lockfile fail `uv --locked`
156
+ # as time passes. Provider runtimes and the audited JobStreaming integration
157
+ # retain their explicit reviewed cutoffs.
158
+ exclude-newer-package = { "google-antigravity" = "2026-06-04T21:19:27Z", "claude-agent-sdk" = "2026-07-18T00:00:00Z", "jobstreaming" = "2026-08-29T23:59:59Z" }
@@ -0,0 +1,3 @@
1
+ """JobCtrl — AI-powered end-to-end job application pipeline."""
2
+
3
+ __version__ = "0.4.0"
@@ -0,0 +1,197 @@
1
+ """Temporal activity for the apply stage."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ import logging
7
+ from typing import Any
8
+
9
+ from temporalio import activity
10
+ from temporalio.exceptions import ApplicationError
11
+
12
+ from jobctrl.domain.identifiers import JobId, canonical_job_id
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class ApplyActivityInput:
19
+ # Every targeted claim is scoped by this tenant and canonical JobId.
20
+ tenant_id: str
21
+ expected_app_dir: str | None = None
22
+ expected_db_path: str | None = None
23
+ job_id: JobId | None = None
24
+ limit: int = 1
25
+ min_score: int = 7
26
+ model: str = "default"
27
+ headless: bool = False
28
+ dry_run: bool = False
29
+ workers: int = 1
30
+ approval_required: bool = True
31
+ # Run-forever poll mode — when True, the activity calls ``apply_main``
32
+ # with ``limit=0`` (the launcher's run-forever sentinel) and ignores
33
+ # ``limit``. Otherwise ``max(1, limit)`` jobs are processed.
34
+ continuous: bool = False
35
+ auto_apply_loop: bool = False
36
+ # Bounded batches belonging to a standing workflow are polls, not manual retries.
37
+ standing_refusal_poll: bool = False
38
+ dispatch_frontier: int | None = None
39
+
40
+ def __post_init__(self) -> None:
41
+ if self.job_id is not None:
42
+ object.__setattr__(self, "job_id", canonical_job_id(str(self.job_id)))
43
+
44
+
45
+ @dataclass(frozen=True)
46
+ class ApplyActivityOutput:
47
+ status: str
48
+ applied: int
49
+ failed: int
50
+ error: str | None = None
51
+ # Older activity histories have no worker-crash observation.
52
+ worker_crashes: int | None = None
53
+ # Only refusals with a durable refund and completed owner settlement count.
54
+ settled_refusals: int | None = None
55
+
56
+
57
+ @dataclass(frozen=True)
58
+ class ApplyFrontierInput:
59
+ tenant_id: str
60
+ expected_app_dir: str | None = None
61
+ expected_db_path: str | None = None
62
+
63
+
64
+ @activity.defn(name='capture_apply_dispatch_frontier')
65
+ async def capture_apply_dispatch_frontier_activity(payload: ApplyFrontierInput) -> int:
66
+ """Start the next standing poll only after observing its own writer frontier."""
67
+ from jobctrl.database import get_connection
68
+ from jobctrl.infrastructure.apply_controls import capture_apply_dispatch_frontier
69
+ from jobctrl.infrastructure.temporal.run_in_activity import run_blocking_with_heartbeat
70
+ from jobctrl.infrastructure.temporal.runtime_guard import assert_activity_runtime
71
+
72
+ assert_activity_runtime(expected_app_dir=payload.expected_app_dir, expected_db_path=payload.expected_db_path)
73
+ return await run_blocking_with_heartbeat(
74
+ lambda: capture_apply_dispatch_frontier(get_connection(), tenant_id=payload.tenant_id)[0],
75
+ starting_message='capturing Apply dispatch frontier',
76
+ )
77
+
78
+
79
+ @activity.defn(name="apply")
80
+ async def apply_activity(payload: ApplyActivityInput) -> ApplyActivityOutput:
81
+ """Run the apply launcher in a worker thread, heart-beating so cancellation lands.
82
+
83
+ Exception policy:
84
+
85
+ - ``CancelledError`` — re-raised so Temporal marks the activity cancelled.
86
+ - ``LookupError`` (missing JobId or other lookup misses) — wrapped in a
87
+ non-retryable ``ApplicationError`` so the workflow fails fast.
88
+ - Any other exception — re-raised verbatim so Temporal's configured retry
89
+ policy can fire on transient browser / network / executor failures.
90
+ """
91
+
92
+ # Every invocation creates its own cancellation/resource owner before
93
+ # handing blocking launcher work to the activity executor.
94
+ from jobctrl.infrastructure.temporal.runtime_guard import assert_activity_runtime
95
+ from jobctrl.infrastructure.temporal.run_in_activity import run_blocking_with_heartbeat
96
+ from jobctrl.infrastructure.scoring.criteria_provider import (
97
+ read_apply_approval_required,
98
+ read_apply_concurrency,
99
+ read_min_fit_score,
100
+ )
101
+ from jobctrl.browser_capabilities import require_system_browser_capability
102
+ from jobctrl.apply.launcher import count_settled_email_refusals, main as apply_main
103
+ from jobctrl.apply.batch_outcome import ApplyBatchCleanupIncomplete, ApplyBatchWorkersCrashed
104
+ from jobctrl.apply.ownership import ApplyLauncherBusy, ApplyLauncherCleanupIncomplete, ApplyLauncherRun
105
+
106
+ assert_activity_runtime(
107
+ expected_app_dir=payload.expected_app_dir,
108
+ expected_db_path=payload.expected_db_path,
109
+ )
110
+ # A caller may have bypassed the CLI/API workflow builder. Re-check at the
111
+ # worker execution boundary before importing the apply launcher or touching
112
+ # a browser profile.
113
+ from jobctrl.runtime import is_bundled_runtime
114
+ bundled = is_bundled_runtime()
115
+ dedicated_scope = bundled
116
+ if not dedicated_scope:
117
+ require_system_browser_capability("auto-apply-browser")
118
+ workflow_id = activity.info().workflow_id
119
+ launcher_run = None if dedicated_scope else ApplyLauncherRun()
120
+ from jobctrl.apply.execution import ScopedApplyExecution
121
+ scoped_execution = ScopedApplyExecution() if dedicated_scope else None
122
+
123
+ def _run_apply() -> tuple[int, int, int | None]:
124
+ # ``continuous=True`` selects the launcher's run-forever poll mode,
125
+ # which it activates via ``limit == 0``. Otherwise enforce a floor
126
+ # of one to keep ``limit < 1`` calls from no-oping.
127
+ effective_limit = 0 if payload.continuous else max(1, payload.limit)
128
+ approval_required = read_apply_approval_required(default=payload.approval_required)
129
+ min_score = read_min_fit_score(default=payload.min_score) if payload.auto_apply_loop else payload.min_score
130
+ workers = read_apply_concurrency(default=payload.workers) if payload.auto_apply_loop else payload.workers
131
+ options = dict(
132
+ limit=effective_limit, target_job_id=str(payload.job_id) if payload.job_id is not None else None,
133
+ tenant_id=payload.tenant_id, min_score=min_score, headless=payload.headless, model=payload.model,
134
+ dry_run=payload.dry_run, continuous=payload.continuous, workers=workers, poll_interval=60,
135
+ approval_required=approval_required, workflow_id=workflow_id,
136
+ standing_refusal_poll=payload.standing_refusal_poll or payload.auto_apply_loop,
137
+ dispatch_frontier=payload.dispatch_frontier,
138
+ )
139
+ if scoped_execution is not None:
140
+ applied, failed = scoped_execution.run(options)
141
+ owner_id = scoped_execution.identity
142
+ else:
143
+ options.pop("poll_interval")
144
+ applied, failed = apply_main(**options, install_signal_handlers=False, launcher_run=launcher_run)
145
+ owner_id = launcher_run.identity
146
+ settled = None
147
+ if failed and (payload.standing_refusal_poll or payload.auto_apply_loop):
148
+ try:
149
+ settled = count_settled_email_refusals(payload.tenant_id, owner_id)
150
+ except Exception: # noqa: BLE001 — missing proof must retain the failed outcome
151
+ logger.warning("Could not verify settled Apply refusals; retaining failed batch status")
152
+ return applied, failed, settled
153
+
154
+
155
+ try:
156
+ applied, failed, settled_refusals = await run_blocking_with_heartbeat(
157
+ _run_apply,
158
+ starting_message="apply starting",
159
+ progress_message="apply still running",
160
+ poll_interval=15.0,
161
+ activity_name="apply",
162
+ job_context={
163
+ "job_id": str(payload.job_id) if payload.job_id is not None else "",
164
+ "dry_run": payload.dry_run,
165
+ },
166
+ on_cancel=scoped_execution.cancel if scoped_execution is not None else launcher_run.cancel,
167
+ )
168
+
169
+ status = "ok" if failed == 0 else "failed"
170
+ return ApplyActivityOutput(
171
+ status=status,
172
+ applied=int(applied),
173
+ failed=int(failed),
174
+ error=None,
175
+ worker_crashes=0,
176
+ settled_refusals=settled_refusals,
177
+ )
178
+ except ApplyBatchWorkersCrashed as exc:
179
+ return ApplyActivityOutput(
180
+ status="failed", applied=exc.counts.applied, failed=exc.counts.failed,
181
+ error="apply_worker_crashed", worker_crashes=exc.counts.worker_crashes,
182
+ )
183
+ except ApplyBatchCleanupIncomplete as exc:
184
+ raise ApplicationError(
185
+ str(exc), exc.counts.to_dict(), type="apply_launcher_cleanup_incomplete", non_retryable=True,
186
+ ) from exc
187
+ except (ApplyLauncherBusy, ApplyLauncherCleanupIncomplete) as exc:
188
+ code = "apply_launcher_busy" if isinstance(exc, ApplyLauncherBusy) else "apply_launcher_cleanup_incomplete"
189
+ raise ApplicationError(str(exc), type=code, non_retryable=True) from exc
190
+ except LookupError as exc:
191
+ # Missing JobId or other lookup misses are operator errors;
192
+ # do not retry — surface them immediately to the workflow.
193
+ raise ApplicationError(str(exc), type=type(exc).__name__, non_retryable=True) from exc
194
+
195
+
196
+ # Re-exported for the registry; activity decorator metadata is preserved.
197
+ __all__: list[Any] = ["apply_activity", "ApplyActivityInput", "ApplyActivityOutput"]
@@ -0,0 +1,201 @@
1
+ """Worker reconciler for the settings-controlled standing apply loop."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sqlite3
6
+ from dataclasses import dataclass
7
+ from datetime import datetime, timezone
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+ from temporalio.client import WorkflowExecutionStatus
12
+ from temporalio.common import WorkflowIDConflictPolicy, WorkflowIDReusePolicy
13
+ from temporalio.service import RPCError, RPCStatusCode
14
+
15
+ from jobctrl.apply.workflow import ApplyWorkflow, ApplyWorkflowInput
16
+ from jobctrl.browser_capabilities import browser_capability_status
17
+ from jobctrl.domain.tenant import LOCAL_TENANT
18
+ from jobctrl.infrastructure.scoring.criteria_provider import (
19
+ read_apply_approval_required,
20
+ read_apply_concurrency,
21
+ read_auto_apply_enabled,
22
+ read_daily_budget_usd,
23
+ read_min_fit_score,
24
+ )
25
+
26
+ AUTO_APPLY_WORKFLOW_PREFIX = "apply-auto"
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class AutoApplyLoopSettings:
31
+ enabled: bool
32
+ min_score: int
33
+ workers: int
34
+ approval_required: bool
35
+
36
+
37
+ @dataclass(frozen=True)
38
+ class AutoApplyReconcileResult:
39
+ workflow_id: str
40
+ action: str
41
+ enabled: bool
42
+
43
+ @property
44
+ def changed(self) -> bool:
45
+ return self.action == "started" or self.action.startswith("canceled")
46
+
47
+
48
+ def auto_apply_workflow_id(tenant_id: str = str(LOCAL_TENANT)) -> str:
49
+ return f"{AUTO_APPLY_WORKFLOW_PREFIX}-{tenant_id}"
50
+
51
+
52
+ def read_auto_apply_loop_settings(
53
+ path: Path | str | None = None,
54
+ ) -> AutoApplyLoopSettings:
55
+ return AutoApplyLoopSettings(
56
+ enabled=read_auto_apply_enabled(default=False),
57
+ min_score=read_min_fit_score(default=7),
58
+ workers=read_apply_concurrency(path, default=1),
59
+ approval_required=read_apply_approval_required(default=True),
60
+ )
61
+
62
+
63
+ async def reconcile_auto_apply_loop(
64
+ client: Any,
65
+ *,
66
+ task_queue: str,
67
+ tenant_id: str = str(LOCAL_TENANT),
68
+ settings_path: Path | str | None = None,
69
+ expected_app_dir: str | None = None,
70
+ expected_db_path: str | None = None,
71
+ ) -> AutoApplyReconcileResult:
72
+ """Ensure the deterministic continuous apply workflow matches settings."""
73
+ settings = read_auto_apply_loop_settings(settings_path)
74
+ workflow_id = auto_apply_workflow_id(tenant_id)
75
+ running = await _is_workflow_running(client, workflow_id)
76
+ if settings.enabled:
77
+ capability = browser_capability_status("auto-apply-browser")
78
+ if capability.status != "ready":
79
+ if running:
80
+ await client.get_workflow_handle(workflow_id).cancel()
81
+ return AutoApplyReconcileResult(
82
+ workflow_id, f"canceled_capability_{capability.status}", False
83
+ )
84
+ return AutoApplyReconcileResult(
85
+ workflow_id, f"blocked_capability_{capability.status}", False
86
+ )
87
+ if running:
88
+ return AutoApplyReconcileResult(workflow_id, "already_running", True)
89
+ if _budget_halt_active(
90
+ db_path=expected_db_path,
91
+ workflow_id=workflow_id,
92
+ settings_path=settings_path,
93
+ ):
94
+ return AutoApplyReconcileResult(workflow_id, "halted_budget_exceeded", True)
95
+ from jobctrl.database import get_connection
96
+ from jobctrl.infrastructure.apply_controls import capture_apply_dispatch_frontier
97
+ from jobctrl.infrastructure.runtime_identity import assert_expected_runtime
98
+
99
+ assert_expected_runtime(expected_app_dir=expected_app_dir, expected_db_path=expected_db_path)
100
+ conn = get_connection()
101
+ if conn.in_transaction:
102
+ raise RuntimeError('Apply dispatch cannot cross a caller-owned database transaction')
103
+ frontier, _ = capture_apply_dispatch_frontier(conn, tenant_id=tenant_id)
104
+ payload = ApplyWorkflowInput(
105
+ tenant_id=tenant_id,
106
+ expected_app_dir=expected_app_dir,
107
+ expected_db_path=expected_db_path,
108
+ dry_run=False,
109
+ min_score=settings.min_score,
110
+ workers=settings.workers,
111
+ limit=0,
112
+ approval_required=settings.approval_required,
113
+ continuous=True,
114
+ auto_apply_loop=True,
115
+ dispatch_frontier=frontier,
116
+ )
117
+ await client.start_workflow(
118
+ ApplyWorkflow.run,
119
+ payload,
120
+ id=workflow_id,
121
+ task_queue=task_queue,
122
+ id_conflict_policy=WorkflowIDConflictPolicy.USE_EXISTING,
123
+ id_reuse_policy=WorkflowIDReusePolicy.ALLOW_DUPLICATE,
124
+ )
125
+ return AutoApplyReconcileResult(workflow_id, "started", True)
126
+
127
+ if running:
128
+ await client.get_workflow_handle(workflow_id).cancel()
129
+ return AutoApplyReconcileResult(workflow_id, "canceled", False)
130
+ return AutoApplyReconcileResult(workflow_id, "already_stopped", False)
131
+
132
+
133
+ async def _is_workflow_running(client: Any, workflow_id: str) -> bool:
134
+ try:
135
+ description = await client.get_workflow_handle(workflow_id).describe()
136
+ except RPCError as exc:
137
+ if exc.status == RPCStatusCode.NOT_FOUND:
138
+ return False
139
+ raise
140
+ status = getattr(description, "status", None)
141
+ return status == WorkflowExecutionStatus.RUNNING or getattr(status, "name", "") == "CONTINUED_AS_NEW"
142
+
143
+
144
+ def _budget_halt_active(
145
+ *,
146
+ db_path: str | None,
147
+ workflow_id: str,
148
+ settings_path: Path | str | None,
149
+ ) -> bool:
150
+ if not db_path:
151
+ return False
152
+ path = Path(db_path)
153
+ if not path.exists():
154
+ return False
155
+ from jobctrl.database import _refuse_unresolved_initialization
156
+
157
+ _refuse_unresolved_initialization(path)
158
+ try:
159
+ with sqlite3.connect(path) as conn:
160
+ row = conn.execute(
161
+ """
162
+ SELECT status, error_code
163
+ FROM workflow_run_projections
164
+ WHERE workflow_id = ?
165
+ LIMIT 1
166
+ """,
167
+ (workflow_id,),
168
+ ).fetchone()
169
+ if not row or str(row[0]) != "failed" or str(row[1]) != "budget_exceeded":
170
+ return False
171
+ daily_budget = read_daily_budget_usd(settings_path, default=25.0)
172
+ spend_day = datetime.now(timezone.utc).date().isoformat()
173
+ spend = conn.execute(
174
+ "SELECT COALESCE(SUM(estimated_usd), 0) FROM llm_spend WHERE day = ?",
175
+ (spend_day,),
176
+ ).fetchone()
177
+ apply_spend = conn.execute(
178
+ "SELECT input_tokens + output_tokens FROM llm_spend WHERE day = ? AND lane = 'apply'",
179
+ (spend_day,),
180
+ ).fetchone()
181
+ except sqlite3.Error:
182
+ return False
183
+ estimated = float(spend[0] or 0.0) if spend else 0.0
184
+ from jobctrl.infrastructure.scoring.criteria_provider import read_lane_token_limits
185
+
186
+ apply_limit = read_lane_token_limits(settings_path)["apply"]
187
+ apply_tokens = int(apply_spend[0] or 0) if apply_spend else 0
188
+ return (
189
+ (daily_budget > 0 and estimated >= daily_budget)
190
+ or (apply_limit > 0 and apply_tokens >= apply_limit)
191
+ )
192
+
193
+
194
+ __all__ = [
195
+ "AUTO_APPLY_WORKFLOW_PREFIX",
196
+ "AutoApplyLoopSettings",
197
+ "AutoApplyReconcileResult",
198
+ "auto_apply_workflow_id",
199
+ "read_auto_apply_loop_settings",
200
+ "reconcile_auto_apply_loop",
201
+ ]