| Version | Supported |
|---|---|
| 0.1.x development line (latest source checkout) | Yes |
StrucIn has not yet been published on PyPI. Fixes listed under Unreleased in
CHANGELOG.md require an updated source checkout; older copies do
not acquire those fixes automatically.
StrucIn analyzes Python source without importing or executing the target project:
- It reads Python files and parses their AST.
- Commands write or replace generated JSON, Markdown, and dashboard files.
- StrucIn-managed cache files are stored in
.strucin_cache/within the target repository. - Normal repository commands remove expired configured outputs and cache files
before running.
[lifecycle] cache_retention_daysdefaults to 14 and applies to both outputs and caches. Keep archival snapshots at separate paths.
Normal-mode analysis and dashboard exports contain identifiers, paths, and docstrings. Semantic indexes also store source/document chunks alongside their vectors. Treat those files as repository content when deciding what to share; use safe mode for anonymized exports.
Python and documentation discovery skips file links that resolve outside the selected repository, dangling links, symlink loops, and non-regular files. Links to regular files inside the repository remain supported, with their repository-relative link paths preserved in analysis and search results. Directory links are not traversed during discovery.
Containment is rechecked whenever source or documentation bytes are read. On
platforms supporting descriptor-relative opens and O_NOFOLLOW, path components
are opened without following links to reject replacements between validation and
reading. Other platforms use the validated canonical path. A file that becomes
unsafe after discovery aborts that run instead of contributing outside content.
Search indexes produced before this policy are rebuilt by the CLI. Existing exports are not retroactively scrubbed; regenerate any previously shared analysis, reports, or indexes that may have included outside links.
Configured outputs and StrucIn-managed caches must stay within the target repository.
Parent-directory segments (..) and symlinks that resolve outside that directory
are rejected before writing or cleaning up artifacts. All configured destinations
are checked before cleanup deletes any stale files.
The explicit web --out /path/to/export option selects a separate dashboard output
directory. Generated dashboard files are confined to that selected directory.
explain can call a provider when its SDK is installed and its API key is present
in the process environment. Anthropic is checked first, then OpenAI. A cached
result can avoid the call; unavailable providers or failed requests use the local
template fallback. No separate confirmation is requested before a provider call.
The JSON context is truncated to 12,000 characters, in addition to the prompt text. In normal mode it can include the repository root, file paths, module names, dependency cycles, metrics, and module docstrings. Whole source files are not uploaded, but docstrings can themselves contain code examples or sensitive text.
Recognized secret patterns in docstrings are redacted before forming that context. Pattern matching is best effort, not a general guarantee that all secrets are removed from arbitrary content or identifiers. Safe mode omits docstrings and anonymizes identifiers before any provider call.
The optional embedding backend runs SentenceTransformer.encode locally. Loading
a model can download files and use the library's own cache outside the repository;
StrucIn's artifact containment and retention rules do not manage that cache.
Set [search] embedding_model = "hashing-v1" to avoid loading or downloading a
neural model. Safe mode alone does not disable model loading.
The dashboard server defaults to 127.0.0.1 and has no authentication or TLS.
It serves the selected output directory, so use a dedicated directory and keep
the loopback binding for local use. Binding to a network interface exposes its
contents to machines that can reach that address.
Enable safe mode for a repository with:
[security]
safe_mode = truescan, analyze, report, explain, search, and web honor this setting.
Each also accepts --safe-mode or --no-safe-mode to override it for one run.
Pre-commit hooks honor the repository setting. diff operates on snapshots
without loading repository configuration; use diff --safe-mode explicitly.
In safe mode:
- Generated index, analysis, graph, report, narration metadata, and dashboard contents hide repository paths, file paths, module/package names, import names, and class/function names. Graph relationships and numeric metrics remain.
- All docstrings and source snippets are omitted from shareable data. LLM context is anonymized before the provider call, including the repository root. Known identifiers and recognized secret patterns are filtered again from provider responses and cached narration before writing or returning them.
- Raw analysis caches are neither read nor written. Narration uses a separate
.strucin_cache/explain_safe_cache.jsoncontaining filtered content. Normal explanation caches are never reused by safe mode. - Search rebuilds its index in memory on every run, without reading or writing
semantic_index.json. Results retain scores and line numbers with anonymous labels; source text and the query are omitted from displayed output.
Anonymous labels are scoped to an export and can change when the file set changes.
For accurate comparisons, run diff --safe-mode on the original snapshots so
matching happens before anonymization.
Safe mode governs newly generated content; it does not retroactively scrub older artifacts or caches. Existing retention cleanup still applies. Output filenames, configuration files, and diagnostic errors are not anonymized, so share the intended generated artifacts rather than the entire working directory or logs. Structural metrics and graph topology remain visible.
Library callers must pass safe_mode=True to the relevant output writer,
report generator, explainer, or dashboard builder. Raw analyze_repository results
remain in memory with original names; use use_cache=False to prevent raw cache
reads and writes. The low-level semantic index writer persists source text and
should not be used for a safe export.
Security minimums are declared for dependencies identified by the September 2026 audit, including transitive packages that an existing environment could retain:
| Package | Minimum | Reason |
|---|---|---|
| Pygments | 2.20.0 | CVE-2026-4539 |
| setuptools | 83.0.0 | CVE-2026-59890, plus earlier package-index fixes |
| PyTorch (embedding extras) | 2.13.0 | CVE-2025-3000 |
| pytest (development) | 9.0.3 | CVE-2025-71176 |
Use pip 26.2 or newer when refreshing an existing environment. Dependency audits run on pull requests, pushes to main, and manual workflow dispatches. They check fresh resolutions and explicit direct minimum versions against current PyPI advisories; see the audit instructions.
Advisories identify affected package versions, not proof that StrucIn exposes the affected code path. A passing audit covers the scanned versions and known advisories at that time. Model weights, live providers, and arbitrary pre-existing environments require separate validation.
If you discover a security vulnerability in StrucIn, please report it responsibly:
- Do not open a public GitHub issue.
- Email contact@macitch.dev with:
- A description of the vulnerability
- Steps to reproduce
- Affected version(s)
- You will receive an acknowledgment within 48 hours.
- A fix will be prioritized and released as a patch version.
The following are in scope for security reports:
- Secret leakage through LLM calls or output artifacts
- Path traversal in file scanning or artifact writing
- Code execution through crafted Python files (AST parsing should never execute code)
- Dependency vulnerabilities in the documented base and optional dependencies
The following are out of scope:
- Denial of service through extremely large repositories (expected behavior)
- Issues requiring physical access to the machine running StrucIn