Skip to content

spec/validate.py accepts a tree source that carry.py refuses, comparing "." as a raw string #1445

Closed

Description

@ptr727

Found while fixing #1443 (2026-09-08). A tree source spelled "./" or ".///." passes spec/validate.py and then fails in scripts/carry.py, so a manifest author gets a green validator and a failing carrier.

The mechanism

spec/files.schema.json constrains a tree source as:

"source": { "type": "string", "minLength": 1, "not": { "const": "." } }

That forbids "" and "." and nothing else, so "./" and ".///." are schema-valid.

spec/validate.py adds two of its own rules, and both let those through:

  • the root check is value == ".", a raw-string compare, so "./" is not equal to "." and passes
  • (ROOT / source).is_dir() is true for "./", since that resolves to the repository root

So validate.py reports green while its own error text for the rule says a source "must be below the repository root".

scripts/carry.py refuses both, because relative_root compares PurePosixPath objects rather than strings, and PurePosixPath("./") == PurePosixPath(".").

Why it matters now

build_dist.py grew its own guard in #1443, which refuses any tree source reducing to the repository root by its own name. That closes the hazard for build_dist.py's consumer only. The validator is still the gate a manifest author runs first, and it is the one that should have caught it.

Suggested shape

Compare normalized paths rather than raw strings in validate.py's tree-source rule, the way carry.py already does. build_dist.py's tree_source() is a third implementation of the same reduction, so this is also a candidate for one shared helper rather than three.

Not a live defect today

spec/files.json declares one tree, source: ".github/skills", so nothing in the fleet currently trips this.

Activity

  1. added
    gateA rule with no mechanical check, or a check that misses a shape
    on Sep 8, 2026
  2. added a commit that references this issue on Sep 9, 2026
    8195c43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    gateA rule with no mechanical check, or a check that misses a shape

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions