Skip to content

adopt-project.py plan: --spec-path and --code-path have no help=, so plan --help and docs/cli.md print two bare lines for the flags that choose where each leg is mounted, and say nothing of the two refusals plan makes on them before anything is created (adopt-leg-path-collides, adopt-bad-leg-path), which #288 is documenting for the scaffold's twins #340

Closed

Description

@brettheap

Lane: openreposhape-4 (openRepoShape-4)

Found by this lane's adversarial review of #288 (PR #309, head 72d1cc2; "Out of scope, named not fixed": "adopt-project.py plan's own --spec-path/--code-path have no help= (the PR body already says so)"). Re-verified on main c7c02fa by reading docs/cli.md (generated from every tool's --help) and by running plan against a one-commit local source repository. It is a docs gap and changes no behaviour. #309 is scoped to scaffold-project.py and does not touch adopt-project.py. Lane 5's open #314 (fix/scaffold-manifest-values, head ab66bc0) adds a help= to plan's --elected-by only. So this survives both landings. Not claimed: the check and execute sides of a hand-edited plan's spec_path: / code_path: (#169 and #172 closed those), and Windows.

What is wrong. plan.add_argument("--spec-path", default="spec") and plan.add_argument("--code-path", default="code") (adopt-project.py:4288-4289 at c7c02fa) carry no help=. These two values are where the legs are mounted in the assembly root and what the plan records as spec_path: / code_path:. plan refuses two kinds of value for them before it writes a plan, and its --help says nothing of either:

# $U: a clean checkout at c7c02fa. docs/cli.md is generated from every tool's --help.
sed -n '/^#### `adopt-project.py plan`/,/^#### `adopt-project.py check`/p' "$U/docs/cli.md" | grep -e '--spec-path\|--code-path'
#                                [--spec-path SPEC_PATH] [--code-path CODE_PATH]
#     --spec-path SPEC_PATH
#     --code-path CODE_PATH
R=$(mktemp -d)
git init -q -b main "$R/Atlas" && mkdir "$R/Atlas/docs" && echo spec > "$R/Atlas/docs/spec.md"
git -C "$R/Atlas" add -A && git -C "$R/Atlas" -c user.name=t -c user.email=t@t commit -qm init
cd "$R"
plan() {
    python3 "$U/adopt-project.py" plan --source "$R/Atlas" --project Atlas --org testorg \
        --elected-by 'Test Human' --out "$R/plan.yaml" "$@" 2>&1 | cut -c1-150
    echo "exit ${PIPESTATUS[0]}"
}
plan --spec-path contracts
#   REFUSED adopt-leg-path-collides: --spec-path 'contracts' contains `contracts/spec-pin.yaml` and 3 more. The shape writes them into the assembly root,
#   Remediation: nothing here picks a path for you, so pass another one yourself. A leg path neither is, holds nor lies inside, whatever the case, a path
#   exit 2
plan --spec-path spec/
#   REFUSED adopt-bad-leg-path: --spec-path is 'spec/', which is not a canonical leg path: Git records a mount without its `.` segments (a leading `./`),
#   Remediation: nothing here rewrites a path for you, so correct the value yourself. A leg path is relative and POSIX: one or more plain segments such as
#   exit 2
plan --code-path project.yaml
#   REFUSED adopt-leg-path-collides: --code-path 'project.yaml' is `project.yaml`. The shape writes it into the assembly root, and `execute` would write i
#   exit 2

The refusals are right, and both say "nothing here picks a path for you". The gap is that a reader of plan --help or docs/cli.md, the flag-level reference AGENTS.md points every assistant at, learns neither what the flags are for nor the default, nor that contracts, project.yaml or a trailing / will be refused. #288 found exactly this for scaffold-project.py's --spec-path / --code-path. #309 answers it there with a help= naming the default and the collision rule ("A path that is, holds or lies inside a FILE the shape writes into the root is refused before anything is created: project.yaml is one, and contracts holds several."). That leaves the two front doors that take the same two flags documented differently.

plan's other options without a help=, for the author's scoping (decision 3): --org, --id, --visibility (choices only), --tracking-branch, --path-policy, --out and --work-dir. check has --work-dir, and execute has --source and --work-dir.

Why. The flags predate docs/cli.md (#97), which renders a flag with no help= as a bare line. The two leg-path refusals were added later, by #169 (adopt-bad-leg-path) and #172 (adopt-leg-path-collides), and neither change touched the flags' help, as #197 and #241 did not on the scaffold side (#288's "Why").

What it should do. plan --help says what --spec-path and --code-path are and what plan refuses on them. The decisions are the author's:

  1. The words. AGENTS.md, README and scaffold-project.py --help: say that a --spec-path or --code-path that is, holds or lies inside a file the shape writes, and a --pin of spec, code or shape or of one product twice, are refused before anything is created, and name those three in the pin refusal's remediation, so an agent briefed from AGENTS.md can say so before it runs the scaffold (#288) #309's scaffold text is the model: "where the spec leg is mounted, as a path in the assembly root (default: spec)", then the refusal rule. Decide whether to name the canonical-path rule too (a trailing /, ./ or // is adopt-bad-leg-path), which AGENTS.md, README and scaffold-project.py --help: say that a --spec-path or --code-path that is, holds or lies inside a file the shape writes, and a --pin of spec, code or shape or of one product twice, are refused before anything is created, and name those three in the pin refusal's remediation, so an agent briefed from AGENTS.md can say so before it runs the scaffold (#288) #309 leaves out on the scaffold side, and whether to name the codes in --help or only describe them.
  2. AGENTS.md. Its "Adopting an existing repository" section never names --spec-path / --code-path. Decide whether it needs the sentence AGENTS.md, README and scaffold-project.py --help: say that a --spec-path or --code-path that is, holds or lies inside a file the shape writes, and a --pin of spec, code or shape or of one product twice, are refused before anything is created, and name those three in the pin refusal's remediation, so an agent briefed from AGENTS.md can say so before it runs the scaffold (#288) #309 adds to section 2 for the scaffold ("Relay the refusal and ask the human for the value; never choose another yourself"). tests/test_repo_hygiene.py caps AGENTS.md: 477 lines after AGENTS.md, README and scaffold-project.py --help: say that a --spec-path or --code-path that is, holds or lies inside a file the shape writes, and a --pin of spec, code or shape or of one product twice, are refused before anything is created, and name those three in the pin refusal's remediation, so an agent briefed from AGENTS.md can say so before it runs the scaffold (#288) #309, 485 once lane 3's fix/adopt-record-submodule-placement also lands. Any added line raises the cap with a dated entry.
  3. Scope. These two flags only, or every option of plan, check and execute listed above that prints a bare line.
  4. docs/cli.md must be regenerated with scripts/render-cli-reference.py, inside a real checkout (tests/test_cli_reference.py fails otherwise). scaffold-project.py and adopt-project.py ask the project's YAML reader and validate-manifest.py about the manifest's values before anything exists, so --id null, --tracking-branch true and a blank --elected-by are refused (#258, #261) #314 edits the same plan.add_argument block, so whichever of the two lands second resolves the argparse lines and regenerates the file rather than hand-merging it.

How to test. There is no behaviour to test. tests/test_cli_reference.py holds docs/cli.md to --help. Hold each new sentence against the tool, as #288's review did for the scaffold: run plan with contracts, contracts/x (accepted), project.yaml, project.yaml/x, spec/ and the defaults, and check that the help claims neither more nor less than what is refused.

Verified at main c7c02fa (adopt-project.py sha256 406bb745…, docs/cli.md 61c6995f…); neither #309 (2ea1717) nor #314 (ab66bc0) adds these two help= strings.

Related:

Activity

  1. brettheap commented on Oct 12, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-2, session 0279452a-ea8e-486f-bf99-698cb0a9bb2f@Eagle, 2026-10-12T15:36:05Z, for #340

    Logged in lanes/log/openRepoShape-2.md at f2ad770cda2eb9af85603118c3a1223956eeb6e0.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#340:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#340"`, kept where the row or its body names `#340`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `340` as a whole token:
       none
    
  2. added this to the v1.0.0 milestone on Oct 12, 2026
  3. added 3 commits that reference this issue on Oct 12, 2026
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions