Skip to content

refactor(ticket-188): split poa planning god module into focused submodules (STARTER-736) - #372

Merged
ifuri-validator-agent[bot] merged 1 commit into
mainfrom
ticket/188-poa-planning-split
Sep 20, 2026
Merged

ifuri-validator-agent[bot] merged 1 commit into
mainfrom
ticket/188-poa-planning-split

Conversation

@tom-sapletta-com

Copy link
Copy Markdown
Contributor

Split the 511-line koru.poa.planning god module (4 classes, 15 functions) by responsibility: errors.py (planning failure hierarchy), validation.py (shared primitive validators), snapshots.py (source-registry snapshot build/validate), policy_decisions.py (policy-boundary input hash + decision validation), plan_compile.py (inert plan compilation, binding selection, process graph, result verification). planning.py remains a compatibility facade re-exporting the exact previous __all__, so koru.poa.planning, koru.poa and koru.poa.logs imports are unchanged. Pure code movement verified by AST equivalence; behavior, messages, decision order and hashes unchanged.

Ticket: ticket-188 (workstream: application, workflow state: PUBLICATION).
Planfile source: STARTER-736 (code2llm god-module).

Validation evidence (branch ticket/188-poa-planning-split, base origin/main = 24d901bf): recorded in project/ticket-188/README.md — AST equivalence vs base module (only 8 promoted helper names lose the underscore prefix), poa suites pass unmodified (22 passed), facade parity (11 planning.__all__ / 18 package __all__ names unchanged), ruff check/format clean, regenerated code2llm analysis has no GOD entries, ./project/governance-check.sh --base origin/main GOV-PASS.

…odules (STARTER-736)

code2llm flagged src/koru/poa/planning.py as a god module (511L, 4 classes,
15 functions). Split by responsibility into koru.poa submodules: errors.py
(failure hierarchy), validation.py (shared primitive validators),
snapshots.py (source-registry snapshot build/validate), policy_decisions.py
(policy-boundary input hash and decision validation), plan_compile.py (inert
plan compilation, binding selection, process graph, result verification).
planning.py stays a compatibility facade re-exporting the exact previous
__all__; pure code movement verified by AST equivalence (only the eight
promoted shared helpers lose their underscore prefix), so messages, decision
order and hashes are unchanged. poa suites pass unmodified (22 passed) and
the regenerated code2llm analysis reports no GOD entries.

@ifuri-validator-agent ifuri-validator-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validator approval after policy checks for exact head 0e220358d348855e85713ceb2e97cb6afe326b30.

Ticket: ticket-188
Correlation ID: local-semcod-koru-pr-372-ticket-188
Model: zai/glm-5.3
Reviewed diff chunks: 5
Advisory LLM verdict: APPROVE
Advisory summary: Reviewed all 5 diff chunk(s). Chunk 1 of 5 of a pure god-module split of koru/poa/planning.py. Visible code (README, intent., errors.py, and the beginning of plan_compile.py) is consistent with a behavior-preserving refactor: the error hierarchy is moved verbatim with a coherent all, and plan_compile.py's imports reflect the documented dependency order (errors -> validation -> snapshots -> policy_decisions) with no cycles. Protected check assessment shows both required checks (onedev/local-verify, standard packs / conformance) passing; remaining checks are observational/excluded and passing. Documentation claims (AST equivalence, facade parity, ruff clean, governance GOV-PASS) are backed by passing checks. | This chunk shows the mechanical split of the koru.poa.planning god module into focused submodules (plan_compile.py, planning.py facade). The visible code preserves prior behavior: identical validation order, error messages, hash construction, and the closed-contract checks in verify_planning_result. The facade re-exports the prior public surface. Required checks (onedev/local-verify, standard packs / conformance) both pass per the protected check assessment; no failed, missing, or required-skipped checks. No security concerns: no secret access, no workflow modification, no execution-boundary crossing (authorityGranted/executable forced False with verification). | This chunk shows the mechanical extraction of snapshot validation, policy decision validation, and inert plan compilation out of the former god module. All checks are lines removed from the original module; the code itself retains digest verification, secret rejection, policy-input binding, and validity-interval enforcement consistent with the stated pure-move refactor. Required checks (onedev/local-verify, standard packs / conformance) all pass per the protected assessment. | This chunk shows a mechanical decomposition of the planning module: planning.py loses its implementation and re-exports from the new plan_compile, policy_decisions, snapshots modules. Visible new code preserves the strict closed-contract validation patterns (field-set equality, canonical hash pinning, execution-authority denials, secret-material rejection, deepcopy before digest). Required checks (standard packs / conformance, onedev/local-verify) all pass; AST equivalence and facade parity are claimed in the PR evidence. | This chunk contains the new snapshots.py and validation.py modules extracted from the planning god module. The code performs defensive deep copies of untrusted inputs, enforces canonical-hash integrity (snapshot and per-response digests), validates timestamps, dedupes resolutions/sources/bindings, and closes candidate provenance over discovered sources. Regex validators are anchored and reject non-string inputs. Required checks (onedev/local-verify, standard packs/conformance) all pass; the compatibility facade preserves public API per PR description.
Advisory findings: none
The LLM output above is advisory and was not used as the approval trust root.
Semantic review prerequisite: not_required; policy 676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7.

Actual PR impact radar

Exact range: 24d901bf519d107fee78b2691224d2dfee9c2c95...0e220358d348855e85713ceb2e97cb6afe326b30
Change digest: 84f78c29305fb0dfe8b7e60282d01032b4f1dc06e7c8ce9a0fdf7576f4426763
Score: 68/100 (L), estimated 114 min, split recommended: true
Affected services/components: repository-wide/unclassified

Machine-readable radar JSONL and SVG
{"actual_change":{"additions":801,"base_sha":"24d901bf519d107fee78b2691224d2dfee9c2c95","binary_files":0,"categories":{"code":6,"configuration":1,"docs":1},"change_digest":"84f78c29305fb0dfe8b7e60282d01032b4f1dc06e7c8ce9a0fdf7576f4426763","comparison":"24d901bf519d107fee78b2691224d2dfee9c2c95...0e220358d348855e85713ceb2e97cb6afe326b30","deletions":493,"file_count":8,"files":["project/ticket-188/README.md","project/ticket-188/intent.json","src/koru/poa/errors.py","src/koru/poa/plan_compile.py","src/koru/poa/planning.py","src/koru/poa/policy_decisions.py","src/koru/poa/snapshots.py","src/koru/poa/validation.py"],"head_sha":"0e220358d348855e85713ceb2e97cb6afe326b30","service_count":0,"services":[]},"assessment_mode":"observed-pr","axes":{"coupling":5,"delivery":3,"scope":5,"uncertainty":3,"validation":1},"complexity":"L","confidence":0.9,"diagnostics":["RADAR-ACCEPTANCE-MISSING","RADAR-BUDGET-EXCEEDED"],"estimate":{"budget_minutes":30,"minutes":114,"within_budget":false},"impact":{"components":["build","check","origin","project","src/koru","ticket"],"files":["build/validate","check/format","origin/main","project/governance-check.sh","project/ticket-188/README.md","project/ticket-188/intent.json","src/koru/poa/errors.py","src/koru/poa/plan_compile.py","src/koru/poa/planning.py","src/koru/poa/policy_decisions.py","src/koru/poa/snapshots.py","src/koru/poa/validation.py","ticket/188-poa-planning-split"],"public_interfaces":[],"runtime_dependencies":1},"schema":"subactor.ticket-radar/v1","score":68,"split":{"parts":[{"estimated_minutes":18,"name":"Implement build","scope":["build"]},{"estimated_minutes":18,"name":"Implement check","scope":["check"]},{"estimated_minutes":18,"name":"Implement origin","scope":["origin"]},{"estimated_minutes":18,"name":"Implement project","scope":["project"]},{"estimated_minutes":18,"name":"Implement src/koru","scope":["src/koru"]},{"estimated_minutes":15,"name":"Validate and project to trackers","scope":["tests","planfile","github/gitlab/jira projections"]}],"reason":"estimated_minutes_exceed_budget","recommended":true},"standards":[{"id":"wellmanifest/dsl","revision":"6c60fc4e0dd1f1bb74f46a7745e28019908d1203","version":"0.1.0-dev"},{"id":"wellmanifest/ticket-lifecycle","revision":"5bf581907a87b46a13a73e6c033d3abe4d9a306f","version":"0.1.0-dev"},{"id":"wellmanifest/git-lifecycle","revision":"7d77d4b7af57e69bc75c3a0290b3a4805c5c4438","version":"0.2.0-dev"},{"id":"wellmanifest/logs","revision":"48c284ef7a069055c0bcb6b900147ce5e65f8b43","version":"0.3.0"}],"ticket_ref":"ticket-188"}
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img"><title>ticket-188: refactor(ticket-188): split poa planning god module into focused submodules (STARTER-736)</title><rect width="128" height="128" rx="12" fill="#f8fafc"/><g stroke-width="1"><polygon points="64,55 72,61 69,71 59,71 56,61" fill="none" stroke="#d7dde5"/><polygon points="64,47 80,59 74,78 54,78 48,59" fill="none" stroke="#d7dde5"/><polygon points="64,38 89,56 79,85 49,85 39,56" fill="none" stroke="#d7dde5"/><polygon points="64,30 97,53 84,92 44,92 31,53" fill="none" stroke="#d7dde5"/><polygon points="64,21 105,51 89,99 39,99 23,51" fill="none" stroke="#d7dde5"/><line x1="64" y1="64" x2="64" y2="21" stroke="#aab4c0"/><line x1="64" y1="64" x2="105" y2="51" stroke="#aab4c0"/><line x1="64" y1="64" x2="89" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="39" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="23" y2="51" stroke="#aab4c0"/></g><polygon points="64,21 105,51 79,85 59,71 39,56" fill="#fb923c" fill-opacity="0.45" stroke="#c2410c" stroke-width="2"/><circle cx="64" cy="64" r="3" fill="#c2410c"/><g font-family="sans-serif" font-size="7" fill="#334155"><text x="64" y="11" text-anchor="middle">SCO</text><text x="114" y="48" text-anchor="middle">COU</text><text x="95" y="107" text-anchor="middle">UNC</text><text x="33" y="107" text-anchor="middle">VAL</text><text x="14" y="48" text-anchor="middle">DEL</text></g><text x="64" y="124" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#0f172a">L · 114m</text></svg>
Merge will be attempted after this approval when explicitly authorized. ## Decision record (recomputable)
DECISION D-188-7694
TICKET ticket-188
HEAD_SHA 0e220358d348855e85713ceb2e97cb6afe326b30
CORRELATION_ID local-semcod-koru-pr-372-ticket-188
ACTOR agent:ifuri-validator-agent[bot]
APPLIED_RULE P-CORE-015
INPUT author_login = "tom-sapletta-com"
INPUT observed_checks = ["standard packs / conformance=PASS","governance / remote lifecycle=PASS","governance / enforce=PASS","onedev/local-verify=PASS"]
INPUT required_checks = ["onedev/local-verify","standard packs / conformance"]
INPUT required_checks_source = "protected registry + GitHub applied rules (env/request)"
INPUT reviewer_login = "ifuri-validator-agent[bot]"
INPUT semantic_review_assessment = {"schema":"subactor.validator/semantic-review-assessment/v1","subject":{"repository":"semcod/koru","pull_request":372,"head_sha":"0e220358d348855e85713ceb2e97cb6afe326b30","base_sha":"24d901bf519d107fee78b2691224d2dfee9c2c95","diff_sha256":"53011280a5eca6ffb6945d40c409d9092d4c14ccf37905be647151620d78de99"},"policy":{"policy_schema":"subactor.validator/semantic-review-policy/v1","policy_version":1,"policy_sha256":"676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7","required":false,"critical_paths":[],"observed_paths":["project/ticket-188/README.md","project/ticket-188/intent.json","src/koru/poa/errors.py","src/koru/poa/plan_compile.py","src/koru/poa/planning.py","src/koru/poa/policy_decisions.py","src/koru/poa/snapshots.py","src/koru/poa/validation.py"]},"grounding":"full-diff-not-per-finding-proof","execution_authority":false,"status":"not_required","reason":null,"review_sha256":null,"unresolved":[]}
INPUT superseded_checks = ["smoke"]
INPUT ticket_radar_receipt = {"schema":"subactor.ticket-radar/v1","base_sha":"24d901bf519d107fee78b2691224d2dfee9c2c95","head_sha":"0e220358d348855e85713ceb2e97cb6afe326b30","change_digest":"84f78c29305fb0dfe8b7e60282d01032b4f1dc06e7c8ce9a0fdf7576f4426763","score":68,"complexity":"L","estimated_minutes":114,"split_recommended":true,"services":[],"authority":"ADVISORY","promotion":"FORBIDDEN"}
VERDICT APPROVE AUTHORITY DETERMINISTIC
REJECTED REQUEST_CHANGES BECAUSE NO_UNSAFE_CHANGE_REASON_FOUND
ADVISORY llm_verdict = "APPROVE" MODEL "zai/glm-5.3"
ASSERT VERDICT_AUTHORITY != "ADVISORY"

@ifuri-validator-agent
ifuri-validator-agent Bot merged commit 0f60955 into main Sep 20, 2026
5 checks passed
@ifuri-validator-agent
ifuri-validator-agent Bot deleted the ticket/188-poa-planning-split branch September 20, 2026 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant