Skip to content

[Feature] Add readable task identity and spec update flows#1

Merged
BumpyClock merged 7 commits into
mainfrom
adityasharma/id-name-refinement-search
May 14, 2026
Merged

[Feature] Add readable task identity and spec update flows#1
BumpyClock merged 7 commits into
mainfrom
adityasharma/id-name-refinement-search

Conversation

@BumpyClock
Copy link
Copy Markdown
Owner

Summary

Adds readable task identity improvements and agent-safe spec editing flows.

Changes

  • Added sequential root task IDs, stable title-derived aliases, alias resolution, and duplicate detection helpers.
  • Added tsq spec --update for whole-spec replacement and tsq spec --patch for in-memory unified-diff updates to the attached spec.
  • Added diffy for patch parsing/apply and guarded patch behavior to one attached spec file.
  • Updated Tasque skill, command reference, README, and agent docs for spec update/patch workflows.
  • Added regression coverage for readable identity, duplicate detection, spec update, patch application, and stale patch rejection.

Testing

  • cargo fmt --check
  • cargo test
  • cargo clippy --all-targets -- -D warnings
  • cargo run --quiet -- spec --help
  • Manual temp-repo update flow: attach spec, update spec, verify old/new fingerprints, show updated content, check spec ok.
  • CodeRabbit review run; remaining duplicate input-type suggestion intentionally kept as semantic API clarity.

Review Notes

  • Review src/app/service_specs.rs patch guardrails and src/app/service_create_update.rs duplicate/alias behavior closely.
  • Branch includes two commits over main: readable identity/duplicate detection and spec update/patch support.

New root tasks use sequential `tsq-<number>` IDs instead of random
base32 strings. Legacy IDs remain valid. Each task gets a stable
kebab-case alias derived from its creation title, usable anywhere
a task ID is accepted (exact match or unique prefix, case-insensitive).

`tsq find similar` ranks candidate duplicates by title/alias similarity.
`tsq create` now refuses tasks similar to active existing tasks unless
`--force` is passed. Batch creates are atomic: if any incoming item is
a duplicate, no tasks are written. `tsq find search` now ranks title
matches above note hits.
--update atomically replaces an existing attached spec.
--patch applies a unified diff via diffy, rejecting stale
context and multi-file patches.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds task-title similarity utilities (ranking, blocking-duplicate detection, normalization, scoring), integrates them into domain APIs, and adds projector invariant tests covering alias normalization and collision rejection.

Changes

Similarity & alias projection

Layer / File(s) Summary
Similarity API & candidate generation
src/domain/similarity.rs
Adds similarity constants and SimilarTaskCandidate, blocking-status helper, find_similar_candidates, per-task scoring paths, alias/phrase/id match handling, and public APIs for blocking detection.
Normalization & scoring internals
src/domain/similarity.rs
Implements normalized_text, meaningful-token extraction, plural stemming, token-overlap scoring, phrase/substring scoring, and a unit test ensuring preservation of #/version tokens.
Projector alias invariants tests
tests/projector_invariants.rs
Adds tests verifying TaskCreated rejects alias collisions and self-ID aliases, normalizes explicit aliases to lowercase, and that legacy mixed-case aliases still resolve and match alias: queries.

Estimated code review effort:
🎯 3 (Moderate) | ⏱️ ~30 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.56% 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 title clearly summarizes the main changes: adding readable task identity (sequential IDs, aliases, resolution) and spec update/patch workflows, which aligns with the substantial feature additions throughout the changeset.
Description check ✅ Passed The description comprehensively covers the key changes (sequential IDs, aliases, duplicate detection, spec --update/--patch, diffy integration, documentation updates, and tests), which directly relate to the changeset modifications.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch adityasharma/id-name-refinement-search

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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.

Inline comments:
In `@src/app/service_specs.rs`:
- Around line 151-166: After reading the attached spec from disk with
read_attached_spec_content(&ctx.repo_root, &id, &attached.spec_path) you must
detect fingerprint drift before applying the patch: compute the current file
fingerprint and compare it to attached.spec_fingerprint and if they differ
return a clear drift error (e.g., Err specifying "spec has diverged" or similar)
instead of proceeding to apply_spec_patch; update the flow in the function that
calls require_attached_spec / read_attached_spec_content so write_updated_spec
is only called when the on-disk fingerprint matches attached.spec_fingerprint.

In `@src/domain/ids.rs`:
- Around line 9-26: The make_root_id function scans state.tasks every call which
is O(n); change it to use a cached max root sequential ID stored on State (e.g.,
add a max_root_seq: AtomicU64/Mutex<u64> or similar) and have
task-creation/deletion paths update that cached value when they add or remove
root tasks (use sequential_number to extract numbers and id_overflow_error for
overflow checks); then make_root_id should read and increment the cached max
(with checked_add and id_overflow_error) and probe state.tasks for collisions
only if necessary. Ensure updates to the cache occur wherever tasks are
inserted/removed so the cached value stays correct and handle
concurrency/atomicity according to State’s synchronization model.

In `@src/domain/projector_tasks.rs`:
- Around line 73-78: The code uses the payload alias as-is (via as_string) while
allocate_alias returns a lowercase normalized alias, causing inconsistency;
update the alias handling so the branch that takes the payload alias normalizes
it the same way (e.g., call the shared normalization helper or .to_lowercase()
on the alias returned by as_string) before passing it to validate_created_alias,
keeping allocate_alias, validate_created_alias and as_string usage intact.

In `@src/domain/query.rs`:
- Around line 154-157: In the match_term "alias" arm, make the comparison use a
lowercased task.alias to match match_task_text's behavior: when computing let
value = term.value.to_lowercase(), compare against task.alias.to_lowercase()
(e.g., use task.alias.to_lowercase() == value ||
task.alias.to_lowercase().starts_with(&value)) so alias comparisons are
consistently case-insensitive; update the alias branch in match_term
accordingly.

In `@src/domain/resolve.rs`:
- Around line 17-20: The comparisons assume aliases are lowercase; normalize
task.alias before comparing by replacing direct comparisons with
case-insensitive checks: in the resolve logic where raw_alias is computed
(raw_alias = raw.to_lowercase()) update the find condition to compare
task.alias.to_lowercase() == raw_alias (reference: raw_alias and
state.tasks.find closure), and in the query logic update the starts_with check
to task.alias.to_lowercase().starts_with(&value) (reference: task.alias usage in
the query handling), matching the behavior of taken_aliases_and_ids() and
is_alias_or_id_taken().
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8cb611ea-2d56-4e94-98c6-4d4c0b2486a8

📥 Commits

Reviewing files that changed from the base of the PR and between 72ccbaf and e1c61c2.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (32)
  • .gitignore
  • AGENTS-reference.md
  • AGENTS.md
  • Cargo.toml
  • README.md
  • SKILLS/tasque/SKILL.md
  • SKILLS/tasque/references/command-reference.md
  • src/app/service.rs
  • src/app/service_create_update.rs
  • src/app/service_query.rs
  • src/app/service_specs.rs
  • src/app/service_types.rs
  • src/app/service_utils.rs
  • src/cli/commands/spec.rs
  • src/cli/commands/task_create.rs
  • src/cli/commands/task_find.rs
  • src/cli/parsers.rs
  • src/cli/render.rs
  • src/domain/alias.rs
  • src/domain/ids.rs
  • src/domain/mod.rs
  • src/domain/projector_tasks.rs
  • src/domain/query.rs
  • src/domain/resolve.rs
  • src/domain/similarity.rs
  • src/types.rs
  • tests/common/mod.rs
  • tests/create_children_batch.rs
  • tests/projector_invariants.rs
  • tests/readable_identity.rs
  • tests/spec_workflow.rs
  • tests/sync_hooks_cli.rs

Comment thread src/app/service_specs.rs Outdated
Comment thread src/domain/ids.rs
Comment thread src/domain/projector_tasks.rs
Comment thread src/domain/query.rs
Comment thread src/domain/resolve.rs
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds “readable identity” improvements (sequential root IDs + stable title-derived aliases) and introduces agent-safe spec editing workflows (tsq spec --update / --patch), along with ranked search and duplicate-detection behavior to reduce accidental duplicate task creation.

Changes:

  • Introduces sequential root task IDs (tsq-<number>), stable aliases, and enhanced task ID/alias resolution (exact + prefix + ambiguity reporting).
  • Adds tsq spec --update (replace attached spec) and tsq spec --patch (apply unified diff in-memory with guardrails) backed by diffy.
  • Adds ranked search and “find similar” along with duplicate-gate behavior in create flows, plus broad regression coverage and docs updates.

Reviewed changes

Copilot reviewed 31 out of 33 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/sync_hooks_cli.rs Makes git helpers more portable by setting per-invocation safe bare repo config.
tests/spec_workflow.rs Adds coverage for spec update/patch flows and stale patch rejection.
tests/readable_identity.rs Adds end-to-end tests for sequential IDs, aliases, resolution, ranking, similarity, and duplicate gate semantics.
tests/projector_invariants.rs Adds invariant tests for alias collision rejection at projection time.
tests/create_children_batch.rs Adds ensure-mode dedup coverage for identical incoming tasks.
tests/common/mod.rs Adjusts test helper defaults to bypass duplicate gate unless explicitly testing it.
src/types.rs Bumps cache schema and adds Task.alias to the core model.
src/domain/similarity.rs Introduces similarity scoring + candidate ranking utilities.
src/domain/resolve.rs Extends task resolution to support exact alias and prefix ambiguity diagnostics.
src/domain/query.rs Adds alias query support, richer text matching, and ranking for find search.
src/domain/projector_tasks.rs Allocates/validates aliases during task creation projection.
src/domain/mod.rs Exposes new alias and similarity modules.
src/domain/ids.rs Switches to sequential root ID allocation and validates legacy IDs.
src/domain/alias.rs Adds alias generation/allocation and collision handling.
src/cli/render.rs Displays alias in task list and adjusts render-width tests for ANSI output.
src/cli/parsers.rs Updates explicit --id validation to accept sequential + legacy formats.
src/cli/commands/task_find.rs Adds tsq find similar command and rendering/JSON output.
src/cli/commands/task_create.rs Adds --force, routes batch create through atomic service API, and tightens flag validation.
src/cli/commands/spec.rs Adds --update/--patch spec actions and prints update results.
src/app/service.rs Exposes create_batch, spec_update, spec_patch, and similar service APIs.
src/app/service_utils.rs Updates root ID allocation to use sequential IDs.
src/app/service_types.rs Adds new inputs/results for spec update/patch, similar search, and batch create; extends CreateInput.
src/app/service_specs.rs Implements spec update + patch (diff parsing/apply + guardrails) and refactors spec attach/content helpers.
src/app/service_query.rs Uses new ranking for search and exposes similarity lookup.
src/app/service_create_update.rs Implements duplicate gate, atomic batch create with ensure semantics, and force bypass.
SKILLS/tasque/SKILL.md Documents new spec update/patch guidance for agents.
SKILLS/tasque/references/command-reference.md Updates CLI reference for new ID formats, aliases, similar, force, and spec update/patch.
README.md Updates user-facing command list and behavior notes for IDs/aliases/duplicate handling.
Cargo.toml Adds diffy dependency.
Cargo.lock Locks diffy and transitive deps.
AGENTS.md Notes new identity/search/duplicate-detection capabilities.
AGENTS-reference.md Updates agent reference docs for IDs, aliases, similar, and spec patch/update workflow.
.gitignore Ignores docs/superpowers/.
Comments suppressed due to low confidence (1)

src/app/service_create_update.rs:470

  • Same concern as the single-create path: duplicate_candidates is persisted into the task.created event payload by serializing full cloned Task objects. In batch mode this can multiply event-log size quickly. Prefer returning candidates in the create response or persisting only minimal candidate fields (id/alias/title/status/score/reason).
                    let duplicate_candidates = if input.force {
                        let candidates = find_similar_candidates(
                            working_state.tasks.values(),
                            title,
                            DEFAULT_SIMILARITY_MIN_SCORE,
                            DEFAULT_SIMILARITY_LIMIT,
                        );
                        if candidates.is_empty() {
                            None
                        } else {
                            Some(serde_json::json!(candidates))
                        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/cli/commands/spec.rs Outdated
Comment thread src/app/service_create_update.rs
Comment thread src/app/service_create_update.rs
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/domain/ids.rs`:
- Around line 34-39: RootIdAllocator::next_id currently increments self.next
before confirming the candidate was reserved, causing the final u64 value to
become unreachable; change the logic to derive candidate from the current
self.next, attempt to insert into reserved_ids first, and only when insert
succeeds update self.next using checked_add (or compute the incremented value
from a local copy and assign it) so that when self.next == u64::MAX the
candidate "tsq-18446744073709551615" can be returned instead of triggering
id_overflow_error; update the code paths around candidate, self.next,
reserved_ids.insert, and id_overflow_error accordingly.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 04a32a17-cf36-4b87-94a5-e9c91a242571

📥 Commits

Reviewing files that changed from the base of the PR and between f50681a and aec4e43.

📒 Files selected for processing (5)
  • src/app/service_create_update.rs
  • src/cli/commands/spec.rs
  • src/domain/ids.rs
  • tests/readable_identity.rs
  • tests/verb_first_task_commands.rs

Comment thread src/domain/ids.rs
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 32 out of 34 changed files in this pull request and generated 1 comment.

Comment thread src/domain/similarity.rs Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/domain/ids.rs`:
- Around line 48-57: next_root_number currently treats legacy digit-only IDs as
sequential because it calls sequential_number(&task.id) unconditionally; update
next_root_number to only consider IDs that pass is_sequential_root_id(&task.id)
before calling sequential_number so only new tsq-N roots contribute to max_seen,
and return id_overflow_error on overflow as before; apply the same guard change
to the analogous loop at lines 87-92 (where sequential_number is used) so legacy
numeric IDs are ignored for sequential allocation and add/update the regression
test to assert legacy IDs like "tsq-00000042" do not influence next sequential
root.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2d24887d-b933-4dff-aaf9-4088daa3be9b

📥 Commits

Reviewing files that changed from the base of the PR and between aec4e43 and fe01b9f.

📒 Files selected for processing (2)
  • src/domain/ids.rs
  • tests/verb_first_task_commands.rs

Comment thread src/domain/ids.rs
@BumpyClock BumpyClock merged commit d705629 into main May 14, 2026
2 checks passed
@BumpyClock BumpyClock deleted the adityasharma/id-name-refinement-search branch May 14, 2026 23:47
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.

2 participants