Project Harness
This skill creates or updates a repo-wide command harness without trying to rewrite the repo's package manifests, lockfiles, or build internals.
It is meant to answer questions like:
- how should this repo expose bootstrap, build, test, lint, fmt, ci, dev, and dist?
- should
dist/stay local, be committed, be tracked with Git LFS, or come only from CI? - should CI call
just ci, mirror commands directly, or stay off until the repo is better defined? - how should a monorepo expose both per-component and aggregate recipes?
- when should a contributor-heavy repo split CI into stable
lint,test, andbuildjobs? - how should a repo with no existing examples still get a usable starting harness?
What this skill owns
This skill owns the repo-level wrapper surface:
justfile.github/workflows/ci.yml.github/workflows/release-cross-os.ymlgithooks/pre-pushwhen the selected architecture uses committed dist outputs.gitignoreadditions related to.local/anddist/.gitattributesmanaged section with broad text/EOL and binary defaults, plusdist/**Git LFS tracking when selected.local/harness/state.json.local/harness/render/*candidate files
This skill does not rewrite:
Cargo.tomlpackage.jsonpyproject.tomlpom.xmlgo.mod- existing build manifests in general
This skill also does not own governance enforcement such as required checks, CODEOWNERS reconciliation, review policy, or branch/ruleset policy. Keep those in repository policy plus native host tooling such as git, gh, and official GitHub or GitLab integrations.
Repo-owned Git hooks are a local convenience overlay, not the authoritative enforcement surface. Keep CI and branch governance authoritative even when this skill emits githooks/pre-push and a hooks-install recipe.
Justfile quality bar
The generated justfile is a user interface, not just a dump of commands.
WHEN this skill generates a public recipe THEN you SHALL place a one-line description comment directly above it. WHEN the recipe is scoped to a component, platform, or distribution surface THEN you SHALL name that scope in the description. WHEN the repo has non-obvious operational surfaces such as packaging, dist refresh, hooks, or Docker workflows THEN you SHOULD add a short header comment block with two or three example invocations. You SHALL NOT rely on bare labels such as "Run linters" or "Build the project" when the repo surface is specific enough to describe more precisely.
Preferred description style:
- one line
- outcome-first
- precise about scope and side effects
- written so it still reads cleanly in
just --list
Good examples:
# Install dependencies, tooling, and local prerequisites for normal development# Compile only crates/render-table in the default build profile# Compile release outputs and stage them into dist/ for local packaging# Remove staged dist payloads without touching source files
Weak examples:
# Run linters# Build the project# Clean
Default workflow
- Detect the repo shape.
python <skills-file-root>/scripts/project_harness.py detect /path/to/repo --pretty
- Choose the command and CI axes:
- architecture:
general,local-dist,committed-dist, orcross-os-dist - dist storage:
none,git,git-lfs, orartifacts - CI mode:
none,just, ordirect - CI shape: single-job direct CI by default, with
--ci-layout splitas an opt-in contributor-scale overlay - change detection:
noneby default, with--change-detection git-diffas an opt-in build-lane overlay for split direct CI - path filters: manual opt-in only when component ownership is explicit
- Preview candidate files without touching managed targets.
python <skills-file-root>/scripts/project_harness.py render /path/to/repo --pretty
- Apply the managed update.
python <skills-file-root>/scripts/project_harness.py update /path/to/repo --pretty
update writes managed files by default. Use render when you want a dry preview.
- Bootstrap or run through the harness.
python <skills-file-root>/scripts/project_harness.py bootstrap /path/to/repo
python <skills-file-root>/scripts/project_harness.py run /path/to/repo test
python <skills-file-root>/scripts/project_harness.py doctor /path/to/repo --pretty
Default decision rules
When the repo already has a clear build surface
Detect and mirror it first.
Examples:
- package scripts -> generate matching
justrecipes - Cargo binaries -> generate
build,release, and dist staging candidates - Makefile or Taskfile -> preserve them, map canonical targets where obvious
- monorepo/workspace -> emit both per-component recipes and aggregate top-level recipes
Also generate recipe descriptions that explain what each recipe does, not just its canonical name.
When the repo has no examples
Do not fail. Generate a minimal canonical harness with placeholder recipes and a comment block that explains what to replace.
Default behavior for no-example repos:
- generate a
justfile - keep CI mode at
noneunless setup is truly obvious - leave distribution mode at
generalunless the repo already shows binary/dist intent - store decisions and warnings in
.local/harness/state.json - include recipe descriptions plus a short header block that shows how the placeholder harness is meant to be used
Load <skills-file-root>/references/generic-harnesses.md for the full no-example policy. Load <skills-file-root>/references/extrapolation-protocol.md when you need the full detect -> infer -> render -> stop protocol for partially explicit repos.
Distribution choices
Use three separate questions.
1) Architecture
general: command wrapper only, no dist sectionlocal-dist: stage artifacts into ignoreddist/committed-dist: keepdist/in git for clone-and-run workflowscross-os-dist: stage per-platform outputs intodist/<os>-<arch>/
2) Dist storage
none: there is no committed dist story yetgit: keepdist/in normal git historygit-lfs: keepdist/committed but move payloads out of normal git blobsartifacts: prefer CI artifacts or release assets instead of committed outputs
3) Release overlay
The generated cross-OS workflow is an artifact-oriented overlay. For true GitHub Release assets, start from <skills-file-root>/assets/workflow-release-assets-cross-os.yml.tpl.
CI choices
none: do not generate CI yetjust: CI installs toolchains plusjust, runsjust bootstrap, thenjust cidirect: CI installs toolchains, runs bootstrap steps directly, then explicit checks; contributor-heavy repos may opt into stablelint,test, andbuildjobs
Use direct for monorepos, matrices, or polyglot repos. Use just for smaller repos where just ci should stay the source of truth. Use split direct CI only when a repo explicitly opts into it and stable per-job checks are more valuable than preserving a single ci check surface. Keep change detection at none unless the repo has an expensive, distinct build lane worth gating. The generated git-diff overlay currently targets split direct CI only. Keep path filters manual and explicit; do not infer them unless the repo truly has stable ownership boundaries.
Load <skills-file-root>/references/ci-workflows.md for workflow quality rules, runner notes, contributor-scale guidance, governance boundaries, and open-source versus private-repo tradeoffs.
When examples do not match the repo exactly:
- explore the actual repo first
- infer from strong signals before weak ones
- prefer generated defaults when the evidence supports them
- prefer placeholders, candidate renders, or
nonewhen the safety boundary is unclear - treat example-only assets as patterns, not as repo truth
- detect broadly, but only promote runnable repo-owned surfaces into generated recipes and workflows
- leave weak nested surfaces in notes and state instead of turning them into decorative scaffolding
Existing-file policy
Managed files are overwritten only when absent or already marked as managed. Unmanaged targets are never force-merged blindly; candidate files are written instead under .local/harness/render/.
.gitattributes is managed by section instead of by whole file. WHEN this skill updates .gitattributes THEN you SHALL preserve human-authored rules outside the project-harness managed section. WHEN .gitattributes already exists without a project-harness section THEN you SHALL insert the managed section after leading comments and blank lines so later repo-specific rules can override the baseline. WHEN .gitattributes already contains a project-harness section THEN you SHALL replace only that section.
Load <skills-file-root>/references/existing-files.md before changing a repo with an existing justfile, workflow set, or custom dist layout.
References to load on demand
Load these only when relevant:
<skills-file-root>/references/detection.md<skills-file-root>/references/selection.md<skills-file-root>/references/distribution-strategies.md<skills-file-root>/references/generic-harnesses.md<skills-file-root>/references/extrapolation-protocol.md<skills-file-root>/references/scenarios.md<skills-file-root>/references/ci-workflows.md<skills-file-root>/references/existing-files.md<skills-file-root>/references/docker-workspaces.md<skills-file-root>/references/makefile-migration.md<skills-file-root>/references/state-and-recovery.md<skills-file-root>/references/language-rust.md<skills-file-root>/references/language-python.md<skills-file-root>/references/language-javascript.md<skills-file-root>/references/language-compiled.md<skills-file-root>/references/language-other.md
Bundled assets
Operational templates:
<skills-file-root>/assets/just-general.just.tpl<skills-file-root>/assets/just-local-dist.just.tpl<skills-file-root>/assets/just-committed-dist.just.tpl<skills-file-root>/assets/just-cross-os-dist.just.tpl<skills-file-root>/assets/workflow-ci-just.yml.tpl<skills-file-root>/assets/workflow-ci-direct.yml.tpl<skills-file-root>/assets/workflow-ci-direct-split.yml.tpl<skills-file-root>/assets/workflow-release-cross-os.yml.tpl
Generalized examples:
<skills-file-root>/assets/just-no-example.just.tpl<skills-file-root>/assets/workflow-ci-direct-component-paths.yml.tpl<skills-file-root>/assets/workflow-release-assets-cross-os.yml.tpl<skills-file-root>/assets/gitattributes-baseline.tpl
Bundled scripts
<skills-file-root>/scripts/project_harness.py<skills-file-root>/scripts/validate_skill.py<skills-file-root>/scripts/selftest_project_harness.py
Validation
python <skills-file-root>/scripts/validate_skill.py <skills-file-root> --pretty
python <skills-file-root>/scripts/validate_skill.py <skills-file-root> --pretty --smoke