Skip to content

Tropfile reference says global config excludes project section, but implementation allows it #54

@plx

Description

@plx

Problem Statement

The docs and implementation disagree on whether project is valid in global config (~/.trop/config.yaml).

Documentation says global config excludes project (and reservations), but runtime validation currently allows project from any source. This creates ambiguity for users and makes config behavior hard to reason about.

Concrete mismatch:

  • Docs: plugins/trop/skills/trop-reference/references/tropfile-reference.md:19 says project is "trop.yaml only".
  • Docs: plugins/trop/skills/trop-reference/references/tropfile-reference.md:97 says global config uses same schema minus project and reservations.
  • Impl: trop/src/config/validator.rs:36-40 explicitly allows project from any source.
  • Impl test: trop/src/config/validator.rs:346-354 (test_validate_project_in_user_config) enforces this permissive behavior.
  • Related design constraint: trop/src/config/builder.rs:133-142 uses a coarse is_tropfile boolean, which cannot distinguish "user config provided project" vs "env/CLI provided project" after merge.

Affected Files / Lines

  • plugins/trop/skills/trop-reference/references/tropfile-reference.md:19
  • plugins/trop/skills/trop-reference/references/tropfile-reference.md:97
  • trop/src/config/validator.rs:36-40
  • trop/src/config/validator.rs:346-354
  • trop/src/config/builder.rs:133-142

Recommended Fix

Align implementation with documented/spec behavior by rejecting project (and reservations) specifically in user config at load time, before merged validation.

// trop/src/config/loader.rs
fn load_user_config(data_dir: Option<&Path>) -> Result<Option<ConfigSource>> {
    // existing path resolution...
    let config = Self::load_file(&config_path)?;

    if config.project.is_some() {
        return Err(Error::Validation {
            field: "project".into(),
            message: "project field is only valid in trop.yaml/trop.local.yaml".into(),
        });
    }

    if config.reservations.is_some() {
        return Err(Error::Validation {
            field: "reservations".into(),
            message: "reservations field is only valid in trop.yaml/trop.local.yaml".into(),
        });
    }

    Ok(Some(ConfigSource { path: config_path, precedence: 1, config }))
}

Also update validator tests so user-config-specific project is rejected, while env/CLI/programmatic project remains allowed.

Validation Strategy

  1. Add tests:
    • ConfigBuilder with custom data dir config.yaml containing project should return validation error.
    • ConfigBuilder with custom data dir config.yaml containing reservations should return validation error.
    • Existing with_config(...) / CLI-style additional config with project should still pass.
    • Env override (TROP_PROJECT) should still pass when no tropfile exists.
  2. Manual verification:
    • Create ~/.trop/config.yaml with project: foo; run a simple command (trop reserve .) and confirm clear validation error.
    • Remove project from global config; set TROP_PROJECT=foo; confirm command succeeds.
    • Put project in trop.yaml; confirm command succeeds.

Acceptance Criteria

  • Global config.yaml rejects project and reservations.
  • trop.yaml / trop.local.yaml continue to allow project and reservations as before.
  • Env/CLI project inputs continue to work.

🤖 Discovered by Codex · expanded by Codex · filed by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low priority fixes: nits, quality of life, and so on.claude-code-pluginConcerns trop's claude code plugin.discovered-by-codexIssues discovered by codex.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions