Operation robustness: one dangling symlink aborts a whole self-verify/weigh run; renumber apply has no partial-failure rollback #49
Labels
No labels
already-shipped
bug
documentation
duplicate
enhancement
good first issue
help wanted
in progress
invalid
needs-decision
proposal
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: crenshawdev/cadence#49
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: low · Area: self-verify / renumber · surfaced in the post-v1.2.0 cross-model review sweep (bundled: two operation-resilience gaps). Related to #44 (the other self-verify robustness gap).
1. One dangling symlink aborts an entire self-verify / weigh run
cadence-core/bin/lib/surface-weight.mjs:31,40,48andcadence-core/bin/self-verify.mjs:117guard files withf.endsWith('.md') && statSync(f).isFile().statSyncon a dangling.mdsymlink underagents/,skills/, orcadence-core/workflows/throwsENOENT, which propagates out of the generator. The consumers' top-level try catches it and the whole run collapses to a single opaque{ok:false, reason:"internal"}— every real lint/weight result for that run is lost, not just the bad entry.2.
renumberapply has no partial-failure rollbackcadence-core/bin/planning.mjs:682-689: apply runsgit rm→ the directory moves → the file rewrites in sequence, with no transaction. AgitMvfailure partway (permissions, collision, cross-device) leaves somephases/Kdirectories moved and the ROADMAP/REQUIREMENTS/STATE not yet rewritten — an inconsistent tree — surfaced only as a genericfail('internal')that names neither what moved nor that the operation was partial. The--dry-rungate reduces likelihood but there is no rollback and no partial-state report.Fix direction
Skip an entry whose
statSyncfails (e.g.statSync(f, { throwIfNoEntry: false })or a try/catch) so one bad symlink can't sink the run; and forrenumberapply, either stage the moves for rollback on failure or, at minimum, report which moves completed so a partial tree can be repaired deliberately.