Skip to content

resolve-frontmatter.sh should resolve manifest path relative to the repo root, not cwd #624

Description

@williamthorsen

Problem

resolve-frontmatter.sh reads the branch manifest from a hardcoded relative path (.agents/{sanitized-branch}.branch-manifest.json at scripts/resolve-frontmatter.sh:397). Because the path is relative, it resolves against \$PWD. When the script is invoked from any subdirectory of the repository, the lookup fails with branch manifest not found at .agents/<branch>.branch-manifest.json — run get-session-context first, even though the manifest exists at <repo-root>/.agents/<branch>.branch-manifest.json.

This is distinct from #621, which addresses the case where the manifest does not exist at all. The bug here is a path-resolution defect: the manifest is present and valid, but the script cannot locate it from the caller's cwd.

Context

Encountered today while running the review-branch skill against node-monorepo-tools. The skill ran a build verification step that left cwd inside packages/nmr/. The subsequent frontmatter resolution failed:

$ ~/.claude/scripts/resolve-frontmatter.sh --skill review-branch --interactive true --model "claude-opus-4-7" --extra "author=…"
resolve-frontmatter.sh: branch manifest not found at .agents/400.branch-manifest.json — run get-session-context first

The manifest existed at /Users/william/repos/oss/node-monorepo-tools.400/.agents/400.branch-manifest.json the whole time. The workaround was to prepend cd <repo-root> && to the invocation, which triggers an extra permission prompt and is invisible to skills that document the script as callable directly.

The misleading error message also implies that get-session-context was not run, when in fact it was — the failure has nothing to do with the manifest's existence.

Considerations

  • The script already calls git rev-parse --abbrev-ref HEAD (scripts/resolve-frontmatter.sh:388) to determine the branch, so a git-repo precondition is already in place. Adding git rev-parse --show-toplevel introduces no new dependency.
  • The get-session-context skill writes the manifest at <repo-root>/.agents/… because it derives the path from Working directory: in its system prompt. The reader should mirror this convention by anchoring at the repo root.
  • Inside a git worktree, git rev-parse --show-toplevel returns the worktree path, which is the correct anchor — the worktree's .agents/ directory is where the manifest is written.
  • Outside a git repository, git rev-parse --show-toplevel fails. The script should still produce a clear error in that case (the existing current_branch() helper already returns non-zero in this scenario; the same handling can apply).

Proposed solution

In read_manifest() (scripts/resolve-frontmatter.sh:393-400), resolve the manifest path against the repo root rather than \$PWD:

read_manifest() {
  local branch=\"\$1\"
  local sanitized repo_root
  sanitized=\$(sanitize_branch \"\$branch\")
  repo_root=\$(git rev-parse --show-toplevel 2>/dev/null) || return 1
  local path=\"\$repo_root/.agents/\$sanitized.branch-manifest.json\"
  [[ -r \"\$path\" ]] || return 1
  cat \"\$path\"
}

Update the failure message at scripts/resolve-frontmatter.sh:154 to include the absolute path the script tried, so future failures are unambiguous about whether the manifest is missing vs. mislocated.

Acceptance criteria

  • resolve-frontmatter.sh successfully reads the manifest when invoked from any subdirectory of the repository (verified by invoking from a nested package directory).
  • The failure message names the absolute path that was checked.
  • Behavior outside a git repository is unchanged (clear error, non-zero exit).
  • Behavior inside a git worktree resolves against the worktree's .agents/, not the primary working tree's.
  • New/modified behavior is covered by tests (shellspec coverage for the cwd-independent lookup).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions