Conversation
Integrate core safe-write helper into specfact-backlog sync and add commands so persistent user-project artifacts are never silently overwritten. Adds TYPE_CHECKING-aware re-exports for BacklogAdapter and BacklogFilters, fixes the import boundary checker to skip TYPE_CHECKING blocks, compacts the daily command signature to meet the LOC gate, and bumps specfact-backlog to 0.41.19. Also sets --level error on the pre-commit code review gate so the hook fails only on error-severity findings, not advisory warnings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- check-bundle-imports: traverse orelse branch of TYPE_CHECKING guards so runtime imports in else-clauses are still scanned (P1 bug fix) - commands.py: infer GitHub provider from github_project_id/v2_id/type_field_id hints before falling through to ADO in _normalize_map_field_providers (P2) - sync.py: run _prepare_baseline_write before _fetch_current_graph so the command exits early when overwrite is blocked instead of doing a network call first - test_sync_command.py: assert backup file content equals original baseline - tutorial-backlog-quickstart-demo.md: remove stale .nold-ai config path line - tasks.md: drop --require-signature from pre-merge gate; add --level error to code review command - TDD_EVIDENCE.md: update version trail to reflect final shipped version 0.41.20 - specfact-backlog: bump to 0.41.20 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Narrow _is_type_checking_guard to only match bare TYPE_CHECKING or typing.TYPE_CHECKING, rejecting settings.TYPE_CHECKING and similar - Re-run code review with --level error per tasks.md requirement and record updated timestamps/counts in TDD_EVIDENCE.md (0 error findings on changed scope, 379 on full repo baseline debt) - Bump specfact-backlog to 0.41.21 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rtifact-write-policy feat(backlog): adopt safe artifact write policy (project-runtime-01)
chore(registry): publish changed modules
PR SummaryMedium Risk Overview Config/mapping updates are documented as merge-preserving. Docs and OpenSpec artifacts are updated to treat Release hygiene updates. Bumps Reviewed by Cursor Bugbot for commit d5e0f68. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (13)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
🧰 Additional context used📓 Path-based instructions (6)registry/**⚙️ CodeRabbit configuration file
Files:
packages/**/module-package.yaml⚙️ CodeRabbit configuration file
Files:
openspec/**/*.md⚙️ CodeRabbit configuration file
Files:
docs/**/*.md⚙️ CodeRabbit configuration file
Files:
**/*.{js,ts,tsx,jsx,py,java,cs,go,rb,php,cpp,c,h}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
tests/**/*.py⚙️ CodeRabbit configuration file
Files:
🧠 Learnings (11)📓 Common learnings📚 Learning: 2026-04-02T21:49:07.435ZApplied to files:
📚 Learning: 2026-04-02T21:49:11.371ZApplied to files:
📚 Learning: 2026-04-13T10:38:22.848ZApplied to files:
📚 Learning: 2026-04-13T10:38:43.535ZApplied to files:
📚 Learning: 2026-04-13T10:38:29.399ZApplied to files:
📚 Learning: 2026-04-13T10:38:22.848ZApplied to files:
📚 Learning: 2026-04-13T10:38:43.535ZApplied to files:
📚 Learning: 2026-04-13T10:38:15.855ZApplied to files:
📚 Learning: 2026-04-13T10:38:22.848ZApplied to files:
📚 Learning: 2026-04-13T10:38:43.535ZApplied to files:
🪛 LanguageToolopenspec/changes/project-runtime-01-safe-artifact-write-policy/proposal.md[style] ~11-~11: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym. (ENGLISH_WORD_REPEAT_BEGINNING_RULE) 🔀 Multi-repo context nold-ai/specfact-clinold-ai/specfact-cli Findings:
Potential impact / reviewers' attention areas (grounded in repo findings):
Conclusion: All relevant consumers and references are inside this repository; no cross-repo references discovered. 🔇 Additional comments (11)
📝 WalkthroughPR
|
| Cohort / File(s) | Summary |
|---|---|
Docs & Guides README.md, docs/bundles/backlog/overview.md, docs/bundles/backlog/delta.md, docs/getting-started/tutorial-backlog-quickstart-demo.md, docs/guides/custom-field-mapping.md |
Restructure README; standardize backlog config/baseline locations to .specfact/*; document ownership semantics and merge/preserve behavior and safe-failure rules. |
OpenSpec / Design openspec/changes/project-runtime-01-safe-artifact-write-policy/... |
Refines safe-write policy scope to .specfact ownership model; narrows adopter paths to backlog-related files; updates tasks, proposal, design, specs, and TDD evidence. |
CLI: sync command packages/specfact-backlog/src/specfact_backlog/backlog_core/commands/sync.py |
Adds --force-baseline-overwrite option; if external baseline exists and flag not set, CLI aborts with message; if set, creates sanitized timestamped backup under .specfact/recovery/ and proceeds to overwrite. |
Type-checking import guards packages/specfact-backlog/src/specfact_backlog/backlog/adapters/interface.py, packages/specfact-backlog/src/specfact_backlog/backlog/filters.py |
Change runtime import resolution to preserve dynamic behavior while importing concrete types under if TYPE_CHECKING: for static analysis; exported symbols unchanged. |
Import-check script scripts/check-bundle-imports.py |
Exclude imports inside if TYPE_CHECKING: / typing.TYPE_CHECKING blocks from import-collection to avoid false positives. |
Pre-commit gate scripts/pre_commit_code_review.py |
Passes --level error to SpecFact code-review invocation to limit findings processed to error-level while preserving JSON output and exit behavior. |
Tests tests/unit/specfact_backlog/test_map_fields_command.py, tests/unit/specfact_backlog/test_sync_command.py, tests/unit/specfact_backlog/test_refine_adapter_contract.py |
Add/adjust tests covering map-fields preservation and invalid YAML safety; sync backup/force behavior; and adapter contract invocation pattern. |
Package & Registry packages/specfact-backlog/module-package.yaml, registry/index.json, registry/modules/specfact-backlog-*.sha256, registry/signatures/specfact-backlog-*.tar.sig |
Bump specfact-backlog package version and refresh integrity checksum/signature files and registry entries to reference the new release artifacts (notably 0.41.24). |
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~50 minutes
Possibly related issues
- [Change] Runtime adoption of safe artifact write policy #177: Implements the runtime safe-artifact-write boundary and external baseline backup/force-overwrite behavior described in the issue.
Possibly related PRs
- feat(backlog): adopt safe artifact write policy (project-runtime-01) #246: Highly overlapping — implements sync baseline force/backup, docs, TYPE_CHECKING import changes, and pre-commit gate adjustment.
- Promote dev branch updates to main #130: Related change to pre-commit gate invocation and SpecFact code-review invocation flags.
- chore(openspec): restore project-runtime-01-safe-artifact-write-policy #180: Related edits to the same OpenSpec safe-artifact-write-policy change set.
Suggested labels
module, documentation
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 15.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
✅ Passed checks (4 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The PR title 'fix(backlog): adopt safe artifact write policy (project-runtime-01)' follows Conventional Commits format with a clear 'fix' prefix, includes the affected component, and accurately describes the main change. |
| Description check | ✅ Passed | The PR description follows the template structure with all major sections completed: Summary with refs, Scope checkboxes, Bundle Impact, Changes, Validation Evidence with local gates, signature verification, code review results, CI/Branch Protection confirmation, Docs updates, and final Checklist all checked and filled. |
| Linked Issues check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
📝 Generate docstrings
- Create stacked PR
- Commit on current branch
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Commit unit tests in branch
dev
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6d6523ab53
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/unit/specfact_backlog/test_map_fields_command.py (1)
646-847: 🧹 Nitpick | 🔵 TrivialConsider extracting shared map-fields test scaffolding.
Line 646 onward repeats near-identical payload stubs,
fake_getbranching, and CLI invocation arguments across multiple tests. A small helper/fixture would reduce drift and keep each test focused on its contract assertion.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/unit/specfact_backlog/test_map_fields_command.py` around lines 646 - 847, The three map-fields tests repeat identical payloads, fake_get logic and the runner.invoke arguments; extract a shared helper (e.g., a function or pytest fixture like prepare_map_fields or make_map_fields_test_context) that sets up fields_payload, work_item_types_payload, work_item_type_fields_payload, registers the fake_get (referencing the fake_get branching used in the tests), and returns the common CLI args list and any paths (mapping_path/config_dir) needed by each test; then update test_map_fields_preserves_unrelated_backlog_config_sections, test_map_fields_preserves_unrelated_custom_mapping_sections, and test_map_fields_fails_safe_when_custom_mapping_file_is_invalid to call that helper, reuse the returned args with runner.invoke(backlog_app, args), and only keep the assertions and the test-specific file setup/teardown in each test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/guides/custom-field-mapping.md`:
- Around line 196-197: Update the user-facing sentence that reads "If the file
is not a valid YAML mapping, the command fails safe and leaves the file
unchanged." to use the correct phrasing "fails safely" so it reads "If the file
is not a valid YAML mapping, the command fails safely and leaves the file
unchanged."; ensure the change is applied in the same sentence that references
the CLI command `specfact backlog map-fields` and the path
`.specfact/templates/backlog/field_mappings/ado_custom.yaml`.
In `@openspec/changes/project-runtime-01-safe-artifact-write-policy/proposal.md`:
- Line 17: Add a blank line after the markdown subheadings "### New
Capabilities" and "### Modified Capabilities" so list items follow the headings
on their own paragraph (fix MD022); locate the headings in proposal.md and
insert a single empty line immediately after each of the two headings to ensure
proper Markdown linting.
In
`@openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/runtime-artifact-write-safety/spec.md`:
- Line 3: Several Markdown headings in the spec (e.g., "Requirement: Bundle
runtime commands SHALL distinguish sanctioned external artifacts from
SpecFact-managed artifacts" and the other similar headings referenced) are
missing the required blank line after the heading; add a single blank line
immediately following each heading so the document complies with MD022 (apply
the same fix to the other headings noted in the comment).
In `@openspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.md`:
- Line 26: Complete checklist item 4.5 by opening the modules PR to the dev
branch, add a clear cross-link to the paired core PR that contains the
external-path contract (reference the core PR number/URL in the PR description),
and add a short "deferred follow-up" note stating whether a broader generic
runtime safe-write change is required and who/which core work item will track it
so merge readiness governance is satisfied.
In
`@openspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.md`:
- Around line 25-33: Update the TDD_EVIDENCE.md entry to include the final
signing and verification commands and timestamps for the shipped backlog version
0.41.21: run the same two commands shown (the sign script: `hatch run python
scripts/sign-modules.py --allow-unsigned --payload-from-filesystem
packages/specfact-backlog/module-package.yaml` and the verifier: `hatch run
verify-modules-signature --payload-from-filesystem --enforce-version-bump`),
capture their exact timestamps and outcomes (e.g., "Result: passed (Verified X
module manifest(s).)" or any error text) and append them in the same
bullet-format used for 0.41.20 so the file records both sign and verify evidence
for version 0.41.21 and matches the actual payload in
packages/specfact-backlog/module-package.yaml.
---
Outside diff comments:
In `@tests/unit/specfact_backlog/test_map_fields_command.py`:
- Around line 646-847: The three map-fields tests repeat identical payloads,
fake_get logic and the runner.invoke arguments; extract a shared helper (e.g., a
function or pytest fixture like prepare_map_fields or
make_map_fields_test_context) that sets up fields_payload,
work_item_types_payload, work_item_type_fields_payload, registers the fake_get
(referencing the fake_get branching used in the tests), and returns the common
CLI args list and any paths (mapping_path/config_dir) needed by each test; then
update test_map_fields_preserves_unrelated_backlog_config_sections,
test_map_fields_preserves_unrelated_custom_mapping_sections, and
test_map_fields_fails_safe_when_custom_mapping_file_is_invalid to call that
helper, reuse the returned args with runner.invoke(backlog_app, args), and only
keep the assertions and the test-specific file setup/teardown in each test.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6de4b792-aaab-4c00-8d9a-f3a89b722047
⛔ Files ignored due to path filters (1)
registry/modules/specfact-backlog-0.41.21.tar.gzis excluded by!**/*.gz
📒 Files selected for processing (25)
README.mddocs/bundles/backlog/delta.mddocs/bundles/backlog/overview.mddocs/getting-started/tutorial-backlog-quickstart-demo.mddocs/guides/custom-field-mapping.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/design.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/proposal.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-add/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-sync/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/runtime-artifact-write-safety/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.mdpackages/specfact-backlog/module-package.yamlpackages/specfact-backlog/src/specfact_backlog/backlog/adapters/interface.pypackages/specfact-backlog/src/specfact_backlog/backlog/commands.pypackages/specfact-backlog/src/specfact_backlog/backlog/filters.pypackages/specfact-backlog/src/specfact_backlog/backlog_core/commands/sync.pyregistry/index.jsonregistry/modules/specfact-backlog-0.41.21.tar.gz.sha256registry/signatures/specfact-backlog-0.41.21.tar.sigscripts/check-bundle-imports.pyscripts/pre_commit_code_review.pytests/unit/specfact_backlog/test_map_fields_command.pytests/unit/specfact_backlog/test_refine_adapter_contract.pytests/unit/specfact_backlog/test_sync_command.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
registry/**
⚙️ CodeRabbit configuration file
registry/**: Registry and index consistency: bundle listings, version pins, and compatibility with
published module artifacts.
Files:
registry/modules/specfact-backlog-0.41.21.tar.gz.sha256registry/signatures/specfact-backlog-0.41.21.tar.sigregistry/index.json
**/*.{js,ts,tsx,jsx,py,java,cs,go,rb,php,cpp,c,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Preserve the clean-code compliance gate and its category references (naming, kiss, yagni, dry, and solid)
Files:
scripts/pre_commit_code_review.pypackages/specfact-backlog/src/specfact_backlog/backlog/adapters/interface.pyscripts/check-bundle-imports.pytests/unit/specfact_backlog/test_refine_adapter_contract.pypackages/specfact-backlog/src/specfact_backlog/backlog/filters.pytests/unit/specfact_backlog/test_sync_command.pytests/unit/specfact_backlog/test_map_fields_command.pypackages/specfact-backlog/src/specfact_backlog/backlog_core/commands/sync.py
scripts/**/*.py
⚙️ CodeRabbit configuration file
scripts/**/*.py: Deterministic tooling: signing, publishing, docs generation; subprocess and path safety.
Files:
scripts/pre_commit_code_review.pyscripts/check-bundle-imports.py
packages/**/src/**/*.py
⚙️ CodeRabbit configuration file
packages/**/src/**/*.py: Focus on adapter and bridge patterns: imports from specfact_cli (models, runtime, validators),
Typer/Rich command surfaces, and clear boundaries so core upgrades do not silently break bundles.
Flag breaking assumptions about registry loading, lazy imports, and environment/mode behavior.
Files:
packages/specfact-backlog/src/specfact_backlog/backlog/adapters/interface.pypackages/specfact-backlog/src/specfact_backlog/backlog/filters.pypackages/specfact-backlog/src/specfact_backlog/backlog_core/commands/sync.py
openspec/**/*.md
⚙️ CodeRabbit configuration file
openspec/**/*.md: Specification truth: proposal/tasks/spec deltas vs. bundle behavior, CHANGE_ORDER, and
drift vs. shipped modules or docs.
Files:
openspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-sync/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-add/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/runtime-artifact-write-safety/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/proposal.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/design.md
packages/**/module-package.yaml
⚙️ CodeRabbit configuration file
packages/**/module-package.yaml: Validate metadata: name, version, commands, dependencies, and parity with packaged src.
Call out semver and signing implications when manifests or payloads change.
Files:
packages/specfact-backlog/module-package.yaml
tests/**/*.py
⚙️ CodeRabbit configuration file
tests/**/*.py: Contract-first and integration tests: migration suites, bundle validation, and flakiness.
Ensure changes to adapters or bridges have targeted coverage.
Files:
tests/unit/specfact_backlog/test_refine_adapter_contract.pytests/unit/specfact_backlog/test_sync_command.pytests/unit/specfact_backlog/test_map_fields_command.py
docs/**/*.md
⚙️ CodeRabbit configuration file
docs/**/*.md: User-facing and cross-site accuracy: Jekyll front matter, links per documentation-url-contract,
CLI examples matching bundled commands.
Files:
docs/bundles/backlog/overview.mddocs/getting-started/tutorial-backlog-quickstart-demo.mddocs/guides/custom-field-mapping.mddocs/bundles/backlog/delta.md
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-13T10:38:29.399Z
Learning: When a change is paired with work in specfact-cli, review the paired public change artifacts there before widening scope or redefining shared workflow semantics
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: .cursorrules:0-0
Timestamp: 2026-04-13T10:38:15.855Z
Learning: Adhere to worktree policy, OpenSpec gating, GitHub hierarchy-cache refresh, TDD order, quality gates, versioning, and documentation rules as defined in `docs/agent-rules/`
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-13T10:38:22.848Z
Learning: This repository enforces the clean-code review gate through hatch run specfact code review run --json --out .specfact/code-review.json
📚 Learning: 2026-04-02T21:49:11.371Z
Learnt from: djm81
Repo: nold-ai/specfact-cli-modules PR: 136
File: registry/modules/specfact-spec-0.40.17.tar.gz.sha256:1-1
Timestamp: 2026-04-02T21:49:11.371Z
Learning: In nold-ai/specfact-cli-modules, module tarball signatures (registry/signatures/*.tar.sig) are generated by the `publish-modules` GitHub Actions runner during the publish workflow, not committed locally to the branch. Missing signature files should NOT be flagged as a pre-merge blocker in PRs.
Applied to files:
registry/modules/specfact-backlog-0.41.21.tar.gz.sha256openspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.mdpackages/specfact-backlog/module-package.yamlregistry/index.jsonREADME.md
📚 Learning: 2026-04-02T21:49:07.435Z
Learnt from: djm81
Repo: nold-ai/specfact-cli-modules PR: 136
File: registry/modules/specfact-spec-0.40.17.tar.gz.sha256:1-1
Timestamp: 2026-04-02T21:49:07.435Z
Learning: In nold-ai/specfact-cli-modules, module tarball signature files under registry/signatures/*.tar.sig are produced by the publish-modules GitHub Actions runner during the publish workflow (not committed to the branch). During PR pre-merge review, do not flag missing *.tar.sig files as blockers; treat signatures as publish-time artifacts.
Applied to files:
registry/signatures/specfact-backlog-0.41.21.tar.sig
📚 Learning: 2026-04-13T10:38:22.848Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-13T10:38:22.848Z
Learning: This repository enforces the clean-code review gate through hatch run specfact code review run --json --out .specfact/code-review.json
Applied to files:
scripts/pre_commit_code_review.pyopenspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.mdREADME.md
📚 Learning: 2026-04-13T10:38:43.535Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-13T10:38:43.535Z
Learning: Fix SpecFact code review findings, including warnings, unless a rare explicit exception is documented
Applied to files:
scripts/pre_commit_code_review.pyopenspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.md
📚 Learning: 2026-04-13T10:38:43.535Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-13T10:38:43.535Z
Learning: Treat the clean-code compliance gate as mandatory: the review surface enforces `naming`, `kiss`, `yagni`, `dry`, and `solid` categories and blocks regressions
Applied to files:
scripts/pre_commit_code_review.py
📚 Learning: 2026-04-13T10:38:29.399Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-13T10:38:29.399Z
Learning: When a change is paired with work in specfact-cli, review the paired public change artifacts there before widening scope or redefining shared workflow semantics
Applied to files:
scripts/pre_commit_code_review.pyopenspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.mddocs/bundles/backlog/overview.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-sync/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-add/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/specs/runtime-artifact-write-safety/spec.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/proposal.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/design.md
📚 Learning: 2026-04-13T10:38:43.535Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-13T10:38:43.535Z
Learning: Perform `spec -> tests -> failing evidence -> code -> passing evidence` in that order for behavior changes
Applied to files:
openspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.mdopenspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.md
📚 Learning: 2026-04-13T10:38:22.848Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-13T10:38:22.848Z
Learning: Signed module or manifest changes require version-bump review and verify-modules-signature
Applied to files:
packages/specfact-backlog/module-package.yamlREADME.md
📚 Learning: 2026-04-13T10:38:43.535Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-13T10:38:43.535Z
Learning: Enforce module signatures and version bumps when signed module assets or manifests are affected
Applied to files:
packages/specfact-backlog/module-package.yamlREADME.md
📚 Learning: 2026-04-13T10:38:22.848Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-13T10:38:22.848Z
Learning: Refresh .specfact/backlog/github_hierarchy_cache.md with python scripts/sync_github_hierarchy_cache.py when GitHub hierarchy metadata is missing or stale before parent or blocker work
Applied to files:
tests/unit/specfact_backlog/test_sync_command.pydocs/bundles/backlog/delta.md
📚 Learning: 2026-04-13T10:38:43.535Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-13T10:38:43.535Z
Learning: If GitHub hierarchy metadata is needed and `.specfact/backlog/github_hierarchy_cache.md` is missing or stale, refresh it with `python scripts/sync_github_hierarchy_cache.py`
Applied to files:
docs/bundles/backlog/delta.md
📚 Learning: 2026-04-13T10:38:15.855Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: .cursorrules:0-0
Timestamp: 2026-04-13T10:38:15.855Z
Learning: Adhere to worktree policy, OpenSpec gating, GitHub hierarchy-cache refresh, TDD order, quality gates, versioning, and documentation rules as defined in `docs/agent-rules/`
Applied to files:
openspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.mdREADME.md
📚 Learning: 2026-04-13T10:38:22.848Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-13T10:38:22.848Z
Learning: Work belongs on feature/*, bugfix/*, hotfix/*, or chore/* branches, normally in a worktree rooted under ../specfact-cli-modules-worktrees/
Applied to files:
openspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.mdREADME.md
📚 Learning: 2026-04-13T10:38:29.399Z
Learnt from: CR
Repo: nold-ai/specfact-cli-modules PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-13T10:38:29.399Z
Learning: Treat canonical rule docs (docs/agent-rules/INDEX.md) as the source of truth for worktree policy, OpenSpec gating, GitHub completeness checks, TDD order, quality gates, versioning, and documentation rules
Applied to files:
README.md
🪛 LanguageTool
openspec/changes/project-runtime-01-safe-artifact-write-policy/proposal.md
[style] ~11-~11: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...d generic modules-side abstraction. - NEW: Define .specfact ownership classes...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
openspec/changes/project-runtime-01-safe-artifact-write-policy/design.md
[style] ~3-~3: Specify a number, remove phrase, use “a few”, or use “some”
Context: ...artifacts under .specfact/, with only a small number of sanctioned external touchpoints outside...
(SMALL_NUMBER_OF)
🪛 markdownlint-cli2 (0.22.1)
openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/runtime-artifact-write-safety/spec.md
[warning] 3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 6-6: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 11-11: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 16-16: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 19-19: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 25-25: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
openspec/changes/project-runtime-01-safe-artifact-write-policy/proposal.md
[warning] 17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🔀 Multi-repo context nold-ai/specfact-cli
[::nold-ai/specfact-cli::]
- packages/specfact-backlog/src/specfact_backlog/backlog_core/commands/sync.py
- Implements new --force-baseline-overwrite flag, pre-write checks, and timestamped backup behavior for external baseline files. Tests exercise both failure (no force) and backup+overwrite (with force). Relevant consumer: CLI sync flow. [::nold-ai/specfact-cli::packages/specfact-backlog/src/specfact_backlog/backlog_core/commands/sync.py]
- packages/specfact-backlog/src/specfact_backlog/backlog/adapters/interface.py
- Changed to conditional TYPE_CHECKING import/re-export of BacklogAdapter; affects static typing and how the symbol is resolved at runtime vs type-check time. Many adapters and tests reference the BacklogAdapter contract. [::nold-ai/specfact-cli::packages/specfact-backlog/src/specfact_backlog/backlog/adapters/interface.py]
- packages/specfact-backlog/src/specfact_backlog/backlog/filters.py
- Conditional TYPE_CHECKING import of BacklogFilters; BacklogFilters is widely used by adapters and commands (fetch_backlog_items signatures). Changing import/gating can affect type-checking and static-analysis tooling. [::nold-ai/specfact-cli::packages/specfact-backlog/src/specfact_backlog/backlog/filters.py]
- scripts/check-bundle-imports.py
- Logic updated to ignore imports inside TYPE_CHECKING/typing.TYPE_CHECKING guards; impacts static import-boundary scanning used in packaging/CI. Verify scanner still treats intended imports correctly. [::nold-ai/specfact-cli::scripts/check-bundle-imports.py]
- scripts/pre_commit_code_review.py
- Now invokes specfact code-review with --level error; changes pre-commit gate behavior and what findings block commits/PRs. [::nold-ai/specfact-cli::scripts/pre_commit_code_review.py]
- Packaging / registry
- packages/specfact-backlog/module-package.yaml bumped 0.41.17 → 0.41.21; registry/index.json, checksum, and signature updated to reference specfact-backlog-0.41.21 artifact. Consumers: any module installer/publish pipeline. [::nold-ai/specfact-cli::packages/specfact-backlog/module-package.yaml] [::nold-ai/specfact-cli::registry/index.json] [::nold-ai/specfact-cli::registry/modules/specfact-backlog-0.41.21.tar.gz.sha256] [::nold-ai/specfact-cli::registry/signatures/specfact-backlog-0.41.21.tar.sig]
- Tests exercising changed behavior
- tests/unit/specfact_backlog/test_sync_command.py — verifies force/backup behavior for external baseline files. [::nold-ai/specfact-cli::tests/unit/specfact_backlog/test_sync_command.py]
- tests/unit/specfact_backlog/test_map_fields_command.py — verifies map-fields preserves unrelated YAML sections and fails safely on malformed YAML. [::nold-ai/specfact-cli::tests/unit/specfact_backlog/test_map_fields_command.py]
- tests/unit/specfact_backlog/test_refine_adapter_contract.py — updated to pass adapter context and BacklogFilters to refined fetch call. [::nold-ai/specfact-cli::tests/unit/specfact_backlog/test_refine_adapter_contract.py]
Notes / Risk surface
- BacklogAdapter and BacklogFilters are core contracts used across adapters/commands/tests in this repo; the TYPE_CHECKING conditional re-exports and the stricter TYPE_CHECKING detection in scripts/check-bundle-imports.py affect type checking and static-analysis tooling. Confirm that runtime import resolution remains correct and static scanners (CI) align with the new guard parsing.
- The new sync behavior is additive (requires explicit --force to overwrite external baseline) but changes command ordering (pre-write check before network fetch). Consumers that invoked sync expecting overwrite-on-write may need explicit flag use; tests already cover intended behavior.
No external repositories were present/queried; all relevant consumers and artifacts are inside nold-ai/specfact-cli.
🔇 Additional comments (16)
scripts/check-bundle-imports.py (1)
82-110: TYPE_CHECKING-aware import scan update looks correct.Line 98 cleanly skips type-check-only guarded imports while still traversing
elsenodes, preserving runtime boundary enforcement.packages/specfact-backlog/src/specfact_backlog/backlog/filters.py (1)
9-13: Adapter boundary re-export pattern is solid.Lines 9-13 keep runtime resolution behavior intact while exposing the symbol cleanly for type-checking flows.
packages/specfact-backlog/src/specfact_backlog/backlog/adapters/interface.py (1)
9-13: Core adapter contract re-export remains safe and consistent.Lines 9-13 preserve the runtime contract while improving static typing ergonomics for adapter consumers.
tests/unit/specfact_backlog/test_refine_adapter_contract.py (1)
46-58: Contract-level test update is aligned with current fetch API usage.Lines 46-58 correctly exercise
_fetch_backlog_itemsvia_AdapterContextplusBacklogFilters, which is the expected adapter boundary.scripts/pre_commit_code_review.py (1)
114-115:--level errorinvocation is valid and consistent with the gated CLI contract.This flag pair is supported by the review command and keeps the pre-commit call deterministic.
packages/specfact-backlog/module-package.yaml (1)
2-2: Module manifest bump and integrity refresh look coherent.Version and integrity fields were updated together, matching expected signed-manifest workflow for a bundle release.
Also applies to: 30-31
registry/index.json (1)
19-21: Registry entry update is consistent with the backlog bundle release bump.
latest_version, artifact path, and checksum move in lockstep fornold-ai/specfact-backlog.docs/getting-started/tutorial-backlog-quickstart-demo.md (1)
51-51: Path corrections are accurate and improve quickstart reliability.The updated config references now match backlog command behavior under
.specfact/.Also applies to: 69-69
docs/bundles/backlog/delta.md (1)
34-34: Delta baseline guidance now correctly reflects sync ownership rules.The default path and external-overwrite/backup behavior are documented clearly and match runtime behavior.
Also applies to: 42-42
docs/bundles/backlog/overview.md (1)
59-67: Ownership model section is clear and implementation-aligned.This accurately documents managed vs user-owned backlog artifacts and the external baseline overwrite guard.
openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-add/spec.md (1)
5-22: Spec requirement framing is tight and testable.The scenarios clearly enforce subtree-only updates and preservation of unrelated
.specfactconfig state.packages/specfact-backlog/src/specfact_backlog/backlog_core/commands/sync.py (1)
34-76: Safety gate and recovery-backup flow are correctly implemented.The external overwrite guard, explicit
--force-baseline-overwrite, and pre-fetch enforcement (before Line 201) match the intended ownership boundary behavior.Based on learnings, paired-core integration should stay scoped to sanctioned external artifacts; this implementation preserves that scope.
Also applies to: 179-201
openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-sync/spec.md (1)
5-20: Spec update is aligned with runtime behavior.The managed
.specfactvs external-target split and non-silent-overwrite requirement are clear and consistent with the sync command changes.README.md (1)
38-65: Gate and signing guidance refresh looks good.The
--level errorgovernance update and the clarified signature/versioning workflow improve contributor-facing accuracy and usability.Also applies to: 66-87
openspec/changes/project-runtime-01-safe-artifact-write-policy/design.md (1)
26-79: Design boundary and rollout strategy are well-scoped.The decision set cleanly separates sanctioned external-path contract reuse from
.specfactownership semantics and keeps first adoption backlog-focused.Based on learnings, paired-core workflow semantics should remain scoped and not be widened without matching public artifacts; this design follows that constraint.
tests/unit/specfact_backlog/test_sync_command.py (1)
14-47: Targeted sync safety coverage is solid.These tests correctly pin both critical behaviors: refusal without force and overwrite-with-backup integrity when force is provided.
Also applies to: 49-85
…wn providers - When both github and ado are selected, print the GitHub informational message then proceed with ADO instead of silently skipping GitHub - Unknown --provider values (e.g. typos) now fail fast with an explicit error instead of silently falling back to ADO - Bump specfact-backlog to 0.41.22 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- custom-field-mapping.md: "fails safe" → "fails safely" (grammar) - proposal.md: add blank lines after ### headings (MD022) - spec.md: add blank lines after requirement headings (MD022) - tasks.md: mark 4.5 done, add PR cross-links and deferred follow-up note - TDD_EVIDENCE.md: add sign + verify entries for version 0.41.21 - test_map_fields_command.py: extract _setup_ado_map_fields helper to eliminate repeated payloads/fake_get/args across three tests - Bump specfact-backlog to 0.41.23 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
chore(modules): auto-sign module manifests
chore(modules): auto-sign module manifests
chore(registry): publish changed modules
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
chore(registry): publish changed modules
Summary
Adopts ownership-aware write safety for
specfact-backlogexternal baseline files and.specfactconfig paths, paired with core changeprofile-04-safe-project-artifact-writes.Refs:
project-runtime-01-safe-artifact-write-policyScope
packages/registry/index.json,packages/*/module-package.yaml).github/workflows/*)docs/*,README.md,AGENTS.md)scripts/sign-modules.py,scripts/verify-modules-signature.py)Bundle Impact
nold-ai/specfact-backlog:0.41.17 -> 0.41.21All other bundles: unchanged.
Changes
backlog sync:_prepare_baseline_writenow runs before_fetch_current_graph, so an unprotected external baseline file blocks the command before any network call is made. External files outside.specfactrequire--force-baseline-overwrite; a timestamped backup is written to.specfact/recovery/automatically.backlog map-fields: Config updates preserve unrelated YAML sections instead of rewriting the whole file; invalid YAML in an existing mapping file exits cleanly rather than overwriting.scripts/check-bundle-imports.py:_is_type_checking_guardnow matches only bareTYPE_CHECKINGor exactlytyping.TYPE_CHECKING, rejecting lookalikes such assettings.TYPE_CHECKING.scripts/pre_commit_code_review.py: Block 2 code review gate now passes--level errorso warnings alone do not block commits.Validation Evidence
Required local gates
hatch run formathatch run type-checkhatch run linthatch run yaml-linthatch run check-bundle-importshatch run contract-test— 654 passedhatch run smart-test— 654 passedSignature + version integrity (required)
hatch run verify-modules-signature --payload-from-filesystem --enforce-version-bumppasses (targetsdev)0.41.17→0.41.21)devCode review
hatch run specfact code review run --level error --json --out .specfact/code-review.changed.json --scope changed→ 0 findings, 0 blocking on changed filesopenspec/changes/project-runtime-01-safe-artifact-write-policy/TDD_EVIDENCE.md)CI and Branch Protection
verify-module-signaturessign-modules-on-approval(on approval, same-repo PRs todev/mainonly)quality (3.11)quality (3.12)quality (3.13)Docs / Pages
docs/)specfact-clidocs updated (if applicable) — deferred; paired core PR handles the core-side narrativeChecklist
--force-baseline-overwriteis additive