user.md
credentials.md
# ...but NOT the generated setup guide of that name. The rule above is
# unanchored, so it matches `credentials.md` at ANY depth — which silently
# swallowed novaya-deploy/setup/credentials.md, a PUBLIC document every setup
# guide links to. It generated fine, passed tests (they read the disk) and
# 404'd in production, because it never reached git at all.
!novaya-deploy/setup/credentials.md
.env
data/
__pycache__/
*.pyc
connectors/*/auth.json

# Runtime / agent-generated artifacts (not source)
workspace/
.gstack/
.nexus_server.pid
*.log
=*
dist/
build/
# Generated by packaging/build_npm_package.py — a verbatim copy of the manifest's
# npm distribution, rmtree'd and rebuilt on every run. Ignored so it is neither
# committed nor indexed: it duplicated every symbol in the knowledge graph and
# made impact analysis report doubled blast radius.
npm/payload/

# Same reasoning, same failure mode: a verbatim copy of sdk/python/codewiki/,
# rebuilt by novaya-installer/scripts/sync-payload.js on every pack.
novaya-installer/payload/
node_modules/

# A LOCAL OVERRIDE for render.yaml, so there is somewhere safe to put values
# while working on the deploy. render.yaml ITSELF is deliberately NOT ignored:
# Render reads it out of the repository to build the service, so ignoring it
# would stop the deploy working at all — and ignoring a file git already tracks
# does not untrack it or remove anything already committed, so it would buy no
# safety either. Real credentials belong in the Render dashboard, which is why
# every secret in render.yaml is declared `sync: false` with no value.
render.local.yaml
render.*.local.yaml

config/google_oauth.json
config/github_oauth.json
config/airtable_oauth.json
config/supabase_oauth.json
config/huggingface_oauth.json
config/twitter_oauth.json
config/netlify_oauth.json
config/digitalocean_oauth.json
config/heroku_oauth.json
config/gitlab_oauth.json
config/dropbox_oauth.json
config/asana_oauth.json

# npm pack output — a build artifact, rebuilt by `npm pack` on demand.
*.tgz

# Large binaries that no page references — verified with grep before removal, and
# untracked with `git rm --cached`, so every one is still on disk. The repo is
# about to be pushed to GitHub for Render to deploy from; 72MB of unreferenced
# video makes every clone slower forever and buys nothing.
#
# nexus-hero.mp4 (7MB) IS referenced by novaya-deploy/index.html and stays.
# nexus-hero.mp4.mp4 is a 60MB duplicate with a doubled extension.
novaya-deploy/nexus-hero.mp4.mp4
Nexus codewiki - Trim.mp4
Nexus codewiki - Trim 2.mp4
# The extracted copy is tracked alongside these, so the archives are the same
# bytes twice.
design_extracted/design.tar
design_extracted/design.tar.gz

# RUNTIME STATE, not source. core/skill_library.py's _write_stats() rewrites
# one of these after EVERY skill invocation (success_rate, invocation_count,
# last_used), so tracking them meant 264 files churning on every Nexus run and
# turning up as diff noise in unrelated commits. Deleting them never stuck —
# the next run recreates them — and a .gitignore rule alone could not help
# while git still tracked them (see the render.local.yaml note above for the
# same trap). They are untracked with `git rm --cached`, so all 264 stay on
# disk and no counter is lost.
#
# Safe to be absent on a fresh clone: _load_meta() backfills `name` from the
# skill's directory and `description` from its SKILL.md, and every counter has
# a default — verified by loading a skill with its stats.json removed.
agents/*/skills/*/stats.json

# Per-machine Claude Code settings — was tracked AND matched by an ignore rule,
# which is the one combination where .gitignore silently does nothing.
.claude/settings.local.json

# installClaudeCode writes project-scoped MCP config to process.cwd(), so any
# test or manual run from novaya-installer/ drops one here. It is a per-project
# artifact of whoever ran the installer, never something to ship.
novaya-installer/.mcp.json
.mcp.json
.coldtest/
