What happened?
When .augment/rules (or files inside it) are symlinks rather than regular files/directories, auggie detects zero rules — no error, no warning, just silently skipped. Real (non-symlinked) files in the exact same location are detected correctly. The same symlink pattern works fine for custom commands .augment/commands), so this looks specific to the rules-discovery code path.
What did you expect to happen?
Symlinked rule files (or a symlinked rules directory) should be resolved to their target and loaded like any regular file or directory.
Steps to reproduce
-
Create a workspace-level rule via a symlinked directory:
mkdir -p real-rules
cat > real-rules/test.md << 'EOF'
---
description: test rule
type: always_apply
---
# Test rule
EOF
ln -s ../real-rules .augment/rules
auggie rules list
Result: always_apply: 0 — the rule is not found.
-
Alternatively, make .augment/rules a real directory but symlink the individual .md file into it:
mkdir .augment/rules
ln -s ../../real-rules/test.md .augment/rules/test.md
auggie rules list
Result: still always_apply: 0.
-
Control case — put a real (non-symlinked) file with identical frontmatter directly in .augment/rules:
cat > .augment/rules/test-real.md << 'EOF'
---
description: test rule real file
type: always_apply
---
# Test rule
EOF
auggie rules list
Result: always_apply: 1, correctly listing .augment/rules/test-real.md.
-
Decisive A/B test — put one real file and one symlinked file side by side in the same (real) .augment/rules direct
ory:
.augment/rules/
test-real.md (regular file)
test-symlink.md -> ../../real-rules/other.md (symlink, same valid frontmatter)
auggie rules list finds only test-real.md; test-symlink.md is completely invisible to it (not even reported a
s an invalid/skipped rule).
Auggie version
0.32.0
Request ID
c8e2f1a8-f868-4dec-b32a-772ec129ac96
Environment details
Environment
auggie version: 0.32.0 (commit eb99b871)
- Node.js: v24.18.0
- OS: Ubuntu 24.04.3 LTS (Noble Numbat), Linux 6.8.0-134-generic, x86_64
Anything else we need to know?
Likely root cause
This matches a well-known Node.js fs.Dirent gotcha: when a directory is scanned via
fs.readdirSync(dir, { withFileTypes: true })
the returned Dirent.isFile() / Dirent.isDirectory() are derived from the raw directory-entry type (d_type) and are not resolved through the symlink — for a symlinked entry pointing at a directory or a regular file, both isFile() and isDirectory() return false (only isSymbolicLink() is true). Confirmed directly in this environment:
const fs = require('fs');
fs.readdirSync('.augment', { withFileTypes: true })
.forEach(e => console.log(e.name, e.isDirectory(), e.isSymbolicLink()));
// rules false true
If the rules-discovery code filters entries with dirent.isFile() / dirent.isDirectory() (instead of resolving via fs.statSync(), which does follow symlinks, or explicitly handling dirent.isSymbolicLink() with a realpath/stat fallback), every symlinked rule file or symlinked rules directory is silently skipped. The commands loader apparently does not have this issue, suggesting it uses a different (symlink-safe) traversal method.
Suggested fix
In the rules-discovery code, resolve directory entries via fs.statSync(fullPath) (or check dirent.isSymbolicLink() and follow up with fs.realpathSync/fs.statSync) instead of relying solely on Dirent.isFile()/isDirectory() from readdir({ withFileTypes: true }).
Why this matters
Symlinking a shared rules directory into .augment/rules (e.g. .augment/rules -> ../shared/rules) is a common pattern for projects that want one source of truth for instructions shared across multiple AI coding agents (Auggie, Claude Code, etc.). Right now this silently produces zero active rules with no warning, which is easy to miss (looks like everything is configured correctly — ls -la shows the files, cat on them works — only auggie rules list / /status reveals the problem).
What happened?
When
.augment/rules(or files inside it) are symlinks rather than regular files/directories,auggiedetects zero rules — no error, no warning, just silently skipped. Real (non-symlinked) files in the exact same location are detected correctly. The same symlink pattern works fine for custom commands.augment/commands), so this looks specific to the rules-discovery code path.What did you expect to happen?
Symlinked rule files (or a symlinked
rulesdirectory) should be resolved to their target and loaded like any regular file or directory.Steps to reproduce
Create a workspace-level rule via a symlinked directory:
Result:
always_apply: 0— the rule is not found.Alternatively, make
.augment/rulesa real directory but symlink the individual.mdfile into it:Result: still
always_apply: 0.Control case — put a real (non-symlinked) file with identical frontmatter directly in
.augment/rules:Result:
always_apply: 1, correctly listing.augment/rules/test-real.md.Decisive A/B test — put one real file and one symlinked file side by side in the same (real)
.augment/rulesdirectory:
auggie rules listfinds onlytest-real.md;test-symlink.mdis completely invisible to it (not even reported as an invalid/skipped rule).
Auggie version
0.32.0
Request ID
c8e2f1a8-f868-4dec-b32a-772ec129ac96
Environment details
Environment
auggieversion: 0.32.0 (commit eb99b871)Anything else we need to know?
Likely root cause
This matches a well-known Node.js
fs.Direntgotcha: when a directory is scanned viathe returned
Dirent.isFile()/Dirent.isDirectory()are derived from the raw directory-entry type (d_type) and are not resolved through the symlink — for a symlinked entry pointing at a directory or a regular file, bothisFile()andisDirectory()returnfalse(onlyisSymbolicLink()istrue). Confirmed directly in this environment:If the rules-discovery code filters entries with
dirent.isFile()/dirent.isDirectory()(instead of resolving viafs.statSync(), which does follow symlinks, or explicitly handlingdirent.isSymbolicLink()with arealpath/statfallback), every symlinked rule file or symlinkedrulesdirectory is silently skipped. The commands loader apparently does not have this issue, suggesting it uses a different (symlink-safe) traversal method.Suggested fix
In the rules-discovery code, resolve directory entries via
fs.statSync(fullPath)(or checkdirent.isSymbolicLink()and follow up withfs.realpathSync/fs.statSync) instead of relying solely onDirent.isFile()/isDirectory()fromreaddir({ withFileTypes: true }).Why this matters
Symlinking a shared rules directory into
.augment/rules(e.g..augment/rules -> ../shared/rules) is a common pattern for projects that want one source of truth for instructions shared across multiple AI coding agents (Auggie, Claude Code, etc.). Right now this silently produces zero active rules with no warning, which is easy to miss (looks like everything is configured correctly —ls -lashows the files,caton them works — onlyauggie rules list//statusreveals the problem).