fix(todo.brownfield-contract-pointer): declare the contracts brownfield writes - #481
Conversation
…ld writes `cairn init --from-code` followed by `cairn change apply brownfield-init` produced a map that immediately failed `cairn scan` with one CAIRN_CONTRACT_LEAF_UNCOVERED finding per discovered node. The contract artefacts were not missing: `write_change` emits meta/changes/<id>/contracts/<id>.md and `parse_artefact_operations` promotes it to meta/contracts/<id>.md in the same apply step. The emitted node block simply carried no `contract` pointer, so the coverage gate reported the artefact absent. `blueprint_delta` now emits `contract "./meta/contracts/<id>.md"` alongside the existing `path` line, and the filename is single-sourced in `contract_file_name` rather than derived independently by the change-directory writer and the delta emitter. Refine inherits the pointer through `blueprint_delta_with_renames`. Verified end to end on a throwaway repo: two discovered packages now emit their contract pointers and `cairn scan` exits 0 where it previously reported two warnings and exited 1. map.json is the snapshot `cairn scan` regenerates; the two span shifts are the new helpers moving `write_change` and `blueprint_delta` down thirteen lines. The remaining CAIRN_ORDER_CYCLE finding on nested-package brownfield output is out of scope and filed as todo.brownfield-parent-package-cycle, with the three facts that block the obvious fix recorded so the next session starts from them.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughSummary by CodeRabbit
WalkthroughBrownfield initialization and refinement now centralize contract filenames, emit contract pointers in blueprint deltas, and verify those pointers against generated files and scanner results. Related TODOs document contract coverage and parent-package cycle issues, while symbol metadata spans are updated. ChangesBrownfield contract coverage
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant run_init_from_code
participant blueprint_delta
participant contracts_directory
participant scanner
run_init_from_code->>blueprint_delta: generate node declarations with contract pointers
blueprint_delta->>contracts_directory: write matching contract stubs
scanner->>blueprint_delta: read archived blueprint
scanner->>contracts_directory: resolve contract pointers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
cairn init --from-codefollowed bycairn change apply brownfield-initproduced a map that immediately failedcairn scan: oneCAIRN_CONTRACT_LEAF_UNCOVEREDfinding per discovered node, on a map cairn generated itself.The contract artefacts were not missing.
write_changeemitsmeta/changes/<id>/contracts/<id>.md, andparse_artefact_operationspromotes it tometa/contracts/<id>.mdin the same apply step (src/changes/artefact_ops.rs:74,root.join("meta").join(relative)). The node block in the emitted delta simply carried nocontractpointer, so the coverage gate reported the artefact absent.Change
blueprint_deltaemitscontract "./meta/contracts/<id>.md"directly after the existingpathline, matching hand-authored field order.contract_file_name; the change-directory writer (src/brownfield/mod.rs) andsrc/brownfield/refine.rspreviously each inlinedformat!("{}.md", id.replace('.', "_")). Zero remaining copies.blueprint_delta_with_renamesdelegates tosuper::blueprint_delta.run_refinefilters out already-declared paths, so an emitted pointer can never overwrite a hand-authored one.@no-contracttag: the contract file genuinely exists, the pointer is the missing half.map.jsonis the snapshotcairn scanregenerates. The two span shifts arewrite_changeandblueprint_deltamoving down thirteen lines. Same class of resync as #477.Tests
Three, all verified failing before the fix and passing after:
test_blueprint_delta_emits_contract_pointer: the wire form.test_contract_pointer_target_matches_written_contract_file: anti-drift, pins the delta pointer to the filewrite_changeactually wrote.test_init__archived_map_declares_contracts_for_every_leaf: end to end, init plus archive plus scan yields zeroCAIRN_CONTRACT_LEAF_UNCOVERED.Verification
scripts/pre-archive-rust-gates.shexit 0.cairn scan --strictexit 0 at the pre-existing baseline (one deferred finding).cairn hook allpass.End to end on a throwaway repo (two Python packages, no prior cairn state):
Before this change the same sequence printed two
CAIRN_CONTRACT_LEAF_UNCOVEREDwarnings and exited 1.Out of scope
The remaining
CAIRN_ORDER_CYCLEfinding on nested-package brownfield output is filed astodo.brownfield-parent-package-cycle, with the three verified facts that block the obvious fix recorded so the next session does not re-derive them. It needs a decision on how brownfield models parent packages plus delta-pipeline work, which does not fit this unit's sizing.