jobctrl 0.3.1__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 (1355) 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/dashboard.py +249 -0
  10. jobctrl-0.4.0/src/jobctrl/apply/dispatch.py +35 -0
  11. jobctrl-0.4.0/src/jobctrl/apply/execution.py +383 -0
  12. jobctrl-0.4.0/src/jobctrl/apply/launcher.py +4414 -0
  13. jobctrl-0.4.0/src/jobctrl/apply/native_custody.py +161 -0
  14. jobctrl-0.4.0/src/jobctrl/apply/ownership.py +582 -0
  15. jobctrl-0.4.0/src/jobctrl/apply/process_birth.py +352 -0
  16. jobctrl-0.4.0/src/jobctrl/apply/workflow.py +261 -0
  17. jobctrl-0.4.0/src/jobctrl/cli.py +3965 -0
  18. jobctrl-0.4.0/src/jobctrl/config.py +2108 -0
  19. jobctrl-0.4.0/src/jobctrl/contact/activities.py +214 -0
  20. jobctrl-0.4.0/src/jobctrl/contact/workflow.py +217 -0
  21. jobctrl-0.4.0/src/jobctrl/database.py +3842 -0
  22. jobctrl-0.4.0/src/jobctrl/digest.py +764 -0
  23. jobctrl-0.4.0/src/jobctrl/discovery/activities.py +859 -0
  24. jobctrl-0.4.0/src/jobctrl/discovery/execution_reconciliation.py +1506 -0
  25. jobctrl-0.4.0/src/jobctrl/discovery/job_url_import_workflow.py +1352 -0
  26. jobctrl-0.4.0/src/jobctrl/discovery/jobspy.py +2188 -0
  27. jobctrl-0.4.0/src/jobctrl/discovery/smartextract.py +1735 -0
  28. jobctrl-0.4.0/src/jobctrl/discovery/workday.py +892 -0
  29. jobctrl-0.4.0/src/jobctrl/discovery/workflow.py +723 -0
  30. jobctrl-0.4.0/src/jobctrl/domain/apply/event_privacy.py +62 -0
  31. jobctrl-0.4.0/src/jobctrl/domain/apply/process_manager.py +885 -0
  32. jobctrl-0.4.0/src/jobctrl/domain/apply/services.py +345 -0
  33. jobctrl-0.4.0/src/jobctrl/domain/apply/use_cases.py +716 -0
  34. jobctrl-0.4.0/src/jobctrl/domain/apply/value_objects.py +325 -0
  35. jobctrl-0.4.0/src/jobctrl/domain/compensation/classification.py +54 -0
  36. jobctrl-0.4.0/src/jobctrl/domain/contact/outreach.py +628 -0
  37. jobctrl-0.4.0/src/jobctrl/domain/contact/outreach_use_cases.py +622 -0
  38. jobctrl-0.4.0/src/jobctrl/domain/contact/research.py +329 -0
  39. jobctrl-0.4.0/src/jobctrl/domain/contact/research_services.py +448 -0
  40. jobctrl-0.4.0/src/jobctrl/domain/contact/research_use_cases.py +207 -0
  41. jobctrl-0.4.0/src/jobctrl/domain/determinations.py +396 -0
  42. jobctrl-0.4.0/src/jobctrl/domain/discovery/posting_qualification.py +68 -0
  43. jobctrl-0.4.0/src/jobctrl/domain/discovery/use_cases.py +649 -0
  44. jobctrl-0.4.0/src/jobctrl/domain/enrichment/interpretation.py +125 -0
  45. jobctrl-0.4.0/src/jobctrl/domain/enrichment/page_interpretation.py +190 -0
  46. jobctrl-0.4.0/src/jobctrl/domain/enrichment/value_objects.py +220 -0
  47. jobctrl-0.4.0/src/jobctrl/domain/errors.py +133 -0
  48. jobctrl-0.4.0/src/jobctrl/domain/events/__init__.py +515 -0
  49. jobctrl-0.4.0/src/jobctrl/domain/events/apply.py +110 -0
  50. jobctrl-0.4.0/src/jobctrl/domain/events/contact.py +343 -0
  51. jobctrl-0.4.0/src/jobctrl/domain/events/workflow.py +389 -0
  52. jobctrl-0.4.0/src/jobctrl/domain/exact_values.py +25 -0
  53. jobctrl-0.4.0/src/jobctrl/domain/interview/catalog.py +455 -0
  54. jobctrl-0.4.0/src/jobctrl/domain/materials/analysis.py +498 -0
  55. jobctrl-0.4.0/src/jobctrl/domain/materials/analyze_use_case.py +342 -0
  56. jobctrl-0.4.0/src/jobctrl/domain/materials/artifact_quality.py +102 -0
  57. jobctrl-0.4.0/src/jobctrl/domain/materials/claim_review_response.py +171 -0
  58. jobctrl-0.4.0/src/jobctrl/domain/materials/claim_verification.py +226 -0
  59. jobctrl-0.4.0/src/jobctrl/domain/materials/evidence_selection.py +203 -0
  60. jobctrl-0.4.0/src/jobctrl/domain/materials/generation.py +63 -0
  61. jobctrl-0.4.0/src/jobctrl/domain/materials/policy.py +769 -0
  62. jobctrl-0.4.0/src/jobctrl/domain/materials/quality.py +787 -0
  63. jobctrl-0.4.0/src/jobctrl/domain/materials/requirement_coverage.py +1394 -0
  64. jobctrl-0.4.0/src/jobctrl/domain/materials/resume_document.py +255 -0
  65. jobctrl-0.4.0/src/jobctrl/domain/materials/services.py +459 -0
  66. jobctrl-0.4.0/src/jobctrl/domain/materials/use_cases.py +4498 -0
  67. jobctrl-0.4.0/src/jobctrl/domain/ports/apply.py +290 -0
  68. jobctrl-0.4.0/src/jobctrl/domain/ports/artifact_quality.py +51 -0
  69. jobctrl-0.4.0/src/jobctrl/domain/ports/claim_verification.py +90 -0
  70. jobctrl-0.4.0/src/jobctrl/domain/ports/contact.py +140 -0
  71. jobctrl-0.4.0/src/jobctrl/domain/ports/letter_reviews.py +39 -0
  72. jobctrl-0.4.0/src/jobctrl/domain/ports/llm.py +100 -0
  73. jobctrl-0.4.0/src/jobctrl/domain/ports/materials.py +506 -0
  74. jobctrl-0.4.0/src/jobctrl/domain/ports/politeness.py +274 -0
  75. jobctrl-0.4.0/src/jobctrl/domain/ports/resume_adversarial.py +69 -0
  76. jobctrl-0.4.0/src/jobctrl/domain/ports/scoring.py +142 -0
  77. jobctrl-0.4.0/src/jobctrl/domain/preparation/work_items.py +60 -0
  78. jobctrl-0.4.0/src/jobctrl/domain/profile/canonical_sources.py +87 -0
  79. jobctrl-0.4.0/src/jobctrl/domain/profile/search_targets.py +72 -0
  80. jobctrl-0.4.0/src/jobctrl/domain/profile/value_objects.py +694 -0
  81. jobctrl-0.4.0/src/jobctrl/domain/scoring/determination.py +136 -0
  82. jobctrl-0.4.0/src/jobctrl/domain/scoring/profile_impact.py +102 -0
  83. jobctrl-0.4.0/src/jobctrl/domain/scoring/requirement_fit.py +202 -0
  84. jobctrl-0.4.0/src/jobctrl/domain/scoring/services.py +518 -0
  85. jobctrl-0.4.0/src/jobctrl/domain/scoring/use_cases.py +1027 -0
  86. jobctrl-0.4.0/src/jobctrl/domain/scoring/value_objects.py +1383 -0
  87. jobctrl-0.4.0/src/jobctrl/enrichment/availability.py +1580 -0
  88. jobctrl-0.4.0/src/jobctrl/enrichment/detail.py +4949 -0
  89. jobctrl-0.4.0/src/jobctrl/infrastructure/analysis/antigravity_analysis_adapter.py +233 -0
  90. jobctrl-0.4.0/src/jobctrl/infrastructure/analysis/claude_analysis_adapter.py +337 -0
  91. jobctrl-0.4.0/src/jobctrl/infrastructure/analysis/codex_analysis_adapter.py +443 -0
  92. jobctrl-0.4.0/src/jobctrl/infrastructure/analysis/ensemble.py +305 -0
  93. jobctrl-0.4.0/src/jobctrl/infrastructure/apply/claude_code_cli.py +827 -0
  94. jobctrl-0.4.0/src/jobctrl/infrastructure/apply/email_sender.py +33 -0
  95. jobctrl-0.4.0/src/jobctrl/infrastructure/apply/local_chrome.py +91 -0
  96. jobctrl-0.4.0/src/jobctrl/infrastructure/apply_controls.py +331 -0
  97. jobctrl-0.4.0/src/jobctrl/infrastructure/apply_tools/mcp_server.py +889 -0
  98. jobctrl-0.4.0/src/jobctrl/infrastructure/career_learning.py +512 -0
  99. jobctrl-0.4.0/src/jobctrl/infrastructure/commit_notifications.py +80 -0
  100. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/automatic_refresh.py +673 -0
  101. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/classification_batch.py +119 -0
  102. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/interpretation.py +69 -0
  103. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/levels_fyi_public.py +763 -0
  104. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/refresh_control.py +73 -0
  105. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/refresh_state.py +588 -0
  106. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/sqlite_market_repository.py +1605 -0
  107. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/sqlite_repository.py +454 -0
  108. jobctrl-0.4.0/src/jobctrl/infrastructure/compensation/workflow.py +204 -0
  109. jobctrl-0.4.0/src/jobctrl/infrastructure/contact/outreach_repository.py +619 -0
  110. jobctrl-0.4.0/src/jobctrl/infrastructure/contact/research_fetcher.py +440 -0
  111. jobctrl-0.4.0/src/jobctrl/infrastructure/contact/research_repository.py +539 -0
  112. jobctrl-0.4.0/src/jobctrl/infrastructure/determinations.py +377 -0
  113. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/archived_smart_posting.py +357 -0
  114. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/capture_recovery.py +227 -0
  115. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/execution_result_plan.py +132 -0
  116. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/production_wiring.py +2257 -0
  117. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/result_budget.py +197 -0
  118. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/smart_postings.py +273 -0
  119. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/sqlite_execution_repository.py +335 -0
  120. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/sqlite_repository.py +1436 -0
  121. jobctrl-0.4.0/src/jobctrl/infrastructure/discovery/sqlite_search_unit_repository.py +895 -0
  122. jobctrl-0.4.0/src/jobctrl/infrastructure/enrichment/interpretation.py +84 -0
  123. jobctrl-0.4.0/src/jobctrl/infrastructure/enrichment/playwright_fetcher.py +629 -0
  124. jobctrl-0.4.0/src/jobctrl/infrastructure/enrichment/posting_sources.py +211 -0
  125. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/auth.py +311 -0
  126. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/client.py +351 -0
  127. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/feedback.py +728 -0
  128. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/privacy.py +74 -0
  129. jobctrl-0.4.0/src/jobctrl/infrastructure/gmail/windows_private_file.py +104 -0
  130. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/agent_runtime_antigravity.py +138 -0
  131. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/agent_runtime_claude.py +131 -0
  132. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/agent_runtime_codex.py +325 -0
  133. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/agent_runtime_pool.py +252 -0
  134. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/attempt_admission.py +23 -0
  135. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/codex_runtime_storage.py +166 -0
  136. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/codex_turn.py +210 -0
  137. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/codex_workspace.py +142 -0
  138. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/llm_client.py +978 -0
  139. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/model_catalog.py +275 -0
  140. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/provider_availability.py +90 -0
  141. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/provider_errors.py +349 -0
  142. jobctrl-0.4.0/src/jobctrl/infrastructure/llm/task_instructions.py +15 -0
  143. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/__init__.py +52 -0
  144. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/cover_letter_policy.py +95 -0
  145. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/html_resume_pdf.py +883 -0
  146. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/letter_reviews.py +198 -0
  147. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/manual_decline.py +149 -0
  148. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/screening_answers.py +446 -0
  149. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/sqlite_repository.py +1553 -0
  150. jobctrl-0.4.0/src/jobctrl/infrastructure/materials/voice_adapter.py +221 -0
  151. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/legacy_to_v15_execute.py +117 -0
  152. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/schema_manifest.py +163 -0
  153. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/schema_v13.py +69 -0
  154. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/schema_v15.py +56 -0
  155. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/schema_v15.sql +137 -0
  156. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/v14_to_v15_execute.py +210 -0
  157. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/v14_to_v15_inplace.py +151 -0
  158. jobctrl-0.4.0/src/jobctrl/infrastructure/migrations/v15_activation.py +205 -0
  159. jobctrl-0.4.0/src/jobctrl/infrastructure/network/http_client.py +175 -0
  160. jobctrl-0.4.0/src/jobctrl/infrastructure/network/politeness.py +371 -0
  161. jobctrl-0.4.0/src/jobctrl/infrastructure/network/rate_limiter.py +213 -0
  162. jobctrl-0.4.0/src/jobctrl/infrastructure/network/url_safety.py +348 -0
  163. jobctrl-0.4.0/src/jobctrl/infrastructure/observability/llm_spans.py +241 -0
  164. jobctrl-0.4.0/src/jobctrl/infrastructure/preparation/sqlite_repository.py +80 -0
  165. jobctrl-0.4.0/src/jobctrl/infrastructure/preparation_recovery.py +682 -0
  166. jobctrl-0.4.0/src/jobctrl/infrastructure/process_ownership.py +598 -0
  167. jobctrl-0.4.0/src/jobctrl/infrastructure/profile/factory.py +90 -0
  168. jobctrl-0.4.0/src/jobctrl/infrastructure/profile/legacy_evidence.py +218 -0
  169. jobctrl-0.4.0/src/jobctrl/infrastructure/profile/legacy_evidence_recovery.py +85 -0
  170. jobctrl-0.4.0/src/jobctrl/infrastructure/profile/sqlite_repository.py +1100 -0
  171. jobctrl-0.4.0/src/jobctrl/infrastructure/projections/projection_builder.py +5197 -0
  172. jobctrl-0.4.0/src/jobctrl/infrastructure/rpc/handlers.py +1517 -0
  173. jobctrl-0.4.0/src/jobctrl/infrastructure/rpc/job_url_import_status.py +71 -0
  174. jobctrl-0.4.0/src/jobctrl/infrastructure/rpc/server.py +356 -0
  175. jobctrl-0.4.0/src/jobctrl/infrastructure/runtime_identity.py +240 -0
  176. jobctrl-0.4.0/src/jobctrl/infrastructure/scoring/criteria_provider.py +195 -0
  177. jobctrl-0.4.0/src/jobctrl/infrastructure/scoring/sqlite_repository.py +1053 -0
  178. jobctrl-0.4.0/src/jobctrl/infrastructure/setup_probes.py +987 -0
  179. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/activity_runtime_telemetry.py +384 -0
  180. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/concurrency.py +76 -0
  181. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/control.py +41 -0
  182. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/finalize.py +341 -0
  183. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/preparation_outcome_audit.py +495 -0
  184. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/registry.py +117 -0
  185. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/run_in_activity.py +580 -0
  186. jobctrl-0.4.0/src/jobctrl/infrastructure/temporal/worker.py +150 -0
  187. jobctrl-0.4.0/src/jobctrl/infrastructure/workflow_run_context.py +96 -0
  188. jobctrl-0.4.0/src/jobctrl/interview/activities.py +526 -0
  189. jobctrl-0.4.0/src/jobctrl/interview/workflow.py +189 -0
  190. jobctrl-0.4.0/src/jobctrl/legacy_evidence_cli.py +79 -0
  191. jobctrl-0.4.0/src/jobctrl/llm.py +816 -0
  192. jobctrl-0.4.0/src/jobctrl/llm_request_context.py +32 -0
  193. jobctrl-0.4.0/src/jobctrl/materials/activities.py +918 -0
  194. jobctrl-0.4.0/src/jobctrl/materials/executor.py +102 -0
  195. jobctrl-0.4.0/src/jobctrl/pipeline/automatic_preparation.py +1089 -0
  196. jobctrl-0.4.0/src/jobctrl/pipeline/current_policy_selectors.py +265 -0
  197. jobctrl-0.4.0/src/jobctrl/pipeline/preparation.py +1160 -0
  198. jobctrl-0.4.0/src/jobctrl/pipeline/retry.py +129 -0
  199. jobctrl-0.4.0/src/jobctrl/pipeline/runner.py +2882 -0
  200. jobctrl-0.4.0/src/jobctrl/pipeline/workflow.py +819 -0
  201. jobctrl-0.4.0/src/jobctrl/preparation/workflow.py +435 -0
  202. jobctrl-0.4.0/src/jobctrl/profile/workflow.py +169 -0
  203. jobctrl-0.4.0/src/jobctrl/provider_packs.py +701 -0
  204. jobctrl-0.4.0/src/jobctrl/resume_profile.py +450 -0
  205. jobctrl-0.4.0/src/jobctrl/runtime.py +384 -0
  206. jobctrl-0.4.0/src/jobctrl/scoring/activities.py +423 -0
  207. jobctrl-0.4.0/src/jobctrl/scoring/cover_letter.py +820 -0
  208. jobctrl-0.4.0/src/jobctrl/scoring/employer_analysis.py +160 -0
  209. jobctrl-0.4.0/src/jobctrl/scoring/material_lifecycle.py +69 -0
  210. jobctrl-0.4.0/src/jobctrl/scoring/scorer.py +1719 -0
  211. jobctrl-0.4.0/src/jobctrl/scoring/tailor.py +1681 -0
  212. jobctrl-0.4.0/src/jobctrl/source_proposals_cli.py +69 -0
  213. jobctrl-0.4.0/src/jobctrl/state.py +1593 -0
  214. jobctrl-0.4.0/src/jobctrl/wizard/init.py +571 -0
  215. jobctrl-0.4.0/src/jobctrl/workflow_specs.py +707 -0
  216. jobctrl-0.4.0/tests/activity_capacity_api_fixture.py +125 -0
  217. jobctrl-0.4.0/tests/apply_execution_fixture.py +30 -0
  218. jobctrl-0.4.0/tests/apply_late_settlement_probe.py +48 -0
  219. jobctrl-0.4.0/tests/apply_receipt_privacy_fixture.py +51 -0
  220. jobctrl-0.4.0/tests/apply_skip_restart_probe.py +40 -0
  221. jobctrl-0.4.0/tests/apply_stopped_owner_probe.py +41 -0
  222. jobctrl-0.4.0/tests/career_learning_fixture.py +183 -0
  223. jobctrl-0.4.0/tests/company_briefing_fixture.py +66 -0
  224. jobctrl-0.4.0/tests/compensation_fakes.py +271 -0
  225. jobctrl-0.4.0/tests/conftest.py +160 -0
  226. jobctrl-0.4.0/tests/determination_fakes.py +327 -0
  227. jobctrl-0.4.0/tests/email_approval_api_probe.py +103 -0
  228. jobctrl-0.4.0/tests/fixtures/rescore_advice_probe.py +40 -0
  229. jobctrl-0.4.0/tests/fixtures/rpc_boundary_python.json +1 -0
  230. jobctrl-0.4.0/tests/gmail_feedback_rpc_fixture.py +101 -0
  231. jobctrl-0.4.0/tests/helpers/apply_batch_outcome_native.py +147 -0
  232. jobctrl-0.4.0/tests/helpers/apply_custody_native.py +119 -0
  233. jobctrl-0.4.0/tests/helpers/apply_execution_native.py +93 -0
  234. jobctrl-0.4.0/tests/helpers/apply_execution_ports.py +212 -0
  235. jobctrl-0.4.0/tests/helpers/apply_execution_retry_native.py +246 -0
  236. jobctrl-0.4.0/tests/helpers/apply_execution_temporal.py +165 -0
  237. jobctrl-0.4.0/tests/helpers/apply_session_fence_native.py +162 -0
  238. jobctrl-0.4.0/tests/legacy_evidence_fixture.py +41 -0
  239. jobctrl-0.4.0/tests/outreach_rpc_harness.py +85 -0
  240. jobctrl-0.4.0/tests/smart_posting_fakes.py +111 -0
  241. jobctrl-0.4.0/tests/source_apply_scope_probe.py +160 -0
  242. jobctrl-0.4.0/tests/source_email_scope_probe.py +116 -0
  243. jobctrl-0.4.0/tests/source_scope_child_evidence.py +131 -0
  244. jobctrl-0.4.0/tests/test_accepted_docx_export.py +328 -0
  245. jobctrl-0.4.0/tests/test_activity_apply.py +293 -0
  246. jobctrl-0.4.0/tests/test_activity_connection_lifetime.py +269 -0
  247. jobctrl-0.4.0/tests/test_activity_control_executor_capacity.py +183 -0
  248. jobctrl-0.4.0/tests/test_activity_cover.py +67 -0
  249. jobctrl-0.4.0/tests/test_activity_executor_generation_capacity.py +363 -0
  250. jobctrl-0.4.0/tests/test_activity_runtime_telemetry.py +361 -0
  251. jobctrl-0.4.0/tests/test_agent_runtime_cleanup_privacy.py +129 -0
  252. jobctrl-0.4.0/tests/test_agent_runtime_codex.py +232 -0
  253. jobctrl-0.4.0/tests/test_agent_runtime_pool.py +304 -0
  254. jobctrl-0.4.0/tests/test_analysis_determinations.py +263 -0
  255. jobctrl-0.4.0/tests/test_analysis_retry_boundaries.py +227 -0
  256. jobctrl-0.4.0/tests/test_antigravity_adapter.py +345 -0
  257. jobctrl-0.4.0/tests/test_apply_batch_crashes.py +509 -0
  258. jobctrl-0.4.0/tests/test_apply_batch_limits.py +245 -0
  259. jobctrl-0.4.0/tests/test_apply_browser_ownership.py +870 -0
  260. jobctrl-0.4.0/tests/test_apply_chrome_dry_run_guard.py +1359 -0
  261. jobctrl-0.4.0/tests/test_apply_chrome_endpoint_ownership.py +287 -0
  262. jobctrl-0.4.0/tests/test_apply_crash_custody.py +287 -0
  263. jobctrl-0.4.0/tests/test_apply_dashboard_isolation.py +158 -0
  264. jobctrl-0.4.0/tests/test_apply_endpoint_consumers.py +108 -0
  265. jobctrl-0.4.0/tests/test_apply_execution.py +484 -0
  266. jobctrl-0.4.0/tests/test_apply_launcher_ownership.py +698 -0
  267. jobctrl-0.4.0/tests/test_apply_log_artifact_registration.py +436 -0
  268. jobctrl-0.4.0/tests/test_apply_native_custody.py +141 -0
  269. jobctrl-0.4.0/tests/test_apply_prompt_builder.py +514 -0
  270. jobctrl-0.4.0/tests/test_apply_regressions.py +4916 -0
  271. jobctrl-0.4.0/tests/test_apply_runs_projection_from_events.py +688 -0
  272. jobctrl-0.4.0/tests/test_apply_saga.py +842 -0
  273. jobctrl-0.4.0/tests/test_apply_source_census_scope.py +198 -0
  274. jobctrl-0.4.0/tests/test_apply_source_lifetime.py +262 -0
  275. jobctrl-0.4.0/tests/test_apply_stopped_owner_recovery.py +168 -0
  276. jobctrl-0.4.0/tests/test_apply_tools_mcp_server.py +788 -0
  277. jobctrl-0.4.0/tests/test_apply_use_cases.py +659 -0
  278. jobctrl-0.4.0/tests/test_approved_material_recovery_ownership.py +135 -0
  279. jobctrl-0.4.0/tests/test_archived_smart_posting_temporal.py +128 -0
  280. jobctrl-0.4.0/tests/test_artifact_determinations.py +474 -0
  281. jobctrl-0.4.0/tests/test_auto_apply_reconciler.py +253 -0
  282. jobctrl-0.4.0/tests/test_automatic_compensation_refresh.py +358 -0
  283. jobctrl-0.4.0/tests/test_automatic_material_decline.py +212 -0
  284. jobctrl-0.4.0/tests/test_automatic_preparation.py +1076 -0
  285. jobctrl-0.4.0/tests/test_automatic_preparation_overlap.py +494 -0
  286. jobctrl-0.4.0/tests/test_automatic_preparation_temporal_qa.py +1475 -0
  287. jobctrl-0.4.0/tests/test_availability_model_budget.py +116 -0
  288. jobctrl-0.4.0/tests/test_baseline_accomplishment_retention.py +286 -0
  289. jobctrl-0.4.0/tests/test_binding_repair_feedback.py +218 -0
  290. jobctrl-0.4.0/tests/test_browser_capabilities.py +1285 -0
  291. jobctrl-0.4.0/tests/test_browser_rate_limit_recovery.py +252 -0
  292. jobctrl-0.4.0/tests/test_browser_request_headers.py +121 -0
  293. jobctrl-0.4.0/tests/test_browser_ua_propagation.py +420 -0
  294. jobctrl-0.4.0/tests/test_captured_posting_recovery.py +782 -0
  295. jobctrl-0.4.0/tests/test_claim_review_response.py +404 -0
  296. jobctrl-0.4.0/tests/test_claude_code_cli_adapter.py +936 -0
  297. jobctrl-0.4.0/tests/test_claude_terminal_failure.py +795 -0
  298. jobctrl-0.4.0/tests/test_codex_home_isolation.py +894 -0
  299. jobctrl-0.4.0/tests/test_codex_runtime_cleanup_privacy.py +950 -0
  300. jobctrl-0.4.0/tests/test_codex_runtime_storage.py +150 -0
  301. jobctrl-0.4.0/tests/test_codex_turn.py +137 -0
  302. jobctrl-0.4.0/tests/test_codex_workspace.py +158 -0
  303. jobctrl-0.4.0/tests/test_company_briefings.py +453 -0
  304. jobctrl-0.4.0/tests/test_compensation_classification_parallelism.py +185 -0
  305. jobctrl-0.4.0/tests/test_compensation_refresh_temporal.py +245 -0
  306. jobctrl-0.4.0/tests/test_compensation_source_outcomes.py +418 -0
  307. jobctrl-0.4.0/tests/test_compensation_v7_job_id.py +248 -0
  308. jobctrl-0.4.0/tests/test_contact_research_activity_heartbeat.py +80 -0
  309. jobctrl-0.4.0/tests/test_contact_research_e2e_fixture.py +278 -0
  310. jobctrl-0.4.0/tests/test_contact_research_inference.py +523 -0
  311. jobctrl-0.4.0/tests/test_contact_research_inference_temporal.py +196 -0
  312. jobctrl-0.4.0/tests/test_contact_research_workflow.py +2052 -0
  313. jobctrl-0.4.0/tests/test_cover_generation_repair.py +115 -0
  314. jobctrl-0.4.0/tests/test_cover_letter_opt_in.py +313 -0
  315. jobctrl-0.4.0/tests/test_cover_reviewed_anchors.py +114 -0
  316. jobctrl-0.4.0/tests/test_dashboard_execution_policy.py +93 -0
  317. jobctrl-0.4.0/tests/test_database_initialization_race.py +499 -0
  318. jobctrl-0.4.0/tests/test_default_resume_fit.py +145 -0
  319. jobctrl-0.4.0/tests/test_dependabot_policy.py +38 -0
  320. jobctrl-0.4.0/tests/test_detail_page_frames.py +67 -0
  321. jobctrl-0.4.0/tests/test_digest_canonical_cli.py +807 -0
  322. jobctrl-0.4.0/tests/test_digest_cli.py +133 -0
  323. jobctrl-0.4.0/tests/test_digest_parity.py +579 -0
  324. jobctrl-0.4.0/tests/test_direct_material_attempt_fencing.py +336 -0
  325. jobctrl-0.4.0/tests/test_discover_reliability.py +3133 -0
  326. jobctrl-0.4.0/tests/test_discovery_execution_reconciliation.py +2653 -0
  327. jobctrl-0.4.0/tests/test_discovery_execution_result_plan.py +122 -0
  328. jobctrl-0.4.0/tests/test_discovery_family_result_budget.py +469 -0
  329. jobctrl-0.4.0/tests/test_discovery_limits.py +1387 -0
  330. jobctrl-0.4.0/tests/test_discovery_preparation_orchestration.py +630 -0
  331. jobctrl-0.4.0/tests/test_discovery_result_budget.py +385 -0
  332. jobctrl-0.4.0/tests/test_domain_events.py +586 -0
  333. jobctrl-0.4.0/tests/test_employer_analysis_ensemble.py +715 -0
  334. jobctrl-0.4.0/tests/test_employer_analysis_leg_config.py +131 -0
  335. jobctrl-0.4.0/tests/test_enrichment_politeness_gate.py +1124 -0
  336. jobctrl-0.4.0/tests/test_enrichment_retry.py +308 -0
  337. jobctrl-0.4.0/tests/test_enrichment_url_safety.py +948 -0
  338. jobctrl-0.4.0/tests/test_enrichment_visible_capture.py +157 -0
  339. jobctrl-0.4.0/tests/test_exact_v7_apply_acquire_job_identity.py +1873 -0
  340. jobctrl-0.4.0/tests/test_exact_v7_schema.py +1523 -0
  341. jobctrl-0.4.0/tests/test_exact_v7_state_reset.py +285 -0
  342. jobctrl-0.4.0/tests/test_gmail_connector.py +559 -0
  343. jobctrl-0.4.0/tests/test_gmail_feedback.py +1087 -0
  344. jobctrl-0.4.0/tests/test_gmail_feedback_client_contract.py +356 -0
  345. jobctrl-0.4.0/tests/test_gmail_feedback_privacy.py +276 -0
  346. jobctrl-0.4.0/tests/test_gmail_feedback_scan_handler.py +85 -0
  347. jobctrl-0.4.0/tests/test_gmail_token_atomic.py +404 -0
  348. jobctrl-0.4.0/tests/test_gmail_token_windows_acl.py +222 -0
  349. jobctrl-0.4.0/tests/test_gmail_windows_acl_contract.py +195 -0
  350. jobctrl-0.4.0/tests/test_interpretation_citable_fields.py +143 -0
  351. jobctrl-0.4.0/tests/test_interview_determinations.py +343 -0
  352. jobctrl-0.4.0/tests/test_job_url_import_status.py +116 -0
  353. jobctrl-0.4.0/tests/test_job_url_import_workflow.py +1405 -0
  354. jobctrl-0.4.0/tests/test_jobstreaming_source_result_budget.py +296 -0
  355. jobctrl-0.4.0/tests/test_jsonrpc_handlers.py +2839 -0
  356. jobctrl-0.4.0/tests/test_legacy_evidence_preservation.py +258 -0
  357. jobctrl-0.4.0/tests/test_legacy_evidence_recovery.py +223 -0
  358. jobctrl-0.4.0/tests/test_linkedin_guest_dialog.py +186 -0
  359. jobctrl-0.4.0/tests/test_llm_provider_routing.py +544 -0
  360. jobctrl-0.4.0/tests/test_llm_spans.py +378 -0
  361. jobctrl-0.4.0/tests/test_llm_spend_budget.py +200 -0
  362. jobctrl-0.4.0/tests/test_locale_variants_integration.py +586 -0
  363. jobctrl-0.4.0/tests/test_material_activity_recovery.py +447 -0
  364. jobctrl-0.4.0/tests/test_material_batch_attempt_fencing.py +421 -0
  365. jobctrl-0.4.0/tests/test_material_candidate_identity.py +85 -0
  366. jobctrl-0.4.0/tests/test_material_context_requirements.py +84 -0
  367. jobctrl-0.4.0/tests/test_material_evidence_selection.py +396 -0
  368. jobctrl-0.4.0/tests/test_material_executor_prerequisites.py +76 -0
  369. jobctrl-0.4.0/tests/test_material_override_retention.py +253 -0
  370. jobctrl-0.4.0/tests/test_material_render_publication.py +556 -0
  371. jobctrl-0.4.0/tests/test_material_review_history.py +224 -0
  372. jobctrl-0.4.0/tests/test_materials_review_constraints.py +107 -0
  373. jobctrl-0.4.0/tests/test_materials_use_cases.py +580 -0
  374. jobctrl-0.4.0/tests/test_model_catalog.py +165 -0
  375. jobctrl-0.4.0/tests/test_native_apply_readiness.py +94 -0
  376. jobctrl-0.4.0/tests/test_native_credentials.py +485 -0
  377. jobctrl-0.4.0/tests/test_numeric_literal_formats.py +30 -0
  378. jobctrl-0.4.0/tests/test_offer_outreach.py +339 -0
  379. jobctrl-0.4.0/tests/test_optional_extension.py +975 -0
  380. jobctrl-0.4.0/tests/test_otel_init.py +222 -0
  381. jobctrl-0.4.0/tests/test_outreach_repository_v7.py +336 -0
  382. jobctrl-0.4.0/tests/test_p1b_error_inversion.py +809 -0
  383. jobctrl-0.4.0/tests/test_packaged_browser_contract.py +22 -0
  384. jobctrl-0.4.0/tests/test_parallel_letter_reviews.py +474 -0
  385. jobctrl-0.4.0/tests/test_parallel_resume_reviews.py +330 -0
  386. jobctrl-0.4.0/tests/test_pdf_renderer_ports.py +1302 -0
  387. jobctrl-0.4.0/tests/test_pipeline_observability.py +214 -0
  388. jobctrl-0.4.0/tests/test_posted_compensation_source_fence.py +313 -0
  389. jobctrl-0.4.0/tests/test_posting_source_selection.py +134 -0
  390. jobctrl-0.4.0/tests/test_posting_sources.py +35 -0
  391. jobctrl-0.4.0/tests/test_preparation_availability_cache.py +132 -0
  392. jobctrl-0.4.0/tests/test_preparation_capture_reuse.py +251 -0
  393. jobctrl-0.4.0/tests/test_preparation_job_reader.py +152 -0
  394. jobctrl-0.4.0/tests/test_preparation_manual_decline.py +565 -0
  395. jobctrl-0.4.0/tests/test_preparation_outcome_audit.py +741 -0
  396. jobctrl-0.4.0/tests/test_preparation_score_cancellation.py +413 -0
  397. jobctrl-0.4.0/tests/test_preparation_score_material_block.py +256 -0
  398. jobctrl-0.4.0/tests/test_process_ownership_census.py +1475 -0
  399. jobctrl-0.4.0/tests/test_process_ownership_graceful.py +952 -0
  400. jobctrl-0.4.0/tests/test_process_ownership_scope_fence.py +136 -0
  401. jobctrl-0.4.0/tests/test_process_ownership_temporal.py +157 -0
  402. jobctrl-0.4.0/tests/test_projection_builder.py +1234 -0
  403. jobctrl-0.4.0/tests/test_provider_availability_recovery.py +293 -0
  404. jobctrl-0.4.0/tests/test_provider_packs.py +603 -0
  405. jobctrl-0.4.0/tests/test_provider_transient_recovery.py +101 -0
  406. jobctrl-0.4.0/tests/test_release_check.py +643 -0
  407. jobctrl-0.4.0/tests/test_release_workflow_topology.py +95 -0
  408. jobctrl-0.4.0/tests/test_remaining_determinations.py +305 -0
  409. jobctrl-0.4.0/tests/test_required_skill_categories.py +129 -0
  410. jobctrl-0.4.0/tests/test_requirement_fit_resolution.py +240 -0
  411. jobctrl-0.4.0/tests/test_requirement_led_tailoring.py +1525 -0
  412. jobctrl-0.4.0/tests/test_resume_html_migration.py +301 -0
  413. jobctrl-0.4.0/tests/test_resume_polish_policy.py +37 -0
  414. jobctrl-0.4.0/tests/test_resume_review_response_bounds.py +151 -0
  415. jobctrl-0.4.0/tests/test_rpc_learning_recommendations.py +433 -0
  416. jobctrl-0.4.0/tests/test_runtime_identity.py +259 -0
  417. jobctrl-0.4.0/tests/test_saved_default_model.py +109 -0
  418. jobctrl-0.4.0/tests/test_saved_posting_availability_runtime.py +1001 -0
  419. jobctrl-0.4.0/tests/test_saved_search_read_failure.py +395 -0
  420. jobctrl-0.4.0/tests/test_score_atomic_publication.py +534 -0
  421. jobctrl-0.4.0/tests/test_score_batch_ownership.py +502 -0
  422. jobctrl-0.4.0/tests/test_score_interview_binding.py +63 -0
  423. jobctrl-0.4.0/tests/test_score_profile_impact.py +480 -0
  424. jobctrl-0.4.0/tests/test_score_repository.py +1061 -0
  425. jobctrl-0.4.0/tests/test_score_saved_search_preflight.py +503 -0
  426. jobctrl-0.4.0/tests/test_score_source_fence.py +352 -0
  427. jobctrl-0.4.0/tests/test_score_staleness_publication.py +191 -0
  428. jobctrl-0.4.0/tests/test_score_use_cases.py +1392 -0
  429. jobctrl-0.4.0/tests/test_scorer.py +1625 -0
  430. jobctrl-0.4.0/tests/test_scoring_determinations.py +163 -0
  431. jobctrl-0.4.0/tests/test_scoring_eval_feedback.py +237 -0
  432. jobctrl-0.4.0/tests/test_screening_answers.py +656 -0
  433. jobctrl-0.4.0/tests/test_selected_board_wiring.py +224 -0
  434. jobctrl-0.4.0/tests/test_semantic_determinations.py +446 -0
  435. jobctrl-0.4.0/tests/test_semantic_storage.py +186 -0
  436. jobctrl-0.4.0/tests/test_setup_probes.py +781 -0
  437. jobctrl-0.4.0/tests/test_single_provider_analysis.py +91 -0
  438. jobctrl-0.4.0/tests/test_smart_posting_intake.py +354 -0
  439. jobctrl-0.4.0/tests/test_smartextract_discovery.py +672 -0
  440. jobctrl-0.4.0/tests/test_smartextract_resilience.py +127 -0
  441. jobctrl-0.4.0/tests/test_source_registry.py +530 -0
  442. jobctrl-0.4.0/tests/test_stage_runner_thread_safety.py +169 -0
  443. jobctrl-0.4.0/tests/test_tailor_judge_selection.py +99 -0
  444. jobctrl-0.4.0/tests/test_tailor_provenance_integration.py +1577 -0
  445. jobctrl-0.4.0/tests/test_tailor_retailor.py +854 -0
  446. jobctrl-0.4.0/tests/test_tailor_voice_audit_integration.py +974 -0
  447. jobctrl-0.4.0/tests/test_tailoring_artifact_boundary.py +225 -0
  448. jobctrl-0.4.0/tests/test_tailoring_ownership_race.py +532 -0
  449. jobctrl-0.4.0/tests/test_tailoring_policy_revisions.py +292 -0
  450. jobctrl-0.4.0/tests/test_tailoring_prompt_projection.py +70 -0
  451. jobctrl-0.4.0/tests/test_target_search_preferences.py +158 -0
  452. jobctrl-0.4.0/tests/test_temporal_concurrency.py +71 -0
  453. jobctrl-0.4.0/tests/test_temporal_env.py +209 -0
  454. jobctrl-0.4.0/tests/test_temporal_worker.py +108 -0
  455. jobctrl-0.4.0/tests/test_terminal_material_rejection.py +69 -0
  456. jobctrl-0.4.0/tests/test_v12_activation.py +298 -0
  457. jobctrl-0.4.0/tests/test_v14_v15_inplace.py +708 -0
  458. jobctrl-0.4.0/tests/test_v15_candidate_execution.py +137 -0
  459. jobctrl-0.4.0/tests/test_v15_lifecycle_revisions.py +122 -0
  460. jobctrl-0.4.0/tests/test_v7_cover_runtime.py +1041 -0
  461. jobctrl-0.4.0/tests/test_v7_score_runtime.py +627 -0
  462. jobctrl-0.4.0/tests/test_v7_tailor_runtime.py +2063 -0
  463. jobctrl-0.4.0/tests/test_voice_adapter.py +247 -0
  464. jobctrl-0.4.0/tests/test_workday_discovery.py +339 -0
  465. jobctrl-0.4.0/tests/test_worker_cooperative_shutdown.py +194 -0
  466. jobctrl-0.4.0/tests/test_worker_reconciler.py +582 -0
  467. jobctrl-0.4.0/tests/test_worker_trace_context.py +238 -0
  468. jobctrl-0.4.0/tests/test_workflow_apply.py +1028 -0
  469. jobctrl-0.4.0/tests/test_workflow_control_capacity.py +346 -0
  470. jobctrl-0.4.0/tests/test_workflow_discovery.py +1670 -0
  471. jobctrl-0.4.0/tests/test_workflow_finalize.py +433 -0
  472. jobctrl-0.4.0/tests/test_workflow_id_overlap.py +109 -0
  473. jobctrl-0.4.0/tests/test_workflow_job_pipeline.py +1731 -0
  474. jobctrl-0.4.0/tests/test_workflow_job_preparation.py +1252 -0
  475. jobctrl-0.4.0/tests/test_workflow_start_metadata.py +141 -0
  476. jobctrl-0.4.0/tests/workflow_determination_fakes.py +131 -0
  477. jobctrl-0.4.0/uv.lock +2376 -0
  478. jobctrl-0.3.1/PKG-INFO +0 -88
  479. jobctrl-0.3.1/README.md +0 -29
  480. jobctrl-0.3.1/pyproject.toml +0 -151
  481. jobctrl-0.3.1/src/jobctrl/__init__.py +0 -3
  482. jobctrl-0.3.1/src/jobctrl/apply/activities.py +0 -142
  483. jobctrl-0.3.1/src/jobctrl/apply/auto_apply.py +0 -188
  484. jobctrl-0.3.1/src/jobctrl/apply/chrome.py +0 -1400
  485. jobctrl-0.3.1/src/jobctrl/apply/dashboard.py +0 -224
  486. jobctrl-0.3.1/src/jobctrl/apply/launcher.py +0 -2886
  487. jobctrl-0.3.1/src/jobctrl/apply/workflow.py +0 -208
  488. jobctrl-0.3.1/src/jobctrl/cli.py +0 -3904
  489. jobctrl-0.3.1/src/jobctrl/config.py +0 -1879
  490. jobctrl-0.3.1/src/jobctrl/contact/activities.py +0 -180
  491. jobctrl-0.3.1/src/jobctrl/contact/workflow.py +0 -209
  492. jobctrl-0.3.1/src/jobctrl/database.py +0 -3621
  493. jobctrl-0.3.1/src/jobctrl/digest.py +0 -750
  494. jobctrl-0.3.1/src/jobctrl/discovery/activities.py +0 -805
  495. jobctrl-0.3.1/src/jobctrl/discovery/execution_reconciliation.py +0 -1488
  496. jobctrl-0.3.1/src/jobctrl/discovery/job_url_import_workflow.py +0 -1441
  497. jobctrl-0.3.1/src/jobctrl/discovery/jobspy.py +0 -2132
  498. jobctrl-0.3.1/src/jobctrl/discovery/smartextract.py +0 -1540
  499. jobctrl-0.3.1/src/jobctrl/discovery/workday.py +0 -854
  500. jobctrl-0.3.1/src/jobctrl/discovery/workflow.py +0 -713
  501. jobctrl-0.3.1/src/jobctrl/domain/apply/process_manager.py +0 -768
  502. jobctrl-0.3.1/src/jobctrl/domain/apply/services.py +0 -339
  503. jobctrl-0.3.1/src/jobctrl/domain/apply/use_cases.py +0 -687
  504. jobctrl-0.3.1/src/jobctrl/domain/apply/value_objects.py +0 -321
  505. jobctrl-0.3.1/src/jobctrl/domain/compensation/classification.py +0 -48
  506. jobctrl-0.3.1/src/jobctrl/domain/contact/outreach.py +0 -616
  507. jobctrl-0.3.1/src/jobctrl/domain/contact/outreach_use_cases.py +0 -624
  508. jobctrl-0.3.1/src/jobctrl/domain/contact/research.py +0 -304
  509. jobctrl-0.3.1/src/jobctrl/domain/contact/research_services.py +0 -323
  510. jobctrl-0.3.1/src/jobctrl/domain/contact/research_use_cases.py +0 -164
  511. jobctrl-0.3.1/src/jobctrl/domain/determinations.py +0 -304
  512. jobctrl-0.3.1/src/jobctrl/domain/discovery/use_cases.py +0 -666
  513. jobctrl-0.3.1/src/jobctrl/domain/enrichment/interpretation.py +0 -115
  514. jobctrl-0.3.1/src/jobctrl/domain/enrichment/page_interpretation.py +0 -113
  515. jobctrl-0.3.1/src/jobctrl/domain/enrichment/value_objects.py +0 -215
  516. jobctrl-0.3.1/src/jobctrl/domain/errors.py +0 -78
  517. jobctrl-0.3.1/src/jobctrl/domain/events/__init__.py +0 -510
  518. jobctrl-0.3.1/src/jobctrl/domain/events/apply.py +0 -109
  519. jobctrl-0.3.1/src/jobctrl/domain/events/contact.py +0 -328
  520. jobctrl-0.3.1/src/jobctrl/domain/events/workflow.py +0 -260
  521. jobctrl-0.3.1/src/jobctrl/domain/exact_values.py +0 -19
  522. jobctrl-0.3.1/src/jobctrl/domain/interview/catalog.py +0 -453
  523. jobctrl-0.3.1/src/jobctrl/domain/materials/analysis.py +0 -491
  524. jobctrl-0.3.1/src/jobctrl/domain/materials/analyze_use_case.py +0 -335
  525. jobctrl-0.3.1/src/jobctrl/domain/materials/artifact_quality.py +0 -80
  526. jobctrl-0.3.1/src/jobctrl/domain/materials/claim_verification.py +0 -165
  527. jobctrl-0.3.1/src/jobctrl/domain/materials/generation.py +0 -49
  528. jobctrl-0.3.1/src/jobctrl/domain/materials/policy.py +0 -760
  529. jobctrl-0.3.1/src/jobctrl/domain/materials/quality.py +0 -739
  530. jobctrl-0.3.1/src/jobctrl/domain/materials/requirement_coverage.py +0 -1368
  531. jobctrl-0.3.1/src/jobctrl/domain/materials/resume_document.py +0 -266
  532. jobctrl-0.3.1/src/jobctrl/domain/materials/services.py +0 -457
  533. jobctrl-0.3.1/src/jobctrl/domain/materials/use_cases.py +0 -4030
  534. jobctrl-0.3.1/src/jobctrl/domain/ports/apply.py +0 -224
  535. jobctrl-0.3.1/src/jobctrl/domain/ports/artifact_quality.py +0 -38
  536. jobctrl-0.3.1/src/jobctrl/domain/ports/claim_verification.py +0 -77
  537. jobctrl-0.3.1/src/jobctrl/domain/ports/contact.py +0 -125
  538. jobctrl-0.3.1/src/jobctrl/domain/ports/llm.py +0 -99
  539. jobctrl-0.3.1/src/jobctrl/domain/ports/materials.py +0 -485
  540. jobctrl-0.3.1/src/jobctrl/domain/ports/politeness.py +0 -260
  541. jobctrl-0.3.1/src/jobctrl/domain/ports/resume_adversarial.py +0 -32
  542. jobctrl-0.3.1/src/jobctrl/domain/ports/scoring.py +0 -142
  543. jobctrl-0.3.1/src/jobctrl/domain/preparation/work_items.py +0 -50
  544. jobctrl-0.3.1/src/jobctrl/domain/profile/canonical_sources.py +0 -63
  545. jobctrl-0.3.1/src/jobctrl/domain/profile/search_targets.py +0 -32
  546. jobctrl-0.3.1/src/jobctrl/domain/profile/value_objects.py +0 -691
  547. jobctrl-0.3.1/src/jobctrl/domain/scoring/determination.py +0 -105
  548. jobctrl-0.3.1/src/jobctrl/domain/scoring/requirement_fit.py +0 -196
  549. jobctrl-0.3.1/src/jobctrl/domain/scoring/services.py +0 -516
  550. jobctrl-0.3.1/src/jobctrl/domain/scoring/use_cases.py +0 -894
  551. jobctrl-0.3.1/src/jobctrl/domain/scoring/value_objects.py +0 -1357
  552. jobctrl-0.3.1/src/jobctrl/enrichment/availability.py +0 -1433
  553. jobctrl-0.3.1/src/jobctrl/enrichment/detail.py +0 -4908
  554. jobctrl-0.3.1/src/jobctrl/infrastructure/analysis/antigravity_analysis_adapter.py +0 -231
  555. jobctrl-0.3.1/src/jobctrl/infrastructure/analysis/claude_analysis_adapter.py +0 -266
  556. jobctrl-0.3.1/src/jobctrl/infrastructure/analysis/codex_analysis_adapter.py +0 -324
  557. jobctrl-0.3.1/src/jobctrl/infrastructure/analysis/ensemble.py +0 -249
  558. jobctrl-0.3.1/src/jobctrl/infrastructure/apply/claude_code_cli.py +0 -637
  559. jobctrl-0.3.1/src/jobctrl/infrastructure/apply/email_sender.py +0 -27
  560. jobctrl-0.3.1/src/jobctrl/infrastructure/apply/local_chrome.py +0 -88
  561. jobctrl-0.3.1/src/jobctrl/infrastructure/apply_tools/mcp_server.py +0 -866
  562. jobctrl-0.3.1/src/jobctrl/infrastructure/career_learning.py +0 -509
  563. jobctrl-0.3.1/src/jobctrl/infrastructure/compensation/automatic_refresh.py +0 -580
  564. jobctrl-0.3.1/src/jobctrl/infrastructure/compensation/interpretation.py +0 -54
  565. jobctrl-0.3.1/src/jobctrl/infrastructure/compensation/levels_fyi_public.py +0 -659
  566. jobctrl-0.3.1/src/jobctrl/infrastructure/compensation/refresh_state.py +0 -541
  567. jobctrl-0.3.1/src/jobctrl/infrastructure/compensation/sqlite_market_repository.py +0 -1599
  568. jobctrl-0.3.1/src/jobctrl/infrastructure/compensation/sqlite_repository.py +0 -435
  569. jobctrl-0.3.1/src/jobctrl/infrastructure/compensation/workflow.py +0 -203
  570. jobctrl-0.3.1/src/jobctrl/infrastructure/contact/outreach_repository.py +0 -534
  571. jobctrl-0.3.1/src/jobctrl/infrastructure/contact/research_fetcher.py +0 -257
  572. jobctrl-0.3.1/src/jobctrl/infrastructure/contact/research_repository.py +0 -456
  573. jobctrl-0.3.1/src/jobctrl/infrastructure/determinations.py +0 -377
  574. jobctrl-0.3.1/src/jobctrl/infrastructure/discovery/capture_recovery.py +0 -109
  575. jobctrl-0.3.1/src/jobctrl/infrastructure/discovery/production_wiring.py +0 -2232
  576. jobctrl-0.3.1/src/jobctrl/infrastructure/discovery/sqlite_execution_repository.py +0 -331
  577. jobctrl-0.3.1/src/jobctrl/infrastructure/discovery/sqlite_repository.py +0 -1394
  578. jobctrl-0.3.1/src/jobctrl/infrastructure/discovery/sqlite_search_unit_repository.py +0 -879
  579. jobctrl-0.3.1/src/jobctrl/infrastructure/enrichment/interpretation.py +0 -80
  580. jobctrl-0.3.1/src/jobctrl/infrastructure/enrichment/playwright_fetcher.py +0 -424
  581. jobctrl-0.3.1/src/jobctrl/infrastructure/gmail/auth.py +0 -239
  582. jobctrl-0.3.1/src/jobctrl/infrastructure/gmail/client.py +0 -302
  583. jobctrl-0.3.1/src/jobctrl/infrastructure/gmail/feedback.py +0 -727
  584. jobctrl-0.3.1/src/jobctrl/infrastructure/llm/codex_turn.py +0 -181
  585. jobctrl-0.3.1/src/jobctrl/infrastructure/llm/llm_client.py +0 -910
  586. jobctrl-0.3.1/src/jobctrl/infrastructure/llm/model_catalog.py +0 -256
  587. jobctrl-0.3.1/src/jobctrl/infrastructure/llm/provider_errors.py +0 -275
  588. jobctrl-0.3.1/src/jobctrl/infrastructure/materials/__init__.py +0 -48
  589. jobctrl-0.3.1/src/jobctrl/infrastructure/materials/html_resume_pdf.py +0 -822
  590. jobctrl-0.3.1/src/jobctrl/infrastructure/materials/screening_answers.py +0 -444
  591. jobctrl-0.3.1/src/jobctrl/infrastructure/materials/sqlite_repository.py +0 -1391
  592. jobctrl-0.3.1/src/jobctrl/infrastructure/materials/voice_adapter.py +0 -193
  593. jobctrl-0.3.1/src/jobctrl/infrastructure/migrations/schema_manifest.py +0 -156
  594. jobctrl-0.3.1/src/jobctrl/infrastructure/migrations/schema_v13.py +0 -106
  595. jobctrl-0.3.1/src/jobctrl/infrastructure/network/http_client.py +0 -152
  596. jobctrl-0.3.1/src/jobctrl/infrastructure/network/politeness.py +0 -320
  597. jobctrl-0.3.1/src/jobctrl/infrastructure/network/rate_limiter.py +0 -193
  598. jobctrl-0.3.1/src/jobctrl/infrastructure/network/url_safety.py +0 -331
  599. jobctrl-0.3.1/src/jobctrl/infrastructure/observability/llm_spans.py +0 -169
  600. jobctrl-0.3.1/src/jobctrl/infrastructure/preparation/sqlite_repository.py +0 -70
  601. jobctrl-0.3.1/src/jobctrl/infrastructure/preparation_recovery.py +0 -493
  602. jobctrl-0.3.1/src/jobctrl/infrastructure/profile/factory.py +0 -83
  603. jobctrl-0.3.1/src/jobctrl/infrastructure/profile/sqlite_repository.py +0 -1086
  604. jobctrl-0.3.1/src/jobctrl/infrastructure/projections/projection_builder.py +0 -5014
  605. jobctrl-0.3.1/src/jobctrl/infrastructure/rpc/handlers.py +0 -1451
  606. jobctrl-0.3.1/src/jobctrl/infrastructure/rpc/server.py +0 -354
  607. jobctrl-0.3.1/src/jobctrl/infrastructure/runtime_identity.py +0 -227
  608. jobctrl-0.3.1/src/jobctrl/infrastructure/scoring/criteria_provider.py +0 -170
  609. jobctrl-0.3.1/src/jobctrl/infrastructure/scoring/sqlite_repository.py +0 -815
  610. jobctrl-0.3.1/src/jobctrl/infrastructure/setup_probes.py +0 -985
  611. jobctrl-0.3.1/src/jobctrl/infrastructure/temporal/activity_runtime_telemetry.py +0 -378
  612. jobctrl-0.3.1/src/jobctrl/infrastructure/temporal/concurrency.py +0 -65
  613. jobctrl-0.3.1/src/jobctrl/infrastructure/temporal/finalize.py +0 -314
  614. jobctrl-0.3.1/src/jobctrl/infrastructure/temporal/registry.py +0 -116
  615. jobctrl-0.3.1/src/jobctrl/infrastructure/temporal/run_in_activity.py +0 -263
  616. jobctrl-0.3.1/src/jobctrl/infrastructure/temporal/worker.py +0 -105
  617. jobctrl-0.3.1/src/jobctrl/infrastructure/workflow_run_context.py +0 -87
  618. jobctrl-0.3.1/src/jobctrl/interview/activities.py +0 -518
  619. jobctrl-0.3.1/src/jobctrl/interview/workflow.py +0 -188
  620. jobctrl-0.3.1/src/jobctrl/llm.py +0 -810
  621. jobctrl-0.3.1/src/jobctrl/materials/activities.py +0 -850
  622. jobctrl-0.3.1/src/jobctrl/materials/executor.py +0 -90
  623. jobctrl-0.3.1/src/jobctrl/pipeline/automatic_preparation.py +0 -779
  624. jobctrl-0.3.1/src/jobctrl/pipeline/current_policy_selectors.py +0 -259
  625. jobctrl-0.3.1/src/jobctrl/pipeline/preparation.py +0 -1119
  626. jobctrl-0.3.1/src/jobctrl/pipeline/retry.py +0 -121
  627. jobctrl-0.3.1/src/jobctrl/pipeline/runner.py +0 -2792
  628. jobctrl-0.3.1/src/jobctrl/pipeline/workflow.py +0 -804
  629. jobctrl-0.3.1/src/jobctrl/preparation/workflow.py +0 -404
  630. jobctrl-0.3.1/src/jobctrl/profile/workflow.py +0 -168
  631. jobctrl-0.3.1/src/jobctrl/provider_packs.py +0 -690
  632. jobctrl-0.3.1/src/jobctrl/resume_profile.py +0 -416
  633. jobctrl-0.3.1/src/jobctrl/runtime.py +0 -363
  634. jobctrl-0.3.1/src/jobctrl/scoring/activities.py +0 -394
  635. jobctrl-0.3.1/src/jobctrl/scoring/cover_letter.py +0 -692
  636. jobctrl-0.3.1/src/jobctrl/scoring/employer_analysis.py +0 -155
  637. jobctrl-0.3.1/src/jobctrl/scoring/scorer.py +0 -1638
  638. jobctrl-0.3.1/src/jobctrl/scoring/tailor.py +0 -1534
  639. jobctrl-0.3.1/src/jobctrl/source_proposals_cli.py +0 -67
  640. jobctrl-0.3.1/src/jobctrl/state.py +0 -1568
  641. jobctrl-0.3.1/src/jobctrl/wizard/init.py +0 -580
  642. jobctrl-0.3.1/src/jobctrl/workflow_specs.py +0 -705
  643. jobctrl-0.3.1/tests/career_learning_fixture.py +0 -183
  644. jobctrl-0.3.1/tests/company_briefing_fixture.py +0 -66
  645. jobctrl-0.3.1/tests/compensation_fakes.py +0 -263
  646. jobctrl-0.3.1/tests/conftest.py +0 -135
  647. jobctrl-0.3.1/tests/determination_fakes.py +0 -253
  648. jobctrl-0.3.1/tests/fixtures/rpc_boundary_python.json +0 -1
  649. jobctrl-0.3.1/tests/test_accepted_docx_export.py +0 -328
  650. jobctrl-0.3.1/tests/test_activity_apply.py +0 -240
  651. jobctrl-0.3.1/tests/test_activity_connection_lifetime.py +0 -161
  652. jobctrl-0.3.1/tests/test_activity_cover.py +0 -62
  653. jobctrl-0.3.1/tests/test_activity_runtime_telemetry.py +0 -246
  654. jobctrl-0.3.1/tests/test_analysis_determinations.py +0 -232
  655. jobctrl-0.3.1/tests/test_antigravity_adapter.py +0 -331
  656. jobctrl-0.3.1/tests/test_apply_chrome_dry_run_guard.py +0 -1340
  657. jobctrl-0.3.1/tests/test_apply_log_artifact_registration.py +0 -422
  658. jobctrl-0.3.1/tests/test_apply_prompt_builder.py +0 -514
  659. jobctrl-0.3.1/tests/test_apply_regressions.py +0 -1946
  660. jobctrl-0.3.1/tests/test_apply_runs_projection_from_events.py +0 -383
  661. jobctrl-0.3.1/tests/test_apply_saga.py +0 -776
  662. jobctrl-0.3.1/tests/test_apply_tools_mcp_server.py +0 -810
  663. jobctrl-0.3.1/tests/test_apply_use_cases.py +0 -638
  664. jobctrl-0.3.1/tests/test_artifact_determinations.py +0 -319
  665. jobctrl-0.3.1/tests/test_auto_apply_reconciler.py +0 -248
  666. jobctrl-0.3.1/tests/test_automatic_compensation_refresh.py +0 -203
  667. jobctrl-0.3.1/tests/test_automatic_preparation.py +0 -908
  668. jobctrl-0.3.1/tests/test_automatic_preparation_temporal_qa.py +0 -1337
  669. jobctrl-0.3.1/tests/test_browser_capabilities.py +0 -1272
  670. jobctrl-0.3.1/tests/test_browser_ua_propagation.py +0 -385
  671. jobctrl-0.3.1/tests/test_captured_posting_recovery.py +0 -158
  672. jobctrl-0.3.1/tests/test_claude_code_cli_adapter.py +0 -877
  673. jobctrl-0.3.1/tests/test_codex_home_isolation.py +0 -453
  674. jobctrl-0.3.1/tests/test_codex_turn.py +0 -76
  675. jobctrl-0.3.1/tests/test_company_briefings.py +0 -453
  676. jobctrl-0.3.1/tests/test_compensation_v7_job_id.py +0 -143
  677. jobctrl-0.3.1/tests/test_contact_research_workflow.py +0 -572
  678. jobctrl-0.3.1/tests/test_dashboard_execution_policy.py +0 -93
  679. jobctrl-0.3.1/tests/test_digest_cli.py +0 -133
  680. jobctrl-0.3.1/tests/test_digest_parity.py +0 -528
  681. jobctrl-0.3.1/tests/test_discover_reliability.py +0 -3087
  682. jobctrl-0.3.1/tests/test_discovery_execution_reconciliation.py +0 -2529
  683. jobctrl-0.3.1/tests/test_discovery_limits.py +0 -1380
  684. jobctrl-0.3.1/tests/test_discovery_preparation_orchestration.py +0 -608
  685. jobctrl-0.3.1/tests/test_domain_events.py +0 -565
  686. jobctrl-0.3.1/tests/test_employer_analysis_ensemble.py +0 -668
  687. jobctrl-0.3.1/tests/test_employer_analysis_leg_config.py +0 -126
  688. jobctrl-0.3.1/tests/test_enrichment_politeness_gate.py +0 -1122
  689. jobctrl-0.3.1/tests/test_enrichment_retry.py +0 -267
  690. jobctrl-0.3.1/tests/test_enrichment_url_safety.py +0 -696
  691. jobctrl-0.3.1/tests/test_exact_v7_apply_acquire_job_identity.py +0 -1053
  692. jobctrl-0.3.1/tests/test_exact_v7_schema.py +0 -1523
  693. jobctrl-0.3.1/tests/test_exact_v7_state_reset.py +0 -187
  694. jobctrl-0.3.1/tests/test_gmail_connector.py +0 -492
  695. jobctrl-0.3.1/tests/test_gmail_feedback.py +0 -1092
  696. jobctrl-0.3.1/tests/test_gmail_feedback_scan_handler.py +0 -69
  697. jobctrl-0.3.1/tests/test_interview_determinations.py +0 -341
  698. jobctrl-0.3.1/tests/test_job_url_import_workflow.py +0 -1207
  699. jobctrl-0.3.1/tests/test_jsonrpc_handlers.py +0 -2835
  700. jobctrl-0.3.1/tests/test_llm_provider_routing.py +0 -512
  701. jobctrl-0.3.1/tests/test_llm_spans.py +0 -217
  702. jobctrl-0.3.1/tests/test_llm_spend_budget.py +0 -199
  703. jobctrl-0.3.1/tests/test_locale_variants_integration.py +0 -586
  704. jobctrl-0.3.1/tests/test_material_activity_recovery.py +0 -365
  705. jobctrl-0.3.1/tests/test_materials_use_cases.py +0 -406
  706. jobctrl-0.3.1/tests/test_model_catalog.py +0 -154
  707. jobctrl-0.3.1/tests/test_native_credentials.py +0 -478
  708. jobctrl-0.3.1/tests/test_offer_outreach.py +0 -337
  709. jobctrl-0.3.1/tests/test_optional_extension.py +0 -955
  710. jobctrl-0.3.1/tests/test_otel_init.py +0 -170
  711. jobctrl-0.3.1/tests/test_outreach_repository_v7.py +0 -116
  712. jobctrl-0.3.1/tests/test_p1b_error_inversion.py +0 -658
  713. jobctrl-0.3.1/tests/test_pdf_renderer_ports.py +0 -1161
  714. jobctrl-0.3.1/tests/test_pipeline_observability.py +0 -202
  715. jobctrl-0.3.1/tests/test_preparation_job_reader.py +0 -118
  716. jobctrl-0.3.1/tests/test_projection_builder.py +0 -1185
  717. jobctrl-0.3.1/tests/test_provider_packs.py +0 -525
  718. jobctrl-0.3.1/tests/test_release_check.py +0 -632
  719. jobctrl-0.3.1/tests/test_release_workflow_topology.py +0 -79
  720. jobctrl-0.3.1/tests/test_remaining_determinations.py +0 -272
  721. jobctrl-0.3.1/tests/test_requirement_fit_resolution.py +0 -192
  722. jobctrl-0.3.1/tests/test_requirement_led_tailoring.py +0 -1496
  723. jobctrl-0.3.1/tests/test_resume_html_migration.py +0 -301
  724. jobctrl-0.3.1/tests/test_rpc_learning_recommendations.py +0 -397
  725. jobctrl-0.3.1/tests/test_runtime_identity.py +0 -243
  726. jobctrl-0.3.1/tests/test_saved_posting_availability_runtime.py +0 -937
  727. jobctrl-0.3.1/tests/test_score_repository.py +0 -818
  728. jobctrl-0.3.1/tests/test_score_use_cases.py +0 -1264
  729. jobctrl-0.3.1/tests/test_scorer.py +0 -1559
  730. jobctrl-0.3.1/tests/test_scoring_determinations.py +0 -163
  731. jobctrl-0.3.1/tests/test_scoring_eval_feedback.py +0 -191
  732. jobctrl-0.3.1/tests/test_screening_answers.py +0 -632
  733. jobctrl-0.3.1/tests/test_semantic_determinations.py +0 -246
  734. jobctrl-0.3.1/tests/test_semantic_storage.py +0 -183
  735. jobctrl-0.3.1/tests/test_setup_probes.py +0 -781
  736. jobctrl-0.3.1/tests/test_smartextract_discovery.py +0 -665
  737. jobctrl-0.3.1/tests/test_smartextract_resilience.py +0 -120
  738. jobctrl-0.3.1/tests/test_source_registry.py +0 -528
  739. jobctrl-0.3.1/tests/test_stage_runner_thread_safety.py +0 -147
  740. jobctrl-0.3.1/tests/test_tailor_provenance_integration.py +0 -1570
  741. jobctrl-0.3.1/tests/test_tailor_retailor.py +0 -844
  742. jobctrl-0.3.1/tests/test_tailor_voice_audit_integration.py +0 -946
  743. jobctrl-0.3.1/tests/test_tailoring_artifact_boundary.py +0 -219
  744. jobctrl-0.3.1/tests/test_tailoring_policy_revisions.py +0 -178
  745. jobctrl-0.3.1/tests/test_target_search_preferences.py +0 -155
  746. jobctrl-0.3.1/tests/test_temporal_concurrency.py +0 -52
  747. jobctrl-0.3.1/tests/test_temporal_env.py +0 -158
  748. jobctrl-0.3.1/tests/test_temporal_worker.py +0 -106
  749. jobctrl-0.3.1/tests/test_v12_activation.py +0 -266
  750. jobctrl-0.3.1/tests/test_v7_cover_runtime.py +0 -882
  751. jobctrl-0.3.1/tests/test_v7_score_runtime.py +0 -627
  752. jobctrl-0.3.1/tests/test_v7_tailor_runtime.py +0 -1950
  753. jobctrl-0.3.1/tests/test_voice_adapter.py +0 -212
  754. jobctrl-0.3.1/tests/test_workday_discovery.py +0 -339
  755. jobctrl-0.3.1/tests/test_worker_reconciler.py +0 -601
  756. jobctrl-0.3.1/tests/test_workflow_apply.py +0 -336
  757. jobctrl-0.3.1/tests/test_workflow_discovery.py +0 -1602
  758. jobctrl-0.3.1/tests/test_workflow_finalize.py +0 -326
  759. jobctrl-0.3.1/tests/test_workflow_id_overlap.py +0 -75
  760. jobctrl-0.3.1/tests/test_workflow_job_pipeline.py +0 -1689
  761. jobctrl-0.3.1/tests/test_workflow_job_preparation.py +0 -908
  762. jobctrl-0.3.1/tests/workflow_determination_fakes.py +0 -112
  763. jobctrl-0.3.1/uv.lock +0 -2203
  764. {jobctrl-0.3.1 → jobctrl-0.4.0}/.gitignore +0 -0
  765. {jobctrl-0.3.1 → jobctrl-0.4.0}/LICENSE +0 -0
  766. {jobctrl-0.3.1 → jobctrl-0.4.0}/NOTICE +0 -0
  767. {jobctrl-0.3.1 → jobctrl-0.4.0}/scripts/search_unit_concurrency_assessment.py +0 -0
  768. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/__main__.py +0 -0
  769. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/actions.py +0 -0
  770. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/apply/__init__.py +0 -0
  771. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/apply/cover_letter_binding.py +0 -0
  772. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/apply/origins.py +0 -0
  773. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/apply/prompt.py +0 -0
  774. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/apply/telemetry.py +0 -0
  775. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/assets/determinations/taxonomy.v1.json +0 -0
  776. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/assets/fonts/GEIST-LICENSE.txt +0 -0
  777. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/assets/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
  778. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/assets/fonts/geist-latin-wght-normal.woff2 +0 -0
  779. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/assets/interview/catalog.v1.json +0 -0
  780. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/browser_capabilities.py +0 -0
  781. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/company_briefing_cli.py +0 -0
  782. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/config/employers.yaml +0 -0
  783. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/config/sites.yaml +0 -0
  784. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/contact/__init__.py +0 -0
  785. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/discovery/__init__.py +0 -0
  786. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/discovery/manual_capture_import.py +0 -0
  787. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/discovery/manual_capture_workflow.py +0 -0
  788. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/discovery/target_queries.py +0 -0
  789. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/__init__.py +0 -0
  790. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/apply/__init__.py +0 -0
  791. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/apply/aggregate.py +0 -0
  792. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/apply/entities.py +0 -0
  793. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/apply/form_mapping.py +0 -0
  794. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/apply/repeat_application.py +0 -0
  795. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/apply/role_equivalence.py +0 -0
  796. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/apply/screening_answers.py +0 -0
  797. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/apply/terminal_report.py +0 -0
  798. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/compensation/__init__.py +0 -0
  799. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/compensation/benchmarks.py +0 -0
  800. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/compensation/market.py +0 -0
  801. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/compensation/posted.py +0 -0
  802. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/contact/__init__.py +0 -0
  803. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/contact/aggregate.py +0 -0
  804. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/contact/outreach_gates.py +0 -0
  805. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/contact/source_policy.py +0 -0
  806. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/contact/use_cases.py +0 -0
  807. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/contact/value_objects.py +0 -0
  808. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/__init__.py +0 -0
  809. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/aggregate.py +0 -0
  810. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/execution.py +0 -0
  811. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/identity.py +0 -0
  812. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/scheduler.py +0 -0
  813. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/search_units.py +0 -0
  814. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/source_registry.py +0 -0
  815. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/discovery/value_objects.py +0 -0
  816. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/__init__.py +0 -0
  817. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/aggregate.py +0 -0
  818. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/entities.py +0 -0
  819. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/filter_override.py +0 -0
  820. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/services.py +0 -0
  821. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/snapshot_services.py +0 -0
  822. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/snapshot_set.py +0 -0
  823. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/snapshot_use_case.py +0 -0
  824. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/snapshot_value_objects.py +0 -0
  825. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/enrichment/use_cases.py +0 -0
  826. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/base.py +0 -0
  827. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/discovery.py +0 -0
  828. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/enrichment.py +0 -0
  829. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/interview.py +0 -0
  830. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/materials.py +0 -0
  831. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/operations.py +0 -0
  832. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/orchestration.py +0 -0
  833. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/profile.py +0 -0
  834. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/events/scoring.py +0 -0
  835. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/extraction.py +0 -0
  836. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/feedback/__init__.py +0 -0
  837. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/feedback/message_interpretation.py +0 -0
  838. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/identifiers.py +0 -0
  839. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/interview/__init__.py +0 -0
  840. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/interview/evidence.py +0 -0
  841. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/interview/preparation.py +0 -0
  842. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/interview/question_generation.py +0 -0
  843. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/interview/use_cases.py +0 -0
  844. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/interview/value_objects.py +0 -0
  845. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/job_content_identity.py +0 -0
  846. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/job_snapshot.py +0 -0
  847. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/__init__.py +0 -0
  848. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/adversarial.py +0 -0
  849. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/aggregate.py +0 -0
  850. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/analysis_agreement.py +0 -0
  851. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/analysis_grounding.py +0 -0
  852. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/claim_grounding.py +0 -0
  853. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/company_briefings.py +0 -0
  854. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/cover_letter_settings.py +0 -0
  855. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/coverage_audit.py +0 -0
  856. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/edit_intent.py +0 -0
  857. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/editable_export.py +0 -0
  858. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/entities.py +0 -0
  859. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/locale_variants.py +0 -0
  860. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/provenance.py +0 -0
  861. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/provenance_builder.py +0 -0
  862. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/screening_answers.py +0 -0
  863. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/value_objects.py +0 -0
  864. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/materials/voice.py +0 -0
  865. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/operations/__init__.py +0 -0
  866. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/operations/career_learning.py +0 -0
  867. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/operations/evidence_map.py +0 -0
  868. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/operations/feedback.py +0 -0
  869. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/operations/learning.py +0 -0
  870. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/operations/projections.py +0 -0
  871. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/__init__.py +0 -0
  872. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/aggregate.py +0 -0
  873. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/repository.py +0 -0
  874. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/state_machine.py +0 -0
  875. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline/use_cases.py +0 -0
  876. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/pipeline_types.py +0 -0
  877. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/__init__.py +0 -0
  878. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/analysis_agreement.py +0 -0
  879. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/artifact_generation.py +0 -0
  880. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/artifact_review.py +0 -0
  881. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/discovery.py +0 -0
  882. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/enrichment.py +0 -0
  883. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/events.py +0 -0
  884. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/feedback.py +0 -0
  885. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/job_interpretation.py +0 -0
  886. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/learning.py +0 -0
  887. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/retrieval.py +0 -0
  888. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/ports/watermark.py +0 -0
  889. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/preparation/__init__.py +0 -0
  890. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/profile/__init__.py +0 -0
  891. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/profile/aggregate.py +0 -0
  892. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/profile/interpretation.py +0 -0
  893. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/profile/ports.py +0 -0
  894. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/profile/required_bullet_coaching.py +0 -0
  895. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/profile/resume_extraction.py +0 -0
  896. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/profile/snapshot.py +0 -0
  897. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/profile/use_cases.py +0 -0
  898. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/rpc/__init__.py +0 -0
  899. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/rpc/messages.py +0 -0
  900. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/__init__.py +0 -0
  901. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/aggregate.py +0 -0
  902. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/eligibility.py +0 -0
  903. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/policy.py +0 -0
  904. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/scoring/retrieval.py +0 -0
  905. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/taxonomy.py +0 -0
  906. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/taxonomy_codes.py +0 -0
  907. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/domain/tenant.py +0 -0
  908. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/enrichment/__init__.py +0 -0
  909. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/enrichment/activities.py +0 -0
  910. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/enrichment/availability_workflow.py +0 -0
  911. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/__init__.py +0 -0
  912. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/__init__.py +0 -0
  913. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/gemini_schema.py +0 -0
  914. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/llm_analysis_synthesizer.py +0 -0
  915. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/prompts.py +0 -0
  916. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/analysis/strict_schema.py +0 -0
  917. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/apply/__init__.py +0 -0
  918. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/apply/form_mapping.py +0 -0
  919. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/apply_tools/__init__.py +0 -0
  920. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/captcha/__init__.py +0 -0
  921. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/captcha/capsolver.py +0 -0
  922. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/__init__.py +0 -0
  923. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/benchmark_ingestion.py +0 -0
  924. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/benchmark_lineage.py +0 -0
  925. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/benchmark_materialization.py +0 -0
  926. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/official_data.py +0 -0
  927. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/refresh.py +0 -0
  928. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/compensation/sqlite_benchmark_repository.py +0 -0
  929. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/contact/__init__.py +0 -0
  930. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/contact/offer_sources.py +0 -0
  931. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/contact/sqlite_repository.py +0 -0
  932. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/__init__.py +0 -0
  933. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/ats_adapters.py +0 -0
  934. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/jobstreaming_gateway.py +0 -0
  935. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/listing_display.py +0 -0
  936. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/live_browser.py +0 -0
  937. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/posting_source_proposals.py +0 -0
  938. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/recovery_manifest.py +0 -0
  939. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/sqlite_identity_resolver.py +0 -0
  940. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/discovery/sqlite_run_repository.py +0 -0
  941. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/__init__.py +0 -0
  942. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/execution_lease.py +0 -0
  943. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/linkedin_apply_resolver.py +0 -0
  944. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/page_interpretation.py +0 -0
  945. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/enrichment/sqlite_repository.py +0 -0
  946. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/events/__init__.py +0 -0
  947. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/events/in_process_bus.py +0 -0
  948. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/events/watermark.py +0 -0
  949. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/gmail/__init__.py +0 -0
  950. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/gmail/mcp_server.py +0 -0
  951. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/interview/__init__.py +0 -0
  952. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/interview/sqlite_repository.py +0 -0
  953. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/job_locators.py +0 -0
  954. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/learning/__init__.py +0 -0
  955. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/learning/sqlite_repository.py +0 -0
  956. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/llm/__init__.py +0 -0
  957. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/accepted_export.py +0 -0
  958. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/accepted_export_api.py +0 -0
  959. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/artifact_writer.py +0 -0
  960. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/bullet_provenance_repository.py +0 -0
  961. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/company_briefing_fetcher.py +0 -0
  962. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/company_briefings.py +0 -0
  963. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/cover_letter_files.py +0 -0
  964. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/docx_export.py +0 -0
  965. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/employer_analysis_repository.py +0 -0
  966. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/locale_variants.py +0 -0
  967. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/playwright_html_pdf.py +0 -0
  968. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/resume_html_migration.py +0 -0
  969. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/resume_style.py +0 -0
  970. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/unit_of_work.py +0 -0
  971. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/user_edit_review.py +0 -0
  972. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/materials/voice_prompts.py +0 -0
  973. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/__init__.py +0 -0
  974. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/compensation_role_family_seed.py +0 -0
  975. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/identity_upcast.py +0 -0
  976. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v10_execute.py +0 -0
  977. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v11_execute.py +0 -0
  978. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v12_execute.py +0 -0
  979. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v13_execute.py +0 -0
  980. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v14_execute.py +0 -0
  981. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/legacy_to_v9_execute.py +0 -0
  982. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/resume_template_seed.py +0 -0
  983. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v10.py +0 -0
  984. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v10.sql +0 -0
  985. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v11.py +0 -0
  986. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v11.sql +0 -0
  987. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v12.py +0 -0
  988. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v12.sql +0 -0
  989. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v13.sql +0 -0
  990. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v14.py +0 -0
  991. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v14.sql +0 -0
  992. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v7.py +0 -0
  993. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v7.sql +0 -0
  994. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v8.py +0 -0
  995. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v8.sql +0 -0
  996. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v9.py +0 -0
  997. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/schema_v9.sql +0 -0
  998. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v10_to_v11_execute.py +0 -0
  999. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v11_to_v12_execute.py +0 -0
  1000. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v12_activation.py +0 -0
  1001. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v12_to_v13_execute.py +0 -0
  1002. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v13_activation.py +0 -0
  1003. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v13_to_v14_execute.py +0 -0
  1004. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v14_activation.py +0 -0
  1005. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_apply_run_projections.py +0 -0
  1006. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_artifact_list_projections.py +0 -0
  1007. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_candidate.py +0 -0
  1008. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_contact_projections.py +0 -0
  1009. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_copy.py +0 -0
  1010. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_dashboard_projections.py +0 -0
  1011. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_duplicate_links.py +0 -0
  1012. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_events.py +0 -0
  1013. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_evidence_usage_projections.py +0 -0
  1014. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_execute.py +0 -0
  1015. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_job_detail_projections.py +0 -0
  1016. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_job_list_projections.py +0 -0
  1017. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_pipeline_step_projections.py +0 -0
  1018. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_plan.py +0 -0
  1019. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_population_steps.py +0 -0
  1020. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_preflight.py +0 -0
  1021. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_quiescence.py +0 -0
  1022. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_root.py +0 -0
  1023. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_score_keywords.py +0 -0
  1024. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_verify.py +0 -0
  1025. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_work_items.py +0 -0
  1026. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v7_workflow_run_projections.py +0 -0
  1027. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v6_to_v8_execute.py +0 -0
  1028. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_dashboard_outcome_conversion.py +0 -0
  1029. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_dashboard_projection_rows.py +0 -0
  1030. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_evidence_usage_projection_rows.py +0 -0
  1031. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_job_list_projection_rows.py +0 -0
  1032. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v7_to_v8_execute.py +0 -0
  1033. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v8_to_v9_execute.py +0 -0
  1034. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/migrations/v9_to_v10_execute.py +0 -0
  1035. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/__init__.py +0 -0
  1036. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/fetch_failures.py +0 -0
  1037. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/proxy.py +0 -0
  1038. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/public_http.py +0 -0
  1039. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/network/robots.py +0 -0
  1040. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/__init__.py +0 -0
  1041. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/adapter_spans.py +0 -0
  1042. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/enrichment_spans.py +0 -0
  1043. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/otel.py +0 -0
  1044. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/observability/source_spans.py +0 -0
  1045. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/pipeline/__init__.py +0 -0
  1046. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/pipeline/sqlite_repository.py +0 -0
  1047. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/preflight.py +0 -0
  1048. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/preparation/__init__.py +0 -0
  1049. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/profile/__init__.py +0 -0
  1050. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/profile/interpretation.py +0 -0
  1051. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/profile/pdf_parser.py +0 -0
  1052. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/__init__.py +0 -0
  1053. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/fetch_failure.py +0 -0
  1054. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/location_normalization.py +0 -0
  1055. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/source_quality.py +0 -0
  1056. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/sqlite_feedback_signals.py +0 -0
  1057. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/projections/sqlite_projection_store.py +0 -0
  1058. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/rpc/__init__.py +0 -0
  1059. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/rpc/enrichment_retry.py +0 -0
  1060. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/rpc/workflow_starter.py +0 -0
  1061. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/scoring/__init__.py +0 -0
  1062. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/scoring/keyword_normalization.py +0 -0
  1063. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/__init__.py +0 -0
  1064. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/cancellation_audit.py +0 -0
  1065. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/client.py +0 -0
  1066. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/durability_probe.py +0 -0
  1067. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/pipeline_step_lifecycle.py +0 -0
  1068. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/runtime_guard.py +0 -0
  1069. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/task_queue_observation.py +0 -0
  1070. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/infrastructure/temporal/task_queues.py +0 -0
  1071. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/interview/__init__.py +0 -0
  1072. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/llm_lanes.py +0 -0
  1073. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/materials/__init__.py +0 -0
  1074. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/model_defaults.py +0 -0
  1075. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/native_credentials.py +0 -0
  1076. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/operational_metrics.py +0 -0
  1077. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/pipeline/__init__.py +0 -0
  1078. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/pipeline/public_fetch_recovery.py +0 -0
  1079. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/preparation/__init__.py +0 -0
  1080. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/profile/__init__.py +0 -0
  1081. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/profile/activities.py +0 -0
  1082. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/profile/importer.py +0 -0
  1083. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/profile_import.py +0 -0
  1084. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/scoring/__init__.py +0 -0
  1085. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/scoring/eligibility_sql.py +0 -0
  1086. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/scoring/eval.py +0 -0
  1087. {jobctrl-0.3.1 → jobctrl-0.4.0}/src/jobctrl/wizard/__init__.py +0 -0
  1088. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/__init__.py +0 -0
  1089. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/availability_fixture.py +0 -0
  1090. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/availability_transports.py +0 -0
  1091. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/cover_letter_pdf_probe.py +0 -0
  1092. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/fixtures/discovery_barcelona_acceptance.json +0 -0
  1093. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/fixtures/enrichment_retry.sql +0 -0
  1094. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/fixtures/hybrid_search_topk.json +0 -0
  1095. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/fixtures/required_bullet_rpc_probe.py +0 -0
  1096. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/fixtures/rpc_boundary.json +0 -0
  1097. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/fixtures/scoring_eval_cases.json +0 -0
  1098. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/fixtures/shipped_v6_schema.sql +0 -0
  1099. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/live_browser_helpers.py +0 -0
  1100. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/page_fakes.py +0 -0
  1101. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/politeness_helpers.py +0 -0
  1102. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/projection_cross_runtime_fixture.py +0 -0
  1103. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/rpc_contract_probe.py +0 -0
  1104. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/temporal_env.py +0 -0
  1105. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_accepted_export_api.py +0 -0
  1106. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_actions.py +0 -0
  1107. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_activity_enrich.py +0 -0
  1108. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_activity_profile_import.py +0 -0
  1109. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_activity_score.py +0 -0
  1110. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_activity_tailor.py +0 -0
  1111. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_analyze_job_use_case.py +0 -0
  1112. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_application_url_authority.py +0 -0
  1113. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_apply_approval_vocabulary.py +0 -0
  1114. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_apply_eligibility_checker.py +0 -0
  1115. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_apply_origin_policy.py +0 -0
  1116. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_apply_queue_selectors.py +0 -0
  1117. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_apply_run_aggregate.py +0 -0
  1118. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_apply_runs_table_dropped.py +0 -0
  1119. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_ats_adapters.py +0 -0
  1120. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_audit_projection_parity.py +0 -0
  1121. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_autonomous_agent_port.py +0 -0
  1122. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_browser_capabilities_rpc.py +0 -0
  1123. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_browser_capability_cli.py +0 -0
  1124. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_browser_port.py +0 -0
  1125. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_bullet_provenance.py +0 -0
  1126. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_bundled_runtime.py +0 -0
  1127. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_cancellation_audit.py +0 -0
  1128. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_capsolver_client.py +0 -0
  1129. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_career_learning.py +0 -0
  1130. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_claim_grounding.py +0 -0
  1131. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_codex_adapter_status.py +0 -0
  1132. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_compensation_audit_contract.py +0 -0
  1133. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_compensation_benchmark_materialization.py +0 -0
  1134. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_compensation_benchmark_repository.py +0 -0
  1135. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_compensation_benchmarks.py +0 -0
  1136. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_compensation_gateway_routing.py +0 -0
  1137. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_compensation_official_data.py +0 -0
  1138. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_compensation_refresh_cli.py +0 -0
  1139. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_compensation_refresh_state.py +0 -0
  1140. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_config_file_transactions.py +0 -0
  1141. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_contact_aggregate.py +0 -0
  1142. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_contact_projection_parity.py +0 -0
  1143. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_contact_provenance.py +0 -0
  1144. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_contact_repository.py +0 -0
  1145. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_contact_research_projection_parity.py +0 -0
  1146. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_contact_research_source_policy.py +0 -0
  1147. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_content_validator.py +0 -0
  1148. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_cover_letter_review.py +0 -0
  1149. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_cover_requirements.py +0 -0
  1150. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_coverage_audit.py +0 -0
  1151. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_crawl_politeness_config.py +0 -0
  1152. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_criteria_provider.py +0 -0
  1153. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_dashboard_projection.py +0 -0
  1154. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_database_backup.py +0 -0
  1155. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_detail_page_fetcher.py +0 -0
  1156. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_detail_projection_job_id_contract.py +0 -0
  1157. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_enrichment_handoff.py +0 -0
  1158. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_execution_identity.py +0 -0
  1159. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_execution_lineage.py +0 -0
  1160. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_identity.py +0 -0
  1161. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_production_wiring.py +0 -0
  1162. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_scheduler_pr4.py +0 -0
  1163. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_search_unit_identity.py +0 -0
  1164. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_search_units.py +0 -0
  1165. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_discovery_transaction_lifecycle.py +0 -0
  1166. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_distribution_smoke_model.py +0 -0
  1167. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_doctor_diagnostics.py +0 -0
  1168. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_doctor_gmail_mcp.py +0 -0
  1169. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_doctor_langfuse.py +0 -0
  1170. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_doctor_llm_budget.py +0 -0
  1171. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_doctor_playwright.py +0 -0
  1172. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_doctor_temporal.py +0 -0
  1173. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_domain_event_parity.py +0 -0
  1174. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_domain_types.py +0 -0
  1175. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_due_follow_up_projection_parity.py +0 -0
  1176. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_employer_analysis_model.py +0 -0
  1177. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_employer_analysis_repository.py +0 -0
  1178. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_aggregate.py +0 -0
  1179. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_detail_staleness.py +0 -0
  1180. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_events_pr3.py +0 -0
  1181. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_extractors.py +0 -0
  1182. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_lease_concurrency.py +0 -0
  1183. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_quarantine_gating.py +0 -0
  1184. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_queue_selectors.py +0 -0
  1185. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_repository.py +0 -0
  1186. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_snapshot_pr3.py +0 -0
  1187. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_enrichment_use_cases.py +0 -0
  1188. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_event_publication.py +0 -0
  1189. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_event_type_migration.py +0 -0
  1190. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_event_watermark.py +0 -0
  1191. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_evidence_interview_value_objects.py +0 -0
  1192. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_exact_v10_schema.py +0 -0
  1193. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_exact_v11_schema.py +0 -0
  1194. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_exact_v12_schema.py +0 -0
  1195. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_exact_v14_schema.py +0 -0
  1196. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_exact_v7_selector_job_identity.py +0 -0
  1197. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_exact_v8_schema.py +0 -0
  1198. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_exact_v9_schema.py +0 -0
  1199. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_feedback_signal_reader.py +0 -0
  1200. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_fetch_failure_projection.py +0 -0
  1201. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_fetch_surface_enforcement.py +0 -0
  1202. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_gateway_http_client.py +0 -0
  1203. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_gemini_schema.py +0 -0
  1204. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_gmail_feedback_v10_anchors.py +0 -0
  1205. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_gmail_mcp_config.py +0 -0
  1206. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_in_process_bus.py +0 -0
  1207. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_interview_catalog.py +0 -0
  1208. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_interview_catalog_packaging.py +0 -0
  1209. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_interview_persistence_v12.py +0 -0
  1210. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_interview_prep_generation.py +0 -0
  1211. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_job_aggregate.py +0 -0
  1212. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_job_application_locators.py +0 -0
  1213. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_job_detail_authority.py +0 -0
  1214. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_job_list_projection.py +0 -0
  1215. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_job_repository.py +0 -0
  1216. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_jobspy_gateway_boundary.py +0 -0
  1217. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_jobstreaming_gateway.py +0 -0
  1218. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_jobstreaming_resumable_discovery.py +0 -0
  1219. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_jsonrpc_server.py +0 -0
  1220. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_keychain_credentials.py +0 -0
  1221. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_learning_recommendations.py +0 -0
  1222. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_legacy_to_v10_execute.py +0 -0
  1223. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_legacy_to_v11_execute.py +0 -0
  1224. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_legacy_to_v12_execute.py +0 -0
  1225. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_legacy_to_v9_execute.py +0 -0
  1226. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_levels_fyi_public.py +0 -0
  1227. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_linkedin_apply_resolver.py +0 -0
  1228. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_linkedin_authenticated_enrichment_retry.py +0 -0
  1229. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_live_browser_discovery.py +0 -0
  1230. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_live_worker_smoke_provider.py +0 -0
  1231. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_llm_analysis_synthesizer.py +0 -0
  1232. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_llm_client.py +0 -0
  1233. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_llm_defaults.py +0 -0
  1234. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_llm_no_credential_leakage.py +0 -0
  1235. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_llm_port.py +0 -0
  1236. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_locale_variants.py +0 -0
  1237. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_location_normalization.py +0 -0
  1238. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_manual_capture_workflow.py +0 -0
  1239. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_market_compensation_estimator.py +0 -0
  1240. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_market_compensation_repository.py +0 -0
  1241. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_materials_adversarial.py +0 -0
  1242. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_materials_aggregate.py +0 -0
  1243. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_materials_quality.py +0 -0
  1244. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_materials_queue_selectors.py +0 -0
  1245. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_materials_repository.py +0 -0
  1246. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_materials_repository_v7.py +0 -0
  1247. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_materials_unit_of_work.py +0 -0
  1248. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_operational_metrics.py +0 -0
  1249. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_outreach_draft_gates.py +0 -0
  1250. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_outreach_follow_up_derivation.py +0 -0
  1251. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_outreach_no_auto_send.py +0 -0
  1252. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_outreach_no_send_transport.py +0 -0
  1253. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_outreach_projection_parity.py +0 -0
  1254. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_outreach_thread_aggregate.py +0 -0
  1255. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_pipeline_repository.py +0 -0
  1256. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_pipeline_status_cli.py +0 -0
  1257. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_pipeline_step_events.py +0 -0
  1258. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_pipeline_step_lifecycle_emission.py +0 -0
  1259. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_pipeline_step_projection.py +0 -0
  1260. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_pipeline_use_cases.py +0 -0
  1261. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_politeness_gateway.py +0 -0
  1262. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_politeness_ports.py +0 -0
  1263. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_posted_compensation_repository.py +0 -0
  1264. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_posting_availability_rereview.py +0 -0
  1265. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_posting_availability_review.py +0 -0
  1266. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_posting_source_proposals.py +0 -0
  1267. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_preflight.py +0 -0
  1268. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_profile_aggregate.py +0 -0
  1269. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_profile_determinations.py +0 -0
  1270. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_profile_import.py +0 -0
  1271. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_profile_snapshot.py +0 -0
  1272. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_profile_use_cases.py +0 -0
  1273. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_public_destination_http.py +0 -0
  1274. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_public_fetch_recovery.py +0 -0
  1275. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_python_package_attribution.py +0 -0
  1276. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_render_resume_pdf_handler.py +0 -0
  1277. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_repeat_application_prevention.py +0 -0
  1278. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_repository_construction.py +0 -0
  1279. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_required_bullet_coaching.py +0 -0
  1280. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_resume_assembler.py +0 -0
  1281. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_rpc_cancel_run.py +0 -0
  1282. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_rpc_contract_boundary.py +0 -0
  1283. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_rpc_handlers_apply_workflow.py +0 -0
  1284. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_rpc_otel.py +0 -0
  1285. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_rpc_server_workflow_mode.py +0 -0
  1286. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_saved_edit_determinations.py +0 -0
  1287. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_saved_posting_availability.py +0 -0
  1288. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_schema_v7_packaging.py +0 -0
  1289. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_score_activity_recovery.py +0 -0
  1290. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_score_aggregate.py +0 -0
  1291. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_score_eligibility_stage_state.py +0 -0
  1292. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_score_queue_selectors.py +0 -0
  1293. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_scoring_eval.py +0 -0
  1294. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_scoring_policy.py +0 -0
  1295. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_screening_answers_integration.py +0 -0
  1296. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_search_unit_concurrency_assessment.py +0 -0
  1297. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_selected_apply_url_refresh.py +0 -0
  1298. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_setup_synthesis_auth.py +0 -0
  1299. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_source_quality_projection_pr4.py +0 -0
  1300. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_source_spans.py +0 -0
  1301. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_sqlite_learning_recommendations.py +0 -0
  1302. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_sqlite_profile_repository.py +0 -0
  1303. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_stage_state_machine.py +0 -0
  1304. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_state_dashboard.py +0 -0
  1305. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_state_legacy_parity.py +0 -0
  1306. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_state_machine_parity.py +0 -0
  1307. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_strict_schema.py +0 -0
  1308. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_task_queue_observation.py +0 -0
  1309. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_temporal_client.py +0 -0
  1310. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_temporal_registry.py +0 -0
  1311. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v10_to_v11_execute.py +0 -0
  1312. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_apply_run_projections.py +0 -0
  1313. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_artifact_list_projections.py +0 -0
  1314. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_candidate.py +0 -0
  1315. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_contact_projections_copy.py +0 -0
  1316. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_copy.py +0 -0
  1317. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_dashboard_projections.py +0 -0
  1318. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_duplicate_links.py +0 -0
  1319. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_event_copy.py +0 -0
  1320. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_evidence_usage_projections.py +0 -0
  1321. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_execute.py +0 -0
  1322. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_feedback_copy.py +0 -0
  1323. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_job_detail_projections.py +0 -0
  1324. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_job_list_projections.py +0 -0
  1325. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_pipeline_step_projections_copy.py +0 -0
  1326. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_plan.py +0 -0
  1327. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_population_steps.py +0 -0
  1328. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_preflight.py +0 -0
  1329. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_quiescence.py +0 -0
  1330. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_root_copy.py +0 -0
  1331. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_score_keywords.py +0 -0
  1332. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_verify.py +0 -0
  1333. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_work_items_copy.py +0 -0
  1334. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v7_workflow_run_projections_copy.py +0 -0
  1335. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v6_to_v8_execute.py +0 -0
  1336. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v7_dashboard_outcome_conversion.py +0 -0
  1337. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v7_dashboard_projection_rows.py +0 -0
  1338. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v7_evidence_usage_projection_rows.py +0 -0
  1339. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v7_job_list_projection_rows.py +0 -0
  1340. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v7_materials_selectors.py +0 -0
  1341. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v7_projection_builder_event_identity.py +0 -0
  1342. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v7_to_v8_execute.py +0 -0
  1343. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v8_to_v9_execute.py +0 -0
  1344. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_v9_to_v10_execute.py +0 -0
  1345. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_voice_payload.py +0 -0
  1346. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_workday_gateway_routing.py +0 -0
  1347. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_worker_heartbeat_loop.py +0 -0
  1348. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_workflow_durability_probe.py +0 -0
  1349. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_workflow_heavy_rpc_conversions.py +0 -0
  1350. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_workflow_run_context.py +0 -0
  1351. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_workflow_runs_projection_from_events.py +0 -0
  1352. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_workflow_starter_cache.py +0 -0
  1353. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/test_workspace_migration.py +0 -0
  1354. {jobctrl-0.3.1 → jobctrl-0.4.0}/tests/v6_feedback_fixture.py +0 -0
  1355. {jobctrl-0.3.1 → 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
+ ]