Skip to content

fmea.json/tara.json file paths truncated to basename, and sci.json emits absolute paths (§4 project-relative MUST) #77

Description

@SoundMatt

Spec reference

x-FuSa spec §4, Path relativity (MUST):

location.file MUST be a path relative to projectRoot (the --dir value), using / separators — never an absolute path.

§9.2 fmea.json: "file": "src/rules.go", // MUST. project-relative (§4 rule). §9.2 tara.json: "location": { "file": "…", "line": 42 }. §9.3 sci.json: "artifacts": [ { "file": "src/main.go", ... } ].

What actually happens

fmea.json / tara.json — basename only, not project-relative

This repo's own committed fmea.json/tara.json show only the basename, discarding the directory:

{"item": "cmd_coupling", "file": "cmd_coupling.c", "line": 121, ...}

The real project-relative path is cmd/cfusa/cmd_coupling.c (confirmed: find . -name cmd_coupling.c./cmd/cfusa/cmd_coupling.c). This is deliberate, not incidental — cmd/cfusa/cmd_tara.c's write_threat_json() explicitly does:

"      \"location\": {\"file\": \"%s\", \"line\": %d}\n"
...
cfusa_basename(a->file), a->line, last ? "" : ",");

and cmd_fmea.c's equivalent JSON writer does the same.

sci.json — absolute path when --dir is absolute

$ cfusa sci --dir /Users/matt/Documents/Coding/SoundMatt/c-FuSa --format json --output sci.json
$ python3 -c "import json; print(json.load(open('sci.json'))['artifacts'][0])"
{'file': '/Users/matt/Documents/Coding/SoundMatt/c-FuSa/cmd/cfusa/cmd_pr.c', 'hash': 'sha256:1f0b...', 'version': '0.5.1'}

For comparison, check handles the identical --dir <absolute-path> case correctly — its location.file is properly relativized even though projectRoot (correctly, per §3.2) is the absolute --dir value:

$ cfusa check --dir /Users/matt/Documents/Coding/SoundMatt/c-FuSa --format json
"projectRoot": "/Users/matt/Documents/Coding/SoundMatt/c-FuSa"
"findings":[{"location":{"file":"cmd/cfusa/cmd_qualify.c","line":473}, ...}]

So sci (new in this PR's schema-conformance pass) is a regression relative to the relativization logic check already gets right elsewhere in the same binary.

Why this matters

Both are the exact failure mode §4 exists to prevent: fingerprints/paths that aren't stable/comparable across machines and tools, and (for sci specifically) real information leakage of local filesystem layout into an artifact meant to be portable evidence.

Suggested fix

  • fmea/tara: emit a->file/fn->file (already stored relative-to---dir) directly instead of running it through cfusa_basename() for the JSON file/location.file fields (basename is fine for the human-readable failureMode/asset/threat prose text, just not for the structured path field).
  • sci: relativize artifacts[].file against the resolved --dir the same way check already does, regardless of whether --dir was given as an absolute or relative path.

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