# Authentic Engineer > Writing down knowledge through sharing Per-page markdown is available at //llms.txt and an index at /llms.txt. --- title: AI Can’t Invent New Methodologies url: https://supanadit.web.id/ai-cant-invent-new-methodologies/ type: post published: 2026-11-01T20:25:06+07:00 updated: 2026-11-02T16:40:08+07:00 There is a dangerous moment in modern development: the moment you see a block of AI-generated code that looks absolutely perfect. It’s clean, it’s indented, and it runs without a single error. But beneath the surface, it’s often conceptually dead. It isn't solving your problem; it's just echoing a pattern it saw a million times in its training data. This is the fundamental limit of LLMs: they are world-class Librarians, but they are not Architects. A librarian can find any book in the building and summarize it perfectly, but they cannot write a new theory of physics. Similarly, AI can synthesize every existing methodology, but it cannot invent a new one. It can't imagine a solution that hasn't already been published. Take the PHP 8.5 Pipe Operator—AI can tell you how the syntax works, but it cannot envision the new architectural patterns that feature unlocks until a human engineer does it first. This is why AI cannot replace the top-tier engineer. The difference lies in the gap between *implementation* and *innovation*. An AI can implement a feature perfectly if the pattern already exists in its library. But innovation is the act of looking at a new tool—like a language update—and realizing it allows for a completely different way of structuring an entire system. That 'leap' of intuition requires a human understanding of trade-offs and the long-term evolution of a codebase—things a model cannot 'calculate' from training data. So when does AI actually become a tool rather than a crutch? It happens when you cross the threshold of true proficiency—usually after a year of deep experience in a specific language and framework. This is where you stop asking 'How do I write this?' and start asking 'Should I write this?' For me, after five years with Flutter, the 'Aha!' moment came when I realized AI was brilliant at the boring parts—the repetitive Bloc boilerplate and state management files—but useless at deciding *how* the state should actually flow to ensure scalability. LLMs evolve rapidly, fueling a cycle of benchmarks and hype. But for professional development, version numbers are irrelevant. The true divide is between the 'Vibe Coder' and the 'Real Engineer.' While a Vibe Coder prompts until the code *looks* right, a Real Engineer uses AI to accelerate a pre-defined architecture. One gambles; the other crafts. A Real Engineer uses AI to replace the writing task, never the thinking process. ![](https://supanadit.web.id/wp-content/uploads/2026/11/image-3.png) I built Morse specifically for the Architect, not the Vibe Coder. While tools like OpenCode or Pi are great for 'vibing' in a TUI, professional engineering requires a different kind of precision. Engineers need to map out complex logic, highlight critical dependencies across files, and leave architectural notes that a simple chat window can't handle. Morse is designed to bridge that gap—giving you the speed of AI without sacrificing the control of a human lead. ![](https://supanadit.web.id/wp-content/uploads/2026/11/image-1024x428.png) ![](https://supanadit.web.id/wp-content/uploads/2026/11/image-1-1024x428.png) ![](https://supanadit.web.id/wp-content/uploads/2026/11/image-2-1024x429.png) With Morse, the goal isn't to let the AI take the wheel, but to give the developer a better dashboard. By combining AI-driven speed with human-centric capabilities for highlighting and mapping, any software developer can work faster and more intentionally. Because at the end of the day, the most valuable thing in a codebase isn't the code itself—it's the intentionality behind it. --- title: Solving the Chicken-and-Egg Problem of PHP Versioning url: https://supanadit.web.id/solving-the-chicken-and-egg-problem-of-php-versioning/ type: post published: 2026-11-01T21:42:51+07:00 updated: 2026-11-02T16:32:26+07:00 Imagine a client calls you today about a project you finished three years ago. You open the code, eager to fix a quick bug, and suddenly—everything crashes. Your current environment is too new, the project is frozen in time, and you're staring at a wall of errors. This is the "Client from the Grave" scenario, and it's a nightmare every professional PHP developer has faced. And somehow somebody just threw out a response, "**I use Docker**"? LOL... When I mentioned this struggle online, the common refrain was: *"Just use Docker."* Don't get me wrong—I use Docker and DevContainers every single day. But for a simple version switch, Docker can feel like using a sledgehammer to crack a nut. The overhead of managing containers, the complex setup for some developers, and the resource drain on a local machine are real frictions. Sometimes, you don't want a virtualized environment; you just want the right version of PHP to run on your machine. Yes, PHP rarely introduces breaking changes, but frameworks often limit the minimum and maximum PHP versions. Most of the time when we work on projects, once finished, the client rarely wants maintenance support or services. Clients often come back 3–4 years after the project is finished due to a need for improvements or bug fixes. In the gap between the project's completion and when they contact us again, PHP, libraries, and frameworks evolve; upgrading those usually requires more work than addressing the reported bugs or requested new features. The reality is that while PHP itself is stable, the ecosystem isn't. Frameworks often impose strict version requirements. When a client returns after three years, you aren't just fighting a bug; you're fighting a version mismatch. Upgrading the environment often takes more effort than fixing the actual code. I went on a quest to find a tool that worked like `nvm` or `pyenv`—something that just worked out of the box. But I hit a "chicken-and-egg" problem: `phpbrew` is written in PHP, meaning you need PHP to install the tool that manages PHP. Other options like `mise` are powerful, but often feel like overkill for a developer who just needs a specific binary. And while distro package managers exist, they usually only give you the latest version, leaving older projects stranded. This is why I built `phpv`. I wanted to strip away the friction of managing third-party libraries. Instead of wrestling with complex build flags, you can now use `phpv ext add` to install and enable extensions effortlessly. To tackle the dreaded build failures on modern operating systems, I integrated support for the Zig compiler (`--compiler zig`) and a custom patch system to keep security and compatibility up to date without the manual headache. One of the biggest hurdles in PHP versioning is the lack of simple, downloadable binaries. Unlike some languages, PHP source code relies heavily on GNU GCC and is notoriously difficult to statically link. If you tried to bake every possible extension into a single binary, you'd end up with a bloated package that's impossible to customize later. The solution? Dynamic linking. By keeping the binaries lean, we get a system that is both flexible and lightweight. Take a look at my Fedora machine in the image below. Despite requiring a few system packages, the total footprint of the PHP installation is only **64 MB**. That's the power of dynamic linking—it provides the functionality we need without the bulk of a full portable distribution. ![](https://supanadit.web.id/wp-content/uploads/2026/11/image-9-1024x390.png) Portable PHP is possible, but each version is bulky, consumes more space, and increases build times. Additionally, adding any new extension, such as PECL, requires a complete rebuild of the source code. Yes, I'm aware of [Pie](https://github.com/php/pie), but my response is: Do you think every project is maintained well and kept up to date? While "Portable PHP" exists, it often comes at a cost: bulky files, slower build times, and the requirement to rebuild the entire source code just to add a single PECL extension. In a professional environment where projects aren't always perfectly maintained, you need a tool that adapts to the project, not the other way around. Unlike [NVM](https://github.com/nvm-sh/nvm), PHP requires a distinct binary build process and integrates directly with servers like Apache and NGINX. This complexity is why installing PHP via [PHPV](https://phpv.supanadit.com/) or other version managers is often slow. I built [PHPV](https://phpv.supanadit.com/) using [Go](https://go.dev/) because it is the right tool for the job. While shell scripts are great for simple tasks, they become complex and difficult to maintain as more features are added. Unlike `nvm`, PHP has to integrate with servers like Apache and NGINX and handle a distinct binary build process. This is why version managers for PHP are traditionally slower and more complex. I chose to build `phpv` in Go because it strikes the perfect balance: it's far more maintainable than a shell script, but allows for much faster iteration than Rust. Some might ask, "Why not Rust?" Rust is incredible when execution speed is the absolute priority. But for a tool like this, development speed and rapid iteration are what matter most. Go was simply the right tool for the job. --- title: The Lazy Guide to Installing Docker url: https://supanadit.web.id/cara-install-docker-di-server/ type: post published: 2025-06-05T19:49:51+07:00 updated: 2026-11-02T08:13:31+07:00 The step-by-step process in this tutorial also works for desktop Linux, because here I explain **how to read** the Docker installation docs from the official site — unlike articles on Medium and elsewhere. For the installation, just follow the step-by-step from **[Docker Docs](https://docs.docker.com/engine/install/ubuntu/)** — trust me, you only need to copy and paste each step, and that's just 2 steps in one menu and 1 more step in another. Here is how I do it when I have a new server and need to install Docker. **First, log in to the server — just run this in the terminal / command line** ``` ## Snippet ssh : ## Example ssh supanadit@123.123.123.123 ## Or if it has been integrated with a domain, simply ssh john@example.com ``` Second, after logging in to the server via SSH, you can see the image below — taken from the Docker documentation — with Point 1 and 2 containing shell commands, and *just run those two points*. **Notice the sidebar on the right: I'm on the Ubuntu tab.** If you're using another OS, simply pick that OS's documentation. What about step 3? Just skip it, because it's wrong.... the Docker documentation assumes you're using the root user. Link: [https://docs.docker.com/engine/install/ubuntu/](https://docs.docker.com/engine/install/ubuntu/) ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-21-1024x493.png) Summary Command ``` ## Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc ## Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin ``` Only after you finish installing Docker can you move on to the documentation below. Link: [https://docs.docker.com/engine/install/linux-postinstall/](https://docs.docker.com/engine/install/linux-postinstall/) ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-22-1024x493.png) Summary Code ``` sudo usermod -aG docker $USER ``` Run only point **No. 2**, then run the command below to enable Docker and ContainerD SystemD services. ``` sudo systemctl enable --now docker.service sudo systemctl enable --now containerd.service ``` After that there are two options: ***close your terminal and log in to the server again***, or ***just restart the server***. How do I restart the server? Just run the command below ``` sudo shutdown -r now ## Atau sudo reboot ``` Once that's done, you can test it by running `docker ps -a` — if there are no errors, Docker is properly installed on your server. Short and sweet, see you in the next article... By the way, if you run into any issues, feel free to write them in the comments — I'll be happy to help. The more problems I get, the more experience I gain 😁. --- title: Traefik: The Reverse Proxy That Just Works url: https://supanadit.web.id/tutorial-deploy-traefik-menggunakan-docker/ type: post published: 2025-06-02T21:31:30+07:00 updated: 2026-11-02T08:11:36+07:00 Traefik is the best and simplest reverse proxy I have ever used, compared to Caddy, NGINX, and others. Besides that, Traefik already comes with automatic SSL like Caddy, but goes further — it's integrated with Docker and Kubernetes. First, you need to create a dedicated network — in my example I create my own network named `pratama-network`, which you can create with the command below. ``` docker network create pratama-network ``` Next, create a directory named `traefik` on your server, then create a `compose.yaml` file with the code below. After this, you still need to create a few files: - **traefik.toml** -> Traefik's main configuration - **dynamic-conf.toml** -> HTTP, TCP and UDP routing configuration - **acme.json** -> SSL content generated by Traefik Here I use the **TOML** format for the Traefik configuration. Normally people use the **YAML** format, but I personally prefer **TOML**. You can use **YAML** directly if you prefer it, but in this tutorial we'll stick with the **TOML** format. Let's create the files first: **traefik.toml** and **dynamic-conf.toml** will be stored in the **conf** directory, while **acme.json** will sit at the same level as **compose.yml** Here are the commands in short: ``` mkdir conf touch conf/traefik.toml touch conf/dynamic-conf.toml touch acme.json chmod 600 acme.json ``` In order, the layout looks like this: ``` -- | /home//docker/traefik | -- compose.yml | -- acme.json | -- conf | -- traefik.toml | -- dynamic-conf.toml ``` Based on the structure above, I added the **docker** directory to keep things tidy, but you're free to decide where the **traefik** directory lives — and it doesn't even have to be called **traefik**, it's just for **tutorial** purposes. Now, let's fill in **traefik.toml**, which looks roughly like this Then fill in the **dynamic-conf.toml** file as below — both files above will be explained in detail later. The code is all done — you just need to replace the **traefik.supanadit.com** part with your own domain, then run it with the command below. ``` docker compose up -d ``` In short, the Traefik deployed on your server is now accessible. With the configuration above, for example, it's ***a small slice*** of my server — and in this case it's at the following link. [http://traefik.supanadit.com](https://traefik.supanadit.com/) Wait.... however, you won't be able to access it — I protect it with **Authelia** as **Middleware**, so not everyone can see the list of apps on the dashboard. 😁Curious how I use **Authelia** and integrate it with **Traefik**? I'll write more articles about Traefik another time, and I'll create a dedicated page about Traefik. ### FAQ How can other Docker apps be accessed? There are two ways to do this: 1. Using labels 2. Writing routing configuration in **dynamic-conf.toml** The details will be covered in a different article, and I'll share the link here. What about acme.json? You can just leave it, because Traefik will fill that file automatically, provided that: 1. Your website is configured with **lets encrypt** in the **traefik.toml** section 2. Then in the **dynamic-conf.toml** section, enable the property I marked with ***Uncomment this for production use***, and comment out the part I marked with ***Comment this for production use***. Except the **service** — never comment that part out, whether in production or not. What about testing locally with Docker Engine / Desktop on Windows / Mac / Linux You can follow the step-by-step above without changing anything — meaning **websecure** stays disabled, and in **traefik.toml** just *comment out* the lines below. ``` [certificatesResolvers.lets-encrypt.acme] email = "xxx@xxx.com" storage = "acme.json" [certificatesResolvers.lets-encrypt.acme.tlsChallenge] ``` Then you can configure **/etc/host** on Linux / Mac and **C:\Windows\System32\drivers\etc\hosts** on Windows with the configuration below. 127.0.0.1 traefik.supanadit.com The domain is up to you, as long as it matches what's in **traefik.toml** If you have questions or something is unclear, write it in the comments below and I'll update this article. --- title: Domains, DNS, and Servers: The Missing Manual url: https://supanadit.web.id/cara-integrasi-dns-dengan-server/ type: post published: 2025-06-03T22:05:09+07:00 updated: 2026-11-02T08:10:37+07:00 Most articles and tutorials out there are quite confusing for people who are new to the IT world — even for professional engineers focused on their own fields, like backend or frontend, who want their own domain and server but don't know where to start. First, before getting into the world of Domains and Servers, you need to understand a bit about networking basics. And you should know that a **Domain** in the IT context is the complete address of a site, whether offline or online — for example, the article you're reading right now has the domain **supanadit.web.id**. As for the suffix on a **Domain** like **.web.id**? That's not the domain — it's the **TLD**. Many people misunderstand and think that **.com**, **.net**, **.co.id**, **.id**, etc. are domains, when in fact they are **TLDs**. Most of you may also wonder why Domains cost money... actually they're **FREE**, so why are there so many Domain service providers? It's because behind every Domain there are servers and networks that must be maintained, along with the experts to run them — and on top of that there's bureaucracy so everything can be connected to one another, regulated by **[ICANN](https://www.icann.org/)**. For publishing an application, the most important thing is the Server — and in this case, every application definitely has different server requirements, especially regarding the operating system used. Servers aren't always Linux, and not always Windows Server either; even plain Windows or a MacBook can be used as a server. But that discussion will be covered in a different article. In theory you could create your own **TLD** simply, for example **.ganteng**, self-hosted on your own laptop / PC. But that's going too far — let's move on to the main discussion. ### Purchasing the domain The very first thing when you want to build a site or application that many people can access is finding an address that matches what you want — usually by searching domain service providers like [Hostinger](https://www.hostinger.com/domain-name-search), [IDCloudHost](https://idcloudhost.com/domain/), [Namecheap](https://www.namecheap.com/domains/), [GoDaddy](https://www.godaddy.com/), and many more. Below are two screenshots where I bought domains from different providers — first at Hostinger and the second at IDCloudHost. (These examples are already purchased.) ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-7-1024x485.png) ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-8-1024x721.png) ### Introducing DNS Manager After you buy and own a Domain, the provider gives you a panel to manage it. Each provider has a different panel and different pages, but the functionality is the same. If you don't even want to use the built-in panel of the domain provider, you can use a third-party panel — covered another time. Back to the discussion — to manage a Domain, let's open the panel. For IDCloudHost, here I'll use the domain **gusrandi.my.id**, my younger sibling's domain that I manage, and on IDCloudHost it looks like this. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-9-1024x603.png) As explained before, every provider has a different look and menu, but they're all roughly similar. For example, **supanadit.web.id** was bought at IDCloudHost but its panel is managed on **Google Cloud Platform**, as shown below. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-10-1024x488.png) ### Managing DNS Here let's integrate the DNS with a server we own. As an example, I have a server with the IP **27.112.78.120**, where my sibling's WordPress also lives on the same server I use. Can you have many DNS records but a single server? Of course — just play around with the reverse proxy and the DNS management. Can you have many servers but a single DNS? (The reverse) This is obviously possible too — just play with the panel. As an example, the image below shows the configuration I applied. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-16-1024x597.png) In the image above, I've added a few arrows with numbers. **No.1** = The domain name; the **@** symbol indicates that row is the main domain, meaning **gusrandi.my.id**. If you replace the @ — for example with **hello** — it becomes a subdomain like this: **hello.gusrandi.my.id** **No.2**= The domain type. Type **A** points to a server over the IPv4 network; public IPs commonly use type **A**, or if you have IPv6 you can use **AAAA**. For email configuration you can use **MX**, and there are many more like **CNAME**, **NS**, **PTR**, **TXT**, **SRV**. **No**.**3** = The value based on its type: for **A** you fill in an **IPv4** address, and for **AAAA** an **IPv6** address of your server. Here's an example of creating a new subdomain with type **A**, as shown below. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-17-1024x590.png) The result in the panel will then be added like the image below. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-18-1024x625.png) After that you have to wait around **1–30 minutes**, depending on how fast your internet provider and the domain service propagate the change everywhere. Once you've waited, you can test it with a simple command in CMD / Terminal using the **ping** program, as shown below. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-19.png) Once the result appears like in the image above — your IP showing up next to the DNS — the configuration has succeeded. Next up is preparing the server, the reverse proxy, and deploying your application. **But** if your IP hasn't appeared yet, wait longer and try pinging again in a few minutes / hours. Please be patient... --- title: Renting Your First Server Without the Headache url: https://supanadit.web.id/cara-menyewa-dan-mempersiapkan-server/ type: post published: 2025-06-03T22:05:23+07:00 updated: 2026-11-02T08:10:04+07:00 In this article we'll discuss how someone can own a server and manage it. I won't get too technical about servers, because it confuses people and mostly causes misunderstandings. Simply put, a server is a computer specially designed to run programs and provide services to users simultaneously (*taking place or happening at the same time; at once*). The word **specially** doesn't mean the computer has to be shaped like the server most people know — for example, most people picture a server like the image below. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-11-1024x576.png) ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-12-1024x576.png) **In reality**, your own PC / laptop can also be a server, because it can run programs that other people can access — whether offline or online. But normally we want the server we build to run programs we own / buy and be accessible by other people. To achieve that, besides the server itself you need an internet connection with a Public IP and a domain, so people don't have to memorize your public IP address. In this article I won't explain how to turn your PC / laptop into a server — instead, renting a server and managing it. In theory, when you rent, you implicitly own it too, but only for as long as you pay for it. #### Purchasing the Server First you have to buy / rent a server, and there are many types — Shared Hosting, VPS, Cloud VPS, Cloud Hosting and more. I'll give a simple overview with an analogy. Shared Hosting You rent a room in a boarding house. You share the kitchen, bathroom, and other facilities with many tenants. Cheap, but the resources are limited and performance can be affected by other tenants VPS You rent an apartment in a large apartment building. You have your own kitchen, bathroom, and living room, isolated from your neighbors. Although you share the same physical building, you have CPU, RAM, and storage resources allocated specifically for you. You hold the "key" (root access) to manage your own apartment. Cloud Hosting You rent an apartment in a very modern apartment complex. The complex has many interconnected buildings. If your apartment suddenly needs more space, you can immediately "borrow" space from another building in the same complex without moving. This is very flexible — it can adjust to your needs dynamically. Cloud VPS This combines the VPS and Cloud Hosting concepts. You rent an apartment in a very large modern apartment complex (like Cloud Hosting), and your apartment is also isolated with dedicated resources like a VPS. The difference: your "apartment" isn't tied to a single physical building — it's distributed across the whole complex. If one building fails, your "apartment" can move to another building without you noticing. Dedicated Server You buy or rent a private house (not an apartment). The whole house, land, and its facilities are fully yours. No neighbors share the physical resources with you. You have full control over everything in the house, from the foundation to the roof. In conclusion, if you look at the image at the beginning of this article, that's a **Dedicated Server** — and owning one requires a fairly high cost, time, effort, and professional-level skills. Besides that, your PC / laptop can also be categorized as a **Dedicated Server**. But for this article, let's stick with **VPS** / **Cloud VPS** — even though the explanations above differ slightly, from our perspective as the buyer it's the same. You'll be given choices of Memory, Storage and CPU at different price ranges. You're also given a Public IP without having to worry about managing the network. Here's an overview of the server I rent at IDCloudHost. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-20-1024x473.png) If you notice, I have the public IP **27.112.78.120**. (Wait, that info can be seen and hacked... ) Yep, that's right.... please hack me 🙏😁. The image above is the result of creating a new instance by pressing the **New** button — then you'll be given options like the image below. ![](https://supanadit.web.id/wp-content/uploads/2025/06/image-14.png) Based on the image above, you get to choose the operating system, server location, specifications, username, password, resource name and the total price. The **SSH** and **VPC Network** parts can be ignored — if it's a new account you'll probably have to create a VPC Network, and you can use the default configuration, just keep clicking **next** until it's done. Once everything above is finished and you have a public IP, ***your server is accessible — then start configuring the reverse proxy and buying a domain***. ## FAQ How do I access the server? For Linux users — whether Fedora, Ubuntu, CentOS, Rocky Linux, etc. — you can access it with the **ssh** command in the terminal or command line, like below ``` ssh dadang@234.34.22.12 ``` You can't access my private SSH server with the IP exposed above... Huh.. why is that? 😁 Secret.... figure it out yourself... Where's the graphical interface? Linux-based servers have no interface, so terminal skills are really required. How do I deploy a frontend or backend application like Java, Angular, NodeJS, PHP, etc.? The easiest way is to try it yourself on the Ubuntu OS on your own laptop / PC — figure out how to run that backend / frontend program on Ubuntu OS. Once you know how, and the step-by-step, what you learned applies to the server you rent. It's just that locally you probably run it at http://localhost:3000. So once you have a server, you can run it on the server and access http://: **Question**: But when we close the terminal, the application dies? Well, you can learn how to keep the application running in the background. How can the server be accessed via a Domain? The Domain itself must be bought first, then you point the domain to your server's public IP, and install a reverse proxy — like NGINX, Caddy, Traefik, etc. --- title: Privacy Policy url: https://supanadit.web.id/privacy-policy/ type: page published: 2022-09-04T02:38:40+07:00 updated: 2025-11-03T22:29:00+07:00 ### Who we are **Suggested text:**Our website address is: https://supanadit.web.id ### Comments **Suggested text:**When visitors leave comments on the site we collect the data shown in the comments form, and also the visitor’s IP address and browser user agent string to help spam detection. An anonymized string created from your email address (also called a hash) may be provided to the Gravatar service to see if you are using it. The Gravatar service privacy policy is available here: https://automattic.com/privacy/. After approval of your comment, your profile picture is visible to the public in the context of your comment. ### Media **Suggested text:**If you upload images to the website, you should avoid uploading images with embedded location data (EXIF GPS) included. Visitors to the website can download and extract any location data from images on the website. ### Cookies **Suggested text:**If you leave a comment on our site you may opt-in to saving your name, email address and website in cookies. These are for your convenience so that you do not have to fill in your details again when you leave another comment. These cookies will last for one year. If you visit our login page, we will set a temporary cookie to determine if your browser accepts cookies. This cookie contains no personal data and is discarded when you close your browser. When you log in, we will also set up several cookies to save your login information and your screen display choices. Login cookies last for two days, and screen options cookies last for a year. If you select "Remember Me", your login will persist for two weeks. If you log out of your account, the login cookies will be removed. If you edit or publish an article, an additional cookie will be saved in your browser. This cookie includes no personal data and simply indicates the post ID of the article you just edited. It expires after 1 day. ### Embedded content from other websites **Suggested text:**Articles on this site may include embedded content (e.g. videos, images, articles, etc.). Embedded content from other websites behaves in the exact same way as if the visitor has visited the other website. These websites may collect data about you, use cookies, embed additional third-party tracking, and monitor your interaction with that embedded content, including tracking your interaction with the embedded content if you have an account and are logged in to that website. ### Who we share your data with **Suggested text:**If you request a password reset, your IP address will be included in the reset email. ### How long we retain your data **Suggested text:**If you leave a comment, the comment and its metadata are retained indefinitely. This is so we can recognize and approve any follow-up comments automatically instead of holding them in a moderation queue. For users that register on our website (if any), we also store the personal information they provide in their user profile. All users can see, edit, or delete their personal information at any time (except they cannot change their username). Website administrators can also see and edit that information. ### What rights you have over your data **Suggested text:**If you have an account on this site, or have left comments, you can request to receive an exported file of the personal data we hold about you, including any data you have provided to us. You can also request that we erase any personal data we hold about you. This does not include any data we are obliged to keep for administrative, legal, or security purposes. ### Where your data is sent **Suggested text:**Visitor comments may be checked through an automated spam detection service.