{
    "ready": true,
    "site": {
        "id": 0,
        "domain": "downey.io",
        "display_name": "downey.io",
        "primary_country_code": "",
        "category_name": "Developer Tools: DevOps & Cloud"
    },
    "metrics": {
        "global_rank": 3314915,
        "country_rank": 1127071,
        "category_rank": 530386,
        "daily_pageviews_per_visitor": 4.53,
        "daily_time_on_site_seconds": 453,
        "bounce_rate": 21.06,
        "search_visits_percent": 40.86,
        "total_sites_linking_in": 1,
        "monthly_unique_visitors": 243,
        "recorded_at": "2026-04-30 23:03:34"
    },
    "audit": {
        "score": 93
    },
    "traffic_sources": {
        "direct_percent": 26.51,
        "search_percent": 36.7,
        "social_percent": 6.69,
        "referral_percent": 17.55,
        "email_percent": 5.58,
        "paid_percent": 6.97
    },
    "seo_profile": {
        "backlinks_total": 1,
        "referring_domains": 1,
        "dofollow_backlinks_percent": 100,
        "organic_keywords": 59,
        "indexed_pages": 67,
        "page_speed_score": 100,
        "mobile_friendliness_score": 86,
        "authority_score": 21,
        "spam_risk_score": 53
    },
    "crawl_report": {
        "robots_status": 200,
        "sitemap_status": 200,
        "sitemap_total_urls": 67,
        "crawl_blocked": false,
        "crawl_blocked_by": "",
        "crawl_blocked_reason": "",
        "notes": [],
        "created_at": "2026-04-30 23:03:34"
    },
    "keywords": [
        {
            "keyword": "downey.io",
            "position": 25,
            "search_engine": "Estimated",
            "checked_at": "2026-06-23 23:23:32",
            "is_estimated": true
        },
        {
            "keyword": "downey.io developer tools: devops & cloud",
            "position": 27,
            "search_engine": "Estimated",
            "checked_at": "2026-06-23 23:23:32",
            "is_estimated": true
        },
        {
            "keyword": "downey.io reviews",
            "position": 29,
            "search_engine": "Estimated",
            "checked_at": "2026-06-23 23:23:32",
            "is_estimated": true
        },
        {
            "keyword": "downey",
            "position": 31,
            "search_engine": "Estimated",
            "checked_at": "2026-06-23 23:23:32",
            "is_estimated": true
        },
        {
            "keyword": "blog",
            "position": 33,
            "search_engine": "Estimated",
            "checked_at": "2026-06-23 23:23:32",
            "is_estimated": true
        }
    ],
    "rating": {
        "overall": 46,
        "label": "Average",
        "breakdown": [
            {
                "label": "Technical foundation",
                "score": 17,
                "max": 18
            },
            {
                "label": "Authority & trust",
                "score": 6,
                "max": 30
            },
            {
                "label": "Reach & market presence",
                "score": 3,
                "max": 18
            },
            {
                "label": "Search visibility",
                "score": 3,
                "max": 12
            },
            {
                "label": "Engagement & retention",
                "score": 9,
                "max": 10
            },
            {
                "label": "Channels & diversification",
                "score": 4,
                "max": 6
            },
            {
                "label": "Registry stability",
                "score": 3,
                "max": 6
            },
            {
                "label": "Quality system",
                "score": 94,
                "max": 100
            },
            {
                "label": "Reputation system",
                "score": 34,
                "max": 100
            },
            {
                "label": "Safety system",
                "score": 100,
                "max": 100
            },
            {
                "label": "Evidence confidence",
                "score": 100,
                "max": 100
            }
        ],
        "authority_score": 21,
        "quality_score": 94,
        "reputation_score": 34,
        "safety_score": 100,
        "confidence_score": 100,
        "fraud_score": 0,
        "authority_signals": {
            "backlinks": 1,
            "referring_domains": 1,
            "organic_keywords": 59,
            "indexed_pages": 67,
            "monthly_visitors": 243,
            "global_rank": 3314915,
            "engagement_score": 90,
            "crawl_quality_score": 100,
            "brand_completeness_score": 60,
            "link_diversity_score": 92,
            "technical_reliability_score": 93,
            "whois_score": 45,
            "whois_age_years": 0,
            "whois_stability_score": 100,
            "spam_penalty": 6
        },
        "whois_signals": {
            "age_years": 0,
            "days_to_expiry": null,
            "days_since_last_registry_update": null,
            "stability_score": 100,
            "registrar_changes": 0,
            "ownership_changes": 0,
            "nameserver_changes": 0,
            "status_changes": 0,
            "history_entries": 2,
            "privacy_protected": false,
            "dnssec_enabled": false,
            "has_registrant_country": false,
            "registrant_country": "",
            "nameserver_count": 0,
            "status_count": 0
        }
    },
    "community_ratings": {
        "votes": [],
        "recent_notes": [],
        "positive_weight": 0,
        "negative_weight": 0,
        "positive_count": 0,
        "negative_count": 0,
        "authenticated_count": 0,
        "anonymous_count": 0,
        "community_delta": 0,
        "community_score": 50,
        "confidence_score": 0,
        "notice": null,
        "positive_notice": false,
        "negative_notice": false,
        "neutral_count": 0,
        "total_votes": 0
    },
    "authority_score": 25,
    "trust_score": 36,
    "domain_tags": {
        "primary_tag": "",
        "primary_tag_score": 0,
        "primary_candidate": "Billing",
        "primary_candidate_score": 0,
        "tag_codes": "",
        "tags": [],
        "tag_breakdown": [
            {
                "code": "Billing",
                "label": "Deceptive billing risk",
                "tone": "scam",
                "description": "Subscription, renewal, charge, or cancellation-abuse signals were detected.",
                "reason": "Subscription, renewal, charge, or cancellation-risk signals were detected.",
                "message": "No meaningful deceptive-billing signals were detected.",
                "priority": 0,
                "score": 0,
                "match_percent": 0,
                "threshold_band": "none"
            },
            {
                "code": "C",
                "label": "Caution",
                "tone": "caution",
                "description": "Signals are mixed or weak, so this domain should be treated carefully.",
                "reason": "Review carefully: mixed trust signals.",
                "message": "The current crawl does not show a meaningful caution match.",
                "priority": 0,
                "score": 0,
                "match_percent": 0,
                "threshold_band": "none"
            },
            {
                "code": "Crypto",
                "label": "Crypto drainer risk",
                "tone": "toxic",
                "description": "Wallet-connect or seed-phrase theft patterns were detected.",
                "reason": "Wallet-connect or seed-phrase theft patterns were detected.",
                "message": "No meaningful crypto-drainer signals were detected.",
                "priority": 0,
                "score": 0,
                "match_percent": 0,
                "threshold_band": "none"
            },
            {
                "code": "D",
                "label": "Dangerous",
                "tone": "toxic",
                "description": "Strong signs of phishing, malware, or other harmful behaviour were detected.",
                "reason": "Multiple high-risk signals pushed this domain into the dangerous range.",
                "message": "No meaningful dangerous-signal match was detected.",
                "priority": 0,
                "score": 0,
                "match_percent": 0,
                "threshold_band": "none"
            },
            {
                "code": "FakeShop",
                "label": "Fake shop risk",
                "tone": "spam",
                "description": "The site behaves like a store but has weak legal or business evidence.",
                "reason": "Store-like behaviour was detected without strong legal or business evidence.",
                "message": "No meaningful fake-shop signals were detected.",
                "priority": 0,
                "score": 0,
                "match_percent": 0,
                "threshold_band": "none"
            }
        ],
        "nsfw_score": 0,
        "trust_score": 37,
        "manual": {
            "has_changes": false,
            "verified_status": "",
            "tag_codes": "",
            "rating_delta": 0,
            "authority_delta": 0,
            "trust_delta": 0,
            "note": "",
            "adjusted_by": 0,
            "adjusted_at": "",
            "lock_scores": false,
            "lock_flags": false
        },
        "summary": "No hard warning tag fired, and the signal mix leans stable rather than risky.",
        "external_intel": [],
        "external_decision": [],
        "signal_scores": [
            {
                "label": "Strongest tag heuristic",
                "value": "Billing",
                "tone": "scam",
                "detail": "The highest raw tag match from the heuristic engine before visibility thresholds and manual overrides."
            },
            {
                "label": "Trust score",
                "value": "37/100",
                "tone": "spam",
                "detail": "Confidence derived from authority, crawl quality, stability, and risk signals."
            },
            {
                "label": "Authority score",
                "value": "25/100",
                "tone": "spam",
                "detail": "A higher authority score usually means broader reputation and backlink confidence."
            },
            {
                "label": "Spam risk",
                "value": "31/100",
                "tone": "caution",
                "detail": "Lower is better. This blends spam indicators with false-positive protections for legitimate sites."
            },
            {
                "label": "Quality score",
                "value": "92/100",
                "tone": "good",
                "detail": "Based on crawl quality, content completeness, and technical evidence."
            },
            {
                "label": "Safety score",
                "value": "100/100",
                "tone": "good",
                "detail": "Higher is safer. Direct fraud signals can heavily cap this even when SEO signals look strong."
            },
            {
                "label": "Fraud score",
                "value": "0/100",
                "tone": "good",
                "detail": "Lower is better. This reflects phishing, drainer, fake-support, fake-shop, and malware signals."
            },
            {
                "label": "Infrastructure risk",
                "value": "0/100",
                "tone": "good",
                "detail": "Lower is better. This reflects the IP, registrar, and nameserver neighbourhood seen by the crawler."
            },
            {
                "label": "Evidence confidence",
                "value": "100/100",
                "tone": "good",
                "detail": "Higher means the crawler had enough pages and registry evidence to make a stronger call."
            },
            {
                "label": "External evidence",
                "value": "Low",
                "tone": "unknown",
                "detail": "Quality of the structured search and review evidence cluster."
            },
            {
                "label": "External decision",
                "value": "Inconclusive",
                "tone": "unknown",
                "detail": "How third-party evidence compares with the current candidate tag."
            },
            {
                "label": "NSFW score",
                "value": "0/100",
                "tone": "good",
                "detail": "Context-aware adult-content detection with medical / educational false-positive reduction."
            },
            {
                "label": "Registry stability",
                "value": "100/100",
                "tone": "good",
                "detail": "Based on age, expiry runway, and the amount of ownership / registrar churn."
            }
        ],
        "signal_sections": [
            {
                "title": "Registry & ownership",
                "items": [
                    {
                        "label": "Domain age",
                        "value": "-",
                        "tone": "unknown",
                        "detail": "Older domains generally carry more historical trust than very new ones."
                    },
                    {
                        "label": "Stability score",
                        "value": "100/100",
                        "tone": "good",
                        "detail": "Penalised by registrar, ownership, and nameserver churn."
                    },
                    {
                        "label": "Days to expiry",
                        "value": "-",
                        "tone": "unknown",
                        "detail": "Very short renewal windows can be a weak trust signal."
                    },
                    {
                        "label": "Registrar / ownership changes",
                        "value": "0 / 0",
                        "tone": "good",
                        "detail": "Frequent ownership churn can weaken trust."
                    },
                    {
                        "label": "Nameserver changes",
                        "value": "0",
                        "tone": "good",
                        "detail": "Repeated infrastructure changes can indicate instability."
                    },
                    {
                        "label": "DNSSEC / privacy",
                        "value": "DNSSEC off - privacy off",
                        "tone": "caution",
                        "detail": "DNSSEC strengthens DNS trust; privacy is neutral on its own."
                    }
                ]
            },
            {
                "title": "Reputation & search evidence",
                "items": [
                    {
                        "label": "Backlinks",
                        "value": "1",
                        "tone": "unknown",
                        "detail": "Broader backlink evidence usually improves confidence."
                    },
                    {
                        "label": "Referring domains",
                        "value": "1",
                        "tone": "unknown",
                        "detail": "Unique linking domains are more useful than raw link volume."
                    },
                    {
                        "label": "Organic keywords",
                        "value": "59",
                        "tone": "caution",
                        "detail": "Search footprint helps distinguish real sites from thin shells."
                    },
                    {
                        "label": "Indexed pages",
                        "value": "67",
                        "tone": "caution",
                        "detail": "Larger index coverage usually means more evidence to classify from."
                    },
                    {
                        "label": "Brand strength",
                        "value": "60/100",
                        "tone": "good",
                        "detail": "Stronger brand signals reduce false positives for legitimate sites."
                    },
                    {
                        "label": "Risk label",
                        "value": "GOOD",
                        "tone": "unknown",
                        "detail": "This is the raw crawl / heuristic risk label feeding the tag model."
                    }
                ]
            },
            {
                "title": "Crawl, content & technicals",
                "items": [
                    {
                        "label": "HTTP status",
                        "value": "200",
                        "tone": "good",
                        "detail": "Healthy responses make classification more reliable."
                    },
                    {
                        "label": "HTTPS / speed",
                        "value": "HTTPS OK - 70 ms",
                        "tone": "good",
                        "detail": "Slow or broken technical signals weaken confidence."
                    },
                    {
                        "label": "Content words",
                        "value": "1,920",
                        "tone": "good",
                        "detail": "Thin pages are harder to trust and easier to manipulate."
                    },
                    {
                        "label": "Schema / structure",
                        "value": "0 schema - meta - H1",
                        "tone": "caution",
                        "detail": "Structured markup and basic on-page hygiene improve quality confidence."
                    },
                    {
                        "label": "Links on page",
                        "value": "26 internal - 2 external",
                        "tone": "good",
                        "detail": "Link patterns help detect thin directories and promo pages."
                    },
                    {
                        "label": "Page speed / mobile",
                        "value": "100/100 - 86/100",
                        "tone": "good",
                        "detail": "Better technical quality generally reduces low-effort site patterns."
                    },
                    {
                        "label": "Crawl access",
                        "value": "Open",
                        "tone": "good",
                        "detail": "The crawler reached the site without an anti-bot challenge."
                    }
                ]
            },
            {
                "title": "External evidence & explainability",
                "items": [
                    {
                        "label": "Decision state",
                        "value": "Inconclusive",
                        "tone": "unknown",
                        "detail": "Structured third-party evidence is still too thin, mixed, or unqualified to force a harder verdict."
                    },
                    {
                        "label": "Evidence quality",
                        "value": "Low",
                        "tone": "unknown",
                        "detail": "Blends source trust, domain matching, evidence diversity, and freshness."
                    },
                    {
                        "label": "Support vs contradiction",
                        "value": "0 / 0",
                        "tone": "unknown",
                        "detail": "Compares how much structured external evidence supports the candidate tag against evidence that contradicts it."
                    },
                    {
                        "label": "Qualified risk sources",
                        "value": "No",
                        "tone": "good",
                        "detail": "Risk tags only promote from external evidence when source diversity or source trust thresholds are met."
                    },
                    {
                        "label": "Uncertainty buffer",
                        "value": "Clear",
                        "tone": "good",
                        "detail": "Prevents thin or mixed external evidence from forcing a stronger tag than the evidence can justify."
                    }
                ]
            }
        ],
        "positives": [
            "Low registrar / ownership churn with solid registry stability.",
            "Healthy crawl quality and on-page completeness."
        ],
        "risks": []
    },
    "traffic_confidence": 44,
    "whois": {
        "current": {
            "id": 39289,
            "domain": "downey.io",
            "source_type": "whois_text",
            "rdap_url": "",
            "registrar_name": "",
            "registrar_handle": "",
            "registrant_name": "",
            "registrant_org": "",
            "registrant_country": "",
            "registrant_email": "",
            "abuse_email": "",
            "created_date": null,
            "updated_date": null,
            "expires_date": null,
            "nameservers_json": "[]",
            "status_json": "[]",
            "dnssec": "unknown",
            "privacy_protected": 0,
            "content_hash": "f7e17c57c5fdd24df1793ece6bff99716369356b90b29c4725ac3ba12a76b72c",
            "history_count": 2,
            "last_checked_at": "2026-04-30 23:03:33",
            "last_changed_at": "2026-04-30 23:03:33",
            "created_at": "2026-03-19 17:34:52",
            "updated_at": "2026-04-30 23:03:34"
        },
        "history": [
            {
                "id": 91380,
                "domain": "downey.io",
                "source_type": "whois_text",
                "registrar_name": "",
                "registrar_handle": "",
                "registrant_name": "",
                "registrant_org": "",
                "registrant_country": "",
                "registrant_email": "",
                "abuse_email": "",
                "created_date": null,
                "updated_date": null,
                "expires_date": null,
                "nameservers_json": "[]",
                "status_json": "[]",
                "dnssec": "unknown",
                "privacy_protected": 0,
                "content_hash": "f7e17c57c5fdd24df1793ece6bff99716369356b90b29c4725ac3ba12a76b72c",
                "checked_at": "2026-04-30 23:03:33",
                "change_summary": "Periodic WHOIS snapshot refreshed with no major field changes.",
                "created_at": "2026-04-30 23:03:33"
            },
            {
                "id": 40154,
                "domain": "downey.io",
                "source_type": "whois_text",
                "registrar_name": "",
                "registrar_handle": "",
                "registrant_name": "",
                "registrant_org": "",
                "registrant_country": "",
                "registrant_email": "",
                "abuse_email": "",
                "created_date": null,
                "updated_date": null,
                "expires_date": null,
                "nameservers_json": "[]",
                "status_json": "[]",
                "dnssec": "unknown",
                "privacy_protected": 0,
                "content_hash": "f7e17c57c5fdd24df1793ece6bff99716369356b90b29c4725ac3ba12a76b72c",
                "checked_at": "2026-03-19 17:34:50",
                "change_summary": "Initial WHOIS snapshot captured.",
                "created_at": "2026-03-19 17:34:50"
            }
        ],
        "signals": {
            "age_years": 0,
            "days_to_expiry": null,
            "days_since_last_registry_update": null,
            "stability_score": 100,
            "registrar_changes": 0,
            "ownership_changes": 0,
            "nameserver_changes": 0,
            "status_changes": 0,
            "history_entries": 2,
            "privacy_protected": false,
            "dnssec_enabled": false,
            "has_registrant_country": false,
            "registrant_country": "",
            "nameserver_count": 0,
            "status_count": 0
        }
    },
    "discovered_domain": {
        "id": 136951,
        "domain": "downey.io",
        "first_seen_at": "2026-03-16 03:50:33",
        "last_crawled_at": "2026-04-30 23:03:34",
        "last_title": "blog|downey.io",
        "last_http_status": 200,
        "discovered_from_domain": "uses.tech",
        "depth": 0,
        "backlinks_count": 1,
        "rating_cache": 46,
        "spam_score": 24,
        "risk_label": "good",
        "category_name": "Developer Tools: DevOps & Cloud",
        "primary_country_code": "",
        "internal_links_count": 26,
        "external_links_count": 2,
        "social_profiles_count": 2,
        "content_word_count": 1920,
        "title_quality_score": 79,
        "has_meta_description": 1,
        "has_h1": 1,
        "language_code": "en",
        "response_time_ms": 70,
        "robots_status": 200,
        "sitemap_status": 200,
        "sitemap_total_urls": 67,
        "quality_score": 92,
        "site_name": "",
        "canonical_domain": "",
        "favicon_present": 0,
        "schema_org_count": 0,
        "noindex_detected": 0,
        "feed_links_count": 0,
        "https_working": 1,
        "estimated_authority_score": 25,
        "trust_score": 52,
        "nsfw_score": 0,
        "overall_rank_estimate": 3603041,
        "primary_tag": "",
        "tag_codes": "T",
        "manual_verified_status": "",
        "manual_tag_codes": "",
        "manual_rating_delta": 0,
        "manual_authority_delta": 0,
        "manual_trust_delta": 0,
        "manual_note": null,
        "manual_adjusted_by": null,
        "manual_adjusted_at": null,
        "manual_lock_scores": 0,
        "manual_lock_flags": 0,
        "crawl_blocked": 0,
        "crawl_blocked_by": "",
        "crawl_blocked_reason": null,
        "safety_score": 100,
        "fraud_score": 0,
        "legitimacy_score": 40,
        "infrastructure_risk_score": 0,
        "score_confidence": 100,
        "tag_confidence": 72,
        "category_confidence": 99,
        "deep_crawl_pages": 50,
        "resolved_ip": "13.224.95.116",
        "category_candidates_json": "[{\"category\":\"Developer Tools: DevOps & Cloud\",\"score\":100},{\"category\":\"Technology: AI & Machine Learning\",\"score\":33},{\"category\":\"Technology\",\"score\":17},{\"category\":\"Personal: Blogs & Journals\",\"score\":11}]",
        "page_signals_json": "[{\"path\":\"/blog/\",\"status\":200,\"title\":\"blog|downey.io\",\"word_count\":1920,\"summary_text\":\"blog|downey.io blog|downey.io code blog photos notes latest posts Code Rot As I was writing my last post a couple of months ago, the age of this site's decade old toolchain became evident. Maybe it was my new Apple Silicon Mac, or perhaps it was the fact that I hadn't updated any of the gems in over a decade. Whatever the reason, nothing worked! My site had finally succumbed to the dreaded code rot. I was left with a choice: either modernize the site a bit or start over from scratch. I chose to modernize. June 09, 2024 Fractal Design Terra Jade Workstation I originally set out to make a headless Linux server build running Proxmox -- basically a homelab that I'd keep in the basement -- but as I built out my parts list I realized I was making more of a desktop workstation. And as I explored the case option\",\"classification_terms\":[\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/notes/\",\"status\":200,\"title\":\"notes|downey.io\",\"word_count\":266,\"summary_text\":\"notes|downey.io notes|downey.io code blog photos notes notes my digital field notes How to Make Kubectl Jsonpath Output On Separate Lines July 19, 2020 How to Make Kubectl Exec Run Against Multiple Pods July 19, 2020 Creating a Super-Privileged Pod with Root and Host Namespaces July 01, 2020 Creating a Simple Kubernetes Debug Pod June 26, 2020 How to Convert a LoadBalancer Service Into a NodePort Service May 31, 2020 How to default null YAML values to empty strings when using ytt December 06, 2019 NP Problem Reduction Notes July 25, 2019 Linear Programming Notes July 21, 2019 Graphs - Finding Minimum Spanning Trees with Kruskal's Algorithm June 16, 2019 Dynamic Programming - Bellman-Ford Algorithm June 08, 2019 Dynamic Programming - DPV 6.4 June 04, 2019 Emulating an OpenMP Parallel For-Loop in Go May 08,\",\"classification_terms\":[\"notes\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/ten-years-of-code-rot/\",\"status\":200,\"title\":\"Code Rot: Celebrating a decade of downey.io|downey.io\",\"word_count\":676,\"summary_text\":\"Code Rot: Celebrating a decade of downey.io|downey.io Code Rot: Celebrating a decade of downey.io|downey.io code blog photos notes Code Rot Celebrating a decade of downey.io June 09, 2024 Last month, this site turned ten years old. At the time, I was a fresh new software engineer who had just started my first real job. I was working with Ruby on Rails, so naturally, I created this site using the Ruby-based Jekyll static site generator. Since I was all about Rails, I incorporated jekyll-assets to layer on the Sprockets asset pipeline and fed it a smorgasbord of Thoughtbot SASS gems for styling. I even sprinkled in some jQuery for good measure. To cap it all off (and since I knew nothing about IaaSes at the time), I used a random gem called s3_website to publish it all to an S3 bucket. That all worked beautifully… for a little while. As I was w\",\"classification_terms\":[\"blog/ten-years-of-code-rot\",\"about\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/fractal-terra-jade-workstation/\",\"status\":200,\"title\":\"Fractal Design Terra Jade Workstation: A 12-core waste of money 🌝|downey.io\",\"word_count\":1269,\"summary_text\":\"Fractal Design Terra Jade Workstation: A 12-core waste of money 🌝|downey.io Fractal Design Terra Jade Workstation: A 12-core waste of money 🌝|downey.io code blog photos notes Fractal Design Terra Jade Workstation A 12-core waste of money 🌝 February 10, 2024 👋 I’m back. It’s been going on two years since I’ve last posted anything and a lot has happened. We moved from the Bay Area to Colorado and even had a kid! 🏔️👶 But now that things have settled down a little bit, I’d like to get back in the groove and start blogging again. So I dusted off the cobwebs of this (nearly a decade) old Jekyll site and got the dev env running again. It’s kind of crufty by this point, but in the words of Han Solo, “she’s got it where it counts, kid.” Anyways, what better way to kick this off than with a new PC build! The Plan My goals for this build were the following (in no particular\",\"classification_terms\":[\"blog/fractal-terra-jade-workstation\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/cloud-native-buildpacks-sbom/\",\"status\":200,\"title\":\"Producing a Software Bill of Materials the Easy Way: Securing your supply chain with SBOMs and Cloud Native Buildpacks|downey.io\",\"word_count\":1243,\"summary_text\":\"Producing a Software Bill of Materials the Easy Way: Securing your supply chain with SBOMs and Cloud Native Buildpacks|downey.io Producing a Software Bill of Materials the Easy Way: Securing your supply chain with SBOMs and Cloud Native Buildpacks|downey.io code blog photos notes Producing a Software Bill of Materials the Easy Way Securing your supply chain with SBOMs and Cloud Native Buildpacks June 05, 2022 It seems like every week we hear that there is a new vulnerability in some core dependency. Or maybe yet another package we all depend on has been hacked (maintainers, please enable two-factor auth!!). The only thing we can do as developers in these cases is patch our software back to a safe version of the dependency as soon as possible. That’s easier said than done, however. For many of us even just knowing what dependencies our deployed code is using is a struggle. That’s where having a Software Bill of Mater\",\"classification_terms\":[\"blog/cloud-native-buildpacks-sbom\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/folding-at-home-raspberry-pi-arm/\",\"status\":200,\"title\":\"Installing Folding at Home on a Raspberry Pi: folding proteins for fun and science|downey.io\",\"word_count\":1349,\"summary_text\":\"Installing Folding at Home on a Raspberry Pi: folding proteins for fun and science|downey.io Installing Folding at Home on a Raspberry Pi: folding proteins for fun and science|downey.io code blog photos notes Installing Folding at Home on a Raspberry Pi folding proteins for fun and science January 30, 2021 tl;dr? Feel free to skip ahead to the installation guide below. Back when I was a kid I used to run Folding@Home on our old family computer – a silver Gateway tower with a 1.8 GHz Pentium 4. I’m not sure how I found out about it, but I remember being inordinately excited by the prospect of contributing CPU cycles to simulate protein folding and help discover cures for cancer and other diseases. Yeah, I was a nerd. 🤓 Anyways, I kind of forgot about the project until this past year – thanks to Covid-19. 😒 In addition to the typical work units, Folding@Home was now distributing wor\",\"classification_terms\":[\"blog/folding-at-home-raspberry-pi-arm\",\"about\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/blog/kubernetes-ephemeral-debug-container-tcpdump/\",\"status\":200,\"title\":\"Capturing Network Traffic from a Kubernetes Pod with Ephemeral Debug Containers: how to tcpdump a running pod|downey.io\",\"word_count\":999,\"summary_text\":\"Capturing Network Traffic from a Kubernetes Pod with Ephemeral Debug Containers: how to tcpdump a running pod|downey.io Capturing Network Traffic from a Kubernetes Pod with Ephemeral Debug Containers: how to tcpdump a running pod|downey.io code blog photos notes Capturing Network Traffic from a Kubernetes Pod with Ephemeral Debug Containers how to tcpdump a running pod September 26, 2020 The other day I had a situation where I needed to debug network traffic between an app and its Envoy sidecar proxy. Fortunately, since the app image was Ubuntu-based and it was an unimportant dev cluster, I was able to just kubectl exec into a shell on the container and apt install tcpdump. Now that I had tcpdump installed, I could run it and pipe the output to Wireshark on my local machine. kubectl exec my-app-pod -c nginx -- tcpdump -i eth0 -w - | wireshark -k -i - It was pretty slick, if I do say so myself, and made me f\",\"classification_terms\":[\"blog/kubernetes-ephemeral-debug-container-tcpdump\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":5,\"depth\":1},{\"path\":\"/blog/publicly-routable-private-internal-kubernetes-cluster/\",\"status\":200,\"title\":\"Public Routing to a Private Kubernetes Cluster: using Inlets, Contour, and external-dns|downey.io\",\"word_count\":1769,\"summary_text\":\"Public Routing to a Private Kubernetes Cluster: using Inlets, Contour, and external-dns|downey.io Public Routing to a Private Kubernetes Cluster: using Inlets, Contour, and external-dns|downey.io code blog photos notes Public Routing to a Private Kubernetes Cluster using Inlets, Contour, and external-dns August 23, 2020 Updated: June 18, 2021 Important Update It looks like inlets-operator has been folded into Inlets PRO and now requires a (fairly inexpensive) paid license to use which comes with HTTPS and TCP load balancing plus support. You can still use inlets for free, you’ll just have to configure the ingress node yourself I believe. Some of the post below still applies – especially if you’re trying to DIY your own set up with inlets – but take it all with a grain of salt as I haven’t had a chance to experiment with any of this since. For personal projects and hacking around on Kub\",\"classification_terms\":[\"blog/publicly-routable-private-internal-kubernetes-cluster\",\"support\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/blog/raspberry-pi-4-heatsinks-and-fans/\",\"status\":200,\"title\":\"The Great Raspberry Pi Cooling Bake-Off: Comparing Passive Heatsinks and Active Cooling for the Raspberry Pi 4|downey.io\",\"word_count\":2116,\"summary_text\":\"The Great Raspberry Pi Cooling Bake-Off: Comparing Passive Heatsinks and Active Cooling for the Raspberry Pi 4|downey.io The Great Raspberry Pi Cooling Bake-Off: Comparing Passive Heatsinks and Active Cooling for the Raspberry Pi 4|downey.io code blog photos notes The Great Raspberry Pi Cooling Bake-Off Comparing Passive Heatsinks and Active Cooling for the Raspberry Pi 4 July 04, 2020 Updated: July 06, 2020 Two years ago, I found myself alone over the Fourth of July and a bit bored. So, of course, I did the reasonable thing and conducted a performance comparison of a few of the cooling options available for the Raspberry Pi 3B. This comparison resulted in my post “Raspberry Pi Heat Sink Science”. 2020 and its Pandemic has gifted me with even more isolation (ahem social distancing 😷) this Fourth, so why not make the best of it and create Raspberry Pi Heat Sink Science Episode II: The 4th Awakens! This time w\",\"classification_terms\":[\"blog/raspberry-pi-4-heatsinks-and-fans\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":2,\"depth\":1},{\"path\":\"/blog/skip-kubernetes-loadbalancer-with-hostport-daemonset/\",\"status\":200,\"title\":\"Save Money and Skip the Kubernetes Load Balancer: Lowering Infrastructure Costs with Ingress Controllers, DNS, and Host Ports|downey.io\",\"word_count\":1783,\"summary_text\":\"Save Money and Skip the Kubernetes Load Balancer: Lowering Infrastructure Costs with Ingress Controllers, DNS, and Host Ports|downey.io Save Money and Skip the Kubernetes Load Balancer: Lowering Infrastructure Costs with Ingress Controllers, DNS, and Host Ports|downey.io code blog photos notes Save Money and Skip the Kubernetes Load Balancer Lowering Infrastructure Costs with Ingress Controllers, DNS, and Host Ports June 14, 2020 LoadBalancer Services are super convenient. Just change the type of a NodePort service to LoadBalancer and your cloud provider will provision a new cloud load balancer, external IP address, and firewall rules to make your workload reachable to the world. It’s a fantastic user experience! It’s no wonder that example installations and tutorials love to include them. Load balancers, however, come with a cost. On Digital Ocean, for example, each load balancer will run you ten dollars a month – and for\",\"classification_terms\":[\"blog/skip-kubernetes-loadbalancer-with-hostport-daemonset\",\"address\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":10,\"depth\":1},{\"path\":\"/blog/how-to-use-kbld-with-kubernetes/\",\"status\":200,\"title\":\"Using kbld to Rapidly Iterate on Kubernetes Deployed Apps: Speeding up the Docker Image Build-Push-Deploy cycle|downey.io\",\"word_count\":1140,\"summary_text\":\"Using kbld to Rapidly Iterate on Kubernetes Deployed Apps: Speeding up the Docker Image Build-Push-Deploy cycle|downey.io Using kbld to Rapidly Iterate on Kubernetes Deployed Apps: Speeding up the Docker Image Build-Push-Deploy cycle|downey.io code blog photos notes Using kbld to Rapidly Iterate on Kubernetes Deployed Apps Speeding up the Docker Image Build-Push-Deploy cycle May 27, 2020 When creating applications that extend or interact with Kubernetes, there are times when it’s necessary to deploy and develop against a real K8s cluster. While Kubernetes makes it trivial to apply and roll out new changes, the building and pushing new dev Docker images for your application can be a rigamarole. On top of that, you also have to remember to configure the imagePullPolicy for your containers to Always. Otherwise, who knows if the node your app ends up running on has the old image cached! Fortunately, there is a to\",\"classification_terms\":[\"blog/how-to-use-kbld-with-kubernetes\",\"api\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/leaving-breadcrumbs/\",\"status\":200,\"title\":\"Leaving Breadcrumbs: the joys of public note taking|downey.io\",\"word_count\":1060,\"summary_text\":\"Leaving Breadcrumbs: the joys of public note taking|downey.io Leaving Breadcrumbs: the joys of public note taking|downey.io code blog photos notes Leaving Breadcrumbs the joys of public note taking May 08, 2020 This post is going to be a bit meta. I’m going to write a bit about why I post my notes and, to a lesser extent, blog in general. I’ve been wanting to write on this for a while now, but just haven’t gotten around to it. However, thanks to this Pandemic we’re all in, I’ve found myself with no commute and a bit more free time. So here we are. 🙂 Why I Blog I started this blog six years ago for kind of a lame reason. I had purchased the downey.io domain name in 2013 and sat on it for a year. Soon it was time to renew, and I decided I had to do better in 2014. After all, .io domains didn’t come cheap back then! So I made a few lackluster posts out\",\"classification_terms\":[\"blog/leaving-breadcrumbs\",\"about\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/desired-state-vs-actual-state-in-kubernetes/\",\"status\":200,\"title\":\"Desired State Versus Actual State in Kubernetes: Eventual Consistency in Kubernetes, Distributed Systems, and the Real World™|downey.io\",\"word_count\":2445,\"summary_text\":\"Desired State Versus Actual State in Kubernetes: Eventual Consistency in Kubernetes, Distributed Systems, and the Real World™|downey.io Desired State Versus Actual State in Kubernetes: Eventual Consistency in Kubernetes, Distributed Systems, and the Real World™|downey.io code blog photos notes Desired State Versus Actual State in Kubernetes Eventual Consistency in Kubernetes, Distributed Systems, and the Real World™ February 02, 2020 It was once acceptable — and even expected — for web services to go down for maintenance or when under heavy load. You could run a simple LAMP stack on a single physical machine and call it a day. Today, however, services are measured in the number of nines of availability they provide. A single server no longer cuts it. One way to achieve higher availability is by running countless copies, or replicas, of our services across geographies. Now, though, we’ve got ourselves a distributed system t\",\"classification_terms\":[\"blog/desired-state-vs-actual-state-in-kubernetes\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":15,\"depth\":1},{\"path\":\"/blog/twenty-twenty-goals/\",\"status\":200,\"title\":\"2020 Goals: a new year, a new decade|downey.io\",\"word_count\":997,\"summary_text\":\"2020 Goals: a new year, a new decade|downey.io 2020 Goals: a new year, a new decade|downey.io code blog photos notes 2020 Goals a new year, a new decade January 12, 2020 When it comes to goals and self-improvement, I have a nasty habit of being over-ambitious and over-committing myself – as evidenced by the piles of technical books and unused yoga equipment cluttering my apartment. And it’s not that I don’t achieve anything. Last year I completed Georgia Tech’s online Masters in Computer Science (OMSCS) and published seventeen posts on dev.to, for example. It’s more that I have trouble focusing on a single thing and seeing it to completion. This year I’m going to focus and plan to complete a smaller number of measurable goals. Last year I focused pretty heavily on academic Computer Science, even to the detriment of my physical health a\",\"classification_terms\":[\"blog/twenty-twenty-goals\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/kubecon-2019-takeaways/\",\"status\":200,\"title\":\"Reflections on Kubecon 2019: good times in San Diego plus a bonus Istio meetup on a boat|downey.io\",\"word_count\":1150,\"summary_text\":\"Reflections on Kubecon 2019: good times in San Diego plus a bonus Istio meetup on a boat|downey.io Reflections on Kubecon 2019: good times in San Diego plus a bonus Istio meetup on a boat|downey.io code blog photos notes Reflections on Kubecon 2019 good times in San Diego plus a bonus Istio meetup on a boat December 01, 2019 A little over a week ago, I had the privilege of attending Kubecon in San Diego (thanks Pivotal!). It was an amazing experience, if not just a tad overwhelming in attendance and scale. It was a lot to take in – and also a lot of fun! Now that I’ve had a bit of a break, I’ve had a chance to revisit my notes. In this post, I’ll jot down a few of my takeaways from the conference. Size and Scale I’ve been to a few tech conferences in the past, such as various Cloud Foundry Summits over the years and Gophercon, but none have been nearly as large as Kubecon. I’m not sure\",\"classification_terms\":[\"blog/kubecon-2019-takeaways\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/deploying-ruby-app-kubernetes-buildpack-kapp/\",\"status\":200,\"title\":\"Simplify Kubernetes App Deployments With Cloud Native Buildpacks and kapp: build your own PaaS using command line tools|downey.io\",\"word_count\":2114,\"summary_text\":\"Simplify Kubernetes App Deployments With Cloud Native Buildpacks and kapp: build your own PaaS using command line tools|downey.io Simplify Kubernetes App Deployments With Cloud Native Buildpacks and kapp: build your own PaaS using command line tools|downey.io code blog photos notes Simplify Kubernetes App Deployments With Cloud Native Buildpacks and kapp build your own PaaS using command line tools November 06, 2019 In recent years the Kubernetes wave has taken the software world by storm. And for good reason. Kubernetes makes it easy for developers to build robust distributed systems. It provides powerful building blocks for deploying and managing containerized workloads. This makes it an enticing platform for the sprawling microservice “apps” of today. Unfortunately, all this power and flexibility carries with it enormous complexity. Kubernetes is not a PaaS (Platform as a Service) like Heroku or Cloud Foundry. It\",\"classification_terms\":[\"blog/deploying-ruby-app-kubernetes-buildpack-kapp\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[\"asciinema.org\"],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":10,\"depth\":1},{\"path\":\"/blog/graduated-georgia-tech-omscs/\",\"status\":200,\"title\":\"Completing Georgia Tech's Online Master of Science in Computer Science: a long three years in the omscs|downey.io\",\"word_count\":1668,\"summary_text\":\"Completing Georgia Tech's Online Master of Science in Computer Science: a long three years in the omscs|downey.io Completing Georgia Tech's Online Master of Science in Computer Science: a long three years in the omscs|downey.io code blog photos notes Completing Georgia Tech's Online Master of Science in Computer Science a long three years in the omscs August 19, 2019 I applied to Georgia Tech’s Online Master of Science in Computer Science (OMSCS) program back in September 2015. One of my friends was applying and encouraged me to apply as well. So I did, not really knowing what I was getting myself in to. I was accepted and took my first class, Software Development Process in Spring 2016 – right as I was moving out to California. Now, three and a half years later, it’s over. I’ve graduated and completed the Computing Systems specialization while working full time! Now I want to take the time to look ba\",\"classification_terms\":[\"blog/graduated-georgia-tech-omscs\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/max-flow-ford-fulkerson-algorithm-explanation/\",\"status\":200,\"title\":\"Finding Max Flow using the Ford-Fulkerson Algorithm and Matthew McConaughey: a step-by-step explanation|downey.io\",\"word_count\":1292,\"summary_text\":\"Finding Max Flow using the Ford-Fulkerson Algorithm and Matthew McConaughey: a step-by-step explanation|downey.io Finding Max Flow using the Ford-Fulkerson Algorithm and Matthew McConaughey: a step-by-step explanation|downey.io code blog photos notes Finding Max Flow using the Ford-Fulkerson Algorithm and Matthew McConaughey a step-by-step explanation June 25, 2019 Updated: July 03, 2020 Prereqs Before reading further, make sure to watch the necessary prerequisite lecture by Matthew McConaughey above. His words of wisdom are the key to all of this. I know there are those who say you can't go back. Yes you can. — Matthew McConaughey on the Maximum Flow Problem What is the Max Flow Problem? The max flow problem is an optimization problem for determining the maximum amount of stuff that can flow at a given point in time through a single source/sink flow network. A flow network is essentially just a direc\",\"classification_terms\":[\"blog/max-flow-ford-fulkerson-algorithm-explanation\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/helman-jaja-list-ranking-explained/\",\"status\":200,\"title\":\"The Helman and JáJá List Ranking Algorithm: a simpler explanation|downey.io\",\"word_count\":1191,\"summary_text\":\"The Helman and JáJá List Ranking Algorithm: a simpler explanation|downey.io The Helman and JáJá List Ranking Algorithm: a simpler explanation|downey.io code blog photos notes The Helman and JáJá List Ranking Algorithm a simpler explanation May 15, 2019 In one of our labs in Georgia Tech’s Intro to High Performance Computing course, we had to explore the parallel computing problem of list ranking. This lecture by Professor Vuduc does a better job explaining than I can, but list ranking is essentially just traversing a linked list and assigning each node a “rank”, or distance from the list’s head. A serial implementation of list ranking is trivial and can be completed in O(n) time by walking the list. A parallel implementation is a bit trickier. In our lab we researched and implemented two such algorithms: Wyllie’s and Helman/JáJá’s. I found Wyllie’s algorithm to be\",\"classification_terms\":[\"blog/helman-jaja-list-ranking-explained\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/cs140e-writing-an-operating-system-in-rust/\",\"status\":200,\"title\":\"Learning to build an Operating System in Rust via CS140e: rust is gr8|downey.io\",\"word_count\":1278,\"summary_text\":\"Learning to build an Operating System in Rust via CS140e: rust is gr8|downey.io Learning to build an Operating System in Rust via CS140e: rust is gr8|downey.io code blog photos notes Learning to build an Operating System in Rust via CS140e rust is gr8 December 15, 2018 Updated: March 30, 2019 ⚠️ important update ⚠️ It was brought to my attention that the cs140e site has been completely redone and the class is now being taught in C. 😒 Fortunately, the Internet Archive has an archived version that will still let you access the assignments. I also recommend checking out Philipp Oppermann’s Writing an OS in Rust blog series. I’ve only had a chance to skim the content, but it looks like another good alternative. introduction I first found out about Stanford’s experimental Rust-based cs140e OS course through a comment on the OMSCS GIOS Slack. Now I’m always down to learn mo\",\"classification_terms\":[\"blog/cs140e-writing-an-operating-system-in-rust\",\"about\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/thoughts-on-omscs-cs-7641-machine-learning/\",\"status\":200,\"title\":\"Adventures in CS 7641 - Machine Learning: \\\"It's over. It's done!\\\"|downey.io\",\"word_count\":1687,\"summary_text\":\"Adventures in CS 7641 - Machine Learning: \\\"It's over. It's done!\\\"|downey.io Adventures in CS 7641 - Machine Learning: \\\"It's over. It's done!\\\"|downey.io code blog photos notes Adventures in CS 7641 - Machine Learning \\\"It's over. It's done!\\\" December 09, 2018 Wow, it’s been months since I’ve written anything here. Between taking on additional leadership responsibilities at work and enduring through Georgia Tech’s graduate Machine Learning course, it has just been difficult to find the time – and energy. 😩 Fortunately, I just wrapped up CS 7641 last evening and felt as though a huge weight had been lifted. I feel a bit like Frodo after he destroyed the One Ring and am happy to repeat his famous line “it’s over. it’s done!” Time to get back to writing and learning Rust! This class definitely took me out of my comfort zone as far as computer science classes go. My unde\",\"classification_terms\":[\"blog/thoughts-on-omscs-cs-7641-machine-learning\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/blog/exploring-cgroups-raspberry-pi/\",\"status\":200,\"title\":\"Cgroups on the Raspberry Pi Zero: A brief survey of the memory, cpu, and freezer cgroups in Raspbian Stretch Lite|downey.io\",\"word_count\":2001,\"summary_text\":\"Cgroups on the Raspberry Pi Zero: A brief survey of the memory, cpu, and freezer cgroups in Raspbian Stretch Lite|downey.io Cgroups on the Raspberry Pi Zero: A brief survey of the memory, cpu, and freezer cgroups in Raspbian Stretch Lite|downey.io code blog photos notes Cgroups on the Raspberry Pi Zero A brief survey of the memory, cpu, and freezer cgroups in Raspbian Stretch Lite August 05, 2018 Cgroups, also known as control groups, are a feature of the Linux kernel which allow groups of processes to be managed and monitored. The Linux man pages go into greater detail, but the gist of it is that cgroups allow you to do things like limit the amount of CPU usage of a process, limit the amount of memory that a process can consume, control how many additional processes a process can fork, and even “freeze” a process in place. If you’re familiar with Linux containers at all, cgroups are what enable a container orc\",\"classification_terms\":[\"blog/exploring-cgroups-raspberry-pi\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":2,\"depth\":1},{\"path\":\"/blog/2\",\"status\":200,\"title\":\"blog|downey.io\",\"word_count\":1209,\"summary_text\":\"blog|downey.io blog|downey.io code blog photos notes latest posts Unlimited Power! My Unstoppable Raspberry Pi Kubernetes Cluster I started working on building a Raspberry Pi-based Kubernetes cluster after attending the Bay Area Maker Faire in May 2018 and now it is finally complete! In this post we'll cover what parts I used, a high level description of how I installed Kubernetes using rak8s, and what I plan to do with it. August 04, 2018 Baking a Pi Router for my Raspberry Pi Kubernetes Cluster How I set up a Raspberry Pi 3 Model B+ to be the dns/dhcp server and router for my Raspberry Pi-based Kubernetes cluster. A general guide to how I eventually managed to get the Pi Router sharing working and some cautionary tales of pitfalls I encountered along the way. July 03, 2018 Raspberry Pi Heat Sink Scienc\",\"classification_terms\":[\"blog/2\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/notes\",\"status\":200,\"title\":\"notes|downey.io\",\"word_count\":266,\"summary_text\":\"notes|downey.io notes|downey.io code blog photos notes notes my digital field notes How to Make Kubectl Jsonpath Output On Separate Lines July 19, 2020 How to Make Kubectl Exec Run Against Multiple Pods July 19, 2020 Creating a Super-Privileged Pod with Root and Host Namespaces July 01, 2020 Creating a Simple Kubernetes Debug Pod June 26, 2020 How to Convert a LoadBalancer Service Into a NodePort Service May 31, 2020 How to default null YAML values to empty strings when using ytt December 06, 2019 NP Problem Reduction Notes July 25, 2019 Linear Programming Notes July 21, 2019 Graphs - Finding Minimum Spanning Trees with Kruskal's Algorithm June 16, 2019 Dynamic Programming - Bellman-Ford Algorithm June 08, 2019 Dynamic Programming - DPV 6.4 June 04, 2019 Emulating an OpenMP Parallel For-Loop in Go May 08,\",\"classification_terms\":[\"notes\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/privacy.html\",\"status\":200,\"title\":\"downey.io - privacy policy|downey.io\",\"word_count\":47,\"summary_text\":\"downey.io - privacy policy|downey.io downey.io - privacy policy|downey.io code blog photos notes This site is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com. Contact Tim Downey tim@downey.io privacy policy\",\"classification_terms\":[\"privacy.html\",\"contact\",\"privacy\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/notes/dev/kubectl-jsonpath-new-lines/\",\"status\":200,\"title\":\"How to Make Kubectl Jsonpath Output On Separate Lines: adding new lines to '-o jsonpath' so that it actually does what you want|downey.io\",\"word_count\":299,\"summary_text\":\"How to Make Kubectl Jsonpath Output On Separate Lines: adding new lines to '-o jsonpath' so that it actually does what you want|downey.io How to Make Kubectl Jsonpath Output On Separate Lines: adding new lines to '-o jsonpath' so that it actually does what you want|downey.io code blog photos notes How to Make Kubectl Jsonpath Output On Separate Lines adding new lines to '-o jsonpath' so that it actually does what you want July 19, 2020 Getting kubectl to output jsonpath results on separate lines is something that I have to Google every time. 😖 For example, the following command extracts the podIP for every running Pod across all namespaces. kubectl get pods -A -o jsonpath='{.items[*].status.podIP}' It returns something like the following: 10.244.0.11 10.244.0.8 10.244.0.14 10.244.0.10 10.244.0.6 10.244.0.12 10.244.0.13 10.244.0.15 10.244.0.7 10.244.0.9 10.244.0.3 10.244.0.2 10.244.0.5 172.18.0.2 172.18.0.2 172.18.0.2 172.18.\",\"classification_terms\":[\"notes/dev/kubectl-jsonpath-new-lines\",\"returns\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":22,\"depth\":2},{\"path\":\"/notes/dev/kubectl-exec-multiple-pods/\",\"status\":200,\"title\":\"How to Make Kubectl Exec Run Against Multiple Pods: thank you, xargs|downey.io\",\"word_count\":286,\"summary_text\":\"How to Make Kubectl Exec Run Against Multiple Pods: thank you, xargs|downey.io How to Make Kubectl Exec Run Against Multiple Pods: thank you, xargs|downey.io code blog photos notes How to Make Kubectl Exec Run Against Multiple Pods thank you, xargs July 19, 2020 I was really surprised to discover the other day that kubectl does not support running the same command against multiple Pods out of the box. I get why that wouldn’t be supported for interactive terminals, but seems like non-interactive commands should be fine. Oh well. We can still do what we want thanks to UNIX tools like xargs. kubectl get pods -o name | xargs -I{} kubectl exec {} -- &lt;command goes here&gt; Just replace the &lt;command goes here&gt; bit with what you want to do. Example: Setting Log Level to Debug for All Istio IngressGateway Envoys Here’s a real world example of when and how you might w\",\"classification_terms\":[\"notes/dev/kubectl-exec-multiple-pods\",\"support\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/dev/kubernetes-privileged-root-pod-example/\",\"status\":200,\"title\":\"Creating a Super-Privileged Pod with Root and Host Namespaces: Dangerous YAML for Dangerous Devs|downey.io\",\"word_count\":838,\"summary_text\":\"Creating a Super-Privileged Pod with Root and Host Namespaces: Dangerous YAML for Dangerous Devs|downey.io Creating a Super-Privileged Pod with Root and Host Namespaces: Dangerous YAML for Dangerous Devs|downey.io code blog photos notes Creating a Super-Privileged Pod with Root and Host Namespaces Dangerous YAML for Dangerous Devs July 01, 2020 Disclaimer: Obligatory warning that creating a Pod that runs as root using the host’s namespaces is not safe. Only do this on development clusters if you have a specific goal in mind. Don’t do it in production please and don’t run regular workloads like this. Thanks. 🙃 Sometimes when developing on Kubernetes you may need to look deeper into what is happening on the host. In the event that you cannot easily ssh on to the host nodes directly. Maybe your cluster was provisioned by a coworker or comes from a managed service. Regardless the reason, in these c\",\"classification_terms\":[\"notes/dev/kubernetes-privileged-root-pod-example\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/dev/ubuntu-sleep-pod-yaml/\",\"status\":200,\"title\":\"Creating a Simple Kubernetes Debug Pod: Premium Ubuntu Sleep Pod YAML|downey.io\",\"word_count\":586,\"summary_text\":\"Creating a Simple Kubernetes Debug Pod: Premium Ubuntu Sleep Pod YAML|downey.io Creating a Simple Kubernetes Debug Pod: Premium Ubuntu Sleep Pod YAML|downey.io code blog photos notes Creating a Simple Kubernetes Debug Pod Premium Ubuntu Sleep Pod YAML June 26, 2020 Sometimes it can be helpful to deploy a simple Ubuntu container to a cluster when debugging. Say you just applied some new NetworkPolicy and want to test network connectivity between namespaces. Or maybe you added a new mutating admission webhook to inject sidecar containers and you need something to test it out with. Or maybe you just want a sandbox container to deploy and play around in. One thing I like to do is deploy a Pod running Ubuntu that will let me install whatever tools I want. No need to worry about thin, distroless images that are so secure I can’t do anything! With the Ubuntu image everything\",\"classification_terms\":[\"notes/dev/ubuntu-sleep-pod-yaml\",\"about\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/dev/convert-loadbalancer-service-to-nodeport-ytt/\",\"status\":200,\"title\":\"How to Convert a LoadBalancer Service Into a NodePort Service: Transforming Kubernetes Service YAML with ytt|downey.io\",\"word_count\":385,\"summary_text\":\"How to Convert a LoadBalancer Service Into a NodePort Service: Transforming Kubernetes Service YAML with ytt|downey.io How to Convert a LoadBalancer Service Into a NodePort Service: Transforming Kubernetes Service YAML with ytt|downey.io code blog photos notes How to Convert a LoadBalancer Service Into a NodePort Service Transforming Kubernetes Service YAML with ytt May 31, 2020 Kubernetes Ingress Controllers often include LoadBalancer type Services as part of their default installation config. If your IaaS supports them, LoadBalancer services are super convenient since they’ll work with the IaaS to automatically provision a load balancer and external IP (and typically firewall rules) to make your service reachable to the world. Load balancers are seldom free, however, and for development clusters they’re often either unsupported or just plain overkill. Fortunately, a LoadBalancer Service is basically just\",\"classification_terms\":[\"notes/dev/convert-loadbalancer-service-to-nodeport-ytt\",\"support\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/dev/null-values-empty-string-ytt/\",\"status\":200,\"title\":\"How to default null YAML values to empty strings when using ytt|downey.io\",\"word_count\":575,\"summary_text\":\"How to default null YAML values to empty strings when using ytt|downey.io How to default null YAML values to empty strings when using ytt|downey.io code blog photos notes How to default null YAML values to empty strings when using ytt December 06, 2019 An example of converting null YAML values to empty strings when using ytt for Kubernetes config templating. This approach uses Python’s boolean short-circuiting behavior to concisely substitute empty strings for None values. It was inspired by this Stack Overflow post. If you stumbled upon this page and have no clue what ytt is, it’s basically yet another way to template out YAML for Kubernetes. Think helm template but where you get to use a Python-like programming language and manipulate the YAML structures directly instead of just manipulating text. tl;dr Use Python’s boolean short-circuiting. #@ prefix = data.v\",\"classification_terms\":[\"notes/dev/null-values-empty-string-ytt\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cs6515/np-reduction-steps/\",\"status\":200,\"title\":\"NP Problem Reduction Notes|downey.io\",\"word_count\":796,\"summary_text\":\"NP Problem Reduction Notes|downey.io NP Problem Reduction Notes|downey.io code blog photos notes NP Problem Reduction Notes July 25, 2019 Typed version of some of my notes on NP and NP-Complete reductions for the Graduate Algorithms course I am taking. Attached at the bottom are various resources that I found helpful, so if you’ve stumbled upon this page somehow I recommend checking those out as well. NP Reduction Steps To show that a new problem of unknown difficulty is NP-Complete we have to do two main things. Show that the problem lies in NP. Show that the problem is NP-Hard. If the problem both lies in NP and is shown to be NP-Hard then we can consider it NP-Complete! 😌 Show that the problem lies in NP Showing that a problem lies in NP isn’t too difficult. To do this we need to think back to our definition of NP. A probl\",\"classification_terms\":[\"notes/omscs/cs6515/np-reduction-steps\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cs6515/linear-programming-notes/\",\"status\":200,\"title\":\"Linear Programming Notes|downey.io\",\"word_count\":1086,\"summary_text\":\"Linear Programming Notes|downey.io Linear Programming Notes|downey.io code blog photos notes Linear Programming Notes July 21, 2019 Typed version of some of my notes on Linear Programming for the Graduate Algorithms course I am taking. Not formatted the best, but it gets the job done. Linear programming provides a way of describing and solving optimization problems via the use of linear functions. Standard Form of Primal LP max cTx subject to Ax ≤ b and x ≥ 0 Standard Form of Dual LP min bTy subject to ATy ≥ c and y ≥ 0 Example Primal LP max x1 - 2x3 x1 - x2 ≤ 1 2x2 - x3 ≤ 1 x1,x2,x3 ≥ 0 Linear Algebra (Matrix) View of LP We can view the Primal LP above as a series of matrices where b is a vector containing the coefficients of the objective function, A is a matrix containing the coefficients for each x variable in each of t\",\"classification_terms\":[\"notes/omscs/cs6515/linear-programming-notes\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cs6515/graphs-minimum-spanning-trees-kruskal/\",\"status\":200,\"title\":\"Graphs - Finding Minimum Spanning Trees with Kruskal's Algorithm: a look into minimum spanning trees, kruskal's algorithm, and the cut property|downey.io\",\"word_count\":1340,\"summary_text\":\"Graphs - Finding Minimum Spanning Trees with Kruskal's Algorithm: a look into minimum spanning trees, kruskal's algorithm, and the cut property|downey.io Graphs - Finding Minimum Spanning Trees with Kruskal's Algorithm: a look into minimum spanning trees, kruskal's algorithm, and the cut property|downey.io code blog photos notes Graphs - Finding Minimum Spanning Trees with Kruskal's Algorithm a look into minimum spanning trees, kruskal's algorithm, and the cut property June 16, 2019 I wrote this up to help solidify my own understanding of minimum spanning trees and Kruskal’s algorithm for the algorithms course I’m currently taking. Explaining things in my own words helps me learn and explaining it differently from what’s already out there may help someone else. 😌 In this post I’ll explain what minimum spanning trees are, include some examples, do a walkthrough of Kruskal’s algorithm, and try my best at explaining the cut property. At the en\",\"classification_terms\":[\"notes/omscs/cs6515/graphs-minimum-spanning-trees-kruskal\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cs6515/dynamic-programming-shortests-paths/\",\"status\":200,\"title\":\"Dynamic Programming - Bellman-Ford Algorithm: an exploration of the Bellman-Ford shortest paths algorithm|downey.io\",\"word_count\":1211,\"summary_text\":\"Dynamic Programming - Bellman-Ford Algorithm: an exploration of the Bellman-Ford shortest paths algorithm|downey.io Dynamic Programming - Bellman-Ford Algorithm: an exploration of the Bellman-Ford shortest paths algorithm|downey.io code blog photos notes Dynamic Programming - Bellman-Ford Algorithm an exploration of the Bellman-Ford shortest paths algorithm June 08, 2019 You may be familiar with Dijkstra’s algorithm for quickly finding the shortest paths in a weighted directed graph. It’s usually great, but if your graph has negative edge weights Dijkstra’s algorithm will let you down. Fortunately we have (slower) alternatives such as the Bellman-Ford and Floyd-Warshall algorithms that do work when we have negative weights. In this post, I’ll talk about how the Bellman-Ford algorithm works to find shortest paths and how we can use it to find negative weight cycles (loops in the graph where the weight en\",\"classification_terms\":[\"notes/omscs/cs6515/dynamic-programming-shortests-paths\",\"about\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cs6515/dynamic-programming-corrupted-text-dpv/\",\"status\":200,\"title\":\"Dynamic Programming - DPV 6.4: an explanation for the sentence with corrupted text problem|downey.io\",\"word_count\":777,\"summary_text\":\"Dynamic Programming - DPV 6.4: an explanation for the sentence with corrupted text problem|downey.io Dynamic Programming - DPV 6.4: an explanation for the sentence with corrupted text problem|downey.io code blog photos notes Dynamic Programming - DPV 6.4 an explanation for the sentence with corrupted text problem June 04, 2019 Updated: January 12, 2020 This was an ungraded practice problem for our CS6515 class. There are existing solutions out there, but I found them a bit unintuitive so this is my attempt at explaining the problem a little differently. Problem Summary You are given a string s containing n characters s[1…n]. The string is corrupted such that all punctuation has been removed. For example, the string “you are a bold one.” would appear as “youareaboldone”. You are also given a dictionary method, dict(w), that is able to determine whether or not a substring w of s is a valid\",\"classification_terms\":[\"notes/omscs/cs6515/dynamic-programming-corrupted-text-dpv\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/dev/openmp-parallel-for-in-golang/\",\"status\":200,\"title\":\"Emulating an OpenMP Parallel For-Loop in Go: Using Goroutines to create OpenMP-style par-for loops in Golang|downey.io\",\"word_count\":507,\"summary_text\":\"Emulating an OpenMP Parallel For-Loop in Go: Using Goroutines to create OpenMP-style par-for loops in Golang|downey.io Emulating an OpenMP Parallel For-Loop in Go: Using Goroutines to create OpenMP-style par-for loops in Golang|downey.io code blog photos notes Emulating an OpenMP Parallel For-Loop in Go Using Goroutines to create OpenMP-style par-for loops in Golang May 08, 2019 In several of the labs for Georgia Tech’s Intro to High Performance Computing course we used OpenMP and C to implement some parallel algorithms. Although C can be a lot of fun, I’ve been trying to get some more practice with Go lately so this got me wondering: “Is there an equivalent to OpenMP in Go?” Although I did not find an exact drop-in replacement for OpenMP, posts on Stackoverflow lead me to realize I could accomplish similar goals using Goroutines. Specifically, I was interested in creating a simple parallel for-loop to try\",\"classification_terms\":[\"notes/dev/openmp-parallel-for-in-golang\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cse6220/distributed-memory-model-mpi-collectives/\",\"status\":200,\"title\":\"Distributed Memory Model and MPI Collectives|downey.io\",\"word_count\":1261,\"summary_text\":\"Distributed Memory Model and MPI Collectives|downey.io Distributed Memory Model and MPI Collectives|downey.io code blog photos notes Distributed Memory Model and MPI Collectives April 27, 2019 These are some of my notes on the distributed memory model and MPI collectives that are discussed in Georgia Tech’s CSE6220 High Performance Computing course. Main goal here is to lay down a brief synopsis on these topics to help me prepare for the final exam, so if you’ve stumbled on these notes some how and want to learn more, I recommend the following resources: MPI Tutorial HPC Udacity Course (Lesson 10) Distributed Memory Model The Distributed Memory model is an abstraction for dealing with problems that are too large to fit on a single machine. Essentially it just describes a networked cluster of individual computers each with their own private mem\",\"classification_terms\":[\"notes/omscs/cse6220/distributed-memory-model-mpi-collectives\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/dev/kubernetes-labels-are-case-sensitive/\",\"status\":200,\"title\":\"Kubernetes labels are case-sensitive: A few examples using Kubernetes label selectors|downey.io\",\"word_count\":582,\"summary_text\":\"Kubernetes labels are case-sensitive: A few examples using Kubernetes label selectors|downey.io Kubernetes labels are case-sensitive: A few examples using Kubernetes label selectors|downey.io code blog photos notes Kubernetes labels are case-sensitive A few examples using Kubernetes label selectors March 30, 2019 The other day someone asked me if Kubernetes label selectors are case insensitive when filtering resources. I said they definitely were, but found it difficult to find examples online. Let this post be one small step toward remedying that. setup I’m doing this all on minikube using the hello-node container image. I’ve used it to create two deployments: $ kubectl create deployment deployment-green --image=gcr.io/hello-minikube-zero-install/hello-node deployment.extensions \\\"deployment-green\\\" created $ kubectl create deployment deployment-blue --image=gcr.io/hello-minikube-zero\",\"classification_terms\":[\"notes/dev/kubernetes-labels-are-case-sensitive\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":12,\"depth\":2},{\"path\":\"/notes/dev/curl-using-mutual-tls/\",\"status\":200,\"title\":\"How to curl an endpoint protected by mutual TLS (mTLS)|downey.io\",\"word_count\":199,\"summary_text\":\"How to curl an endpoint protected by mutual TLS (mTLS)|downey.io How to curl an endpoint protected by mutual TLS (mTLS)|downey.io code blog photos notes How to curl an endpoint protected by mutual TLS (mTLS) March 24, 2019 In Cloud Foundry most internal components within the distributed system authenticate with each other via mutually-authenticated TLS (we often abbreviate this to mTLS). In mutual TLS, both the client and the server present their certificates and choose to trust each other based on their trusted certificate authorities (CAs). In traditional “one-way” TLS, it’s typically just the server that shares its certificate. This video by Lyle Franklin does a great job of explaining it in more detail. So while mTLS is great for security, it can make using common debugging techniques like directly testing an endpoint with curl trickier. You’ll need\",\"classification_terms\":[\"notes/dev/curl-using-mutual-tls\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cse6220/parallel-building-blocks-part-1/\",\"status\":200,\"title\":\"Pre-Midterm IHPC Concurrency Primitives|downey.io\",\"word_count\":1124,\"summary_text\":\"Pre-Midterm IHPC Concurrency Primitives|downey.io Pre-Midterm IHPC Concurrency Primitives|downey.io code blog photos notes Pre-Midterm IHPC Concurrency Primitives February 23, 2019 These are some of the parallel algorithm “primitives” that are discussed in the first half of the course and used to solve some parallel programming problems. Some are more generic and some are pretty specialized. There’s some ruby-esque pseudocode as well that I’ve adopted from the pseudocode in the lectures. This is all to help me prepare for the midterm exam, so if you’ve stumbled on this somehow I recommend just watching the lectures for yourself (I’ll try and include links). Those should have better explanations. All pseudocode examples will assume the presence of a spawn function for spawning a concurrent task and a sync function for blocking and waiting\",\"classification_terms\":[\"notes/omscs/cse6220/parallel-building-blocks-part-1\",\"help\",\"blog\",\"links\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cse6220/work-and-span/\",\"status\":200,\"title\":\"Work Span Analysis Notes|downey.io\",\"word_count\":430,\"summary_text\":\"Work Span Analysis Notes|downey.io Work Span Analysis Notes|downey.io code blog photos notes Work Span Analysis Notes February 17, 2019 Some loosely structured notes on the IHPC “Work and Span” lectures to help me prepare for the midterm. Explaining things in my own words helps me focus on the material and gives me a searchable artifact to find later. The contents of this one probably won’t be that useful for others though and there’s a lot of messily written non-LaTeX equations. I recommend checking out the official notes for this section. Work Span Analysis Formalism for analyzing parallel algorithms Work W(n) Total number of vertices (work) in a DAG (directed acyclic graph) Span D(n) (D represents depth) Total number of vertices in the longest path through a DAG The average available parallelism for an algorithm can be r\",\"classification_terms\":[\"notes/omscs/cse6220/work-and-span\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/notes/omscs/cs7641/restriction-and-preference-bias-supervised-learning/\",\"status\":200,\"title\":\"Preference and Restriction Biases for Supervised Learning Algorithms|downey.io\",\"word_count\":606,\"summary_text\":\"Preference and Restriction Biases for Supervised Learning Algorithms|downey.io Preference and Restriction Biases for Supervised Learning Algorithms|downey.io code blog photos notes Preference and Restriction Biases for Supervised Learning Algorithms October 06, 2018 Scattered thoughts about a few supervised learning algorithms and their restrictiona nd preference biases – it’s just to help me organize my thoughts for the CS7641 midterm. What is Restriction Bias Restriction bias is the representational power of an algorithm, or, the set of hypotheses our algorithm will consider. So, in other words, restriction bias tells us what our model is able to represent. What is Preference Bias Preference bias is simply what representation(s) a supervised learning algorithm prefers. For example, a decision tree algorithm might prefer shorter, less complex trees. In other words,\",\"classification_terms\":[\"notes/omscs/cs7641/restriction-and-preference-bias-supervised-learning\",\"about\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_coun",
        "score_reasons_json": "[\"Category evidence stayed thin, so the output was softened to a broader classification.\",\"Trusted status now requires clean crawl access and stronger confidence, so this result was downgraded to caution.\",\"Clean low-risk signals now remain neutral instead of receiving a caution tag from low confidence alone.\",\"Backfill preserved the existing category because replacement evidence was broad and low confidence.\"]",
        "estimated_monthly_visitors": 322,
        "route_domain": "downey.io",
        "display_domain": "downey.io"
    },
    "explainability": {
        "summary": "downey.io currently scores 46/100. The score is being shaped by a mixed signal profile rather than one dominant factor. Evidence confidence is strong enough for a relatively stable read. This is an estimated profile rather than a manually tracked one. Crawler access looks clean.",
        "badges": [
            {
                "label": "Profile",
                "value": "Estimated profile",
                "tone": "unknown",
                "detail": null
            },
            {
                "label": "Evidence confidence",
                "value": "High confidence",
                "tone": "good",
                "detail": "100/100"
            },
            {
                "label": "Traffic confidence",
                "value": "Moderate confidence",
                "tone": "caution",
                "detail": "44/100"
            },
            {
                "label": "Crawler access",
                "value": "Clean visibility",
                "tone": "good",
                "detail": null
            }
        ],
        "weighted_contributions": [
            {
                "label": "Quality system",
                "points": "+32.0",
                "tone": "good",
                "detail": "Technical quality, crawl depth, page structure, and implementation hygiene. Current subsystem score: 94/100."
            },
            {
                "label": "Reputation system",
                "points": "+11.6",
                "tone": "risk",
                "detail": "Authority, search visibility, reach, engagement, and registry stability. Current subsystem score: 34/100."
            },
            {
                "label": "Safety system",
                "points": "+32.0",
                "tone": "good",
                "detail": "Fraud, spam, and trust signals from infrastructure, crawl, and registry evidence. Current subsystem score: 100/100."
            },
            {
                "label": "Risk clamp",
                "points": "-30.0",
                "tone": "risk",
                "detail": "Safety thresholds capped the final score until the risk profile improves."
            }
        ],
        "evidence_cards": [
            {
                "label": "Authority and trust",
                "value": "25/100 · trust 36/100",
                "tone": "risk",
                "detail": "243 monthly visitors, 59 organic keywords, brand completeness 60/100, engagement 90/100."
            },
            {
                "label": "Backlink and search evidence",
                "value": "1 referring domains",
                "tone": "good",
                "detail": "1 backlinks across 1 referring domains. Diversity 92/100; spam penalty 6."
            },
            {
                "label": "Registry and domain stability",
                "value": "0.0 years old",
                "tone": "good",
                "detail": "Stability 100/100 · age 0.0 years."
            },
            {
                "label": "Safety and fraud posture",
                "value": "Safety 100/100 · fraud 0/100",
                "tone": "good",
                "detail": "Safety 100/100 · fraud 0/100."
            }
        ],
        "positives": [
            "Low registrar / ownership churn with solid registry stability.",
            "Healthy crawl quality and on-page completeness.",
            "Registry history looks stable, which supports legitimacy and trust.",
            "HTTPS is working, so the site clears a basic transport-security check.",
            "Backlink diversity looks broad enough to strengthen authority confidence."
        ],
        "risks": [
            "Traffic and reach estimates are still low confidence, so commercial scale signals may move after more evidence is collected."
        ],
        "freshness": [
            {
                "label": "Crawl evidence",
                "value": "2026-04-30 23:03:34",
                "tone": "risk",
                "detail": "Crawl and page content sample. Age: 1mo ago."
            },
            {
                "label": "WHOIS snapshot",
                "value": "2026-04-30 23:03:33",
                "tone": "risk",
                "detail": "Registry profile and stability signals. Age: 1mo ago."
            },
            {
                "label": "Keyword view",
                "value": "2026-06-23 23:23:32",
                "tone": "good",
                "detail": "Estimated visibility until tracked keyword snapshots exist. Age: 0s ago."
            },
            {
                "label": "Rank history",
                "value": "2026-06-23 23:23:32",
                "tone": "good",
                "detail": "Estimated trend derived from current profile and crawl signals. Age: 0s ago."
            },
            {
                "label": "Audience geography",
                "value": "Not captured yet",
                "tone": "unknown",
                "detail": "Audience mix is estimated from available signals rather than first-party audience logs."
            }
        ],
        "section_notes": {
            "audience": "Audience geography is estimated from category, country, traffic mix, and brand signals until first-party audience data is collected.",
            "keywords": "Top keywords are estimated from crawl language, brand, category, and visibility signals until tracked keyword snapshots are stored.",
            "history": "Rank history is estimated from the current profile because no stored history exists for this domain yet."
        },
        "base_weighted_score": 76,
        "fraud_clamp_penalty": 30,
        "final_score": 46
    },
    "insight_snapshot": {
        "version": 1,
        "generated_at": "2026-06-23T23:23:32+00:00",
        "domain": "downey.io",
        "display_name": "downey.io",
        "is_tracked": false,
        "is_estimated": true,
        "overall_score": 46,
        "authority_score": 25,
        "trust_score": 36,
        "safety_score": 100,
        "fraud_score": 0,
        "confidence_score": 100,
        "traffic_confidence": 44,
        "last_crawled_at": "2026-04-30 23:03:34",
        "crawl_blocked": false,
        "summary": "downey.io currently scores 46/100. The score is being shaped by a mixed signal profile rather than one dominant factor. Evidence confidence is strong enough for a relatively stable read. This is an estimated profile rather than a manually tracked one. Crawler access looks clean.",
        "badges": [
            {
                "label": "Profile",
                "value": "Estimated profile",
                "tone": "unknown",
                "detail": null
            },
            {
                "label": "Evidence confidence",
                "value": "High confidence",
                "tone": "good",
                "detail": "100/100"
            },
            {
                "label": "Traffic confidence",
                "value": "Moderate confidence",
                "tone": "caution",
                "detail": "44/100"
            },
            {
                "label": "Crawler access",
                "value": "Clean visibility",
                "tone": "good",
                "detail": null
            }
        ],
        "top_positive_signals": [
            "Low registrar / ownership churn with solid registry stability.",
            "Healthy crawl quality and on-page completeness.",
            "Registry history looks stable, which supports legitimacy and trust.",
            "HTTPS is working, so the site clears a basic transport-security check.",
            "Backlink diversity looks broad enough to strengthen authority confidence."
        ],
        "top_risk_signals": [
            "Traffic and reach estimates are still low confidence, so commercial scale signals may move after more evidence is collected."
        ],
        "freshness": [
            {
                "label": "Crawl evidence",
                "value": "2026-04-30 23:03:34",
                "tone": "risk",
                "detail": "Crawl and page content sample. Age: 1mo ago."
            },
            {
                "label": "WHOIS snapshot",
                "value": "2026-04-30 23:03:33",
                "tone": "risk",
                "detail": "Registry profile and stability signals. Age: 1mo ago."
            },
            {
                "label": "Keyword view",
                "value": "2026-06-23 23:23:32",
                "tone": "good",
                "detail": "Estimated visibility until tracked keyword snapshots exist. Age: 0s ago."
            },
            {
                "label": "Rank history",
                "value": "2026-06-23 23:23:32",
                "tone": "good",
                "detail": "Estimated trend derived from current profile and crawl signals. Age: 0s ago."
            },
            {
                "label": "Audience geography",
                "value": "Not captured yet",
                "tone": "unknown",
                "detail": "Audience mix is estimated from available signals rather than first-party audience logs."
            }
        ],
        "top_tags": []
    },
    "is_tracked": false,
    "is_estimated": true,
    "live_state": {
        "status": "processing",
        "status_label": "Cache build running",
        "message": "The refreshed page cache is still being built for this domain.",
        "updated_at": "2026-06-24T01:27:07+00:00"
    },
    "refresh_state": {
        "canRequest": false,
        "queued": true,
        "processing": true,
        "stageKey": "cache-queued",
        "stageLabel": "Cache build running",
        "cooldownUntil": null,
        "message": "The refreshed page cache is still being built for this domain.",
        "action": "/domain/downey.io/refresh",
        "isGuestCooldown": false,
        "cooldownSeconds": 0
    },
    "urlscan_report": {
        "domain": "downey.io",
        "status": "idle",
        "submitted_at": null,
        "completed_at": null,
        "last_checked_at": null,
        "last_error": "",
        "submitted_url": "https://downey.io/",
        "uuid": "",
        "result_url": "",
        "api_result_url": "",
        "visibility": "public",
        "summary": "No urlscan.io report has been requested for this domain yet.",
        "report": [],
        "report_summary": [],
        "is_fresh": false,
        "can_retry": true,
        "poll_after_seconds": 20
    }
}