Skip to contents

Walks each root and returns one row per file. This is a filename-only sweep: no file is opened, nothing is parsed, and there is no TemporalHazard dependency.

Usage

job_files(roots)

Arguments

roots

Character. One or more directories to sweep. A root is a directory that contains studies, not a study itself: the study is read as the path from the root down to the taxonomy folder's parent, so a root that is itself a study leaves nothing to name it and every prefix collapses to one study called "." (warned about). Each root must exist and be a directory, or this errors. A duplicate root is dropped; a root nested inside another warns and the inner one is dropped, since its files would otherwise be counted twice under two study labels.

Value

A data frame with one row per file and the columns path, study, folder, status, depth, naming, prefix, is_template, qualifier1, qualifiers, n_qualifiers, stem, ext, prefix_class, folder_expected and folder_ok. The three qualifier columns carry the dot-fields of a legacy name that lie between the prefix and the extension, or the trailing qualifier field of a scaffolded name, and are NA (count zero) for every other convention. They are named by position because the second field means a different thing in each taxonomy folder; see hvti_taxonomy and the design note referenced in R/job_names.R. Zero rows if the roots hold no files.

Details

Nothing is filtered out. Placement and classification are columns, not reasons to drop a row, so a file this sweep cannot classify stays findable. A sweep that reports only what it kept makes a missing job indistinguishable from a job that does not exist. The one exception is tooling: a path with a .git or .checkpoint component holds version-control internals or a study checkpoint's mirror, not study files, and is not listed.

A scaffolded name, <subject>-<type>-<prefix>[-<qualifier>].qmd as written by hvtiRtemplates::add_job(), is parsed with its qualifier. So is the template-first form, <prefix>[.<qualifier>].<subject>.<type>.qmd. The -runner.R (or .runner.R) that add_job() writes beside some reports takes the report's stem, so it counts as a file of that job rather than as a second job.

A legacy prefix listed in hvti_prefix_folds is reported as the prefix it folds into, so a pm.* file counts as lm. stem keeps the name as written, so a folded file stays findable.

There is deliberately no extension allowlist. See vignette-adjacent design note dev/specs/2026-08-26-job-type-inventory-design.md, section 4.4: a plausible default tuned on the hazard prefixes would have dropped every R-side job in the corpus.

folder_ok is folder == folder_expected, and is therefore NA – not FALSE – whenever either side is unknown. An unplaced file has no folder and an unparsed name has no expected folder; neither is a misfiled job, and !folder_ok must not select them.

Run this server-side. It stats every file beneath roots, which is metadata-latency-bound over an SMB mount – a 40-file scan has timed out at two minutes over the share.

Examples

d <- file.path(tempdir(), "job-files-example")
dir.create(file.path(d, "alpha", "distributions"), recursive = TRUE)
file.create(file.path(d, "alpha", "distributions", "hz.dead.lst"))
#> [1] TRUE
job_files(d)[, c("study", "folder", "prefix", "status")]
#>   study        folder prefix status
#> 1 alpha distributions     hz placed
unlink(d, recursive = TRUE)