I build AWS infrastructure and operate a self-hosted AI platform. My work connects deployment, security, debugging, and recovery—backed by source code and engineering records.
I built a console-based three-tier AWS environment, separating the web, application, and database layers.
VPC · EC2 · RDS · Security groups
AWS foundations · network boundaries
BrowserPublic request
↓ HTTP
VPC / PUBLIC SUBNET
Web EC2 / bastionPublic entry point
PRIVATE SUBNETS
Application EC2Application logic
↓ Database connection
RDS MySQLNo public database access
Simplified tier boundaries. This console project uses one web instance and one application instance; subnet coverage does not imply duplicated compute.
ENGINEERING TAKEAWAY
Network boundaries
Working through routing and security groups taught me to trace an application request across each tier.
PROJECT RECORDConsole-based AWS implementation
Build details & evidence +
Public and private subnets, a bastion, and isolated database access established the groundwork for my Terraform project.
Private application tierAuto Scaling across the two zones
↓ Restricted database access
Private RDS MySQLApplication data
Logical deployment view. Source configuration separates public web traffic, private application traffic, and database access.
ENGINEERING TAKEAWAY
Explicit dependencies
Writing infrastructure as code made me account for how networking, permissions, compute, and data depend on each other.
PROJECT RECORD6 subnets · 2 Availability Zones
Build details & evidence +
The project documents tiered security groups, Auto Scaling, S3, and Parameter Store. Moving from console setup to code made the infrastructure easier to review.
I connected Jenkins, Docker, ECR, and EKS to build, smoke-test, publish, and deploy a Node.js application.
Jenkins · Docker · EKS · Argo CD
Delivery pipeline · release and failure paths
Git commit → JenkinsCheckout and pipeline execution
↓ Build and smoke-test
Docker image → ECRTagged image published to the registry
↓ Deploy
EKS rollout validationWait for the deployment result
SUCCESS
Updated applicationNew image running
FAILURE
Diagnostics + rollback attemptRestore the prior image when available
The Jenkinsfile includes rollout checks, failure diagnostics, and conditional rollback logic. This describes the pipeline, not a guarantee of recovery.
ENGINEERING TAKEAWAY
Validate the rollout
A successful image build was only the start. The pipeline needed deployment checks and a rollback path when a rollout failed.
PROJECT RECORDRollout validation + rollback
Build details & evidence +
The EKS pipeline includes rollout validation and rollback. A separate Java project extended my delivery work into SonarQube, Argo CD, Prometheus, and Grafana.
Primary → secondary replicationS3 replication and RDS replica
CloudWatch / SNSMonitoring and notifications
Conceptual design from my project notes. The public repository does not yet contain implementation files; recovery times are not benchmarked.
ENGINEERING TAKEAWAY
Configuration must agree
An alarm-region mismatch reinforced the need to align resource locations, Terraform providers, and monitoring configuration.
PROJECT RECORDRegional recovery design
Build details & evidence +
The design uses S3 replication, an RDS replica, Route 53, and CloudWatch/SNS. Architecture and troubleshooting are documented in my project notes; the public README is minimal. Recovery times have not been benchmarked.
I designed and operated DAP on my Ubuntu homelab, owning its architecture, security boundaries, deployment decisions, testing, and release process. Local AI supports research and career workflows while final execution and application decisions stay with me.
FastAPI · Next.js · llama.cpp · Qdrant · Ubuntu
DAP · inference and controlled workflows
Owner dashboard / gatewayRequests and owner review
↓ DAP API and policy checks
INFERENCE
Model routerGeneral tasks → Granite / Coding → Qwen
Knowledge retrievalQdrant context
WORKFLOWS
Research and career toolingEvidence and proposed actions
Owner reviewFinal application and execution decisions
Authority boundaryModel output does not grant privileged system access
Logical overview based on my implementation records. Public documents below show earlier admission controls and reliability gates; they are not v2.2 release proof.
ENGINEERING TAKEAWAY
A timeout was a capacity-control problem.
I traced a Qwen request failure to a long completion, then introduced a server-controlled output limit. The lesson became a platform rule: generation capacity must be bounded.
I integrated a FastAPI backend, Next.js dashboard, Qdrant retrieval, Docker services, systemd workloads, Tailscale access, and research and career tooling. I adapted llama.cpp into intent-based routing between Granite for general tasks and Qwen Coder for coding, preserving safety metadata and separating inference from execution authority.
The Career Cockpit covers job discovery, evidence, ATS analysis, application materials, lifecycle tracking, owner review, and notifications. I deliberately excluded automatic job applications. Release work included recovery bundles, SHA-256 manifests, tagged releases, regression gates, reboot testing, runtime-drift investigations, and backup verification.
How I used AI—and retained control +
ChatGPT helped draft implementation approaches, code changes, test cases, threat models, shell verification procedures, and debugging hypotheses. I reviewed the plans, executed changes on my server, inspected the evidence, and retained final architecture, security, and release decisions.
AI did not have unrestricted shell, Docker, root, database, firewall, or deployment authority. My contribution combined design, integration, hands-on validation, and operational ownership with AI-assisted development.
INSIDE THE INVESTIGATION
The model was healthy. The request was unbounded.
Follow the evidence behind a 120-second timeout.
120s
Symptom
An explicit Qwen request hit the client’s 120-second timeout during v2.2 validation. I treated it as a failed release gate.
919 tokens
Evidence
I inspected systemd and router logs, llama.cpp logs, processes, RAM and swap, OOM events, model hashes, and request timing. Granite was evicted and Qwen loaded in about 19 seconds. Qwen then produced 919 tokens at roughly 6.7 tokens/second; recorded generation time was about 143 seconds.
No crash
Root cause
The model remained healthy. The long completion outlasted the client timeout. The later BrokenPipeError followed the client disconnect; it was not the initiating fault.
16.76s
Correction
I introduced a server-controlled output-token limit that public callers cannot arbitrarily raise. A bounded Granite-to-Qwen cold-switch test completed in 16.76 seconds with HTTP 200, preserved safety metadata, and 176 prompt + 9 completion = 185 total tokens.
These are separate runs with different output lengths. The successful test demonstrates bounded-request behavior, not an equivalent-workload speedup. Timings and token counts are from my project investigation records.
Release context +
I released v2.1 with a recovery and verification process. The earlier September 4 V2 milestone records 61 passing regression checks, a passing TypeScript check, and off-disk backup replication. The Qwen investigation belongs to v2.2 development and does not imply that v2.2 is released. The public main-branch README reflects an earlier roadmap.