Skip to content

feat: typed task-relationship link substrate (ADR 0042 phase 1)#3550

Merged
matthiasn merged 1 commit into
mainfrom
feat/task-dependency-links-p1
Jul 23, 2026
Merged

feat: typed task-relationship link substrate (ADR 0042 phase 1)#3550
matthiasn merged 1 commit into
mainfrom
feat/task-dependency-links-p1

Conversation

@matthiasn

@matthiasn matthiasn commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Phase 1 (of 3 active phases) of the plan in docs/implementation_plans/2026-07-23_task_dependency_links.md — the link substrate only, ships alone ahead of any UI writes per ADR 0042's old-build compatibility window.
  • Adds blocks/followsUp/duplicates/fixes/supersedes as new EntryLink union variants on the existing linked_entries table (no schema change) plus an EntryLinkType enum with a buildLink factory.
  • linkedDbEntity derives the new type-column strings; typedLinksForTaskIds is a new type-scoped batch query (both directions, mirrors basicLinksForEntryIds's discipline).
  • createLink gains an optional linkType parameter (defaults to basic, zero call-site churn) and runs a bounded local cycle guard before creating a blocks edge (ADR 0042 §5).
  • No UI, no ready-frontier/agent integration yet — those are Phases 2 and 3, not included here.

Test plan

  • flutter analyze clean project-wide
  • 268 tests green across the touched files: variant round-trips + type-column tagging (entry_link_test.dart), query direction/type-scoping/tombstone-exclusion (database_links_ratings_test.dart), cycle-guard scenarios — self-loop, 1-hop, 2-hop, dedup, inbound-link filtering (persistence_entries_test.dart), facade delegation (persistence_logic_test.dart), a genuine sync round-trip through SyncEventProcessor against a real in-memory DB, and a fallback-union test proving an unknown future type degrades to BasicLink without crashing (sync_event_processor_journal_handlers_test.dart)

Summary by CodeRabbit

  • New Features

    • Added typed task relationships: blocks, follows up, duplicates, fixes, and supersedes.
    • Added support for creating, storing, syncing, and querying links by relationship type.
    • Prevented creation of circular “blocks” relationships.
  • Bug Fixes

    • Unknown future relationship types now safely fall back to a basic link.
    • Link queries now correctly deduplicate results and exclude deleted links.
  • Tests

    • Added coverage for serialization, database persistence, synchronization, filtering, and cycle prevention.

Adds blocks/followsUp/duplicates/fixes/supersedes as new EntryLink union
variants on the existing linked_entries substrate, per ADR 0042 and the
implementation plan. Model and storage only, ships alone ahead of any UI
writes to open the old-build compatibility window (fallbackUnion: 'basic'
degrades unknown types on old builds).

- EntryLink gains 5 new variants + an EntryLinkType enum/buildLink factory
- linkedDbEntity derives the new type-column strings
- typedLinksForTaskIds: type-scoped batch query, both directions
- createLink takes an optional linkType (defaults to basic, no call-site
  churn) and runs a bounded local cycle guard before creating a blocks edge
- Sync round-trip and fallback-union tests confirm typed links survive
  serialize/receive/upsert and degrade safely on unknown future types
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The EntryLink union now supports five typed relationship variants with JSON and database discriminator support. Persistence accepts link types, queries typed links in both directions, and applies bounded cycle detection to blocks links. Tests cover serialization, database queries, persistence, and sync fallback behavior.

Typed entry links

Layer / File(s) Summary
Link model and serialization
lib/classes/entry_link.dart, lib/classes/entry_link.freezed.dart, lib/classes/entry_link.g.dart, lib/database/conversions.dart, test/classes/entry_link_test.dart
Adds blocks, followsUp, duplicates, fixes, and supersedes variants, typed construction, generated serialization, pattern matching, and database type mappings.
Typed link queries and cycle protection
lib/database/database_links_ratings.dart, lib/logic/persistence_entries.dart, lib/logic/persistence_logic.dart
Adds bidirectional typed-link queries and forwards EntryLinkType through link creation, with bounded cycle detection for blocks links.
Persistence and sync validation
test/database/database_links_ratings_test.dart, test/logic/persistence_entries_test.dart, test/logic/persistence_logic_test.dart, test/features/sync/matrix/sync_event_processor_journal_handlers_test.dart
Tests typed queries, cycle prevention, persisted concrete variants, sync round-trips, and fallback of unknown runtime types to BasicLink.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding typed task-relationship link support for ADR 0042 phase 1.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/task-dependency-links-p1

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/database/conversions.dart (1)

260-269: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a shared constant for the EntryLinkType → persisted type-name mapping. Both sites independently hardcode 'BlocksLink' (and siblings) as literal strings with no single source of truth, so a future rename could silently desync them without a compiler error.

  • lib/database/conversions.dart#L260-L269: extract the EntryLinkType → type-string mapping (e.g. as an EntryLinkType extension getter) instead of inline literals in link.map(...).
  • lib/logic/persistence_entries.dart#L258-L284: reuse the same mapping instead of the independent const {'BlocksLink'} literal in _wouldCreateBlocksCycle.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/database/conversions.dart` around lines 260 - 269, Create one shared
EntryLinkType-to-persisted-name mapping, preferably as an EntryLinkType
extension getter, and update the link.map(...) conversion in
lib/database/conversions.dart lines 260-269 to use it instead of inline
literals. Update _wouldCreateBlocksCycle in lib/logic/persistence_entries.dart
lines 258-284 to reuse the same mapping rather than its independent const
{'BlocksLink'} literal.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/database/conversions.dart`:
- Around line 260-269: Create one shared EntryLinkType-to-persisted-name
mapping, preferably as an EntryLinkType extension getter, and update the
link.map(...) conversion in lib/database/conversions.dart lines 260-269 to use
it instead of inline literals. Update _wouldCreateBlocksCycle in
lib/logic/persistence_entries.dart lines 258-284 to reuse the same mapping
rather than its independent const {'BlocksLink'} literal.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8bd6ec41-9265-44d8-8e43-fe68c00ac431

📥 Commits

Reviewing files that changed from the base of the PR and between ac70407 and ffcd933.

📒 Files selected for processing (12)
  • lib/classes/entry_link.dart
  • lib/classes/entry_link.freezed.dart
  • lib/classes/entry_link.g.dart
  • lib/database/conversions.dart
  • lib/database/database_links_ratings.dart
  • lib/logic/persistence_entries.dart
  • lib/logic/persistence_logic.dart
  • test/classes/entry_link_test.dart
  • test/database/database_links_ratings_test.dart
  • test/features/sync/matrix/sync_event_processor_journal_handlers_test.dart
  • test/logic/persistence_entries_test.dart
  • test/logic/persistence_logic_test.dart

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.21%. Comparing base (ac70407) to head (ffcd933).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3550   +/-   ##
=======================================
  Coverage   99.21%   99.21%           
=======================================
  Files        1761     1761           
  Lines      129098   129148   +50     
=======================================
+ Hits       128087   128137   +50     
  Misses       1011     1011           
Flag Coverage Δ
glados 14.25% <9.61%> (-0.01%) ⬇️
standard 98.95% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant