{"authors":[{"name":"Benoît H. Dicaire"}],"description":"Bilingual personal site for writing, projects, talks, and notes.","feed_url":"https://BHDicaire.com/en/feed.json","home_page_url":"https://BHDicaire.com/en/","items":[{"content_html":"\u003cp\u003eUnited Nations M49 geographic regions organize countries and areas into one statistical hierarchy: world, region, sub-region, optional intermediate region, and country or area.\u003c/p\u003e\n\u003cp\u003eUse this page when you need to understand how the United Nations Statistics Division groups countries and areas for statistical publications and databases. For country-code fields in products and integrations, use the companion \u003ca href=\"/en/blog/ref/iso-3166/\"\u003eISO 3166 country codes\u003c/a\u003e\n reference instead.\u003c/p\u003e\n","date_modified":"2026-08-10T00:00:00Z","date_published":"2026-06-22T00:00:00Z","id":"https://BHDicaire.com/en/blog/ref/continents/","summary":"United Nations M49 geographic regions organize countries and areas into one statistical hierarchy: world, region, sub-region, optional intermediate region, and country or area.\nUse this page when you need to understand how the United Nations Statistics Division groups countries and areas for statistical publications and databases. For country-code fields in products and integrations, use the companion ISO 3166 country codes reference instead.\n","title":"UN M49 geographic regions","url":"https://BHDicaire.com/en/blog/ref/continents/"},{"content_html":"\u003cp\u003eThis reference tracks key cybersecurity workforce frameworks, occupational taxonomies, and skill mapping references. Use it to standardise job descriptions, map team capabilities, and identify training gaps across four main categories:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"#framework-category-1-primary-cybersecurity-workforce-frameworks\"\u003ePrimary Cybersecurity Frameworks\u003c/a\u003e\n - Core standards for defining roles, competencies, and tasks.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#framework-category-2-specialized--sector-specific-cybersecurity-standards\"\u003eSpecialized \u0026amp; Sector-Specific Standards\u003c/a\u003e\n - Frameworks for defence, government, and regulated environments.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#framework-category-3-broad-it-digital--occupational-taxonomy-standards\"\u003eBroad IT \u0026amp; Digital Taxonomies\u003c/a\u003e\n - Enterprise-wide IT and global labor skill frameworks.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#framework-category-4-foundational-knowledge-bases--mapping-references\"\u003eFoundational Knowledge Bases\u003c/a\u003e\n - Underlying bodies of knowledge and research inventories.\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-08-10T00:00:00Z","date_published":"2026-08-09T00:00:00Z","id":"https://BHDicaire.com/en/blog/ref/workforce-frameworks/","summary":"This reference tracks key cybersecurity workforce frameworks, occupational taxonomies, and skill mapping references. Use it to standardise job descriptions, map team capabilities, and identify training gaps across four main categories:\n","title":"Cybersecurity Workforce Frameworks","url":"https://BHDicaire.com/en/blog/ref/workforce-frameworks/"},{"content_html":"\u003cp\u003eMost products should not ask people to choose a continent.\u003c/p\u003e\n\u003cp\u003eFor billing, shipping, tax, legal residency, localization, analytics joins, and integrations with external systems, a country or territory field is usually the right starting point. Store an \u003ca href=\"/en/blog/ref/iso-3166/\"\u003eISO 3166 country code\u003c/a\u003e\n, then derive broader reporting groups when you need them.\u003c/p\u003e\n\u003cp\u003eA continent field can still make sense when the product is explicitly asking for a broad region: travel preferences, market coverage, editorial categorization, coarse dashboards, or a non-address profile field. In those cases, store stable values and keep the labels separate so translation or naming changes do not require data migrations.\u003c/p\u003e\n\u003cp\u003eIf the work needs statistical groupings rather than a simple product-facing list, use \u003ca href=\"/en/blog/ref/continents/\"\u003eUN M49 geographic regions\u003c/a\u003e\n. M49 is more precise than a seven-continent dropdown because it includes regions, sub-regions, intermediate regions, country or area assignments, and development groupings such as least developed countries, landlocked developing countries, and small island developing states.\u003c/p\u003e\n\u003cp\u003eThe practical rule: ask for the smallest field that fits the workflow, store a stable code, and derive broader geography from maintained reference data instead of asking users to classify themselves.\u003c/p\u003e\n","date_modified":"2026-08-10T00:00:00Z","date_published":"2026-08-10T00:00:00Z","id":"https://BHDicaire.com/en/blog/continent-fields-in-forms/","summary":"Most products should not ask people to choose a continent.\nFor billing, shipping, tax, legal residency, localization, analytics joins, and integrations with external systems, a country or territory field is usually the right starting point. Store an ISO 3166 country code , then derive broader reporting groups when you need them.\n","title":"Continent fields in forms","url":"https://BHDicaire.com/en/blog/continent-fields-in-forms/"},{"content_html":"\u003cp\u003eThe Linux Foundation has published a useful \u003ca href=\"https://cybersecurityframework.io/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCybersecurity Skills Framework\u003c/a\u003e\n that identifies 14 cybersecurity-related job families and organizes baseline skills into three proficiency tiers.\u003c/p\u003e\n\u003cp\u003eThe most important sentence on the page is not the number of job families or the export format. It is the reminder that the framework is a starting point, not a prescription.\u003c/p\u003e\n\u003cp\u003eThat matters.\u003c/p\u003e\n\u003cp\u003eSecurity work changes too quickly, and organizations are too different, for one global model to become a perfect local answer. A bank, a hospital, a manufacturer, a SaaS company, and a public-sector agency may all need security architecture, incident response, risk management, secure development, and governance. They do not need the same emphasis, the same depth, or the same language in every job description.\u003c/p\u003e\n\u003cp\u003eWhat they do need is a box of consistent pieces.\u003c/p\u003e\n\u003ch2 id=\"job-descriptions-need-better-building-blocks\"\u003eJob Descriptions Need Better Building Blocks\u003ca class=\"heading-anchor\" href=\"#job-descriptions-need-better-building-blocks\" aria-label=\"Link to Job Descriptions Need Better Building Blocks\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eToo many technical job descriptions are assembled like wish lists.\u003c/p\u003e\n\u003cp\u003eThey ask for every tool, every cloud, every framework, every certification, every regulatory acronym, and somehow still leave out the actual work the person will be expected to do.\u003c/p\u003e\n\u003cp\u003eThis is how we get job postings that ask for 10 years of experience with technology that has not existed for 10 years. Generative AI is the current easy example. You cannot reasonably require a decade of hands-on production experience with a field that only recently became part of mainstream enterprise operations.\u003c/p\u003e\n\u003cp\u003eThe problem is not only that these requirements are unrealistic. It is that they are imprecise.\u003c/p\u003e\n\u003cp\u003eA better job description separates the pieces:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ethe job family\u003c/li\u003e\n\u003cli\u003ethe real responsibilities\u003c/li\u003e\n\u003cli\u003ethe baseline security knowledge expected of everyone\u003c/li\u003e\n\u003cli\u003ethe specialized skills required for the role\u003c/li\u003e\n\u003cli\u003ethe proficiency level needed on day one\u003c/li\u003e\n\u003cli\u003ethe skills that can be developed after hiring\u003c/li\u003e\n\u003cli\u003ethe organizational context that makes the role different here\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThis is where a framework becomes useful. It gives HR, security leaders, managers, and practitioners a shared vocabulary. Instead of writing \u0026ldquo;must know security\u0026rdquo; or \u0026ldquo;AI expertise required\u0026rdquo;, you can identify the actual skills: threat modeling, secure coding, data handling, incident response, governance, compliance, logging, model risk, prompt-injection awareness, vendor assessment, or secure deployment.\u003c/p\u003e\n\u003cp\u003eThe Lego analogy works because the value is not in any single brick. The value is in having clean, reusable pieces that can be combined without pretending every role is the same role.\u003c/p\u003e\n\u003ch2 id=\"a-framework-is-not-a-checklist\"\u003eA Framework Is Not a Checklist\u003ca class=\"heading-anchor\" href=\"#a-framework-is-not-a-checklist\" aria-label=\"Link to A Framework Is Not a Checklist\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe Linux Foundation tool lets you select job families, adjust skills across basic, intermediate, and advanced tiers, and export the result as CSV or JSON. That is exactly the right kind of utility because it encourages tailoring.\u003c/p\u003e\n\u003cp\u003eThe tailoring is the work.\u003c/p\u003e\n\u003cp\u003eFor example, \u0026ldquo;AI Engineer\u0026rdquo; and \u0026ldquo;Software Developer\u0026rdquo; may both need secure coding skills, but they may need different depth in data privacy, model behavior, supply-chain security, abuse cases, and monitoring. A \u0026ldquo;GRC Manager\u0026rdquo; may not need to build a machine-learning pipeline, but they do need enough AI literacy to ask better risk questions and translate those answers into policy, control design, and evidence.\u003c/p\u003e\n\u003cp\u003eThat is the distinction job descriptions often miss. Not everyone needs to be an expert in everything. Everyone needs enough shared language to collaborate without creating blind spots.\u003c/p\u003e\n\u003ch2 id=\"a-foundation-for-ai-skills\"\u003eA Foundation for AI Skills\u003ca class=\"heading-anchor\" href=\"#a-foundation-for-ai-skills\" aria-label=\"Link to A Foundation for AI Skills\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCybersecurity is a strong foundation for building AI skills because it already forces the right habits:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003edefine what matters\u003c/li\u003e\n\u003cli\u003eclassify risk\u003c/li\u003e\n\u003cli\u003eunderstand misuse\u003c/li\u003e\n\u003cli\u003emap controls to responsibilities\u003c/li\u003e\n\u003cli\u003edistinguish awareness from operational competence\u003c/li\u003e\n\u003cli\u003ekeep evidence of what has been done\u003c/li\u003e\n\u003cli\u003erevisit assumptions when the environment changes\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThose habits transfer directly to AI adoption.\u003c/p\u003e\n\u003cp\u003eAn AI skills framework should not be a pile of tool names. Tools change. The durable pieces are things like data stewardship, evaluation, model limitations, human review, privacy, prompt and context design, automation boundaries, secure integration, auditability, and incident response for AI-enabled workflows.\u003c/p\u003e\n\u003cp\u003eThe cybersecurity skills framework gives organizations a practical pattern for this. Start with job families. Define the baseline. Separate beginner, intermediate, and advanced expectations. Let teams adapt the vocabulary. Export it. Review it. Improve it.\u003c/p\u003e\n\u003ch2 id=\"what-else-can-be-built-on-this-foundation\"\u003eWhat Else Can Be Built On This Foundation?\u003ca class=\"heading-anchor\" href=\"#what-else-can-be-built-on-this-foundation\" aria-label=\"Link to What Else Can Be Built On This Foundation?\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eOnce the organization has reusable skills blocks, job descriptions are only the beginning.\u003c/p\u003e\n\u003cp\u003eThe same foundation can support:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ecareer paths that show how people move from one role to another\u003c/li\u003e\n\u003cli\u003etraining plans tied to the skills people actually need\u003c/li\u003e\n\u003cli\u003eonboarding checklists for new security, IT, engineering, and AI roles\u003c/li\u003e\n\u003cli\u003einterview guides that test relevant capability instead of trivia\u003c/li\u003e\n\u003cli\u003eperformance conversations grounded in observable responsibilities\u003c/li\u003e\n\u003cli\u003eworkforce planning for missing or over-concentrated skills\u003c/li\u003e\n\u003cli\u003esuccession planning for critical security roles\u003c/li\u003e\n\u003cli\u003eprocurement questions for vendors that claim AI or security capabilities\u003c/li\u003e\n\u003cli\u003etabletop exercises mapped to job families and proficiency levels\u003c/li\u003e\n\u003cli\u003eboard reporting that explains capability gaps without drowning leaders in tool names\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThis is also useful for conversations between security and HR. Security teams often know the work but struggle to translate it into hiring language. HR teams know job architecture but may not know which technical requirements are real, teachable, overstated, or obsolete. A shared framework gives both sides something better than improvisation.\u003c/p\u003e\n\u003ch2 id=\"the-real-goal\"\u003eThe Real Goal\u003ca class=\"heading-anchor\" href=\"#the-real-goal\" aria-label=\"Link to The Real Goal\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe goal is not to standardize people into boxes.\u003c/p\u003e\n\u003cp\u003eThe goal is to make the work legible.\u003c/p\u003e\n\u003cp\u003eWhen the work is legible, organizations can hire more honestly, train more deliberately, and stop pretending that every new technology requires impossible experience requirements. They can say: this role needs advanced incident response, intermediate cloud security, basic AI literacy, and a clear path toward model risk assessment over the next year.\u003c/p\u003e\n\u003cp\u003eThat is a much better conversation than asking for 10 years of generative AI experience.\u003c/p\u003e\n\u003cp\u003eI am currently capturing the framework information to turn it into mind maps. More to come there. For now, the useful move is simple: treat the framework as a box of building blocks, not as a finished building.\u003c/p\u003e\n","date_modified":"2026-08-09T00:00:00Z","date_published":"2026-08-09T00:00:00Z","id":"https://BHDicaire.com/en/blog/build-your-own-cybersecurity-skills-framework/","summary":"The Linux Foundation has published a useful Cybersecurity Skills Framework that identifies 14 cybersecurity-related job families and organizes baseline skills into three proficiency tiers.\n","title":"Build your own Cybersecurity Skills Framework","url":"https://BHDicaire.com/en/blog/build-your-own-cybersecurity-skills-framework/"},{"content_html":"\u003ch1 id=\"til-portable-filename-rules\"\u003eTIL: Portable Filename Rules\u003c/h1\u003e\n\u003caside class=\"not-prose my-5 flex gap-3 border-l-2 border-line pl-[var(--space-xs)]\" aria-label=\"Companion note\"\u003e\n  \u003cspan class=\"text-accent select-none\" aria-hidden=\"true\"\u003e↩︎\u003c/span\u003e\n  \u003cp class=\"m-0 text-sm text-muted [\u0026\u003ea]:text-accent\"\u003e\n    \u003cspan class=\"meta\"\u003eCompanion note —\u003c/span\u003e\n    \u003ca href=\"/en/blog/files/\"\u003eFile survival\u003c/a\u003e\n    is the narrative starting point for the file survival series.\n  \u003c/p\u003e\n\u003c/aside\u003e\n\n\u003cp\u003ePortable filenames should optimize for the strictest system in the chain, not the most permissive one.\u003c/p\u003e\n\u003cp\u003eUse this safe character set:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ea-z 0-9 - _ .\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eAvoid spaces, emoji, shell-sensitive punctuation, URL-sensitive punctuation, leading spaces, trailing spaces, and trailing dots.\u003c/p\u003e\n\u003cp\u003eRecommended pattern:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_scope_kind_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_infosec_runbook_backup-restore_v01.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"facts\"\u003eFacts\u003ca class=\"heading-anchor\" href=\"#facts\" aria-label=\"Link to Facts\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e/\u003c/code\u003e is a path separator on Unix-like systems and cannot be used inside a filename.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\\\u003c/code\u003e is a path separator on Windows and should not be used inside a filename.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eThe NUL byte cannot be used inside POSIX-style filenames.\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eNames that differ only by case can behave differently across Linux, macOS, Windows, SMB, Git, and ZFS settings.\u003csup id=\"fnref:4\"\u003e\u003ca href=\"#fn:4\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e4\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eFilename length may be counted in bytes, characters, or UTF-16 code units depending on the layer.\u003csup id=\"fnref1:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eNon-ASCII names may expand when URL-encoded.\u003c/li\u003e\n\u003cli\u003eUnicode normalization can make visually identical names compare differently.\u003csup id=\"fnref1:4\"\u003e\u003ca href=\"#fn:4\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e4\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eEmoji and other complex Unicode symbols make normalization, rendering, byte-length, sorting, and input-method problems more likely.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"emoji\"\u003eEmoji\u003ca class=\"heading-anchor\" href=\"#emoji\" aria-label=\"Link to Emoji\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eDo not use emoji in filenames, folder names, or portable passwords.\u003c/p\u003e\n\u003cp\u003eEmoji can be represented by multiple Unicode code points, consume more bytes than expected, render differently across platforms, sort unpredictably, and fail in older tools, scripts, archives, URLs, sync clients, or password-entry flows.\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eApple Developer Documentation, \u003ca href=\"https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemDetails/FileSystemDetails.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFile System Programming Guide\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eMicrosoft Learn, \u003ca href=\"https://learn.microsoft.com/en-us/windows/win32/fileio/filesystem-functionality-comparison\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFile System Functionality Comparison\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u0026#160;\u003ca href=\"#fnref1:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:3\"\u003e\n\u003cp\u003eThe POSIX portable filename character set avoids system-specific punctuation and control-character problems. See The Open Group, \u003ca href=\"https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ePortable Filename Character Set\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:4\"\u003e\n\u003cp\u003eOpenZFS documents dataset properties for case sensitivity, UTF-8-only names, and normalization. See OpenZFS, \u003ca href=\"https://openzfs.github.io/openzfs-docs/man/master/7/zfsprops.7.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eZFS Properties\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:4\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u0026#160;\u003ca href=\"#fnref1:4\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/til/portable-filename-rules/","summary":"TIL: Portable Filename Rules ↩︎ Companion note — File survival is the narrative starting point for the file survival series. ","title":"TIL: Portable Filename Rules","url":"https://BHDicaire.com/en/til/portable-filename-rules/"},{"content_html":"\u003ch1 id=\"til-network-transfer-filename-limits\"\u003eTIL: Network Transfer Filename Limits\u003c/h1\u003e\n\u003caside class=\"not-prose my-5 flex gap-3 border-l-2 border-line pl-[var(--space-xs)]\" aria-label=\"Companion note\"\u003e\n  \u003cspan class=\"text-accent select-none\" aria-hidden=\"true\"\u003e↩︎\u003c/span\u003e\n  \u003cp class=\"m-0 text-sm text-muted [\u0026\u003ea]:text-accent\"\u003e\n    \u003cspan class=\"meta\"\u003eCompanion note —\u003c/span\u003e\n    \u003ca href=\"/en/blog/files/\"\u003eFile survival\u003c/a\u003e\n    is the narrative starting point for the file survival series.\n  \u003c/p\u003e\n\u003c/aside\u003e\n\n\u003cp\u003eNetwork protocols add another translation layer between the client, server, and underlying filesystem.\u003c/p\u003e\n\u003cp\u003eThe safe name is the name that survives every layer in the transfer chain.\u003c/p\u003e\n\u003ch2 id=\"facts\"\u003eFacts\u003ca class=\"heading-anchor\" href=\"#facts\" aria-label=\"Link to Facts\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eSMB/CIFS often exposes Windows-like naming and path behavior even when backed by non-Windows storage.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eNFSv4 generally uses UTF-8 strings, but server and filesystem behavior can vary.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eSFTP/SCP usually transfer file content reliably, but metadata preservation depends on tool behavior.\u003c/li\u003e\n\u003cli\u003ersync can preserve owners, groups, permissions, ACLs, xattrs, hard links, and timestamps when configured with the right options.\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eWebDAV exposes names through URL paths, so escaping and path length matter.\u003csup id=\"fnref:4\"\u003e\u003ca href=\"#fn:4\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e4\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eCloud sync clients add their own local path roots, conflict naming, ignored files, and metadata behavior.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse the conservative filename and path budget before transferring files:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efilename:        80 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder segment:  40 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efull path:       160 characters or fewer when practical\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder depth:    4 to 6 levels maximum\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eMicrosoft Learn, \u003ca href=\"https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/09c2ccc8-4aaf-439f-9b4e-13b3fe85a4cf\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCIFS File and Directory Names\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eRFC Editor, \u003ca href=\"https://www.rfc-editor.org/info/rfc7530/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eNFS Version 4 Protocol\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:3\"\u003e\n\u003cp\u003ersync, \u003ca href=\"https://rsync.samba.org/ftp/rsync/rsync.1.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ersync Manpage\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:4\"\u003e\n\u003cp\u003eRFC Editor, \u003ca href=\"https://www.rfc-editor.org/info/rfc4918/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWebDAV\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:4\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/til/network-transfer-filename-limits/","summary":"TIL: Network Transfer Filename Limits ↩︎ Companion note — File survival is the narrative starting point for the file survival series. ","title":"TIL: Network Transfer Filename Limits","url":"https://BHDicaire.com/en/til/network-transfer-filename-limits/"},{"content_html":"\u003ch1 id=\"til-filesystem-filename-limits\"\u003eTIL: Filesystem Filename Limits\u003c/h1\u003e\n\u003caside class=\"not-prose my-5 flex gap-3 border-l-2 border-line pl-[var(--space-xs)]\" aria-label=\"Companion note\"\u003e\n  \u003cspan class=\"text-accent select-none\" aria-hidden=\"true\"\u003e↩︎\u003c/span\u003e\n  \u003cp class=\"m-0 text-sm text-muted [\u0026\u003ea]:text-accent\"\u003e\n    \u003cspan class=\"meta\"\u003eCompanion note —\u003c/span\u003e\n    \u003ca href=\"/en/blog/files/\"\u003eFile survival\u003c/a\u003e\n    is the narrative starting point for the file survival series.\n  \u003c/p\u003e\n\u003c/aside\u003e\n\n\u003cp\u003eModern filesystems can handle much more than a conservative naming convention allows. That does not mean portable names should use every available feature.\u003c/p\u003e\n\u003ch2 id=\"windows-and-ntfs\"\u003eWindows and NTFS\u003ca class=\"heading-anchor\" href=\"#windows-and-ntfs\" aria-label=\"Link to Windows and NTFS\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eNTFS stores filenames in Unicode.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eNTFS supports long filenames, but many Windows tools and applications still encounter practical path limits.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eAvoid reserved Windows names such as \u003ccode\u003eCON\u003c/code\u003e, \u003ccode\u003ePRN\u003c/code\u003e, \u003ccode\u003eAUX\u003c/code\u003e, \u003ccode\u003eNUL\u003c/code\u003e, \u003ccode\u003eCOM1\u003c/code\u003e, and \u003ccode\u003eLPT1\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eAvoid \u003ccode\u003e\\ / : * ? \u0026quot; \u0026lt; \u0026gt; |\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eNTFS alternate data streams may not survive cross-platform copy, archive, or migration workflows.\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eNTFS ACLs, owners, groups, and audit data require tools that explicitly preserve Windows security metadata.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"macos\"\u003emacOS\u003ca class=\"heading-anchor\" href=\"#macos\" aria-label=\"Link to macOS\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003emacOS supports Unicode filenames and long names, but each path component is commonly limited to 255 characters.\u003csup id=\"fnref:4\"\u003e\u003ca href=\"#fn:4\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e4\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003emacOS files may have extended attributes, Finder info, quarantine flags, ACLs, and resource forks.\u003c/li\u003e\n\u003cli\u003eSome archive and transfer tools preserve this metadata; others drop it or store it as AppleDouble \u003ccode\u003e._\u003c/code\u003e sidecar files.\u003c/li\u003e\n\u003cli\u003eA filename-only convention does not preserve macOS metadata.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"linux-filesystems\"\u003eLinux Filesystems\u003ca class=\"heading-anchor\" href=\"#linux-filesystems\" aria-label=\"Link to Linux Filesystems\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eext4 filenames are limited to 255 bytes.\u003csup id=\"fnref:5\"\u003e\u003ca href=\"#fn:5\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e5\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eBtrfs documents a 255-byte filename limit.\u003csup id=\"fnref:6\"\u003e\u003ca href=\"#fn:6\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e6\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eZFS supports dataset properties that affect case sensitivity, UTF-8 enforcement, and Unicode normalization.\u003csup id=\"fnref:7\"\u003e\u003ca href=\"#fn:7\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e7\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003ePOSIX-style permissions, owners, groups, ACLs, extended attributes, SELinux labels, hard links, symlinks, and sparse files may need explicit preservation during archive or transfer.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eMicrosoft Learn, \u003ca href=\"https://learn.microsoft.com/en-us/windows/win32/fileio/filesystem-functionality-comparison\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFile System Functionality Comparison\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eMicrosoft Support, \u003ca href=\"https://support.microsoft.com/en-us/onedrive/what-are-file-path-length-limits\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWhat are the file path length limits?\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:3\"\u003e\n\u003cp\u003eMicrosoft Learn, \u003ca href=\"https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/c54dec26-1551-4d3a-a0ea-4fa40f848eb3\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eNTFS Streams\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:4\"\u003e\n\u003cp\u003eApple Developer Documentation, \u003ca href=\"https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemDetails/FileSystemDetails.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFile System Programming Guide\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:4\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:5\"\u003e\n\u003cp\u003eLinux Kernel Documentation, \u003ca href=\"https://www.kernel.org/doc/html/latest/filesystems/ext4/directory.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eext4 Directory Entries\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:5\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:6\"\u003e\n\u003cp\u003eBtrfs Documentation, \u003ca href=\"https://btrfs.readthedocs.io/en/latest/ch-fs-limits.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFilesystem Limits\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:6\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:7\"\u003e\n\u003cp\u003eOpenZFS, \u003ca href=\"https://openzfs.github.io/openzfs-docs/man/master/7/zfsprops.7.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eZFS Properties\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:7\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/til/filesystem-filename-limits/","summary":"TIL: Filesystem Filename Limits ↩︎ Companion note — File survival is the narrative starting point for the file survival series. ","title":"TIL: Filesystem Filename Limits","url":"https://BHDicaire.com/en/til/filesystem-filename-limits/"},{"content_html":"\u003ch1 id=\"til-file-naming-portability-facts\"\u003eTIL: File Naming Portability Facts\u003c/h1\u003e\n\u003caside class=\"not-prose my-5 flex gap-3 border-l-2 border-line pl-[var(--space-xs)]\" aria-label=\"Companion note\"\u003e\n  \u003cspan class=\"text-accent select-none\" aria-hidden=\"true\"\u003e↩︎\u003c/span\u003e\n  \u003cp class=\"m-0 text-sm text-muted [\u0026\u003ea]:text-accent\"\u003e\n    \u003cspan class=\"meta\"\u003eCompanion note —\u003c/span\u003e\n    \u003ca href=\"/en/blog/files/\"\u003eFile survival\u003c/a\u003e\n    is the narrative starting point for the file survival series.\n  \u003c/p\u003e\n\u003c/aside\u003e\n\n\u003cp\u003eThe original portability note was too long for one TIL. I split it into shorter references so each one answers a smaller question.\u003c/p\u003e\n\u003cp\u003eStart here:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/en/til/portable-filename-rules/\"\u003ePortable filename rules\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/filesystem-filename-limits/\"\u003eFilesystem filename limits\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/cloud-git-filename-limits/\"\u003eCloud and Git filename limits\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/network-transfer-filename-limits/\"\u003eNetwork transfer filename limits\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/archive-metadata-portability/\"\u003eArchive and metadata portability\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe shared recommendation stays the same:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_scope_kind_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse this conservative character set:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ea-z 0-9 - _ .\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse this conservative working budget:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efilename:        80 characters or fewer, including extension\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder segment:  40 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efull path:       160 characters or fewer when practical\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder depth:    4 to 6 levels maximum\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe \u003ccode\u003e160\u003c/code\u003e character full-path target is intentionally conservative. It is not the maximum supported by modern filesystems or cloud platforms. It is a practical limit meant to reduce failures across sync clients, Office apps, URLs, archives, migrations, and mixed operating systems.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eMicrosoft documents higher OneDrive and SharePoint limits, including a 400-character decoded path limit in Microsoft 365. The recommendation here is deliberately below those limits to leave room for sync roots, local tools, and future folder growth. See Microsoft Support, \u003ca href=\"https://support.microsoft.com/en-US/onedrive/restrictions-and-limitations-in-onedrive-and-sharepoint\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRestrictions and limitations in OneDrive and SharePoint\u003c/a\u003e\n and \u003ca href=\"https://support.microsoft.com/en-us/onedrive/what-are-file-path-length-limits\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWhat are the file path length limits?\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/til/file-naming-portability-facts/","summary":"TIL: File Naming Portability Facts ↩︎ Companion note — File survival is the narrative starting point for the file survival series. ","title":"TIL: File Naming Portability Facts","url":"https://BHDicaire.com/en/til/file-naming-portability-facts/"},{"content_html":"\u003ch1 id=\"til-cloud-and-git-filename-limits\"\u003eTIL: Cloud and Git Filename Limits\u003c/h1\u003e\n\u003caside class=\"not-prose my-5 flex gap-3 border-l-2 border-line pl-[var(--space-xs)]\" aria-label=\"Companion note\"\u003e\n  \u003cspan class=\"text-accent select-none\" aria-hidden=\"true\"\u003e↩︎\u003c/span\u003e\n  \u003cp class=\"m-0 text-sm text-muted [\u0026\u003ea]:text-accent\"\u003e\n    \u003cspan class=\"meta\"\u003eCompanion note —\u003c/span\u003e\n    \u003ca href=\"/en/blog/files/\"\u003eFile survival\u003c/a\u003e\n    is the narrative starting point for the file survival series.\n  \u003c/p\u003e\n\u003c/aside\u003e\n\n\u003cp\u003eCloud platforms and Git usually fail at the edges: long paths, sync roots, local client behavior, case-only names, and names that are technically allowed but operationally annoying.\u003c/p\u003e\n\u003ch2 id=\"git-and-github\"\u003eGit and GitHub\u003ca class=\"heading-anchor\" href=\"#git-and-github\" aria-label=\"Link to Git and GitHub\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eGit can track files whose names differ only by case, but case-insensitive client filesystems can have trouble checking them out.\u003c/li\u003e\n\u003cli\u003eLowercase filenames reduce cross-platform Git friction.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ekebab-case\u003c/code\u003e is common for repository files, documentation, static assets, and URLs.\u003c/li\u003e\n\u003cli\u003eDate-first names are useful for chronological artifacts such as reports, release notes, exports, and incident records.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"sharepoint-and-onedrive\"\u003eSharePoint and OneDrive\u003ca class=\"heading-anchor\" href=\"#sharepoint-and-onedrive\" aria-label=\"Link to SharePoint and OneDrive\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eMicrosoft documents a 400-character decoded path limit for OneDrive and SharePoint in Microsoft 365.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eSync clients and desktop apps add additional practical limits.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eOneDrive sync roots can add a long local prefix such as \u003ccode\u003eOneDrive - Organization Name\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eOffice temporary lock files can make near-limit paths fail.\u003c/li\u003e\n\u003cli\u003eSome organizations may still restrict characters such as \u003ccode\u003e#\u003c/code\u003e and \u003ccode\u003e%\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eAvoid leading/trailing spaces and trailing dots.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"google-drive\"\u003eGoogle Drive\u003ca class=\"heading-anchor\" href=\"#google-drive\" aria-label=\"Link to Google Drive\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eGoogle Drive stores many file types and supports large files.\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eGoogle Workspace documents large upload and storage limits.\u003csup id=\"fnref:4\"\u003e\u003ca href=\"#fn:4\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e4\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003eGoogle Drive for desktop still interacts with local macOS or Windows path behavior.\u003c/li\u003e\n\u003cli\u003eDeep shared-drive structures can cause practical path problems during sync, download, ZIP extraction, or migration.\u003c/li\u003e\n\u003cli\u003eDo not rely on Drive-only metadata if files may later be exported or migrated.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eMicrosoft Support, \u003ca href=\"https://support.microsoft.com/en-US/onedrive/restrictions-and-limitations-in-onedrive-and-sharepoint\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRestrictions and limitations in OneDrive and SharePoint\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eMicrosoft Support, \u003ca href=\"https://support.microsoft.com/en-us/onedrive/what-are-file-path-length-limits\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWhat are the file path length limits?\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:3\"\u003e\n\u003cp\u003eGoogle Drive Help, \u003ca href=\"https://support.google.com/drive/answer/37603\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFiles you can store in Google Drive\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:4\"\u003e\n\u003cp\u003eGoogle Workspace Help, \u003ca href=\"https://knowledge.workspace.google.com/admin/drive/storage-and-upload-limits-for-google-workspace\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStorage and upload limits for Google Workspace\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:4\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/til/cloud-git-filename-limits/","summary":"TIL: Cloud and Git Filename Limits ↩︎ Companion note — File survival is the narrative starting point for the file survival series. ","title":"TIL: Cloud and Git Filename Limits","url":"https://BHDicaire.com/en/til/cloud-git-filename-limits/"},{"content_html":"\u003ch1 id=\"til-archive-and-metadata-portability\"\u003eTIL: Archive and Metadata Portability\u003c/h1\u003e\n\u003caside class=\"not-prose my-5 flex gap-3 border-l-2 border-line pl-[var(--space-xs)]\" aria-label=\"Companion note\"\u003e\n  \u003cspan class=\"text-accent select-none\" aria-hidden=\"true\"\u003e↩︎\u003c/span\u003e\n  \u003cp class=\"m-0 text-sm text-muted [\u0026\u003ea]:text-accent\"\u003e\n    \u003cspan class=\"meta\"\u003eCompanion note —\u003c/span\u003e\n    \u003ca href=\"/en/blog/files/\"\u003eFile survival\u003c/a\u003e\n    is the narrative starting point for the file survival series.\n  \u003c/p\u003e\n\u003c/aside\u003e\n\n\u003cp\u003eArchives are not all equivalent. Some are file bundles. Some are compression streams. Some preserve metadata well. Some preserve only visible file contents and basic names.\u003c/p\u003e\n\u003ch2 id=\"archive-formats\"\u003eArchive Formats\u003ca class=\"heading-anchor\" href=\"#archive-formats\" aria-label=\"Link to Archive Formats\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e.zip\u003c/code\u003e is broadly compatible but not a complete metadata-preserving backup format by default.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.rar\u003c/code\u003e can preserve some NTFS-specific metadata when created with the right options.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.7z\u003c/code\u003e has strong compression and modern Unicode support, but metadata preservation varies by tool and platform.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.tar\u003c/code\u003e is a better fit for Unix/Linux directory trees and metadata.\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.tar.gz\u003c/code\u003e, \u003ccode\u003e.tgz\u003c/code\u003e, \u003ccode\u003e.tar.xz\u003c/code\u003e, and \u003ccode\u003e.tar.zst\u003c/code\u003e are tar archives compressed by another algorithm.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.gz\u003c/code\u003e alone normally compresses one stream, not a directory tree.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"metadata-not-captured-by-filenames\"\u003eMetadata Not Captured by Filenames\u003ca class=\"heading-anchor\" href=\"#metadata-not-captured-by-filenames\" aria-label=\"Link to Metadata Not Captured by Filenames\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ecreated, modified, and accessed timestamps;\u003c/li\u003e\n\u003cli\u003eowner and group names;\u003c/li\u003e\n\u003cli\u003enumeric UID and GID;\u003c/li\u003e\n\u003cli\u003ePOSIX mode bits;\u003c/li\u003e\n\u003cli\u003ePOSIX ACLs;\u003c/li\u003e\n\u003cli\u003eNTFS ACLs and security descriptors;\u003c/li\u003e\n\u003cli\u003eNTFS alternate data streams;\u003c/li\u003e\n\u003cli\u003emacOS resource forks;\u003c/li\u003e\n\u003cli\u003emacOS Finder info;\u003c/li\u003e\n\u003cli\u003emacOS extended attributes;\u003c/li\u003e\n\u003cli\u003eLinux extended attributes;\u003c/li\u003e\n\u003cli\u003eSELinux labels;\u003c/li\u003e\n\u003cli\u003ehard links;\u003c/li\u003e\n\u003cli\u003esymbolic links;\u003c/li\u003e\n\u003cli\u003esparse file layout;\u003c/li\u003e\n\u003cli\u003efile flags and immutability attributes.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA filename convention protects names, not full file identity.\u003c/p\u003e\n\u003cp\u003eUse tools that explicitly preserve the metadata you need. Then test restore, not just backup.\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003ePKWARE, \u003ca href=\"https://support.pkware.com/pkzip/appnote\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eZIP Application Note\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eWinRAR Documentation, \u003ca href=\"https://documentation.help/WinRAR/HELPGetArcAdvanced.htm\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAdvanced Archive Options\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:3\"\u003e\n\u003cp\u003eGNU, \u003ca href=\"https://www.gnu.org/software/tar/manual/tar.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGNU tar Manual\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/til/archive-metadata-portability/","summary":"TIL: Archive and Metadata Portability ↩︎ Companion note — File survival is the narrative starting point for the file survival series. ","title":"TIL: Archive and Metadata Portability","url":"https://BHDicaire.com/en/til/archive-metadata-portability/"},{"content_html":"\u003cp\u003eThis temporary page tests a more visual way to browse mindmaps before deciding whether it should replace or complement the series table.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/mindmaps/gallery/","summary":"This temporary page tests a more visual way to browse mindmaps before deciding whether it should replace or complement the series table.\n","title":"Mindmap gallery","url":"https://BHDicaire.com/en/blog/mindmaps/gallery/"},{"content_html":"\u003ch1 id=\"git-repository-naming\"\u003eGit Repository Naming\u003c/h1\u003e\n\u003cp\u003eGit repositories are file systems with memory.\u003c/p\u003e\n\u003cp\u003eNames matter because they become paths, URLs, imports, scripts, documentation links, package names, release artifacts, and habits.\u003c/p\u003e\n\u003ch2 id=\"repository-names\"\u003eRepository Names\u003ca class=\"heading-anchor\" href=\"#repository-names\" aria-label=\"Link to Repository Names\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse lowercase \u003ccode\u003ekebab-case\u003c/code\u003e for repository names:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efiles-guide\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebackup-restore-playbook\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esharepoint-migration-tools\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eAvoid:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eFileSurvivalGuide\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efile_survival_guide\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efile survival guide\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efiles-guide-final\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eRepository names often become URLs. Kebab case is boring, readable, and web-friendly.\u003c/p\u003e\n\u003ch2 id=\"directory-names\"\u003eDirectory Names\u003ca class=\"heading-anchor\" href=\"#directory-names\" aria-label=\"Link to Directory Names\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse lowercase names for directories:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocs/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003escripts/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esrc/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etests/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eassets/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eexamples/\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor documentation collections, use \u003ccode\u003ekebab-case\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eincidents/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebackup-restore/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efiles/\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"file-names\"\u003eFile Names\u003ca class=\"heading-anchor\" href=\"#file-names\" aria-label=\"Link to File Names\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse the convention of the ecosystem when one exists.\u003c/p\u003e\n\u003cp\u003eExamples:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eREADME.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eLICENSE\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eDockerfile\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eMakefile\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003epackage.json\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ego.mod\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003epyproject.toml\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor ordinary docs and assets, use lowercase \u003ccode\u003ekebab-case\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebackup-restore-checklist.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esharepoint-path-limits.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efile-naming.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse date-first names for chronological artifacts:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_incident-report_auth-timeout_v01.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_dependency-audit_v01.json\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_release-notes_v01.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"avoid-case-only-renames\"\u003eAvoid Case-Only Renames\u003ca class=\"heading-anchor\" href=\"#avoid-case-only-renames\" aria-label=\"Link to Avoid Case-Only Renames\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCase-only renames can be awkward across Git clients and filesystems.\u003c/p\u003e\n\u003cp\u003eInstead of changing:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eReadme.md -\u0026gt; README.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003euse an explicit two-step rename when needed:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eReadme.md -\u0026gt; readme-temp.md -\u0026gt; README.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat makes the change visible to Git and safer across platforms.\u003c/p\u003e\n\u003ch2 id=\"branch-names\"\u003eBranch Names\u003ca class=\"heading-anchor\" href=\"#branch-names\" aria-label=\"Link to Branch Names\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse lowercase slash-separated branch names:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efeature/files-intro\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efix/sharepoint-path-budget\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocs/archive-metadata\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eKeep branch names short enough to read in terminals, CI systems, and pull request pages.\u003c/p\u003e\n\u003ch2 id=\"generated-files\"\u003eGenerated Files\u003ca class=\"heading-anchor\" href=\"#generated-files\" aria-label=\"Link to Generated Files\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eGenerated files should be clearly named or clearly located:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003epublic/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edist/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebuild/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egenerated/\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eAvoid mixing generated files with hand-authored source when possible.\u003c/p\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor Git:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erepo names:      kebab-case\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebranch names:    lowercase/path-style\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edoc files:       kebab-case.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echronological:   YYYYMMDD_subject_v##.ext\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eavoid:           case-only differences\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eGit remembers names for a long time. Make them calm.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/git-repository-naming/","summary":"Git Repository Naming Git repositories are file systems with memory.\nNames matter because they become paths, URLs, imports, scripts, documentation links, package names, release artifacts, and habits.\n","title":"Git repository naming","url":"https://BHDicaire.com/en/blog/files/git-repository-naming/"},{"content_html":"\u003ch1 id=\"file-survival-operational-checklist\"\u003eFile Survival Operational Checklist\u003c/h1\u003e\n\u003cp\u003eUse this checklist before moving, syncing, archiving, backing up, or restoring important files.\u003c/p\u003e\n\u003ch2 id=\"1-name\"\u003e1. Name\u003ca class=\"heading-anchor\" href=\"#1-name\" aria-label=\"Link to 1. Name\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCheck:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003efilenames use safe characters;\u003c/li\u003e\n\u003cli\u003eno emoji;\u003c/li\u003e\n\u003cli\u003eno spaces where scripts or URLs matter;\u003c/li\u003e\n\u003cli\u003eno case-only duplicates;\u003c/li\u003e\n\u003cli\u003eextensions are lowercase;\u003c/li\u003e\n\u003cli\u003edates use \u003ccode\u003eYYYYMMDD\u003c/code\u003e when chronological sorting matters;\u003c/li\u003e\n\u003cli\u003eversions use \u003ccode\u003ev01\u003c/code\u003e, \u003ccode\u003ev02\u003c/code\u003e, \u003ccode\u003ev03\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eRecommended pattern:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_scope_kind_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"2-path\"\u003e2. Path\u003ca class=\"heading-anchor\" href=\"#2-path\" aria-label=\"Link to 2. Path\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCheck:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003efilename is 80 characters or fewer;\u003c/li\u003e\n\u003cli\u003efolder segment is 40 characters or fewer;\u003c/li\u003e\n\u003cli\u003efull path is 160 characters or fewer when practical;\u003c/li\u003e\n\u003cli\u003efolder depth is 4 to 6 levels maximum;\u003c/li\u003e\n\u003cli\u003eshared-drive roots and sync roots are included in the real path length.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"3-content\"\u003e3. Content\u003ca class=\"heading-anchor\" href=\"#3-content\" aria-label=\"Link to 3. Content\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCheck:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003efile opens on the destination;\u003c/li\u003e\n\u003cli\u003efile hash matches if exact preservation matters;\u003c/li\u003e\n\u003cli\u003eline endings are acceptable;\u003c/li\u003e\n\u003cli\u003ebinary files were not transformed;\u003c/li\u003e\n\u003cli\u003eapp-specific files still open in the intended app.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"4-permissions\"\u003e4. Permissions\u003ca class=\"heading-anchor\" href=\"#4-permissions\" aria-label=\"Link to 4. Permissions\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCheck:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eexecutable bits;\u003c/li\u003e\n\u003cli\u003eowner;\u003c/li\u003e\n\u003cli\u003egroup;\u003c/li\u003e\n\u003cli\u003eUID/GID mapping;\u003c/li\u003e\n\u003cli\u003ebasic mode bits;\u003c/li\u003e\n\u003cli\u003ePOSIX ACLs;\u003c/li\u003e\n\u003cli\u003eNTFS ACLs;\u003c/li\u003e\n\u003cli\u003einherited permissions.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"5-metadata\"\u003e5. Metadata\u003ca class=\"heading-anchor\" href=\"#5-metadata\" aria-label=\"Link to 5. Metadata\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCheck:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ecreated/modified timestamps;\u003c/li\u003e\n\u003cli\u003eextended attributes;\u003c/li\u003e\n\u003cli\u003emacOS resource forks;\u003c/li\u003e\n\u003cli\u003eFinder info;\u003c/li\u003e\n\u003cli\u003equarantine flags;\u003c/li\u003e\n\u003cli\u003eNTFS alternate data streams;\u003c/li\u003e\n\u003cli\u003eSELinux labels;\u003c/li\u003e\n\u003cli\u003efile flags.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"6-links-and-special-files\"\u003e6. Links and Special Files\u003ca class=\"heading-anchor\" href=\"#6-links-and-special-files\" aria-label=\"Link to 6. Links and Special Files\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCheck:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003esymlinks;\u003c/li\u003e\n\u003cli\u003ehard links;\u003c/li\u003e\n\u003cli\u003esparse files;\u003c/li\u003e\n\u003cli\u003epackage directories;\u003c/li\u003e\n\u003cli\u003ehidden files;\u003c/li\u003e\n\u003cli\u003edotfiles;\u003c/li\u003e\n\u003cli\u003etemporary lock files;\u003c/li\u003e\n\u003cli\u003eignored files.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"7-tool-choice\"\u003e7. Tool Choice\u003ca class=\"heading-anchor\" href=\"#7-tool-choice\" aria-label=\"Link to 7. Tool Choice\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eChoose the tool by job:\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eJob\u003c/th\u003e\n          \u003cth\u003eTool family\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003equick personal copy\u003c/td\u003e\n          \u003ctd\u003eFinder, Explorer, basic copy\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003erepeatable tree copy\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003ersync\u003c/code\u003e, \u003ccode\u003erobocopy\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eUnix-like archive\u003c/td\u003e\n          \u003ctd\u003eTAR\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ebroad sharing\u003c/td\u003e\n          \u003ctd\u003eZIP\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ecloud collaboration\u003c/td\u003e\n          \u003ctd\u003eSharePoint, OneDrive, Google Drive\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003erecovery\u003c/td\u003e\n          \u003ctd\u003ebackup system with tested restore\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"8-test-restore\"\u003e8. Test Restore\u003ca class=\"heading-anchor\" href=\"#8-test-restore\" aria-label=\"Link to 8. Test Restore\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA restore test should prove:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ethe files can be found;\u003c/li\u003e\n\u003cli\u003ecredentials work;\u003c/li\u003e\n\u003cli\u003erestore target is clean;\u003c/li\u003e\n\u003cli\u003enames and paths survive;\u003c/li\u003e\n\u003cli\u003epermissions are correct;\u003c/li\u003e\n\u003cli\u003emetadata needed by the workflow survives;\u003c/li\u003e\n\u003cli\u003eapplications still work;\u003c/li\u003e\n\u003cli\u003erecovery time is acceptable.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"9-document-the-result\"\u003e9. Document the Result\u003ca class=\"heading-anchor\" href=\"#9-document-the-result\" aria-label=\"Link to 9. Document the Result\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eRecord:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003esource;\u003c/li\u003e\n\u003cli\u003edestination;\u003c/li\u003e\n\u003cli\u003etool and version;\u003c/li\u003e\n\u003cli\u003ecommand or settings;\u003c/li\u003e\n\u003cli\u003eexcluded paths;\u003c/li\u003e\n\u003cli\u003epreserved metadata;\u003c/li\u003e\n\u003cli\u003eknown losses;\u003c/li\u003e\n\u003cli\u003evalidation checks;\u003c/li\u003e\n\u003cli\u003edate tested.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"final-question\"\u003eFinal Question\u003ca class=\"heading-anchor\" href=\"#final-question\" aria-label=\"Link to Final Question\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eBefore declaring success, ask:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eDid the file merely arrive, or did it survive?\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/files-operational-checklist/","summary":"File Survival Operational Checklist Use this checklist before moving, syncing, archiving, backing up, or restoring important files.\n1. Name# Check:\n","title":"File survival operational checklist","url":"https://BHDicaire.com/en/blog/files/files-operational-checklist/"},{"content_html":"\u003ch1 id=\"file-and-directory-permissions\"\u003eFile and Directory Permissions\u003c/h1\u003e\n\u003cp\u003eFile names tell you what something is. Permissions decide who can do something with it.\u003c/p\u003e\n\u003cp\u003eThat distinction matters when files move across systems. A document can keep its name and visible content while losing the permission details that made it usable, private, executable, restorable, or secure.\u003c/p\u003e\n\u003ch2 id=\"the-basic-posix-model\"\u003eThe Basic POSIX Model\u003ca class=\"heading-anchor\" href=\"#the-basic-posix-model\" aria-label=\"Link to The Basic POSIX Model\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUnix-like systems commonly start with three permission classes:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eowner;\u003c/li\u003e\n\u003cli\u003egroup;\u003c/li\u003e\n\u003cli\u003eothers.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eAnd three basic actions:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eread;\u003c/li\u003e\n\u003cli\u003ewrite;\u003c/li\u003e\n\u003cli\u003eexecute.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThat gives familiar modes like:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e0644  owner can read/write; group and others can read\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e0755  owner can read/write/execute; group and others can read/execute\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e0600  owner can read/write; nobody else has access\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e0700  owner can read/write/execute; nobody else has access\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor directories, execute has a special meaning: it controls whether a user can traverse the directory. A directory can be readable but not enterable, or enterable but not listable, depending on the exact mode.\u003c/p\u003e\n\u003ch2 id=\"owners-groups-uid-and-gid\"\u003eOwners, Groups, UID, and GID\u003ca class=\"heading-anchor\" href=\"#owners-groups-uid-and-gid\" aria-label=\"Link to Owners, Groups, UID, and GID\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eHuman-readable owner and group names are labels. Under the hood, Unix-like systems use numeric IDs:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eowner name  -\u0026gt; UID\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egroup name  -\u0026gt; GID\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat matters during backup and restore. If a file is restored to another machine where UID \u003ccode\u003e501\u003c/code\u003e belongs to a different user, the file may appear to have the wrong owner even if the numeric metadata was preserved.\u003c/p\u003e\n\u003cp\u003eFor personal files, owner-name drift is annoying. For servers, services, containers, and shared storage, UID/GID drift can break applications.\u003c/p\u003e\n\u003ch2 id=\"umask\"\u003eumask\u003ca class=\"heading-anchor\" href=\"#umask\" aria-label=\"Link to umask\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003eumask\u003c/code\u003e controls the default permissions applied when new files and directories are created.\u003c/p\u003e\n\u003cp\u003eFor example:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edefault request: 0666\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eumask:           0022\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eresult:          0644\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eDifferent shells, services, containers, deployment tools, and network shares may use different default masks. If copied files suddenly become too open or too closed, \u003ccode\u003eumask\u003c/code\u003e is one of the first places to look.\u003c/p\u003e\n\u003ch2 id=\"acls\"\u003eACLs\u003ca class=\"heading-anchor\" href=\"#acls\" aria-label=\"Link to ACLs\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eACLs add more detailed access rules than basic owner/group/others permissions.\u003c/p\u003e\n\u003cp\u003eThey can express rules such as:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ethis user can read;\u003c/li\u003e\n\u003cli\u003ethis group can write;\u003c/li\u003e\n\u003cli\u003ethis folder inherits permissions from a parent;\u003c/li\u003e\n\u003cli\u003ethis entry applies only to new child files;\u003c/li\u003e\n\u003cli\u003ethis deny rule overrides an allow rule.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eACLs are useful, but they are also easy to lose during copy, sync, archive, and restore. POSIX ACLs, NTFS ACLs, and macOS ACLs are related ideas, not identical formats.\u003c/p\u003e\n\u003ch2 id=\"extended-attributes\"\u003eExtended Attributes\u003ca class=\"heading-anchor\" href=\"#extended-attributes\" aria-label=\"Link to Extended Attributes\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eExtended attributes store extra key/value metadata outside the visible file contents.\u003c/p\u003e\n\u003cp\u003eExamples include:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003emacOS quarantine information;\u003c/li\u003e\n\u003cli\u003eFinder metadata;\u003c/li\u003e\n\u003cli\u003eLinux extended attributes;\u003c/li\u003e\n\u003cli\u003ebackup or sync tool metadata;\u003c/li\u003e\n\u003cli\u003eapplication-specific markers.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eExtended attributes can affect whether a file opens, whether an app is trusted, whether a file is indexed, or how a system labels it.\u003c/p\u003e\n\u003ch2 id=\"selinux-labels\"\u003eSELinux Labels\u003ca class=\"heading-anchor\" href=\"#selinux-labels\" aria-label=\"Link to SELinux Labels\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSELinux adds mandatory access control labels on systems that use it.\u003c/p\u003e\n\u003cp\u003eA file can have apparently correct POSIX permissions and still be blocked because its SELinux context is wrong. That is a common restore problem on hardened Linux systems.\u003c/p\u003e\n\u003cp\u003eFor SELinux-aware systems, permissions are not just:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eowner + group + mode\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThey are closer to:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eowner + group + mode + ACL + xattrs + SELinux context\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"transfer-risk\"\u003eTransfer Risk\u003ca class=\"heading-anchor\" href=\"#transfer-risk\" aria-label=\"Link to Transfer Risk\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eDifferent tools preserve different permission layers.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eMethod\u003c/th\u003e\n          \u003cth\u003eTypical risk\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFinder or Windows Explorer copy\u003c/td\u003e\n          \u003ctd\u003eMay preserve enough for everyday files, but metadata behavior depends on source and destination.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ecp\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eOften needs explicit flags to preserve mode, owner, timestamps, xattrs, and ACLs.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ersync\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eCan preserve rich metadata, but only when configured with the right options.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eZIP\u003c/td\u003e\n          \u003ctd\u003eGood for ordinary sharing, not a reliable permission-preserving backup by default.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTAR\u003c/td\u003e\n          \u003ctd\u003eBetter fit for Unix-like trees, especially with explicit metadata options.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCloud sync\u003c/td\u003e\n          \u003ctd\u003eUsually optimized for collaboration, not full filesystem identity preservation.\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eBefore moving important files, decide which metadata matters:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003econtent only;\u003c/li\u003e\n\u003cli\u003etimestamps;\u003c/li\u003e\n\u003cli\u003eexecutable bits;\u003c/li\u003e\n\u003cli\u003eownership;\u003c/li\u003e\n\u003cli\u003egroups;\u003c/li\u003e\n\u003cli\u003ePOSIX modes;\u003c/li\u003e\n\u003cli\u003eACLs;\u003c/li\u003e\n\u003cli\u003exattrs;\u003c/li\u003e\n\u003cli\u003eSELinux labels;\u003c/li\u003e\n\u003cli\u003esymlinks and hard links;\u003c/li\u003e\n\u003cli\u003esparse files.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThen choose and test a tool that preserves those exact things.\u003c/p\u003e\n\u003cp\u003eThe phrase \u0026ldquo;the copy worked\u0026rdquo; is not enough. The better test is:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erestore it somewhere else and verify behavior\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/permissions-ownership-acls/","summary":"File and Directory Permissions File names tell you what something is. Permissions decide who can do something with it.\nThat distinction matters when files move across systems. A document can keep its name and visible content while losing the permission details that made it usable, private, executable, restorable, or secure.\n","title":"File and directory permissions","url":"https://BHDicaire.com/en/blog/files/permissions-ownership-acls/"},{"content_html":"\u003ch1 id=\"copy-sync-and-migration-tools\"\u003eCopy, Sync, and Migration Tools\u003c/h1\u003e\n\u003cp\u003e\u0026ldquo;I copied the file\u0026rdquo; can mean many different things.\u003c/p\u003e\n\u003cp\u003eIt might mean the visible bytes arrived. It might mean timestamps survived. It might mean permissions survived. It might mean the file tree behaves exactly the same on the destination.\u003c/p\u003e\n\u003cp\u003eThose are different promises.\u003c/p\u003e\n\u003ch2 id=\"copy\"\u003eCopy\u003ca class=\"heading-anchor\" href=\"#copy\" aria-label=\"Link to Copy\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA copy operation usually creates another instance of a file or folder.\u003c/p\u003e\n\u003cp\u003eCommon tools include:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFinder;\u003c/li\u003e\n\u003cli\u003eWindows Explorer;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecp\u003c/code\u003e;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003escp\u003c/code\u003e;\u003c/li\u003e\n\u003cli\u003edrag-and-drop cloud clients.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eCopy is useful for simple movement. It is not always a faithful preservation tool.\u003c/p\u003e\n\u003ch2 id=\"sync\"\u003eSync\u003ca class=\"heading-anchor\" href=\"#sync\" aria-label=\"Link to Sync\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSync tries to make two locations converge.\u003c/p\u003e\n\u003cp\u003eThat sounds stronger than copy, but sync can also propagate mistakes:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003edeleted files;\u003c/li\u003e\n\u003cli\u003erenamed files;\u003c/li\u003e\n\u003cli\u003econflict copies;\u003c/li\u003e\n\u003cli\u003epermission changes;\u003c/li\u003e\n\u003cli\u003ecorrupted content;\u003c/li\u003e\n\u003cli\u003eaccidental overwrites.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSync is not automatically backup. Sync is often replication of current state.\u003c/p\u003e\n\u003ch2 id=\"migration\"\u003eMigration\u003ca class=\"heading-anchor\" href=\"#migration\" aria-label=\"Link to Migration\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eMigration is a planned move from one system of record to another.\u003c/p\u003e\n\u003cp\u003eMigration usually needs more structure:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003einventory;\u003c/li\u003e\n\u003cli\u003emapping;\u003c/li\u003e\n\u003cli\u003etest copy;\u003c/li\u003e\n\u003cli\u003epermission translation;\u003c/li\u003e\n\u003cli\u003euser acceptance;\u003c/li\u003e\n\u003cli\u003ecutover;\u003c/li\u003e\n\u003cli\u003erollback plan;\u003c/li\u003e\n\u003cli\u003epost-migration validation.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eMigration is where naming conventions, path budgets, permissions, ownership, metadata, and application behavior all meet.\u003c/p\u003e\n\u003ch2 id=\"tool-comparison\"\u003eTool Comparison\u003ca class=\"heading-anchor\" href=\"#tool-comparison\" aria-label=\"Link to Tool Comparison\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eTool or method\u003c/th\u003e\n          \u003cth\u003eBest for\u003c/th\u003e\n          \u003cth\u003eWatch for\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFinder\u003c/td\u003e\n          \u003ctd\u003eEveryday macOS copying\u003c/td\u003e\n          \u003ctd\u003eMetadata behavior depends on destination.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eWindows Explorer\u003c/td\u003e\n          \u003ctd\u003eEveryday Windows copying\u003c/td\u003e\n          \u003ctd\u003eLong paths, hidden files, ACL behavior.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ecp\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eLocal Unix-like copies\u003c/td\u003e\n          \u003ctd\u003eNeeds flags for preservation.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ersync\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eRepeatable copy/sync/migration\u003c/td\u003e\n          \u003ctd\u003eOptions matter enormously.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003escp\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eSimple remote copy\u003c/td\u003e\n          \u003ctd\u003eLimited metadata preservation.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSFTP\u003c/td\u003e\n          \u003ctd\u003eInteractive remote file movement\u003c/td\u003e\n          \u003ctd\u003eClient/server behavior varies.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003erobocopy\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eWindows tree copy and migration\u003c/td\u003e\n          \u003ctd\u003ePowerful, but option-heavy.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ecloud sync\u003c/td\u003e\n          \u003ctd\u003eCollaboration and device access\u003c/td\u003e\n          \u003ctd\u003eConflict files, ignored files, path roots.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ebackup tool\u003c/td\u003e\n          \u003ctd\u003eRecovery\u003c/td\u003e\n          \u003ctd\u003eMust test restore.\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"rsync-is-a-tool-not-a-spell\"\u003ersync Is a Tool, Not a Spell\u003ca class=\"heading-anchor\" href=\"#rsync-is-a-tool-not-a-spell\" aria-label=\"Link to rsync Is a Tool, Not a Spell\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003ersync\u003c/code\u003e is excellent because it is explicit.\u003c/p\u003e\n\u003cp\u003eIt can preserve:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003etimestamps;\u003c/li\u003e\n\u003cli\u003epermissions;\u003c/li\u003e\n\u003cli\u003eowners;\u003c/li\u003e\n\u003cli\u003egroups;\u003c/li\u003e\n\u003cli\u003esymlinks;\u003c/li\u003e\n\u003cli\u003ehard links;\u003c/li\u003e\n\u003cli\u003eACLs;\u003c/li\u003e\n\u003cli\u003eextended attributes;\u003c/li\u003e\n\u003cli\u003epartial transfers;\u003c/li\u003e\n\u003cli\u003edeletions.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eBut it preserves what you ask it to preserve. A casual command and a migration-grade command are not the same thing.\u003c/p\u003e\n\u003ch2 id=\"robocopy-is-similar\"\u003eRobocopy Is Similar\u003ca class=\"heading-anchor\" href=\"#robocopy-is-similar\" aria-label=\"Link to Robocopy Is Similar\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eOn Windows, \u003ccode\u003erobocopy\u003c/code\u003e can be very effective for file tree migration.\u003c/p\u003e\n\u003cp\u003eIt can handle retries, timestamps, attributes, ACLs, and large trees better than casual drag-and-drop. But it also needs careful options and testing.\u003c/p\u003e\n\u003ch2 id=\"cloud-sync-is-not-filesystem-preservation\"\u003eCloud Sync Is Not Filesystem Preservation\u003ca class=\"heading-anchor\" href=\"#cloud-sync-is-not-filesystem-preservation\" aria-label=\"Link to Cloud Sync Is Not Filesystem Preservation\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCloud sync clients are optimized for collaboration and convenience.\u003c/p\u003e\n\u003cp\u003eThey may not preserve:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eall timestamps;\u003c/li\u003e\n\u003cli\u003eall permission semantics;\u003c/li\u003e\n\u003cli\u003elocal owners and groups;\u003c/li\u003e\n\u003cli\u003eextended attributes;\u003c/li\u003e\n\u003cli\u003eresource forks;\u003c/li\u003e\n\u003cli\u003ealternate data streams;\u003c/li\u003e\n\u003cli\u003esymlink behavior;\u003c/li\u003e\n\u003cli\u003eignored temporary files.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eCloud sync is excellent when the cloud service is the system of record. It is weaker when the filesystem identity itself matters.\u003c/p\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eName the job before choosing the tool:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecopy        move visible content\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esync        keep locations aligned\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emigration   move system of record\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebackup      recover from loss\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003earchive     preserve a point-in-time package\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erestore     prove the preservation worked\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe tool choice follows the job.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/copy-sync-migration-tools/","summary":"Copy, Sync, and Migration Tools \u0026ldquo;I copied the file\u0026rdquo; can mean many different things.\nIt might mean the visible bytes arrived. It might mean timestamps survived. It might mean permissions survived. It might mean the file tree behaves exactly the same on the destination.\n","title":"Copy, sync, and migration tools","url":"https://BHDicaire.com/en/blog/files/copy-sync-migration-tools/"},{"content_html":"\u003ch1 id=\"cloud-storage-and-shared-drives\"\u003eCloud Storage and Shared Drives\u003c/h1\u003e\n\u003cp\u003eCloud storage makes files feel locationless. They are not.\u003c/p\u003e\n\u003cp\u003eEvery cloud file still has a name, a path, a sync client, a local representation, a sharing model, and a set of behaviors that differ from a plain local filesystem.\u003c/p\u003e\n\u003ch2 id=\"the-cloud-adds-layers\"\u003eThe Cloud Adds Layers\u003ca class=\"heading-anchor\" href=\"#the-cloud-adds-layers\" aria-label=\"Link to The Cloud Adds Layers\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA synced file can pass through:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ebrowser UI;\u003c/li\u003e\n\u003cli\u003ecloud API;\u003c/li\u003e\n\u003cli\u003elocal sync client;\u003c/li\u003e\n\u003cli\u003elocal filesystem;\u003c/li\u003e\n\u003cli\u003eOffice or desktop app;\u003c/li\u003e\n\u003cli\u003emobile app;\u003c/li\u003e\n\u003cli\u003esharing link;\u003c/li\u003e\n\u003cli\u003earchive download;\u003c/li\u003e\n\u003cli\u003emigration tool.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eEach layer may have its own limits.\u003c/p\u003e\n\u003ch2 id=\"sharepoint-and-onedrive\"\u003eSharePoint and OneDrive\u003ca class=\"heading-anchor\" href=\"#sharepoint-and-onedrive\" aria-label=\"Link to SharePoint and OneDrive\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSharePoint and OneDrive are powerful, but the practical risks usually appear around:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003epath length;\u003c/li\u003e\n\u003cli\u003eorganization sync root names;\u003c/li\u003e\n\u003cli\u003edocument library names;\u003c/li\u003e\n\u003cli\u003eOffice lock files;\u003c/li\u003e\n\u003cli\u003especial characters;\u003c/li\u003e\n\u003cli\u003erenamed folders;\u003c/li\u003e\n\u003cli\u003ebroken shared links;\u003c/li\u003e\n\u003cli\u003elocal sync lag;\u003c/li\u003e\n\u003cli\u003ecoauthoring expectations.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eA path can be technically valid in the web UI and still be annoying locally.\u003c/p\u003e\n\u003ch2 id=\"google-drive\"\u003eGoogle Drive\u003ca class=\"heading-anchor\" href=\"#google-drive\" aria-label=\"Link to Google Drive\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eGoogle Drive has similar practical risks:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003edeep shared-drive structures;\u003c/li\u003e\n\u003cli\u003elocal Drive for desktop behavior;\u003c/li\u003e\n\u003cli\u003eZIP downloads;\u003c/li\u003e\n\u003cli\u003emigration out of Drive;\u003c/li\u003e\n\u003cli\u003efiles created by Google apps;\u003c/li\u003e\n\u003cli\u003elocal file representations;\u003c/li\u003e\n\u003cli\u003epermissions that do not map neatly to filesystem permissions.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eDrive is usually not the fragile part. The fragile part is the path from Drive to everything else.\u003c/p\u003e\n\u003ch2 id=\"shared-drives-are-social-systems\"\u003eShared Drives Are Social Systems\u003ca class=\"heading-anchor\" href=\"#shared-drives-are-social-systems\" aria-label=\"Link to Shared Drives Are Social Systems\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eMost shared drive problems are not caused by a single bad filename.\u003c/p\u003e\n\u003cp\u003eThey come from accumulated decisions:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eseveral teams add folder layers;\u003c/li\u003e\n\u003cli\u003epeople duplicate context in every path;\u003c/li\u003e\n\u003cli\u003eusers create \u0026ldquo;final\u0026rdquo; and \u0026ldquo;archive\u0026rdquo; folders everywhere;\u003c/li\u003e\n\u003cli\u003epermissions are inherited accidentally;\u003c/li\u003e\n\u003cli\u003eold links remain in documents and emails;\u003c/li\u003e\n\u003cli\u003esync clients add conflict files.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eA naming convention helps, but shared drives also need governance.\u003c/p\u003e\n\u003ch2 id=\"practical-folder-budget\"\u003ePractical Folder Budget\u003ca class=\"heading-anchor\" href=\"#practical-folder-budget\" aria-label=\"Link to Practical Folder Budget\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor shared cloud folders, keep a smaller budget than the platform maximum:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder segment: 40 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efull path:      160 characters or fewer when practical\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder depth:   4 to 6 levels maximum\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat leaves room for sync roots, library names, team names, and future folders.\u003c/p\u003e\n\u003ch2 id=\"collaboration-changes-file-meaning\"\u003eCollaboration Changes File Meaning\u003ca class=\"heading-anchor\" href=\"#collaboration-changes-file-meaning\" aria-label=\"Link to Collaboration Changes File Meaning\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eIn collaborative systems, a file can have cloud-specific meaning:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eversion history;\u003c/li\u003e\n\u003cli\u003ecomments;\u003c/li\u003e\n\u003cli\u003esharing permissions;\u003c/li\u003e\n\u003cli\u003elabels;\u003c/li\u003e\n\u003cli\u003eretention policy;\u003c/li\u003e\n\u003cli\u003esensitivity labels;\u003c/li\u003e\n\u003cli\u003ecoauthoring state;\u003c/li\u003e\n\u003cli\u003eapproval workflow;\u003c/li\u003e\n\u003cli\u003elegal hold.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eDownloading the file may preserve the content but not the collaboration context.\u003c/p\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor cloud storage, separate three questions:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCan the file exist here?\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCan the file sync cleanly?\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCan the file leave and still make sense?\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe naming convention is mostly about the third question.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/cloud-storage-shared-drives/","summary":"Cloud Storage and Shared Drives Cloud storage makes files feel locationless. They are not.\nEvery cloud file still has a name, a path, a sync client, a local representation, a sharing model, and a set of behaviors that differ from a plain local filesystem.\n","title":"Cloud storage and shared drives","url":"https://BHDicaire.com/en/blog/files/cloud-storage-shared-drives/"},{"content_html":"\u003ch1 id=\"case-sensitivity-and-unicode\"\u003eCase Sensitivity and Unicode\u003c/h1\u003e\n\u003cp\u003eTwo filenames can look the same to a person and still be different to a computer.\u003c/p\u003e\n\u003cp\u003eTwo filenames can also look different to a person and collide on another system.\u003c/p\u003e\n\u003cp\u003eThat is why portable file naming should be conservative about case and Unicode.\u003c/p\u003e\n\u003ch2 id=\"case-sensitivity\"\u003eCase Sensitivity\u003ca class=\"heading-anchor\" href=\"#case-sensitivity\" aria-label=\"Link to Case Sensitivity\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSome filesystems are case-sensitive:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eReport.pdf\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ereport.pdf\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThose can be two different files.\u003c/p\u003e\n\u003cp\u003eOther filesystems are case-insensitive but case-preserving. They remember the spelling you used, but they treat the names as equivalent for lookup.\u003c/p\u003e\n\u003cp\u003eThat matters when files move between:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eLinux;\u003c/li\u003e\n\u003cli\u003emacOS;\u003c/li\u003e\n\u003cli\u003eWindows;\u003c/li\u003e\n\u003cli\u003eSMB shares;\u003c/li\u003e\n\u003cli\u003eGit repositories;\u003c/li\u003e\n\u003cli\u003eZFS datasets with different settings.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"the-git-problem\"\u003eThe Git Problem\u003ca class=\"heading-anchor\" href=\"#the-git-problem\" aria-label=\"Link to The Git Problem\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eGit can represent paths that differ only by case.\u003c/p\u003e\n\u003cp\u003eBut a developer on a case-insensitive filesystem may not be able to check out or rename those paths cleanly.\u003c/p\u003e\n\u003cp\u003eAvoid:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eREADME.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eReadme.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ereadme.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003ePick one convention and use it everywhere.\u003c/p\u003e\n\u003ch2 id=\"unicode\"\u003eUnicode\u003ca class=\"heading-anchor\" href=\"#unicode\" aria-label=\"Link to Unicode\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUnicode allows filenames in many languages and scripts. That is good.\u003c/p\u003e\n\u003cp\u003eThe portability problem is that Unicode has layers:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ecode points;\u003c/li\u003e\n\u003cli\u003ecomposed characters;\u003c/li\u003e\n\u003cli\u003edecomposed characters;\u003c/li\u003e\n\u003cli\u003enormalization forms;\u003c/li\u003e\n\u003cli\u003ecombining marks;\u003c/li\u003e\n\u003cli\u003eemoji sequences;\u003c/li\u003e\n\u003cli\u003evariation selectors;\u003c/li\u003e\n\u003cli\u003ezero-width joiners.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eA name can look identical while being stored differently.\u003c/p\u003e\n\u003ch2 id=\"accents\"\u003eAccents\u003ca class=\"heading-anchor\" href=\"#accents\" aria-label=\"Link to Accents\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor human-facing documents, accented names may be appropriate.\u003c/p\u003e\n\u003cp\u003eFor long-lived portable infrastructure names, prefer ASCII transliteration:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003equebec-city.pdf\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emontreal-office.csv\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eresume-template.docx\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat is less expressive, but more portable.\u003c/p\u003e\n\u003ch2 id=\"emoji\"\u003eEmoji\u003ca class=\"heading-anchor\" href=\"#emoji\" aria-label=\"Link to Emoji\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eEmoji are especially poor for filenames, folders, and portable passwords.\u003c/p\u003e\n\u003cp\u003eThey can:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003euse multiple code points;\u003c/li\u003e\n\u003cli\u003erender differently across systems;\u003c/li\u003e\n\u003cli\u003econsume more bytes than expected;\u003c/li\u003e\n\u003cli\u003esort unpredictably;\u003c/li\u003e\n\u003cli\u003ebreak older tools;\u003c/li\u003e\n\u003cli\u003ebecome difficult to type during recovery;\u003c/li\u003e\n\u003cli\u003econfuse password entry and copy/paste flows.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eEmoji are fine in chat. They are bad infrastructure.\u003c/p\u003e\n\u003ch2 id=\"urls\"\u003eURLs\u003ca class=\"heading-anchor\" href=\"#urls\" aria-label=\"Link to URLs\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eURLs add another layer.\u003c/p\u003e\n\u003cp\u003eSpaces and non-ASCII characters may be encoded:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003espace          -\u0026gt; %20\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enon-ASCII      -\u0026gt; percent-encoded bytes\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat can make paths longer and harder to debug.\u003c/p\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor files that may move across systems:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003elowercase ASCII\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ea-z 0-9 - _ .\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eno emoji\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eno case-only differences\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor personal files that never leave one environment, use more expressive names if you want. For shared, synced, archived, scripted, or restored files, keep the names boring.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/case-sensitivity-unicode/","summary":"Case Sensitivity and Unicode Two filenames can look the same to a person and still be different to a computer.\nTwo filenames can also look different to a person and collide on another system.\n","title":"Case sensitivity and Unicode","url":"https://BHDicaire.com/en/blog/files/case-sensitivity-unicode/"},{"content_html":"\u003ch1 id=\"blog-series-practical-file-names-permissions-and-portability\"\u003eBlog Series: Practical File Names, Permissions, and Portability\u003c/h1\u003e\n\u003cp\u003eThis series documents a conservative, practical approach to naming, storing, transferring, archiving, and restoring files across macOS, Linux, Windows, GitHub, SharePoint, OneDrive, Google Drive, SMB, NFS, and common archive formats.\u003c/p\u003e\n\u003ch2 id=\"1-a-practical-file-naming-convention-that-sorts-syncs-and-survives\"\u003e1. A Practical File Naming Convention That Sorts, Syncs, and Survives\u003ca class=\"heading-anchor\" href=\"#1-a-practical-file-naming-convention-that-sorts-syncs-and-survives\" aria-label=\"Link to 1. A Practical File Naming Convention That Sorts, Syncs, and Survives\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFocus:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003edate-first filenames;\u003c/li\u003e\n\u003cli\u003esafe characters;\u003c/li\u003e\n\u003cli\u003efilename structure;\u003c/li\u003e\n\u003cli\u003emedium profiles;\u003c/li\u003e\n\u003cli\u003elength budgets;\u003c/li\u003e\n\u003cli\u003eGitHub, SharePoint, OneDrive, Google Drive, macOS, Linux, and NTFS compatibility;\u003c/li\u003e\n\u003cli\u003ewhy emoji are a bad idea in filenames, folder names, and portable passwords.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-til-file-naming-portability-facts\"\u003e2. TIL: File Naming Portability Facts\u003ca class=\"heading-anchor\" href=\"#2-til-file-naming-portability-facts\" aria-label=\"Link to 2. TIL: File Naming Portability Facts\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFocus:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/\"\u003eFile Survival Guide Across Systems\u003c/a\u003e\n;\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/file-naming-portability-facts/\"\u003eFile naming portability facts\u003c/a\u003e\n;\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/portable-filename-rules/\"\u003ePortable filename rules\u003c/a\u003e\n;\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/filesystem-filename-limits/\"\u003eFilesystem filename limits\u003c/a\u003e\n;\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/cloud-git-filename-limits/\"\u003eCloud and Git filename limits\u003c/a\u003e\n;\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/network-transfer-filename-limits/\"\u003eNetwork transfer filename limits\u003c/a\u003e\n;\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/archive-metadata-portability/\"\u003eArchive and metadata portability\u003c/a\u003e\n.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"3-file-and-directory-permissions\"\u003e3. File and Directory Permissions\u003ca class=\"heading-anchor\" href=\"#3-file-and-directory-permissions\" aria-label=\"Link to 3. File and Directory Permissions\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFocus:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ePOSIX mode bits such as \u003ccode\u003e0644\u003c/code\u003e, \u003ccode\u003e0750\u003c/code\u003e, and executable bits;\u003c/li\u003e\n\u003cli\u003eowners and groups;\u003c/li\u003e\n\u003cli\u003enumeric UID and GID;\u003c/li\u003e\n\u003cli\u003edefault permissions and umask;\u003c/li\u003e\n\u003cli\u003ePOSIX ACLs;\u003c/li\u003e\n\u003cli\u003eNTFS ACLs and inheritance;\u003c/li\u003e\n\u003cli\u003emacOS ACLs and extended attributes;\u003c/li\u003e\n\u003cli\u003eLinux extended attributes;\u003c/li\u003e\n\u003cli\u003eSELinux labels;\u003c/li\u003e\n\u003cli\u003efile flags and immutability attributes;\u003c/li\u003e\n\u003cli\u003ewhat survives copy, archive, sync, and restore.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eDraft:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/permissions-ownership-acls/\"\u003eFile and Directory Permissions\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"4-archives-and-metadata\"\u003e4. Archives and Metadata\u003ca class=\"heading-anchor\" href=\"#4-archives-and-metadata\" aria-label=\"Link to 4. Archives and Metadata\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFocus:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eZIP versus TAR versus 7z versus RAR;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.tar.gz\u003c/code\u003e, \u003ccode\u003e.tar.xz\u003c/code\u003e, \u003ccode\u003e.tar.zst\u003c/code\u003e, and \u003ccode\u003e.gz\u003c/code\u003e;\u003c/li\u003e\n\u003cli\u003emacOS resource forks and AppleDouble sidecar files;\u003c/li\u003e\n\u003cli\u003eNTFS alternate data streams;\u003c/li\u003e\n\u003cli\u003esparse files;\u003c/li\u003e\n\u003cli\u003ehard links and symbolic links;\u003c/li\u003e\n\u003cli\u003echoosing archive tools for sharing versus backup.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eDraft:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/archives-and-metadata/\"\u003eArchives and Metadata\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"5-cloud-sync-and-shared-drives\"\u003e5. Cloud Sync and Shared Drives\u003ca class=\"heading-anchor\" href=\"#5-cloud-sync-and-shared-drives\" aria-label=\"Link to 5. Cloud Sync and Shared Drives\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFocus:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eSharePoint and OneDrive;\u003c/li\u003e\n\u003cli\u003eGoogle Drive and Drive for desktop;\u003c/li\u003e\n\u003cli\u003eSMB and NFS shares;\u003c/li\u003e\n\u003cli\u003esync roots and path length;\u003c/li\u003e\n\u003cli\u003econflict files;\u003c/li\u003e\n\u003cli\u003elocal app behavior;\u003c/li\u003e\n\u003cli\u003emigration and restore testing.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eDraft:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/copy-sync-migration-tools/\"\u003eCopy, Sync, and Migration Tools\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/cloud-storage-shared-drives/\"\u003eCloud Storage and Shared Drives\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/backup-restore-reality-check/\"\u003eBackup and Restore Reality Check\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/case-sensitivity-unicode/\"\u003eCase Sensitivity and Unicode\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/git-repository-naming/\"\u003eGit Repository Naming\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/files/files-operational-checklist/\"\u003eFile Survival Operational Checklist\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"site-convention-directory-trees\"\u003eSite Convention: Directory Trees\u003ca class=\"heading-anchor\" href=\"#site-convention-directory-trees\" aria-label=\"Link to Site Convention: Directory Trees\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse the existing Hugo \u003ccode\u003efiletree\u003c/code\u003e shortcode for directory-like examples across the website.\u003c/p\u003e\n\u003cp\u003eUse \u003ccode\u003efiletree\u003c/code\u003e when the article needs:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003estable rendering without client-side JavaScript;\u003c/li\u003e\n\u003cli\u003econsistent styling with the site;\u003c/li\u003e\n\u003cli\u003eaccessible HTML roles;\u003c/li\u003e\n\u003cli\u003efile and folder icons;\u003c/li\u003e\n\u003cli\u003eannotations beside filenames;\u003c/li\u003e\n\u003cli\u003eexamples that should render in feeds, build output, and static HTML.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eUse Mermaid only when the article needs an actual diagram type that the shortcode does not cover, such as flowcharts, sequence diagrams, dependency graphs, or state diagrams.\u003c/p\u003e\n\u003cp\u003eMermaid TreeView is available in Mermaid \u003ccode\u003ev11.14.0+\u003c/code\u003e. The site loads Mermaid \u003ccode\u003e11.16.1\u003c/code\u003e only on pages with \u003ccode\u003emermaid: true\u003c/code\u003e in front matter, so TreeView can be used selectively without adding Mermaid JavaScript to every page.\u003c/p\u003e\n\u003ch2 id=\"series-principle\"\u003eSeries Principle\u003ca class=\"heading-anchor\" href=\"#series-principle\" aria-label=\"Link to Series Principle\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse conservative names by default:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_scope_kind_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse conservative characters:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ea-z 0-9 - _ .\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse conservative path budgets:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efilename:        80 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder segment:  40 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efull path:       160 characters or fewer when practical\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder depth:    4 to 6 levels maximum\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe point is not to use every feature every platform supports. The point is to reduce edge cases when files move.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/series-outline/","summary":"Blog Series: Practical File Names, Permissions, and Portability This series documents a conservative, practical approach to naming, storing, transferring, archiving, and restoring files across macOS, Linux, Windows, GitHub, SharePoint, OneDrive, Google Drive, SMB, NFS, and common archive formats.\n","title":"Blog series: practical file names, permissions, and portability","url":"https://BHDicaire.com/en/blog/files/series-outline/"},{"content_html":"\u003cp\u003eThis page gathers the recurring blog series and connected notes that are easier to read as a set than as isolated posts.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/series/","summary":"This page gathers the recurring blog series and connected notes that are easier to read as a set than as isolated posts.\n","title":"Blog series","url":"https://BHDicaire.com/en/blog/series/"},{"content_html":"\u003ch1 id=\"backup-and-restore-reality-check\"\u003eBackup and Restore Reality Check\u003c/h1\u003e\n\u003cp\u003eA backup is not real until restore works.\u003c/p\u003e\n\u003cp\u003eThat sounds severe, but it is the difference between having comforting files somewhere and having a recovery plan.\u003c/p\u003e\n\u003ch2 id=\"copy-is-not-backup\"\u003eCopy Is Not Backup\u003ca class=\"heading-anchor\" href=\"#copy-is-not-backup\" aria-label=\"Link to Copy Is Not Backup\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA copy is useful, but it is usually just another copy.\u003c/p\u003e\n\u003cp\u003eIt may not protect against:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eaccidental deletion;\u003c/li\u003e\n\u003cli\u003esilent corruption;\u003c/li\u003e\n\u003cli\u003eransomware;\u003c/li\u003e\n\u003cli\u003ebad sync;\u003c/li\u003e\n\u003cli\u003emissing metadata;\u003c/li\u003e\n\u003cli\u003epermission loss;\u003c/li\u003e\n\u003cli\u003eapplication-level inconsistency;\u003c/li\u003e\n\u003cli\u003edisaster at the same site.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"sync-is-not-backup\"\u003eSync Is Not Backup\u003ca class=\"heading-anchor\" href=\"#sync-is-not-backup\" aria-label=\"Link to Sync Is Not Backup\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSync keeps locations aligned.\u003c/p\u003e\n\u003cp\u003eThat is convenient until the wrong thing syncs:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003edeletion;\u003c/li\u003e\n\u003cli\u003eoverwrite;\u003c/li\u003e\n\u003cli\u003erenamed folder;\u003c/li\u003e\n\u003cli\u003eencrypted files;\u003c/li\u003e\n\u003cli\u003ecorrupted files;\u003c/li\u003e\n\u003cli\u003epermission changes.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSync can be part of a backup strategy, but sync alone is not the strategy.\u003c/p\u003e\n\u003ch2 id=\"archive-is-not-backup\"\u003eArchive Is Not Backup\u003ca class=\"heading-anchor\" href=\"#archive-is-not-backup\" aria-label=\"Link to Archive Is Not Backup\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eAn archive captures a package.\u003c/p\u003e\n\u003cp\u003eThat can be useful for:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eprojects;\u003c/li\u003e\n\u003cli\u003eexports;\u003c/li\u003e\n\u003cli\u003elegal records;\u003c/li\u003e\n\u003cli\u003ereleases;\u003c/li\u003e\n\u003cli\u003ehandoffs.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eBut an archive may not include full metadata, version history, permissions, application state, or a tested restore process.\u003c/p\u003e\n\u003ch2 id=\"snapshot-is-not-backup\"\u003eSnapshot Is Not Backup\u003ca class=\"heading-anchor\" href=\"#snapshot-is-not-backup\" aria-label=\"Link to Snapshot Is Not Backup\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSnapshots are excellent for fast rollback.\u003c/p\u003e\n\u003cp\u003eBut snapshots can share fate with the original system. If the disk, storage pool, account, or site is lost, the snapshot may be lost too.\u003c/p\u003e\n\u003cp\u003eSnapshots are strongest when combined with replication or backup outside the failure domain.\u003c/p\u003e\n\u003ch2 id=\"replica-is-not-backup\"\u003eReplica Is Not Backup\u003ca class=\"heading-anchor\" href=\"#replica-is-not-backup\" aria-label=\"Link to Replica Is Not Backup\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA replica is another current copy.\u003c/p\u003e\n\u003cp\u003eIt helps with availability. It may not help with:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eunnoticed corruption;\u003c/li\u003e\n\u003cli\u003eaccidental deletion;\u003c/li\u003e\n\u003cli\u003emalicious changes;\u003c/li\u003e\n\u003cli\u003ebad application state;\u003c/li\u003e\n\u003cli\u003emissing history.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eAvailability and recoverability are related, not identical.\u003c/p\u003e\n\u003ch2 id=\"the-restore-test\"\u003eThe Restore Test\u003ca class=\"heading-anchor\" href=\"#the-restore-test\" aria-label=\"Link to The Restore Test\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA useful restore test answers:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eCan we find the backup?\u003c/li\u003e\n\u003cli\u003eCan we authenticate?\u003c/li\u003e\n\u003cli\u003eCan we restore to a clean location?\u003c/li\u003e\n\u003cli\u003eAre permissions correct?\u003c/li\u003e\n\u003cli\u003eAre owners and groups correct?\u003c/li\u003e\n\u003cli\u003eAre ACLs and xattrs correct?\u003c/li\u003e\n\u003cli\u003eAre symlinks and hard links correct?\u003c/li\u003e\n\u003cli\u003eAre sparse files still sparse?\u003c/li\u003e\n\u003cli\u003eDoes the application work?\u003c/li\u003e\n\u003cli\u003eHow long did it take?\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe test should be written down.\u003c/p\u003e\n\u003ch2 id=\"recovery-objectives\"\u003eRecovery Objectives\u003ca class=\"heading-anchor\" href=\"#recovery-objectives\" aria-label=\"Link to Recovery Objectives\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eTwo useful questions:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eRPO: How much data can we afford to lose?\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eRTO: How long can we afford to be down?\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThose questions shape the backup system.\u003c/p\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse precise words:\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eWord\u003c/th\u003e\n          \u003cth\u003eMeaning\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ecopy\u003c/td\u003e\n          \u003ctd\u003eanother instance of files\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003esync\u003c/td\u003e\n          \u003ctd\u003ealigned state between locations\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003earchive\u003c/td\u003e\n          \u003ctd\u003epackaged point-in-time material\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003esnapshot\u003c/td\u003e\n          \u003ctd\u003epoint-in-time view of a system\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ereplica\u003c/td\u003e\n          \u003ctd\u003eanother live or near-live copy\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ebackup\u003c/td\u003e\n          \u003ctd\u003erecoverable copy outside the immediate failure path\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003erestore\u003c/td\u003e\n          \u003ctd\u003eproof that recovery works\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThe file survived only when the restore proves it.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/backup-restore-reality-check/","summary":"Backup and Restore Reality Check A backup is not real until restore works.\nThat sounds severe, but it is the difference between having comforting files somewhere and having a recovery plan.\n","title":"Backup and restore reality check","url":"https://BHDicaire.com/en/blog/files/backup-restore-reality-check/"},{"content_html":"\u003ch1 id=\"archives-and-metadata\"\u003eArchives and Metadata\u003c/h1\u003e\n\u003cp\u003eAn archive is not automatically a backup.\u003c/p\u003e\n\u003cp\u003eThat sounds fussy until the day a restored script no longer runs, a symlink becomes a regular file, a macOS application loses metadata, or a sparse disk image expands to its full logical size.\u003c/p\u003e\n\u003cp\u003eArchives vary in what they preserve.\u003c/p\u003e\n\u003ch2 id=\"the-big-split\"\u003eThe Big Split\u003ca class=\"heading-anchor\" href=\"#the-big-split\" aria-label=\"Link to The Big Split\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThere are two common archive shapes:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ea \u003cstrong\u003econtainer\u003c/strong\u003e that stores a file tree;\u003c/li\u003e\n\u003cli\u003ea \u003cstrong\u003ecompression stream\u003c/strong\u003e that compresses bytes.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFor example:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e.tar      stores a file tree\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e.zip      stores a file tree\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e.7z       stores a file tree\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e.rar      stores a file tree\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e.gz       compresses one stream\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e.tar.gz   stores a file tree, then compresses it\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat is why \u003ccode\u003e.gz\u003c/code\u003e alone is not the same thing as \u003ccode\u003e.tar.gz\u003c/code\u003e.\u003c/p\u003e\n\u003ch2 id=\"zip\"\u003eZIP\u003ca class=\"heading-anchor\" href=\"#zip\" aria-label=\"Link to ZIP\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eZIP is excellent for broad sharing.\u003c/p\u003e\n\u003cp\u003eIt is widely supported, easy to open, and good for ordinary documents. But ZIP should not be treated as a complete metadata-preserving backup format unless the creating and extracting tools are known to preserve the metadata you care about.\u003c/p\u003e\n\u003cp\u003eZIP metadata behavior varies across tools and platforms.\u003c/p\u003e\n\u003ch2 id=\"tar\"\u003eTAR\u003ca class=\"heading-anchor\" href=\"#tar\" aria-label=\"Link to TAR\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eTAR is a better fit for Unix-like directory trees.\u003c/p\u003e\n\u003cp\u003eIt was designed around file trees, modes, owners, groups, symlinks, and timestamps. With the right options and format choices, it can preserve more of a Unix/Linux tree than ZIP usually does.\u003c/p\u003e\n\u003cp\u003eTAR is often the better default for:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eLinux server backups;\u003c/li\u003e\n\u003cli\u003esource trees with executable bits;\u003c/li\u003e\n\u003cli\u003esymlink-heavy directories;\u003c/li\u003e\n\u003cli\u003eUnix ownership and group preservation;\u003c/li\u003e\n\u003cli\u003econtainer build contexts;\u003c/li\u003e\n\u003cli\u003efilesystem migrations.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"7z-and-rar\"\u003e7z and RAR\u003ca class=\"heading-anchor\" href=\"#7z-and-rar\" aria-label=\"Link to 7z and RAR\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e7z and RAR can be useful, especially for compression and platform-specific workflows.\u003c/p\u003e\n\u003cp\u003eBut for long-term portability, the important question is not \u0026ldquo;can this format compress well?\u0026rdquo; It is:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ewhich tools can extract it correctly in five years?\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor everyday interoperability, ZIP wins. For Unix-like metadata, TAR often wins. For maximum compression, 7z may win. For Windows-specific archive workflows, RAR may be useful.\u003c/p\u003e\n\u003ch2 id=\"macos-metadata\"\u003emacOS Metadata\u003ca class=\"heading-anchor\" href=\"#macos-metadata\" aria-label=\"Link to macOS Metadata\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003emacOS files may carry metadata beyond visible content:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eresource forks;\u003c/li\u003e\n\u003cli\u003eFinder info;\u003c/li\u003e\n\u003cli\u003eextended attributes;\u003c/li\u003e\n\u003cli\u003equarantine flags;\u003c/li\u003e\n\u003cli\u003epackage directory structure;\u003c/li\u003e\n\u003cli\u003eACLs.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSome tools preserve these. Some drop them. Some create \u003ccode\u003e._\u003c/code\u003e AppleDouble sidecar files.\u003c/p\u003e\n\u003cp\u003eThat can be surprising, but it is not random. It means the archive tool is translating macOS metadata into a format that may or may not be understood by the destination.\u003c/p\u003e\n\u003ch2 id=\"windows-metadata\"\u003eWindows Metadata\u003ca class=\"heading-anchor\" href=\"#windows-metadata\" aria-label=\"Link to Windows Metadata\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eWindows files may include:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eNTFS ACLs;\u003c/li\u003e\n\u003cli\u003eowner and group security identifiers;\u003c/li\u003e\n\u003cli\u003ealternate data streams;\u003c/li\u003e\n\u003cli\u003etimestamps;\u003c/li\u003e\n\u003cli\u003eattributes such as hidden or system.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThose details often do not survive naive cross-platform archive and extraction workflows.\u003c/p\u003e\n\u003ch2 id=\"unixlinux-metadata\"\u003eUnix/Linux Metadata\u003ca class=\"heading-anchor\" href=\"#unixlinux-metadata\" aria-label=\"Link to Unix/Linux Metadata\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUnix-like systems may include:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003emode bits;\u003c/li\u003e\n\u003cli\u003eowners and groups;\u003c/li\u003e\n\u003cli\u003enumeric UID/GID;\u003c/li\u003e\n\u003cli\u003ePOSIX ACLs;\u003c/li\u003e\n\u003cli\u003eextended attributes;\u003c/li\u003e\n\u003cli\u003eSELinux labels;\u003c/li\u003e\n\u003cli\u003esymlinks;\u003c/li\u003e\n\u003cli\u003ehard links;\u003c/li\u003e\n\u003cli\u003esparse file layout.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eLosing any of these can change behavior after restore.\u003c/p\u003e\n\u003ch2 id=\"practical-rule\"\u003ePractical Rule\u003ca class=\"heading-anchor\" href=\"#practical-rule\" aria-label=\"Link to Practical Rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse archive formats by intent:\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eIntent\u003c/th\u003e\n          \u003cth\u003eBetter default\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSend ordinary files to people\u003c/td\u003e\n          \u003ctd\u003eZIP\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePreserve Unix/Linux file trees\u003c/td\u003e\n          \u003ctd\u003eTAR with explicit metadata options\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCompress a large archive\u003c/td\u003e\n          \u003ctd\u003eTAR plus gzip, xz, or zstd\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePreserve Windows security metadata\u003c/td\u003e\n          \u003ctd\u003eWindows-aware backup/archive tool\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePreserve macOS metadata\u003c/td\u003e\n          \u003ctd\u003emacOS-aware archive/backup tool\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eLong-term disaster recovery\u003c/td\u003e\n          \u003ctd\u003eBackup system with tested restore\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThe archive is only part of the answer. The restore test is the answer.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/archives-and-metadata/","summary":"Archives and Metadata An archive is not automatically a backup.\nThat sounds fussy until the day a restored script no longer runs, a symlink becomes a regular file, a macOS application loses metadata, or a sparse disk image expands to its full logical size.\n","title":"Archives and metadata","url":"https://BHDicaire.com/en/blog/files/archives-and-metadata/"},{"content_html":"\u003cp\u003eA good file naming convention should be boring in the best possible way.\u003c/p\u003e\n\u003cp\u003eIt should sort correctly. It should be easy to read. It should work on macOS, Linux, Windows/NTFS, GitHub, and SharePoint. It should not break when copied into a terminal, pasted into a URL, synced to cloud storage, or processed by a script six months later.\u003c/p\u003e\n\u003cp\u003eMost filename debates start with word styles: \u003ccode\u003esnake_case\u003c/code\u003e, \u003ccode\u003ekebab-case\u003c/code\u003e, \u003ccode\u003ecamelCase\u003c/code\u003e, \u003ccode\u003ePascalCase\u003c/code\u003e, and their louder cousins. That is useful, but it is only one layer. A reliable convention also needs rules for dates, versions, categories, separators, length, and characters to avoid.\u003c/p\u003e\n\u003cp\u003eThis post compares the common alternatives, then proposes a practical convention for everyday documents, Git repositories, Linux file servers, NTFS volumes, macOS folders, and SharePoint sites.\u003c/p\u003e\n\u003ch2 id=\"the-goal\"\u003eThe Goal\u003ca class=\"heading-anchor\" href=\"#the-goal\" aria-label=\"Link to The Goal\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe ideal filename is:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eChronological\u003c/strong\u003e: date-first names sort naturally.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ePortable\u003c/strong\u003e: the name works across common operating systems and cloud platforms.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eReadable\u003c/strong\u003e: humans can scan it without decoding a private cipher.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eScriptable\u003c/strong\u003e: terminals, URLs, Git, and automation tools do not need special escaping.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eStable\u003c/strong\u003e: the name still makes sense years later.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"the-missing-layer-medium-type\"\u003eThe Missing Layer: Medium Type\u003ca class=\"heading-anchor\" href=\"#the-missing-layer-medium-type\" aria-label=\"Link to The Missing Layer: Medium Type\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA filename convention should define the \u003cstrong\u003ename pattern\u003c/strong\u003e, but it should also define the \u003cstrong\u003emedium type\u003c/strong\u003e: the place where the file is expected to live.\u003c/p\u003e\n\u003cp\u003eThe medium determines the real restrictions:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eallowed characters;\u003c/li\u003e\n\u003cli\u003eblocked names;\u003c/li\u003e\n\u003cli\u003emaximum filename length;\u003c/li\u003e\n\u003cli\u003emaximum folder name length;\u003c/li\u003e\n\u003cli\u003emaximum full path length;\u003c/li\u003e\n\u003cli\u003efolder depth;\u003c/li\u003e\n\u003cli\u003ecase sensitivity;\u003c/li\u003e\n\u003cli\u003esync and URL behavior.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eA name that works on a local Mac might still be annoying in Git, awkward in a terminal, broken in SharePoint sync, or too long for a Windows user opening it from OneDrive.\u003c/p\u003e\n\u003ch2 id=\"medium-profiles\"\u003eMedium Profiles\u003ca class=\"heading-anchor\" href=\"#medium-profiles\" aria-label=\"Link to Medium Profiles\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse profiles to decide how strict the naming rules should be.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eMedium\u003c/th\u003e\n          \u003cth\u003ePractical rule\u003c/th\u003e\n          \u003cth\u003eWhy it matters\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePersonal macOS folder\u003c/td\u003e\n          \u003ctd\u003eSafe characters, filename under 100 characters, shallow folders.\u003c/td\u003e\n          \u003ctd\u003emacOS is flexible, but names may later move to Git, Windows, or SharePoint.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eLinux file server\u003c/td\u003e\n          \u003ctd\u003eSafe characters, lowercase, avoid spaces, filename under 100 characters.\u003c/td\u003e\n          \u003ctd\u003eLinux is case-sensitive, so \u003ccode\u003eReport.pdf\u003c/code\u003e and \u003ccode\u003ereport.pdf\u003c/code\u003e can be different files.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eWindows / NTFS\u003c/td\u003e\n          \u003ctd\u003eSafe characters, avoid reserved Windows names, keep paths short.\u003c/td\u003e\n          \u003ctd\u003eNTFS supports long names, but Windows tools and apps still commonly hit path limits.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eGitHub repo\u003c/td\u003e\n          \u003ctd\u003eLowercase, \u003ccode\u003ekebab-case\u003c/code\u003e for code/docs, avoid case-only differences.\u003c/td\u003e\n          \u003ctd\u003eGit behaves differently across case-sensitive and case-insensitive systems.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSharePoint / OneDrive\u003c/td\u003e\n          \u003ctd\u003eStrict safe characters, filename under 80 characters, full synced path under 160 characters when possible.\u003c/td\u003e\n          \u003ctd\u003eCloud URLs, sync folders, organization names, Office apps, and local OS limits all stack together.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eGoogle Drive\u003c/td\u003e\n          \u003ctd\u003eStrict safe characters, filename under 80 characters, full synced path under 160 characters when possible.\u003c/td\u003e\n          \u003ctd\u003eDrive for desktop still passes through macOS or Windows path behavior, and shared drives can accumulate deep folder structures.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eArchive / cold storage\u003c/td\u003e\n          \u003ctd\u003eInclude enough context in the filename, avoid relying on folder names only.\u003c/td\u003e\n          \u003ctd\u003eArchived files often get moved, flattened, zipped, or restored without their original context.\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThe best default is to use the \u003cstrong\u003estrictest common profile\u003c/strong\u003e unless a folder has a clear reason to be different.\u003c/p\u003e\n\u003ch2 id=\"assumptions-behind-this-recommendation\"\u003eAssumptions Behind This Recommendation\u003ca class=\"heading-anchor\" href=\"#assumptions-behind-this-recommendation\" aria-label=\"Link to Assumptions Behind This Recommendation\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThis convention assumes the file may eventually cross more than one storage boundary:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003elocal macOS folders;\u003c/li\u003e\n\u003cli\u003eLinux filesystems such as ext4, Btrfs, or ZFS;\u003c/li\u003e\n\u003cli\u003eWindows and NTFS;\u003c/li\u003e\n\u003cli\u003eGit and GitHub;\u003c/li\u003e\n\u003cli\u003eSMB or NFS network shares;\u003c/li\u003e\n\u003cli\u003eSharePoint, OneDrive, or Google Drive;\u003c/li\u003e\n\u003cli\u003eZIP, TAR, 7z, RAR, or backup archives;\u003c/li\u003e\n\u003cli\u003emigration, sync, backup, and restore tools.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe recommendation is intentionally stricter than any single platform requires. The goal is not to use every feature each system supports. The goal is to avoid names that become awkward, ambiguous, or broken when files move.\u003c/p\u003e\n\u003cp\u003eFor a facts-only reference, see \u003ca href=\"/en/til/file-naming-portability-facts/\"\u003eFile Naming Portability Facts\u003c/a\u003e\n.\u003c/p\u003e\n\u003ch2 id=\"recommended-medium-budget\"\u003eRecommended Medium Budget\u003ca class=\"heading-anchor\" href=\"#recommended-medium-budget\" aria-label=\"Link to Recommended Medium Budget\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor files that may move between macOS, GitHub, Linux, NTFS, SharePoint, OneDrive, and Google Drive, use this conservative budget:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efilename:        80 characters or fewer, including extension\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder segment:  40 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efull path:       160 characters or fewer when practical\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder depth:    4 to 6 levels maximum\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe \u003ccode\u003e160\u003c/code\u003e character full-path target is intentionally conservative. It is not the maximum supported by most modern systems. It is a working limit designed to reduce edge cases when files move between local disks, cloud sync clients, web links, ZIP files, Git repositories, and Office applications.\u003c/p\u003e\n\u003cp\u003eThose numbers leave room for:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eOneDrive sync roots such as \u003ccode\u003eOneDrive - Organization Name\u003c/code\u003e;\u003c/li\u003e\n\u003cli\u003eGoogle Drive for desktop mount or mirror locations;\u003c/li\u003e\n\u003cli\u003eSharePoint document library names;\u003c/li\u003e\n\u003cli\u003eOffice temporary lock files;\u003c/li\u003e\n\u003cli\u003eZIP extraction folders;\u003c/li\u003e\n\u003cli\u003emigration tools;\u003c/li\u003e\n\u003cli\u003euser-created subfolders;\u003c/li\u003e\n\u003cli\u003efuture renames.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThink of this as a road speed, not an engine limit. Many platforms allow more, but the convention should keep you out of the failure zone. If a path must exceed 160 characters, treat that as a prompt to shorten folder names, flatten the folder structure, or move important context into metadata rather than adding another directory level.\u003c/p\u003e\n\u003ch2 id=\"common-filename-styles\"\u003eCommon Filename Styles\u003ca class=\"heading-anchor\" href=\"#common-filename-styles\" aria-label=\"Link to Common Filename Styles\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eStyle\u003c/th\u003e\n          \u003cth\u003eExample\u003c/th\u003e\n          \u003cth\u003ePros\u003c/th\u003e\n          \u003cth\u003eCons\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003esnake_case\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e20260804_project_notes_v01.md\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eEasy to read, familiar in Python and data work, visually separates words well.\u003c/td\u003e\n          \u003ctd\u003eUnderscores can be less URL-like and are slightly harder to type on mobile keyboards.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ekebab-case\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e20260804-project-notes-v01.md\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eExcellent for URLs, web projects, Markdown files, and command-line use.\u003c/td\u003e\n          \u003ctd\u003eLong filenames can become visually flat because every separator looks the same.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eMixed blocks\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e20260804_project-notes_meeting-summary_v01.md\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eSeparates metadata blocks with underscores while keeping words readable with hyphens.\u003c/td\u003e\n          \u003ctd\u003eRequires a little discipline because two separator types have different meanings.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ecamelCase\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e20260804ProjectNotesV01.md\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eFamiliar to programmers, compact, no separator characters.\u003c/td\u003e\n          \u003ctd\u003eHarder to read quickly, poor for general documents, awkward with acronyms and dates.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ePascalCase\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e20260804ProjectNotesV01.md\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eCommon for classes, components, and some code files.\u003c/td\u003e\n          \u003ctd\u003eBetter for code symbols than documents; not ideal for shared folders.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eTitle Case With Spaces\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e2026 08 04 Project Notes v01.docx\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eVery readable for non-technical users.\u003c/td\u003e\n          \u003ctd\u003eSpaces are annoying in terminals, URLs, scripts, and some automation workflows.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003enocase\u003c/code\u003e / flatcase\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e20260804projectnotesv01.md\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eExtremely simple and package-friendly.\u003c/td\u003e\n          \u003ctd\u003ePoor readability; words blend together.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eSCREAMING_SNAKE_CASE\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e20260804_PROJECT_NOTES_V01.md\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eUseful for constants and environment variables.\u003c/td\u003e\n          \u003ctd\u003eVisually loud and tiring; not good for everyday file names.\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"recommended-style\"\u003eRecommended Style\u003ca class=\"heading-anchor\" href=\"#recommended-style\" aria-label=\"Link to Recommended Style\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse a \u003cstrong\u003edate-first mixed-block convention\u003c/strong\u003e:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_context-name_content-type_description_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_acme-corp_meeting-notes_security-review_v01.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThis uses:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eYYYYMMDD\u003c/code\u003e for date-first sorting.\u003c/li\u003e\n\u003cli\u003eunderscores \u003ccode\u003e_\u003c/code\u003e to separate major metadata blocks.\u003c/li\u003e\n\u003cli\u003ehyphens \u003ccode\u003e-\u003c/code\u003e to separate words inside a block.\u003c/li\u003e\n\u003cli\u003elowercase letters for portability.\u003c/li\u003e\n\u003cli\u003ezero-padded versions like \u003ccode\u003ev01\u003c/code\u003e, \u003ccode\u003ev02\u003c/code\u003e, \u003ccode\u003ev10\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003elowercase file extensions.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"why-yyyymmdd\"\u003eWhy \u003ccode\u003eYYYYMMDD\u003c/code\u003e?\u003ca class=\"heading-anchor\" href=\"#why-yyyymmdd\" aria-label=\"Link to Why YYYYMMDD?\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe date \u003ccode\u003e20260804\u003c/code\u003e is the compact ISO-style date format for August 4, 2026. It sorts perfectly as plain text:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260115\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20261231\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat means your file browser, terminal, GitHub repository, SharePoint folder, and Linux server all agree on the order without relying on fragile file metadata like \u0026ldquo;created date\u0026rdquo; or \u0026ldquo;modified date.\u0026rdquo;\u003c/p\u003e\n\u003cp\u003eThe alternative \u003ccode\u003eYYYY-MM-DD\u003c/code\u003e is also excellent and more readable:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e2026-08-04_project-notes.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eBut if the filename already uses hyphens inside words, \u003ccode\u003eYYYYMMDD\u003c/code\u003e keeps the date compact and reduces separator clutter.\u003c/p\u003e\n\u003ch2 id=\"the-portable-character-rules\"\u003eThe Portable Character Rules\u003ca class=\"heading-anchor\" href=\"#the-portable-character-rules\" aria-label=\"Link to The Portable Character Rules\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor maximum compatibility across macOS, Linux, NTFS, GitHub, and SharePoint:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eUse lowercase \u003ccode\u003ea-z\u003c/code\u003e, numbers \u003ccode\u003e0-9\u003c/code\u003e, hyphen \u003ccode\u003e-\u003c/code\u003e, underscore \u003ccode\u003e_\u003c/code\u003e, and one final dot before the extension.\u003c/li\u003e\n\u003cli\u003eAvoid spaces.\u003c/li\u003e\n\u003cli\u003eAvoid \u003ccode\u003e\\ / : * ? \u0026quot; \u0026lt; \u0026gt; |\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eAvoid \u003ccode\u003e#\u003c/code\u003e, \u003ccode\u003e%\u003c/code\u003e, \u003ccode\u003e\u0026amp;\u003c/code\u003e, \u003ccode\u003e{}\u003c/code\u003e, \u003ccode\u003e$\u003c/code\u003e, \u003ccode\u003e!\u003c/code\u003e, \u003ccode\u003e'\u003c/code\u003e, backticks, and other shell or URL-sensitive characters.\u003c/li\u003e\n\u003cli\u003eAvoid leading or trailing spaces.\u003c/li\u003e\n\u003cli\u003eAvoid trailing dots.\u003c/li\u003e\n\u003cli\u003eAvoid names reserved by Windows, such as \u003ccode\u003eCON\u003c/code\u003e, \u003ccode\u003ePRN\u003c/code\u003e, \u003ccode\u003eAUX\u003c/code\u003e, \u003ccode\u003eNUL\u003c/code\u003e, \u003ccode\u003eCOM1\u003c/code\u003e, and \u003ccode\u003eLPT1\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eKeep filenames reasonably short, ideally under 80 characters for synced/shared files and under 100 characters for local-only files.\u003c/li\u003e\n\u003cli\u003eKeep full paths reasonably short, ideally under 160 characters for SharePoint/OneDrive synced workflows.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe safest character set is:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ea-z 0-9 - _ .\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eAvoid emoji in filenames and folder names. Emoji may render differently across systems, use multiple Unicode code points, increase byte length, break older tools, sort unpredictably, and become awkward in terminals, URLs, archives, cloud sync clients, and migration tools.\u003c/p\u003e\n\u003cp\u003eAlso avoid emoji in passwords unless a specific password system explicitly supports them and you have tested sign-in, recovery, mobile entry, password managers, and copy/paste behavior. Long random ASCII passphrases are usually safer and more reliable than passwords containing visually ambiguous Unicode characters or emoji.\u003c/p\u003e\n\u003ch2 id=\"a-practical-blog-series\"\u003eA Practical Blog Series\u003ca class=\"heading-anchor\" href=\"#a-practical-blog-series\" aria-label=\"Link to A Practical Blog Series\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThis topic is bigger than one article. A useful series could look like this:\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eArticle\u003c/th\u003e\n          \u003cth\u003eFocus\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFile Naming Convention\u003c/td\u003e\n          \u003ctd\u003ePortable names, date-first sorting, safe characters, medium profiles, and versioning.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFile Naming Portability Facts\u003c/td\u003e\n          \u003ctd\u003eFacts about filesystems, network shares, Unicode, archives, and metadata loss.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFile and Directory Permissions\u003c/td\u003e\n          \u003ctd\u003ePOSIX permissions, owners, groups, ACLs, extended attributes, SELinux labels, and practical transfer/backup implications.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eArchives and Metadata\u003c/td\u003e\n          \u003ctd\u003eZIP, TAR, 7z, RAR, resource forks, NTFS streams, xattrs, sparse files, symlinks, and what each tool preserves.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCloud Sync and Shared Drives\u003c/td\u003e\n          \u003ctd\u003eSharePoint, OneDrive, Google Drive, SMB/NFS-backed shares, sync conflicts, path length, and migration behavior.\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThe naming convention article should stay focused on names. Permissions, ownership, ACLs, extended attributes, and SELinux labels deserve their own article because they define who can read, write, execute, inherit, audit, or restore a file after it moves.\u003c/p\u003e\n\u003ch2 id=\"the-convention\"\u003eThe Convention\u003ca class=\"heading-anchor\" href=\"#the-convention\" aria-label=\"Link to The Convention\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse this general pattern:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_scope_kind_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eWhere:\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eBlock\u003c/th\u003e\n          \u003cth\u003eMeaning\u003c/th\u003e\n          \u003cth\u003eExample\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eYYYYMMDD\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eDate of the document, event, export, or snapshot.\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e20260804\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003escope\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eProject, client, repo, system, team, or area.\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003eacme-corp\u003c/code\u003e, \u003ccode\u003ehome-lab\u003c/code\u003e, \u003ccode\u003esharepoint-migration\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ekind\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eType of file.\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003emeeting-notes\u003c/code\u003e, \u003ccode\u003erunbook\u003c/code\u003e, \u003ccode\u003ediagram\u003c/code\u003e, \u003ccode\u003einvoice\u003c/code\u003e, \u003ccode\u003eexport\u003c/code\u003e, \u003ccode\u003ereport\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003esubject\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eSpecific topic or detail.\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003esecurity-review\u003c/code\u003e, \u003ccode\u003eq3-budget\u003c/code\u003e, \u003ccode\u003evpn-access\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ev##\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eVersion when needed.\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003ev01\u003c/code\u003e, \u003ccode\u003ev02\u003c/code\u003e, \u003ccode\u003ev10\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e.ext\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eLowercase extension.\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e.md\u003c/code\u003e, \u003ccode\u003e.pdf\u003c/code\u003e, \u003ccode\u003e.docx\u003c/code\u003e, \u003ccode\u003e.xlsx\u003c/code\u003e, \u003ccode\u003e.png\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eExamples:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_home-lab_runbook_proxmox-backup_v01.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_acme-corp_meeting-notes_security-review_v01.docx\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_github_repo-readme_file-naming_v02.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_sharepoint_export_policy-library_v01.csv\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_linux-server_diagram_backup-network_v01.png\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"when-to-omit-blocks\"\u003eWhen to Omit Blocks\u003ca class=\"heading-anchor\" href=\"#when-to-omit-blocks\" aria-label=\"Link to When to Omit Blocks\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eNot every file needs every block. A short filename is better than a perfect but exhausting one.\u003c/p\u003e\n\u003cp\u003eUse this shorter form for simple personal files:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_file-naming_v01.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse this form for recurring notes:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_scope_notes_subject.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_infosec_notes_file-naming.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse this form for exports and snapshots:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_system_export_dataset_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_sharepoint_export_documents-inventory_v01.csv\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"versioning-rules\"\u003eVersioning Rules\u003ca class=\"heading-anchor\" href=\"#versioning-rules\" aria-label=\"Link to Versioning Rules\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse \u003ccode\u003ev01\u003c/code\u003e, \u003ccode\u003ev02\u003c/code\u003e, \u003ccode\u003ev03\u003c/code\u003e for meaningful revisions.\u003c/p\u003e\n\u003cp\u003eDo not use:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efinal\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efinal-final\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enew\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eold\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003elatest\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ereally-final\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThose words feel useful in the moment, but they decay quickly. The clean rule is: the highest version number is the latest named version.\u003c/p\u003e\n\u003cp\u003eGood:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_acme-corp_report_security-assessment_v01.pdf\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260805_acme-corp_report_security-assessment_v02.pdf\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260807_acme-corp_report_security-assessment_v03.pdf\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eIf the date changes because the file is a new issued version, update the date. If the file is just a minor working edit on the same day, increment the version.\u003c/p\u003e\n\u003ch2 id=\"dates-created-updated-or-event-date\"\u003eDates: Created, Updated, or Event Date?\u003ca class=\"heading-anchor\" href=\"#dates-created-updated-or-event-date\" aria-label=\"Link to Dates: Created, Updated, or Event Date?\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003ePick the date that best describes why the file exists:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eMeeting notes: meeting date.\u003c/li\u003e\n\u003cli\u003eInvoice: invoice date.\u003c/li\u003e\n\u003cli\u003eReport: publication or delivery date.\u003c/li\u003e\n\u003cli\u003eExport: export date.\u003c/li\u003e\n\u003cli\u003eBackup: backup date.\u003c/li\u003e\n\u003cli\u003ePhoto/video: capture date, if known.\u003c/li\u003e\n\u003cli\u003eDraft document: creation date or major revision date.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe key is consistency inside each folder or workflow.\u003c/p\u003e\n\u003ch2 id=\"github-repositories\"\u003eGitHub Repositories\u003ca class=\"heading-anchor\" href=\"#github-repositories\" aria-label=\"Link to GitHub Repositories\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor GitHub repos, use lowercase \u003ccode\u003ekebab-case\u003c/code\u003e for most source files and directories:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efile-naming.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebackup-restore-runbook.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esharepoint-migration-checklist.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse date-first names when the files are chronological artifacts:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_release-notes_v01.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_incident-report_auth-timeout_v01.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_export_dependency-audit_v01.json\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eAvoid filenames that differ only by case:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eReadme.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eREADME.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat can behave differently across macOS, Windows, Linux, and Git.\u003c/p\u003e\n\u003ch2 id=\"sharepoint-and-onedrive\"\u003eSharePoint and OneDrive\u003ca class=\"heading-anchor\" href=\"#sharepoint-and-onedrive\" aria-label=\"Link to SharePoint and OneDrive\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSharePoint is friendlier than it used to be, but conservative filenames still prevent sync problems and broken links. Microsoft currently documents a 400-character decoded path limit for OneDrive and SharePoint in Microsoft 365, with additional sync and desktop-app limits depending on the local machine, Office app, and sync root length.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/p\u003e\n\u003cp\u003eFor SharePoint:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eavoid special characters even if the current interface allows some of them;\u003c/li\u003e\n\u003cli\u003eavoid very deep folder nesting;\u003c/li\u003e\n\u003cli\u003ekeep filenames short enough to leave room for the full path;\u003c/li\u003e\n\u003cli\u003etarget 160 characters or fewer for the synced full path when you control the structure;\u003c/li\u003e\n\u003cli\u003eavoid renaming shared files casually because links and sync clients may lag behind.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eGood SharePoint examples:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_hr_policy_remote-work_v03.docx\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_finance_report_q3-forecast_v01.xlsx\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_it_inventory_laptops-vancouver_v01.csv\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"google-drive\"\u003eGoogle Drive\u003ca class=\"heading-anchor\" href=\"#google-drive\" aria-label=\"Link to Google Drive\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eGoogle Drive can store almost any file type, and Google Workspace currently documents large storage/upload limits.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e The naming risk is usually not Drive itself. The risk appears when files are mirrored or streamed through \u003cstrong\u003eDrive for desktop\u003c/strong\u003e, opened through local apps, downloaded into ZIP files, moved to another platform, or migrated into SharePoint, GitHub, Linux, or Windows storage.\u003c/p\u003e\n\u003cp\u003eFor Google Drive:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003euse the same safe character set as the rest of the convention;\u003c/li\u003e\n\u003cli\u003eavoid deep nesting even though Drive supports deeply nested folders;\u003c/li\u003e\n\u003cli\u003ekeep shared drive structures flatter than personal folders;\u003c/li\u003e\n\u003cli\u003euse \u003ccode\u003eYYYYMMDD\u003c/code\u003e in exported reports, meeting notes, snapshots, and archived documents;\u003c/li\u003e\n\u003cli\u003eavoid relying on Drive-only metadata if the file may later be downloaded or migrated.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eGood Google Drive examples:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_ops_meeting-notes_weekly-sync_v01.docx\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_marketing_export_campaign-assets_v01.zip\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_finance_report_budget-review_v02.xlsx\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"linux-filesystems-ext4-btrfs-and-zfs\"\u003eLinux Filesystems: ext4, Btrfs, and ZFS\u003ca class=\"heading-anchor\" href=\"#linux-filesystems-ext4-btrfs-and-zfs\" aria-label=\"Link to Linux Filesystems: ext4, Btrfs, and ZFS\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor ordinary filenames, ext4, Btrfs, and ZFS do not change the recommendation. They mostly reinforce it.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eFilesystem\u003c/th\u003e\n          \u003cth\u003ePractical impact\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eext4\u003c/td\u003e\n          \u003ctd\u003eCommon Linux default. Filenames are limited by bytes, not human-visible characters. A 255-byte filename is not the same as 255 accented or non-Latin characters.\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eBtrfs\u003c/td\u003e\n          \u003ctd\u003eSimilar practical filename behavior for this convention; Btrfs documents a 255-byte filename limit.\u003csup id=\"fnref1:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eZFS\u003c/td\u003e\n          \u003ctd\u003eAdds important dataset-level settings for case sensitivity, UTF-8 enforcement, and Unicode normalization. Those settings can affect whether two visually similar names compare as the same name.\u003csup id=\"fnref:4\"\u003e\u003ca href=\"#fn:4\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e4\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eFor a portable convention, assume:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003efilename components may be limited to 255 bytes or characters depending on the layer;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/\u003c/code\u003e separates directories and cannot be part of a filename;\u003c/li\u003e\n\u003cli\u003ethe NUL byte cannot be part of a filename;\u003c/li\u003e\n\u003cli\u003ecase sensitivity may differ between systems;\u003c/li\u003e\n\u003cli\u003eUnicode normalization may differ between systems.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe recommendation stays the same:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003euse lowercase ASCII names with a-z, 0-9, hyphen, underscore, and dot\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat avoids the most common cross-filesystem problems.\u003c/p\u003e\n\u003ch2 id=\"character-encoding-and-utf-8\"\u003eCharacter Encoding and UTF-8\u003ca class=\"heading-anchor\" href=\"#character-encoding-and-utf-8\" aria-label=\"Link to Character Encoding and UTF-8\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eModern systems commonly support Unicode, and UTF-8 is the best default assumption for interchange. That does not mean every filename that displays correctly on one system will compare, sort, sync, or extract correctly on another.\u003c/p\u003e\n\u003cp\u003eThe hard parts are:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003ebytes vs characters\u003c/strong\u003e: Linux-style filesystems often care about byte length, while humans count visible characters;\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003enormalization\u003c/strong\u003e: the same visible character can have more than one Unicode representation;\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecase folding\u003c/strong\u003e: uppercase/lowercase behavior differs by filesystem, locale, and protocol;\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003elegacy tools\u003c/strong\u003e: older ZIP tools, scripts, and backup systems may mishandle non-ASCII names;\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eURLs\u003c/strong\u003e: non-ASCII characters and spaces may be encoded, increasing path length.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFor maximum portability, prefer ASCII filenames:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eresume.pdf        safer than resume-with-accents-or-symbols.pdf\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003equebec-city.pdf   safer than québec-city.pdf\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThis is not a rule against using real names or non-English text when needed. It is a rule for files that must survive migrations, scripts, Git, cloud sync, Linux servers, Windows clients, archives, and web links.\u003c/p\u003e\n\u003ch2 id=\"network-transfers-smb-nfs-and-friends\"\u003eNetwork Transfers: SMB, NFS, and Friends\u003ca class=\"heading-anchor\" href=\"#network-transfers-smb-nfs-and-friends\" aria-label=\"Link to Network Transfers: SMB, NFS, and Friends\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eNetwork protocols add another translation layer between the client, server, and underlying filesystem.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eTransfer method\u003c/th\u003e\n          \u003cth\u003ePractical impact\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSMB / CIFS\u003c/td\u003e\n          \u003ctd\u003eCommon for Windows shares, NAS devices, and macOS/Windows interoperability. Expect Windows-like character restrictions, case-preserving but often case-insensitive behavior, and path-length surprises from UNC paths.\u003csup id=\"fnref:5\"\u003e\u003ca href=\"#fn:5\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e5\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eNFS\u003c/td\u003e\n          \u003ctd\u003eCommon for Unix/Linux servers. NFSv4 generally uses UTF-8 for strings, but servers and exported filesystems can vary in how strictly they enforce encoding and normalization.\u003csup id=\"fnref1:5\"\u003e\u003ca href=\"#fn:5\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e5\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSFTP / SCP\u003c/td\u003e\n          \u003ctd\u003eUsually preserves file content reliably, but metadata preservation depends on the client, server, and options used.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ersync\u003c/td\u003e\n          \u003ctd\u003eExcellent for migrations and backups when configured correctly. Use options intentionally if you need ownership, groups, permissions, ACLs, extended attributes, hard links, or timestamps.\u003csup id=\"fnref:6\"\u003e\u003ca href=\"#fn:6\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e6\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eWebDAV\u003c/td\u003e\n          \u003ctd\u003eUsed behind some document and cloud workflows. File and folder names become URL path segments, so escaping and path length matter.\u003csup id=\"fnref:7\"\u003e\u003ca href=\"#fn:7\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e7\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCloud sync clients\u003c/td\u003e\n          \u003ctd\u003eOneDrive, Google Drive for desktop, Dropbox-style tools, and NAS sync tools add their own local path roots, conflict naming, ignored files, and metadata behavior.\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThe transfer rule is simple:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ethe safe name is the name that survives the strictest client, server, filesystem, and protocol in the chain\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat is another reason the \u003ccode\u003e160\u003c/code\u003e character full-path target is intentionally conservative.\u003c/p\u003e\n\u003ch2 id=\"archives-zip-rar-7z-tar-and-gzip\"\u003eArchives: ZIP, RAR, 7z, TAR, and Gzip\u003ca class=\"heading-anchor\" href=\"#archives-zip-rar-7z-tar-and-gzip\" aria-label=\"Link to Archives: ZIP, RAR, 7z, TAR, and Gzip\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eArchives are not all equivalent. Some are file bundles. Some are compression streams. Some preserve metadata well. Some preserve only the visible file contents and basic names.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eFormat\u003c/th\u003e\n          \u003cth\u003ePractical impact\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e.zip\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eBest for broad sharing. Good for ordinary documents. Metadata preservation varies by tool, especially permissions, extended attributes, resource forks, and non-ASCII names.\u003csup id=\"fnref:8\"\u003e\u003ca href=\"#fn:8\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e8\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e.rar\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eCan preserve some Windows-specific metadata when created with the right options, including NTFS streams and security data. Less universal than ZIP.\u003csup id=\"fnref1:8\"\u003e\u003ca href=\"#fn:8\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e8\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e.7z\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eStrong compression and Unicode-friendly in modern tools, but metadata behavior varies by platform and extraction tool.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e.tar\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eBest fit for Unix/Linux trees because it is designed to store directory structures and Unix metadata. Use POSIX pax options when preserving extended metadata matters.\u003csup id=\"fnref2:8\"\u003e\u003ca href=\"#fn:8\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e8\u003c/a\u003e\u003c/sup\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e.tar.gz\u003c/code\u003e, \u003ccode\u003e.tgz\u003c/code\u003e, \u003ccode\u003e.tar.xz\u003c/code\u003e, \u003ccode\u003e.tar.zst\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eA tar archive compressed by another algorithm. The tar layer stores the file tree; the compression layer only compresses the tar stream.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e.gz\u003c/code\u003e alone\u003c/td\u003e\n          \u003ctd\u003eUsually compresses one file stream, not a directory tree. Use \u003ccode\u003etar.gz\u003c/code\u003e when archiving folders.\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eFor ordinary cross-platform sharing:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ezip is convenient, but do not treat it as a perfect backup format\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor Linux/Unix backup or migration:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etar with explicit owner, permission, ACL, xattr, and sparse-file options is usually more appropriate\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor Windows backup or migration:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echoose a tool that explicitly preserves NTFS ACLs, owners, groups, alternate data streams, and timestamps\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor macOS backup or migration:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echoose a tool that explicitly preserves resource forks, Finder info, extended attributes, ACLs, and package directories\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"metadata-that-filenames-do-not-capture\"\u003eMetadata That Filenames Do Not Capture\u003ca class=\"heading-anchor\" href=\"#metadata-that-filenames-do-not-capture\" aria-label=\"Link to Metadata That Filenames Do Not Capture\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA filename is only one part of a file. Moving or archiving a file may lose or change metadata.\u003c/p\u003e\n\u003cp\u003eCommon metadata includes:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003emodified, created, and accessed timestamps;\u003c/li\u003e\n\u003cli\u003eowner and group names;\u003c/li\u003e\n\u003cli\u003enumeric UID and GID;\u003c/li\u003e\n\u003cli\u003ePOSIX mode bits such as \u003ccode\u003e0644\u003c/code\u003e or \u003ccode\u003e0750\u003c/code\u003e;\u003c/li\u003e\n\u003cli\u003ePOSIX ACLs;\u003c/li\u003e\n\u003cli\u003eNTFS ACLs and security descriptors;\u003c/li\u003e\n\u003cli\u003eNTFS alternate data streams;\u003c/li\u003e\n\u003cli\u003emacOS resource forks;\u003c/li\u003e\n\u003cli\u003emacOS Finder info;\u003c/li\u003e\n\u003cli\u003emacOS extended attributes such as quarantine flags;\u003c/li\u003e\n\u003cli\u003eLinux extended attributes;\u003c/li\u003e\n\u003cli\u003eSELinux labels;\u003c/li\u003e\n\u003cli\u003ehard links and symbolic links;\u003c/li\u003e\n\u003cli\u003esparse file layout;\u003c/li\u003e\n\u003cli\u003efile flags and immutability attributes.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThis matters because two files can have the same name and visible content but behave differently after transfer.\u003c/p\u003e\n\u003cp\u003eExamples:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eA script may lose execute permission.\u003c/li\u003e\n\u003cli\u003eA restored file may belong to the wrong UID/GID.\u003c/li\u003e\n\u003cli\u003eA macOS app or package may lose extended attributes.\u003c/li\u003e\n\u003cli\u003eA Windows file may lose an alternate data stream.\u003c/li\u003e\n\u003cli\u003eA sparse VM disk image may expand to its full logical size.\u003c/li\u003e\n\u003cli\u003eA symlink may be restored as a regular file, or a regular file may be restored where a symlink was expected.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe naming convention cannot solve those problems. It can only avoid making them worse. Backup, archive, and transfer tools must be selected and tested for the metadata you actually need.\u003c/p\u003e\n\u003ch2 id=\"folder-names\"\u003eFolder Names\u003ca class=\"heading-anchor\" href=\"#folder-names\" aria-label=\"Link to Folder Names\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse the same rules for folders:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e2026\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e2026-08\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_security-review\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eclient-acme-corp\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eproject-sharepoint-migration\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFor numbered folders, use leading zeros:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e01_inbox\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e02_working\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e03_review\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e04_published\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e99_archive\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"final-recommendation\"\u003eFinal Recommendation\u003ca class=\"heading-anchor\" href=\"#final-recommendation\" aria-label=\"Link to Final Recommendation\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse this as the default:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_scope_kind_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse this for simple files:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse this safe character set:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003elowercase letters, numbers, hyphens, underscores, and one extension dot\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_infosec_blog-file-naming_v01.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse this medium budget:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e80 characters per filename\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e40 characters per folder segment\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e160 characters per full synced path\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e4 to 6 folder levels\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eIt is compact, readable, sortable, scriptable, Git-friendly, SharePoint-safe, Google-Drive-safe, Linux-safe, macOS-safe, NTFS-safe, SMB-friendly, NFS-friendly, and archive-friendly.\u003c/p\u003e\n\u003cp\u003eThat is the sweet spot: boring enough for computers, clear enough for humans, and structured enough that your future self can find the file without muttering at your past self.\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eMicrosoft Support, \u003ca href=\"https://support.microsoft.com/en-US/onedrive/restrictions-and-limitations-in-onedrive-and-sharepoint\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRestrictions and limitations in OneDrive and SharePoint\u003c/a\u003e\n and \u003ca href=\"https://support.microsoft.com/en-us/onedrive/what-are-file-path-length-limits\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWhat are the file path length limits?\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eGoogle Drive Help, \u003ca href=\"https://support.google.com/drive/answer/37603\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFiles you can store in Google Drive\u003c/a\u003e\n, and Google Workspace Help, \u003ca href=\"https://knowledge.workspace.google.com/admin/drive/storage-and-upload-limits-for-google-workspace\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStorage and upload limits for Google Workspace\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:3\"\u003e\n\u003cp\u003eLinux Kernel Documentation, \u003ca href=\"https://www.kernel.org/doc/html/latest/filesystems/ext4/directory.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eext4 Directory Entries\u003c/a\u003e\n, and Btrfs Documentation, \u003ca href=\"https://btrfs.readthedocs.io/en/latest/ch-fs-limits.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFilesystem Limits\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u0026#160;\u003ca href=\"#fnref1:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:4\"\u003e\n\u003cp\u003eOpenZFS, \u003ca href=\"https://openzfs.github.io/openzfs-docs/man/master/7/zfsprops.7.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eZFS Properties\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:4\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:5\"\u003e\n\u003cp\u003eMicrosoft Learn, \u003ca href=\"https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/09c2ccc8-4aaf-439f-9b4e-13b3fe85a4cf\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCIFS File and Directory Names\u003c/a\u003e\n, and RFC Editor, \u003ca href=\"https://www.rfc-editor.org/info/rfc7530/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eNFS Version 4 Protocol\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:5\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u0026#160;\u003ca href=\"#fnref1:5\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:6\"\u003e\n\u003cp\u003ersync, \u003ca href=\"https://rsync.samba.org/ftp/rsync/rsync.1.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ersync Manpage\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:6\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:7\"\u003e\n\u003cp\u003eRFC Editor, \u003ca href=\"https://www.rfc-editor.org/info/rfc4918/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWebDAV\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:7\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:8\"\u003e\n\u003cp\u003ePKWARE, \u003ca href=\"https://support.pkware.com/pkzip/appnote\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eZIP Application Note\u003c/a\u003e\n; GNU, \u003ca href=\"https://www.gnu.org/software/tar/manual/tar.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGNU tar Manual\u003c/a\u003e\n; WinRAR Documentation, \u003ca href=\"https://documentation.help/WinRAR/HELPGetArcAdvanced.htm\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAdvanced Archive Options\u003c/a\u003e\n.\u0026#160;\u003ca href=\"#fnref:8\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u0026#160;\u003ca href=\"#fnref1:8\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u0026#160;\u003ca href=\"#fnref2:8\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/file-naming/","summary":"A good file naming convention should be boring in the best possible way.\nIt should sort correctly. It should be easy to read. It should work on macOS, Linux, Windows/NTFS, GitHub, and SharePoint. It should not break when copied into a terminal, pasted into a URL, synced to cloud storage, or processed by a script six months later.\n","title":"A practical file naming convention that sorts, syncs, and survives","url":"https://BHDicaire.com/en/blog/files/file-naming/"},{"content_html":"\u003cp\u003eWelcome to the antidote for boring infrastructure. If your current naming convention looks like a cat walked across your keyboard while holding down the caps lock key, you are in the right place.\u003c/p\u003e\n\u003cp\u003eSystem conventions are great until you have to scream a server name over a frantic incident call. \u003ccode\u003eprod-app-server-04b\u003c/code\u003e just doesn\u0026rsquo;t have the same urgency—or charm—as \u003ccode\u003eElvis\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eWhile we aren\u0026rsquo;t supposed to treat our infrastructure like pets anymore, certain machines just demand an actual identity. Whether it’s a lab box, a dedicated NAS, or a bastion host that refuses to die, some components deserve a name that doesn\u0026rsquo;t feel like a serial number.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/themes/introduction/","summary":"Welcome to the antidote for boring infrastructure. If your current naming convention looks like a cat walked across your keyboard while holding down the caps lock key, you are in the right place.\n","title":"Introduction","url":"https://BHDicaire.com/en/blog/themes/introduction/"},{"content_html":"\u003cp\u003eThis is my slashes page where you can find all of my \u003ca href=\"https://slashpages.net/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eslash pages.\u003c/a\u003e\n\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003ePage\u003c/th\u003e\n          \u003cth\u003eDescription\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/blog/blogroll/\"\u003e/blogroll\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eA list of other sites I currently follow and recommend\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/blog/colophon/\"\u003e/colophon\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eThe technology and techniques I used to build this website\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/contact/\"\u003e/contact\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eA page with a contact form which you can use to reach me\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/blog/feeds/\"\u003e/feeds\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eThe available RSS feeds you can subscribe to to follow my work\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/legal/\"\u003e/legal\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eOfficial information about this website, its owner, contact routes, and disclosures\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/legal/license/\"\u003e/license\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eA page which clarifies how the content on this site is licenced\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/blog/now/\"\u003e/now\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eWhat I’m choosing to focus my attention on right now\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/legal/privacy/\"\u003e/privacy\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eHow I’m respecting the privacy of visitors to my website\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/resources/books/\"\u003e/reading\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eThe books I’ve read since 2018\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/sitemap/\"\u003e/sitemap\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eA human-readable index of the main pages on this site\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/blog/slashes/\"\u003e/slashes\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eA page that lists all my slash pages (how meta)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/support\"\u003e/support\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eWays in which you can support my work (should you wish to)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/resources/projects/\"\u003e/projects\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eProjects from the past or that I’m currently working on\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/testimonials\"\u003e/testimonials\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eThe kind words my clients have said about working with me\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/then/\"\u003e/then\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eAn archive of previous Now page snapshots\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"/en/blog/uses/\"\u003e/uses\u003c/a\u003e\n\u003c/td\u003e\n          \u003ctd\u003eRedirects to \u003ca href=\"/en/blog/uses/\"\u003e/en/blog/uses/\u003c/a\u003e\n, my office setup and the app and services I use day to day\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eLearn more about my thoughts on slash pages and /slashes.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/slashes/introduction/","summary":"This is my slashes page where you can find all of my slash pages. Page Description /blogroll A list of other sites I currently follow and recommend /colophon The technology and techniques I used to build this website /contact A page with a contact form which you can use to reach me /feeds The available RSS feeds you can subscribe to to follow my work /legal Official information about this website, its owner, contact routes, and disclosures /license A page which clarifies how the content on this site is licenced /now What I’m choosing to focus my attention on right now /privacy How I’m respecting the privacy of visitors to my website /reading The books I’ve read since 2018 /sitemap A human-readable index of the main pages on this site /slashes A page that lists all my slash pages (how meta) /support Ways in which you can support my work (should you wish to) /projects Projects from the past or that I’m currently working on /testimonials The kind words my clients have said about working with me /then An archive of previous Now page snapshots /uses Redirects to /en/blog/uses/ , my office setup and the app and services I use day to day Learn more about my thoughts on slash pages and /slashes.\n","title":"Introduction","url":"https://BHDicaire.com/en/blog/slashes/introduction/"},{"content_html":"\u003cp\u003eNaming is a design decision, not decoration. The useful question is not whether a name is clever. It is whether the name helps people and automation understand what something is, how replaceable it is, and how much attention it deserves.\u003c/p\u003e\n\u003cp\u003eMost modern infrastructure should be treated like cattle: replaceable, patterned, documented, and generated from clear attributes such as environment, region, role, owner, and sequence. Those names are not glamorous, but they are searchable, automatable, and hard to misread at scale.\u003c/p\u003e\n\u003cp\u003ePet-style names still have a place, but it is narrower: long-lived machines, personal workstations, lab systems, bastions, storage boxes, and other devices where humans repeatedly interact with the same individual system. In those cases, a memorable name can reduce friction, as long as it stays short, pronounceable, and operationally boring enough not to cause trouble.\u003c/p\u003e\n\u003cp\u003eThis collection covers naming conventions for devices from four angles: structured cattle-style patterns, curated themes for pet-style hostnames, privacy-aware names that deliberately blend into the background, and architecture patterns that help names describe system intent.\u003c/p\u003e\n\u003ch2 id=\"suggested-structure\"\u003eSuggested structure\u003ca class=\"heading-anchor\" href=\"#suggested-structure\" aria-label=\"Link to Suggested structure\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eStart with cattle-style names for fleets and automated infrastructure. Use pet-style names only when the system is durable enough that people truly benefit from recognizing it. Use boring default-looking names when privacy or camouflage matters more than personality. Keep architectural names for diagrams, documentation, and service boundaries where the name explains the role.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/naming/introduction/","summary":"Naming is a design decision, not decoration. The useful question is not whether a name is clever. It is whether the name helps people and automation understand what something is, how replaceable it is, and how much attention it deserves.\n","title":"Introduction","url":"https://BHDicaire.com/en/blog/naming/introduction/"},{"content_html":"\u003cp\u003eIncident response is easier when the first decisions are already written down. This collection gathers practical notes for reporting vulnerabilities, finding incidents teams, and keeping jurisdiction-specific contact sheets close to the runbook.\u003c/p\u003e\n\u003cp\u003eStart with the workflow, then keep the contact sheets nearby:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/incident-reporting/\"\u003eHow to report a security vulnerability\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/incident-response-teams/\"\u003eIncident response team directories\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/incident-response-canada/\"\u003eCanada cyber incident contact sheet\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/incident-response-usa/\"\u003eUnited States cyber incident contact sheet\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/incidents/introduction/","summary":"Incident response is easier when the first decisions are already written down. This collection gathers practical notes for reporting vulnerabilities, finding incidents teams, and keeping jurisdiction-specific contact sheets close to the runbook.\n","title":"Introduction","url":"https://BHDicaire.com/en/blog/incidents/introduction/"},{"content_html":"\u003cp\u003eFiles look simple until they move.\u003c/p\u003e\n\u003cp\u003eA file that behaves perfectly on a Mac can become awkward on Windows. A filename that syncs through Google Drive can still be painful in a terminal. A directory tree that works on Linux can lose meaning when copied to SharePoint. A ZIP file can preserve the visible document while quietly dropping permissions, owners, resource forks, extended attributes, alternate data streams, or other metadata that made the original file behave the way it did.\u003c/p\u003e\n\u003cp\u003eThis series is about files that survive the trip.\u003c/p\u003e\n\u003cp\u003eNot just files that copy. Not just files that open. Files that keep enough of their name, path, content, permissions, metadata, and context to remain useful after they move between systems.\u003c/p\u003e\n\u003ch2 id=\"why-this-series-exists\"\u003eWhy this series exists\u003ca class=\"heading-anchor\" href=\"#why-this-series-exists\" aria-label=\"Link to Why this series exists\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eMost file advice stops at simple rules:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003edo not use weird characters;\u003c/li\u003e\n\u003cli\u003eavoid spaces;\u003c/li\u003e\n\u003cli\u003ekeep names short;\u003c/li\u003e\n\u003cli\u003emake backups.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThose rules are useful, but incomplete.\u003c/p\u003e\n\u003cp\u003eThe real world is messier. Files move across:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003emacOS;\u003c/li\u003e\n\u003cli\u003eLinux;\u003c/li\u003e\n\u003cli\u003eWindows and NTFS;\u003c/li\u003e\n\u003cli\u003eext4, Btrfs, and ZFS;\u003c/li\u003e\n\u003cli\u003eGit and GitHub;\u003c/li\u003e\n\u003cli\u003eSMB and NFS shares;\u003c/li\u003e\n\u003cli\u003eSharePoint and OneDrive;\u003c/li\u003e\n\u003cli\u003eGoogle Drive;\u003c/li\u003e\n\u003cli\u003eZIP, TAR, 7z, and RAR archives;\u003c/li\u003e\n\u003cli\u003ebackup, sync, migration, and restore tools.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eEach layer has its own assumptions about names, paths, character encoding, permissions, ownership, metadata, and conflict handling.\u003c/p\u003e\n\u003cp\u003eThe goal of this series is to make those assumptions visible.\u003c/p\u003e\n\u003ch2 id=\"the-core-principle\"\u003eThe core principle\u003ca class=\"heading-anchor\" href=\"#the-core-principle\" aria-label=\"Link to The core principle\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUse conservative defaults for files that may move.\u003c/p\u003e\n\u003cp\u003eThat does not mean every system is fragile. Modern systems can often handle long names, Unicode, deep paths, rich metadata, ACLs, extended attributes, and complex directory trees.\u003c/p\u003e\n\u003cp\u003eThe problem is not one system. The problem is the chain.\u003c/p\u003e\n\u003cp\u003eA file may pass through a local filesystem, a sync client, a network share, a browser download, an archive tool, a migration utility, an Office app, a backup job, and a restore process. The safe choice is the one that survives the strictest link in that chain.\u003c/p\u003e\n\u003ch2 id=\"the-starting-recommendation\"\u003eThe starting recommendation\u003ca class=\"heading-anchor\" href=\"#the-starting-recommendation\" aria-label=\"Link to The starting recommendation\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor portable filenames, this series starts with:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eYYYYMMDD_scope_kind_subject_v##.ext\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e20260804_infosec_runbook_backup-restore_v01.md\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse a conservative character set:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ea-z 0-9 - _ .\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eUse a conservative path budget:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efilename:        80 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder segment:  40 characters or fewer\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efull path:       160 characters or fewer when practical\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efolder depth:    4 to 6 levels maximum\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat \u003ccode\u003e160\u003c/code\u003e character full-path target is intentionally conservative. It is not the maximum most systems support. It is a practical working limit meant to reduce edge cases when files pass through cloud sync, web links, Office apps, ZIP files, Git repositories, network shares, and mixed operating systems.\u003c/p\u003e\n\u003ch2 id=\"emoji-are-not-portable-infrastructure\"\u003eEmoji are not portable infrastructure\u003ca class=\"heading-anchor\" href=\"#emoji-are-not-portable-infrastructure\" aria-label=\"Link to Emoji are not portable infrastructure\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eEmoji are great in chat. They are a bad default for filenames, folder names, and portable passwords.\u003c/p\u003e\n\u003cp\u003eEmoji can use multiple Unicode code points, render differently across platforms, consume more bytes than expected, sort unpredictably, and fail in older tools, scripts, archives, URLs, sync clients, and password-entry flows.\u003c/p\u003e\n\u003cp\u003eFor files that need to survive across systems, boring ASCII wins.\u003c/p\u003e\n\u003ch2 id=\"what-this-series-will-cover\"\u003eWhat this series will cover\u003ca class=\"heading-anchor\" href=\"#what-this-series-will-cover\" aria-label=\"Link to What this series will cover\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"filetree not-prose\" role=\"tree\" aria-label=\"File tree\"\u003e\u003cul class=\"filetree-root\"\u003e\n\u003cli class=\"filetree-item\" role=\"treeitem\" aria-expanded=\"true\"\u003e\n\u003cdiv class=\"filetree-row filetree-folder-row\"\u003e\u003csvg class=\"filetree-icon filetree-folder-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M5 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1M5 19h14a2 2 0 002-2v-5a2 2 0 00-2-2H9a2 2 0 00-2 2v5a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name filetree-folder-name\"\u003econtent/\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eseries map\u003c/span\u003e\u003c/div\u003e\u003cul class=\"filetree-children\" role=\"group\"\u003e\n\u003cli class=\"filetree-item\" role=\"treeitem\" aria-expanded=\"true\"\u003e\n\u003cdiv class=\"filetree-row filetree-folder-row\"\u003e\u003csvg class=\"filetree-icon filetree-folder-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M5 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1M5 19h14a2 2 0 002-2v-5a2 2 0 00-2-2H9a2 2 0 00-2 2v5a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name filetree-folder-name\"\u003eblog/files/\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003enarrative series\u003c/span\u003e\u003c/div\u003e\u003cul class=\"filetree-children\" role=\"group\"\u003e\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003e_index.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eseries overview\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003efile-naming.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eportable naming rules\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003epermissions-ownership-acls.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003epermissions and ownership\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003earchives-and-metadata.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003earchive behavior\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003ecopy-sync-migration-tools.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003emovement tools\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003ecloud-storage-shared-drives.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003ecloud collaboration\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003ebackup-restore-reality-check.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003erecovery proof\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003ecase-sensitivity-unicode.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003ecase and character handling\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003egit-repository-naming.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eGit naming rules\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003efiles-operational-checklist.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eoperational checklist\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003eseries-outline.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eworking map\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003c/ul\u003e\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\" aria-expanded=\"true\"\u003e\n\u003cdiv class=\"filetree-row filetree-folder-row\"\u003e\u003csvg class=\"filetree-icon filetree-folder-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M5 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1M5 19h14a2 2 0 002-2v-5a2 2 0 00-2-2H9a2 2 0 00-2 2v5a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name filetree-folder-name\"\u003etil/\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eshort facts\u003c/span\u003e\u003c/div\u003e\u003cul class=\"filetree-children\" role=\"group\"\u003e\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003efile-naming-portability-facts.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003efacts index\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003eportable-filename-rules.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003echaracters and patterns\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003efilesystem-filename-limits.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003emacOS, Windows, Linux, ZFS\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003ecloud-git-filename-limits.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eGit, SharePoint, OneDrive, Google Drive\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003enetwork-transfer-filename-limits.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eSMB, NFS, rsync, WebDAV\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003cli class=\"filetree-item\" role=\"treeitem\"\u003e\n\u003cdiv class=\"filetree-row filetree-file-row\"\u003e\n\u003csvg class=\"filetree-icon filetree-file-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z\"/\u003e\u003c/svg\u003e\u003cspan class=\"filetree-name\"\u003earchive-metadata-portability.en.md\u003c/span\u003e\u003cspan class=\"filetree-annotation\"\u003eZIP, TAR, metadata\u003c/span\u003e\u003c/div\u003e\n\u003c/li\u003e\n\n\u003c/ul\u003e\u003c/li\u003e\n\n\u003c/ul\u003e\u003c/li\u003e\n\n\u003c/ul\u003e\u003c/div\u003e\n\n\u003ch3 id=\"1-file-naming-convention\"\u003e1. File naming convention\u003ca class=\"heading-anchor\" href=\"#1-file-naming-convention\" aria-label=\"Link to 1. File naming convention\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eHow to create filenames that sort well, read well, and survive macOS, Linux, Windows, GitHub, SharePoint, OneDrive, Google Drive, SMB, NFS, and archives.\u003c/p\u003e\n\u003ch3 id=\"2-file-naming-portability-facts\"\u003e2. File naming portability facts\u003ca class=\"heading-anchor\" href=\"#2-file-naming-portability-facts\" aria-label=\"Link to 2. File naming portability facts\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eA set of shorter facts-only references for filename rules, filesystem limits, cloud and Git behavior, network transfer limits, archive formats, and metadata risks:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/en/til/file-naming-portability-facts/\"\u003eFile naming portability facts\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/portable-filename-rules/\"\u003ePortable filename rules\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/filesystem-filename-limits/\"\u003eFilesystem filename limits\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/cloud-git-filename-limits/\"\u003eCloud and Git filename limits\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/network-transfer-filename-limits/\"\u003eNetwork transfer filename limits\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/til/archive-metadata-portability/\"\u003eArchive and metadata portability\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"3-file-and-directory-permissions\"\u003e3. File and directory permissions\u003ca class=\"heading-anchor\" href=\"#3-file-and-directory-permissions\" aria-label=\"Link to 3. File and directory permissions\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003ePOSIX mode bits, owners, groups, UID/GID, umask, ACLs, inheritance, extended attributes, SELinux labels, NTFS security descriptors, and macOS metadata.\u003c/p\u003e\n\u003ch3 id=\"4-archives-and-metadata\"\u003e4. Archives and metadata\u003ca class=\"heading-anchor\" href=\"#4-archives-and-metadata\" aria-label=\"Link to 4. Archives and metadata\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eWhat ZIP, TAR, 7z, RAR, gzip, and related tools preserve or drop, including resource forks, alternate data streams, symlinks, hard links, sparse files, and permissions.\u003c/p\u003e\n\u003ch3 id=\"5-copy-sync-and-migration-tools\"\u003e5. Copy, sync, and migration tools\u003ca class=\"heading-anchor\" href=\"#5-copy-sync-and-migration-tools\" aria-label=\"Link to 5. Copy, sync, and migration tools\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eWhy \u003ccode\u003ecp\u003c/code\u003e, Finder, Windows Explorer, \u003ccode\u003ersync\u003c/code\u003e, \u003ccode\u003erobocopy\u003c/code\u003e, SFTP, SCP, SMB, NFS, OneDrive, Google Drive, and SharePoint do not all preserve the same file identity.\u003c/p\u003e\n\u003ch3 id=\"6-cloud-storage-and-shared-drives\"\u003e6. Cloud storage and shared drives\u003ca class=\"heading-anchor\" href=\"#6-cloud-storage-and-shared-drives\" aria-label=\"Link to 6. Cloud storage and shared drives\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003ePath limits, sync roots, shared drives, conflict files, coauthoring, lock files, and migration behavior in SharePoint, OneDrive, Google Drive, and network-backed storage.\u003c/p\u003e\n\u003ch3 id=\"7-backup-and-restore-reality-check\"\u003e7. Backup and restore reality check\u003ca class=\"heading-anchor\" href=\"#7-backup-and-restore-reality-check\" aria-label=\"Link to 7. Backup and restore reality check\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe difference between copy, sync, archive, backup, snapshot, replica, and tested restore.\u003c/p\u003e\n\u003ch3 id=\"8-case-sensitivity-and-unicode\"\u003e8. Case sensitivity and Unicode\u003ca class=\"heading-anchor\" href=\"#8-case-sensitivity-and-unicode\" aria-label=\"Link to 8. Case sensitivity and Unicode\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eCase-sensitive versus case-insensitive filesystems, Unicode normalization, UTF-8, accented characters, emoji, URL encoding, and why visually identical names may not be identical.\u003c/p\u003e\n\u003ch3 id=\"9-git-repository-naming\"\u003e9. Git repository naming\u003ca class=\"heading-anchor\" href=\"#9-git-repository-naming\" aria-label=\"Link to 9. Git repository naming\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eRepository names, branch names, file paths, case-only rename problems, generated files, documentation assets, and long-lived conventions.\u003c/p\u003e\n\u003ch3 id=\"10-operational-checklist\"\u003e10. Operational checklist\u003ca class=\"heading-anchor\" href=\"#10-operational-checklist\" aria-label=\"Link to 10. Operational checklist\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eA practical checklist for moving, syncing, archiving, backing up, and restoring files without losing the details that matter.\u003c/p\u003e\n\u003ch2 id=\"a-living-guide\"\u003eA living guide\u003ca class=\"heading-anchor\" href=\"#a-living-guide\" aria-label=\"Link to A living guide\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThis introduction is a starting point, not the final map.\u003c/p\u003e\n\u003cp\u003eAs the series develops, the shape may change. Some articles may split. Some may merge. The checklist will improve as the examples become sharper.\u003c/p\u003e\n\u003cp\u003eThe goal will stay the same: make files easier to name, move, preserve, and restore across systems with fewer surprises.\u003c/p\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/files/introduction/","summary":"Files look simple until they move.\nA file that behaves perfectly on a Mac can become awkward on Windows. A filename that syncs through Google Drive can still be painful in a terminal. A directory tree that works on Linux can lose meaning when copied to SharePoint. A ZIP file can preserve the visible document while quietly dropping permissions, owners, resource forks, extended attributes, alternate data streams, or other metadata that made the original file behave the way it did.\n","title":"Introduction","url":"https://BHDicaire.com/en/blog/files/introduction/"},{"content_html":"\u003cp\u003eCloudflare is part publishing platform, part security control plane, and part edge runtime. This collection gathers notes on operating that shared surface carefully: rules, Workers, deployment configuration, and the places where product defaults become security decisions.\u003c/p\u003e\n\u003cp\u003eStart with the published domain-level controls:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/cf/cloudflare-domain-protection/\"\u003eCloudflare protection is shared state\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/en/blog/cf/cloudflare-rule-inventory/\"\u003eA Cloudflare rule inventory\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-08-08T00:00:00Z","date_published":"2026-08-08T00:00:00Z","id":"https://BHDicaire.com/en/blog/cf/introduction/","summary":"Cloudflare is part publishing platform, part security control plane, and part edge runtime. This collection gathers notes on operating that shared surface carefully: rules, Workers, deployment configuration, and the places where product defaults become security decisions.\n","title":"Introduction","url":"https://BHDicaire.com/en/blog/cf/introduction/"},{"content_html":"","date_modified":"2026-08-07T00:00:00Z","date_published":"2026-08-07T00:00:00Z","id":"https://BHDicaire.com/en/blog/mindmaps/smtp-tls-reporting/","summary":"","title":"SMTP TLS reporting (TLS-RPT)","url":"https://BHDicaire.com/en/blog/mindmaps/smtp-tls-reporting/"},{"content_html":"","date_modified":"2026-08-07T00:00:00Z","date_published":"2026-08-07T00:00:00Z","id":"https://BHDicaire.com/en/blog/mindmaps/microsoft-ur-ls/","summary":"","title":"Azure \u0026 Microsoft 365 URLs","url":"https://BHDicaire.com/en/blog/mindmaps/microsoft-ur-ls/"},{"content_html":"\u003cp\u003eI liked the shape of thoughtbot\u0026rsquo;s \u003ca href=\"https://thoughtbot.com/blog/copy-as-markdown-ai-friendly-blog-posts\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCopy as Markdown\u003c/a\u003e\n button: a small reader-facing control that copies the canonical article in Markdown instead of forcing someone to paste rendered HTML into a prompt.\u003c/p\u003e\n\u003cp\u003eThat is a good fit for this site because the source of truth is already Markdown. Blog posts and TIL notes should be easy to read in a browser, but they should also be easy to hand to an assistant, quote in a working note, or archive as plain text.\u003c/p\u003e\n\u003cp\u003eThe implementation has three parts.\u003c/p\u003e\n\u003cp\u003eFirst, Hugo now renders a Markdown output for regular pages:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003emediaTypes\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003etext/markdown\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003esuffixes\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      - \u003cspan style=\"color:#ae81ff\"\u003emd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eoutputFormats\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eMarkdown\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003emediaType\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003etext/markdown\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003erel\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ealternate\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003eisPlainText\u003c/span\u003e: \u003cspan style=\"color:#66d9ef\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003enotAlternative\u003c/span\u003e: \u003cspan style=\"color:#66d9ef\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eoutputs\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003epage\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    - \u003cspan style=\"color:#ae81ff\"\u003eHTML\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    - \u003cspan style=\"color:#ae81ff\"\u003eMarkdown\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe Markdown template emits a small front matter block and then the page\u0026rsquo;s raw Markdown content:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-go-html-template\" data-lang=\"go-html-template\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e---\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etitle: \u003cspan style=\"color:#75715e\"\u003e{{\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003e.Title\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ejsonify\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e}}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edate: \u003cspan style=\"color:#75715e\"\u003e{{\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003e.Date.Format\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;2006-01-02\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ejsonify\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e}}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecanonical: \u003cspan style=\"color:#75715e\"\u003e{{\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003e.Permalink\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ejsonify\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e}}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e---\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e{{\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003e.RawContent\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e}}\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eSecond, blog posts and TIL notes include a \u003ccode\u003eCopy as Markdown\u003c/code\u003e button that points at the generated Markdown output. Hugo gives the button the real output URL, so the JavaScript does not need to guess whether the Markdown lives at \u003ccode\u003epost.md\u003c/code\u003e or \u003ccode\u003epost/index.md\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThird, the page head advertises the alternate representation:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026lt;\u003cspan style=\"color:#f92672\"\u003elink\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003erel\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;alternate\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003etype\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;text/markdown\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ehref\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;...\u0026#34;\u003c/span\u003e /\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe button itself fetches that Markdown URL, copies the response to the clipboard, and briefly swaps the label to \u003ccode\u003eCopied\u003c/code\u003e. It reuses the same clipboard helper as code block copying, so there is only one fallback path for older browsers.\u003c/p\u003e\n\u003cp\u003eThis is one of those small web features I like: no account, no API, no special integration. Just a durable plain-text version of the page and a button for readers who want the Markdown directly.\u003c/p\u003e\n","date_modified":"2026-08-06T00:00:00Z","date_published":"2026-08-06T00:00:00Z","id":"https://BHDicaire.com/en/blog/copy-as-markdown/","summary":"I liked the shape of thoughtbot\u0026rsquo;s Copy as Markdown button: a small reader-facing control that copies the canonical article in Markdown instead of forcing someone to paste rendered HTML into a prompt.\n","title":"Copy as Markdown","url":"https://BHDicaire.com/en/blog/copy-as-markdown/"},{"content_html":"","date_modified":"2026-08-01T00:00:00Z","date_published":"2026-08-01T00:00:00Z","id":"https://BHDicaire.com/en/blog/mindmaps/email-formulas/","summary":"","title":"Email formulas when you’re stuck","url":"https://BHDicaire.com/en/blog/mindmaps/email-formulas/"},{"content_html":"\u003cp\u003e\u003ca href=\"https://tld-list.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eTLD List\u003c/a\u003e\n checks a name across every top-level domain at once and compares registrar prices, so availability and cost land in one place.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.expireddomains.net/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eExpiredDomains.net\u003c/a\u003e\n tracks dropped domain availability.\u003c/p\u003e\n\u003ch2 id=\"registrars\"\u003eRegistrars\u003ca class=\"heading-anchor\" href=\"#registrars\" aria-label=\"Link to Registrars\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eRetail\u003c/strong\u003e\nReputable registrars offer free WHOIS privacy and avoid deceptive upsell tactics.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.cloudflare.com/en-ca/products/registrar/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCloudflare\u003c/a\u003e\n: At-cost pricing with no markup that requires using Cloudflare for DNS\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.hover.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHover\u003c/a\u003e\n: Canadian-based organisation owned by \u003ca href=\"https://www.tucows.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eTucows\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://porkbun.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ePorkbun\u003c/a\u003e\n: Tons of TLDs and low prices\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eCorporate\u003c/strong\u003e\nUnlike registrars built for individual consumers, these specialized providers defend trademarks at scale for large corporations and multinational brands.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://comlaude.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCom Laude\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.cscdbs.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCSC\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.markmonitor.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eMarkMonitor\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eMarketplace\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.atom.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAtom\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://sedo.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eSedo\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"independent-escrow-providers\"\u003eIndependent escrow providers\u003ca class=\"heading-anchor\" href=\"#independent-escrow-providers\" aria-label=\"Link to Independent escrow providers\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eMost domain marketplaces include a built-in escrow process. Specialized domain escrow services focus on holding funds and verifying the technical transfer of the domain for high-value or complex legal deals.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://escrow.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eEscrow.com\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://safefunds.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eSafeFunds\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://uniscrow.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eUniscrow\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-07-29T00:00:00Z","date_published":"2012-05-10T00:00:00Z","id":"https://BHDicaire.com/en/til/finding-available-domain-name/","summary":"TLD List checks a name across every top-level domain at once and compares registrar prices, so availability and cost land in one place.\n","title":"Finding an available domain name","url":"https://BHDicaire.com/en/til/finding-available-domain-name/"},{"content_html":"\u003cp\u003eI recently watched someone spend an afternoon trying to register what looked like the perfect domain name. The search ended the same way most of them do: every sensible extension was taken, the \u003ccode\u003e.com\u003c/code\u003e was parked, and the only obvious next step was to make an offer.\u003c/p\u003e\n\u003cp\u003eThat is usually the point where people discover that registering a domain and buying one are two different problems.\u003c/p\u003e\n\u003cp\u003eThe important distinction is simple. Finding an available name is largely a search problem. Acquiring an existing one is a negotiation problem. Understanding which problem you are solving saves time and avoids unrealistic expectations.\u003c/p\u003e\n\u003ch2 id=\"start-by-understanding-why-the-domain-exists\"\u003eStart by understanding why the domain exists\u003ca class=\"heading-anchor\" href=\"#start-by-understanding-why-the-domain-exists\" aria-label=\"Link to Start by understanding why the domain exists\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA registered domain usually falls into one of a handful of categories.\u003c/p\u003e\n\u003ch3 id=\"active-use\"\u003eActive use\u003ca class=\"heading-anchor\" href=\"#active-use\" aria-label=\"Link to Active use\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe domain hosts a website, email, APIs, or other production services. It is part of someone\u0026rsquo;s infrastructure.\u003c/p\u003e\n\u003cp\u003eThese domains are technically available for purchase if the owner is willing to sell. In practice, replacing a domain embedded across an organization\u0026rsquo;s infrastructure is expensive. Most owners simply decline.\u003c/p\u003e\n\u003ch3 id=\"parked\"\u003eParked\u003ca class=\"heading-anchor\" href=\"#parked\" aria-label=\"Link to Parked\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe domain resolves to a registrar parking page, advertisements, or a generic \u0026ldquo;Make an Offer\u0026rdquo; page.\u003c/p\u003e\n\u003cp\u003eThis does not necessarily mean the owner wants to sell. It only means the domain is not currently being used for an active service.\u003c/p\u003e\n\u003ch3 id=\"held-for-resale\"\u003eHeld for resale\u003ca class=\"heading-anchor\" href=\"#held-for-resale\" aria-label=\"Link to Held for resale\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eSome domains are acquired specifically as investments.\u003c/p\u003e\n\u003cp\u003eThe owner expects appreciation and prices accordingly. Negotiation is normal.\u003c/p\u003e\n\u003ch3 id=\"defensive-registration\"\u003eDefensive registration\u003ca class=\"heading-anchor\" href=\"#defensive-registration\" aria-label=\"Link to Defensive registration\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eMany organizations register trademark variants they never intend to use.\u003c/p\u003e\n\u003cp\u003eThis is standard brand-protection practice and these domains are rarely for sale.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e If the brand is no longer strategic, negotiations become possible, but you should expect to make it worth their while.\u003c/p\u003e\n\u003ch3 id=\"expired\"\u003eExpired\u003ca class=\"heading-anchor\" href=\"#expired\" aria-label=\"Link to Expired\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eNot every unavailable domain stays unavailable. Refer to \u003ca href=\"/en/til/finding-available-domain-name/\"\u003efinding an available domain name\u003c/a\u003e\n for more information.\u003c/p\u003e\n\u003cp\u003eDomains typically move through expiration, a redemption period, pending deletion, and eventually become available again or are sold through an auction, depending on the registry and registrar.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u003c/p\u003e\n\u003cp\u003ePatience occasionally beats negotiation.\u003c/p\u003e\n\u003ch2 id=\"search-broadly-before-negotiating\"\u003eSearch broadly before negotiating\u003ca class=\"heading-anchor\" href=\"#search-broadly-before-negotiating\" aria-label=\"Link to Search broadly before negotiating\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eBefore deciding that your preferred name is unavailable, check every relevant top-level domain.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://tld-list.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eTLD List\u003c/a\u003e\n provides a useful view across hundreds of TLDs while comparing registrar prices. Availability and cost appear in one place.\u003c/p\u003e\n\u003cp\u003eChoosing a different extension is often cheaper than purchasing a premium domain. It is also frequently the better long-term decision.\u003c/p\u003e\n\u003ch2 id=\"buying-an-existing-domain\"\u003eBuying an existing domain\u003ca class=\"heading-anchor\" href=\"#buying-an-existing-domain\" aria-label=\"Link to Buying an existing domain\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThere are three practical approaches.\u003c/p\u003e\n\u003ch3 id=\"contact-the-owner\"\u003eContact the owner\u003ca class=\"heading-anchor\" href=\"#contact-the-owner\" aria-label=\"Link to Contact the owner\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eIf the domain hosts a website, start with the contact page. A contact form or published email address is usually more effective than registration records.\u003c/p\u003e\n\u003cp\u003eThe official \u003ca href=\"https://lookup.icann.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eICANN Registration Data Lookup Service\u003c/a\u003e\n is still worth checking, but privacy regulations and registrar redaction mean it often contains little or no registrant information. The service is the successor to the traditional WHOIS service. WHOIS itself has not disappeared, but modern registration data is now provided through the Registration Data Directory Service (RDDS).\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e\u003c/p\u003e\n\u003cp\u003eIf the site belongs to a business in Germany, Austria, or Switzerland, the \u003cem\u003eImpressum\u003c/em\u003e frequently contains contact information for the operator.\u003c/p\u003e\n\u003ch3 id=\"use-a-marketplace\"\u003eUse a marketplace\u003ca class=\"heading-anchor\" href=\"#use-a-marketplace\" aria-label=\"Link to Use a marketplace\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eMany domains are already listed for sale.\u003c/p\u003e\n\u003cp\u003eMarketplaces simplify negotiation, transfer, and payment. These platforms generally integrate payment protection into the transaction workflow.\u003c/p\u003e\n\u003ch3 id=\"hire-a-broker\"\u003eHire a broker\u003ca class=\"heading-anchor\" href=\"#hire-a-broker\" aria-label=\"Link to Hire a broker\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eFor high-value acquisitions, anonymity has value.\u003c/p\u003e\n\u003cp\u003eA broker negotiates without revealing the buyer, manages expectations on both sides, and coordinates the transfer. This is generally worthwhile only when the domain itself justifies the additional cost.\u003c/p\u003e\n\u003ch2 id=\"use-escrow-when-appropriate\"\u003eUse escrow when appropriate\u003ca class=\"heading-anchor\" href=\"#use-escrow-when-appropriate\" aria-label=\"Link to Use escrow when appropriate\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe financial transaction and the technical transfer should be treated as separate events.\u003c/p\u003e\n\u003cp\u003eMost domain marketplaces include an escrow process as part of the transaction.\u003c/p\u003e\n\u003cp\u003eIndependent escrow providers focus exclusively on holding funds until ownership has been transferred successfully. They are primarily useful for high-value purchases, complex legal transactions, or deals negotiated outside established marketplaces.\u003c/p\u003e\n\u003ch2 id=\"choose-a-registrar-for-reliability\"\u003eChoose a registrar for reliability\u003ca class=\"heading-anchor\" href=\"#choose-a-registrar-for-reliability\" aria-label=\"Link to Choose a registrar for reliability\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eRegistrar selection is not only about price.\u003c/p\u003e\n\u003cp\u003eOperational stability, DNS capabilities, transfer policies, support quality, and jurisdiction all matter once a domain becomes production infrastructure.\u003c/p\u003e\n\u003cp\u003eAs of July 2026:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.hover.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHover\u003c/a\u003e\n remains my preferred registrar. It operates under Canadian law and is owned by \u003ca href=\"https://www.tucows.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eTucows\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.cloudflare.com/products/registrar/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCloudflare Registrar\u003c/a\u003e\n sells domains at cost if Cloudflare hosts the authoritative DNS\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://porkbun.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ePorkbun\u003c/a\u003e\n features a wide variety of generic and niche TLD options and remains competitively priced\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eOrganizations managing large trademark portfolios typically use specialist providers such as \u003ca href=\"https://comlaude.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCom Laude\u003c/a\u003e\n, \u003ca href=\"https://www.markmonitor.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eMarkMonitor\u003c/a\u003e\n, or \u003ca href=\"https://www.cscdbs.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCSC Digital Brand Services\u003c/a\u003e\n rather than retail registrars.\u003c/p\u003e\n\u003ch2 id=\"the-tradeoff\"\u003eThe tradeoff\u003ca class=\"heading-anchor\" href=\"#the-tradeoff\" aria-label=\"Link to The tradeoff\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003ePaying a premium for the exact name is not always the best decision.\u003c/p\u003e\n\u003cp\u003eA memorable brand on a slightly less fashionable extension often outperforms an expensive acquisition that consumes budget better spent elsewhere.\u003c/p\u003e\n\u003cp\u003eThe domain is only one part of the identity. It is rarely the limiting factor.\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eICANN Trademark Clearinghouse (TMCH): \u003ca href=\"https://www.icann.org/resources/pages/tmch-requirements-2014-01-09-en\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://www.icann.org/resources/pages/tmch-requirements-2014-01-09-en\u003c/a\u003e\n\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003e\u003ca href=\"https://www.icann.org/resources/pages/errp-2013-02-28-en\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eICANN Expired Registration Recovery Policy (ERRP)\u003c/a\u003e\n and \u003ca href=\"https://www.icann.org/resources/pages/gtld-lifecycle-2012-02-25-en\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGeneric Top-Level Domain Lifecycle\u003c/a\u003e\n\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:3\"\u003e\n\u003cp\u003e\u003ca href=\"https://lookup.icann.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eICANN Registration Data Lookup Service\u003c/a\u003e\n, \u003ca href=\"https://www.icann.org/resources/pages/rdds-2018-05-22-en\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRegistration Data Directory Service (RDDS)\u003c/a\u003e\n, and Country-code top-level domains (ccTLDs) may provide their own registration lookup service and follow different disclosure rules.\u0026#160;\u003ca href=\"#fnref:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-07-29T00:00:00Z","date_published":"2015-07-29T00:00:00Z","id":"https://BHDicaire.com/en/blog/domain-name/","summary":"I recently watched someone spend an afternoon trying to register what looked like the perfect domain name. The search ended the same way most of them do: every sensible extension was taken, the .com was parked, and the only obvious next step was to make an offer.\n","title":"Registering a domain Name is the easy part","url":"https://BHDicaire.com/en/blog/domain-name/"},{"content_html":"\u003cp\u003eAnyone who has worked with domain names has typed \u003ccode\u003ewhois example.com\u003c/code\u003e more times than they can count.\u003c/p\u003e\n\u003cp\u003eThe command still works.\u003c/p\u003e\n\u003cp\u003eThe protocol behind it is effectively obsolete.\u003c/p\u003e\n\u003cp\u003eThe distinction matters because the information you receive today is no longer governed by the original \u003ca href=\"https://www.rfc-editor.org/rfc/rfc954\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWHOIS\u003c/a\u003e\n protocol. For most generic top-level domains (gTLDs), it comes from the \u003ca href=\"https://www.rfc-editor.org/rfc/rfc9082\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRegistration Data Access Protocol (RDAP)\u003c/a\u003e\n, a modern replacement standardized by the \u003ca href=\"https://www.ietf.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eInternet Engineering Task Force (IETF)\u003c/a\u003e\n and adopted by the \u003ca href=\"https://www.icann.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eInternet Corporation for Assigned Names and Numbers (ICANN)\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eUnderstanding the difference explains why domain lookups behave differently than they did a decade ago.\u003c/p\u003e\n\u003ch2 id=\"whois-solved-yesterdays-problem\"\u003eWHOIS solved yesterday\u0026rsquo;s problem\u003ca class=\"heading-anchor\" href=\"#whois-solved-yesterdays-problem\" aria-label=\"Link to WHOIS solved yesterday’s problem\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eWHOIS predates the modern web.\u003c/p\u003e\n\u003cp\u003eThe protocol was originally defined in 1982 in \u003ca href=\"https://www.rfc-editor.org/rfc/rfc812\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFC 812 — NICNAME/WHOIS\u003c/a\u003e\n, then revised in \u003ca href=\"https://www.rfc-editor.org/rfc/rfc954\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFC 954 — NICNAME/WHOIS\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eIts design reflected a much smaller Internet where every registered domain was expected to expose publicly available contact information.\u003c/p\u003e\n\u003cp\u003eThe protocol is deliberately simple.\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eClient\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    │\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eTCP/43\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    │\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    ▼\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eWHOIS server\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    │\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ePlain text response\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eA client connects to TCP port 43, sends a domain name, and receives an unstructured block of text.\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ whois example.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eDomain Name: EXAMPLE.COM\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eRegistrar: ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCreation Date: ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eRegistrant:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e...\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThere is no schema.\u003c/p\u003e\n\u003cp\u003eThere is no standard response format.\u003c/p\u003e\n\u003cp\u003eEvery registry decides how information is presented.\u003c/p\u003e\n\u003cp\u003eThat simplicity made WHOIS easy to implement. It also made automation unnecessarily difficult.\u003c/p\u003e\n\u003ch2 id=\"why-whois-had-to-change\"\u003eWhy WHOIS had to change\u003ca class=\"heading-anchor\" href=\"#why-whois-had-to-change\" aria-label=\"Link to Why WHOIS had to change\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eWHOIS accumulated technical debt for decades.\u003c/p\u003e\n\u003cp\u003eAmong its shortcomings:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eplain text only\u003c/li\u003e\n\u003cli\u003eno standardized schema\u003c/li\u003e\n\u003cli\u003einconsistent field names\u003c/li\u003e\n\u003cli\u003eno authentication\u003c/li\u003e\n\u003cli\u003eno authorization\u003c/li\u003e\n\u003cli\u003eno structured error handling\u003c/li\u003e\n\u003cli\u003eno internationalization\u003c/li\u003e\n\u003cli\u003eno standardized pagination\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe arrival of the European Union\u0026rsquo;s \u003ca href=\"https://eur-lex.europa.eu/eli/reg/2016/679/oj\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGeneral Data Protection Regulation (GDPR)\u003c/a\u003e\n exposed another weakness.\u003c/p\u003e\n\u003cp\u003eWHOIS had no concept of differentiated access.\u003c/p\u003e\n\u003cp\u003eEveryone received the same answer.\u003c/p\u003e\n\u003cp\u003eSometimes that answer became almost empty.\u003c/p\u003e\n\u003cp\u003eThe protocol itself was no longer capable of supporting modern privacy requirements.\u003c/p\u003e\n\u003ch2 id=\"rdap-arrives\"\u003eRDAP arrives\u003ca class=\"heading-anchor\" href=\"#rdap-arrives\" aria-label=\"Link to RDAP arrives\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe \u003ca href=\"https://www.rfc-editor.org/rfc/rfc9082\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRegistration Data Access Protocol (RDAP)\u003c/a\u003e\n is defined primarily by \u003ca href=\"https://www.rfc-editor.org/rfc/rfc9082\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFC 9082 — Registration Data Access Protocol Query Format\u003c/a\u003e\n and \u003ca href=\"https://www.rfc-editor.org/rfc/rfc9083\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFC 9083 — Registration Data Access Protocol JSON Responses\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eAt first glance, RDAP looks like WHOIS with JSON.\u003c/p\u003e\n\u003cp\u003eThat description misses the point.\u003c/p\u003e\n\u003cp\u003eRDAP introduces capabilities WHOIS never had.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eHTTPS transport\u003c/li\u003e\n\u003cli\u003eJSON responses\u003c/li\u003e\n\u003cli\u003emachine-readable schemas\u003c/li\u003e\n\u003cli\u003estandardized error responses\u003c/li\u003e\n\u003cli\u003eauthentication\u003c/li\u003e\n\u003cli\u003edifferentiated access control\u003c/li\u003e\n\u003cli\u003einternationalization\u003c/li\u003e\n\u003cli\u003ehyperlinks between related objects\u003c/li\u003e\n\u003cli\u003eextensibility through IANA-registered extensions\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eA simplified response looks like this.\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003e\u0026#34;objectClassName\u0026#34;\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;domain\u0026#34;\u003c/span\u003e,\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003e\u0026#34;ldhName\u0026#34;\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;example.com\u0026#34;\u003c/span\u003e,\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003e\u0026#34;status\u0026#34;\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;active\u0026#34;\u003c/span\u003e],\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003e\u0026#34;events\u0026#34;\u003c/span\u003e: [\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003e\u0026#34;eventAction\u0026#34;\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;registration\u0026#34;\u003c/span\u003e,\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003e\u0026#34;eventDate\u0026#34;\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;1995-08-14T04:00:00Z\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    }\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  ]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e}\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eApplications can parse this without vendor-specific parsers or regular expressions.\u003c/p\u003e\n\u003cp\u003eThat was never true of WHOIS.\u003c/p\u003e\n\u003ch2 id=\"a-brief-history-of-the-transition\"\u003eA brief history of the transition\u003ca class=\"heading-anchor\" href=\"#a-brief-history-of-the-transition\" aria-label=\"Link to A brief history of the transition\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eReplacing WHOIS was not a single event.\u003c/p\u003e\n\u003cp\u003eIt has taken more than a decade.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eYear\u003c/th\u003e\n          \u003cth\u003eMilestone\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2011\u003c/td\u003e\n          \u003ctd\u003eICANN\u0026rsquo;s Security and Stability Advisory Committee recommends replacing WHOIS.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2012\u003c/td\u003e\n          \u003ctd\u003eThe IETF begins developing RDAP through the WEIRDS Working Group.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2015\u003c/td\u003e\n          \u003ctd\u003eThe core RDAP specifications are published as RFCs.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2017\u003c/td\u003e\n          \u003ctd\u003eICANN launches an RDAP pilot for registries and registrars.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2019\u003c/td\u003e\n          \u003ctd\u003eRDAP becomes mandatory for ICANN-accredited gTLD registries and registrars.\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2025\u003c/td\u003e\n          \u003ctd\u003eICANN begins retiring WHOIS contractual requirements for generic top-level domains.\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThe protocol changed gradually.\u003c/p\u003e\n\u003cp\u003eMany users barely noticed.\u003c/p\u003e\n\u003ch2 id=\"why-ca-behaves-differently-from-com\"\u003eWhy \u003ccode\u003e.ca\u003c/code\u003e behaves differently from \u003ccode\u003e.com\u003c/code\u003e\u003ca class=\"heading-anchor\" href=\"#why-ca-behaves-differently-from-com\" aria-label=\"Link to Why .ca behaves differently from .com\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eOne of the biggest misconceptions about ICANN is that it governs every top-level domain.\u003c/p\u003e\n\u003cp\u003eIt does not.\u003c/p\u003e\n\u003cp\u003eFor generic top-level domains such as \u003ccode\u003e.com\u003c/code\u003e, \u003ccode\u003e.org\u003c/code\u003e, \u003ccode\u003e.net\u003c/code\u003e, and \u003ccode\u003e.info\u003c/code\u003e, registration data is governed by ICANN policies and accessed through the \u003ca href=\"https://www.icann.org/resources/pages/rdds-2018-05-22-en\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRegistration Data Directory Service (RDDS)\u003c/a\u003e\n using RDAP.\u003c/p\u003e\n\u003cp\u003eThe official starting point is the \u003ca href=\"https://lookup.icann.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eICANN Registration Data Lookup Service\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eCountry-code top-level domains (ccTLDs) operate differently.\u003c/p\u003e\n\u003cp\u003eRegistries responsible for domains such as:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e.ca\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.fr\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.de\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.uk\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.jp\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003edefine their own registration policies.\u003c/p\u003e\n\u003cp\u003eMany have implemented RDAP.\u003c/p\u003e\n\u003cp\u003eSome continue supporting WHOIS.\u003c/p\u003e\n\u003cp\u003eOthers expose proprietary lookup services.\u003c/p\u003e\n\u003cp\u003eDisclosure rules also vary considerably.\u003c/p\u003e\n\u003cp\u003eA \u003ccode\u003e.com\u003c/code\u003e lookup and a \u003ccode\u003e.ca\u003c/code\u003e lookup should not be expected to return the same information, even when queried using RDAP.\u003c/p\u003e\n\u003cp\u003eThe protocol is standardized.\u003c/p\u003e\n\u003cp\u003eThe disclosure policy is not.\u003c/p\u003e\n\u003ch2 id=\"whois-is-not-dead\"\u003eWHOIS is not dead\u003ca class=\"heading-anchor\" href=\"#whois-is-not-dead\" aria-label=\"Link to WHOIS is not dead\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eWHOIS still exists.\u003c/p\u003e\n\u003cp\u003eMany registries continue operating WHOIS services for backward compatibility.\u003c/p\u003e\n\u003cp\u003eCommand-line tools continue to work because registries continue exposing WHOIS endpoints.\u003c/p\u003e\n\u003cp\u003eThe direction of travel, however, is clear.\u003c/p\u003e\n\u003cp\u003eNew development should target RDAP rather than WHOIS.\u003c/p\u003e\n\u003ch2 id=\"practical-guidance\"\u003ePractical guidance\u003ca class=\"heading-anchor\" href=\"#practical-guidance\" aria-label=\"Link to Practical guidance\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eIf you occasionally need to look up information about a generic top-level domain, start with the \u003ca href=\"https://lookup.icann.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eICANN Registration Data Lookup Service\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eIf you are writing software, implement RDAP.\u003c/p\u003e\n\u003cp\u003eIf you are investigating a country-code domain, expect different registries to expose different information under different policies.\u003c/p\u003e\n\u003cp\u003eThose differences are usually policy decisions rather than protocol limitations.\u003c/p\u003e\n\u003ch2 id=\"references\"\u003eReferences\u003ca class=\"heading-anchor\" href=\"#references\" aria-label=\"Link to References\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.rfc-editor.org/rfc/rfc812\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFC 812 — NICNAME/WHOIS\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.rfc-editor.org/rfc/rfc954\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFC 954 — NICNAME/WHOIS\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.rfc-editor.org/rfc/rfc9082\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFC 9082 — Registration Data Access Protocol (RDAP) Query Format\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.rfc-editor.org/rfc/rfc9083\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFC 9083 — Registration Data Access Protocol (RDAP) JSON Responses\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.ietf.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eInternet Engineering Task Force (IETF)\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.icann.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eInternet Corporation for Assigned Names and Numbers (ICANN)\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://lookup.icann.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eICANN Registration Data Lookup Service\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.icann.org/resources/pages/rdds-2018-05-22-en\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRegistration Data Directory Service (RDDS)\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://eur-lex.europa.eu/eli/reg/2016/679/oj\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGeneral Data Protection Regulation (GDPR)\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.iana.org/assignments/rdap-extensions/rdap-extensions.xhtml\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eIANA RDAP Extensions Registry\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cem\u003eLast verified: 2026-07-29.\u003c/em\u003e\u003c/p\u003e\n","date_modified":"2026-07-29T00:00:00Z","date_published":"2026-07-29T00:00:00Z","id":"https://BHDicaire.com/en/blog/rdap-whois/","summary":"Anyone who has worked with domain names has typed whois example.com more times than they can count.\nThe command still works.\nThe protocol behind it is effectively obsolete.\n","title":"RDAP and WHOIS: What's Actually Changing?","url":"https://BHDicaire.com/en/blog/rdap-whois/"},{"content_html":"\u003cp\u003eThree horizontal marks, three jobs. The keyboard offers only the shortest one, so the other two get skipped or misused.\u003c/p\u003e\n\u003ch2 id=\"hyphen--\"\u003eHyphen (\u003ccode\u003e-\u003c/code\u003e)\u003ca class=\"heading-anchor\" href=\"#hyphen--\" aria-label=\"Link to Hyphen (-)\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe key beside \u003ccode\u003e0\u003c/code\u003e. It joins:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eCompound modifiers before a noun: \u003ccode\u003ewell-known\u003c/code\u003e, \u003ccode\u003eup-to-date\u003c/code\u003e, \u003ccode\u003efirst-quarter results\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003ePrefixes where clarity needs it: \u003ccode\u003ere-cover\u003c/code\u003e a chair, not \u003ccode\u003erecover\u003c/code\u003e a file.\u003c/li\u003e\n\u003cli\u003eWords broken across a line, which is the typesetter\u0026rsquo;s job, not yours.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"en-dash-\"\u003eEn dash (\u003ccode\u003e–\u003c/code\u003e)\u003ca class=\"heading-anchor\" href=\"#en-dash-\" aria-label=\"Link to En dash (–)\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe width of an \u0026ldquo;n\u0026rdquo;. It marks spans and pairings:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eRanges, read as \u0026ldquo;to\u0026rdquo;: \u003ccode\u003epages 3–5\u003c/code\u003e, \u003ccode\u003e2020–2026\u003c/code\u003e, \u003ccode\u003eMonday–Friday\u003c/code\u003e. Do not pair it with \u0026ldquo;from\u0026rdquo; or \u0026ldquo;between\u0026rdquo;: write \u003ccode\u003efrom 2020 to 2026\u003c/code\u003e, not \u003ccode\u003efrom 2020–2026\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eA relation between two peers: \u003ccode\u003ethe Montréal–Toronto route\u003c/code\u003e, \u003ccode\u003ea client–server split\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eType it: \u003ccode\u003e⌥-\u003c/code\u003e on macOS, \u003ccode\u003eAlt+0150\u003c/code\u003e on Windows, \u003ccode\u003e\u0026amp;ndash;\u003c/code\u003e in HTML.\u003c/p\u003e\n\u003ch2 id=\"em-dash-\"\u003eEm dash (\u003ccode\u003e—\u003c/code\u003e)\u003ca class=\"heading-anchor\" href=\"#em-dash-\" aria-label=\"Link to Em dash (—)\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe width of an \u0026ldquo;m\u0026rdquo;, and the only one that works at sentence level:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eA break stronger than a comma and lighter than parentheses.\u003c/li\u003e\n\u003cli\u003eA matched pair that sets off an aside: \u003ccode\u003eThe plan — debated for months — finally shipped.\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eKeep it to one pair per sentence. US style closes it up, \u003ccode\u003elike—this\u003c/code\u003e; many house styles and most of the web space it out, \u003ccode\u003elike — this\u003c/code\u003e. Pick one and hold it.\u003c/p\u003e\n\u003cp\u003eType it: \u003ccode\u003e⇧⌥-\u003c/code\u003e on macOS, \u003ccode\u003eAlt+0151\u003c/code\u003e on Windows, \u003ccode\u003e\u0026amp;mdash;\u003c/code\u003e in HTML.\u003c/p\u003e\n\u003ch2 id=\"picking-one\"\u003ePicking one\u003ca class=\"heading-anchor\" href=\"#picking-one\" aria-label=\"Link to Picking one\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eTwo words, one idea: hyphen.\u003c/li\u003e\n\u003cli\u003eOne value to another: en dash.\u003c/li\u003e\n\u003cli\u003eA break inside a sentence: em dash.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"on-this-site\"\u003eOn this site\u003ca class=\"heading-anchor\" href=\"#on-this-site\" aria-label=\"Link to On this site\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThis site enables Goldmark\u0026rsquo;s \u003ca href=\"https://gohugo.io/getting-started/configuration-markup/#goldmark\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003etypographer\u003c/code\u003e\u003c/a\u003e\n extension, so Markdown does some of the work: \u003ccode\u003e--\u003c/code\u003e renders as an en dash, \u003ccode\u003e---\u003c/code\u003e as an em dash, and straight quotes and apostrophes turn curly. Typing the real \u003ccode\u003e–\u003c/code\u003e and \u003ccode\u003e—\u003c/code\u003e characters works too, and stays unambiguous in files that other tools also read.\u003c/p\u003e\n","date_modified":"2026-07-29T00:00:00Z","date_published":"2026-07-29T00:00:00Z","id":"https://BHDicaire.com/en/til/dashes/","summary":"Three horizontal marks, three jobs. The keyboard offers only the shortest one, so the other two get skipped or misused.\nHyphen (-)# The key beside 0. It joins:\n","title":"Dashes: hyphen, en dash, and em dash","url":"https://BHDicaire.com/en/til/dashes/"},{"content_html":"\u003cp\u003eYou often need to serve the current directory over HTTP: to test a static build, check relative links, or open a file that \u003ccode\u003efile://\u003c/code\u003e will not render. Two one-liners do it, and you probably already have one installed.\u003c/p\u003e\n\u003ch2 id=\"python-built-in\"\u003ePython (built in)\u003ca class=\"heading-anchor\" href=\"#python-built-in\" aria-label=\"Link to Python (built in)\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003epython3 -m http.server \u003cspan style=\"color:#ae81ff\"\u003e8000\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eServes the working directory at \u003ccode\u003ehttp://localhost:8000\u003c/code\u003e. Python 3 ships with macOS and most Linux distributions, so this needs no install.\u003c/p\u003e\n\u003ch2 id=\"node\"\u003eNode\u003ca class=\"heading-anchor\" href=\"#node\" aria-label=\"Link to Node\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enpx http-server\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eFetches and runs \u003ca href=\"https://www.npmjs.com/package/http-server\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003ehttp-server\u003c/code\u003e\u003c/a\u003e\n on demand, defaulting to port 8080.\u003c/p\u003e\n\u003cp\u003eStop either one with \u003ccode\u003eControl-C\u003c/code\u003e in the terminal running it.\u003c/p\u003e\n\u003ch2 id=\"one-caveat\"\u003eOne caveat\u003ca class=\"heading-anchor\" href=\"#one-caveat\" aria-label=\"Link to One caveat\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eBoth bind to every network interface by default, so anyone on your network can reach the directory while the server runs. Keep it to your own machine:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003epython3 -m http.server \u003cspan style=\"color:#ae81ff\"\u003e8000\u003c/span\u003e --bind 127.0.0.1\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e\u003ccode\u003ehttp-server\u003c/code\u003e takes \u003ccode\u003e-a 127.0.0.1\u003c/code\u003e for the same effect.\u003c/p\u003e\n","date_modified":"2026-07-29T00:00:00Z","date_published":"2026-07-29T00:00:00Z","id":"https://BHDicaire.com/en/til/local-webserver/","summary":"You often need to serve the current directory over HTTP: to test a static build, check relative links, or open a file that file:// will not render. Two one-liners do it, and you probably already have one installed.\n","title":"A local webserver in one line","url":"https://BHDicaire.com/en/til/local-webserver/"},{"content_html":"\u003cp\u003eIf you must include an email address in open text files or documentation, use standard obfuscation techniques to keep automated scrapers from parsing it.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eHuman-readable obfuscation:\u003c/strong\u003e write it as \u003ccode\u003ejoe42 [at] domain [dot] com\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eGitHub-provided email alias:\u003c/strong\u003e \u003ccode\u003e12345678+patd42@users.noreply.github.com\u003c/code\u003e. Scrapers rarely target these, because GitHub discards standard spam sent to noreply addresses.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eThird-party contact forms:\u003c/strong\u003e link to a form service that abstracts your address and adds anti-spam/CAPTCHA protection.\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eTally.so, Typeform, or Google Forms:\u003c/strong\u003e create a minimal, anonymous three-field form (Summary, Steps to reproduce, Contact info).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFormspree or Web3Forms:\u003c/strong\u003e set up a lightweight HTML/Markdown form endpoint that routes messages to your inbox while shielding your address from scrapers.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"identify-the-private-github-provided-alias\"\u003eIdentify the private GitHub-provided alias\u003ca class=\"heading-anchor\" href=\"#identify-the-private-github-provided-alias\" aria-label=\"Link to Identify the private GitHub-provided alias\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe alias follows the structure \u003ccode\u003eID+USERNAME@users.noreply.github.com\u003c/code\u003e — for example, \u003ccode\u003e12345678+joe42@users.noreply.github.com\u003c/code\u003e.\u003c/p\u003e\n\u003ch3 id=\"method-1-the-github-ui-easiest\"\u003eMethod 1: the GitHub UI (easiest)\u003ca class=\"heading-anchor\" href=\"#method-1-the-github-ui-easiest\" aria-label=\"Link to Method 1: the GitHub UI (easiest)\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eLog into GitHub and click your profile picture in the top-right corner.\u003c/li\u003e\n\u003cli\u003eSelect \u003cstrong\u003eSettings\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eUnder \u003cstrong\u003eAccess\u003c/strong\u003e in the left sidebar, click \u003cstrong\u003eEmails\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eLook under \u003cstrong\u003eKeep my email addresses private\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eThe explanation box there contains your exact noreply address.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"method-2-the-github-api-or-terminal\"\u003eMethod 2: the GitHub API or terminal\u003ca class=\"heading-anchor\" href=\"#method-2-the-github-api-or-terminal\" aria-label=\"Link to Method 2: the GitHub API or terminal\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eIf you know your username, fetch your unique numeric user ID from GitHub\u0026rsquo;s API:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecurl -s https://api.github.com/users/patd42 | grep \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;\u0026#34;id\u0026#34;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eLook for the \u003ccode\u003e\u0026quot;id\u0026quot;\u003c/code\u003e number in the output (for example, \u003ccode\u003e12345678\u003c/code\u003e). Your private alias is then:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[ID]+[USERNAME]@users.noreply.github.com\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"things-to-know-about-the-noreply-alias\"\u003eThings to know about the noreply alias\u003ca class=\"heading-anchor\" href=\"#things-to-know-about-the-noreply-alias\" aria-label=\"Link to Things to know about the noreply alias\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eOutbound commits:\u003c/strong\u003e point Git at this address (\u003ccode\u003egit config --global user.email \u0026quot;ID+USERNAME@users.noreply.github.com\u0026quot;\u003c/code\u003e) so your personal email never lands in Git history.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eInbound emails are dropped:\u003c/strong\u003e because \u003ccode\u003e@users.noreply.github.com\u003c/code\u003e is a pseudo-domain, anything third parties send to it bounces. It exists for commit attribution and identity verification, not for receiving messages.\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-07-26T00:00:00Z","date_published":"2026-07-26T00:00:00Z","id":"https://BHDicaire.com/en/blog/masking-your-email-address/","summary":"If you must include an email address in open text files or documentation, use standard obfuscation techniques to keep automated scrapers from parsing it.\n","title":"Masking your email address","url":"https://BHDicaire.com/en/blog/masking-your-email-address/"},{"content_html":"\u003cp\u003e\u003ccode\u003egit log\u003c/code\u003e keeps every address you have ever committed with. Mine was a personal account, set once and then written into the permanent history of every repository I touched — public and private, copied into every clone and fork. Nothing leaked it. Git recorded it by design, because I never told it not to.\u003c/p\u003e\n\u003cp\u003eA commit stores an author email, and GitHub and GitLab use that address to attribute the commit to your account. It is public, and it does not expire. Scrubbing it out of history afterward is expensive and coordinated; not writing it in the first place is a three-line configuration change. This post makes Git record a per-host no-reply alias by default, without depending on you to remember.\u003c/p\u003e\n\u003ch2 id=\"the-address-each-host-gives-you\"\u003eThe address each host gives you\u003ca class=\"heading-anchor\" href=\"#the-address-each-host-gives-you\" aria-label=\"Link to The address each host gives you\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eGitHub and GitLab both issue a no-reply commit address that attributes commits to your account without exposing a real inbox.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eGitHub: \u003ccode\u003eID+username@users.noreply.github.com\u003c/code\u003e, once you enable \u003ca href=\"https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-email-preferences/setting-your-commit-email-address\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eKeep my email addresses private\u003c/a\u003e\n.\u003c/li\u003e\n\u003cli\u003eGitLab: \u003ccode\u003eID-username@users.noreply.gitlab.com\u003c/code\u003e, shown in your \u003ca href=\"https://docs.gitlab.com/ee/user/profile/#use-an-automatically-generated-private-commit-email\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eprofile settings\u003c/a\u003e\n.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eGitHub joins the numeric ID with \u003ccode\u003e+\u003c/code\u003e, GitLab with \u003ccode\u003e-\u003c/code\u003e. Mail to either address is discarded — they exist for attribution, not correspondence. \u003cem\u003eLast verified: 2026-07-26.\u003c/em\u003e\u003c/p\u003e\n\u003ch2 id=\"make-the-private-address-the-default\"\u003eMake the private address the default\u003ca class=\"heading-anchor\" href=\"#make-the-private-address-the-default\" aria-label=\"Link to Make the private address the default\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSetting it per repository is the step everyone forgets. Two configuration keys remove the memory requirement.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://git-scm.com/docs/git-config#Documentation/git-config.txt-useruseConfigOnly\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003euser.useConfigOnly\u003c/code\u003e\u003c/a\u003e\n stops Git from inventing an identity:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit config --global user.useConfigOnly true\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eWithout it, when no email is configured Git synthesizes one from your username and hostname — \u003ccode\u003euser@laptop.local\u003c/code\u003e — and commits under it silently. With it, a repository with no configured email refuses to commit until you set one. The silent default becomes a loud failure. \u003ccode\u003euseConfigOnly\u003c/code\u003e has shipped since Git 2.8 (2016); it is the durable half of this setup.\u003c/p\u003e\n\u003ch2 id=\"select-the-address-by-remote\"\u003eSelect the address by remote\u003ca class=\"heading-anchor\" href=\"#select-the-address-by-remote\" aria-label=\"Link to Select the address by remote\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003euseConfigOnly\u003c/code\u003e blocks the bad default. It does not choose the right address. A \u003ca href=\"https://git-scm.com/docs/git-config#_conditional_includes\" target=\"_blank\" rel=\"noopener noreferrer\"\u003econditional include\u003c/a\u003e\n does, keyed on the repository\u0026rsquo;s remote URL:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-ini\" data-lang=\"ini\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# ~/.gitconfig\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[user]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003euseConfigOnly\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[includeIf \u0026#34;hasconfig:remote.*.url:**/*github.com/**\u0026#34;]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003epath\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e~/.gitconfig-github\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[includeIf \u0026#34;hasconfig:remote.*.url:**/*gitlab.com/**\u0026#34;]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003epath\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e~/.gitconfig-gitlab\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-ini\" data-lang=\"ini\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# ~/.gitconfig-github\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[user]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003eemail\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e12345678+username@users.noreply.github.com\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe GitLab file mirrors it with the GitLab address. \u003ccode\u003ehasconfig:remote.*.url:\u003c/code\u003e matches against the repository\u0026rsquo;s configured remotes; the \u003ccode\u003e**/*github.com/**\u003c/code\u003e glob covers both HTTPS (\u003ccode\u003ehttps://github.com/…\u003c/code\u003e) and SSH (\u003ccode\u003egit@github.com:…\u003c/code\u003e). It requires Git 2.36 (April 2022) or newer.\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/p\u003e\n\u003cp\u003eThe address now follows the remote: clone from GitHub and commit as your GitHub alias, clone from GitLab and commit as your GitLab alias, with no per-repository step. My own \u003ca href=\"https://github.com/bhdicaire/dotFiles/blob/main/dot_gitconfig\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003e~/.gitconfig\u003c/code\u003e\u003c/a\u003e\n and \u003ca href=\"https://github.com/bhdicaire/dotFiles/blob/main/dot_config/git/config.tmpl\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003e~/.config/git/config\u003c/code\u003e\u003c/a\u003e\n carry the full version.\u003c/p\u003e\n\u003ch2 id=\"where-it-breaks\"\u003eWhere it breaks\u003ca class=\"heading-anchor\" href=\"#where-it-breaks\" aria-label=\"Link to Where it breaks\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eA new repository has no remote yet.\u003c/strong\u003e \u003ccode\u003ehasconfig:remote.*.url\u003c/code\u003e matches the remotes that exist. Run \u003ccode\u003egit init\u003c/code\u003e, commit before \u003ccode\u003egit remote add\u003c/code\u003e, and no host block fires — with \u003ccode\u003euseConfigOnly\u003c/code\u003e, that first commit fails. Add the remote first, or set the email locally.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eSelf-hosted and other hosts.\u003c/strong\u003e The \u003ccode\u003egithub.com\u003c/code\u003e and \u003ccode\u003egitlab.com\u003c/code\u003e globs match the public services only. A self-hosted GitLab, Gitea, or Bitbucket instance needs its own block and its own address.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eWorkflows that expect a real inbox.\u003c/strong\u003e Projects that take patches over email — the Linux kernel and other \u003ca href=\"https://git-scm.com/docs/git-send-email\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003egit send-email\u003c/code\u003e\u003c/a\u003e\n lists — need an address that accepts replies. A no-reply alias is the wrong choice there.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"what-this-does-not-fix\"\u003eWhat this does not fix\u003ca class=\"heading-anchor\" href=\"#what-this-does-not-fix\" aria-label=\"Link to What this does not fix\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe addresses already in your history stay there. Correcting them means rewriting commits with \u003ca href=\"https://github.com/newren/git-filter-repo\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003egit filter-repo\u003c/code\u003e\u003c/a\u003e\n or remapping them through a \u003ca href=\"https://git-scm.com/docs/gitmailmap\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003e.mailmap\u003c/code\u003e\u003c/a\u003e\n, then force-pushing and re-coordinating every clone — a larger operation with its own costs. The configuration here is the cheap half: it governs the next commit, not the last thousand. \u003ccode\u003euseConfigOnly\u003c/code\u003e earns its place even alone. It does not make you private; it removes Git\u0026rsquo;s permission to guess, so a fresh machine fails loudly instead of committing under a name you did not choose.\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eThe \u003ccode\u003ehasconfig:remote.*.url:\u003c/code\u003e condition arrived in \u003ca href=\"https://github.com/git/git/blob/v2.36.0/Documentation/RelNotes/2.36.0.txt\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGit 2.36.0\u003c/a\u003e\n (2022-04-18).\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eConditional includes are evaluated when Git reads configuration, against the remotes present at that moment — not the ones you intend to add later.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","date_modified":"2026-07-26T00:00:00Z","date_published":"2026-07-26T00:00:00Z","id":"https://BHDicaire.com/en/blog/git-commit-email-privacy/","summary":"git log keeps every address you have ever committed with. Mine was a personal account, set once and then written into the permanent history of every repository I touched — public and private, copied into every clone and fork. Nothing leaked it. Git recorded it by design, because I never told it not to.\n","title":"Git commit email privacy","url":"https://BHDicaire.com/en/blog/git-commit-email-privacy/"},{"content_html":"\u003cp\u003e\u003ca href=\"https://editorconfig.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eEditorConfig\u003c/a\u003e\n files enforce consistent settings across editors for a given project, and they\u0026rsquo;re \u003ca href=\"https://editorconfig.org/#download\" target=\"_blank\" rel=\"noopener noreferrer\"\u003efairly widely supported\u003c/a\u003e\n. Useful for collaboration: the coding standard travels with the repository instead of living in each person\u0026rsquo;s editor preferences.\u003c/p\u003e\n\u003cp\u003eApparently, \u003ca href=\"https://www.barebones.com/support/technotes/editorconfig.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eBBEdit supports EditorConfig natively\u003c/a\u003e\n — no plugin required.\u003c/p\u003e\n\u003ch2 id=\"how-the-lookup-works\"\u003eHow the lookup works\u003ca class=\"heading-anchor\" href=\"#how-the-lookup-works\" aria-label=\"Link to How the lookup works\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eWhen opening a file, EditorConfig plugins look for a file named \u003ccode\u003e.editorconfig\u003c/code\u003e in the directory of the opened file and in every parent directory. The search stops when the root filepath is reached, or when an EditorConfig file with \u003ccode\u003eroot = true\u003c/code\u003e is found.\u003c/p\u003e\n\u003cp\u003eThat last part is why the top-level file in a project should start with \u003ccode\u003eroot = true\u003c/code\u003e — otherwise the search keeps walking up into your home directory and picks up unrelated settings.\u003c/p\u003e\n\u003ch2 id=\"bbedit-specific-keys\"\u003eBBEdit-specific keys\u003ca class=\"heading-anchor\" href=\"#bbedit-specific-keys\" aria-label=\"Link to BBEdit-specific keys\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSoft-wrap settings aren\u0026rsquo;t part of the \u003ca href=\"https://editorconfig.org/#file-format-details\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecore properties\u003c/a\u003e\n, so BBEdit defines its own \u003ccode\u003ex-\u003c/code\u003e prefixed keys, including \u003ccode\u003ex-soft-wrap-text\u003c/code\u003e, \u003ccode\u003ex-soft-wrap-mode\u003c/code\u003e, and \u003ccode\u003ex-soft-wrap-limit\u003c/code\u003e. Other editors ignore unknown keys, so these are safe to commit.\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-ini\" data-lang=\"ini\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[*]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003ex-soft-wrap-text\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003ex-soft-wrap-mode\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003eWindowWidth\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003ex-show-invisibles\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003ex-show-spaces\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eWatch the two soft-wrap keys, which are easy to swap: \u003ccode\u003ex-soft-wrap-mode\u003c/code\u003e takes \u003ccode\u003eCharacterWidth\u003c/code\u003e, \u003ccode\u003eWindowWidth\u003c/code\u003e, or \u003ccode\u003ePageGuide\u003c/code\u003e, while \u003ccode\u003ex-soft-wrap-limit\u003c/code\u003e is an \u003cem\u003einteger\u003c/em\u003e character count that only means anything when the mode is \u003ccode\u003eCharacterWidth\u003c/code\u003e. Writing \u003ccode\u003ex-soft-wrap-limit = WindowWidth\u003c/code\u003e looks plausible and does nothing.\u003c/p\u003e\n\u003cp\u003eThe technote lists more: \u003ccode\u003ex-typographers-quotes\u003c/code\u003e, \u003ccode\u003ex-balance-while-typing\u003c/code\u003e, \u003ccode\u003ex-font-name\u003c/code\u003e, and \u003ccode\u003ex-font-size\u003c/code\u003e. Everything except the mode, limit, and font keys is a Boolean flag.\u003c/p\u003e\n\u003ch2 id=\"my-current-standard\"\u003eMy current standard\u003ca class=\"heading-anchor\" href=\"#my-current-standard\" aria-label=\"Link to My current standard\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThis is the \u003ca href=\"https://github.com/bhdicaire/dotFiles/blob/main/.editorconfig\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003ccode\u003e.editorconfig\u003c/code\u003e from my dotfiles\u003c/a\u003e\n:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-ini\" data-lang=\"ini\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eroot\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[*]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003echarset\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003eutf-8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eend_of_line\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003elf\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eindent_size\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eindent_style\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003espace\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003einsert_final_newline\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003etrim_trailing_whitespace\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[*.md]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003etrim_trailing_whitespace\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Makefiles REQUIRE tabs\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[{Makefile,makefile,GNUmakefile,*.mk}]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eindent_style\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003etab\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Terminfo files use tabs\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[*.terminfo]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eindent_style\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003etab\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Git config uses tabs by convention\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[dot_config/git/config.tmpl]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eindent_style\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003etab\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Vim colorschemes — third-party, don\u0026#39;t enforce\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[dot_vim/colors/*.vim]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eindent_style\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003eunset\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eindent_size\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003eunset\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003etrim_trailing_whitespace\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003eunset\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Contributor Covenant — don\u0026#39;t enforce indent rules\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[.github/CODE_OF_CONDUCT.md]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eindent_size\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003eunset\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThree things worth knowing about that file.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eSet the defaults once.\u003c/strong\u003e Rather than listing every extension in a glob, \u003ccode\u003e[*]\u003c/code\u003e carries the whole baseline and later sections carve out exceptions. Sections apply in order and later ones win for files they match, so the exceptions have to come after \u003ccode\u003e[*]\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eMarkdown needs the trailing-whitespace rule turned off.\u003c/strong\u003e Two trailing spaces are a hard line break in Markdown, so a global \u003ccode\u003etrim_trailing_whitespace = true\u003c/code\u003e silently eats them. Hence the \u003ccode\u003e[*.md]\u003c/code\u003e override.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ccode\u003eunset\u003c/code\u003e is the escape hatch for third-party files.\u003c/strong\u003e Vendored code — vim colorschemes, an upstream Code of Conduct — shouldn\u0026rsquo;t be reformatted to match your house style. Setting a property to \u003ccode\u003eunset\u003c/code\u003e makes the editor fall back to its own default rather than inheriting from \u003ccode\u003e[*]\u003c/code\u003e, which is cleaner than trying to guess the upstream author\u0026rsquo;s settings.\u003c/p\u003e\n\u003cp\u003eA tab-indented Makefile is not a style preference: make requires tabs for recipe lines, and a space-indented one fails to run. Same reasoning for terminfo.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eFor Windows users:\u003c/strong\u003e to create an \u003ccode\u003e.editorconfig\u003c/code\u003e file within Windows Explorer, create a file named \u003ccode\u003e.editorconfig.\u003c/code\u003e — Explorer will automatically rename it to \u003ccode\u003e.editorconfig\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eSource note: prompted by Jeff Vautin\u0026rsquo;s \u003ca href=\"https://jeffvautin.com/2018/02/editorconfig/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eEditorConfig\u003c/a\u003e\n.\u003c/p\u003e\n","date_modified":"2026-07-20T00:00:00Z","date_published":"2017-01-01T00:00:00Z","id":"https://BHDicaire.com/en/til/editorconfig/","summary":"EditorConfig files enforce consistent settings across editors for a given project, and they\u0026rsquo;re fairly widely supported . Useful for collaboration: the coding standard travels with the repository instead of living in each person\u0026rsquo;s editor preferences.\n","title":"EditorConfig: consistent settings across editors","url":"https://BHDicaire.com/en/til/editorconfig/"},{"content_html":"\u003cp\u003eWindows Subsystem for Linux (WSL) allows you to run a full Debian environment directly on Windows, making it the perfect companion for your macOS and Proxmox workflow.\u003c/p\u003e\n\u003ch3 id=\"1-install-wsl-and-debian\"\u003e1. Install WSL and Debian\u003ca class=\"heading-anchor\" href=\"#1-install-wsl-and-debian\" aria-label=\"Link to 1. Install WSL and Debian\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eOpen PowerShell as Administrator and run:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ewsl --install -d Debian\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eOnce installed, update your system:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt update \u003cspan style=\"color:#f92672\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e sudo apt upgrade -y\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"2-install-zsh-and-chezmoi\"\u003e2. Install Zsh and Chezmoi\u003ca class=\"heading-anchor\" href=\"#2-install-zsh-and-chezmoi\" aria-label=\"Link to 2. Install Zsh and Chezmoi\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eTo maintain consistency with your macOS and server setups, install Zsh and the \u003cstrong\u003echezmoi\u003c/strong\u003e binary [\u003ca href=\"https://chezmoi.io/install/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e2\u003c/a\u003e\n]:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt install zsh\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esh -c \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#66d9ef\"\u003e$(\u003c/span\u003ecurl -fsLS get.chezmoi.io\u003cspan style=\"color:#66d9ef\"\u003e)\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"3-deploy-your-configuration\"\u003e3. Deploy Your Configuration\u003ca class=\"heading-anchor\" href=\"#3-deploy-your-configuration\" aria-label=\"Link to 3. Deploy Your Configuration\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eInitialize your environment using your public repository [\u003ca href=\"https://github.com/bhdicaire/dotFiles\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e1\u003c/a\u003e\n]:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echezmoi init --apply bhdicaire\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echsh -s \u003cspan style=\"color:#66d9ef\"\u003e$(\u003c/span\u003ewhich zsh\u003cspan style=\"color:#66d9ef\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"4-headless-secrets-with-1password\"\u003e4. Headless Secrets with 1Password\u003ca class=\"heading-anchor\" href=\"#4-headless-secrets-with-1password\" aria-label=\"Link to 4. Headless Secrets with 1Password\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eSince you avoid GUIs on servers and WSL, install the \u003cstrong\u003e1Password CLI\u003c/strong\u003e to manage secrets via SSH or the terminal [\u003ca href=\"https://developer.1password.com/docs/cli/get-started/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e3\u003c/a\u003e\n]. This ensures your Debian WSL instance can securely inject environment variables or RAM-only secrets during runtime, matching your Proxmox and Raspberry Pi automation [\u003ca href=\"https://boranuzun.ch/blog/dotfiles-setup/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e4\u003c/a\u003e\n].\u003c/p\u003e\n\u003ch2 id=\"-sources\"\u003e🌐 Sources\u003ca class=\"heading-anchor\" href=\"#-sources\" aria-label=\"Link to 🌐 Sources\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/bhdicaire/dotFiles\" target=\"_blank\" rel=\"noopener noreferrer\"\u003egithub.com - bhdicaire/dotFiles: my chezmoi-managed dotfiles\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://chezmoi.io/install/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003echezmoi.io - Install\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://developer.1password.com/docs/cli/get-started/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003edeveloper.1password.com - Get started with 1Password CLI\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://boranuzun.ch/blog/dotfiles-setup/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eboranuzun.ch - ~/how i manage my dotfiles - Boran UZUN\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n","date_modified":"2026-07-20T00:00:00Z","date_published":"2021-03-12T00:00:00Z","id":"https://BHDicaire.com/en/til/wsl/","summary":"Windows Subsystem for Linux (WSL) allows you to run a full Debian environment directly on Windows, making it the perfect companion for your macOS and Proxmox workflow.\n","title":"Windows Subsystem for Linux (WSL)","url":"https://BHDicaire.com/en/til/wsl/"},{"content_html":"\u003cp\u003e\u003ca href=\"https://www.chezmoi.io/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003echezmoi\u003c/a\u003e\n manages dotfiles across multiple machines from a single git repository. Unlike a symlink farm, it keeps a \u003cem\u003esource state\u003c/em\u003e separate from your home directory and materialises files into place — which is what makes per-machine differences and secrets tractable.\u003c/p\u003e\n\u003cp\u003eMy configuration lives at \u003ca href=\"https://github.com/bhdicaire/dotFiles\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ebhdicaire/dotFiles\u003c/a\u003e\n.\u003c/p\u003e\n\u003ch2 id=\"the-daily-loop\"\u003eThe daily loop\u003ca class=\"heading-anchor\" href=\"#the-daily-loop\" aria-label=\"Link to The daily loop\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-sh\" data-lang=\"sh\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echezmoi add ~/.zshrc      \u003cspan style=\"color:#75715e\"\u003e# start managing an existing file\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echezmoi edit ~/.zshrc     \u003cspan style=\"color:#75715e\"\u003e# edit the source, not the target\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echezmoi diff              \u003cspan style=\"color:#75715e\"\u003e# preview what would change in $HOME\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echezmoi -v apply          \u003cspan style=\"color:#75715e\"\u003e# write the changes\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e\u003ccode\u003echezmoi cd\u003c/code\u003e opens a shell in the source directory, where it\u0026rsquo;s an ordinary git repository:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-sh\" data-lang=\"sh\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echezmoi cd\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit add .\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit commit -m \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;chore: update zsh config\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit push\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eexit\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eOn another machine, pull and apply in one step:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-sh\" data-lang=\"sh\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echezmoi update -v\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"file-naming-is-the-configuration\"\u003eFile naming is the configuration\u003ca class=\"heading-anchor\" href=\"#file-naming-is-the-configuration\" aria-label=\"Link to File naming is the configuration\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe source directory doesn\u0026rsquo;t contain \u003ccode\u003e.zshrc\u003c/code\u003e — it contains \u003ccode\u003edot_zshrc\u003c/code\u003e. Attributes are encoded in the filename, which is why the source tree looks odd at first and why tooling that keys off file extensions needs help.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003ePrefix\u003c/th\u003e\n          \u003cth\u003eEffect\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003edot_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eRename to a leading dot: \u003ccode\u003edot_zshrc\u003c/code\u003e → \u003ccode\u003e.zshrc\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eprivate_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eRemove group and world permissions\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ereadonly_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eRemove write permissions\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eexecutable_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eAdd executable permissions\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003esymlink_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eCreate a symlink instead of a regular file\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eencrypted_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eStore the file encrypted in the source state\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eexact_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eOn a directory, delete anything chezmoi doesn\u0026rsquo;t manage\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ecreate_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eCreate if missing, then leave alone\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003erun_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eTreat the contents as a script to run\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eliteral_\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eStop parsing prefixes — for a file genuinely named \u003ccode\u003edot_foo\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003ePrefixes compose, so \u003ccode\u003eprivate_dot_ssh\u003c/code\u003e is a \u003ccode\u003e.ssh\u003c/code\u003e directory with permissions stripped. The \u003ccode\u003e.tmpl\u003c/code\u003e suffix marks a file as a template.\u003c/p\u003e\n\u003cp\u003eScripts combine \u003ccode\u003erun_\u003c/code\u003e with \u003ccode\u003eonce_\u003c/code\u003e or \u003ccode\u003eonchange_\u003c/code\u003e: \u003ccode\u003erun_once_install-packages.sh\u003c/code\u003e runs a single time per machine, \u003ccode\u003erun_onchange_\u003c/code\u003e re-runs whenever its own contents change — the usual way to reinstall packages after editing a Brewfile.\u003c/p\u003e\n\u003ch2 id=\"per-machine-differences\"\u003ePer-machine differences\u003ca class=\"heading-anchor\" href=\"#per-machine-differences\" aria-label=\"Link to Per-machine differences\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThis is the reason to prefer chezmoi over symlinks. A \u003ccode\u003e.tmpl\u003c/code\u003e file is Go templating with machine facts available:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-gotmpl\" data-lang=\"gotmpl\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e{{\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eif\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eeq\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003e.chezmoi.os\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;darwin\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e}}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eexport HOMEBREW_PREFIX=\u0026#34;/opt/homebrew\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e{{\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eelse\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eif\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eeq\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003e.chezmoi.os\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;linux\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e}}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eexport HOMEBREW_PREFIX=\u0026#34;/home/linuxbrew/.linuxbrew\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e{{\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eend\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e}}\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e\u003ccode\u003echezmoi data\u003c/code\u003e prints everything available to templates — OS, architecture, hostname, username, plus any variables you define yourself.\u003c/p\u003e\n\u003ch2 id=\"secrets-stay-in-1password\"\u003eSecrets stay in 1Password\u003ca class=\"heading-anchor\" href=\"#secrets-stay-in-1password\" aria-label=\"Link to Secrets stay in 1Password\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eTemplates can call out to a password manager, so a secret is fetched at apply time and never lands in the repository. With the \u003ca href=\"/en/blog/1password-secrets/\"\u003e1Password CLI\u003c/a\u003e\n already set up, \u003ccode\u003eonepasswordRead\u003c/code\u003e takes the same \u003ccode\u003eop://\u003c/code\u003e secret reference:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-gotmpl\" data-lang=\"gotmpl\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eexport GITHUB_TOKEN=\u0026#34;\u003cspan style=\"color:#75715e\"\u003e{{\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eonepasswordRead\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;op://Production/GitHub/token\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e}}\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003echezmoi also exposes \u003ccode\u003eonepassword\u003c/code\u003e for a whole item as structured data, \u003ccode\u003eonepasswordDetailsFields\u003c/code\u003e for fields indexed by name, and \u003ccode\u003eonepasswordDocument\u003c/code\u003e for stored files.\u003c/p\u003e\n\u003cp\u003eThere is a distinction worth being deliberate about. \u003ccode\u003eop run\u003c/code\u003e keeps the secret out of the file entirely — the file holds the \u003ccode\u003eop://\u003c/code\u003e reference and resolution happens at runtime, every time. A chezmoi template resolves at \u003cem\u003eapply\u003c/em\u003e time and writes the real secret to disk in \u003ccode\u003e$HOME\u003c/code\u003e. That\u0026rsquo;s the right trade for something that has to be a literal value in a config file that can\u0026rsquo;t call \u003ccode\u003eop\u003c/code\u003e itself, but for anything a shell can resolve on demand, exporting the reference and using \u003ccode\u003eop run\u003c/code\u003e leaves less on disk.\u003c/p\u003e\n\u003cp\u003eEither way the source repository only ever contains the reference, which is what makes it safe to push.\u003c/p\u003e\n\u003ch2 id=\"a-new-machine\"\u003eA new machine\u003ca class=\"heading-anchor\" href=\"#a-new-machine\" aria-label=\"Link to A new machine\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-sh\" data-lang=\"sh\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esh -c \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#66d9ef\"\u003e$(\u003c/span\u003ecurl -fsLS get.chezmoi.io\u003cspan style=\"color:#66d9ef\"\u003e)\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u003c/span\u003e -- init --apply bhdicaire/dotFiles\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat installs chezmoi, clones the repository, and applies it in one command. The shorthand expands to a GitHub URL — and it resolves fine despite the capital F in \u003ccode\u003edotFiles\u003c/code\u003e. For any other host, use the full \u003ccode\u003ehttps://…git\u003c/code\u003e form.\u003c/p\u003e\n\u003ch2 id=\"the-tradeoff\"\u003eThe tradeoff\u003ca class=\"heading-anchor\" href=\"#the-tradeoff\" aria-label=\"Link to The tradeoff\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe indirection is real: you edit \u003ccode\u003e~/.local/share/chezmoi/dot_zshrc\u003c/code\u003e, not \u003ccode\u003e~/.zshrc\u003c/code\u003e, and forgetting that means editing a file that the next \u003ccode\u003eapply\u003c/code\u003e will overwrite. \u003ccode\u003echezmoi edit\u003c/code\u003e exists precisely to stop you doing this. In exchange you get templating, encryption, and one command to bring up a new machine.\u003c/p\u003e\n\u003cp\u003eOne practical wrinkle: because attributes hide the real extension, editor tooling that dispatches on file type won\u0026rsquo;t recognise \u003ccode\u003edot_zshrc\u003c/code\u003e as shell. That includes \u003ca href=\"/en/til/editorconfig/\"\u003eEditorConfig\u003c/a\u003e\n, which needs explicit sections for the chezmoi naming scheme.\u003c/p\u003e\n","date_modified":"2026-07-20T00:00:00Z","date_published":"2026-02-04T00:00:00Z","id":"https://BHDicaire.com/en/til/chezmoi/","summary":"chezmoi manages dotfiles across multiple machines from a single git repository. Unlike a symlink farm, it keeps a source state separate from your home directory and materialises files into place — which is what makes per-machine differences and secrets tractable.\n","title":"chezmoi: managing dotfiles across machines","url":"https://BHDicaire.com/en/til/chezmoi/"},{"content_html":"\u003cp\u003eShortcodes are Hugo\u0026rsquo;s escape hatch: a way to put something in a page that Markdown has no syntax for, without dropping into raw HTML. This site has accumulated a fair number, and until now nothing listed them.\u003c/p\u003e\n\u003cp\u003eThe table below is \u003cstrong\u003egenerated at build time\u003c/strong\u003e by reading \u003ccode\u003elayouts/shortcodes/\u003c/code\u003e. Add a shortcode and it appears; delete one and it disappears. A hand-maintained list would have started drifting the day after I wrote it.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eShortcode\u003c/th\u003e\n      \u003cth\u003eWhat it does\u003c/th\u003e\n      \u003cth\u003eUsage\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003earrow\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eAn inline \u003ccode\u003e←\u003c/code\u003e or \u003ccode\u003e→\u003c/code\u003e, used as an annotation gutter beside a term.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; arrow left \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003ecallout\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eAn admonition box. Prefer the Markdown \u003ccode\u003e\u0026gt; [!NOTE]\u003c/code\u003e syntax; this remains for \u003ccode\u003earchive\u003c/code\u003e.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; callout type=\u0026#34;archive\u0026#34; title=\u0026#34;Optional title\u0026#34; \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003ecard\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA linked card with an icon and title.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; card \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003ecards\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eResponsive grid wrapper for a set of \u003ccode\u003ecard\u003c/code\u003e shortcodes.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; cards \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003ecode\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA code block with a filename header and a copy button.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; code file=\u0026#34;config/deploy.yml\u0026#34; lang=\u0026#34;yaml\u0026#34; \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003ecompanion\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA top-of-page pointer to one related page, with a sentence saying why.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; companion \u0026#34;/blog/rustdesk/self-hosting/\u0026#34; \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003edefinition\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA glossary tooltip, resolved from \u003ccode\u003edata/series/ref/glossary.yml\u003c/code\u003e.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; definition \u0026#34;saffron\u0026#34; /\u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003edetails\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA collapsible accordion section.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; details \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eemoji\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eAn emoji looked up by name from \u003ccode\u003edata/series/ref/emoji.yml\u003c/code\u003e.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; emoji \u0026#34;warning\u0026#34; \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003efiletree/container\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eWrapper for a file tree; holds \u003ccode\u003efiletree/folder\u003c/code\u003e and \u003ccode\u003efiletree/file\u003c/code\u003e entries.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; filetree/container \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003efiletree/file\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA file entry inside a \u003ccode\u003efiletree/container\u003c/code\u003e.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; filetree/file \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003efiletree/folder\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA folder entry inside a \u003ccode\u003efiletree/container\u003c/code\u003e.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; filetree/folder \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003ekbd\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA keycap, for keyboard shortcuts.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; kbd \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003emermaid\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA Mermaid diagram rendered from a text definition.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; mermaid \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003epullquote\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA quotation set aside from the main flow.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; pullquote \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003esteps\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA numbered sequence of steps.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; steps \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003etab\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA single panel inside a \u003ccode\u003etabs\u003c/code\u003e group.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; tab label=\u0026#34;Ruby\u0026#34; \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003etabs\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA tabbed panel group; wraps \u003ccode\u003etab\u003c/code\u003e entries.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; tabs \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003etimeline\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eA vertical timeline of dated milestones; each \u003ccode\u003e###\u003c/code\u003e heading is one entry.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; timeline \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eversion\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eAn added, changed, or deprecated badge.\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003e{{\u0026lt; version added=\u0026#34;2.1\u0026#34; \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThe \u003cem\u003eUsage\u003c/em\u003e column is extracted from the documentation comment at the top of each template, so it stays honest for the same reason the list does. Descriptions come from \u003ccode\u003edata/shortcodes.yml\u003c/code\u003e; anything missing an entry is listed anyway and flagged, and the build prints a warning naming it.\u003c/p\u003e\n\u003ch2 id=\"built-ins-are-not-in-the-table\"\u003eBuilt-ins are not in the table\u003ca class=\"heading-anchor\" href=\"#built-ins-are-not-in-the-table\" aria-label=\"Link to Built-ins are not in the table\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eHugo ships its own shortcodes, and those aren\u0026rsquo;t in \u003ccode\u003elayouts/shortcodes/\u003c/code\u003e, so they don\u0026rsquo;t appear above. The one that matters here is \u003ccode\u003erelref\u003c/code\u003e, which resolves an internal link at build time:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[\u003cspan style=\"color:#f92672\"\u003eNow page\u003c/span\u003e](\u003cspan style=\"color:#a6e22e\"\u003e{{\u0026lt; relref \u0026#34;/blog/slashes/now/\u0026#34; \u0026gt;}}\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eTwo reasons to prefer it over a hand-typed URL. It \u003cstrong\u003efails the build\u003c/strong\u003e on a bad path rather than publishing a dead link — which is how the cross-reference posts got caught pointing at \u003ccode\u003e/blog/hugo/callouts/\u003c/code\u003e when the published URL is actually \u003ccode\u003e/blog/callouts/\u003c/code\u003e. And it resolves against the \u003cstrong\u003econtent path\u003c/strong\u003e, so it keeps working when a permalink pattern changes.\u003c/p\u003e\n\u003cp\u003eGive it an absolute content path. A bare filename resolves, but only until a file moves or a name collides.\u003c/p\u003e\n\u003ch2 id=\"writing-about-shortcodes\"\u003eWriting about shortcodes\u003ca class=\"heading-anchor\" href=\"#writing-about-shortcodes\" aria-label=\"Link to Writing about shortcodes\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eTo show a shortcode without executing it, wrap the braces in \u003ccode\u003e/*\u003c/code\u003e and \u003ccode\u003e*/\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{{\u0026lt;/* callout type=\u0026#34;archive\u0026#34; */\u0026gt;}}\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat is Hugo parser syntax rather than a shortcode, which is why it isn\u0026rsquo;t in the table either. Everything on this page that displays a shortcode uses it.\u003c/p\u003e\n\u003ch2 id=\"when-not-to-reach-for-one\"\u003eWhen not to reach for one\u003ca class=\"heading-anchor\" href=\"#when-not-to-reach-for-one\" aria-label=\"Link to When not to reach for one\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA shortcode is worth it when the alternative is repeating markup, or when the content needs data from elsewhere in the site — \u003ccode\u003edefinition\u003c/code\u003e reads the glossary, \u003ccode\u003eemoji\u003c/code\u003e reads the emoji table.\u003c/p\u003e\n\u003cp\u003eIt is not worth it when Markdown already has a syntax. \u003ca href=\"/en/blog/callouts/\"\u003eCallouts\u003c/a\u003e\n are the clearest case: they used to be shortcode-only, and moving them to the standard \u003ccode\u003e\u0026gt; [!NOTE]\u003c/code\u003e alert syntax meant the same text works in Bear, on GitHub, and here. A shortcode is a small lock-in — content that only renders inside this site. Worth paying when it buys something, worth avoiding when it doesn\u0026rsquo;t.\u003c/p\u003e\n","date_modified":"2026-07-20T00:00:00Z","date_published":"2026-07-20T00:00:00Z","id":"https://BHDicaire.com/en/blog/shortcodes/","summary":"Shortcodes are Hugo\u0026rsquo;s escape hatch: a way to put something in a page that Markdown has no syntax for, without dropping into raw HTML. This site has accumulated a fair number, and until now nothing listed them.\n","title":"Shortcodes","url":"https://BHDicaire.com/en/blog/shortcodes/"},{"content_html":"\u003cp\u003ePointing a reader at another page sounds like one problem. It is three, and for a while this site solved it four different ways — a front matter list on one post, hand-typed \u0026ldquo;Companion note:\u0026rdquo; lines on four others, an arrow in the data tables, and ad-hoc \u0026ldquo;See also\u0026rdquo; prose wherever I happened to want one. Nothing enforced consistency, so nothing was consistent.\u003c/p\u003e\n\u003cp\u003eThere are now three mechanisms, chosen by what the pointer is \u003cem\u003efor\u003c/em\u003e.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eMechanism\u003c/th\u003e\n          \u003cth\u003eWhere it appears\u003c/th\u003e\n          \u003cth\u003eUse it when\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003erelated:\u003c/code\u003e front matter\u003c/td\u003e\n          \u003ctd\u003eEnd of page, as a list\u003c/td\u003e\n          \u003ctd\u003eSeveral pages are relevant; no explanation needed\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e{{\u0026lt; companion \u0026gt;}}\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eTop of page, with a sentence\u003c/td\u003e\n          \u003ctd\u003eOne page gives essential context for this one\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003ebackLink\u003c/code\u003e in a data file\u003c/td\u003e\n          \u003ctd\u003eInside a table row, as \u003ccode\u003e↩︎\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eA table row has a matching note\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"related--the-end-of-page-list\"\u003erelated: — the end-of-page list\u003ca class=\"heading-anchor\" href=\"#related--the-end-of-page-list\" aria-label=\"Link to related: — the end-of-page list\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA list of paths in front matter renders a \u003cem\u003eRelated posts\u003c/em\u003e block after the content.\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003erelated\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  - \u003cspan style=\"color:#ae81ff\"\u003e/blog/hugo/callouts/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  - \u003cspan style=\"color:#ae81ff\"\u003e/til/editorconfig/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003ePaths are language-agnostic. Each language site resolves them against its own pages, so the identical list goes in both the \u003ccode\u003e.en.md\u003c/code\u003e and \u003ccode\u003e.fr.md\u003c/code\u003e front matter — which is the point, because the previous hand-maintained version existed only in English and the French pages silently rendered nothing.\u003c/p\u003e\n\u003cp\u003eTwo things it does deliberately:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eIt renders every entry.\u003c/strong\u003e An earlier version capped the list at three, silently. The post that hit the cap had four, and the hidden fourth turned out to point at a page that did not exist — so the truncation was concealing a broken link.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eIt warns on unresolvable paths\u003c/strong\u003e at build time. Note that a \u003ccode\u003edraft: true\u003c/code\u003e page does not resolve, so pointing at an unpublished draft is reported as missing rather than failing quietly.\u003c/p\u003e\n\u003ch2 id=\"companion--the-top-of-page-pointer\"\u003ecompanion — the top-of-page pointer\u003ca class=\"heading-anchor\" href=\"#companion--the-top-of-page-pointer\" aria-label=\"Link to companion — the top-of-page pointer\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSometimes the reader needs a page \u003cem\u003ebefore\u003c/em\u003e this one, and needs to know why. That is not a list; the sentence is the value.\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{{\u0026lt; companion \u0026#34;/blog/rustdesk/self-hosting/\u0026#34; \u0026gt;}}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eexplains the architecture and server-side tradeoffs behind this install runbook.\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{{\u0026lt; /companion \u0026gt;}}\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eIt renders as a quiet \u003ccode\u003e↩︎\u003c/code\u003e aside above the content: the label, the linked page title, then your sentence. The install runbooks use it to point back at the architecture post, so each runbook stays a runbook instead of re-explaining the design.\u003c/p\u003e\n\u003cp\u003eHugo resolves the path at build time and fails the build on a bad one — a typo is caught immediately rather than shipping as a dead link.\u003c/p\u003e\n\u003ch2 id=\"backlink--the-table-arrow\"\u003ebackLink — the table arrow\u003ca class=\"heading-anchor\" href=\"#backlink--the-table-arrow\" aria-label=\"Link to backLink — the table arrow\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe \u003ccode\u003e/uses\u003c/code\u003e, \u003ccode\u003e/projects\u003c/code\u003e and \u003ccode\u003e/publications\u003c/code\u003e pages are built from YAML, and a table row has no room for prose. A \u003ccode\u003ebackLink\u003c/code\u003e on an entry adds a superscript \u003ccode\u003e↩︎\u003c/code\u003e after the name, linking to the related note:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e- \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003echezmoi\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ebackLink\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e/til/chezmoi/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"the-rule\"\u003eThe rule\u003ca class=\"heading-anchor\" href=\"#the-rule\" aria-label=\"Link to The rule\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eTwo rules keep these from sprawling again.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eCross-references are navigation, not severity.\u003c/strong\u003e They stay visually quiet — no fill, no colour. \u003ca href=\"/en/blog/callouts/\"\u003eCallouts\u003c/a\u003e\n are the loud mechanism, reserved for content that changes what the reader should \u003cem\u003edo\u003c/em\u003e. A companion note dressed as a warning devalues real warnings.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ccode\u003e↩︎\u003c/code\u003e always means \u0026ldquo;related content.\u0026rdquo;\u003c/strong\u003e It is the shared glyph across companion notes and table rows, so the same mark means the same thing everywhere it appears.\u003c/p\u003e\n\u003cp\u003eOne case deliberately stays plain prose: a line pointing at \u003cem\u003eexternal\u003c/em\u003e sources is a citation, not a cross-reference, and belongs in the text where the reader can see what they are clicking.\u003c/p\u003e\n","date_modified":"2026-07-20T00:00:00Z","date_published":"2026-07-20T00:00:00Z","id":"https://BHDicaire.com/en/blog/cross-references/","summary":"Pointing a reader at another page sounds like one problem. It is three, and for a while this site solved it four different ways — a front matter list on one post, hand-typed \u0026ldquo;Companion note:\u0026rdquo; lines on four others, an arrow in the data tables, and ad-hoc \u0026ldquo;See also\u0026rdquo; prose wherever I happened to want one. Nothing enforced consistency, so nothing was consistent.\n","title":"Cross-references","url":"https://BHDicaire.com/en/blog/cross-references/"},{"content_html":"\u003cblockquote\u003e\n    \u003cp\u003e\u003cstrong\u003eNot legal advice.\u003c/strong\u003e I run a personal site out of Montreal; I am not a lawyer. This is a map of the terrain, current as of July 2026, with links to primary sources so you can check my work. Copyright law moved considerably in the first half of 2026 — see the dates on the cases below. If something here matters to your business, pay an actual lawyer.\u003c/p\u003e\n\n  \u003c/blockquote\u003e\u003cp\u003eCopyright infringement is the exercise of one of a rightsholder\u0026rsquo;s exclusive rights — reproduction, distribution, public performance, communication to the public, adaptation — without authorisation and without a statutory exception covering it.\u003c/p\u003e\n\u003cp\u003eThat definition is boring and nearly universal. What is \u003cem\u003enot\u003c/em\u003e universal is everything that follows from it: which unauthorised uses are excused, what your host must do when someone complains, and how much you can lose. Those differ enough between Canada, the United States and the European Union that advice written for one jurisdiction is routinely wrong in the others. Most of the \u0026ldquo;DMCA compliance\u0026rdquo; material on the open web is written for the US and presented as if it were the law everywhere.\u003c/p\u003e\n\u003ch2 id=\"three-jurisdictions-three-different-shapes\"\u003eThree jurisdictions, three different shapes\u003ca class=\"heading-anchor\" href=\"#three-jurisdictions-three-different-shapes\" aria-label=\"Link to Three jurisdictions, three different shapes\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"canada-notice-and-notice\"\u003eCanada: notice and \u003cem\u003enotice\u003c/em\u003e\u003ca class=\"heading-anchor\" href=\"#canada-notice-and-notice\" aria-label=\"Link to Canada: notice and notice\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThis surprises people, so it goes first: \u003cstrong\u003eCanada has no notice-and-takedown regime.\u003c/strong\u003e It has notice-and-\u003cem\u003enotice\u003c/em\u003e, in \u003ca href=\"https://laws-lois.justice.gc.ca/eng/acts/C-42/section-41.26.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ess. 41.25–41.27\u003c/a\u003e\n of the \u003cem\u003eCopyright Act\u003c/em\u003e, in force since 2 January 2015.\u003c/p\u003e\n\u003cp\u003eWhen a rightsholder sends a compliant notice, a Canadian host or ISP must forward it to the subscriber and retain records identifying them for six months. That is the whole obligation. \u003cstrong\u003eNothing in the Act requires removing anything.\u003c/strong\u003e Removal, if it happens, is voluntary or contractual.\u003c/p\u003e\n\u003cp\u003eThe hosting immunity in \u003ca href=\"https://laws-lois.justice.gc.ca/eng/acts/C-42/section-31.1.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003es. 31.1(4)\u003c/a\u003e\n works differently too: a host loses it when it knows of a \u003cstrong\u003ecourt decision\u003c/strong\u003e finding the stored material infringing — not when a rightsholder sends a letter. Receiving a notice does not strip your protection.\u003c/p\u003e\n\u003cp\u003eTwo more Canadian specifics worth carrying around:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eFair dealing is a closed list.\u003c/strong\u003e Unlike US fair use, which opens with \u0026ldquo;purposes such as,\u0026rdquo; Canadian fair dealing only covers eight enumerated purposes: research, private study, education, parody, satire (s. 29), criticism, review (s. 29.1), and news reporting (s. 29.2). Criticism, review and news reporting require attribution. A use that fits none of the eight cannot be fair, however transformative. \u003cem\u003e\u003ca href=\"https://www.canlii.org/en/ca/scc/doc/2004/2004scc13/2004scc13.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCCH Canadian v. Law Society of Upper Canada\u003c/a\u003e\n\u003c/em\u003e, 2004 SCC 13, then applies a six-factor fairness test — and established that fair dealing is a \u003cstrong\u003euser\u0026rsquo;s right\u003c/strong\u003e, not merely a defence.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eStatutory damages are modest for non-commercial infringement\u003c/strong\u003e: $100–$5,000 \u003ca href=\"https://laws-lois.justice.gc.ca/eng/acts/C-42/section-38.1.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ein aggregate\u003c/a\u003e\n — across all works and all proceedings between the same parties — versus $500–$20,000 \u003cem\u003eper work\u003c/em\u003e for commercial infringement. Compare the US ceiling of $150,000 per work for willful infringement and you have the single starkest number in this post.\u003c/p\u003e\n\u003cp\u003eSince 13 December 2018, a notice may not contain a settlement offer or a demand for payment or personal information (s. 41.25(3)). A notice that does is non-compliant and triggers no obligation at all. That amendment exists because copyright trolls spent three years using Canadian ISPs as a delivery service for speculative invoices.\u003c/p\u003e\n\u003ch3 id=\"united-states-the-dmca-bargain\"\u003eUnited States: the DMCA bargain\u003ca class=\"heading-anchor\" href=\"#united-states-the-dmca-bargain\" aria-label=\"Link to United States: the DMCA bargain\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003ca href=\"https://www.law.cornell.edu/uscode/text/17/512\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e17 U.S.C. § 512\u003c/a\u003e\n offers four safe harbours — conduit, caching, storage at a user\u0026rsquo;s direction, and information location tools — and the deal is explicit: comply with the procedure and you get immunity from monetary liability for your users\u0026rsquo; infringement.\u003c/p\u003e\n\u003cp\u003eThe conditions that matter for a website hosting user content:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eA designated agent\u003c/strong\u003e, published on your site \u003cem\u003eand\u003c/em\u003e registered with the Copyright Office through its \u003ca href=\"https://www.copyright.gov/dmca-directory/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eelectronic directory\u003c/a\u003e\n.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eA repeat-infringer policy\u003c/strong\u003e under § 512(i) that you actually enforce, and that you tell users about.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eExpeditious removal\u003c/strong\u003e once you have actual or \u0026ldquo;red flag\u0026rdquo; knowledge of specific infringing material.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNo direct financial benefit\u003c/strong\u003e from infringing activity you have the right and ability to control.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"european-union-no-dmca-two-overlapping-regimes\"\u003eEuropean Union: no DMCA, two overlapping regimes\u003ca class=\"heading-anchor\" href=\"#european-union-no-dmca-two-overlapping-regimes\" aria-label=\"Link to European Union: no DMCA, two overlapping regimes\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe EU has no single equivalent. It has two.\u003c/p\u003e\n\u003cp\u003eThe \u003cstrong\u003eDigital Services Act\u003c/strong\u003e (\u003ca href=\"https://eur-lex.europa.eu/eli/reg/2022/2065/oj/eng\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRegulation (EU) 2022/2065\u003c/a\u003e\n), fully applicable since 17 February 2024, absorbed the old e-Commerce Directive safe harbours — Art 14 hosting immunity is now \u003cstrong\u003eArt 6\u003c/strong\u003e, and the no-general-monitoring rule is \u003cstrong\u003eArt 8\u003c/strong\u003e. Its Art 16 notice-and-action mechanism applies to \u003cem\u003eevery\u003c/em\u003e hosting provider, with no size exemption, and a compliant notice confers actual knowledge for Art 6 purposes.\u003c/p\u003e\n\u003cp\u003eThe \u003cstrong\u003eDSM Copyright Directive\u003c/strong\u003e (\u003ca href=\"https://eur-lex.europa.eu/eli/dir/2019/790/oj/eng\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e2019/790\u003c/a\u003e\n) Art 17 is the aggressive one, but it only bites \u0026ldquo;online content-sharing service providers\u0026rdquo; — services whose main purpose is storing and giving access to a \u003cem\u003elarge amount\u003c/em\u003e of protected work, organised and promoted for profit. Those providers must license, filter, and keep content down. Wikipedia, open-source repositories, marketplaces, B2B cloud and personal cloud storage are expressly outside the definition. \u003cstrong\u003eA blog with comments is not an OCSSP.\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eAnd there is no European fair use. \u003ca href=\"https://eur-lex.europa.eu/eli/dir/2001/29/oj/eng\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eInfoSoc Art 5\u003c/a\u003e\n is an exhaustive menu, most of it optional for member states, which is why freedom of panorama is fine in Germany and a problem in France. The Court of Justice has said plainly that fundamental rights cannot create an exception outside that list (\u003cem\u003ePelham\u003c/em\u003e, \u003cem\u003eFunke Medien\u003c/em\u003e, \u003cem\u003eSpiegel Online\u003c/em\u003e, all 29 July 2019).\u003c/p\u003e\n\u003ch3 id=\"the-comparison-in-one-table\"\u003eThe comparison in one table\u003ca class=\"heading-anchor\" href=\"#the-comparison-in-one-table\" aria-label=\"Link to The comparison in one table\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e\u003c/th\u003e\n          \u003cth\u003eCanada\u003c/th\u003e\n          \u003cth\u003eUnited States\u003c/th\u003e\n          \u003cth\u003eEuropean Union\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eHost\u0026rsquo;s duty on notice\u003c/td\u003e\n          \u003ctd\u003eForward it; retain records. \u003cstrong\u003eNo takedown duty\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eExpeditious removal, to keep § 512 immunity\u003c/td\u003e\n          \u003ctd\u003eAct on it; a valid Art 16 notice = actual knowledge\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eImmunity lost when\u003c/td\u003e\n          \u003ctd\u003eHost knows of a \u003cstrong\u003ecourt decision\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eActual or red-flag knowledge of specific material\u003c/td\u003e\n          \u003ctd\u003eActual knowledge or awareness (Art 6)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFlexible exception\u003c/td\u003e\n          \u003ctd\u003eFair dealing — \u003cstrong\u003eclosed list of 8\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eFair use — open-ended\u003c/td\u003e\n          \u003ctd\u003e\u003cstrong\u003eNo fair use\u003c/strong\u003e; closed list, mostly optional\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eStatutory damages\u003c/td\u003e\n          \u003ctd\u003e$100–$5,000 aggregate (non-commercial)\u003c/td\u003e\n          \u003ctd\u003eUp to $150,000 per work (willful)\u003c/td\u003e\n          \u003ctd\u003eNo EU-wide statutory damages regime\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTerm\u003c/td\u003e\n          \u003ctd\u003eLife + 70 (since 30 Dec 2022)\u003c/td\u003e\n          \u003ctd\u003eLife + 70\u003c/td\u003e\n          \u003ctd\u003eLife + 70\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"safe-harbour-and-whose-job-is-what\"\u003eSafe harbour, and whose job is what\u003ca class=\"heading-anchor\" href=\"#safe-harbour-and-whose-job-is-what\" aria-label=\"Link to Safe harbour, and whose job is what\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u0026ldquo;Safe harbour\u0026rdquo; is not a status you have. It is a \u003cstrong\u003edefence you qualify for by behaving in a specified way\u003c/strong\u003e, and you can lose it through paperwork alone.\u003c/p\u003e\n\u003cp\u003eThe most common unforced error in the US is the one nobody expects: \u003cstrong\u003eyour Copyright Office agent registration expires every three years.\u003c/strong\u003e Let it lapse and you have no § 512(c) protection, with no argument available about knowledge or good conduct — the precondition simply is not met. Put the renewal in a calendar, not in your memory. The old paper directory has been dead since the end of 2017.\u003c/p\u003e\n\u003cp\u003eThe responsibilities split roughly like this:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eRightsholders\u003c/strong\u003e must send notices that actually comply — identifying the work, identifying the material precisely enough to locate it, asserting good faith under penalty of perjury. In the US they must also \u003cem\u003econsider fair use before sending\u003c/em\u003e, per \u003cem\u003e\u003ca href=\"https://www.eff.org/cases/lenz-v-universal\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eLenz v. Universal\u003c/a\u003e\n\u003c/em\u003e (9th Cir. 2016). Be aware that this is a weak constraint: the standard is subjective, so a sender with an unreasonable but sincere belief is not liable under § 512(f). Don\u0026rsquo;t plan around § 512(f) as a remedy.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eIntermediaries\u003c/strong\u003e run the procedure: receive, assess, act, tell both sides what happened, and honour the counter-notice clock. Under § 512(g) the material goes back up between \u003cstrong\u003e10 and 14 business days\u003c/strong\u003e after a counter-notice unless the complainant files suit. Following that timeline is what protects you from your own user suing you for taking their content down.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eUsers\u003c/strong\u003e who file a counter-notice should understand what they are signing: § 512(g)(3) requires consenting to the jurisdiction of a US federal district court. For a Canadian, contesting a takedown means opting into US litigation. That asymmetry is the practical reason many valid counter-notices never get filed.\u003c/p\u003e\n\u003ch3 id=\"the-monitoring-question-which-almost-everyone-gets-wrong\"\u003eThe monitoring question, which almost everyone gets wrong\u003ca class=\"heading-anchor\" href=\"#the-monitoring-question-which-almost-everyone-gets-wrong\" aria-label=\"Link to The monitoring question, which almost everyone gets wrong\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eGuidance floating around the web — including the page that prompted this post — advises avoiding actual knowledge of infringing material \u0026ldquo;such as implementing content filtering or monitoring tools.\u0026rdquo;\u003c/p\u003e\n\u003cp\u003eThat is confused, and following it could hurt you. Here is the actual rule:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e§ 512(m) says there is no duty to monitor\u003c/strong\u003e, categorically. You cannot lose a safe harbour for failing to look. Voluntary filtering does not forfeit it either — Veoh kept its harbour while running hash filtering and Audible Magic (\u003cem\u003eUMG v. Shelter Capital\u003c/em\u003e, 9th Cir. 2013), and the EU codified the same idea as the \u0026ldquo;Good Samaritan\u0026rdquo; rule in DSA Art 7.\u003c/p\u003e\n\u003cp\u003eBut filtering does not help you \u003cem\u003eavoid\u003c/em\u003e knowledge. It \u003cstrong\u003emanufactures\u003c/strong\u003e knowledge. Every mechanism that strips the harbour runs through \u003cem\u003especific\u003c/em\u003e knowledge of \u003cem\u003especific\u003c/em\u003e material, so the moment your filter surfaces an infringing item, the clock starts. The rule reduces to one line:\u003c/p\u003e\n\u003cblockquote\u003e\n    \u003cp\u003e\u003cstrong\u003eFilter only if you will act on what you find.\u003c/strong\u003e Building detection and ignoring its output is worse than never building it.\u003c/p\u003e\n\n  \u003c/blockquote\u003e\u003cp\u003eGeneral awareness that infringement happens on your service is not disqualifying — that is the central holding of \u003cem\u003e\u003ca href=\"https://cyber.harvard.edu/people/tfisher/cx/2012_Viacom.pdf\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eViacom v. YouTube\u003c/a\u003e\n\u003c/em\u003e (2d Cir. 2012), and it is the load-bearing protection for anyone hosting user content.\u003c/p\u003e\n\u003ch3 id=\"the-other-thing-everyone-gets-wrong-cda-230-does-not-cover-copyright\"\u003eThe other thing everyone gets wrong: CDA 230 does not cover copyright\u003ca class=\"heading-anchor\" href=\"#the-other-thing-everyone-gets-wrong-cda-230-does-not-cover-copyright\" aria-label=\"Link to The other thing everyone gets wrong: CDA 230 does not cover copyright\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe same guidance blends § 512 together with advice about \u0026ldquo;defamatory, obscene, or otherwise objectionable\u0026rdquo; content. Those are two different statutes, and the distinction is not academic.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.law.cornell.edu/uscode/text/47/230\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e47 U.S.C. § 230\u003c/a\u003e\n shields you from liability for third-party content — defamation, most state-law torts — with no registration, no agent, no procedure. But \u003cstrong\u003e§ 230(e)(2) expressly carves out intellectual property\u003c/strong\u003e. For copyright, § 230 gives you exactly nothing. The DMCA procedure is the only statutory shield, which is why the mechanics are not optional for a site with user content.\u003c/p\u003e\n\u003ch3 id=\"two-2026-decisions-worth-knowing-about\"\u003eTwo 2026 decisions worth knowing about\u003ca class=\"heading-anchor\" href=\"#two-2026-decisions-worth-knowing-about\" aria-label=\"Link to Two 2026 decisions worth knowing about\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eBoth post-date most of the compliance guidance you will find by searching, including the pages that prompted this post.\u003c/p\u003e\n\u003cp\u003eIn \u003cem\u003e\u003ca href=\"https://www.supremecourt.gov/opinions/25pdf/24-171_bq7d.pdf\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCox Communications v. Sony Music\u003c/a\u003e\n\u003c/em\u003e (decided 25 March 2026), a unanimous Supreme Court reversed a roughly $1B judgment and rejected mere knowledge as a basis for contributory infringement. Liability now requires \u003cstrong\u003eintent\u003c/strong\u003e — shown through inducement, or a service tailored to infringement. \u0026ldquo;A company is not liable as a copyright infringer for merely providing a service to the general public with knowledge that it will be used by some to infringe.\u0026rdquo; Safe harbour still matters as the cheaper, earlier exit, but losing it is no longer the catastrophe it was.\u003c/p\u003e\n\u003cp\u003eIn the other direction, the Court of Justice in \u003ca href=\"https://curia.europa.eu/site/upload/docs/application/pdf/2026-06/cp260087en.pdf\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eC-188/24 and C-190/24\u003c/a\u003e\n (16 June 2026) held that an operator cannot claim hosting immunity over information it \u003cstrong\u003econtrols\u003c/strong\u003e — including where it \u0026ldquo;determines, by means of an algorithm, under what conditions, how and in which order of priority that information is or is not rebroadcast.\u0026rdquo; Knowledge and control are cumulative tests. How far this reaches is untested, but if you rank or curate user comments algorithmically rather than chronologically, it is now a live question. Chronological is the conservative choice.\u003c/p\u003e\n\u003ch2 id=\"so-what-should-a-normal-website-actually-do\"\u003eSo what should a normal website actually do?\u003ca class=\"heading-anchor\" href=\"#so-what-should-a-normal-website-actually-do\" aria-label=\"Link to So what should a normal website actually do?\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eHere is the honest answer for most sites: \u003cstrong\u003efar less than the compliance content implies, because you are not Reddit.\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eA static site publishing your own writing stores no third-party content. There is no safe harbour question because there is no intermediary role to protect. Your realistic copyright exposure runs the other way — it is about the images, snippets and quotations \u003cem\u003eyou\u003c/em\u003e publish. Licence your own material clearly, keep attribution honest, and stay inside fair dealing.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eRisk arrives with a text box.\u003c/strong\u003e The moment you add comments, a forum, a wiki, file uploads, or a public Slack or Discord, you are storing content at someone else\u0026rsquo;s direction. That is the definition of hosting, and the obligations attach. Note the nuance for chat platforms: if your community lives in Slack or Discord, \u003cem\u003ethey\u003c/em\u003e are the host and \u003cem\u003etheir\u003c/em\u003e process governs — but you are the operator, and you own the moderation and repeat-infringer decisions inside your space.\u003c/p\u003e\n\u003cp\u003eIf you do host user content, this is the corrected checklist:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003ePublish a takedown contact.\u003c/strong\u003e An email address on a legal page is enough for a small site. If you are US-hosted with user content, register a designated agent with the Copyright Office — and diarise the three-year renewal.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eWrite down your notice-and-takedown procedure\u003c/strong\u003e, and follow it consistently. Consistency is most of what \u0026ldquo;reasonably implemented\u0026rdquo; means.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eHave a repeat-infringer policy and actually enforce it.\u003c/strong\u003e Cox lost its safe harbour for maintaining a policy it never applied; Motherless kept its harbour with no written policy at all, because one human was demonstrably making real termination decisions. Enforcement beats paperwork.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eDon\u0026rsquo;t take direct financial benefit\u003c/strong\u003e from infringing activity you control.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eMonitor only if you will act.\u003c/strong\u003e See above. This is the item most guidance gets backwards.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eDon\u0026rsquo;t rely on CDA 230 for copyright.\u003c/strong\u003e It does not apply.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eTell users what you did and why.\u003c/strong\u003e Required in the EU by DSA Art 17 as a statement of reasons; good practice everywhere, and it is what makes a repeat-infringer policy defensible later.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRead your host\u0026rsquo;s terms.\u003c/strong\u003e For a Canadian operator this is the practical governing document. Your host wants its own US safe harbour, so it pushes compliance down to you by contract and will disable content to protect itself. The rightsholder complains to your host, not to you — and your Canadian fair dealing rights never get adjudicated anywhere in that loop. The same is true at every US-touching layer: CDN, registrar, DNS, payments.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThat last point deserves the final word. If you operate from Canada, the law that most often decides what happens to your content is not the \u003cem\u003eCopyright Act\u003c/em\u003e. It is your hosting agreement.\u003c/p\u003e\n","date_modified":"2026-07-20T00:00:00Z","date_published":"2026-07-20T00:00:00Z","id":"https://BHDicaire.com/en/blog/copyright-infringement/","summary":" Not legal advice. I run a personal site out of Montreal; I am not a lawyer. This is a map of the terrain, current as of July 2026, with links to primary sources so you can check my work. Copyright law moved considerably in the first half of 2026 — see the dates on the cases below. If something here matters to your business, pay an actual lawyer.\n","title":"Copyright Infringement, Safe Harbour, and What Your Website Actually Has to Do","url":"https://BHDicaire.com/en/blog/copyright-infringement/"},{"content_html":"\u003cp\u003eHave a question, a project, or something worth sharing? Send a note below, or reach me on the platforms listed here.\u003c/p\u003e\n","date_modified":"2026-07-20T00:00:00Z","date_published":"2026-07-20T00:00:00Z","id":"https://BHDicaire.com/en/contact/","summary":"Have a question, a project, or something worth sharing? Send a note below, or reach me on the platforms listed here.\n","title":"Contact","url":"https://BHDicaire.com/en/contact/"},{"content_html":"\u003cp\u003eCallouts — admonitions, alerts, whatever you call them — are blockquotes with a colour, an icon and a label, used to mark content that a skimming reader should not miss.\u003c/p\u003e\n\u003cp\u003eThe important decision here was \u003cstrong\u003enot inventing a syntax\u003c/strong\u003e. This site renders \u003ca href=\"https://github.blog/changelog/2023-12-14-new-markdown-extension-alerts-provide-distinctive-styling-for-significant-content/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGitHub\u0026rsquo;s alert extension\u003c/a\u003e\n, which is the same syntax Bear uses. A note written in Bear pastes into a post and renders correctly, with nothing to translate. That is the whole point: the notes and the published site share one format.\u003c/p\u003e\n\u003ch2 id=\"the-five-standard-types\"\u003eThe five standard types\u003ca class=\"heading-anchor\" href=\"#the-five-standard-types\" aria-label=\"Link to The five standard types\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003e[!NOTE]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003eUseful information that users should know, even when skimming content.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003e[!TIP]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003eHelpful advice for doing things better or more easily.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003e[!IMPORTANT]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003eKey information users need to know to achieve their goal.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003e[!WARNING]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003eUrgent info that needs immediate user attention to avoid problems.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003e[!CAUTION]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026gt; Advises about risks or negative outcomes of certain actions.\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eWhich renders as:\u003c/p\u003e\n\u003c!-- markdownlint-disable MD028 --\u003e\n\u003cdiv class=\"not-prose my-5 rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-900/20 p-4\"\u003e\n  \u003cdiv class=\"flex gap-3\"\u003e\n    \u003csvg class=\"w-5 h-5 text-blue-500 dark:text-blue-400 shrink-0 mt-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/\u003e\n    \u003c/svg\u003e\n    \u003cdiv class=\"flex-1 min-w-0\"\u003e\n      \u003cp class=\"text-sm font-semibold text-blue-800 dark:text-blue-300 mb-1\"\u003eNote\u003c/p\u003e\n      \u003cdiv class=\"callout-body text-sm text-blue-700 dark:text-blue-300 [\u0026\u003ep]:m-0 [\u0026\u003ep+p]:mt-2 [\u0026\u003ecode]:bg-black/10 [\u0026\u003ecode]:px-1 [\u0026\u003ecode]:rounded\"\u003e\n        \u003cp\u003eUseful information that users should know, even when skimming content.\u003c/p\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"not-prose my-5 rounded-lg border border-green-200 dark:border-green-800 bg-green-50 dark:bg-green-900/20 p-4\"\u003e\n  \u003cdiv class=\"flex gap-3\"\u003e\n    \u003csvg class=\"w-5 h-5 text-green-500 dark:text-green-400 shrink-0 mt-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"/\u003e\n    \u003c/svg\u003e\n    \u003cdiv class=\"flex-1 min-w-0\"\u003e\n      \u003cp class=\"text-sm font-semibold text-green-800 dark:text-green-300 mb-1\"\u003eTip\u003c/p\u003e\n      \u003cdiv class=\"callout-body text-sm text-green-700 dark:text-green-300 [\u0026\u003ep]:m-0 [\u0026\u003ep+p]:mt-2 [\u0026\u003ecode]:bg-black/10 [\u0026\u003ecode]:px-1 [\u0026\u003ecode]:rounded\"\u003e\n        \u003cp\u003eHelpful advice for doing things better or more easily.\u003c/p\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"not-prose my-5 rounded-lg border border-purple-200 dark:border-purple-800 bg-purple-50 dark:bg-purple-900/20 p-4\"\u003e\n  \u003cdiv class=\"flex gap-3\"\u003e\n    \u003csvg class=\"w-5 h-5 text-purple-500 dark:text-purple-400 shrink-0 mt-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.9 9.9 0 01-4-.8L3 20l1.2-3.6A7.9 7.9 0 013 12c0-4.418 4.03-8 9-8s9 3.582 9 8z\"/\u003e\n    \u003c/svg\u003e\n    \u003cdiv class=\"flex-1 min-w-0\"\u003e\n      \u003cp class=\"text-sm font-semibold text-purple-800 dark:text-purple-300 mb-1\"\u003eImportant\u003c/p\u003e\n      \u003cdiv class=\"callout-body text-sm text-purple-700 dark:text-purple-300 [\u0026\u003ep]:m-0 [\u0026\u003ep+p]:mt-2 [\u0026\u003ecode]:bg-black/10 [\u0026\u003ecode]:px-1 [\u0026\u003ecode]:rounded\"\u003e\n        \u003cp\u003eKey information users need to know to achieve their goal.\u003c/p\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"not-prose my-5 rounded-lg border border-amber-200 dark:border-amber-800 bg-amber-50 dark:bg-amber-900/20 p-4\"\u003e\n  \u003cdiv class=\"flex gap-3\"\u003e\n    \u003csvg class=\"w-5 h-5 text-amber-500 dark:text-amber-400 shrink-0 mt-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"/\u003e\n    \u003c/svg\u003e\n    \u003cdiv class=\"flex-1 min-w-0\"\u003e\n      \u003cp class=\"text-sm font-semibold text-amber-800 dark:text-amber-300 mb-1\"\u003eWarning\u003c/p\u003e\n      \u003cdiv class=\"callout-body text-sm text-amber-700 dark:text-amber-300 [\u0026\u003ep]:m-0 [\u0026\u003ep+p]:mt-2 [\u0026\u003ecode]:bg-black/10 [\u0026\u003ecode]:px-1 [\u0026\u003ecode]:rounded\"\u003e\n        \u003cp\u003eUrgent info that needs immediate user attention to avoid problems.\u003c/p\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"not-prose my-5 rounded-lg border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-900/20 p-4\"\u003e\n  \u003cdiv class=\"flex gap-3\"\u003e\n    \u003csvg class=\"w-5 h-5 text-red-500 dark:text-red-400 shrink-0 mt-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 17.25h.007v.008H12v-.008z\"/\u003e\n    \u003c/svg\u003e\n    \u003cdiv class=\"flex-1 min-w-0\"\u003e\n      \u003cp class=\"text-sm font-semibold text-red-800 dark:text-red-300 mb-1\"\u003eCaution\u003c/p\u003e\n      \u003cdiv class=\"callout-body text-sm text-red-700 dark:text-red-300 [\u0026\u003ep]:m-0 [\u0026\u003ep+p]:mt-2 [\u0026\u003ecode]:bg-black/10 [\u0026\u003ecode]:px-1 [\u0026\u003ecode]:rounded\"\u003e\n        \u003cp\u003eAdvises about risks or negative outcomes of certain actions.\u003c/p\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-enable MD028 --\u003e\n\u003cp\u003eThe distinction that actually matters when writing is \u003cstrong\u003ewarning versus caution\u003c/strong\u003e. A warning is about the \u003cem\u003ereader\u0026rsquo;s attention\u003c/em\u003e — something will go wrong if you skim past this. A caution is about the \u003cem\u003econsequences of an action\u003c/em\u003e — this step can destroy data. If nothing bad happens by ignoring it, it is a note.\u003c/p\u003e\n\u003cp\u003eA plain blockquote stays a plain blockquote. Use one for actual quotation.\u003c/p\u003e\n\u003ch2 id=\"custom-titles\"\u003eCustom titles\u003ca class=\"heading-anchor\" href=\"#custom-titles\" aria-label=\"Link to Custom titles\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eText after the type replaces the default label:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003e[!IMPORTANT] Registration expires every three years\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026gt; Diarise the renewal.\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cdiv class=\"not-prose my-5 rounded-lg border border-purple-200 dark:border-purple-800 bg-purple-50 dark:bg-purple-900/20 p-4\"\u003e\n  \u003cdiv class=\"flex gap-3\"\u003e\n    \u003csvg class=\"w-5 h-5 text-purple-500 dark:text-purple-400 shrink-0 mt-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.9 9.9 0 01-4-.8L3 20l1.2-3.6A7.9 7.9 0 013 12c0-4.418 4.03-8 9-8s9 3.582 9 8z\"/\u003e\n    \u003c/svg\u003e\n    \u003cdiv class=\"flex-1 min-w-0\"\u003e\n      \u003cp class=\"text-sm font-semibold text-purple-800 dark:text-purple-300 mb-1\"\u003eRegistration expires every three years\u003c/p\u003e\n      \u003cdiv class=\"callout-body text-sm text-purple-700 dark:text-purple-300 [\u0026\u003ep]:m-0 [\u0026\u003ep+p]:mt-2 [\u0026\u003ecode]:bg-black/10 [\u0026\u003ecode]:px-1 [\u0026\u003ecode]:rounded\"\u003e\n        \u003cp\u003eDiarise the renewal.\u003c/p\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTitles are localised when you don\u0026rsquo;t override them: a \u003ccode\u003e[!TIP]\u003c/code\u003e is \u003cem\u003eTip\u003c/em\u003e in English and \u003cem\u003eConseil\u003c/em\u003e in French, so the same file works in both languages without hardcoding.\u003c/p\u003e\n\u003ch2 id=\"rich-content\"\u003eRich content\u003ca class=\"heading-anchor\" href=\"#rich-content\" aria-label=\"Link to Rich content\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eCallouts take normal Markdown — lists, inline code, emphasis, links:\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003e[!NOTE]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003eThree things worth knowing:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"font-style:italic\"\u003e\u0026gt; - Lists work\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e\u0026gt; \u003c/span\u003e\u003cspan style=\"font-style:italic\"\u003e- So does `inline code`\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026gt; - And **emphasis**\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cdiv class=\"not-prose my-5 rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-900/20 p-4\"\u003e\n  \u003cdiv class=\"flex gap-3\"\u003e\n    \u003csvg class=\"w-5 h-5 text-blue-500 dark:text-blue-400 shrink-0 mt-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/\u003e\n    \u003c/svg\u003e\n    \u003cdiv class=\"flex-1 min-w-0\"\u003e\n      \u003cp class=\"text-sm font-semibold text-blue-800 dark:text-blue-300 mb-1\"\u003eNote\u003c/p\u003e\n      \u003cdiv class=\"callout-body text-sm text-blue-700 dark:text-blue-300 [\u0026\u003ep]:m-0 [\u0026\u003ep+p]:mt-2 [\u0026\u003ecode]:bg-black/10 [\u0026\u003ecode]:px-1 [\u0026\u003ecode]:rounded\"\u003e\n        \u003cp\u003eThree things worth knowing:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eLists work\u003c/li\u003e\n\u003cli\u003eSo does \u003ccode\u003einline code\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eAnd \u003cstrong\u003eemphasis\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003ch2 id=\"the-sixth-type-archive\"\u003eThe sixth type: archive\u003ca class=\"heading-anchor\" href=\"#the-sixth-type-archive\" aria-label=\"Link to The sixth type: archive\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003earchive\u003c/code\u003e is this site\u0026rsquo;s own, with no GitHub equivalent, so it stays a shortcode. It marks a page kept for the record rather than maintained — most of the macOS release pages carry one.\u003c/p\u003e\n\u003cdiv class=\"code-block not-prose\"\u003e\n  \u003cbutton class=\"copy-btn-inline code-block-copy\" type=\"button\" aria-label=\"Copy\" title=\"Copy\" data-copy-label=\"Copy\" data-copied-label=\"Copied\"\u003e\n    \u003csvg class=\"code-block-copy-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\n      \u003cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/\u003e\n    \u003c/svg\u003e\n    \u003cspan class=\"sr-only\"\u003eCopy\u003c/span\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"code-block-body\"\u003e\n    \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{{\u0026lt; callout type=\u0026#34;archive\u0026#34; \u0026gt;}}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eThis page documents a release that Apple no longer supports.\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{{\u0026lt; /callout \u0026gt;}}\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThe shortcode still accepts every type, and \u003ccode\u003edanger\u003c/code\u003e is kept as an alias for \u003ccode\u003ecaution\u003c/code\u003e so older posts keep working. For anything except \u003ccode\u003earchive\u003c/code\u003e, prefer the Markdown syntax — it survives being copied out of the site.\u003c/p\u003e\n\u003ch2 id=\"how-it-works\"\u003eHow it works\u003ca class=\"heading-anchor\" href=\"#how-it-works\" aria-label=\"Link to How it works\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eA \u003ca href=\"https://gohugo.io/render-hooks/blockquotes/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eblockquote render hook\u003c/a\u003e\n at \u003ccode\u003elayouts/_default/_markup/render-blockquote.html\u003c/code\u003e inspects each blockquote, and hands anything carrying an alert marker to \u003ccode\u003elayouts/partials/callout.html\u003c/code\u003e. The shortcode calls that same partial, so the two entry points cannot drift into rendering differently.\u003c/p\u003e\n\u003cp\u003eCallouts signal \u003cstrong\u003eseverity\u003c/strong\u003e. They are deliberately not used for pointing at other pages — that is a separate, quieter mechanism, covered in \u003ca href=\"/en/blog/cross-references/\"\u003ecross-references\u003c/a\u003e\n. A companion note styled like a warning teaches readers to ignore warnings.\u003c/p\u003e\n","date_modified":"2026-07-20T00:00:00Z","date_published":"2026-07-20T00:00:00Z","id":"https://BHDicaire.com/en/blog/callouts/","summary":"Callouts — admonitions, alerts, whatever you call them — are blockquotes with a colour, an icon and a label, used to mark content that a skimming reader should not miss.\n","title":"Callouts","url":"https://BHDicaire.com/en/blog/callouts/"},{"content_html":"\u003cp\u003eLocal archive of Apple’s official Technical Specifications page from Cheetah to Golden Gate. For the story behind the names, see \u003ca href=\"/en/blog/macos-history/\"\u003emacOS History\u003c/a\u003e\n.\u003c/p\u003e\n","date_modified":"2026-07-17T00:00:00Z","date_published":"2026-07-17T00:00:00Z","id":"https://BHDicaire.com/en/blog/macos-technical-specifications/","summary":"Local archive of Apple’s official Technical Specifications page from Cheetah to Golden Gate. For the story behind the names, see macOS History .\n","title":"macOS Technical Specifications","url":"https://BHDicaire.com/en/blog/macos-technical-specifications/"},{"content_html":"\u003cp\u003eTwenty-five years separate Cheetah from Golden Gate. Along the way Apple\u0026rsquo;s desktop operating system changed its name three times, switched processor architectures twice, and reset its version number from 10 to 11. This is that history told in four overlapping eras. For the release-by-release details — code names, ship dates, architectures, and archived specifications — see \u003ca href=\"/en/blog/macos-technical-specifications/\"\u003emacOS Technical Specifications\u003c/a\u003e\n.\u003c/p\u003e\n\u003ch2 id=\"the-big-cats-era\"\u003eThe Big Cats Era\u003ca class=\"heading-anchor\" href=\"#the-big-cats-era\" aria-label=\"Link to The Big Cats Era\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"/images/blog/macos-1.png\" alt=\"The Big Cats Era — Mac OS X 10.0 to 10.8\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eMac OS X 10.0 to 10.8.\u003c/strong\u003e The first decade of Mac OS X was named after big cats, from Cheetah (2001) through Mountain Lion (2012): Cheetah, Puma, Jaguar, Panther, Tiger, Leopard, Snow Leopard, Lion, and Mountain Lion. This era carried the platform from its PowerPC roots through the Intel transition — Tiger shipped the first Intel Macs with universal binaries, and Snow Leopard dropped PowerPC support entirely.\u003c/p\u003e\n\u003ch2 id=\"the-california-landmarks-era\"\u003eThe California Landmarks Era\u003ca class=\"heading-anchor\" href=\"#the-california-landmarks-era\" aria-label=\"Link to The California Landmarks Era\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"/images/blog/macos-2.png\" alt=\"The California Landmarks Era — OS X 10.9 to 10.15\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eOS X 10.9 to 10.15.\u003c/strong\u003e Starting with Mavericks in 2013, Apple retired the big cats and began naming releases after California landmarks: Mavericks, Yosemite, El Capitan, Sierra, High Sierra, Mojave, and Catalina. Upgrades became free and shipped on a yearly cadence, and by Catalina the system had dropped support for 32-bit applications.\u003c/p\u003e\n\u003ch2 id=\"the-apple-silicon-transition-era\"\u003eThe Apple Silicon Transition Era\u003ca class=\"heading-anchor\" href=\"#the-apple-silicon-transition-era\" aria-label=\"Link to The Apple Silicon Transition Era\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"/images/blog/macos-3.png\" alt=\"The Apple Silicon Transition Era — macOS 11 to 26\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003emacOS 11 to 26.\u003c/strong\u003e Big Sur broke a two-decade convention by moving the version number from 10 to 11, marking the shift to Apple Silicon. Big Sur, Monterey, Ventura, Sonoma, Sequoia, and Tahoe kept the California-landmark names while the Mac moved from Intel to Apple\u0026rsquo;s own M-series chips, bridged by Rosetta 2 and Universal 2 binaries. Tahoe (26) is the last release to support Intel Macs.\u003c/p\u003e\n\u003ch2 id=\"the-ai-era\"\u003eThe AI Era\u003ca class=\"heading-anchor\" href=\"#the-ai-era\" aria-label=\"Link to The AI Era\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"/images/blog/macos-4.png\" alt=\"The AI Era — macOS 15 to 27\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003emacOS 15 to 27.\u003c/strong\u003e Overlapping the tail of the Apple Silicon transition, the most recent era is defined by on-device intelligence. Sequoia introduced Apple Intelligence, Tahoe brought the Liquid Glass redesign, and Golden Gate (27) continues the line. These releases lean on the Neural Engine and Apple Silicon to fold generative features throughout the system.\u003c/p\u003e\n","date_modified":"2026-07-17T00:00:00Z","date_published":"2026-07-17T00:00:00Z","id":"https://BHDicaire.com/en/blog/macos-history/","summary":"Twenty-five years separate Cheetah from Golden Gate. Along the way Apple\u0026rsquo;s desktop operating system changed its name three times, switched processor architectures twice, and reset its version number from 10 to 11. This is that history told in four overlapping eras. For the release-by-release details — code names, ship dates, architectures, and archived specifications — see macOS Technical Specifications .\n","title":"macOS History","url":"https://BHDicaire.com/en/blog/macos-history/"},{"content_html":"\u003cp\u003eThis is a personal digital sandbox website operated by Benoît H. Dicaire out of Montreal, Canada. It serves as a living archive of thoughts, technical experiments, and deep dives into security, privacy, and technology.\u003c/p\u003e\n\u003cp\u003eBy accessing or using this website, you agree to comply with and be bound by the following Terms \u0026amp; Conditions. If you do not agree to use the site lawfully, respectfully, and at your own risk, please do not use this site.\u003c/p\u003e\n\u003ch2 id=\"informational-content--professional-disclaimer\"\u003eInformational Content \u0026amp; Professional Disclaimer\u003ca class=\"heading-anchor\" href=\"#informational-content--professional-disclaimer\" aria-label=\"Link to Informational Content \u0026amp; Professional Disclaimer\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe writing, notes, references, diagrams, and examples published on this site are provided strictly for general informational, educational, and experimental purposes.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eNo Advice:\u003c/strong\u003e Nothing on this site constitutes formal information security advice tailored to your environment, technical implementation, incident response direction, or legal privacy advice.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNo Reliance:\u003c/strong\u003e Do not rely on site content as the only basis for decisions that affect legal obligations, production systems, investigations, safety, finances, or compliance.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNo Relationship:\u003c/strong\u003e Consuming this content, testing these configurations, or reaching out via email does not establish a consultant-client, professional, or fiduciary relationship of any kind.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"acceptable-use\"\u003eAcceptable Use\u003ca class=\"heading-anchor\" href=\"#acceptable-use\" aria-label=\"Link to Acceptable Use\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eYou agree to use this site responsibly. Do not use the site to:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eattempt unauthorized access;\u003c/li\u003e\n\u003cli\u003edisrupt availability;\u003c/li\u003e\n\u003cli\u003escrape in a way that harms service reliability;\u003c/li\u003e\n\u003cli\u003esubmit malicious content;\u003c/li\u003e\n\u003cli\u003eimpersonate another person; or\u003c/li\u003e\n\u003cli\u003eviolate applicable law.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSecurity research regarding this domain or its public infrastructure should follow the guidelines on our \u003ca href=\"/en/legal/responsible-disclosure/\"\u003eResponsible disclosure\u003c/a\u003e\n page.\u003c/p\u003e\n\u003ch2 id=\"intellectual-property--copyright\"\u003eIntellectual Property \u0026amp; Copyright\u003ca class=\"heading-anchor\" href=\"#intellectual-property--copyright\" aria-label=\"Link to Intellectual Property \u0026amp; Copyright\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eUnless a page or asset says otherwise, the text, diagrams, images, and original materials on this site are owned by Benoît H. Dicaire and are protected by Canadian and international copyright laws.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eShort quotations with clear attribution are welcome.\u003c/li\u003e\n\u003cli\u003eFor broader reuse, republication, translations, commercial use, or full reuse of diagrams, please contact me first.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"open-source--experimental-code\"\u003eOpen-Source \u0026amp; Experimental Code\u003ca class=\"heading-anchor\" href=\"#open-source--experimental-code\" aria-label=\"Link to Open-Source \u0026amp; Experimental Code\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThis sandbox frequently references or links to code repositories, configurations, and community projects across various GitHub organizations including personal profiles, corporate entities, and community contributions like \u003ca href=\"https://vanityurls.link\" target=\"_blank\" rel=\"noopener noreferrer\"\u003evanityURLs\u003c/a\u003e\n.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eCode, scripts, or templates distributed via public repositories are governed strictly by the \u003cstrong\u003eopen-source license accompanying that specific project\u003c/strong\u003e (e.g., MIT, Apache 2.0, GPL).\u003c/li\u003e\n\u003cli\u003eAny code snippet shared directly on this site without an explicit license is provided \u0026ldquo;as-is\u0026rdquo; as an example for educational reference only, without warranty of any kind.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"external-links\"\u003eExternal Links\u003ca class=\"heading-anchor\" href=\"#external-links\" aria-label=\"Link to External Links\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eLinks to third-party websites are provided for context and convenience. I do not control those sites and am not responsible for their content, security posture, availability, or privacy practices. Browse safely!\u003c/p\u003e\n\u003ch2 id=\"limitation-of-liability--sandbox-disclaimer\"\u003eLimitation of Liability \u0026amp; Sandbox Disclaimer\u003ca class=\"heading-anchor\" href=\"#limitation-of-liability--sandbox-disclaimer\" aria-label=\"Link to Limitation of Liability \u0026amp; Sandbox Disclaimer\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThis website and its contents are provided entirely on an \u0026ldquo;as-is\u0026rdquo; and \u0026ldquo;as-available\u0026rdquo; basis. I do not guarantee that the site will be error-free, uninterrupted, complete, current, or suitable for any specific purpose.\u003c/p\u003e\n\u003cblockquote\u003e\n    \u003cp\u003e\u003cstrong\u003eExperimental Risk Warning:\u003c/strong\u003e This is a sandbox environment. The setups, configurations, and scripts discussed here may be experimental, highly specific to a moment in time, or intentionally risky for research purposes.\u003c/p\u003e\n\n  \u003c/blockquote\u003e\u003cp\u003eTo the maximum extent allowed by applicable law, Benoît H. Dicaire shall not be liable for any losses or direct, indirect, incidental, consequential, or punitive damages arising out of your access to, use of, reliance on, or inability to access this website or any open-source code referenced herein. You assume \u003cstrong\u003e100% full responsibility\u003c/strong\u003e for any technical deployments, environment changes, data loss, or security posture shifts you execute based on information found here.\u003c/p\u003e\n\u003ch2 id=\"governing-law\"\u003eGoverning Law\u003ca class=\"heading-anchor\" href=\"#governing-law\" aria-label=\"Link to Governing Law\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThese Terms \u0026amp; Conditions are governed by and construed in accordance with the laws of the \u003cstrong\u003eProvince of Quebec and the federal laws of Canada\u003c/strong\u003e applicable therein. Any disputes arising out of or in connection with the use of this website shall be subject to the exclusive jurisdiction of the courts located in the district of Montreal, Quebec.\u003c/p\u003e\n\u003ch2 id=\"changes\"\u003eChanges\u003ca class=\"heading-anchor\" href=\"#changes\" aria-label=\"Link to Changes\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eI may update these terms as the site changes. The \u003ccode\u003elastmod\u003c/code\u003e date on this page shows when they were last updated.\u003c/p\u003e\n\u003ch2 id=\"contact-information\"\u003eContact Information\u003ca class=\"heading-anchor\" href=\"#contact-information\" aria-label=\"Link to Contact Information\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eIf you have questions regarding these terms, you can reach out through the \u003ca href=\"/en/contact/\"\u003econtact page\u003c/a\u003e\n.\u003c/p\u003e\n","date_modified":"2026-07-11T00:00:00Z","date_published":"2026-07-11T00:00:00Z","id":"https://BHDicaire.com/en/legal/terms/","summary":"This is a personal digital sandbox website operated by Benoît H. Dicaire out of Montreal, Canada. It serves as a living archive of thoughts, technical experiments, and deep dives into security, privacy, and technology.\n","title":"Terms \u0026 Conditions","url":"https://BHDicaire.com/en/legal/terms/"}],"title":"Benoît H. Dicaire","version":"https://jsonfeed.org/version/1.1"}