[Feature] Add readable task identity and spec update flows#1
Conversation
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.
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds 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. ChangesSimilarity & alias projection
Estimated code review effort: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (32)
.gitignoreAGENTS-reference.mdAGENTS.mdCargo.tomlREADME.mdSKILLS/tasque/SKILL.mdSKILLS/tasque/references/command-reference.mdsrc/app/service.rssrc/app/service_create_update.rssrc/app/service_query.rssrc/app/service_specs.rssrc/app/service_types.rssrc/app/service_utils.rssrc/cli/commands/spec.rssrc/cli/commands/task_create.rssrc/cli/commands/task_find.rssrc/cli/parsers.rssrc/cli/render.rssrc/domain/alias.rssrc/domain/ids.rssrc/domain/mod.rssrc/domain/projector_tasks.rssrc/domain/query.rssrc/domain/resolve.rssrc/domain/similarity.rssrc/types.rstests/common/mod.rstests/create_children_batch.rstests/projector_invariants.rstests/readable_identity.rstests/spec_workflow.rstests/sync_hooks_cli.rs
There was a problem hiding this comment.
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) andtsq spec --patch(apply unified diff in-memory with guardrails) backed bydiffy. - 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_candidatesis persisted into thetask.createdevent payload by serializing full clonedTaskobjects. 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.
There was a problem hiding this comment.
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
📒 Files selected for processing (5)
src/app/service_create_update.rssrc/cli/commands/spec.rssrc/domain/ids.rstests/readable_identity.rstests/verb_first_task_commands.rs
There was a problem hiding this comment.
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
📒 Files selected for processing (2)
src/domain/ids.rstests/verb_first_task_commands.rs
Summary
Adds readable task identity improvements and agent-safe spec editing flows.
Changes
tsq spec --updatefor whole-spec replacement andtsq spec --patchfor in-memory unified-diff updates to the attached spec.diffyfor patch parsing/apply and guarded patch behavior to one attached spec file.Testing
cargo fmt --checkcargo testcargo clippy --all-targets -- -D warningscargo run --quiet -- spec --helpReview Notes
src/app/service_specs.rspatch guardrails andsrc/app/service_create_update.rsduplicate/alias behavior closely.main: readable identity/duplicate detection and spec update/patch support.