diff --git a/.forgejo/workflows/build_and_deploy_site.yml b/.forgejo/workflows/build_and_deploy_site.yml index 4521658..b8e48ce 100644 --- a/.forgejo/workflows/build_and_deploy_site.yml +++ b/.forgejo/workflows/build_and_deploy_site.yml @@ -10,41 +10,16 @@ jobs: deploy: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 with: submodules: true # Fetch Hugo themes (true OR recursive) fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod - - name: Setup Hugo - run: | - wget https://github.com/gohugoio/hugo/releases/download/v0.147.8/hugo_extended_0.147.8_linux-amd64.tar.gz - tar -xzf hugo_extended_0.147.8_linux-amd64.tar.gz - chmod +x hugo - mkdir -p ~/bin - mv hugo ~/bin/ - echo "~/bin" >> $GITHUB_PATH + - name: Setup + run: apt-get install hugo -y - name: Build run: hugo --minify - - name: Setup SSH - run: | - echo "Setting up SSH..." - mkdir -p ~/.ssh - if [ -z "${{ secrets.SSH_PRIVATE_KEY }}" ]; then - echo "ERROR: SSH_PRIVATE_KEY secret is not set!" - exit 1 - fi - echo "SSH_PRIVATE_KEY secret is present" - echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - chmod 700 ~/.ssh - echo "SSH key saved and permissions set" - ssh-keyscan -H alexselimov.com >> ~/.ssh/known_hosts - echo "Host key added to known_hosts" - # Test SSH connection - echo "Testing SSH connection..." - ssh -o StrictHostKeyChecking=no -o BatchMode=yes root@alexselimov.com "echo 'SSH connection successful'" || echo "SSH connection failed" - - name: Deploy - run: rsync -azvr public/* root@alexselimov.com:/var/www/alexselimov.com/ + run: rsync -azvr public/* root@smokey:/var/www/alexselimov.com/ diff --git a/.gitignore b/.gitignore index 501a56b..46f5006 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ public/* -resources/* diff --git a/.gitmodules b/.gitmodules index 094f5d7..f320301 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "themes/hugo-bearcub"] - path = themes/hugo-bearcub - url = https://forge.alexselimov.com/aselimov/hugo-bearcub.git +[submodule "themes/hugo-theme-terminal"] + path = themes/hugo-theme-terminal + url = https://github.com/panr/hugo-theme-terminal.git diff --git a/archetypes/posts.md b/archetypes/posts.md deleted file mode 100644 index 68cad01..0000000 --- a/archetypes/posts.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "{{ replace .Name "-" " " | title }}" -date: {{ .Date }} -tags: [] ---- diff --git a/content/_index.md b/content/_index.md index 087e8c0..e26619b 100644 --- a/content/_index.md +++ b/content/_index.md @@ -1,18 +1,18 @@ --- title: "" +framed: true date: 2022-10-03T14:17:10-04:00 layout: index --- -# Hi I'm Alex Selimov. -I'm a computational materials science PhD turned software developer. -My background is primarily in Molecular Dynamics and FEA/FEM, but I've dabbled with thermodynamic equilibrium calculations as well as 6-DOF simulations. -Most of my time has been spent writing code for HPC including MPI and openMP, although I haven't done that in a few years. -The languages I currently use for building are Rust, Java, and Python. -In another life I worked mainly in C++ and Fortran. +I am a materials scientist and software developer proficient in Rust, Fortran, C++, Java, and Python. I have extensive experience with Unix operating systems on both high performance computing resources and on my personal computer (check out [Void Linux](https://voidlinux.org)). I currently work at [UKG](https://www.ukg.com) as a Java Backend Engineer. -I use this site as a dumping ground for thoughts and tips I find useful. -Hopefully someone else will find something useful here as well. -Thanks for stopping by! +This website is a place for me to post about a range of topics from professional news, to tech tutorials, to recipes I enjoy very much. Checkout some of my recent posts below or find them all organized by tags [here](/posts). -You can browse posts by topic [here](/tags). +I also designed and manage a few websites for family members, so check them out: + +[alexanderselimov.com](https://alexanderselimov.com) + +[iberoamericanliterarysociety.com](https://iberoamericanliterarysociety.com) + +**Checkout some posts below and thanks for stopping by!** diff --git a/content/about.md b/content/about.md index d84530a..e957768 100644 --- a/content/about.md +++ b/content/about.md @@ -1,29 +1,21 @@ ---- -title: "About" -date: 2026-03-02 -hideDate: true -hideUpvotes: true -hideReply: true ---- ++++ +title = "About" +date = "2019-01-25" +author = "Radek" ++++ +# Hi there -{{< img src="/profile.webp" max-width="250px" >}} +My name is Radek and I'm the author of this theme. I made it to help you present your ideas easier. -## Quick Facts +We all know how hard is to start something on the web, especially these days. You need to prepare a bunch of stuff, configure them and when that’s done — create the content. -- Father of two and husband of one -- **Scientific and Backend** Software Developer -- Computational Materials Science PhD from Georgia Tech -- **Favorite programming language is Rust 🦀** +This theme is pretty basic and covers all of the essentials. All you have to do is start typing! -## Technical knowledge +The theme includes: -- **Programming Languages:** Rust, Fortran, Python, C++, Java, Typescript -- **Parallel Programming:** MPI, OpenMP, Rayon, etc... -- **Good at Algorithm design, performance tuning** -- **AI:** Did work with Active Learning and traditional models (small data) before ChatGPT. -- **LLMs:** Messing around with them, use codex mainly, planning a write up on my thoughts. +- fully customizable color schemes generated by [**terminal.css**](https://panr.github.io/terminal-css/). +- great reading experience thanks to [**Fira Code**](https://github.com/tonsky/FiraCode). +- nice code highlighting thanks to [**PrismJS**](https://prismjs.com) that matches the theme's color scheme. -## Curriculum Vitae - -[Click here for my CV](/cv.html) +So, there you have it... enjoy! diff --git a/content/cv.md b/content/cv.md index b6bd688..48a18bf 100644 --- a/content/cv.md +++ b/content/cv.md @@ -1,75 +1,15 @@ --- title: "" -hideDate: true +date: 2022-10-04T23:35:54-04:00 --- Alex Selimov ================== -**alex@alexselimov.com · [https://alexselimov.com](https://alexselimov.com)** -## Skills - -- Programming Languages: Python, C++, Rust, Java, Fortran, Bash -- Algorithm design, data structure design, runtime complexity analysis -- High Performance Computing: Message Passing Interface (MPI), OpenMP, C++17 parallelism, Rayon, Python multithreading -- Proficient in Linux environments on desktop, personal server, and computing cluster architectures. -- Knowledge of product development tools such as git, Docker, CI/CD pipelines, JIRA, and Agile workflow. -- Expertise with development and profiling tools: Valgrind, gdb, gprof, Intel VTune profiler, tau profiler. -- Technical writing abilities which resulted in 8 published journal articles and creation of software specifications/documentation. - - -## Experience - -**UKG**, Atlanta\ -*Software Engineer (May 2025 -- Present)* - -- Worked as backend engineer on notifications as a service using a microservice architecture built on top Java, SpringBoot, Kafka, RabbitMQ, MongoDB, Splunk, and Grafana technologies. -- Implemented improved observability for services to reduce service downtime. -- Acted as a Security Champion and addressed security vulnerabilities in existing code based on SAST and SCA scans performed using CXOne Checkmarx. -- Led implementation of testing services for web push notification services. -- Assisted in development of MCP server and LLM chatbot proof-of-concept to act as an internal assistant for providing support to other UKG teams. - -**SpaceWorks Enterprises**, Atlanta\ -*Senior Software Developer (January 2024 -- April 2025)* - -- Lead development and maintainer role for commercial off-the-shelf (COTS) software products as well as NASA and NAVAIR programs in Rust and Python. -- Led development of modular and extensible simulation libraries for modeling applications including multi-body six-degree-of-freedom simulations, state-space linear simulations for control system design, differential evolution optimization, among others. -- Improved mesh based calculations from **~1 hour to ~1 minute** per analysis through improved data structure and algorithm design. -- Implemented multi-threading for accelerating simulation analysis and for asynchronous execution. -- Developed equilibrium gas composition solver for different stages of a rocket engine cycle with **order-of-magnitude improved speed compared to legacy approach**. -- Product owner for COTS product including final approval of merge requests, interfacing with customers for sales and technical support, and helping to develop software roadmaps. -- Developed and maintained CI/CD pipelines for COTS products using Gitlab runners and docker containers. -- Mentored junior developers in idiomatic Rust and software architecture. - -**Third Wave Systems**, Minnesota\ -*Computational Mechanics Engineer (December 2022 -- January 2024)* - -- Worked in an Agile team on a variety of projects requiring fast context switching to implement cutting edge functionality in C++, Fortran, and Python. -- Worked on large legacy C++ FEA code bases to add new functionality as well as address subtle legacy bugs resulting from race conditions, invalid memory access, and incorrect usage of programming language built-ins. -- Refactored core solvers utilizing an Octree data structure for adaptive mesh refinement, utilizing OpenMP and C++17 built in multi-threading, resulting in **90% reduction in simulation time**. -- Implemented improved force models for drilling through addition of analytical equations for elastic indentation, **which reduced error by 10% relative to experiments**. -- Led team members in implementation of machine learning analysis in Python requiring accurate effort estimation and selection of functionality based on effort/risk to reward. -- Mentored junior developers in idiomatic Python and machine learning concepts. -- Automated manual simulation creation and analysis workflows using Python, leveraging active learning based adaptive sampling, to reduce manual effort by engineers and **reduce usage of compute resources by ~80%**. - -**McDowell Research Group**, Dr. David McDowell, Georgia Tech\ -*Graduate Research Assistant (August 2017 -- December 2022)* - -- Developed and extended Concurrent Atomistic-Continuum (CAC) simulation toolkit involving the development of a coupled finite element method and classical many-body molecular dynamics simulation tool in C++ and Fortran. -- Developed a series of Python pipelines for analyzing simulations and visualization of simulation results. -- Refactored significant portions of the code to **reduce simulation run times by 60%** through design of new algorithms and improved implementation of communication subroutines utilizing MPI. -- Profiled and tuned software performance for high performance computing clusters including implementing code structure changes enabling improved compiler optimizations and addressing MPI communication bottlenecks. -- Worked independently on self-guided research topics while also collaborating with external sources such as Sandia National Lab and University of Florida. -- **Authored three published journal articles and four conference presentations**. - -**Mechanics of Materials Organization**, Dr. Xiaowang Zhou., Sandia National Lab\ -*Intern - Engineering Sciences Summer institute (May 2021 -- August 2021)* - -- Restructured simulation toolkit codebase to abide by an object-oriented programming paradigm to ease addition of functionality. -- Worked on the development of finite temperature CAC simulations through design of novel finite elements. -- Developed methods for pressure controlled CAC simulations. +**aselimov3@gatech.edu · [https://alexselimov.com](https://alexselimov.com)** +[{{< fontawesome class="fa-solid fa-download" >}}PDF version](/AlexSelimovCV.pdf) ## Education - **Georgia Institute of Technology** (North Avenue, Atlanta, GA 30332)\ @@ -92,3 +32,44 @@ Alex Selimov Funding Source: Extreme Science and Engineering Discovery Environment (XSEDE)\ Project Title: Concurrent atomistic-continuum simulations of extended scale defect interactions in heterogeneous microstructures (TG-MSS150010)\ Funding Period: Jan 1, 2019 - June 30, 2022 + +## Research Experience +**McDowell Research Group**, Dr. David McDowell, Georgia Tech\ +*Graduate Research Assistant (August 2017 -- Present)* + +- Worked on the development and extension of the Concurrent Atomistic-Continuum method for running massively parallel coarse-grained atomistic simulations of dislocation interactions with interfaces and other defect structures in nanolaminate and stainless steel materials. +- Improved parallel implementation and tuned calculation algorithms of in-house simulation suite obtaining runtime reductions of 66%. Also contributed to a fork of LAMMPS implementing the CAC simulation method. +- Implemented the finite element method to solve conservation law field equations to enable reductions in degrees-of-freedom leading to reduced computational cost. +- Tested various metrics to numerically characterize atomic interface structure of metallic semi-coherent interfaces and applied machine learning methods to track the interface structure evolution with loading. +- Modeled solute distributions in diffuse Cu/Ni semi-coherent interfaces and their effect on the glide of interface misfit dislocations and overall interface properties. +- Investigated the sequential interactions between dislocations and obstacles in various systems to quantify evolving obstacle strength and interaction mechanisms. + +**Mechanics of Materials Organization**, Dr. Xiaowang Zhou, Sandia National Lab\ +*Intern - Engineering Sciences Summer institute (May 2021 -- Aug 2021)* + +- Studied the barrier strength of grain boundaries with embedded helium bubbles to improve hardening predictions of irradiated stainless steel materials, collaboration continued beyond internship period. +- Extended molecular dynamics barostat algorithms to coarse-grained regions for pressure relaxation. +- Worked on CAC capabilities for high temperature dynamics simulations through development of new finite element types and extension of neighboring codes for cluster potentials. + +**AeroStructures Lab**, Dr. Seetha Raghavan, UCF\ +*Research Assistant (September 2013 -- December 2016)* + +- Utilized photoluminescence spectroscopy and piezospectroscopy for the characterization of material and mechanical properties in ceramic and composite materials. +- Worked on collaborative project with Imperial College London (Dr. Ambrose Taylor’s Research Group) for the testing and characterization of novel hybrid carbon fiber reinforced polymer (HCFRP) composites. +- Worked on collaborative project with German Aerospace Center (DLR) to study stress development in thermally grown oxide layers of thermal barrier coatings. + +**Pollock Research Group**, Dr. Tresa Pollock, UCSB \ +*RISE Undergraduate Intern, NSF funded REU (June -- August 2015)* + +- Studied Magnesium-zinc alloys to determine methods for texture weakening for improvement of material properties through analyzing presence of intermetallic particles. +- Utilized scanning electron microscopy to take secondary electron images, backscatter electron images, and to analyze crystallographic texture through electron backscatter diffraction +- Prepared image analysis tools to determine volume fraction of intermetallic particles from SEM images for comparison to grain size distribution of samples with Matlab. + +## Skills + +- Programming in Fortran, C, and C++ with additional expertise utilizing the Message Passing Interface (MPI) for implementation of parallel and scalable simulation tools. +- Programming in MATLAB, HTML, and CSS. +- Data analysis and pipeline creation using Python with Numpy, Scipy, Scikit-Learn, Pandas, and Tkinter modules. Additional familiarity with Jupyter Notebooks. +- Expertise in atomistic simulations using LAMMPS with Molecular Statics, Molecular Dynamics, and Monte-Carlo methods. +- Expertise with Linux software environment and building applications for use with computing cluster architectures. +- Familiarity with software development methodologies including test case design and CI/CD pipelines. diff --git a/content/posts/ai_confession.md b/content/posts/ai_confession.md deleted file mode 100644 index be6897a..0000000 --- a/content/posts/ai_confession.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "Role of AI in my writing" -date: 2026-03-13T12:11:23-04:00 -tags: ["LLMs", "Agents", "AI"] ---- - -I have a confession to make to anyone who has stumbled across this blog. Some of the posts I've previously written had strong AI generated segments. I've since added a note at the start to mention this. The post ideas were always mine, and I always edited the outputs. However, there were still occasions where AI generated segments made it into my final draft unedited. I'm currently rethinking the role of AI in my workflow. - -### I fell for the siren's song of low effort output - -I've been wanting to output more content. Main reason is that a lot of people I respect have blogs that span years. I also wanted to share some perspectives I've had and issues I've resolved in case anyone was ever looking/to keep them as a log. [The blog post about CUDA on void linux](https://www.alexselimov.com/posts/cuda_on_void/) has been particularly helpful as I've set up multiple void linux machines that all had the same issues. - -The issue for me was that creating content takes away from other things I could've been working on. I thought that this was the point of AI acceleration so I leveraged ChatGPT to help automate the generation of some posts. In most cases I went in and manually edited for style and formatting, but there are many examples of ChatGPT generated sentences that made it to my blog. This helped me to get useful (at least to me) posts out, but in hindsight I don't think the trade-offs were worth it. What I gained in posting velocity I lost in: - -- **Posts are not authentic.** While I always picked the post topics (No "what should I post" prompts), it's hard to separate what thoughts are genuinely mine versus what is just background noise added by the LLM. The best example of what I mean comes from image generation models. The tree in a human created painting was placed for a reason and has some kind of meaning. The tree in an image generation model created painting was placed there just because and has no meaning. I kind of feel the same way about LLM generated text. -- **I miss on developing my writing skills.** I personally think this is the most important reason to not rely on LLMs for writing. I've written a lot of academic/technical documents ([see publications](https://alexselimov.com/cv)) but that kind of writing is fake/performative. I've been trying to embrace Paul Graham's [write like you talk](https://paulgraham.com/talk.html). Outsourcing to LLMs as a first step means adopting the interpolated average writing style instead of finding my own unique voice and style. - -### Seeing the light and fighting the slop - -What helped me see the light was Mitchell Hashimoto's writings. In particular his article on [vibing a ghostty feature](https://mitchellh.com/writing/non-trivial-vibing). In it, I found a workflow that made more sense to me. I think I've been on the internet too much and was trying to convince myself Gas Town and endless Ralph Loops were actually the future. I haven't convinced myself yet, and I think I will stop trying to. Instead, I'm going to be more intentional about doing things manually for both the love of it and the skill-set growth potential. - -This does not mean I will go back to the "halcyon" pre-AI workflows. LLMs have been transformative for me. I just plan to use them as tools where they belong and not buy the developer --> agent manager transition that is being sold. The exact role of agents in my work is still something that is evolving. - -### Commitment to ensure all writings on this blog are fully human generated - -Moving forward anything I write on this blog will be fully human generated, with *some* assistance from LLMs. For writing that means using it as an editor to help with tone, structure, and grammatical errors. In general, I also use it as a sounding board to help me develop ideas. Claude-Code and Codex still have a big role to play in automating certain tasks (tedious edits, research on specific topics, even code changes once I know exactly what I want) but I no longer think they should have a primary role in something as personal as publishing my own thoughts. - -Will close with the quote that really hit me from Mitchell Hashimoto: - -> I believe good AI drivers are experts in their domains and utilize AI as an assistant, not a replacement. - diff --git a/content/posts/cuda_on_void.md b/content/posts/cuda_on_void.md index 091d5cf..ca6ab46 100644 --- a/content/posts/cuda_on_void.md +++ b/content/posts/cuda_on_void.md @@ -1,7 +1,6 @@ --- title: "Getting CUDA toolkit installed on Void Linux" date: 2025-04-15T10:45:26-04:00 -tags: [software development, CUDA] --- This is a short post (mainly for myself) to remember how I got CUDA installed on Void Linux. diff --git a/content/posts/debian_upgrade.md b/content/posts/debian_upgrade.md deleted file mode 100644 index 2273995..0000000 --- a/content/posts/debian_upgrade.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "The folly of Debian major version upgrades" -date: 2025-07-13T08:35:50-05:00 -tags: ["git", "matrix", "self-host"] ---- - -I recently realized that my web server was still on Debian Buster, **2 whole major versions behind** the latest Debian version. Normally this kind of thing wouldn't matter to me except that my matrix-synapse server was unable to federate with matrix synapse servers running newer versions. I normally run rolling release distributions on my local machines (I use Void btw) and it had been a long time since I tried this kind of upgrade. I went in hopeful that it would be straightforward. - -**This is a reminder to backup consistently.** - - Of course after thinking everything went fine, I tried to install a new package and libcrypt ends up getting removed leaving me unable to login to my server. Luckily I had backed up before this which saved all of my bespoke configurations. I'm sure no one noticed the down time but I did use this as an opportunity to make the followjng changes: - -- matrix-synapse upgrade to dendrite for better performance. -- Gitea to forgejo just to try something different. -- Properly set up actions to auto build and deploy site on push. -- Rework website and swap to the [terminal hugo theme](https://forge.alexselimov.com/aselimov/Terminal-Hugo-Theme) - -So far, I have positive opinions of all of my changes and highly recommend dendrite and forgejo. - - **Note to self: Never consider it upgrading Debian version. Always structure it as a migration to newer Debian version to avoid downtime** diff --git a/content/posts/gitea.md b/content/posts/gitea.md index b468292..c65c11a 100644 --- a/content/posts/gitea.md +++ b/content/posts/gitea.md @@ -1,7 +1,7 @@ --- title: "Hosting your own git frontend service using Gitea" date: 2023-02-25T10:19:50-05:00 -tags: ['git', 'self-host'] +topics: ['git', 'self-host'] --- I recently had interest in starting to work on the implementation of the [Concurrent Atomistic-Continuum Method](https://doi.org/10.1063/1.5099653) using C++ to take advantage of GPU acceleration. diff --git a/content/posts/highlighedmenu.md b/content/posts/highlighedmenu.md index aadeba2..41edaa8 100644 --- a/content/posts/highlighedmenu.md +++ b/content/posts/highlighedmenu.md @@ -1,7 +1,7 @@ --- title: "Highlighting the active menu item in Hugo" date: 2023-07-03T22:19:00-04:00 -tags: ['hugo','web design'] +topics: ['hugo','web design'] --- I've recently been developing sites for some family/friends. diff --git a/content/posts/java_dev_problems.md b/content/posts/java_dev_problems.md index e56c5d5..ea8e496 100644 --- a/content/posts/java_dev_problems.md +++ b/content/posts/java_dev_problems.md @@ -1,7 +1,7 @@ --- title: "Solutions to problems with Java Development" date: 2024-05-12T20:03:17-04:00 -tags: ['Java', 'software development', 'Neovim'] +topics: ['Java', 'software development', 'Neovim'] --- I recently ran into some problems with java development. diff --git a/content/posts/leaving_artix_for_void.md b/content/posts/leaving_artix_for_void.md index d5e91c8..525dfa8 100644 --- a/content/posts/leaving_artix_for_void.md +++ b/content/posts/leaving_artix_for_void.md @@ -1,7 +1,7 @@ --- title: "Why I left Artix for Void Linux" date: 2024-01-05T21:46:58-05:00 -tags: ['Artix', 'Void Linux', 'Linux', 'Opinions'] +topics: ['Artix', 'Void Linux', 'Linux', 'Opinions'] --- This is going to be primarily opinion based post but I want to talk about a shakeup that has happened. diff --git a/content/posts/let_no_crisis_go_to_waste.md b/content/posts/let_no_crisis_go_to_waste.md deleted file mode 100644 index 0aef5d6..0000000 --- a/content/posts/let_no_crisis_go_to_waste.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "From AI doomer to handwriting code again" -date: 2026-03-29T10:53:45-04:00 -tags: ["LLM", "AI", "Life Optimization", "Productivity" ] ---- - -> Let no good crisis go to waste\ -> \-\- Winston Churchill [^1] - -I've been thinking about the above quote lately. -Normally this is applied in political contexts, but I think it does a good job describing the last couple of months for me. -For example, today I’ve been sick as a dog (probably with that new covid variant). -Normally I would be trying to speed things along by rotting my brain on YouTube or other pointless entertainment. -While there was some of that, I was really surprised to find myself wanting to write some code for a project I’m working on! And this wasn’t Agentic Engineering™. -I was enjoying writing good old-fashioned, organic, artisanal, free-range, handwritten code. -I knew I had to summarize (at least for myself) how exactly I got here. - -## **The “crisis”** - -Around last September I started working pretty hard in my free-time on a startup idea (state of idea still tbd). -Even though I’m anti-social media, I decided to swallow the poison pill and get on LinkedIn to try and build some early traction/validation. -When I got on, I started getting drowned by - -- “AI has made programmers obsolete.” -- “Agentic engineering is the future” -- “If you aren’t orchestrating agent swarms you are falling behind.” - -That started to raise some hairs and my anxiety. -Now at the time I was using Claude Code daily at work and for my personal project. -I noticed that Claude Code was decent at my work tasks but not very good at my more innovative personal tasks. -Then my feed started hitting me with news about the “inflection point” with Opus 4.6, full agent dev teams, mandated agentic engineering in big tech. -The news about Gas Town and Ralph Loops made me feel like I was falling behind. - -Personally I saw big workflow and productivity improvements with AI tools. -This was particularly around search and boilerplate generation. -Biggest use-case was copying patterns (although I always had to double-check it was actually implemented correctly). -When I tried doing more complex changes, I saw the LLMs struggle. -None of this suggested that full agent dev teams were actually feasible long-term. -So I thought this was a skill issue. - -Now I have two kids and my wife raises them full-time. -This means it’s on my shoulders to make sure we can eat and that we have a roof over our heads. -I really had to figure out some way of getting through the AI apocalypse intact. -I was mainly experimenting with different projects, different types of AI vibe coding (spec-driven, human in the loop, human-less Ralph loops). -I’ve seen [articles suggesting it wasn’t just me.](https://www.businessinsider.com/sober-startup-founders-younger-drinking-less-alcohol-2025-8?) -## **The realization that I'm spiraling** - -After several months of grinding with steadily growing anxiety, I came across Mitchell Hashimoto’s workflow. -I wrote another post about it [here](https://www.alexselimov.com/posts/ai_confession/). -This was the first time I was exposed to a serious guy who wasn’t on the AI will replace us hype train. -After this, I started paying attention to a lot more news that was also anti-hype: - -- [Mo Bitar](https://m.youtube.com/@atmoio), guy that talks a ton about AI code quality and, more importantly, the impact of AI on our own brains. -- [Commentary on Metr article](https://entropicthoughts.com/no-swe-bench-improvement) suggesting code quality from LLMs isn’t actually getting better. -- [Metr article](https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/) suggesting AI doesn’t actually improve productivity. -- [Armin Ronacher post](https://lucumr.pocoo.org/2026/1/18/agent-psychosis/) about comprehension debt and AI psychosis among vibe coders. - -Those resources, among others, talked me down from the doomer cliff I was on. -I’m a lot more pragmatic now. -Current AI can’t replace a good dev (it’s not a skill issue). -There is no guarantee one way or another that future AI will be able to replace a good dev (I lean towards it won’t be able to). -Regardless, the only thing I can do is continue to keep my coding skills sharp and keep using/exploring Claude code/codex, but without the anxiety. -I don't think it's worth learning the modern advanced agent orchestration techniques since best practices around LLM techniques are constantly changing. -In the last 6 months since I started paying attention, I've seen a lot of noise with different approaches. -Two major changes I can recall off the top of my head are: - -1. Claude.md is important, you can have claude generate it[^2] → agent generated Claude.md worsens results. Only good approach is minimal human generated[^3] -2. MCP is the best standard for calling external tools → clis are the best standard for calling external tools[^4]. - -There is no guarantee that the prompting/orchestration skills relevant now will be relevant to a future LLM that can fully autonomously generate robust, secure, and production ready code. -Those skills are also not relevant if LLMs continue to have the same issues they have today. -Either way it's still useful to continue writing code manually. -If LLMs don't get much better than demand for a dev that can actually write robust, secure, and production grade code will be high. -If they do get better, then at least I will have refined my taste. -I can always learn the advanced prompting/orchestrating skill-set later. - -## **The change** - -Was this roller-coaster of anxiety pointless? -I think the answer goes back to the quote of never letting a good crisis go to waste. -I used the stress and anxiety induced by all of this to develop a habit of daily project work and generated a backlog of projects to explore. -To try and find alternative approaches to surviving the AI apocalypse I decided to try publishing more writings (which I've been enjoying greatly). -These have replaced the ways I used to waste my time, which I think is a huge net positive. -The biggest change is just genuinely enjoying programming again. -I'm no longer spending my cognitive capacity on the soft LLM prompting skills[^5]. -Instead, I'm working on things I enjoy more like exploring new languages, developing my taste for code architecture, and solving hard technical problems myself. - -If you are worried about AI and the links I included above haven't convinced you otherwise, that's okay! -Just don't let a good crisis go to waste. -Use the motivating power of stress and anxiety to drive you instead of letting it stop you. -No matter how things play out, you will be better off! - - -[^1]: This is attributed to Winston Churchill although supposedly this attribution is in question. The source doesn't really matter to me though. -[^2]: The /init command generates an overview of the project structure and notes. This is still recommended by Anthropic in their [best practices](https://code.claude.com/docs/en/best-practices) -[^3]: From [Evaluating AGENTS.md: Are Repository-Level Context Files Helpful for Coding Agents?](https://arxiv.org/abs/2602.11988) -[^4]: [Cloudflare suggested](https://blog.cloudflare.com/code-mode/) that having LLMs generate code was a better approach to traditional MCP. -[^5]: I became an engineer for the hard technical skills, not to be a manager! diff --git a/content/posts/mac_style_copy_paste.md b/content/posts/mac_style_copy_paste.md deleted file mode 100644 index 22dd2ca..0000000 --- a/content/posts/mac_style_copy_paste.md +++ /dev/null @@ -1,53 +0,0 @@ -+++ -title = "Mac style copy/paste on Void Linux" -date = "2025-09-05T23:49:40-04:00" -topics = ["software development", "linux", "configurations"] -+++ - -{{< callout >}} -First version of this post was generated with LLMs before manual revision. See [this link](/posts/ai_confession/) for more details. -{{< /callout >}} - -Another quick post that may be useful to somebody else. -I've been working at UKG for about 4 months now. -In my work I use a Mac laptop. -I've tried my best to unify my configurations between my personal Linux system and the Mac dev machine provided by UKG to reduce headaches when having to switch from professional to personal projects. -This even went as far as trying to configure OpenBox to be more like the MacOS desktop environment (HA a big failed endeavour). -While I ultimately found peace with differences in desktop environments, there was another thing I found very hard to deal with. - -## Differences in Keybindings!! - -I made a lot of changes and compromises when setting up my Mac system and configuring my personal machine. -One notable change was swapping my main modkey for `dwm` from `Meta` to `Alt` to better mimic the Mac setup. -I tried doing the reverse of swapping `Option` and `Cmd` in Mac, but that was a really rough time. -I've also tried to keep many other keybindings, associated with things like moving windows or changing workspaces, consistent. -One thing that was causing endless headaches was copy and paste. -I don't know the exact count of times I've pressed `Alt+C` or `Alt+V` at home in vain, but it is certainly significant. -As a result I spent some time to figure out how to do this. - -## Final Solution - -I configure my `dwm` specific keybindings in my `config.h`, but for everything else I use `sxhkd`. -This allows me to more easily reload keybindings instead of having to cycle `dwm` and lose all of my window placements. -I highly recommend this kind of setup. -My final solution, added to my `sxhkdrc` is: - -``` - -alt + c - xclip -selection primary -o | xclip -selection clipboard -i - alt + v - sh -c 'xclip -selection clipboard -o | xclip -selection primary -i && xdotool click 2' -``` - - -I tried several other ways, most notable being just trying to send `Ctrl+C` when I pressed `Alt+C`, but nothing else worked. - -## How it works - -A quick description of how it works: - -- `Alt+C` takes the primary selection and copies it to the clipboard -- `Alt+V` takes the clipboard and copies it to the primary selection and then emulates a middle mouse button click to paste. - -I was hoping for a more elegant solution but ¯\_(ツ)_/¯ diff --git a/content/posts/misc_thoughts_ai.md b/content/posts/misc_thoughts_ai.md deleted file mode 100644 index 9046fed..0000000 --- a/content/posts/misc_thoughts_ai.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Misc thoughts on AI" -date: 2025-08-01T07:45:26-04:00 -tags: ['AI', 'Software development', 'LLMs'] - ---- - -## AI has become a very useful tool for me - -If you know me personally, you know that I've been pretty slow on the LLM/GenAI uptake. -At this point, however, if you are a software developer that isn't integrating GenAI tools into your workflow I think you are probably going to be left behind. -I've been playing around with these tools a lot more lately, and I've come to a few conclusions. - - -1. Models that can be run locally (I've used a lot of different Ollama models) are mainly just ok. The best results I've had is with Gemma3:27b on an m4 macbook. Haven't tried qwen3 coder yet. -2. The amazing metrics you see referenced require 100b+ models that are not going to be feasible to run locally for most people. -3. Your application matters a lot. I find that these tools are extremely useful for java spring boot microservices but a lot less useful for scientific projects in Rust. -4. I really enjoy using the expensive LLM tools provided at work and enjoy using the free version of tools less. -5. Claude has given me the best performance so far. - -I'm still debating which subscription to get for personal projects. -I know Claude is my favorite, but it's also much more expensive. -I also have a newborn right now and not much time for side projects, so I'm delaying the decision. - - -## AI has NOT become an irreplaceable tool - -I am not a vibe coder and don't think I will ever give in to the vibes. -Even when I prompt claude code to make changes, I always know exactly what I want done and how I want it done. -Many times I'll make the changes myself because it's faster than trying to prompt Claude. -LLMs have definitely improved my efficiency, but I would be fine if all the GPUs in the world suddenly melted down. -I'm not a viber for a couple reasons: - -1. I enjoy coding and problem solving. -2. I'm not convinced models are capable enough to be fully trusted. -3. I want to keep my own skillset because the future of AI is uncertain to me - -## How does the economics of AI work? - -From my very limited understanding, the fact that major AI companies are still requiring funding rounds indicates that AI is currently not profitable. -That makes sense to me since ChatGPT and Claude are available for free even though inference is certainly not free. -I think the significant portion of cost is due to model training. -It seems like model training costs won't be stopping anytime soon as companies race towards general and then "super" intelligence. -I'm not convinced either of those are a given. -As a result, prices will have to increase or ads will be introduced to recuperate investor money. -I'm also not sure how this applies to providers of open weight models. -Those prices can seem more reasonable, but are those subsidized as well? Finally, the current datacenter power consumption for model training seems entirely unsustainable. -If I recall correctly, Elon Musk is powering some of his datacenters with a constant flow of diesel fuel into generators because he can't get enough power from the power grid. -The scale of everything at the moment seems to border absurdity. -I think we are in for a bumpy ride for the next few years as the impact of GenAI technology and infrastructure works itself out. - - -Please let me know if I'm wrong about anything or with better predictions! diff --git a/content/posts/mobile_navbar.md b/content/posts/mobile_navbar.md index f401f05..0d5b128 100644 --- a/content/posts/mobile_navbar.md +++ b/content/posts/mobile_navbar.md @@ -2,7 +2,7 @@ title: "Developing a mobile-friendly navigation menu for your website" date: 2023-02-13T11:13:34-05:00 toc: true -tags: ["web design", "css", "javascript"] +topics: ["web design", "css", "javascript"] --- I personally am a big fan of navbars as they are a clean way to navigate any website. diff --git a/content/posts/nvidia_cuda_sleep_issue.md b/content/posts/nvidia_cuda_sleep_issue.md deleted file mode 100644 index 6c57867..0000000 --- a/content/posts/nvidia_cuda_sleep_issue.md +++ /dev/null @@ -1,81 +0,0 @@ -+++ -title = "NVIDIA graphics card faulting after sleep/wake cycle on Void Linux" -date = "2025-09-04T19:44:19-04:00" -topics = ["software development", "CUDA"] -+++ - -{{< callout >}} -First version of this post was generated with LLMs before manual revision. See [this link](/posts/ai_confession/) for more details. -{{< /callout >}} - -I run Void Linux on a Thinkpad T480 with Integrated Intel graphics and a discrete Nvidia MX150. I've decided to start working with more CUDA development and was running into an issue where my Nvidia GPU would suddenly stop being detected by CUDA applications. The only way I could figure out to get it back online was by rebooting my computer. Eventually I became so frustrated that I decided to dive in and find a solution. - -## The Problem - -Here's what I was experiencing: - -- GPU appeared normal in `nvidia-smi` -- All NVIDIA kernel modules were loaded correctly -- Device files in `/dev/nvidia*` existed with proper permissions -- But testing CUDA availability using Pytorch, by running the following command would return FAlSE: - -```python - python -c "import torch; print(torch.cuda.is_available())" -``` - -The root cause was eventually found in the kernel logs (`dmesg`): - -``` -NVRM: Xid (PCI:0000:01:00): 31, pid=1596, name=modprobe, Ch 00000003, -intr 10000000. MMU Fault: ENGINE HOST6 HUBCLIENT_HOST faulted @ 0x1_01010000. -Fault is of type FAULT_PDE ACCESS_TYPE_READ - -NVRM: Xid (PCI:0000:01:00): 154, GPU recovery action changed from 0x0 (None) -to 0x2 (Node Reboot Required) -``` - -## The Root Cause - -The issue stems from NVIDIA GPU memory management during sleep/resume cycles. When the system suspends: - -1. The GPU's memory mappings and contexts can become corrupted -2. The GPU's Memory Management Unit (MMU) enters a faulted state -3. While the driver stack appears to reload correctly, the GPU hardware itself is in an inconsistent state -4. CUDA runtime fails to initialize because it can't establish proper memory contexts - -This seems to be common on mobile NVIDIA GPUs (like the MX series) in laptops with hybrid graphics setups running Linux. -At least, I've seen a few postings about this. - -## The Solution - -The fix is to add these parameters to your kernel command line in `/etc/default/grub`: - -```bash -GRUB_CMDLINE_LINUX_DEFAULT="... nvidia-drm.modeset=1 nvidia.NVreg_PreserveVideoMemoryAllocations=1" -``` - -Then update GRUB: - -```bash -sudo update-grub -``` - -And reboot to apply the changes. - -### What These Parameters Do - -- **`nvidia-drm.modeset=1`**: Enables kernel mode setting for the NVIDIA driver, providing better integration with the display subsystem and more robust power management -- **`nvidia.NVreg_PreserveVideoMemoryAllocations=1`**: Tells the NVIDIA driver to preserve GPU memory allocations across suspend/resume cycles, preventing the MMU faults - -## Why This Works - -These parameters ensure that: - -1. GPU memory contexts are properly preserved during sleep -2. The kernel's display management system maintains better control over the GPU state -3. Memory mappings remain consistent across suspend/resume cycles -4. The GPU's MMU doesn't enter the faulted state that breaks CUDA - -## Conclusion - -Haven't had an issue since making this fix! Hopefully someone else can benefit from this as well! diff --git a/content/posts/ppv.md b/content/posts/ppv.md deleted file mode 100644 index af6c6c0..0000000 --- a/content/posts/ppv.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: "Pillars, Pipelines, and Vaults System by August Bradley" -date: 2025-09-23T21:22:45-04:00 -tags: ["life optimization", "productivity", "self-reflection"] - ---- - -{{< callout >}} -First version of this post was generated with LLMs before manual revision. See [this link](/posts/ai_confession/) for more details. -{{< /callout >}} - -## What motivated me to try it - -I somehow recently accidentally stumbled across the Pillars, Pipelines, and Vaults (PPV) system by August Bradley. -In a nutshell, this system is a way to align your daily efforts to the pursuit of goals that contribute to core areas of your life (the pillars). -As a husband and the father of a toddler and an infant, the free time that I previously had in excess has been scarce. -My routines and schedules were extremely disrupted as I transitioned from my life as a PhD student to working a 9-5 and raising a family (my first child was born exactly one week after my dissertation defense). -These routines never truly recovered. -As a result, when I do come across some free time I find that I often don't know what to do with it. -I also am guilty of jumping from project to project without focus, leaving things half finished or skills incompletely developed. - -## I've tried a few different methods for improving focus and alignment, but nothing ever really stuck. - -I've been learning about the PPV system and have noticed some positive effects already. -Primarily around self-reflection, ensuring daily tasks are aligned to what is important, and ensuring that my effort towards things important to me is getting tracked. -I'm halfway through the [PPV playlist](https://www.youtube.com/playlist?list=PLAl0gPKnL3V8s7dPXoo07mYnuErhWVk8b) and have started building out my personal PPV system. -So far I recommend it. -I definitely think that it needs per-user customization as I am not August Bradley, and his priorities won't directly translate to me. -But some of the overarching concepts I find extremely useful: - -- You should define a small set of "pillars" that hold up your life (e.g. career, family, learning, personal projects, etc...) -- Ensure that your daily actions and goals are aligned to those pillars -- The action zone concept is fairly genius and has certainly led to improved focus for me. - - -## I, of course, am not actually implementing these systems in Notion directly - -Instead, I found a FOSS alternative called [anytype](https://anytype.io/). -I tried some other FOSS options like AppFlowy and AFFiNE. -AFFiNE struggled from: - -- UI that was cramming in their AI service everywhere, and it couldn't be disabled. -- Some concerns about how their telemetry works, [see this github issue](https://github.com/toeverything/AFFiNE/issues/6920) - -AppFlowy was pretty clean but I wasn't able to get the self-hosted AppFlowy-Cloud setup. -I've yet to self-host a node for anytype. -It uses a P2P protocol to synchronize spaces between devices which seems to make the self-hosting more complex. -I plan to upload an additional guide if I find it difficult to set-up. - -## Conclusion - -If you haven't heard about PPV, definitely check it out [here](https://www.youtube.com/playlist?list=PLAl0gPKnL3V8s7dPXoo07mYnuErhWVk8b)! -It isn't for everyone, but I've seen the benefits already in my limited time using it. -I may do a dive into my personal flavor of PPV and how I deviated from the original once it is fully completed. -Hopefully this is helpful to someone! - diff --git a/content/posts/pull_files_into_submodule.md b/content/posts/pull_files_into_submodule.md index 8ac2ecf..0153ea7 100644 --- a/content/posts/pull_files_into_submodule.md +++ b/content/posts/pull_files_into_submodule.md @@ -1,7 +1,7 @@ --- title: "Separate files from git repo into a submodule" date: 2023-02-22T20:31:34-05:00 -tags: ["git", "software development"] +topics: ["git", "software development"] --- I recently had a situation where a library I was working on, originally as part of one project, was going to be needed for another project. diff --git a/content/posts/st_to_ghostty.md b/content/posts/st_to_ghostty.md deleted file mode 100644 index 786bcab..0000000 --- a/content/posts/st_to_ghostty.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: "Say goodbye to st and say hello to ghostty" -date: 2025-09-10T23:16:26-04:00 -tags: [software development, linux, tools] ---- - -{{< callout >}} -First version of this post was generated with LLMs before manual revision. See [this link](/posts/ai_confession/) for more details. -{{< /callout >}} - -I've been a suckless software user for a long time because the software was superior to a lot of other options out there. -If you have never experienced the blazing fast speed of `st` opening, you are definitely missing out. -Sadly it was time for me to leave `st` behind and move on to a new terminal that I think offers a lot of benefits. - -## Why I Liked st - -- **Speed.** `st` launches instantly -- **Config as code is cool.** That combined with the patching culture really provides some fun puzzles. Who knew reading your terminal source code to fix a broken patch could be so fun. -- **DWM swallow patch compatibility.** If you use the swallow patch, st works flawlessly. - -## Why I Switched to ghostty - -- **Time constraints.** Two kids means no time to debug patches and code when I want modern features like ligatures. -- **Modern niceties.** Ligatures and images in terminal are supported out of the box. I spent way too long trying to unsuccessfully get sixel support in st. -- **Cross-platform config.** Same configuration file on both Linux and work Mac. Reduces burden of swapping dev environments. -- **Swallowing compatibility.** Unlike WezTerm and others, ghostty plays nice with DWM's swallow patch. Since WezTerm uses existing terminals to create new terminals, the process tree for the swallow patch gets messed up. This leads to the wrong terminal windows getting swallowed which is very frustrating. -- **Fast enough.** Noticeably slower to start than st but faster than everything else I've tried. - - -I definitely think I'm losing cool points by swapping from my handcrafted `st` build, but priorities change and the `ghostty` guy is pretty cool. -Hopefully this doesn't commence my slide down the slippery slope straight into an Apple Store *shudder*. - -``` - ==**=*x=====================ox*=**==xo - ox==**=*x ox*=**==xo - ++**+= =+**++ - ==== ~+%$@@@@@@@@@@@@@@$%+~ ==== - ===+ x%@@@@@$$$$$$$$$$$$$$$$@@@@@%x +=== - ===+ +@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$@@@@+ +=== - ++=+ %@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@% +=++ - ox== %@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@% ==xx - ==+x x@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@x x+== -xx== %@$$$$@@@@$$$$$$$$$$$$$$$$$$$$@@@@$$$$$$$$$$$$$$@% ==xo -++++ %@$$$@@+~o=@@@@$$$$$$$$$$$$$$@@+~o*@@@@$$$$$$$$$$$@% ++++ -==+· x@$$$$$ ~*@@@@$$$$$$$$$$% o*@@@@$$$$$$$$@x ·+== -== @$$$$$$ ~*@@@$$$$$$$% o%@@@$$$$$$@ == -== $$$$$$$@=· =$$$$$$$@@= *$$$$$$$ == -== ·@$$$$$$$@@@@+ $$$$$$$$$@@@@x $$$$$$@· == -== ·@$$$$$$@$x o$$$$$$$@@$x x$$$$$$@· == -== ·@$$$$$$ x$@@$$$$$$$$ +$@@$$$$$$@· == -== ·@$$$$@$ x%@@@@$$$$$$$$@% x$@@@@$$$$$$$$@· == -== ·@$$$$$@$~ x%@@@@$$$$$$$$$$$$$@%· x%@@@@$$$$$$$$$$$$@· == -== ·@$$$$$$@@@@@@$$$$$$$$$$$$$$$$$$@@@@@@$$$$$$$$$$$$$$$$@· == -== ·@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@· == -== ·@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@· == -== ·@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@· == -== ·@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@· == -== ·@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@· == -== ·@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@· == -== ·@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@· == -== ·@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@· == -== ~$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$~ == -== @@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@ == -==+· %@@@$$$$$$$$@@@$$$@@@@$$$$$$$$@@@@$$$@@@$$$$$$$$@@@% ·+== -x+== +$@@@@@@@$+ o%@@@@@@@@*~ =$@@@@@@@$+ ==xx - ===+ +=== - ==== ==%%++ ++%%== ==== - ++**=***++==%***==++***%**++++*=%**=++==***%==++**%=**++ - x+++==++++ x+++++==++xx ++++++++++ -``` diff --git a/content/posts/thoughts_on_rust.md b/content/posts/thoughts_on_rust.md index 1e27405..ba70e96 100644 --- a/content/posts/thoughts_on_rust.md +++ b/content/posts/thoughts_on_rust.md @@ -1,7 +1,7 @@ --- title: "Rust is pretty good (Short thoughts on Rust)" date: 2024-04-09T21:31:01-04:00 -tags: ['rust', 'Opinions', 'software development'] +topics: ['rust', 'Opinions', 'software development'] --- In my current position I've had to swap to full time Rust development. diff --git a/content/posts/tmux_and_nvim.md b/content/posts/tmux_and_nvim.md index 8b43690..c336f25 100644 --- a/content/posts/tmux_and_nvim.md +++ b/content/posts/tmux_and_nvim.md @@ -1,7 +1,7 @@ --- title: "My nvim/tmux workflow" date: 2024-03-04T21:44:00-05:00 -tags: [software development, neovim, tmux] +topics: [software development, neovim, tmux] --- At my previous employment I was forced to use a windows system. diff --git a/content/posts/upvoters.md b/content/posts/upvoters.md deleted file mode 100644 index e61232e..0000000 --- a/content/posts/upvoters.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: "Upvoters - Small rust back-end for anonymous likes on static blogs" -date: 2026-03-21T22:47:50-04:00 -tags: ["Rust", "Hugo", "Web Design", "Self-Host"] ---- - -## Long Story Short - -I wrote a little system called [upvoters](https://github.com/aselimov/upvoters) in Rust to handle anonymous upvotes, and it's compatible with Hugo! -In fact, you should see a little chevron at the bottom of this post to upvote if you like it. -Check it out if you need something like it! - -## Motivation - -I've been working on some website refactors/design changes lately. -My taste has been influenced recently. -I may at some point write something about my taste evolution. -The tl;dr for that article is that I came across an article on [Armin Ronacher's blog](https://lucumr.pocoo.org/about/) and was hugely affected. -I've been trying to use my little piece of internet land to serve an aesthetic, technical, and minimal blog and his site is what I wish mine was. - -While I don't have all of Armin's experience or skills, I thought I could at least try to give off a similar vibe with my own site. -I use Hugo to generate my static blog, so my first try was searching through existing Hugo themes to get a starting point. -The rest of the story I think works better as an enumeration: - -1. Came across the [hugo-bearcub theme](https://github.com/clente/hugo-bearcub) by clente. -2. Looked up [Bear Blog](https://bearblog.dev/). -3. Looked up the creator of Bear Blog, [Herman Martinus](https://herman.bearblog.dev/). -4. Read through some of his posts and noticed his little anonymous upvote button. -5. Thought the anonymous upvote button was super cool and wanted my own. - -## Upvoters - -I then spent a couple hours putting together `upvoters`, a little Rust web server to handle this functionality. -I picked postgres for the db because I run this site (and a few other services like email, matrix, [forgejo](https://forge.alexselimov.com), etc...) using a VPS that already had a postgres setup. -Probably could've just done SQLite to make it easier on everyone but didn't think about that until later. - -This service just tracks votes in a single table with the following important variables in the schema: - -1. `slug`: A unique identifier for each post that is just created from the URL. -2. `voter_id`: A unique identifier for each voter. - -Since this is just a personal blog, and exact upvote count doesn't matter, the `voter_id` is a UUID assigned to each user as a cookie upon the first vote. -Obviously all it takes to "break" the system is clearing your cookies. -This would allow you to upvote the same post multiple times but the only risk there is me getting delusions of grandeur. - -## Getting started with it - -I wrote some instructions in the [upvoters](https://github.com/aselimov/upvoters) readme, but also feel free to email me if you need help setting it up! - diff --git a/content/posts/valgrind-artix-linux.md b/content/posts/valgrind-artix-linux.md index 3d327a1..78443d3 100644 --- a/content/posts/valgrind-artix-linux.md +++ b/content/posts/valgrind-artix-linux.md @@ -1,7 +1,7 @@ --- title: "Gettting Valgrind working on Artix Linux" date: 2023-08-29T21:38:32-04:00 -tags: ['software development', 'linux', 'Artix'] +topics: ['software development', 'linux', 'Artix'] --- I'm currently working on developing an implementation of the Concurrent Atomistic-Continuum method using C++ and CUDA to accelerate calculations. diff --git a/content/posts/web_obesity.md b/content/posts/web_obesity.md index d2af9d8..03f75de 100644 --- a/content/posts/web_obesity.md +++ b/content/posts/web_obesity.md @@ -2,7 +2,7 @@ title: "Fighting the web obesity crisis using Hugo and Skeleton CSS" date: 2023-02-12T12:45:48-05:00 toc: true -tags: ["css","web design","hugo", 'self-host'] +topics: ["css","web design","hugo", 'self-host'] --- diff --git a/content/projects.md b/content/projects.md deleted file mode 100644 index 6a1d437..0000000 --- a/content/projects.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "Projects" -hideDate: true -hideUpvotes: true -hideReply: true ---- - -Here are some of the projects I am working or have worked on: - -**Scientific** - -- [CAC ← Implementation of the Concurrent Atomistic Continuum method](https://forge.alexselimov.com/aselimov/CAC) -- [CACmb ← Model builder for CAC (inspired by atomsk)](https://forge.alexselimov.com/aselimov/CACmb) - -**Random** - -- [neovim configs](https://forge.alexselimov.com/aselimov/neovim) -- [PaperPicker ← Use local llms to find relevant arxiv papers](https://github.com/aselimov/PaperPicker.git) -- [upvoters ← Rust backend with postgres to handle anonymous upvotes on this blog](https://forge.alexselimov.com/aselimov/upvoters) diff --git a/favicon.svg b/favicon.svg deleted file mode 100644 index 54cfd79..0000000 --- a/favicon.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - $AS - - diff --git a/hugo.toml b/hugo.toml index bfa2da0..2a85f9b 100644 --- a/hugo.toml +++ b/hugo.toml @@ -1,20 +1,17 @@ -baseURL = "https://www.alexselimov.com/" -languageCode = "en-US" -theme = "hugo-bearcub" -defaultContentLanguage = "en" -copyright = "© Alex Selimov" -enableRobotsTXT = true +baseurl = "https://www.alexselimov.com/" +languageCode = "en-us" +theme = "hugo-theme-terminal" +pagination.pagerSize = 5 -[pagination] -pagerSize = 10 - -[markup] [markup.goldmark.renderer] unsafe = true -[markup.highlight] -lineNos = true -lineNumbersInTable = false -noClasses = false + +[params] +contentTypeName = "posts" +showMenuItems = 5 +postsToShowOnIndex = 3 +fullWidthTheme = false +centerTheme = true [taxonomies] tag = "tags" @@ -23,38 +20,32 @@ topic = "topics" [languages] [languages.en] title = "Alex Selimov" -languageName = "en-US" -languageCode = "en-US" +subtitle = "" +keywords = "" +copyright = "© Alex Selimov" + +[languages.en.params] +menuMore = "Show more" +readMore = "Read more" +readOtherPosts = "Read other posts" + +[languages.en.params.logo] +logoText = "Alex Selimov" +logoHomeLink = "/" + [languages.en.menu] [[languages.en.menu.main]] -identifier = "home" -name = "Home" -url = "/" -weight = 1 -[[languages.en.menu.main]] -identifier = "projects" -name = "Projects" -url = "/projects/" -weight = 2 -[[languages.en.menu.main]] identifier = "about" -name = "About" -url = "/about/" -weight = 3 - -[params] -description = "Alex Selimov personal site and blog." -title = "Alex Selimov" -favicon = "favicon.png" -images = ["og-image.png"] -dateFormat = "2006-01-02" -hideUntranslated = false -themeStyle = "herman" -generateSocialCard = true -postsToShowOnIndex = 10 -upvotes = true -upvoteApi = "https://www.alexselimov.com/api" - -[params.author] -name = "Alex Selimov" -email = "alex@alexselimov.com" +name = "[About Me]" +url = "/about" +weight = 10 +[[languages.en.menu.main]] +identifier = "cv" +name = "[CV]" +url = "/cv" +weight = 10 +[[languages.en.menu.main]] +identifier = "git" +name = "[Git]" +url = "https://forge.alexselimov.com/aselimov" +weight = 10 diff --git a/layouts/page/presentation.html b/layouts/page/presentation.html new file mode 100644 index 0000000..9eda755 --- /dev/null +++ b/layouts/page/presentation.html @@ -0,0 +1,5 @@ + diff --git a/layouts/partials/custom_head.html b/layouts/partials/custom_head.html deleted file mode 100644 index d0d59f9..0000000 --- a/layouts/partials/custom_head.html +++ /dev/null @@ -1,4 +0,0 @@ -{{ $autoTheme := resources.Get "auto-theme.css" | minify }} - - - diff --git a/layouts/shortcodes/callout.html b/layouts/shortcodes/callout.html deleted file mode 100644 index 03dbc3f..0000000 --- a/layouts/shortcodes/callout.html +++ /dev/null @@ -1 +0,0 @@ -
{{ .Inner | markdownify }}
diff --git a/layouts/shortcodes/fontawesome.html b/layouts/shortcodes/fontawesome.html new file mode 100644 index 0000000..7e68a9c --- /dev/null +++ b/layouts/shortcodes/fontawesome.html @@ -0,0 +1 @@ + diff --git a/layouts/shortcodes/img.html b/layouts/shortcodes/img.html new file mode 100644 index 0000000..86148b3 --- /dev/null +++ b/layouts/shortcodes/img.html @@ -0,0 +1,6 @@ +
+ +
diff --git a/layouts/shortcodes/presentations.html b/layouts/shortcodes/presentations.html new file mode 100644 index 0000000..9e7e7d8 --- /dev/null +++ b/layouts/shortcodes/presentations.html @@ -0,0 +1,6 @@ + diff --git a/layouts/shortcodes/publications.html b/layouts/shortcodes/publications.html new file mode 100644 index 0000000..ce11be6 --- /dev/null +++ b/layouts/shortcodes/publications.html @@ -0,0 +1,5 @@ + diff --git a/.hugo_build.lock b/layouts/shortcodes/recent-articles.html similarity index 100% rename from .hugo_build.lock rename to layouts/shortcodes/recent-articles.html diff --git a/scripts/generate_triangulated_mesh.py b/scripts/generate_triangulated_mesh.py deleted file mode 100644 index fa36ce1..0000000 --- a/scripts/generate_triangulated_mesh.py +++ /dev/null @@ -1,235 +0,0 @@ -#!/usr/bin/env python3 -"""Generate a triangulated mesh graphic as an SVG file. - -Example: - python scripts/generate_triangulated_mesh.py --width 1920 --height 1080 --output mesh.svg -""" - -from __future__ import annotations - -import argparse -import math -import random -from dataclasses import dataclass -from pathlib import Path - - -@dataclass(frozen=True) -class Point: - x: float - y: float - - -def clamp(value: float, low: float, high: float) -> float: - return max(low, min(high, value)) - - -def parse_args() -> argparse.Namespace: - parser = argparse.ArgumentParser(description="Generate a triangulated mesh SVG.") - parser.add_argument("--width", type=int, required=True, help="Graphic width in pixels.") - parser.add_argument("--height", type=int, required=True, help="Graphic height in pixels.") - parser.add_argument( - "--output", - type=Path, - default=Path("triangulated-mesh.svg"), - help="Output SVG path (default: triangulated-mesh.svg)", - ) - parser.add_argument( - "--cell-size", - type=float, - default=120.0, - help="Approximate grid cell size in pixels when x/y step are not set.", - ) - parser.add_argument( - "--x-step", - type=float, - default=None, - help="Horizontal point spacing in pixels (overrides --cell-size on x-axis).", - ) - parser.add_argument( - "--y-step", - type=float, - default=None, - help="Vertical point spacing in pixels (overrides --cell-size on y-axis).", - ) - parser.add_argument( - "--jitter", - type=float, - default=0.35, - help="Point jitter amount as a fraction of cell size (0.0-0.5).", - ) - parser.add_argument( - "--seed", - type=int, - default=None, - help="Random seed for reproducible output.", - ) - parser.add_argument( - "--stroke", - type=float, - default=1.25, - help="Edge stroke width in pixels.", - ) - parser.add_argument( - "--dot-radius", - type=float, - default=1.9, - help="Vertex dot radius in pixels.", - ) - parser.add_argument( - "--line-color", - type=str, - default="#334155", - help="Edge color as hex (default: #334155).", - ) - parser.add_argument( - "--dot-color", - type=str, - default="#0f172a", - help="Dot color as hex (default: #0f172a).", - ) - parser.add_argument( - "--background", - type=str, - default="#f8fafc", - help="Background color as hex (default: #f8fafc).", - ) - return parser.parse_args() - - -def build_points( - width: int, - height: int, - x_step: float, - y_step: float, - jitter_frac: float, - rng: random.Random, -) -> list[list[Point]]: - cols = max(2, math.ceil(width / x_step) + 1) - rows = max(2, math.ceil(height / y_step) + 1) - - points: list[list[Point]] = [] - jitter = clamp(jitter_frac, 0.0, 0.5) * min(x_step, y_step) - - for row in range(rows): - y = (height * row) / (rows - 1) - row_points: list[Point] = [] - for col in range(cols): - x = (width * col) / (cols - 1) - - # Keep border anchored to make the mesh fill the canvas cleanly. - if 0 < row < rows - 1 and 0 < col < cols - 1: - x += rng.uniform(-jitter, jitter) - y_jittered = y + rng.uniform(-jitter, jitter) - else: - y_jittered = y - - row_points.append(Point(x=clamp(x, 0.0, float(width)), y=clamp(y_jittered, 0.0, float(height)))) - points.append(row_points) - - return points - - -def generate_triangles(points: list[list[Point]], rng: random.Random) -> list[tuple[Point, Point, Point]]: - triangles: list[tuple[Point, Point, Point]] = [] - rows = len(points) - cols = len(points[0]) if rows else 0 - - for row in range(rows - 1): - for col in range(cols - 1): - p00 = points[row][col] - p10 = points[row][col + 1] - p01 = points[row + 1][col] - p11 = points[row + 1][col + 1] - - if rng.random() < 0.5: - triangles.append((p00, p10, p11)) - triangles.append((p00, p11, p01)) - else: - triangles.append((p00, p10, p01)) - triangles.append((p10, p11, p01)) - - return triangles - - -def svg_polygon(points: tuple[Point, Point, Point], stroke: str, stroke_width: float) -> str: - pts = " ".join(f"{p.x:.2f},{p.y:.2f}" for p in points) - return ( - f'' - ) - - -def write_svg( - width: int, - height: int, - triangles: list[tuple[Point, Point, Point]], - stroke_width: float, - dot_radius: float, - line_color: str, - dot_color: str, - background: str, - output: Path, - points: list[list[Point]], -) -> None: - elements: list[str] = [] - - for tri in triangles: - elements.append(svg_polygon(tri, stroke=line_color, stroke_width=stroke_width)) - - circles: list[str] = [] - for row in points: - for p in row: - circles.append(f'') - - svg = "\n".join( - [ - '', - f'', - f'', - *elements, - *circles, - "", - ] - ) - - output.parent.mkdir(parents=True, exist_ok=True) - output.write_text(svg, encoding="utf-8") - - -def main() -> None: - args = parse_args() - - if args.width <= 0 or args.height <= 0: - raise SystemExit("--width and --height must be positive integers") - - if args.cell_size <= 1: - raise SystemExit("--cell-size must be > 1") - - x_step = args.x_step if args.x_step is not None else args.cell_size - y_step = args.y_step if args.y_step is not None else args.cell_size - - if x_step <= 1 or y_step <= 1: - raise SystemExit("--x-step and --y-step must be > 1") - - rng = random.Random(args.seed) - points = build_points(args.width, args.height, x_step, y_step, args.jitter, rng) - triangles = generate_triangles(points, rng) - write_svg( - args.width, - args.height, - triangles, - args.stroke, - args.dot_radius, - args.line_color, - args.dot_color, - args.background, - args.output, - points, - ) - - print(f"Generated {len(triangles)} triangles -> {args.output}") - - -if __name__ == "__main__": - main() diff --git a/static/favicon.png b/static/favicon.png index f6b7405..3d9a71a 100644 Binary files a/static/favicon.png and b/static/favicon.png differ diff --git a/static/profile.webp b/static/profile.webp deleted file mode 100644 index e46ba1b..0000000 Binary files a/static/profile.webp and /dev/null differ diff --git a/static/public.key b/static/public.key deleted file mode 100644 index 4af9c07..0000000 --- a/static/public.key +++ /dev/null @@ -1,41 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -mQGNBF+bKU8BDADTiLgohwLsqQimXPiRQyjD/Z7XysupX+TeHJ8rxduO3Mvj0Z8i -kfxQYunWX5kAQjgwW/Coh0NuSyVioJ6iOtXurOYmh1yQhECrEo27pBKAcT6kgfae -BrbZ8oRDCJQDxqviQZAe7YaXScjpZZ1nUZW2FI0Aw+dNyaN+jqjIMagHDsu/MCUW -BpNwfbjyBRJ9jdlye/YYBWS2YQAoNzs/u7JxN7H3pa+nZlGNvokdN3vW3CApTFOJ -eJB4h7BxLHVGNjGbP7Yjz+9oZxRKx/ELYqFSRF/0Mh7+whpaN3bh0XTLIC6kLqdm -6stQq54ZTtRRrHmr5VUvgos12YxjW22eX6HK03dUj6oe0+POZp7M9ZcKhyPqHjzA -6UdDyEoumxXQCN++zY8oKwvwX0ibwnqWFKvpjkK43HWk5kZ3DMfk2LEELruXvmsA -hXdfFF2leGpojCZ86Q9abHKkrFarKrhpHV60qoPYLX9IpEafhA0ebG591TRIlT8W -yS7kxWZH77ZEXysAEQEAAbQjQWxleCBTZWxpbW92IDxhbGV4QGFsZXhzZWxpbW92 -Lnh5ej6JAdQEEwEIAD4WIQRW9MD5ina4RyXULgE925w+Aj8fMQUCX5spTwIbAwUJ -A8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRA925w+Aj8fMRu8DACxCb8Q -YXFtX8p+t0o3I8+uIy5GQrIVRIXFN1A3w7tjsDB4P/04h5pNgo4zrlMmOImeMj6t -wuHdIGFZWg931IuVVFnT7VrTYV/0CVV3DOOMnYVL3/4RYcmY59tJr+G3PusV04Uw -4v1YabMInBIhtGg3smUC0njpqnD30VOQ2xI+B8U1jT6AJ72ea+5a+fAJYQ74AQdv -kABwrWilrcI/IU2iH/VtigDY/XXehvmLLRkqkaWM29I2vJXlQoq1L12fXHrWWk/9 -zyxSQbzXSUARfd09WWz5kM03ubhmWBc8EAjzoO2PqOlaDPxylpc5EXK21isxPl00 -f53VQMdGKrbGHur/ZSyY2CzX5El+jzgWTa9KgiBNTV+No/pI4OC6y/nVCuncrFL8 -ZCzgZn4TvFrjX7O5/6XYVCUiSnDUkl9SDltvhdCmmB1UXxIFa32ME4MuNqYxgmx2 -05QmUQEhp4nK0bkNfz8Y6ZgJXNGO0rPDo7o+w5sZooRCRBMIuiaRWh4fTty5AY0E -X5spTwEMAMCUogK0opti5WgNsPZErT7wCe/yrbU8APpeKCBvbvCUW4w9370q+Ec4 -6PLz5z7Pzbtdo+Ddk2ilWZMDZI9dDmdunJZUu6GssipmSpx0nycFiM7ENmypz9y8 -u3b585vnIxD5jQD30EQTAr70TqgmXBHCT3SA0zbnj3zIROlgPcnSo3qoOKH6LMkb -up6cIbijfsdHJAFbRtYjgX9ym8OMYCNYyDU/7W9ybXhPyChw5/0Rvikwzr92ynnH -0WvxGpfle6YEzgCIxWq+8mpZ5zip3xHGkf09wgXpATIZVBJw2Undv/zP7HRnHr3P -qQ3Yk4d+pE3+IQA1YmsFmU582EEFfFLVTwQOUMXbQnSbZGJYiIPHHdCCTkJL9bWQ -OGjXntrHqi8ILLkhQ8M1DkY16twFvIHYxlA2okE7ca5N9r/WmqIvXe2BmbuiCB4r -OIyExKSwSuYphrTtEBqKaHVXwNKffRmEAgTGy2pPt7Z33J4aSsSoqGXaYe8HPw0C -2scTho8ouwARAQABiQG8BBgBCAAmFiEEVvTA+Yp2uEcl1C4BPducPgI/HzEFAl+b -KU8CGwwFCQPCZwAACgkQPducPgI/HzGFMAv/dmyaCg6Gw5C9LURI/HpO7rHPKmgt -db2HmUmFdcW/TUgJ1EoC413/s3orKk899DE4njxHO1hv/+H6Gf95L03KtVh4PgbI -Mh7n7KU7t0b6y4SqFAj0LNg01wiTjuv923KEzER4vaMmei+kg2kvqimaH5j3tIah -8nqtCLh5LO3vpk2XIThZuRVtmZ4Ux/VMl1BpnfBuJM8dvZRrEwCniEQGjmrvIELe -5uhEXIIwyNfT02b+0QmZakhcNVmUgG+jyjkGFWslvJKzlzSm9JR5blgcF2mD8fXF -CaKmLF1J2s6jnJbXo9k2P+iRV8UiGOZe550dC/N9l2j8skjrRfDUhf116O1sO/9F -dTzkB/u5jN3MStjZbZu27KLD5Ywv1+t3CpoGbHpmvKEFeq68x6QNzYS2S8D6Jczu -JfyTpSTHZGqbqqcJySDM+En1Xe+h6DhH0Dp6FgBPWycDurv7H/TEUjLFQTTG20/b -oOzx0x0y7ELQVGJVtpxqVxLcA58xJCE34I+h -=5X5g ------END PGP PUBLIC KEY BLOCK----- diff --git a/static/terminal.css b/static/terminal.css index d31310d..619e112 100644 --- a/static/terminal.css +++ b/static/terminal.css @@ -1,5 +1,5 @@ :root { --background: #191919; --foreground: #eceae5; - --accent: #EF9F27; + --accent: #88ae68; } diff --git a/themes/hugo-bearcub b/themes/hugo-bearcub deleted file mode 160000 index 17c78a6..0000000 --- a/themes/hugo-bearcub +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 17c78a6bcdc956b4cb720bcf23ef483d3f416a62 diff --git a/themes/hugo-theme-terminal b/themes/hugo-theme-terminal new file mode 160000 index 0000000..4e2b017 --- /dev/null +++ b/themes/hugo-theme-terminal @@ -0,0 +1 @@ +Subproject commit 4e2b01779a5d2cc1b869c6bce1edf4676a4684b9