Shattered Vales Studio Inc.

Repository Standards & Best Practices

Every studio repository should feel familiar the moment you open it: the same files in the same places, a README that gets you running quickly, no secrets in history, and protected branches that can't be broken by accident. This guide is the checklist for new repositories and the standard existing ones are held to.

Step 1: Include the Required Files

Every repository contains these files at the paths shown. If one doesn't apply, keep the file and say so in it, so readers know it wasn't simply forgotten.

FilePurpose
README.mdWhat the project is and how to run it (Step 2).
.gitignoreFiles Git must never track (Step 3).
.gitattributesLine-ending rules and, for game projects, Git LFS tracking (see Git LFS guide).
.env.exampleEvery environment variable the project needs, with placeholder values (Step 4).
LICENSEThe license, or for private repositories, a proprietary notice.
.github/CODEOWNERSWho must review changes to which paths (Step 5).
.github/pull_request_template.mdPre-filled PR description (see the code review guide).
ARCHITECTURE.mdProject scope, invariants, and conventions for anything beyond a small utility.
CLAUDE.mdInstructions for AI coding agents, in repositories where they are used (see Claude Code setup).

Step 2: Write the README to the Mandatory Structure

The test for a README is simple: a new developer with a fresh machine can go from git clone to a running project and passing tests using only the README, in under 30 minutes. Every README contains the sections below, in this order.

  1. Title and summary: the project name and one sentence on what it is and who uses it.
  2. Overview: a short paragraph on what the system does and how it fits with other studio systems.
  3. Tech stack: languages, frameworks, engine and version, database, and hosting.
  4. Prerequisites: every tool to install, with exact versions (for example "Unity 6000.0.23f1", ".NET SDK 8.0").
  5. Getting started: numbered, copy-pasteable commands to clone, install, configure, and run.
  6. Configuration: a table of environment variables (name, purpose, example, required or not). Never real values.
  7. Testing: how to run the tests and linters locally.
  8. Project structure: the top-level folders and what lives in each.
  9. Deployment: how and where the project is released, or a link to the runbook.
  10. Contributing: the branch and pull request workflow, or a link to it.
  11. Ownership: the owning team and who to contact.

README template:

# Project Name

One sentence: what this is and who uses it.

## Overview
What the system does and how it connects to other studio systems.

## Tech Stack
- Language / framework:
- Database:
- Hosting:

## Prerequisites
- Tool X 1.2+ (install: https://...)
- Tool Y 8.0

## Getting Started
1. Clone: `git clone git@github.com:Shattered-Vales-Studio/project-name.git`
2. Install dependencies: `...`
3. Copy the environment file and fill in values: `cp .env.example .env`
4. Run: `...`

## Configuration
| Variable       | Purpose                    | Example                 | Required |
|----------------|----------------------------|-------------------------|----------|
| `DATABASE_URL` | Main database connection   | `postgres://localhost/app` | Yes   |

## Testing
`...`

## Project Structure
- `src/`: application code
- `tests/`: automated tests

## Deployment
How releases happen, or a link to the runbook.

## Contributing
Branch from `Dev`; open pull requests against `Dev`. See the studio's
Daily Git Terminal Workflow guide.

## Ownership
Team: ... ยท Contact: ...

Update the README in the same pull request as the change that makes it out of date. A wrong README is worse than a short one.

Step 3: Set Up a Standard .gitignore

.gitignore lists files Git should never track. Ignore anything that is generated (build output, caches), downloaded (dependency folders), personal (editor settings), or secret (.env files, keys).

Do commit dependency lockfiles, such as package-lock.json, yarn.lock, packages.lock.json (.NET), and Packages/packages-lock.json (Unity). They record the exact version of every installed package, so every developer, CI, and production build uses the same dependencies. Don't confuse them with temporary lock files that programs create while running, such as Unity's Temp/UnityLockfile or Office's ~$Report.docx; those are never committed.

Don't write one from scratch. Start from GitHub's maintained gitignore templates (opens in a new tab) for your stack (Unity, VisualStudio, Node, and so on), then add the studio block below to the end of it:

# --- Shattered Vales Studio baseline ---

# Secrets and local environment (commit .env.example instead)
.env
.env.*
!.env.example
*.pem
*.key
*.pfx
*.p12
secrets/

# Operating system and temporary lock files
.DS_Store
Thumbs.db
desktop.ini
~$*

# Editors and IDEs (keep shared settings deliberately, not by accident)
.vs/
.idea/
.vscode/*
!.vscode/extensions.json
*.swp

# Logs and local AI agent settings
*.log
.claude/settings.local.json

Operating system and editor files are better ignored once for your whole machine, so you never commit them to any repository:

macOS

printf '.DS_Store\n.idea/\n.vscode/\n' >> ~/.gitignore_global && git config --global core.excludesFile ~/.gitignore_global

Linux

printf '.idea/\n.vscode/\n*.swp\n' >> ~/.gitignore_global && git config --global core.excludesFile ~/.gitignore_global

Windows

Add-Content "$env:USERPROFILE\.gitignore_global" "Thumbs.db`ndesktop.ini`n.vs/`n.idea/`n.vscode/"; git config --global core.excludesFile "$env:USERPROFILE\.gitignore_global"

Fixing an already-tracked file

Adding a file to .gitignore doesn't affect files Git already tracks. Remove it from the index (your local copy stays on disk), then commit. To find out which rule is ignoring a file, use git check-ignore -v:

git rm --cached path/to/file.log
git commit -m "chore: stop tracking local log file"
git check-ignore -v path/to/file.log

Step 4: Keep Secrets and Environment Variables Out of Git

A secret is anything that grants access: passwords, API keys, tokens, connection strings, private keys, signing certificates, and webhook URLs. Secrets are never committed to any repository, private or not. Git keeps everything forever, private repositories get cloned onto laptops and shared with contractors, and automated scanners find leaked keys within minutes of a push to a public repository.

  1. Read configuration from environment variables, not from values written in the code.
  2. Commit .env.example listing every variable with a fake or empty value. Developers copy it to .env, which is ignored, and fill in real values from the team password manager.
  3. Store shared secrets in the team password manager or the cloud provider's secret store, never in chat, email, issues, or wikis.
  4. Give CI/CD its secrets through GitHub Actions secrets, which are encrypted and hidden in logs.
  5. Check git diff --staged before every commit. It's the last chance to spot a key you pasted while debugging.

.env.example (committed):

# Copy to .env and fill in real values from the password manager.
DATABASE_URL=postgres://user:password@localhost:5432/app_dev
STRIPE_SECRET_KEY=sk_test_replace_me
JWT_SIGNING_KEY=
LOG_LEVEL=debug

Add a secret for GitHub Actions (prompts for the value, so it isn't saved in your shell history):

gh secret set STRIPE_SECRET_KEY --repo Shattered-Vales-Studio/<repo>

Repositories should have GitHub secret scanning and push protection enabled (Settings > Code security). Push protection blocks a push that contains a recognized key format before it reaches GitHub.

Step 5: Meet the Branch Protection Expectations

Every repository protects main, QA, and Dev with GitHub branch protection rules or rulesets (Settings > Rules > Rulesets). Repository admins configure them when the repository is created. Every developer should understand what they enforce:

RuleWhat it means for you
Require a pull request before mergingNo direct pushes. All changes arrive through a reviewed PR.
Require approvals (at least one)Someone other than the author must approve.
Require review from code ownersChanges to paths listed in CODEOWNERS need that owner's approval.
Dismiss stale approvals on new commitsPushing after approval requires a fresh approval.
Require status checks to passCI (build, tests, lint) must be green.
Require branches to be up to dateRebase onto the latest target branch before merging.
Require conversation resolutionEvery review thread must be resolved.
Block force pushes and deletionsHistory on protected branches can't be rewritten or removed.

Work flows in one direction: feature branches merge into Dev; maintainers promote Dev to QA for testing, then QA to main for release. Never open a pull request from a feature branch into QA or main. A CODEOWNERS file maps paths to reviewers; the last matching line wins:

# .github/CODEOWNERS
*                       @Shattered-Vales-Studio/maintainers
/src/Billing/           @Shattered-Vales-Studio/billing-team
/.github/workflows/     @Shattered-Vales-Studio/devops

Team names above are examples. Use the teams that exist in the organization.

Step 6: Create New Repositories the Standard Way

Name repositories in lowercase kebab-case that says what the project is (tenant-billing-api, vale-sandbox-client), with a one-line description. New repositories are private unless a lead approves otherwise. With the GitHub CLI:

gh repo create Shattered-Vales-Studio/<repo-name> --private --clone \
  --description "One line on what this is" --gitignore Unity
cd <repo-name>
git switch -c Dev
git push -u origin Dev
  1. Add the required files from Step 1, including the studio .gitignore block.
  2. Create the QA branch from Dev and push it.
  3. Ask an admin to apply the standard branch rulesets and enable secret scanning with push protection.
  4. Create the standard labels, including agentic if AI agents will work in the repository.