Skip to content

fix(add): accept qualified position IDs and make --dry-run resolve placement - #55

Merged
fohara merged 1 commit into
mainfrom
fix/53-qualified-position-ids
Aug 11, 2026
Merged

fix(add): accept qualified position IDs and make --dry-run resolve placement#55
fohara merged 1 commit into
mainfrom
fix/53-qualified-position-ids

Conversation

@fohara

@fohara fohara commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #53.

--before/--after rejected the ID lash prints

lash show and lash list qualify IDs with their file (index#beta-task), so
that is the string people paste back into --before. It failed with "task not
found", which reads as the task being missing rather than the argument being
spelled the way the tool spells it — and --depends-on on the same command
line accepts the qualified form, so one invocation could need both.

Position IDs now go through PlacementResolver::local_position_id, which
strips a file# qualifier when it names the target file and errors when it
names a different one. Accepting the qualifier is not the same as ignoring it:
a qualifier pointing elsewhere means the caller expected the task in another
file, and positioning against whatever local task shares the slug would be
silently wrong.

The qualifier matches the file's @id, its name with or without .md, and any
trailing portion of its path; a #task: prefix on the local part is tolerated
because that is how @depends-on references are written.

The not-found error now names the IDs that do exist at that level, since the
bare "not found" was misleading precisely when the task did exist.

--dry-run did not validate the position

Dry run printed the request back field by field and exited 0. It never opened
the target file, so it passed for a --before naming a task that did not
exist — a false green on the one thing it is for.

create_task now splits into plan_task (load, validate, resolve placement)
and the emit that follows. Dry run calls plan_task, so there is no separate
dry-run path left to drift out of agreement with the real one. It also reports
the resolved insert line rather than the argument it was handed, stated as a
lower bound when the emitter still has to step past a preceding task's
free-text body.

Tests

  • 12 unit tests in placement.rs covering every accepted qualifier spelling,
    the cross-file rejection, and the new error content
  • 10 integration tests in add_command_test.rs covering both halves end to end,
    including that a failing dry run writes nothing and a passing one writes
    nothing either

Full workspace suite passes; clippy and fmt clean.

…acement

--before/--after now take the file#slug form that lash show prints, and
--dry-run runs the same load/validate/resolve path as a real add instead
of echoing the request back.

Fixes #53
@fohara
fohara merged commit 34c9ce3 into main Aug 11, 2026
21 checks passed
@fohara
fohara deleted the fix/53-qualified-position-ids branch August 11, 2026 23:03
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.

lash add --before/--after rejects the qualified file#slug ID that lash itself prints, and --dry-run does not catch it

1 participant