sourcecode 2.3.0__py3-none-any.whl → 2.5.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.
@@ -0,0 +1,297 @@
1
+ """QueryPlanner — translate a ResolvedIntent into a declarative KnowledgeQuery
2
+ (design §4.3). It PLANS only: it never executes and never reads the graph.
3
+
4
+ One entry per intent in the plan registry. Adding an intent adds a plan builder here
5
+ (plus the enum member and a resolver strategy); the executor is untouched whenever the
6
+ plan is composed of existing steps — which is the Phase-2 extensibility contract.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from typing import Callable
11
+
12
+ from sourcecode.retrieval.errors import UnknownIntentError
13
+ from sourcecode.retrieval.query import (
14
+ BuildResult,
15
+ Characterize,
16
+ CollectEvidence,
17
+ CollectImpactEvidence,
18
+ ComputeBlastRadius,
19
+ KnowledgeQuery,
20
+ RankByRisk,
21
+ RankByScore,
22
+ ResolveDependents,
23
+ ResolveEndpoints,
24
+ ResolveIntegrations,
25
+ ResolveModules,
26
+ ResolvePropagation,
27
+ ResolveSecurityChain,
28
+ ResolveSecuritySurface,
29
+ ResolveTarget,
30
+ ResolveTransactionEntrypoints,
31
+ ResolveTransactionFlow,
32
+ ResolveTransactions,
33
+ ResolveValidationPoints,
34
+ RankByCriticality,
35
+ CollectSecurityEvidence,
36
+ ResolveEndpointInventory,
37
+ ResolveIntegrationInventory,
38
+ ResolveEventTopology,
39
+ CollectInterfaceEvidence,
40
+ ResolveScope,
41
+ ResolveSubsystemInventory,
42
+ ResolveSubsystemMembers,
43
+ ResolveModuleDependents,
44
+ ResolveModuleDependencies,
45
+ ResolveTypeDependents,
46
+ CollectStructureEvidence,
47
+ ResolveEndpointRef,
48
+ ResolveEndpointContract,
49
+ ResolveEndpointSecurity,
50
+ ResolveCallNeighborhood,
51
+ CollectEndpointEvidence,
52
+ ResolveExecutionPaths,
53
+ ResolveTransactionsReaching,
54
+ ResolveSubsystemCoupling,
55
+ CollectGraphEvidence,
56
+ Step,
57
+ )
58
+ from sourcecode.retrieval.request import RetrievalIntent
59
+ from sourcecode.retrieval.resolution import ResolvedIntent
60
+
61
+
62
+ class QueryPlanner:
63
+ """Maps `ResolvedIntent → KnowledgeQuery`."""
64
+
65
+ def __init__(self) -> None:
66
+ # Both architecture intents share ONE plan shape, differing only in the archetype
67
+ # dimension — the clearest demonstration that a new intent is a new *plan*, not
68
+ # new runtime. Adding a further intent is another entry here; nothing else.
69
+ self._plans: dict[RetrievalIntent, Callable[[ResolvedIntent], KnowledgeQuery]] = {
70
+ RetrievalIntent.ARCHITECTURAL_CORE: lambda r: self._characterization_plan(
71
+ r, "software_archetype"
72
+ ),
73
+ RetrievalIntent.ARCHITECTURAL_STYLE: lambda r: self._characterization_plan(
74
+ r, "architectural_style"
75
+ ),
76
+ RetrievalIntent.DEPLOYMENT_SHAPE: lambda r: self._characterization_plan(
77
+ r, "deployment_shape"
78
+ ),
79
+ RetrievalIntent.PRIMARY_INTERFACE: lambda r: self._characterization_plan(
80
+ r, "primary_interface"
81
+ ),
82
+ # IMPACT pack — each intent is a distinct COMPOSITION of shared steps. The
83
+ # projection step (in the middle) is the only difference between four of them.
84
+ RetrievalIntent.BLAST_RADIUS: lambda r: self._impact_plan(
85
+ r, ResolveDependents(), rank=True
86
+ ),
87
+ RetrievalIntent.AFFECTED_ENDPOINTS: lambda r: self._impact_plan(r, ResolveEndpoints()),
88
+ RetrievalIntent.AFFECTED_INTEGRATIONS: lambda r: self._impact_plan(
89
+ r, ResolveIntegrations()
90
+ ),
91
+ RetrievalIntent.TRANSACTION_BOUNDARIES: lambda r: self._impact_plan(
92
+ r, ResolveTransactions()
93
+ ),
94
+ RetrievalIntent.CROSS_MODULE_IMPACT: lambda r: self._impact_plan(r, ResolveModules()),
95
+ # TRANSACTIONS & SECURITY pack — each intent is a projection step + the shared
96
+ # RankByCriticality → CollectSecurityEvidence → BuildResult tail. SECURITY_CHAIN
97
+ # additionally reuses the impact pack's ResolveTarget (cross-pack step reuse).
98
+ RetrievalIntent.TRANSACTION_FLOW: lambda r: self._txsec_plan(r, ResolveTransactionFlow()),
99
+ RetrievalIntent.TRANSACTION_ENTRYPOINTS: lambda r: self._txsec_plan(
100
+ r, ResolveTransactionEntrypoints()
101
+ ),
102
+ RetrievalIntent.TRANSACTION_PROPAGATION: lambda r: self._txsec_plan(r, ResolvePropagation()),
103
+ RetrievalIntent.SECURITY_SURFACE: lambda r: self._txsec_plan(r, ResolveSecuritySurface()),
104
+ RetrievalIntent.SECURITY_CHAIN: lambda r: self._txsec_plan(
105
+ r, ResolveSecurityChain(), target=True
106
+ ),
107
+ RetrievalIntent.VALIDATION_POINTS: lambda r: self._txsec_plan(r, ResolveValidationPoints()),
108
+ # INTERFACES & INTEGRATIONS pack — whole-repo inventories. Each intent is a
109
+ # single projection step + the shared CollectInterfaceEvidence → BuildResult
110
+ # tail. No target, no ranking (inventories are deterministically ordered).
111
+ RetrievalIntent.ENDPOINT_INVENTORY: lambda r: self._interface_plan(
112
+ r, ResolveEndpointInventory()
113
+ ),
114
+ RetrievalIntent.INTEGRATION_INVENTORY: lambda r: self._interface_plan(
115
+ r, ResolveIntegrationInventory()
116
+ ),
117
+ RetrievalIntent.EVENT_TOPOLOGY: lambda r: self._interface_plan(r, ResolveEventTopology()),
118
+ # SUBSYSTEMS & DEPENDENCIES pack — inventory is whole-repo; members/dependents/
119
+ # dependencies are scoped, prepending the shared ResolveScope. Each intent is a
120
+ # single projection + the shared CollectStructureEvidence → BuildResult tail.
121
+ RetrievalIntent.SUBSYSTEM_INVENTORY: lambda r: self._structure_plan(
122
+ r, ResolveSubsystemInventory()
123
+ ),
124
+ RetrievalIntent.SUBSYSTEM_MEMBERS: lambda r: self._structure_plan(
125
+ r, ResolveSubsystemMembers(), scope=True
126
+ ),
127
+ RetrievalIntent.MODULE_DEPENDENTS: lambda r: self._structure_plan(
128
+ r, ResolveModuleDependents(), scope=True
129
+ ),
130
+ RetrievalIntent.MODULE_DEPENDENCIES: lambda r: self._structure_plan(
131
+ r, ResolveModuleDependencies(), scope=True
132
+ ),
133
+ # TYPE_DEPENDENTS is symbol-scoped: it reuses the impact pack's ResolveTarget
134
+ # head (cross-pack step reuse) instead of ResolveScope.
135
+ RetrievalIntent.TYPE_DEPENDENTS: lambda r: self._structure_plan(
136
+ r, ResolveTypeDependents(), head=ResolveTarget()
137
+ ),
138
+ # ENDPOINT & CALL deep-dive pack — endpoint-scoped intents bind via the shared
139
+ # ResolveEndpointRef; call-neighborhood reuses the impact pack's ResolveTarget.
140
+ RetrievalIntent.ENDPOINT_CONTRACT: lambda r: self._endpoint_plan(
141
+ r, ResolveEndpointContract(), head=ResolveEndpointRef()
142
+ ),
143
+ RetrievalIntent.ENDPOINT_SECURITY: lambda r: self._endpoint_plan(
144
+ r, ResolveEndpointSecurity(), head=ResolveEndpointRef()
145
+ ),
146
+ RetrievalIntent.CALL_NEIGHBORHOOD: lambda r: self._endpoint_plan(
147
+ r, ResolveCallNeighborhood(), head=ResolveTarget()
148
+ ),
149
+ # GRAPH-analysis pack — the symbol-scoped intents reuse the impact pack's
150
+ # ResolveTarget head; subsystem-coupling is whole-repo.
151
+ RetrievalIntent.EXECUTION_PATHS_THROUGH: lambda r: self._graph_plan(
152
+ r, ResolveExecutionPaths(), head=ResolveTarget()
153
+ ),
154
+ RetrievalIntent.TRANSACTIONS_REACHING: lambda r: self._graph_plan(
155
+ r, ResolveTransactionsReaching(), head=ResolveTarget()
156
+ ),
157
+ RetrievalIntent.SUBSYSTEM_COUPLING: lambda r: self._graph_plan(
158
+ r, ResolveSubsystemCoupling()
159
+ ),
160
+ }
161
+
162
+ def plan(self, resolved: ResolvedIntent) -> KnowledgeQuery:
163
+ builder = self._plans.get(resolved.intent)
164
+ if builder is None:
165
+ raise UnknownIntentError(f"no plan for intent {resolved.intent!r}")
166
+ return builder(resolved)
167
+
168
+ # ── plans ────────────────────────────────────────────────────────────────────
169
+ @staticmethod
170
+ def _characterization_plan(resolved: ResolvedIntent, dimension: str) -> KnowledgeQuery:
171
+ """Characterize one archetype dimension, rank candidates by the engine's own
172
+ scores, collect the winning evidence + graph-topology observations, and build the
173
+ typed result. Pure composition of existing capabilities."""
174
+ return KnowledgeQuery(
175
+ intent=resolved.intent,
176
+ steps=(
177
+ Characterize(dimension=dimension),
178
+ RankByScore(),
179
+ CollectEvidence(),
180
+ BuildResult(),
181
+ ),
182
+ )
183
+
184
+ @staticmethod
185
+ def _impact_plan(
186
+ resolved: ResolvedIntent, projection: Step, *, rank: bool = False
187
+ ) -> KnowledgeQuery:
188
+ """Resolve the target, run the blast engine ONCE, project the requested slice,
189
+ (optionally rank by risk), collect evidence, build the result. Every impact intent
190
+ is this shape with a different `projection` step — the reuse the pack demonstrates."""
191
+ middle: tuple[Step, ...] = (projection, RankByRisk()) if rank else (projection,)
192
+ return KnowledgeQuery(
193
+ intent=resolved.intent,
194
+ steps=(
195
+ ResolveTarget(),
196
+ ComputeBlastRadius(),
197
+ *middle,
198
+ CollectImpactEvidence(),
199
+ BuildResult(),
200
+ ),
201
+ )
202
+
203
+ @staticmethod
204
+ def _txsec_plan(
205
+ resolved: ResolvedIntent, projection: Step, *, target: bool = False
206
+ ) -> KnowledgeQuery:
207
+ """Project a transactions/security question from an existing engine, rank by the
208
+ engine's own criticality, collect evidence, build the result. Every tx/security
209
+ intent is this shape with a different `projection`; `target=True` prepends the
210
+ shared ResolveTarget for scoped intents (SECURITY_CHAIN)."""
211
+ head: tuple[Step, ...] = (ResolveTarget(),) if target else ()
212
+ return KnowledgeQuery(
213
+ intent=resolved.intent,
214
+ steps=(
215
+ *head,
216
+ projection,
217
+ RankByCriticality(),
218
+ CollectSecurityEvidence(),
219
+ BuildResult(),
220
+ ),
221
+ )
222
+
223
+ @staticmethod
224
+ def _interface_plan(resolved: ResolvedIntent, projection: Step) -> KnowledgeQuery:
225
+ """Project a whole-repo interfaces/integrations inventory from an existing engine,
226
+ collect evidence, build the result. Every intent in the pack is this shape with a
227
+ different `projection` — the reuse the pack demonstrates."""
228
+ return KnowledgeQuery(
229
+ intent=resolved.intent,
230
+ steps=(
231
+ projection,
232
+ CollectInterfaceEvidence(),
233
+ BuildResult(),
234
+ ),
235
+ )
236
+
237
+ @staticmethod
238
+ def _structure_plan(
239
+ resolved: ResolvedIntent,
240
+ projection: Step,
241
+ *,
242
+ scope: bool = False,
243
+ head: Step | None = None,
244
+ ) -> KnowledgeQuery:
245
+ """Project a subsystems/dependencies question from the repo_ir subsystem partition
246
+ or the module graph, collect evidence, build the result. `scope=True` prepends the
247
+ shared ResolveScope; `head` supplies an explicit binding step (e.g. the impact
248
+ pack's ResolveTarget for the symbol-scoped TYPE_DEPENDENTS)."""
249
+ head_steps: tuple[Step, ...]
250
+ if head is not None:
251
+ head_steps = (head,)
252
+ elif scope:
253
+ head_steps = (ResolveScope(),)
254
+ else:
255
+ head_steps = ()
256
+ return KnowledgeQuery(
257
+ intent=resolved.intent,
258
+ steps=(
259
+ *head_steps,
260
+ projection,
261
+ CollectStructureEvidence(),
262
+ BuildResult(),
263
+ ),
264
+ )
265
+
266
+ @staticmethod
267
+ def _graph_plan(
268
+ resolved: ResolvedIntent, projection: Step, *, head: Step | None = None
269
+ ) -> KnowledgeQuery:
270
+ """Project a graph-analysis question from an existing engine (Spring call chain,
271
+ tx index, module graph), collect evidence, build the result. `head` supplies the
272
+ symbol binder (ResolveTarget) for the scoped intents; subsystem-coupling has none."""
273
+ head_steps: tuple[Step, ...] = (head,) if head is not None else ()
274
+ return KnowledgeQuery(
275
+ intent=resolved.intent,
276
+ steps=(
277
+ *head_steps,
278
+ projection,
279
+ CollectGraphEvidence(),
280
+ BuildResult(),
281
+ ),
282
+ )
283
+
284
+ @staticmethod
285
+ def _endpoint_plan(resolved: ResolvedIntent, projection: Step, *, head: Step) -> KnowledgeQuery:
286
+ """Bind an endpoint/symbol reference, project the scoped contract / security / call
287
+ neighborhood from an existing engine, collect evidence, build the result. Every
288
+ intent in the pack is this shape with a different `head` binder + `projection`."""
289
+ return KnowledgeQuery(
290
+ intent=resolved.intent,
291
+ steps=(
292
+ head,
293
+ projection,
294
+ CollectEndpointEvidence(),
295
+ BuildResult(),
296
+ ),
297
+ )