feat(installsurface): VC-002L Python import-time analyzer (facts-only, unwired) - #138
Merged
Merged
Conversation
…, unwired) Land the analyzer half of VC-002L per docs/VC-002L-python-import-time.md, mirroring how VC-013 staged its analyzer before any check/ecosystem wiring. Closes the coverage gap named in D-165: a payload in an ordinary runtime module (the telnyx/_client.py shape) that runs on import, which no install-hook analyzer sees. AnalyzePythonLoadTime scans a package's own modules for import-time-reachable code carrying an escalating capability. Reachability follows module-level statements plus the bodies of functions CALLED at module level (one level deep), excluding uncalled helpers, class bodies, and __main__ guards — so the telnyx shape (payload in called functions) is caught while benign helpers are not. Reuses scanCaps and the D-25/D-160 strip pipeline; bounded by maxLoadTimeRefs with disclosed truncation; zero-execution (D-04). The emit gate requires a capability COMBINATION the VC-002 family acts on (decode+exec, credential+network, cradle, named-credential read), not bare exec/network — tighter than the spec's §5, deferring bare signals to the §7 corpus eval. This is what keeps the seven benign false-positive controls clean. Facts-only: the analyzer has no callers and is not in the check registry, so no detection, scope, or gate behavior changes. Deferred to the wiring phase: sdist module enumeration, adapter wiring, and a dedicated VC-002L check at an advisory ceiling (the block-class conflict with D-165 is documented in the spec). Tests (pyloadtime_test.go): 4 malicious (incl. telnyx called-function shape + reachability pair), 7 benign FP controls, disclosed module bound. go test ./... green, vet clean, build ok. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Land the analyzer half of VC-002L (
docs/VC-002L-python-import-time.md), closing the coverage gap named in D-165: a payload injected into an ordinary Python runtime module — the telnyx_client.pyshape — runs onimportand is invisible to every install-hook analyzer (setup.py/pyproject/.pth). Staged analyzer-first, exactly as VC-013 was.Changes
internal/installsurface/pyloadtime.go—AnalyzePythonLoadTime: scans a package's own modules for import-time-reachable code carrying an escalating capability.if __name__ == "__main__":. This is what catches the telnyx shape (payload in called functions) without flagging benign helpers.loadTimeEscalates): fires only on a capability combination the VC-002 family acts on — decode+exec, credential+network, cradle, or a named-credential read — not bareexec/network(tighter than the spec's §5; bare signals deferred to §7 corpus eval).scanCaps+ the D-25/D-160 strip pipeline; bounded bymaxLoadTimeRefswith disclosed truncation; zero-execution (D-04).internal/installsurface/pyloadtime_test.go— corpus test: 4 malicious (incl. telnyx called-function shape + the reachability pair), 7 benign false-positive controls, disclosed bound.docs/VC-002L-python-import-time.md— status → "analyzer prototype landed"; documents what's deferred and the block-class/advisory design decision.Security semantics
No detection, scope, or gate change. The analyzer has no callers and is not in the check registry — it produces facts nothing acts on. Existing checks are untouched.
Adversarial / FP review
The benign corpus (env read, embedded-data decode with no exec, subprocess capability probe, plugin registry, uncalled malicious helper,
__main__-guarded payload) all produce zero hooks. The reachability pair asserts the same body is detected when called and ignored when not.Validation
go test ./...all pass ·go vetclean ·go buildok · new files gofmt-clean · confirmed unwired (no VC-002L indepsnort checks).Remaining limitations / follow-on (the wiring phase)
sdist module enumeration (hostile-input change to
sdist.go), adapter wiring, and a dedicatedVC-002Lcheck at an advisory ceiling + exclusion ofmodule-load:hooks from the block-class family members. One-level reachability andscanCaps's split-string blind spot are documented lower bounds.🤖 Generated with Claude Code