Repository Analysis

mail-in-a-box/mailinabox

Mail-in-a-Box helps individuals take back control of their email by defining a one-click, easy-to-deploy SMTP+everything else server: a mail server in a box.

14.6 Low AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of mail-in-a-box/mailinabox, a Python project with 15,362 GitHub stars. SynthScan v2.0 examined 21,120 lines of code across 85 source files, recording 205 pattern matches distributed across 11 syntactic categories. The overall adjusted score of 14.6 places this repository in the Low AI signal band.

The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).

14.6
Adjusted Score
14.6
Raw Score
100%
Time Factor
2026-05-24
Last Push
15.4K
Stars
Python
Language
21.1K
Lines of Code
85
Files
205
Pattern Hits
2026-07-14
Scan Date
0.01
HC Hit Rate

What These Metrics Mean

Adjusted Score
Primary synthetic code indicator. Raw score normalised per 1,000 lines of code and multiplied by the temporal discount factor. This is the definitive comparative metric — use it to rank repositories by AI authorship density.
Raw Score
The unmodified sum of all severity-weighted, context-multiplied pattern match scores before temporal discounting. Reflects the absolute signal strength independent of when the repository was last active.
Time Factor
The temporal discount multiplier (0–100%) applied to the raw score. Repositories last updated before ChatGPT's launch (Nov 2022) receive a 5% factor. Full signal is only assigned to repositories active in the post-adoption era (Jan 2024+).
Pattern Hits
Total count of individual pattern matches across all files and categories. A high hit count with a low score may indicate a very large codebase with isolated AI snippets; a low count with a high score indicates dense, concentrated AI signatures.
HC Hit Rate
High+Critical pattern hits per file, averaged across the repository. This orthogonal signal catches repositories where a few files are densely packed with high-severity AI tells — a strong indicator even when the normalised score appears moderate due to codebase size.
Lines of Code / Files
Total lines and files analysed. The scanner examines 94 file extensions. These denominators are used to normalise the score, enabling fair comparison between repositories of vastly different sizes.

Score History

This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.

Severity Breakdown

Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.

CRITICAL 0HIGH 1MEDIUM 48LOW 156

Directory Score Breakdown

This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.

Pattern Findings

The scanner identified 205 distinct pattern matches across 11 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.

Self-Referential Comments30 hits · 86 pts
SeverityFileLineSnippetContext
MEDIUMsetup/munin.sh64# Create a systemd service for munin.COMMENT
MEDIUMsetup/management.sh24# Create a virtualenv for the installation of Python 3 packagesCOMMENT
MEDIUMsetup/management.sh54# Create a backup directory and a random key for encrypting backups.COMMENT
MEDIUMsetup/management.sh85# Create an init script to start the management daemon and keep itCOMMENT
MEDIUMsetup/ssl.sh6# Create an RSA private key, a self-signed SSL certificate, and someCOMMENT
MEDIUMsetup/ssl.sh39# Create a directory to store TLS-related things like "SSL" certificates.COMMENT
MEDIUMsetup/dkim.sh45# Create a new DKIM key. This creates mail.private and mail.txtCOMMENT
MEDIUMsetup/firstuser.sh50 # Create the user's mail account. This will ask for a password if none was given above.COMMENT
MEDIUMsetup/firstuser.sh56 # Create an alias to which we'll direct all automatically-created administrative aliases.COMMENT
MEDIUMsetup/web.sh102# Create the iOS/OS X Mobile Configuration file which is exposed via theCOMMENT
MEDIUMsetup/web.sh115# Create the Mozilla Auto-configuration file which is exposed via theCOMMENT
MEDIUMsetup/web.sh125# Create a generic mta-sts.txt file which is exposed via theCOMMENT
MEDIUMsetup/dns.sh49# Create a directory for additional configuration directives, includingCOMMENT
MEDIUMsetup/dns.sh96 # Create the Key-Signing Key (KSK) (with `-k`) which is the so-calledCOMMENT
MEDIUMsetup/mail-users.sh20# Create an empty database if it doesn't yet exist.COMMENT
MEDIUMsetup/webmail.sh105# Create a configuration file.COMMENT
MEDIUMsetup/start.sh69# Create the STORAGE_USER and STORAGE_ROOT directory if they don't already exist.COMMENT
MEDIUMsetup/nextcloud.sh127 # Create a symlink to the config.php in STORAGE_ROOT (for upgrades we're restoring the symlink we previouslyCOMMENT
MEDIUMsetup/nextcloud.sh182 # Create a backup directory to store the current installation and database toCOMMENT
MEDIUMsetup/nextcloud.sh255 # Create an initial configuration file.COMMENT
MEDIUMsetup/nextcloud.sh281 # Create an auto-configuration file to fill in database settingsCOMMENT
MEDIUMmanagement/auth.py130 # Create a token that changes if the user's password or MFA options changeCOMMENT
MEDIUMmanagement/auth.py143 # Create a new session.COMMENT
MEDIUMmanagement/ssl_certificates.py304 # Create a CSR file for our master private key so that certbotCOMMENT
MEDIUMmanagement/backup.py271 # Create an global exclusive lock so that the backup scriptCOMMENT
MEDIUMmanagement/dns_update.py135 # Create a dictionary of domains to a set of attributes for eachCOMMENT
MEDIUMmanagement/dns_update.py660 # Create a stable (by sorting the items) hash of all of the private keysSTRING
MEDIUMmanagement/dns_update.py724 # Create a DS record based on the patched-up key files. The DS record is specific to theSTRING
MEDIUMmanagement/daemon.py138# Create a session key by checking the username/password in the Authorization header.COMMENT
MEDIUMmanagement/daemon.py590 # Create a temporary pool of processes for the status checksCOMMENT
Over-Commented Block71 hits · 71 pts
SeverityFileLineSnippetContext
LOWtools/parse-nginx-log-bootstrap-accesses.py1#!/usr/bin/python3COMMENT
LOWtools/editconf.py1#!/usr/bin/python3COMMENT
LOWsetup/zpush.sh1#!/bin/bashCOMMENT
LOWsetup/management.sh1#!/bin/bashCOMMENT
LOWsetup/spamassassin.sh1#!/bin/bashCOMMENT
LOWsetup/spamassassin.sh41# check with: pyzor --homedir /etc/mail/spamassassin/pyzor pingCOMMENT
LOWsetup/spamassassin.sh61# content or execute scripts, and it is probably confusing to most users.COMMENT
LOWsetup/spamassassin.sh121# -----------------COMMENT
LOWsetup/ssl.sh1#!/bin/bashCOMMENT
LOWsetup/ssl.sh41mkdir -p "$STORAGE_ROOT/ssl"COMMENT
LOWsetup/mail-postfix.sh1#!/bin/bashCOMMENT
LOWsetup/mail-postfix.sh21# connections from users who can authenticate and then sendsCOMMENT
LOWsetup/mail-postfix.sh41# always will.COMMENT
LOWsetup/mail-postfix.sh81tools/editconf.py /etc/postfix/main.cf \COMMENT
LOWsetup/mail-postfix.sh121# Modify the `outgoing_mail_header_filters` file to use the local machine name and ipCOMMENT
LOWsetup/mail-postfix.sh161# relayed elsewhere. We don't want to be an "open relay". On outboundCOMMENT
LOWsetup/mail-postfix.sh181# for opportunistic encryption but "Intermediate" recommendations when DANECOMMENT
LOWsetup/mail-postfix.sh221# Who can send mail to us? Some basic filters.COMMENT
LOWsetup/mail-postfix.sh241 smtpd_recipient_restrictions="permit_sasl_authenticated,permit_mynetworks,reject_rbl_client zen.spamhaus.org=127.0.0.[2COMMENT
LOWsetup/mail-dovecot.sh1#!/bin/bashCOMMENT
LOWsetup/mail-dovecot.sh21COMMENT
LOWsetup/mail-dovecot.sh41# can be allocated. It should be set *reasonably high* to avoid allocationCOMMENT
LOWsetup/mail-dovecot.sh121# are made available (IMAPS on port 993; POP3S on port 995).COMMENT
LOWsetup/mail-dovecot.sh141COMMENT
LOWsetup/mail-dovecot.sh181 "postmaster_address=postmaster@$PRIMARY_HOSTNAME"COMMENT
LOWsetup/dkim.sh41RequireSafeKeys falseCOMMENT
LOWsetup/dkim.sh101# intercepts outgoing mail to perform the signing (by adding a mail header)COMMENT
LOWsetup/web.sh21COMMENT
LOWsetup/system.sh21# permissions (group writeable) set on the following directories.COMMENT
LOWsetup/system.sh121# PPAs so we can install those packages later.COMMENT
LOWsetup/system.sh161fiCOMMENT
LOWsetup/system.sh201# * DNSSEC signing keys (see `dns.sh`)COMMENT
LOWsetup/system.sh221# entropy saved across boots to a local file" as well as the order ofCOMMENT
LOWsetup/system.sh301# (This is unrelated to the box's public, non-recursive DNS server thatCOMMENT
LOWsetup/system.sh321#COMMENT
LOWsetup/system.sh381# On first installation, the log files that the jails look at don't all exist.COMMENT
LOWsetup/functions.sh41 #COMMENT
LOWsetup/functions.sh81}COMMENT
LOWsetup/functions.sh101 # assigned to an interface. `ip route get` reports theCOMMENT
LOWsetup/bootstrap.sh1#!/bin/bashCOMMENT
LOWsetup/dns.sh81# TLDs, registrars, and validating nameservers don't all support the same algorithms,COMMENT
LOWsetup/dns.sh101 # we're capturing into the `KSK` variable.COMMENT
LOWsetup/dns.sh121 # * `K_domain_.+007+08882.ds`: DS record normally provided to domain name registrar (but it's actually invalid with `_dCOMMENT
LOWsetup/mail-users.sh1#!/bin/bashCOMMENT
LOWsetup/mail-users.sh81COMMENT
LOWsetup/mail-users.sh121# SQL statement to check if we handle incoming mail for a user.COMMENT
LOWsetup/mail-users.sh141# before postfix gets to the third query for catch-alls/domain alises.COMMENT
LOWsetup/webmail.sh1#!/bin/bashCOMMENT
LOWsetup/webmail.sh21# These dependencies are from `apt-cache showpkg roundcube-core`.COMMENT
LOWsetup/start.sh1#!/bin/bashCOMMENT
LOWsetup/start.sh61# Skip on existing installs since we don't want this to block the ability toCOMMENT
LOWsetup/questions.sh1#!/bin/bashCOMMENT
LOWsetup/nextcloud.sh1#!/bin/bashCOMMENT
LOWsetup/nextcloud.sh21# we automatically install intermediate versions as needed.COMMENT
LOWsetup/nextcloud.sh41COMMENT
LOWsetup/nextcloud.sh301 chown -R www-data:www-data "$STORAGE_ROOT/owncloud" /usr/local/lib/owncloudCOMMENT
LOWsetup/nextcloud.sh441EOFCOMMENT
LOWtests/tls.py1#!/usr/bin/python3COMMENT
LOWmanagement/auth.py81 # The user is trying to log in with a username and a passwordCOMMENT
LOWmanagement/ssl_certificates.py101COMMENT
11 more matches not shown…
Decorative Section Separators15 hits · 45 pts
SeverityFileLineSnippetContext
MEDIUMsetup/zpush.sh4# ----------------------------------------------COMMENT
MEDIUMsetup/spamassassin.sh3# -------------------------------------------COMMENT
MEDIUMsetup/spamassassin.sh16# ----------------------------------------COMMENT
MEDIUMsetup/spamassassin.sh72# ---------------------------------------COMMENT
MEDIUMsetup/spamassassin.sh121# -----------------COMMENT
MEDIUMsetup/ssl.sh4# -------------------------------------------COMMENT
MEDIUMsetup/mail-postfix.sh4# --------------COMMENT
MEDIUMsetup/mail-dovecot.sh4# ----------------------COMMENT
MEDIUMsetup/system.sh6# -------------------------COMMENT
MEDIUMsetup/dns.sh3# -----------------------------------------------COMMENT
MEDIUMsetup/mail-users.sh4# ----------------------------------------------COMMENT
MEDIUMsetup/webmail.sh3# ----------------------COMMENT
MEDIUMsetup/nextcloud.sh16# --------------COMMENT
MEDIUMsetup/nextcloud.sh28# --------------COMMENT
MEDIUMsetup/nextcloud.sh51# ----------------------------COMMENT
Deep Nesting37 hits · 37 pts
SeverityFileLineSnippetContext
LOWtools/readable_bash.py299CODE
LOWtools/readable_bash.py402CODE
LOWsetup/migrate.py69CODE
LOWsetup/migrate.py150CODE
LOWtests/tls.py70CODE
LOWmanagement/ssl_certificates.py12CODE
LOWmanagement/ssl_certificates.py172CODE
LOWmanagement/ssl_certificates.py240CODE
LOWmanagement/ssl_certificates.py24CODE
LOWmanagement/backup.py157CODE
LOWmanagement/backup.py441CODE
LOWmanagement/status_checks.py92CODE
LOWmanagement/status_checks.py333CODE
LOWmanagement/status_checks.py399CODE
LOWmanagement/status_checks.py538CODE
LOWmanagement/status_checks.py740CODE
LOWmanagement/status_checks.py1012CODE
LOWmanagement/dns_update.py175CODE
LOWmanagement/dns_update.py474CODE
LOWmanagement/dns_update.py671CODE
LOWmanagement/dns_update.py750CODE
LOWmanagement/dns_update.py803CODE
LOWmanagement/dns_update.py855CODE
LOWmanagement/dns_update.py890CODE
LOWmanagement/dns_update.py982CODE
LOWmanagement/dns_update.py1027CODE
LOWmanagement/mail_log.py63CODE
LOWmanagement/mail_log.py93CODE
LOWmanagement/mail_log.py326CODE
LOWmanagement/mail_log.py390CODE
LOWmanagement/mail_log.py421CODE
LOWmanagement/mail_log.py641CODE
LOWmanagement/web_update.py59CODE
LOWmanagement/web_update.py131CODE
LOWmanagement/mailconfig.py117CODE
LOWmanagement/mailconfig.py510CODE
LOWmanagement/daemon.py363CODE
Hyper-Verbose Identifiers23 hits · 24 pts
SeverityFileLineSnippetContext
LOWmanagement/auth.py36 def parse_http_authorization_basic(header):CODE
LOWmanagement/auth.py129 def create_user_password_state_token(self, email, env):CODE
LOWmanagement/ssl_certificates.py172def get_certificates_to_provision(env, limit_domains=None, show_valid_certs=True):CODE
LOWmanagement/ssl_certificates.py374def provision_certificates_cmdline():CODE
LOWmanagement/backup.py219def get_duplicity_additional_args(env):CODE
LOWmanagement/backup.py396def run_duplicity_verification():CODE
LOWmanagement/status_checks.py204def is_reboot_needed_due_to_package_installation():CODE
LOWmanagement/status_checks.py399def run_domain_checks_on_domain(domain, rounded_time, env, dns_domains, dns_zonefiles, mail_domains, web_domains, domainCODE
LOWmanagement/status_checks.py456def check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles):CODE
LOWmanagement/status_checks.py622def check_dns_zone_suggestions(domain, env, output, dns_zonefiles, domains_with_a_records):CODE
LOWmanagement/dns_update.py378def is_domain_cert_signed_and_valid(domain, env):CODE
LOWmanagement/mail_log.py541def scan_postfix_submission_line(date, log, collector):CODE
LOWmanagement/web_update.py51def get_domains_with_a_records(env):CODE
LOWmanagement/web_update.py59def get_web_domains_with_root_overrides(env):CODE
LOWmanagement/mailconfig.py57def sanitize_idn_email_address(email):CODE
LOWmanagement/mailconfig.py77def prettify_idn_email_address(email):CODE
LOWmanagement/mailconfig.py483def add_remove_mail_user_privilege(email, priv, action, env):CODE
LOWmanagement/daemon.py48def authorized_personnel_only(viewfunc):CODE
LOWmanagement/daemon.py299def dns_get_secondary_nameserver():CODE
LOWmanagement/daemon.py305def dns_set_secondary_nameserver():CODE
LOWmanagement/daemon.py565def system_latest_upstream_version():CODE
LOWmanagement/daemon.py686def check_request_cookie_for_admin_access():CODE
LOWmanagement/daemon.py693def authorized_personnel_only_via_cookie(f):CODE
Excessive Try-Catch Wrapping11 hits · 16 pts
SeverityFileLineSnippetContext
LOWsetup/migrate.py91 except Exception as e:CODE
MEDIUMsetup/migrate.py92 print("Error updating IDNA alias", email, e)CODE
LOWsetup/migrate.py248 except Exception as e:CODE
MEDIUMsetup/migrate.py250 print("Error running the migration script:")CODE
LOWmanagement/ssl_certificates.py364 except Exception as e:CODE
LOWmanagement/backup.py290 except Exception as e:CODE
LOWmanagement/daemon.py294 except Exception as e:CODE
LOWmanagement/daemon.py560 except Exception as e:CODE
LOWmanagement/daemon.py569 except Exception as e:CODE
LOWmanagement/daemon.py638 except Exception as e:CODE
MEDIUMmanagement/daemon.py171def logout():CODE
Fake / Example Data6 hits · 9 pts
SeverityFileLineSnippetContext
LOWmanagement/templates/aliases.html204 $('#addaliasAddress').attr('placeholder', 'you@yourdomain.com (incoming email address)');CODE
LOWmanagement/templates/aliases.html205 $('#addaliasForwardsTo').attr('placeholder', 'one address per line or separated by commas');CODE
LOWmanagement/templates/aliases.html210 $('#addaliasAddress').attr('placeholder', '@yourdomain.com (incoming catch-all domain)');CODE
LOWmanagement/templates/aliases.html211 $('#addaliasForwardsTo').attr('placeholder', 'one address per line or separated by commas');CODE
LOWmanagement/templates/aliases.html216 $('#addaliasAddress').attr('placeholder', '@yourdomain.com (incoming catch-all domain)');CODE
LOWmanagement/templates/aliases.html217 $('#addaliasForwardsTo').attr('placeholder', '@otherdomain.com (forward to other domain)');CODE
Redundant / Tautological Comments6 hits · 8 pts
SeverityFileLineSnippetContext
LOWtools/editconf.py93 # Check if this line contain this setting from the command-line arguments.COMMENT
LOWsetup/system.sh71 # Check if swap is mounted then activate on bootCOMMENT
LOWmanagement/backup.py162 # Check if day of week is a weekend dayCOMMENT
LOWmanagement/dns_update.py622 # Check if the file is changing. If it isn't changing,STRING
LOWmanagement/mail_log.py354 # Check if the found date is within the time span we are scanningCOMMENT
LOWmanagement/mail_log.py424 # Check if the incoming mail was rejectedCOMMENT
Cross-Language Confusion1 hit · 8 pts
SeverityFileLineSnippetContext
HIGHmanagement/mailconfig.py250 # permitted_senders: ["user1@domain.com", "sender-only1@domain.com", ...] OR null,COMMENT
Modern Structural Boilerplate4 hits · 4 pts
SeverityFileLineSnippetContext
LOWmanagement/ssl_certificates.py516 if not isinstance(cert, Certificate): raise ValueError("This is not a certificate file.")CODE
LOWmanagement/backup.py592 if not isinstance(custom_config, dict): raise ValueError # caught belowCODE
LOWmanagement/dns_update.py807 if not isinstance(custom_dns, dict): raise ValueError # caught belowSTRING
LOWmanagement/utils.py40 if not isinstance(config, dict): raise ValueError # caught belowCODE
Unused Imports1 hit · 1 pts
SeverityFileLineSnippetContext
LOWtools/readable_bash.py8CODE