algo-cli-runtime 0.14.0__py3-none-any.whl
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.
- algo_cli/__init__.py +3 -0
- algo_cli/__main__.py +7 -0
- algo_cli/_internal/__init__.py +12 -0
- algo_cli/_internal/policy_chain.py +259 -0
- algo_cli/action_registry.py +1047 -0
- algo_cli/agent_blocks.py +550 -0
- algo_cli/agent_pipeline.py +1457 -0
- algo_cli/agent_threads.py +308 -0
- algo_cli/animations.py +316 -0
- algo_cli/cache_admission.py +209 -0
- algo_cli/capability_mask.py +66 -0
- algo_cli/chat_protocol.py +116 -0
- algo_cli/chatgpt_auth.py +510 -0
- algo_cli/chatgpt_client.py +657 -0
- algo_cli/code_rag.py +479 -0
- algo_cli/config.py +651 -0
- algo_cli/context_budget.py +679 -0
- algo_cli/credential_helpers.py +315 -0
- algo_cli/deliberation.py +29 -0
- algo_cli/display.py +1470 -0
- algo_cli/evals/__init__.py +21 -0
- algo_cli/evals/algorithm_effectiveness.py +560 -0
- algo_cli/evals/competitive_harness_rating.py +702 -0
- algo_cli/evals/cot_quality.py +220 -0
- algo_cli/evals/harness_retrieval_benchmark.py +401 -0
- algo_cli/evals/performance_regression.py +136 -0
- algo_cli/evals/scorecard_grading.py +308 -0
- algo_cli/evals/session_distribution.py +84 -0
- algo_cli/execution_guardrails.py +806 -0
- algo_cli/extensions_manifest.py +84 -0
- algo_cli/git_evidence.py +227 -0
- algo_cli/google_workspace.py +407 -0
- algo_cli/google_workspace_auth.py +523 -0
- algo_cli/harness.py +2587 -0
- algo_cli/identity.py +557 -0
- algo_cli/index_compute_lab.py +228 -0
- algo_cli/inference_harness.py +70 -0
- algo_cli/intelligence/__init__.py +1103 -0
- algo_cli/intelligence/acrobat_config.py +307 -0
- algo_cli/intelligence/acrobat_manifests.py +338 -0
- algo_cli/intelligence/acrobat_models.py +195 -0
- algo_cli/intelligence/acrobat_pipeline.py +295 -0
- algo_cli/intelligence/acrobat_runtime.py +302 -0
- algo_cli/intelligence/acrobat_security.py +261 -0
- algo_cli/intelligence/acrobat_workflows.py +226 -0
- algo_cli/intelligence/actionability.py +165 -0
- algo_cli/intelligence/adversarial_audit.py +136 -0
- algo_cli/intelligence/agent_arena.py +92 -0
- algo_cli/intelligence/agent_benchmark.py +236 -0
- algo_cli/intelligence/agent_runtime.py +171 -0
- algo_cli/intelligence/agents_as_tools.py +70 -0
- algo_cli/intelligence/artifact_binding.py +80 -0
- algo_cli/intelligence/autonomous_engineer.py +1976 -0
- algo_cli/intelligence/backpressure.py +99 -0
- algo_cli/intelligence/bloom_filter.py +186 -0
- algo_cli/intelligence/bonferroni.py +66 -0
- algo_cli/intelligence/boundary_compaction.py +98 -0
- algo_cli/intelligence/catalog_verifier.py +172 -0
- algo_cli/intelligence/cavecrew.py +118 -0
- algo_cli/intelligence/changelog.py +176 -0
- algo_cli/intelligence/checkpoint_resume.py +92 -0
- algo_cli/intelligence/circuit_breaker.py +88 -0
- algo_cli/intelligence/clarification_gate.py +101 -0
- algo_cli/intelligence/code_graph.py +180 -0
- algo_cli/intelligence/coderank.py +97 -0
- algo_cli/intelligence/consistent_hash.py +150 -0
- algo_cli/intelligence/consortium_synthesis.py +139 -0
- algo_cli/intelligence/construction/__init__.py +241 -0
- algo_cli/intelligence/construction/common.py +273 -0
- algo_cli/intelligence/construction/documents.py +496 -0
- algo_cli/intelligence/construction/labor_units.py +1395 -0
- algo_cli/intelligence/construction/payments.py +470 -0
- algo_cli/intelligence/construction/risk.py +784 -0
- algo_cli/intelligence/content_extractor.py +132 -0
- algo_cli/intelligence/context_adaptive.py +102 -0
- algo_cli/intelligence/context_ops.py +95 -0
- algo_cli/intelligence/count_min.py +145 -0
- algo_cli/intelligence/cow_state.py +103 -0
- algo_cli/intelligence/critic_loop.py +119 -0
- algo_cli/intelligence/cross_source.py +113 -0
- algo_cli/intelligence/daemon_mode.py +99 -0
- algo_cli/intelligence/dag_orchestration.py +151 -0
- algo_cli/intelligence/deep_research.py +155 -0
- algo_cli/intelligence/degenerate_detector.py +78 -0
- algo_cli/intelligence/delta_report.py +92 -0
- algo_cli/intelligence/discovery_event_log.py +92 -0
- algo_cli/intelligence/document_ingest.py +298 -0
- algo_cli/intelligence/dual_layer_validate.py +151 -0
- algo_cli/intelligence/echo_fidelity.py +73 -0
- algo_cli/intelligence/ema_tuning.py +104 -0
- algo_cli/intelligence/event_log.py +92 -0
- algo_cli/intelligence/evidence_graph.py +114 -0
- algo_cli/intelligence/extension_host.py +162 -0
- algo_cli/intelligence/extension_manifest.py +115 -0
- algo_cli/intelligence/falsification_suite.py +178 -0
- algo_cli/intelligence/finance/__init__.py +169 -0
- algo_cli/intelligence/finance/anomalies.py +135 -0
- algo_cli/intelligence/finance/ap_ar.py +351 -0
- algo_cli/intelligence/finance/cash.py +162 -0
- algo_cli/intelligence/finance/close.py +332 -0
- algo_cli/intelligence/finance/common.py +244 -0
- algo_cli/intelligence/finance/construction.py +135 -0
- algo_cli/intelligence/finance/controls.py +172 -0
- algo_cli/intelligence/finance/evidence.py +119 -0
- algo_cli/intelligence/finance/exceptions.py +157 -0
- algo_cli/intelligence/finance/reconciliations.py +254 -0
- algo_cli/intelligence/finance/revenue.py +109 -0
- algo_cli/intelligence/finance/tax.py +74 -0
- algo_cli/intelligence/finance/workpapers.py +111 -0
- algo_cli/intelligence/finding_record.py +120 -0
- algo_cli/intelligence/flow_dag.py +267 -0
- algo_cli/intelligence/gatherer.py +223 -0
- algo_cli/intelligence/golden_master.py +98 -0
- algo_cli/intelligence/graph_rag.py +195 -0
- algo_cli/intelligence/group_chat.py +143 -0
- algo_cli/intelligence/hash_dedup.py +145 -0
- algo_cli/intelligence/hyperloglog.py +128 -0
- algo_cli/intelligence/incremental_index.py +316 -0
- algo_cli/intelligence/index_store.py +16 -0
- algo_cli/intelligence/iteration_plan.py +133 -0
- algo_cli/intelligence/kernel_plugins.py +167 -0
- algo_cli/intelligence/lesson_catalog.py +135 -0
- algo_cli/intelligence/llm_fallback.py +169 -0
- algo_cli/intelligence/log2_histogram.py +267 -0
- algo_cli/intelligence/lsp_integration.py +147 -0
- algo_cli/intelligence/memory_evolution.py +117 -0
- algo_cli/intelligence/minhash_lsh.py +182 -0
- algo_cli/intelligence/multi_model_score.py +174 -0
- algo_cli/intelligence/multi_tier_grade.py +211 -0
- algo_cli/intelligence/negative_controls.py +113 -0
- algo_cli/intelligence/numeric_clamp.py +63 -0
- algo_cli/intelligence/occ_editor.py +66 -0
- algo_cli/intelligence/output_normalize.py +112 -0
- algo_cli/intelligence/parallel_delegation.py +98 -0
- algo_cli/intelligence/parallel_fanout.py +104 -0
- algo_cli/intelligence/permission_modes.py +105 -0
- algo_cli/intelligence/pre_push_gate.py +68 -0
- algo_cli/intelligence/prefetch.py +171 -0
- algo_cli/intelligence/process_framework.py +217 -0
- algo_cli/intelligence/project_graph.py +387 -0
- algo_cli/intelligence/query_expansion.py +146 -0
- algo_cli/intelligence/ralph_loop.py +117 -0
- algo_cli/intelligence/rate_limiter.py +153 -0
- algo_cli/intelligence/refactor_transaction.py +94 -0
- algo_cli/intelligence/research_workspace.py +108 -0
- algo_cli/intelligence/retraction_ledger.py +72 -0
- algo_cli/intelligence/saga_pattern.py +88 -0
- algo_cli/intelligence/session_fork.py +100 -0
- algo_cli/intelligence/shadow_editor.py +67 -0
- algo_cli/intelligence/shell_session.py +213 -0
- algo_cli/intelligence/source_registry.py +143 -0
- algo_cli/intelligence/spawn_scales.py +99 -0
- algo_cli/intelligence/stat_stability.py +104 -0
- algo_cli/intelligence/structural_validator.py +148 -0
- algo_cli/intelligence/subagent_spawner.py +111 -0
- algo_cli/intelligence/symmetric_verify.py +70 -0
- algo_cli/intelligence/task_classifier.py +129 -0
- algo_cli/intelligence/team_execution.py +122 -0
- algo_cli/intelligence/tiered_access.py +121 -0
- algo_cli/intelligence/utility_registry.py +159 -0
- algo_cli/intuition_engine.py +560 -0
- algo_cli/intuition_injector.py +82 -0
- algo_cli/kernels/__init__.py +5 -0
- algo_cli/kernels/manifest.py +763 -0
- algo_cli/main.py +3903 -0
- algo_cli/memory_candidates.py +541 -0
- algo_cli/memory_echo_veil.py +394 -0
- algo_cli/memory_runtime.py +112 -0
- algo_cli/model_info.py +548 -0
- algo_cli/model_profile.py +160 -0
- algo_cli/model_routing.py +74 -0
- algo_cli/oneshot.py +331 -0
- algo_cli/perf_telemetry.py +389 -0
- algo_cli/plugins.py +245 -0
- algo_cli/private_event_store.py +654 -0
- algo_cli/quantization/__init__.py +24 -0
- algo_cli/quantization/lloyd_max.py +98 -0
- algo_cli/quantization/turbo_quant.py +308 -0
- algo_cli/reasoning/__init__.py +46 -0
- algo_cli/reasoning/combinatorial.py +356 -0
- algo_cli/reasoning/graph_of_thought.py +297 -0
- algo_cli/reasoning/mcts.py +220 -0
- algo_cli/reasoning/neuro_symbolic.py +250 -0
- algo_cli/reasoning/react.py +246 -0
- algo_cli/reasoning/reflexion.py +225 -0
- algo_cli/reasoning/tree_of_thought.py +241 -0
- algo_cli/reasoning_bridge.py +150 -0
- algo_cli/reconciliation.py +284 -0
- algo_cli/reflex.py +385 -0
- algo_cli/resources/docs/ALGO.md +13958 -0
- algo_cli/resources/docs/algo-cli-algorithm-evidence-contract.md +60 -0
- algo_cli/resources/docs/algo-cli-execution-verification-contract.md +59 -0
- algo_cli/resources/docs/algo-cli-memory-lifecycle-contract.md +72 -0
- algo_cli/resources/docs/harness-extension-cleanup-recommendation.md +41 -0
- algo_cli/resources/docs/index-compute-lab-integration.md +32 -0
- algo_cli/resources/docs/inference-harness-loop-blueprint-2026-06.md +55 -0
- algo_cli/resources/docs/main-split-map.md +35 -0
- algo_cli/resources/docs/privacy-and-context.md +48 -0
- algo_cli/resources/docs/reflex-loop-v0.2.md +354 -0
- algo_cli/resources/skills/README.md +26 -0
- algo_cli/resources/skills/algo-cli.md +59 -0
- algo_cli/resources/skills/edit-file-precision.md +49 -0
- algo_cli/resources/skills/harness-search-first.md +47 -0
- algo_cli/resources/skills/memory-recall-ritual.md +51 -0
- algo_cli/resources/skills/qol-algorithms.md +224 -0
- algo_cli/resources/skills/smart-error-recovery.md +56 -0
- algo_cli/resources/skills/tool-selection-cheatsheet.md +65 -0
- algo_cli/retrieval_algorithms.py +127 -0
- algo_cli/runtime_qos.py +236 -0
- algo_cli/runtime_services.py +320 -0
- algo_cli/session_commands.py +95 -0
- algo_cli/session_mode.py +113 -0
- algo_cli/skills.py +430 -0
- algo_cli/slash_dispatch.py +1265 -0
- algo_cli/small_context.py +206 -0
- algo_cli/spawn_budget.py +89 -0
- algo_cli/task_ledger.py +84 -0
- algo_cli/task_router.py +197 -0
- algo_cli/tool_context.py +94 -0
- algo_cli/tool_contract.py +99 -0
- algo_cli/tool_policy.py +357 -0
- algo_cli/tool_runtime.py +647 -0
- algo_cli/tools.py +3056 -0
- algo_cli/url_scheme.py +174 -0
- algo_cli/verify.py +154 -0
- algo_cli/version_manifest.py +178 -0
- algo_cli/vision_screenshot_verify.py +76 -0
- algo_cli/workspace_resolver.py +68 -0
- algo_cli/x_account.py +209 -0
- algo_cli/xai_auth.py +374 -0
- algo_cli/xai_client.py +600 -0
- algo_cli_runtime-0.14.0.dist-info/METADATA +369 -0
- algo_cli_runtime-0.14.0.dist-info/RECORD +237 -0
- algo_cli_runtime-0.14.0.dist-info/WHEEL +4 -0
- algo_cli_runtime-0.14.0.dist-info/entry_points.txt +3 -0
- algo_cli_runtime-0.14.0.dist-info/licenses/LICENSE +21 -0
- ollama_cli/__init__.py +67 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""Construction contracts / subcontracts / independent-contractor patterns B106-B126."""
|
|
2
|
+
|
|
3
|
+
from .labor_units import (
|
|
4
|
+
BUILDING_HEIGHT_FACTORS,
|
|
5
|
+
CONCEALED_FACTORS,
|
|
6
|
+
LADDER_HEIGHT_FACTORS,
|
|
7
|
+
LABOR_COMPOSITION,
|
|
8
|
+
REPETITIVE_FACTORS,
|
|
9
|
+
RESIDENTIAL_DEFAULTS,
|
|
10
|
+
ChartSituation,
|
|
11
|
+
CrewSizeEstimate,
|
|
12
|
+
LaborAdjustmentChart,
|
|
13
|
+
LaborFactorScoreSheet,
|
|
14
|
+
LaborUnit,
|
|
15
|
+
LaborUnitDatabase,
|
|
16
|
+
ScoreCondition,
|
|
17
|
+
SearchResult,
|
|
18
|
+
build_database,
|
|
19
|
+
building_height_adjustment,
|
|
20
|
+
crew_size_curve,
|
|
21
|
+
crew_size_straight_line,
|
|
22
|
+
difficulty_from_chart_score,
|
|
23
|
+
difficulty_from_score,
|
|
24
|
+
durand_core_multiplier,
|
|
25
|
+
durand_horizontal_setup_hours,
|
|
26
|
+
durand_vertical_multiplier,
|
|
27
|
+
ladder_height_adjustment,
|
|
28
|
+
non_working_supervision,
|
|
29
|
+
repetitive_adjustment,
|
|
30
|
+
residential_minutes,
|
|
31
|
+
)
|
|
32
|
+
from .common import (
|
|
33
|
+
ClauseHit,
|
|
34
|
+
ConstructionIssue,
|
|
35
|
+
Deadline,
|
|
36
|
+
Jurisdiction,
|
|
37
|
+
PatternResult,
|
|
38
|
+
ProjectType,
|
|
39
|
+
ProjectUse,
|
|
40
|
+
ReviewGate,
|
|
41
|
+
RiskLevel,
|
|
42
|
+
SourceRef,
|
|
43
|
+
add_business_days,
|
|
44
|
+
add_months_approx,
|
|
45
|
+
contains_any,
|
|
46
|
+
decimalize,
|
|
47
|
+
hash_source_bytes,
|
|
48
|
+
make_issue,
|
|
49
|
+
normalize_label,
|
|
50
|
+
normalize_space,
|
|
51
|
+
parse_date,
|
|
52
|
+
stable_issue_id,
|
|
53
|
+
)
|
|
54
|
+
from .documents import (
|
|
55
|
+
ContractDocument,
|
|
56
|
+
ContractDocumentGraph,
|
|
57
|
+
ContractDocumentGraphCompiler,
|
|
58
|
+
DelegatedDesignGate,
|
|
59
|
+
DelegatedDesignItem,
|
|
60
|
+
DelegatedDesignResult,
|
|
61
|
+
DisputeProtocol,
|
|
62
|
+
DisputeProtocolExtractor,
|
|
63
|
+
DocumentEdge,
|
|
64
|
+
FlowDownObligation,
|
|
65
|
+
FlowDownResult,
|
|
66
|
+
FlowDownRiskMapper,
|
|
67
|
+
LowerTierFlowdownPack,
|
|
68
|
+
LowerTierFlowdownResult,
|
|
69
|
+
LowerTierGap,
|
|
70
|
+
ScopeAtom,
|
|
71
|
+
ScopeMatrix,
|
|
72
|
+
ScopeMatrixBuilder,
|
|
73
|
+
ScopeStatus,
|
|
74
|
+
)
|
|
75
|
+
from .payments import (
|
|
76
|
+
ChangeEvent,
|
|
77
|
+
ChangeNotice,
|
|
78
|
+
ChangeNoticeEngine,
|
|
79
|
+
ChangeNoticeResult,
|
|
80
|
+
ContingentPaymentReview,
|
|
81
|
+
ContingentPaymentRiskGate,
|
|
82
|
+
ContingentPaymentType,
|
|
83
|
+
LienBondDeadlineCalendar,
|
|
84
|
+
LienWaiverClassifier,
|
|
85
|
+
LienWaiverReview,
|
|
86
|
+
PayApplication,
|
|
87
|
+
PaymentAnalysis,
|
|
88
|
+
PaymentRetainageAnalyzer,
|
|
89
|
+
RightsCalendar,
|
|
90
|
+
WaiverType,
|
|
91
|
+
)
|
|
92
|
+
from .risk import (
|
|
93
|
+
BackchargeDocumentationGate,
|
|
94
|
+
BackchargeReview,
|
|
95
|
+
ClassificationFactor,
|
|
96
|
+
CloseoutItem,
|
|
97
|
+
CloseoutMatrix,
|
|
98
|
+
ContractRedFlagQueue,
|
|
99
|
+
CoverageGap,
|
|
100
|
+
CureGate,
|
|
101
|
+
DelayAccelerationAnalyzer,
|
|
102
|
+
DelayAnalysis,
|
|
103
|
+
DelayEvent,
|
|
104
|
+
IndemnityInsuranceRiskSplitter,
|
|
105
|
+
IndemnityScope,
|
|
106
|
+
IndependentContractorClassifier,
|
|
107
|
+
InsuranceRequirement,
|
|
108
|
+
InsuranceRiskResult,
|
|
109
|
+
JurisdictionOverlayResult,
|
|
110
|
+
JurisdictionOverlayRouter,
|
|
111
|
+
OSHAEmployerRole,
|
|
112
|
+
OSHAMultiEmployerClassifier,
|
|
113
|
+
OnboardingCompliancePack,
|
|
114
|
+
OnboardingPackResult,
|
|
115
|
+
OnboardingRequirement,
|
|
116
|
+
OverlayRoute,
|
|
117
|
+
RedFlag,
|
|
118
|
+
RedFlagQueueResult,
|
|
119
|
+
SafetyEvent,
|
|
120
|
+
SafetyRoleResult,
|
|
121
|
+
TerminationDefaultGate,
|
|
122
|
+
TerminationMode,
|
|
123
|
+
WarrantyCloseoutMatrix,
|
|
124
|
+
WorkerClassificationResult,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
__all__ = [
|
|
128
|
+
"LaborUnit",
|
|
129
|
+
"LaborUnitDatabase",
|
|
130
|
+
"SearchResult",
|
|
131
|
+
"build_database",
|
|
132
|
+
"difficulty_from_score",
|
|
133
|
+
"difficulty_from_chart_score",
|
|
134
|
+
"building_height_adjustment",
|
|
135
|
+
"ladder_height_adjustment",
|
|
136
|
+
"repetitive_adjustment",
|
|
137
|
+
"residential_minutes",
|
|
138
|
+
"ChartSituation",
|
|
139
|
+
"CrewSizeEstimate",
|
|
140
|
+
"LaborAdjustmentChart",
|
|
141
|
+
"LaborFactorScoreSheet",
|
|
142
|
+
"ScoreCondition",
|
|
143
|
+
"crew_size_curve",
|
|
144
|
+
"crew_size_straight_line",
|
|
145
|
+
"durand_core_multiplier",
|
|
146
|
+
"durand_horizontal_setup_hours",
|
|
147
|
+
"durand_vertical_multiplier",
|
|
148
|
+
"non_working_supervision",
|
|
149
|
+
"BUILDING_HEIGHT_FACTORS",
|
|
150
|
+
"LADDER_HEIGHT_FACTORS",
|
|
151
|
+
"CONCEALED_FACTORS",
|
|
152
|
+
"REPETITIVE_FACTORS",
|
|
153
|
+
"LABOR_COMPOSITION",
|
|
154
|
+
"RESIDENTIAL_DEFAULTS",
|
|
155
|
+
"ClauseHit",
|
|
156
|
+
"ConstructionIssue",
|
|
157
|
+
"Deadline",
|
|
158
|
+
"Jurisdiction",
|
|
159
|
+
"PatternResult",
|
|
160
|
+
"ProjectType",
|
|
161
|
+
"ProjectUse",
|
|
162
|
+
"ReviewGate",
|
|
163
|
+
"RiskLevel",
|
|
164
|
+
"SourceRef",
|
|
165
|
+
"add_business_days",
|
|
166
|
+
"add_months_approx",
|
|
167
|
+
"contains_any",
|
|
168
|
+
"decimalize",
|
|
169
|
+
"hash_source_bytes",
|
|
170
|
+
"make_issue",
|
|
171
|
+
"normalize_label",
|
|
172
|
+
"normalize_space",
|
|
173
|
+
"parse_date",
|
|
174
|
+
"stable_issue_id",
|
|
175
|
+
"ContractDocument",
|
|
176
|
+
"ContractDocumentGraph",
|
|
177
|
+
"ContractDocumentGraphCompiler",
|
|
178
|
+
"DelegatedDesignGate",
|
|
179
|
+
"DelegatedDesignItem",
|
|
180
|
+
"DelegatedDesignResult",
|
|
181
|
+
"DisputeProtocol",
|
|
182
|
+
"DisputeProtocolExtractor",
|
|
183
|
+
"DocumentEdge",
|
|
184
|
+
"FlowDownObligation",
|
|
185
|
+
"FlowDownResult",
|
|
186
|
+
"FlowDownRiskMapper",
|
|
187
|
+
"LowerTierFlowdownPack",
|
|
188
|
+
"LowerTierFlowdownResult",
|
|
189
|
+
"LowerTierGap",
|
|
190
|
+
"ScopeAtom",
|
|
191
|
+
"ScopeMatrix",
|
|
192
|
+
"ScopeMatrixBuilder",
|
|
193
|
+
"ScopeStatus",
|
|
194
|
+
"ChangeEvent",
|
|
195
|
+
"ChangeNotice",
|
|
196
|
+
"ChangeNoticeEngine",
|
|
197
|
+
"ChangeNoticeResult",
|
|
198
|
+
"ContingentPaymentReview",
|
|
199
|
+
"ContingentPaymentRiskGate",
|
|
200
|
+
"ContingentPaymentType",
|
|
201
|
+
"LienBondDeadlineCalendar",
|
|
202
|
+
"LienWaiverClassifier",
|
|
203
|
+
"LienWaiverReview",
|
|
204
|
+
"PayApplication",
|
|
205
|
+
"PaymentAnalysis",
|
|
206
|
+
"PaymentRetainageAnalyzer",
|
|
207
|
+
"RightsCalendar",
|
|
208
|
+
"WaiverType",
|
|
209
|
+
"BackchargeDocumentationGate",
|
|
210
|
+
"BackchargeReview",
|
|
211
|
+
"ClassificationFactor",
|
|
212
|
+
"CloseoutItem",
|
|
213
|
+
"CloseoutMatrix",
|
|
214
|
+
"ContractRedFlagQueue",
|
|
215
|
+
"CoverageGap",
|
|
216
|
+
"CureGate",
|
|
217
|
+
"DelayAccelerationAnalyzer",
|
|
218
|
+
"DelayAnalysis",
|
|
219
|
+
"DelayEvent",
|
|
220
|
+
"IndemnityInsuranceRiskSplitter",
|
|
221
|
+
"IndemnityScope",
|
|
222
|
+
"IndependentContractorClassifier",
|
|
223
|
+
"InsuranceRequirement",
|
|
224
|
+
"InsuranceRiskResult",
|
|
225
|
+
"JurisdictionOverlayResult",
|
|
226
|
+
"JurisdictionOverlayRouter",
|
|
227
|
+
"OSHAEmployerRole",
|
|
228
|
+
"OSHAMultiEmployerClassifier",
|
|
229
|
+
"OnboardingCompliancePack",
|
|
230
|
+
"OnboardingPackResult",
|
|
231
|
+
"OnboardingRequirement",
|
|
232
|
+
"OverlayRoute",
|
|
233
|
+
"RedFlag",
|
|
234
|
+
"RedFlagQueueResult",
|
|
235
|
+
"SafetyEvent",
|
|
236
|
+
"SafetyRoleResult",
|
|
237
|
+
"TerminationDefaultGate",
|
|
238
|
+
"TerminationMode",
|
|
239
|
+
"WarrantyCloseoutMatrix",
|
|
240
|
+
"WorkerClassificationResult",
|
|
241
|
+
]
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"""Shared contracts for construction contract intelligence patterns B106-B126."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import re
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from datetime import date, datetime, timedelta
|
|
9
|
+
from decimal import Decimal, InvalidOperation
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from typing import Any, Iterable, Mapping
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RiskLevel(str, Enum):
|
|
15
|
+
"""Coarse risk levels used by construction contract analyzers."""
|
|
16
|
+
|
|
17
|
+
LOW = "low"
|
|
18
|
+
MEDIUM = "medium"
|
|
19
|
+
HIGH = "high"
|
|
20
|
+
CRITICAL = "critical"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ReviewGate(str, Enum):
|
|
24
|
+
"""Human-review gates for consequential construction-contract actions."""
|
|
25
|
+
|
|
26
|
+
NONE = "none"
|
|
27
|
+
BUSINESS_REVIEW = "business_review"
|
|
28
|
+
ATTORNEY_REVIEW = "attorney_review"
|
|
29
|
+
INSURANCE_REVIEW = "insurance_review"
|
|
30
|
+
TAX_HR_REVIEW = "tax_hr_review"
|
|
31
|
+
SAFETY_REVIEW = "safety_review"
|
|
32
|
+
STOP_EXTERNAL_ACTION = "stop_external_action"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ProjectType(str, Enum):
|
|
36
|
+
"""Project routing used for lien/bond/payment overlays."""
|
|
37
|
+
|
|
38
|
+
PRIVATE = "private"
|
|
39
|
+
PUBLIC = "public"
|
|
40
|
+
FEDERAL = "federal"
|
|
41
|
+
UNKNOWN = "unknown"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ProjectUse(str, Enum):
|
|
45
|
+
"""Commercial/residential routing where statutes differ."""
|
|
46
|
+
|
|
47
|
+
COMMERCIAL = "commercial"
|
|
48
|
+
RESIDENTIAL = "residential"
|
|
49
|
+
UNKNOWN = "unknown"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True)
|
|
53
|
+
class SourceRef:
|
|
54
|
+
"""Reference to a clause, document, row, or supporting artifact."""
|
|
55
|
+
|
|
56
|
+
document: str
|
|
57
|
+
clause: str | None = None
|
|
58
|
+
page: int | None = None
|
|
59
|
+
row: int | None = None
|
|
60
|
+
quote: str | None = None
|
|
61
|
+
url: str | None = None
|
|
62
|
+
document_hash: str | None = None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass(frozen=True)
|
|
66
|
+
class ConstructionIssue:
|
|
67
|
+
"""A contract issue/red flag produced by a pattern engine."""
|
|
68
|
+
|
|
69
|
+
id: str
|
|
70
|
+
pattern_id: str
|
|
71
|
+
title: str
|
|
72
|
+
message: str
|
|
73
|
+
risk_level: RiskLevel = RiskLevel.MEDIUM
|
|
74
|
+
review_gate: ReviewGate = ReviewGate.BUSINESS_REVIEW
|
|
75
|
+
source_refs: tuple[SourceRef, ...] = ()
|
|
76
|
+
tags: frozenset[str] = frozenset()
|
|
77
|
+
amount: Decimal | None = None
|
|
78
|
+
deadline: date | None = None
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def requires_human_review(self) -> bool:
|
|
82
|
+
return self.review_gate is not ReviewGate.NONE
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@dataclass(frozen=True)
|
|
86
|
+
class Jurisdiction:
|
|
87
|
+
"""State/project context for contract overlays."""
|
|
88
|
+
|
|
89
|
+
state: str | None = None
|
|
90
|
+
county: str | None = None
|
|
91
|
+
city: str | None = None
|
|
92
|
+
project_type: ProjectType = ProjectType.UNKNOWN
|
|
93
|
+
project_use: ProjectUse = ProjectUse.UNKNOWN
|
|
94
|
+
tier: str | None = None
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def normalized_state(self) -> str | None:
|
|
98
|
+
if not self.state:
|
|
99
|
+
return None
|
|
100
|
+
value = self.state.strip().upper()
|
|
101
|
+
aliases = {"KANSAS": "KS", "MISSOURI": "MO", "FEDERAL": "FEDERAL"}
|
|
102
|
+
return aliases.get(value, value)
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def is_kansas_private(self) -> bool:
|
|
106
|
+
return self.normalized_state == "KS" and self.project_type is ProjectType.PRIVATE
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def is_federal(self) -> bool:
|
|
110
|
+
return self.project_type is ProjectType.FEDERAL or self.normalized_state == "FEDERAL"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True)
|
|
114
|
+
class Deadline:
|
|
115
|
+
"""A computed review deadline. Not a legal deadline/sign-off."""
|
|
116
|
+
|
|
117
|
+
name: str
|
|
118
|
+
due_date: date
|
|
119
|
+
source: str
|
|
120
|
+
pattern_id: str
|
|
121
|
+
review_gate: ReviewGate = ReviewGate.ATTORNEY_REVIEW
|
|
122
|
+
confidence: str = "review"
|
|
123
|
+
notes: tuple[str, ...] = ()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass(frozen=True)
|
|
127
|
+
class ClauseHit:
|
|
128
|
+
"""A simple keyword/regex extraction hit."""
|
|
129
|
+
|
|
130
|
+
label: str
|
|
131
|
+
text: str
|
|
132
|
+
source_ref: SourceRef
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@dataclass
|
|
136
|
+
class PatternResult:
|
|
137
|
+
"""Generic result envelope for construction pattern engines."""
|
|
138
|
+
|
|
139
|
+
pattern_id: str
|
|
140
|
+
issues: list[ConstructionIssue] = field(default_factory=list)
|
|
141
|
+
source_refs: list[SourceRef] = field(default_factory=list)
|
|
142
|
+
review_gate: ReviewGate = ReviewGate.BUSINESS_REVIEW
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def requires_human_review(self) -> bool:
|
|
146
|
+
return self.review_gate is not ReviewGate.NONE or any(issue.requires_human_review for issue in self.issues)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def decimalize(value: Any, default: Decimal = Decimal("0")) -> Decimal:
|
|
150
|
+
"""Parse construction dollar/percent-ish numeric values safely."""
|
|
151
|
+
|
|
152
|
+
if value is None:
|
|
153
|
+
return default
|
|
154
|
+
if isinstance(value, Decimal):
|
|
155
|
+
return value
|
|
156
|
+
if isinstance(value, int):
|
|
157
|
+
return Decimal(value)
|
|
158
|
+
if isinstance(value, float):
|
|
159
|
+
return Decimal(str(value))
|
|
160
|
+
text = str(value).strip()
|
|
161
|
+
if not text:
|
|
162
|
+
return default
|
|
163
|
+
negative = text.startswith("(") and text.endswith(")")
|
|
164
|
+
text = text.strip("()")
|
|
165
|
+
text = text.replace("$", "").replace(",", "").replace("%", "")
|
|
166
|
+
try:
|
|
167
|
+
number = Decimal(text)
|
|
168
|
+
except (InvalidOperation, ValueError):
|
|
169
|
+
return default
|
|
170
|
+
return -number if negative else number
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def parse_date(value: Any) -> date | None:
|
|
174
|
+
"""Parse common date forms used in tests/imports."""
|
|
175
|
+
|
|
176
|
+
if value is None:
|
|
177
|
+
return None
|
|
178
|
+
if isinstance(value, date) and not isinstance(value, datetime):
|
|
179
|
+
return value
|
|
180
|
+
if isinstance(value, datetime):
|
|
181
|
+
return value.date()
|
|
182
|
+
text = str(value).strip()
|
|
183
|
+
if not text:
|
|
184
|
+
return None
|
|
185
|
+
for fmt in ("%Y-%m-%d", "%m/%d/%Y", "%m/%d/%y"):
|
|
186
|
+
try:
|
|
187
|
+
return datetime.strptime(text, fmt).date()
|
|
188
|
+
except ValueError:
|
|
189
|
+
continue
|
|
190
|
+
try:
|
|
191
|
+
return datetime.fromisoformat(text).date()
|
|
192
|
+
except ValueError:
|
|
193
|
+
return None
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def add_business_days(start: date, days: int) -> date:
|
|
197
|
+
"""Add business days, skipping Saturday/Sunday."""
|
|
198
|
+
|
|
199
|
+
current = start
|
|
200
|
+
remaining = days
|
|
201
|
+
step = 1 if days >= 0 else -1
|
|
202
|
+
while remaining:
|
|
203
|
+
current += timedelta(days=step)
|
|
204
|
+
if current.weekday() < 5:
|
|
205
|
+
remaining -= step
|
|
206
|
+
return current
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def add_months_approx(start: date, months: int) -> date:
|
|
210
|
+
"""Add months while clamping day to the target month length."""
|
|
211
|
+
|
|
212
|
+
month_index = start.month - 1 + months
|
|
213
|
+
year = start.year + month_index // 12
|
|
214
|
+
month = month_index % 12 + 1
|
|
215
|
+
month_lengths = [31, 29 if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
216
|
+
return date(year, month, min(start.day, month_lengths[month - 1]))
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def hash_source_bytes(data: bytes) -> str:
|
|
220
|
+
return hashlib.sha256(data).hexdigest()[:16]
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def normalize_space(text: str) -> str:
|
|
224
|
+
return re.sub(r"\s+", " ", text or "").strip()
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def normalize_label(text: str) -> str:
|
|
228
|
+
return re.sub(r"[^a-z0-9]+", "_", (text or "").strip().lower()).strip("_")
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def contains_any(text: str, terms: Iterable[str]) -> bool:
|
|
232
|
+
haystack = (text or "").lower()
|
|
233
|
+
return any(term.lower() in haystack for term in terms)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def stable_issue_id(pattern_id: str, *parts: object) -> str:
|
|
237
|
+
payload = "|".join(str(part) for part in (pattern_id, *parts))
|
|
238
|
+
return f"{pattern_id.lower()}-{hashlib.sha1(payload.encode('utf-8')).hexdigest()[:10]}"
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def make_issue(
|
|
242
|
+
pattern_id: str,
|
|
243
|
+
title: str,
|
|
244
|
+
message: str,
|
|
245
|
+
*,
|
|
246
|
+
risk_level: RiskLevel = RiskLevel.MEDIUM,
|
|
247
|
+
review_gate: ReviewGate = ReviewGate.BUSINESS_REVIEW,
|
|
248
|
+
source_refs: Iterable[SourceRef] = (),
|
|
249
|
+
tags: Iterable[str] = (),
|
|
250
|
+
amount: Decimal | str | int | None = None,
|
|
251
|
+
deadline: date | None = None,
|
|
252
|
+
) -> ConstructionIssue:
|
|
253
|
+
parsed_amount = decimalize(amount) if amount is not None else None
|
|
254
|
+
return ConstructionIssue(
|
|
255
|
+
id=stable_issue_id(pattern_id, title, message, deadline or ""),
|
|
256
|
+
pattern_id=pattern_id,
|
|
257
|
+
title=title,
|
|
258
|
+
message=message,
|
|
259
|
+
risk_level=risk_level,
|
|
260
|
+
review_gate=review_gate,
|
|
261
|
+
source_refs=tuple(source_refs),
|
|
262
|
+
tags=frozenset(tags),
|
|
263
|
+
amount=parsed_amount,
|
|
264
|
+
deadline=deadline,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def source_from_mapping(data: Mapping[str, Any], default_doc: str = "input") -> tuple[SourceRef, ...]:
|
|
269
|
+
refs = data.get("source_refs")
|
|
270
|
+
if refs:
|
|
271
|
+
return tuple(ref for ref in refs if isinstance(ref, SourceRef))
|
|
272
|
+
document = str(data.get("document") or default_doc)
|
|
273
|
+
return (SourceRef(document, clause=data.get("clause"), quote=data.get("text") or data.get("quote")),)
|