No description
  • Shell 72.4%
  • Rust 27.6%
Find a file
2026-07-12 01:47:25 -04:00
rust Add shared Rust lint workspace and CI validation 2026-07-11 20:26:49 -04:00
scripts Scope check-links.sh to published guideline docs only 2026-07-11 20:10:09 -04:00
.editorconfig Initialize femboy coding guidelines repository 2026-07-11 19:56:33 -04:00
.gitignore Gitignore planning docs and fix a link-text typo 2026-07-11 20:37:54 -04:00
bash.md Add Bash guidelines 2026-07-11 20:16:48 -04:00
frontend.md Gitignore planning docs and fix a link-text typo 2026-07-11 20:37:54 -04:00
LICENSE Initialize femboy coding guidelines repository 2026-07-11 19:56:33 -04:00
privacy.md Add privacy and security guidelines 2026-07-11 20:20:18 -04:00
python.md Add Python guidelines 2026-07-11 20:15:07 -04:00
README.md Add top-level README with philosophy and process guidelines 2026-07-11 20:30:22 -04:00
rust.md Add Rust guidelines 2026-07-11 20:13:34 -04:00
SECURITY.md.example meow! :3 2026-07-12 01:47:25 -04:00

Femboy Cyber Networks coding guidelines

These documents describe how we design, write, and review code across femboyisp's projects — network services, tooling, and the occasional frontend. They exist so that decisions don't have to be re-litigated on every PR, and so a new contributor (human or AI) can pick up the same conventions everyone else follows.

This is a living document. If something here stops making sense for how the team actually works, change it — but change the doc, don't just quietly ignore it.

Complexity, edge cases, and problem scope

When implementing a feature, resist the urge to solve for every hypothetical case up front. Make the common path simple and correct, and let genuinely unlikely scenarios fail loudly (an error, a panic in debug builds) rather than adding branches to handle them "just in case."

Don't generalize before you need to. If you're writing a function that allows traffic from a specific source, call it what it does — allow_lan_subnet() — rather than building a generic create_rule(Action, Subject) abstraction before a second caller actually needs it. Reuse that justifies the added complexity should come from a real second use case, not a predicted one.

Code quality and documentation

Leave code in an equally good or better state than you found it. That doesn't mean unrelated refactoring in every PR — it means not adding a second undocumented, tangled function next to an existing one just because "that's how the file already looks."

What to document

Comments should add information the code doesn't already express. A comment that restates the function signature in prose is dead weight — remove it or replace it with the thing the signature can't tell the reader:

/// Spawns `command` as a subprocess. Dropping the returned handle
/// does NOT kill the child process — call `.kill()` explicitly.
/// `stdin`/`stdout`/`stderr` are all inherited from the parent.
fn spawn_cmd(command: String) -> CmdHandle

The first line restating "spawns a subprocess" would be useless. The ownership/lifetime behavior and stdio wiring are not obvious from the signature — that's what's worth writing down.

Code review and PR process

Femboy is currently a small team, sometimes a solo effort on a given repo. The review process should scale to that reality without dropping the parts that actually catch bugs.

  • Solo work: before merging your own change, do a self-review pass on the diff as if you were reviewing someone else's PR — re-read it fresh, not from memory of writing it. Write a PR description that explains why, not just what changed.
  • With a second person available: assign a reviewer who's familiar with the part of the code being touched. It's fine to ask for early feedback on a proof of concept before a full implementation, to avoid a large PR built on an approach the reviewer would have pushed back on.
  • Always get a second reviewer, regardless of team size, for changes to cryptographic code, authentication/authorization, parsing of untrusted network input, or firewall/routing rule generation. See privacy.md. If no second person is available, treat this as a blocker to ship, not something to skip.
  • Mark work-in-progress PRs as drafts (or a WIP label) if you want early feedback on unfinished code — don't let an unfinished PR sit ambiguously.

Code formatting

See .editorconfig for the enforced baseline. In summary:

  • UTF-8 encoding, no BOM.
  • Files end with a newline.
  • No trailing whitespace on any line.
  • LF (\n) line endings only — configure git to convert on checkout if your OS needs CRLF locally, but never commit CRLF.
  • Indent with spaces, except where a language's ecosystem customarily uses tabs (e.g. Makefiles).

Variable naming

Variables that represent filesystem paths follow a consistent suffix so the reader doesn't have to guess what a value actually holds:

  • foo_path — a path to a file, absolute or relative (/tmp/lol.data, ./output.log).
  • foo_dir — a path to a directory (/tmp, ../foo/bar). Don't end the value with a trailing separator.
  • foo_filename — a bare filename, not a path (foo.log), usually combined with a _dir to build a path.
  • foo_dirname — a bare directory name, not a path.

If a variable holds only a fragment of a path or a template that resolves to one (".exe", "/var/log/app.{}.log"), suffix it with prefix, suffix, or template instead.

Language-specific guidelines

Privacy and security

Femboy is a privacy-focused company — that has to show up in the code, not just the marketing copy. See privacy.md for data minimization, logging discipline, secrets handling, and dependency vetting. SECURITY.md.example is a template repos can copy for their own vulnerability-reporting policy.

Git

Commit messages

For repos containing code (Rust, Python, Bash, frontend projects): follow the standard imperative-mood convention —

  • Capitalize the subject line.
  • Don't end the subject line with a period.
  • Use the imperative mood ("Add", "Fix", "Increase" — not "Added", "Fixes", "Increased").
  • Keep the subject line under ~72 characters.
  • Separate subject from body with a blank line if you need a body.

Docs-only or personal-lab repos (e.g. CastleTCP) are explicitly exempt — keep whatever tone already exists there rather than retrofitting a formal style onto casual, personal documentation.

Branch naming

Kebab-case, lowercase: add-links-to-readme, fix-linux-lan-route-parsing. Describe what's being done without extra verbosity — fix-routing-table is less useful than fix-linux-lan-route-parsing. Keep exact external identifiers (CVE numbers, ticket IDs) in their canonical casing if changing it would make them harder to recognize.

Changelogs

Keep a changelog for every project that ships something reusable (a service, a library, a CLI) following Keep a Changelog:

  • Categories in order: Added, Changed, Deprecated, Removed, Fixed, Security.
  • Write entries in the imperative mood, matching commit message style.
  • Only list what changed since the last release — if something was added and then modified within the same unreleased period, merge them into one entry describing the net effect.

Dead code

Don't leave unused code around "in case it's needed later." It adds surface area for a reader to wonder about and maintain. If you're adding code now that a follow-up PR (arriving soon) will use, that's fine — but justify it in the PR description or a comment, and don't let it linger past that follow-up.