Brownfield Modernization FAQ
Frequently asked questions about using SpecFact CLI for legacy code modernization
General Questions
What is brownfield modernization?
Brownfield modernization refers to improving, refactoring, or migrating existing (legacy) codebases, as opposed to greenfield development (starting from scratch).
SpecFact CLI is designed specifically for brownfield projects where you need to:
- Understand undocumented legacy code
- Modernize without breaking existing behavior
- Extract specs from existing code (code2spec)
- Enforce contracts during refactoring
Code Analysis
Can SpecFact analyze code with no docstrings?
Yes. SpecFact’s code2spec analyzes:
- Function signatures and type hints
- Code patterns and control flow
- Existing validation logic
- Module dependencies
- Commit history and code structure
No docstrings needed. SpecFact infers behavior from code patterns.
What if the legacy code has no type hints?
SpecFact infers types from usage patterns and generates specs. You can add type hints incrementally as part of modernization.
Example:
# Legacy code (no type hints)
def process_order(user_id, amount):
# SpecFact infers: user_id: int, amount: float
...
# SpecFact generates:
# - Precondition: user_id > 0, amount > 0
# - Postcondition: returns Order object
Can SpecFact handle obfuscated or minified code?
Limited. SpecFact works best with:
- Source code (not compiled bytecode)
- Readable variable names
- Standard Python patterns
For heavily obfuscated code, consider:
- Deobfuscation first (if possible)
- Manual documentation of critical paths
- Adding contracts incrementally to deobfuscated sections
What about code with no tests?
SpecFact doesn’t require tests. In fact, code2spec is designed for codebases with:
- No tests
- No documentation
- No type hints
SpecFact extracts specs from code structure and patterns, not from tests.
Contract Enforcement
Will contracts slow down my code?
Minimal impact. Contract checks are fast (microseconds per call). For high-performance code:
- Development/Testing: Keep contracts enabled (catch violations)
- Production: Optionally disable contracts (performance-critical paths only)
Best practice: Keep contracts in tests, disable only in production hot paths if needed.
Can I add contracts incrementally?
Yes. Recommended approach:
- Week 1: Add contracts to 3-5 critical functions
- Week 2: Expand to 10-15 functions
- Week 3: Add contracts to all public APIs
- Week 4+: Add contracts to internal functions as needed
Start with shadow mode (observe only), then enable enforcement incrementally.
What if a contract is too strict?
Contracts are configurable. You can:
- Relax contracts: Adjust preconditions/postconditions to match actual behavior
- Shadow mode: Observe violations without blocking
- Warn mode: Log violations but don’t raise exceptions
- Block mode: Raise exceptions on violations (default)
Start in shadow mode, then tighten as you understand the code better.
Edge Case Discovery
How does CrossHair discover edge cases?
CrossHair uses symbolic execution to explore all possible code paths mathematically. It:
- Represents inputs symbolically (not concrete values)
- Explores all feasible execution paths
- Finds inputs that violate contracts
- Generates concrete test cases for violations
Example:
@icontract.require(lambda numbers: len(numbers) > 0)
@icontract.ensure(lambda numbers, result: min(numbers) > result)
def remove_smallest(numbers: List[int]) -> int:
smallest = min(numbers)
numbers.remove(smallest)
return smallest
# CrossHair finds: [3, 3, 5] violates postcondition
# (duplicates cause min(numbers) == result after removal)
Can CrossHair find all edge cases?
No tool can find all edge cases, but CrossHair is more thorough than:
- Manual testing (limited by human imagination)
- Random testing (limited by coverage)
- LLM suggestions (probabilistic, not exhaustive)
CrossHair provides mathematical guarantees for explored paths, but complex code may have paths that are computationally infeasible to explore.
How long does CrossHair take?
Typically 10-60 seconds per function, depending on:
- Function complexity
- Number of code paths
- Contract complexity
For large codebases, run CrossHair on critical functions first, then expand.
Modernization Workflow
How do I start modernizing safely?
Recommended workflow:
- Extract specs (
specfact code import) - Add contracts to 3-5 critical functions
- Run CrossHair to discover edge cases
- Refactor incrementally (one function at a time)
- Verify contracts still pass after refactoring
- Expand contracts to more functions
Start in shadow mode, then enable enforcement as you gain confidence.
What if I break a contract during refactoring?
That’s the point! Contracts catch regressions immediately:
# Refactored code violates contract
process_payment(user_id=-1, amount=-50, currency="XYZ")
# Contract violation caught:
# ❌ ContractViolation: Payment amount must be positive (got -50)
# → Fix the bug before it reaches production!
Contracts are your safety net - they prevent breaking changes from being deployed.
Can I use SpecFact with existing test suites?
Yes. SpecFact complements existing tests:
- Tests: Verify specific scenarios
- Contracts: Enforce behavior at API boundaries
- CrossHair: Discover edge cases tests miss
Use all three together for comprehensive coverage.
What’s the learning curve for contract-first development?
Minimal. SpecFact is designed for incremental adoption:
Week 1 (2-4 hours):
- Run
specfact code importto extract specs (10 seconds) - Review extracted project bundle
- Add contracts to 3-5 critical functions
Week 2 (4-6 hours):
- Expand contracts to 10-15 functions
- Run CrossHair on critical paths
- Set up pre-commit hook
Week 3+ (ongoing):
- Add contracts incrementally as you refactor
- Use shadow mode to observe violations
- Enable enforcement when confident
No upfront training required. Start with shadow mode (observe only), then enable enforcement incrementally as you understand the code better.
Resources:
- Brownfield Engineer Guide - Complete walkthrough
- Integration Showcases - Real examples
- Getting Started - Quick start guide
Integration
Does SpecFact work with GitHub Spec-Kit?
Yes. SpecFact complements Spec-Kit:
- Spec-Kit: Interactive spec authoring (greenfield)
- SpecFact: Automated enforcement + brownfield support
Use both together:
- Use Spec-Kit for initial spec generation (fast, LLM-powered)
- Use SpecFact to add runtime contracts to critical paths (safety net)
- Spec-Kit generates docs, SpecFact prevents regressions
See Spec-Kit Comparison Guide for details.
Can I use SpecFact in CI/CD?
Yes. SpecFact integrates with:
- GitHub Actions: PR annotations, contract validation
- GitLab CI: Pipeline integration
- Jenkins: Plugin support (planned)
- Local CI: Run
specfact govern enforcein your pipeline
Contracts can block merges if violations are detected (configurable).
Does SpecFact work with VS Code, Cursor, or other IDEs?
Yes. SpecFact’s CLI-first design means it works with any IDE or editor:
- VS Code: Pre-commit hooks, tasks, or extensions
- Cursor: AI assistant integration with contract validation
- Any editor: Pure CLI, no IDE lock-in required
- Agentic workflows: Works with any AI coding assistant
Example VS Code integration:
# .git/hooks/pre-commit
#!/bin/sh
uvx specfact-cli@latest govern enforce stage --preset balanced
Example Cursor integration:
# Validate AI suggestions before accepting
cursor-agent --validate-with "uvx specfact-cli@latest enforce stage"
See Integration Showcases for real examples of bugs caught via different integrations.
Do I need to learn a new platform?
No. SpecFact is CLI-first—it integrates into your existing workflow:
- ✅ Works with your current IDE (VS Code, Cursor, etc.)
- ✅ Works with your current CI/CD (GitHub Actions, GitLab, etc.)
- ✅ Works with your current tools (no new platform to learn)
- ✅ Works offline (no cloud account required)
- ✅ Zero vendor lock-in (OSS forever)
No platform migration needed. Just add SpecFact CLI to your existing workflow.
Performance
How fast is code2spec extraction?
Typical timing:
- Small codebases (10-50 files): ~10 seconds to 1-2 minutes
- Medium codebases (50-100 files): ~1-2 minutes
- Large codebases (100+ files): 2-3 minutes for AST + Semgrep analysis
- Large codebases with contracts (100+ files): 15-30+ minutes with contract extraction, graph analysis, and parallel processing (8 workers)
The import process performs AST analysis, Semgrep pattern detection, and (when enabled) extracts OpenAPI contracts, relationships, and graph dependencies in parallel, which can take significant time for large repositories.
Does SpecFact require internet?
No. SpecFact works 100% offline:
- No cloud services required
- No API keys needed
- No telemetry (opt-in only)
- Fully local execution
Perfect for air-gapped environments or sensitive codebases.
Limitations
What are SpecFact’s limitations?
Known limitations:
- Python-only (JavaScript/TypeScript support planned Q1 2026)
- Source code required (not compiled bytecode)
- Readable code preferred (obfuscated code may have lower accuracy)
- Complex contracts may slow CrossHair (timeout configurable)
What SpecFact does well:
- ✅ Extracts specs from undocumented code
- ✅ Enforces contracts at runtime
- ✅ Discovers edge cases with symbolic execution
- ✅ Prevents regressions during modernization
Support
Where can I get help?
- 💬 GitHub Discussions - Ask questions
- 🐛 GitHub Issues - Report bugs
- 📧 [email protected] - Direct support
Can I contribute?
Yes! SpecFact is open source. See CONTRIBUTING.md for guidelines.
Next Steps
- Brownfield Engineer Guide - Complete modernization workflow
- ROI Calculator - Calculate your savings
- Examples - Real-world brownfield examples
Still have questions? Open a discussion or email us.