test(bdd): add direct test for _fast_init_or_upgrade early-return behavior #1156
Merged
CoreRasurae
merged 1 commits from 2026-04-01 23:14:58 +00:00
test/m3-fast-init-early-return into master
Dismiss Review
Are you sure you want to dismiss this review?
Labels
Clear labels
auto/needs-reevaluation
controller-managed
overdue
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Needs Feedback
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
Controller deferred this PR; awaiting Phase 6+ scope-evaluator or operator re-enablement.
Auto-agents controller manages this PR/issue (see tools/controller/deploy/RUNBOOK.md). Remove this label to abandon controller management.
PR blocked by an open issue dependency. Operator must close the dep (or remove the dependency link) before the merge driver can act. Auto-cleared by merge_drive when no open deps remain.
Most recent merge cycle hit CI timeout. Driver excludes this PR while last merge_cycle row is < 30 min old; label persists thereafter as visible history.
Currently being processed by an implementer worker.
Currently being processed by the merge driver.
Currently being processed by a reviewer worker.
Merge driver heartbeat stale; pipeline halted. Closed automatically on next clean tick.
Detected master commit violating the strict merge invariant. Tracked as an issue (not a PR label); kept here for label completeness.
In-cycle escalation: most recent attempt ran at the Tier 0 slot (`tier-0`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 1 slot (`tier-1`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 2 slot (`tier-2`). Slot's model defined in .opencode/models/tiers.yaml. Gated behind IMPLEMENTER_ESCALATION_TIER2_ENABLED.
In-cycle escalation: most recent attempt ran at the Tier -1 slot (`tier-min`). Slot's model defined in .opencode/models/tiers.yaml. Suffix is ``-min`` (not ``--1``) so the Forgejo UI reads naturally.
Tracking issues used by the AI Automation system for agents to communicate and report.
Rebase conflict needs LLM conflict-resolver.
Failing CI needs implementer attention.
Documenting a driver incident or rollback.
Reviewer has APPROVED this PR and no later REQUEST_CHANGES is outstanding. The merge driver requires this label to even consider a PR for merging. Set by the reviewer worker on APPROVE; cleared on REQUEST_CHANGES.
Train repeatedly lost master-tempo races. Driver excludes via merge_cycle until cooldown elapses; label persists as visible history.
Revert PR backing out an invariant violation. Fast-tracked through the merge driver.
Sentinel PR duplicated from upstream into a personal fork by tools/duplicate_prs_to_fork.py for pipeline testing. Lives only in the fork; the canonical pipeline never sees it.
No implementer activity for N days. Flagged for human review. Auto-cleared on next push to head branch.
Repeatedly fails on current master (>= 3 ci-fail-on-rebased-sha releases in 12 h). Excluded from driver until human triage.
A ticket in a blocked state and unable to complete until some other task is completed first.
Bounty
$100
A bounty of $100 for any open-source contributor who provides a MR that solves this issue
Bounty
$1000
A bounty of $1000 for any open-source contributor who provides a MR that solves this issue
Bounty
$10000
A bounty of $10000 for any open-source contributor who provides a MR that solves this issue
Bounty
$20
A bounty of $20 for any open-source contributor who provides a MR that solves this issue
Bounty
$2000
A bounty of $2000 for any open-source contributor who provides a MR that solves this issue
Bounty
$250
A bounty of $250 for any open-source contributor who provides a MR that solves this issue
Bounty
$50
A bounty of $50 for any open-source contributor who provides a MR that solves this issue
Bounty
$500
A bounty of $500 for any open-source contributor who provides a MR that solves this issue
Bounty
$5000
A bounty of $5000 for any open-source contributor who provides a MR that solves this issue
Bounty
$750
A bounty of $750 for any open-source contributor who provides a MR that solves this issue
MoSCoW
Could have
Could have feature in order to satisfy the epic/legendary.
MoSCoW
Must have
Must have feature in order to satisfy the epic/legendary.
MoSCoW
Should have
Should have feature in order to satisfy the epic/legendary.
There are questions in the ticket that can not be completed until the project owner provides clarity.
Points
1
1 man-hours worth of work for an expert with no learning curve.
Points
13
13 man-hours worth of work for an expert with no learning curve.
Points
2
2 man-hours worth of work for an expert with no learning curve.
Points
21
21 man-hours worth of work for an expert with no learning curve.
Points
3
3 man-hours worth of work for an expert with no learning curve.
Points
34
34 man-hours worth of work for an expert with no learning curve.
Points
5
5 man-hours worth of work for an expert with no learning curve.
Points
55
55 man-hours worth of work for an expert with no learning curve.
Points
8
8 man-hours worth of work for an expert with no learning curve.
Points
88
88 man-hours worth of work for an expert with no learning curve.
Priority
Backlog
This ticket has backlogged priority and is not to be worked on yet
Priority
CI Blocker
Critical priority issue that blocks CI/CD pipeline and prevents PR merges
Priority
Critical
The priority is critical
Priority
High
The priority is high
Priority
Low
The priority is low
Priority
Medium
The priority is medium
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
A ticket for learning a tool or technology that is needed to be able to do future planning and design.
State
Completed
The ticket has been fully implemented, completed, and merged with the source code. This label should only be applied once a ticket is closed.
State
Duplicate
A ticket that represents the same content as an existing ticket.
State
In Progress
A ticket that is actively being developed.
State
In Review
A ticket that has had some code completed to implement but is waiting to pass peer review and is not yet merged in.
State
Paused
This ticket's work started but wasn't finished. It's on hold (likely in a feature branch) and will be resumed later, either due to a blocker or a delay.
State
Unverified
All new tickets start in this state. A developer may set it to show the ticket is unverified. This means we haven't agreed to work on it. It will either move to a verified state or be closed as wontdo.
State
Verified
The issue has been verified by a developer as legitimate. It will be worked on and verified tickets are now considered part of the backlog.
State
Wont Do
This ticket has been decided it wont be done. This may mean the bug has been determined to not be real (cant verify) or the feature is one we have decided we dont want to adopt.
Type
Automation
Any edits or discussion about the AI automated coding system.
Type
Bug
Something that doesnt work as intended.
Type
Discussion
Anytime a ticket represents a discussion about a subject and doesnt fall into one of the other categories.
Type
Documentation
An error or improvement needed in the documentation.
Type
Epic
Any first tier epic. That is, an epic which contains only issues as children and will not have sub-epics.
Type
Feature
Some new functionality not present.
Type
Legendary
A type of Epic which will contain other Epics.
Type
Refactor
A code change that restructures existing code without changing its external behavior.
Type
Support
Someone needs help using the project.
Type
Task
A generic task that doesnt fit into the other type categories.
Type
Testing
Work exclusively focusing on fixing or expanding testing.
Projects
Clear projects
No project
Assignees
aditya (Aditya Chhabra)
aleenaumair (Aleena Umair)
brent.edwards (Brent Edwards)
CoreRasurae (Luis Mendes)
drew (Drew Morris)
eugen.thaci (Eugen Thaci)
freemo (Jeffrey Phillips Freeman)
HAL9000 (HAL 9000)
HAL9001 (HAL9001)
hamza.khyari (Hamza Khyari)
hurui200320 (Rui Hu)
justin.morris
khird (Kyle Hird)
org.cleveragents
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Blocks
#733 test(bdd): add direct test for _fast_init_or_upgrade early-return behavior
cleveragents/cleveragents-core
Reference: cleveragents/cleveragents-core#1156
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "test/m3-fast-init-early-return"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds direct BDD coverage for the
_fast_init_or_upgradeclosure installed by the template-DB patch so the early-return behavior is explicitly verified instead of only being inferred from broader CLI scenarios. This protects the anti-hang behavior for parallel test execution by asserting when migration delegation must be skipped versus executed.Changes
features/fast_init_upgrade.featurewith five@mock_onlyscenarios that cover all relevant paths:features/steps/fast_init_upgrade_steps.pywith step definitions that set up each DB/url case, invokeMigrationRunner.init_or_upgrade, and assert both call behavior and file outcomes.features/mocks/fast_init_test_helpers.pywithpatch_original_init_or_upgrade()to patch the closure-captured_original_init_or_upgradereference for deterministic call tracking during BDD execution.Testing
_fast_init_or_upgradebehavior under the same patching mechanism used at runtime.Related Issues
Closes #733
Dependency Link
Forgejo dependency direction is set as required: this PR blocks #733, and issue #733 depends on this PR.
Implementation Notes
The helper uses closure-cell replacement of
_original_init_or_upgradeto avoid recreating or re-implementing the function under test, keeping the tests focused on real production control flow while remaining isolated and deterministic.Scoped Code Review Report (Issue #733)
I reviewed the latest local commit by Luis Mendes:
1b1dc3a1e52dbae56d76f812a75e811a0281918ftest/m3-fast-init-early-returnScope enforced
Per request, the review scope was limited to:
features/fast_init_upgrade.featurefeatures/steps/fast_init_upgrade_steps.pyfeatures/mocks/fast_init_test_helpers.pyfeatures/environment.py(_install_template_db_patch,_fast_init_or_upgrade)src/cleveragents/infrastructure/database/migration_runner.py(init_or_upgrade)docs/specification.mdtesting architecture sectionsIterative review cycles performed
I repeated full-category passes until no new issue types appeared.
Cycle 1 (correctness/coverage/security/perf):
Cycle 2 (execution/type/lint + parallel behavior):
nox -s unit_tests -- features/fast_init_upgrade.feature --processes 1nox -s unit_tests -- features/fast_init_upgrade.feature --processes 4nox -s typechecknox -s lintCycle 3 (targeted security pass):
Findings (ordered by severity, then category)
Medium
1) Security / Test Reliability — insecure temp path creation (TOCTOU)
features/steps/fast_init_upgrade_steps.py:103tempfile.mktemp(...)is used to generate a non-existent DB path.mktempis deprecated/insecure due race-window behavior. Another process can claim that path before use, causing flaky behavior in parallel CI and creating potential symlink/path-hijack risk on shared runners.mkstemp+ close/unlink before use, or allocate path inside aTemporaryDirectory.Low
2) Test Coverage Gap — missing explicit scenario for existing empty DB file path
features/environment.py:474@mock_onlyscenario asserting existing empty DB triggers template copy and does not call original migration.3) Type-Safety Policy Drift — inline type suppression in new helper
features/mocks/fast_init_test_helpers.py:90,features/mocks/fast_init_test_helpers.py:94# type: ignore[attr-defined]oncell.cell_contentsassignment.Anycast/helper abstraction and keep pyright strict without ignores.Overall assessment
Follow-up on the scoped review findings for #1156 / issue #733:
Applied all valid fixes on branch
test/m3-fast-init-early-return:Security/reliability fix
tempfile.mktemp) with a race-safe approach usingtempfile.mkdtemp+ deterministic filename in a private temp directory.Coverage fix
Type-safety cleanup
# type: ignoresuppression from closure-cell patch helper by using localAnynarrowing on the cell reference.Validation run (with
TEST_PROCESSES=9as required):nox -s unit_tests -- features/fast_init_upgrade.feature --processes 1✅nox -s unit_tests -- features/fast_init_upgrade.feature --processes 9✅nox -s lint✅nox -s typecheck✅No additional invalid/contradictory fixes were identified against issue #733 or
docs/specification.mdfor this scoped branch work.1b1dc3a1e5toa52b54b4caCode Review Note
Unable to review — the branch
test/m3-fast-init-early-returnwas not found on the remote. Please verify the branch exists and has been pushed.Review: APPROVED
Thorough testing of
_fast_init_or_upgradeclosure mechanism. The closure cell manipulation is brittle but necessary and well-documented. 6 BDD scenarios covering non-empty DB skip, template copy, empty DB copy, non-matching prefix fallback, in-memory fallback, and non-SQLite fallback. Mocks correctly placed infeatures/mocks/.Independent Code Review Report -- PR #1156 / Issue #733
Reviewer: automated deep review (4 iterative cycles)
Scope: Code changes in branch
test/m3-fast-init-early-returnplus close connections to surrounding code (features/environment.pypatch logic,migration_runner.py)Cross-referenced: Issue #733 acceptance criteria,
docs/specification.md, prior review (comment #72933)Methodology
Performed 4 full review cycles across all categories (bugs, test coverage/flaws, security, performance, code quality/documentation). Each cycle re-examined all categories until no new findings emerged. Prior review findings (mktemp insecurity, missing empty-DB scenario, type suppression) were confirmed as already addressed in commit
a52b54b.Findings by Severity
LOW
L1: Test Coverage Gap -- Missing test for
sqlite://bare in-memory URL variantfeatures/fast_init_upgrade.feature(missing scenario)features/environment.py:459_fast_init_or_upgradeclosure checks two in-memory SQLite forms:sqlite:///:memory:but no scenario tests thesqlite://variant. This leaves one branch of the disjunction untested.sqlite://equality check is accidentally removed or altered, no test would catch the regression.Given a bare sqlite:// URL for fast-init testingthat setscontext.fast_init_db_url = "sqlite://"and asserts delegation to original.L2: Test Flaw -- Delegation scenarios don't verify
selfargument passed to mockfeatures/steps/fast_init_upgrade_steps.py:180-183mock_original.call_count == 1but never verify the mock was called with the correct arguments. Specifically, they don't check thatself(theMigrationRunnerinstance) was the first positional argument:selfis lost or substituted in the delegation call_original_init_or_upgrade(self, **kwargs)would pass silently.mock_original.call_argson context and add a Then step asserting the runner instance was passed.L3: Test Flaw -- No verification that
kwargsare forwarded in delegation pathsfeatures/steps/fast_init_upgrade_steps.py:181runner.init_or_upgrade()is always called without arguments. The originalMigrationRunner.init_or_upgradeacceptsrequire_confirmation: boolandprompt_for_migration: Callable. The_fast_init_or_upgradeclosure uses**kwargsto forward these, but no scenario exercises this forwarding:**kwargsforwarding breaks (e.g., closure signature changes to drop**kwargs), no test catches it.call_args.kwargs.L4: Documentation -- Commit message claims "5 BDD scenarios" but feature file contains 6
a52b54bmessage bodyL5: Documentation -- CHANGELOG entry misleading about "replacing"
mktempCHANGELOG.md, unreleased sectionmktempusage with private temp-directory allocation."However, this diff does not replace any existing
mktempcalls. The new code usesmkstemp/mkdtempfrom the start. The existingtempfile.mktempinenvironment.py:564(before_scenario) remains untouched. The word "replacing" implies a modification to existing code that didn't occur.mktempreplacement is tracked in the separate PR #736._fast_init_or_upgrade[...]. Uses race-safe temp-path allocation (mkstemp/mkdtemp) throughout."INFO
I1: Code Quality -- Redundant
hasattrchecks in cleanup helpersfeatures/steps/fast_init_upgrade_steps.py:31,44_register_path_cleanupand_register_directory_cleanupguard withif not hasattr(context, "_cleanup_handlers"). However,before_scenario(environment.py:509) always initializescontext._cleanup_handlers = []before any step runs. The guard is dead code.repl_coverage_steps.py:99,settings_steps.py:378). Not harmful but technically unreachable.I2: Thread Safety -- Class-level closure cell replacement without synchronization
features/mocks/fast_init_test_helpers.py:91patch_original_init_or_upgrade()mutates the_original_init_or_upgradeclosure cell on the class-levelMigrationRunner.init_or_upgradefunction. During thewithblock window, any concurrent thread hitting a fallback path in_fast_init_or_upgradewould invoke theMagicMockinstead of the real migration runner, silently skipping migration.@mock_onlyfeatures skip DB-touching setup. In the current execution model this is safe. However, if multi-threaded test execution is introduced, this would become a subtle concurrency bug.I3: Portability -- Closure cell manipulation is CPython-specific
features/mocks/fast_init_test_helpers.py:87-91cell_contentsread/write on closure cells is a CPython implementation detail documented in the C API but not guaranteed by the Python language specification. This technique would fail on PyPy or GraalPython.I4: Security Scanner -- Hardcoded credentials in test fixture
features/steps/fast_init_upgrade_steps.py:160"postgresql://user:pass@localhost/testdb"contains cleartext credentials. While obviously a test-only placeholder (no real database is contacted), automated secret scanners (e.g., Gitleaks, Semgrep secrets, GitHub Advanced Security) may flag this as a credential leak.postgresql://placeholder:placeholder@localhost/testdbor a clearly synthetic pattern that scanners are less likely to flag.Summary
Overall assessment: The implementation is solid and correctly addresses all 4 acceptance criteria from issue #733. The prior review findings (mktemp, empty-DB gap, type suppression) were properly resolved. The 6 scenarios cover all meaningful code paths in
_fast_init_or_upgrade. The closure-cell mocking approach is creative, well-documented, and appropriate for the testing need. The findings above are refinement-level observations -- none block merge.@@ -0,0 +37,4 @@Scenario: In-memory SQLite delegates to original init_or_upgradeGiven an in-memory SQLite database URL for fast-init testingWhen I call init_or_upgrade on the fast-init databaseThen the original init_or_upgrade should have been invoked exactly onceL1: Missing scenario for the
sqlite://bare in-memory URL variant. The source code atenvironment.py:459checksdb_url == "sqlite://"as an alternative to":memory:" in db_url, but only the:memory:form is tested here. Consider adding a 7th scenario.@@ -0,0 +88,4 @@cell_ref: Any = cellsaved: Any = cell_ref.cell_contentsmock = MagicMock(name="_original_init_or_upgrade")cell_ref.cell_contents = mockI2+I3: This closure cell mutation is (1) not thread-safe -- concurrent callers hitting fallback paths during the
withwindow would invoke the MagicMock -- and (2) CPython-specific (cell_contentsis a C-level implementation detail). Both are acceptable for the current Behave sequential execution model targeting CPython, but worth documenting as assumptions.@@ -0,0 +28,4 @@def _register_path_cleanup(context: Context, path: str) -> None:"""Schedule *path* (and its SQLite sidecar files) for removal."""if not hasattr(context, "_cleanup_handlers"):I1: This
hasattrguard is technically unreachable --before_scenario(environment.py:509) always initializescontext._cleanup_handlers = []before any step runs. Consistent with other step files but dead code.@@ -0,0 +157,4 @@def step_create_nonsqlite_url(context: Context) -> None:"""Set up a non-SQLite URL (PostgreSQL placeholder)."""context.fast_init_db_path = Nonecontext.fast_init_db_url = "postgresql://user:pass@localhost/testdb"I4: Hardcoded
user:passcredentials may trigger automated secret scanners. Consider using a clearly synthetic pattern likepostgresql://placeholder:placeholder@localhost/testdb.@@ -0,0 +180,4 @@with patch_original_init_or_upgrade() as mock_original:runner.init_or_upgrade()context.fast_init_mock_called = mock_original.calledcontext.fast_init_mock_call_count = mock_original.call_countL2+L3: The mock's
call_argsare not captured or verified. Consider storingmock_original.call_argson context so Then steps can assert thatself(the runner instance) was passed correctly, and that keyword arguments (e.g.,require_confirmation=True) are forwarded when provided.Independent Code Review Report -- PR #1156 / Issue #733
Reviewer: Independent automated review (3 iterative cycles)
Scope: Code changes in branch
test/m3-fast-init-early-return(commit056ca8f) plus close connections to surrounding codeCross-referenced: Issue #733 acceptance criteria,
docs/specification.md, prior reviews (#72933, #2957, #3054)Methodology
Performed 3 full review cycles across all categories (bugs, test coverage, test flaws, performance, security, code quality, documentation). Each cycle re-examined every category globally until no new findings emerged. All changed files were read in full; surrounding code (
features/environment.py:418-603,migration_runner.py:198-254) was traced to verify behavioral correctness of each scenario.Acceptance Criteria Verification (Issue #733)
_fast_init_or_upgradewith a non-empty DB_original_init_or_upgradeis not calledFindings by Severity and Category
LOW -- Test Coverage (1 finding)
L1: Missing
sqlite://bare in-memory URL variant scenariofeatures/fast_init_upgrade.feature(missing scenario)features/environment.py:459_fast_init_or_upgradeclosure checks two in-memory SQLite forms:sqlite:///:memory:but no scenario tests thesqlite://bare URL variant. This leaves one branch of the disjunction untested.sqlite://equality check is accidentally removed or altered, no test would catch the regression.Given a bare sqlite:// URL for fast-init testingthat setscontext.fast_init_db_url = "sqlite://"and asserts delegation to original.LOW -- Test Flaws (2 findings)
L2: Delegation scenarios don't verify arguments passed to mock
features/steps/fast_init_upgrade_steps.py:180-183mock_original.call_count == 1but never verify the mock was called with the correctselfargument. The delegation call in_fast_init_or_upgradeis_original_init_or_upgrade(self, **kwargs)-- theself(theMigrationRunnerinstance) is never validated.selfis lost or substituted in the delegation call would pass silently.mock_original.call_argson context and add a Then step asserting the runner instance was passed as the first positional argument.L3: No verification that
**kwargsare forwarded in delegation pathsfeatures/steps/fast_init_upgrade_steps.py:181runner.init_or_upgrade()is always called without arguments. The originalMigrationRunner.init_or_upgradeacceptsrequire_confirmation: boolandprompt_for_migration: Callable. The_fast_init_or_upgradeclosure uses**kwargsto forward these, but no scenario exercises this forwarding.**kwargsforwarding breaks (e.g., closure signature changes to drop**kwargs), no test catches it.call_args.kwargs.LOW -- Documentation (2 findings)
L4: Commit message claims "5 BDD scenarios" but feature file contains 6
056ca8fmessage bodyL5: CHANGELOG entry misleading about "replacing" mktemp
CHANGELOG.md, unreleased sectionmktempusage with private temp-directory allocation." However, this diff does not replace any existingmktempcalls -- the new code usesmkstemp/mkdtempfrom the start. The existingtempfile.mktempinenvironment.py:564(before_scenario) remains untouched.mkstemp/mkdtemp) throughout new fast-init test steps."INFO -- Code Quality (1 finding)
I1: Redundant
hasattrchecks in cleanup helpersfeatures/steps/fast_init_upgrade_steps.py:31,44_register_path_cleanupand_register_directory_cleanupguard withif not hasattr(context, "_cleanup_handlers"). However,before_scenario(environment.py:509) always initializescontext._cleanup_handlers = []before any step runs. The guard is dead code in normal execution.plan_lifecycle_cli_steps.py:102,config_three_scope_steps.py:85), so it is at least consistent with project conventions.INFO -- Thread Safety (1 finding)
I2: Class-level closure cell replacement without synchronization
features/mocks/fast_init_test_helpers.py:91patch_original_init_or_upgrade()mutates the_original_init_or_upgradeclosure cell on the class-levelMigrationRunner.init_or_upgradefunction. During thewithblock window, any concurrent thread hitting a fallback path would invoke theMagicMockinstead of the real migration runner.@mock_onlyfeatures skip DB-touching setup. Safe in the current execution model.INFO -- Portability (1 finding)
I3: Closure cell manipulation is CPython-specific
features/mocks/fast_init_test_helpers.py:87-91cell_contentsread/write is a CPython implementation detail. Would fail on PyPy or GraalPython.INFO -- Security Scanner (1 finding)
I4: Hardcoded credentials in test fixture
features/steps/fast_init_upgrade_steps.py:160"postgresql://user:pass@localhost/testdb"may trigger automated secret scanners (Gitleaks, Semgrep secrets, etc.) despite being a test-only placeholder.postgresql://placeholder:placeholder@localhost/testdbor a clearly synthetic pattern.INFO -- Documentation (1 finding, NEW)
I5: Surrounding code docstring inconsistency
features/environment.py:447(surrounding code, not changed by this PR)_fast_init_or_upgradedocstring says "In-memory SQLite ->Base.metadata.create_all()+ alembic stamp" but the actual implementation delegates to_original_init_or_upgrade. The test correctly verifies the actual behavior (delegation), not the documented behavior.Summary
Overall Assessment
The implementation correctly addresses all 4 acceptance criteria from issue #733. The 6 BDD scenarios cover all meaningful code paths in
_fast_init_or_upgrade(early return, template copy, empty-DB copy, non-matching prefix fallback, in-memory fallback, non-SQLite fallback). The closure-cell mocking approach infast_init_test_helpers.pyis creative, well-documented, and appropriate for the testing need.Prior review findings (insecure mktemp, missing empty-DB scenario, type suppression) were properly resolved in the current commit. The remaining findings are refinement-level observations. None of the findings block merge.
This independent review confirms the findings from the prior self-review (#3054) and adds one new informational item (I5). The PR has already been APPROVED by @freemo (#2957).
a52b54b4catoe3703f953bNew commits pushed, approval review dismissed automatically according to repository settings
e3703f953btob21e0fedea