# Cyberole security hiring language study Snapshot: 2 November 2026. Author: Farhad R / Cyberole. This is descriptive research, not a vacancy forecast or a representative labour-market survey. ## Reproduce Requirements: Python 3 standard library, Node.js 22+ (no npm dependencies for collection/analysis), internet access to the public HN APIs. The responsive opening chart uses a small derived JSON file; matplotlib is only needed for the older optional static export. Unzip security-hiring-reproduction.zip into an empty directory. Run from that directory: python3 scripts/research/collect-security-hiring.py node scripts/research/build-security-hiring.mjs node scripts/research/build-security-hiring-overview.mjs The default cache is the operating system temporary directory, cyberole-hn-research. Set HN_RESEARCH_CACHE to the same absolute directory for both commands to change it. Outputs are public/research/security-hiring-2016-2026.json and content/research/security-hiring-findings.json. The overview builder produces content/research/security-hiring-overview.json from the frozen post records, checks pooled counts against the published findings and retains all ten annual observations. The older plotting script requires matplotlib and numpy; the article now renders its opening chart as responsive HTML and Recharts instead of that static image. Collection is cached and retry-limited, with six parallel thread requests and sixteen parallel requests for missing direct comments. It fetches no profiles, contact endpoints, external job descriptions or credentials. Re-running with the cache preserves the retrieved source versions. Fresh collection can differ because posts can change or be deleted. Raw source caches are not published. ## Frame and units 120 regular monthly Who is hiring? threads, November 2016 through October 2026, by whoishiring. Nonregular special threads and the partial November 2026 thread are excluded. Search discovery uses https://hn.algolia.com/api, then each thread's direct-child inventory is checked against https://github.com/HackerNews/API . Every missing indexed direct child is fetched from the official API. The snapshot has 69,065 readable direct comments, 5,273 deleted/dead/textless comments, no unresolved IDs and no missing months. Replies are excluded. Six exact case-normalised duplicates within the same month are removed from the security subset. Unit: one security-classified company comment per month, not one vacancy, candidate, company, or filled job. One comment can advertise several roles. Employers can reappear across months. The final sample has 2,284 ads, including a heuristic focused subset of 513. A multi-role comment can contain keywords unrelated to its security vacancy. ## Classification and audit lib/security-hiring.js contains the full role regexes and 37 predeclared skill/keyword dictionaries. Classification requires a security role-title pattern, including reversed application-security titles. Bare company claims about security compliance or offensive-security products do not qualify by themselves. Explicit role exceptions and exclusions are recorded in JSON files. Security-near nonmatches form a diagnostic review pool. A separate agent read 60 deterministically selected candidate ads: 10 early included, 10 middle included, 10 recent included, 10 focused included, 20 excluded security-near. That initial diagnostic review found both false inclusions and missed roles; the rules and six individual inclusion/exclusion exceptions were corrected. Another 20 included posts were read as a diagnostic holdout after changes. This is model-assisted review, not independent human validation or an estimate of whole-corpus accuracy. The holdout identified role-list and incumbent-title ambiguities; known examples were corrected and regression-tested. Remaining automated classifications should still be checked against source posts. The focused flag requires a security-role match in the first 450 characters and no recognised other-role phrase in the comment. It is deliberately described as heuristic: it can miss mixed-role lists and exclude a genuine security-only ad that mentions software-engineer colleagues. ## Matching and denominators Each dictionary contributes one binary indicator per ad. Percent = 100 * matching ads / all filtered security ads in the period. It measures mentions, not required skills, tool usage, competence or seniority of every vacancy. Missing wording is not proof of irrelevance. All category memberships overlap. HN annual periods run November through October, labelled by ending year 2017 to 2026. The descriptive early/recent comparison pools November2016-October2019 (n731) and November2023-October2026 (n356), two equal 36-month windows with the same seasonal coverage. No significance labels or hypothesis-test conclusions are reported. All 37 predeclared dictionaries remain visible, including low-count or null results. Custom keywords search one literal case-insensitive token, 2 to40 characters, from a sorted vocabulary. They cannot execute regex or scripts and do not search phrases. Vocabulary tokenisation is in the builder. Complete email addresses and HTTP/bare-domain web addresses are removed before vocabulary extraction; raw ad prose and commenter handles are not published. Post IDs permit original-source inspection. Preset dictionary indicators are computed on decoded text after stripping email addresses and HTTP/bare-domain web addresses, so their phrase/alias behaviour differs from custom single-word searches. The exact-wording sensitivity mode counts the first occurrence of a normalised full-text SHA-256 hash within the selected filters/date range. It is not company deduplication: small textual changes evade it, and different companies could share wording. Across the full decade this yields 2,002 posts. The main AI and seniority directions persist with this option and in the focused subset. First-in-period attribution can move repeats into earlier periods, so this is a sensitivity check, not a preferred estimate. ## Uncertainty 95% Wilson score intervals: z=1.959963984540054; p=k/n; denominator d=1+z*z/n; centre=(p+z*z/(2*n))/d; halfwidth=z*sqrt(p*(1-p)/n+z*z/(4*n*n))/d. Return centre +/- halfwidth, clipped to[0,1]. Empty denominators yield missing values, not zero. A zero numerator still has a positive upper interval. Method reference: https://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm . These intervals assume independent Bernoulli observations. This is a nonrandom platform sample with repeated employers; intervals do not cover selection bias, correlated posts, classification error, missing descriptions or changes in source composition. They are conditional precision guides, not population uncertainty. No multiple-testing significance claims or causal estimates are made. ## Geography Optional US, UK, EU or other/unspecified tags use explicit country/city tokens in the first350 characters only. The matching expressions are in the builder, not inferred from IP addresses. The list is incomplete, cities can be ambiguous and regions overlap. REMOTE alone cannot establish eligibility. These tags are suitable for exploratory filtering, not national hiring-rate estimates. ## Opening chart labels The opening comparison uses the first and last 36 months, with 731 and 356 posts. Its selectable line chart shows every November-to-October year across the full decade. Senior/staff/principal wording counts those literal words anywhere in the post, including another vacancy or a generic reference to company staff. Teamwork/stakeholder wording counts words beginning with collaborat, teamwork, cross-functional, and stakeholder/stakeholders. AI/ML wording uses the existing AI dictionary. Labels are descriptions of matching words, not validated experience requirements or candidate attributes. Each post counts at most once per word group. Matching definitions and annual denominators are available in the opening chart and its data table. ## Separate UK dataset Aggregate rounded percentages from DSIT / Lightcast core cybersecurity ads, not HN. Calendar2023 n48,492 (2024 report Figure7.7),2024 n32,370 (2025 Figure4.7),2025 n34,932 (2026 Figure4.7). Source URLs are attached to every year in uk-security-skills-2023-2025.json. AI2023 is missing, not0. No inferred exact counts, artificial intervals, interpolation across missing values, or linkage to a ten-year certificate series. Public-sector information is attributed under the Open Government Licence v3.0; third-party rights remain with owners. ## Future scenarios The explorer uses a transparent assumption calculator: future share = clip(last observed share + user-selected annual percentage-point change * years,0,100). It is not fitted, backtested, or presented as a statistical prediction. Its dashed guide is an assumed future share, not an observed value. Short, selective series cannot justify a reliable labour-market forecast. ## Files and provenance The public HN snapshot includes month/thread IDs, readable counts, security counts, official direct-child counts, source-index SHA-256 hashes, ad IDs, role/location/scope flags, normalised-wording hashes, dictionary matches and sorted vocabulary. The reproduction archive contains collection, analysis and plotting scripts, shared matching/statistical code and diagnostic audit records. HN content has no implied Cyberole relicensing; ad prose is not republished. Source sites and ad content can change after retrieval. Historical inspiration: https://github.com/hacker-job/hacker-job/blob/d14b18cc7fd5c867d84552652f754a32d5ea7f5a/README.md and https://www.hntrends.com/ . Their figures are not reused as security-market measurements.