v0.68.0
feder-cr/invisible_dotsv0.68.0Sep 15, 2026by github-actions[bot]
Upgrading?
AI Summary
This release implements an automated gate to enforce dependency declarations in pyproject.toml, specifically catching missed transitive imports like pydantic and httpx. Additionally, it improves the /live/frame route logic to correctly determine service availability based on tool schema constraints rather than error sentence matching.
Key Highlights
- Implemented an automated gate to scan for undeclared imports in pyproject.toml.
- Fixed false positives in the dependency scan regarding optional imports and local module names.
- Updated the /live/frame route logic to choose between 204 and 503 status codes based on tool schema validation.
- Verified that all runtime dependencies are actually imported and scripts are called by workflows.
New Features
- Automated dependency declaration scanning (Gate) to catch transitive dependencies.
- Dynamic resolution of local module names for import scanning.
- Smart exemption for optional imports (e.g., packaging.markers) inside try/except blocks.
- Improved /live/frame route availability detection using tool schema validation.
Full Release Notes
pyproject.toml states this rule twice, in its own words, about three packages: python-dotenv is "declared rather than inherited ... a transitive dependency is one somebody else can drop in a minor release without telling us", and starlette and uvicorn are "declared even though mcp already pulls both in ... the day mcp stops needing them, the failure would otherwise land here". It was not applied to pydantic. src/aihawk/mcp/server.py says `from pydantic import Field` and nothing declared it: it arrives because mcp requires pydantic>=2.11,<3. The project knew the rule, wrote it down twice, and missed the third - which is the shape that asks for a gate on the class rather than a fourth careful sentence. WHY NOTHING COULD HAVE FOUND IT. Every environment that has mcp has pydantic, so the suite is green, the six matrix jobs are green, and a clean-environment check installing from the index is green too. The wheel is broken only in a future that has not happened yet, and when it does the traceback names pydantic while the cause is in somebody else's pyproject. httpx is the same defect in the test extra: the real-server test imports it and it was arriving through mcp. THE GATE IS ON THE CLASS. Every third-party module the package imports must be declared, and the same question is asked of the suite against the test extra. It was written before the fix and went red on the real state, naming pydantic and the file that imports it, which is the only way to know a gate can fail. AND AN IMPORT THAT DECLARES ITSELF OPTIONAL IS EXEMPT, which the same scan taught by being wrong. Run over the two sibling packages, it raised exactly one thing in shipped code: `from packaging.markers import Marker` in invisible_core, which is correct - inside a function, in a try that catches ImportError and answers "cannot tell", with a docstring saying packaging is not one of that package's runtime dependencies. The scan was wrong, not the line, and this gate had the same blind spot waiting for the first optional import anybody writes here. The exemption is the SHAPE of the code, not a name on a list, and both sides are held: guarded is left alone, the same module imported at module level is still caught. The first version of the gate also carried a hand-written list of local module names and was already wrong on its first run: it missed test_web_service, which another test imports by bare name under this suite's convention. The list is resolved from the tree now. A list of what a directory already says is a second declaration, which is the thing this release is about. What it does not see is written into it: an import through importlib with a computed name, and whether a floor is high enough, which only a resolver can answer. pytest-asyncio is correctly declared and correctly never imported, because a plugin is loaded by pytest rather than by code. THE 503 BRANCH OF /live/frame IS NOW CHOSEN BY THE SERVER. That route picks between 204 and 503 by asking whether the sentence a tool raised IS the not-open one, and only the yes was proven end to end: a comparison that answered "not open" to EVERYTHING passed the whole suite, which turns every real breakage into a silently idle pane. Reaching the other side without starting a browser costs nothing once you notice that `browser` is declared Literal["main", "support"], so a third value is refused by the tool's own schema and comes back as an error result that is not that sentence. Known-bad applied to the real route: the new test fails and the 204 one stays green, which is what should happen. WHAT WAS SCANNED AND IS CLEAN, recorded as measured negatives rather than assumptions. The six scripts in scripts/ are all invoked by workflows and carry no unreferenced top-level definition and no uncalled method. All eight runtime dependencies are genuinely imported by the package. AND ONE THING THIS AUDIT REPORTED THAT WAS FALSE. It listed mixed line endings as remaining debt. Measured on the index: 255 of 255 text files are LF only, zero CRLF, zero mixed, zero lines a renormalisation would rewrite. The working tree is CRLF because core.autocrlf is true on that machine, which is a property of a checkout and not of this repository. A claim carried over from a sibling repo without being measured, which is the error this audit exists to find, made by the audit. Suite 671 green from 664.
Related Repositories
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
Interactive roadmaps, guides and other educational content to help developers grow in their careers.
Reverse engineer anything with agents, from app behavior down to native binaries.
The open source coding agent.
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.