refactor(server): fold in PM review notes on classify_path

- classify_path now Rejects a collection slug containing '.' (mirrors
  OrgCollections::validate, plan L317, and item_path's documented contract,
  plan L990). Unreachable today since git normalizes './' away, but keeps the
  pre-receive hook self-defensive against path traversal.
- Rename test item_write_nested_slug_takes_leading_segment_only ->
  item_write_nested_slug_is_rejected (it asserts Rejected; old name misled).
- Add dotted_slug_is_rejected covering the new guard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5brcDrT35r5GaJySXD5ja
This commit is contained in:
adlee-was-taken
2026-06-19 23:06:48 -04:00
parent 675b7836e1
commit 2dd5d79f36
2 changed files with 19 additions and 2 deletions

View File

@@ -32,6 +32,13 @@ pub fn classify_path(path: &str) -> PathClass {
if slug.is_empty() {
return PathClass::Rejected("empty collection slug in items path".to_string());
}
// Defense-in-depth: mirror `OrgCollections::validate` — a slug containing
// '.' (e.g. a `..`/`.` path-traversal attempt) is structurally invalid.
// git normalizes most `./` away before the hook sees the path, so this is
// unreachable today; it keeps the hook self-defensive regardless.
if slug.contains('.') {
return PathClass::Rejected(format!("invalid collection slug: {:?}", slug));
}
return PathClass::Item { collection: slug.to_string() };
}