ConceptioArchivearXiv CS
arXiv CSopen access

Code Lifespan Survival Analysis (CLSA): Predicting the Survival of Source Code Lines Using AST-Aware Mining

Unknown · 2026 · arxiv_cs
arXiv CS · Papers · License: Open Access · 2026
Open Source ↗Direct PDF ↓
softwarearchitecturesoftwareengineeringtesting
software engineering, software architecture, testing

Code Lifespan Survival Analysis (CLSA): Predicting the Survival of Source Code Lines Using AST-Aware Mining Authors: Pavel Gurov Affiliations: Independent Researcher

arXiv:2606.04993v1 [cs.SE] 3 Jun 2026

Abstract Context: Predicting which source code lines will be deleted — and when — has direct implications for maintenance planning, technical-debt management, and code-review prioritization. Existing MSR approaches operate at file or method granularity, masking the heterogeneous deletion risk of individual statements. Objective: We introduce Code Lifespan Survival Analysis (CLSA), the first framework to model code survival at the granularity of individual lines. CLSA treats each source line as a right-censored survival subject and estimates its deletion risk from structural, contextual, and temporal covariates, with its strongest predictors computable statically from a single source file — combining AST structure with lexical features such as line entropy — without any version history or historical bug data. Method: We mine 32.5 million line birth events from 120 active open-source TypeScript repositories. A 5-stage bipartite matching pipeline separates true deletions from refactoring noise (migrations and semantic rewrites), preventing 8.3 million false death classifications — a prerequisite for unbiased line-level survival estimation. We fit a Cox Proportional Hazards model with 15 covariates and assess robustness via Weibull and Log-Logistic AFT models, a shared gamma frailty model, time-stratified landmark analysis, and four sensitivity subsets. Results: Within our observation window, more than half of all lines are never deleted (Kaplan–Meier median survival not reached); among deleted lines, the median lifespan is 95.7 days, marking an early “stabilize-or-die” phase. Covariate effects are strongly time-varying and organize into an interpretable three-regime structure. Line Shannon entropy is moderately protective for new code (HR = 0.84, 0–90 days) and strongly protective for mature code (HR = 0.36, 365+ days) — a monotonic strengthening that mechanistically explains its proportional-hazards violation. Lines in conditional branches reverse direction: mildly protective at birth (HR = 0.97) but a risk factor after 90 days (HR = 1.21). Repository identity is the single largest predictive factor: a shared gamma frailty model (variance θ = 1.449) raises concordance from 0.586 to 0.666, outweighing every structural covariate. Conclusion: Line-level survival modeling is tractable and yields interpretable, largely statically-computable risk signals (from AST structure and lexical features) for software evolution. The three-regime time structure and the dominance of repository frailty provide both an empirical basis and a calibration recipe for time-conditional risk scoring in IDEs and code review. 1

1. Introduction Source code is inherently dynamic. Across a project’s lifecycle, lines of code are continuously added, modified, migrated between files, and deleted—processes that collectively constitute software evolution. While traditional metrics in Mining Software Repositories (MSR)—such as code churn [8], file age, or architectural ownership—provide valuable macro-level insights, they often lack the granularity required to evaluate individual statement volatility. File-level and method-level aggregations mask the heterogeneous risk profiles of individual statements: a stable function signature and a volatile expression within the same method face fundamentally different hazard dynamics. In this work, we model each source code line as a survival subject—an entity born at the commit where it first appears and at risk of permanent deletion throughout the repository’s history. Leveraging classical survival analysis techniques from actuarial science and biostatistics, we estimate the probability that a given line persists in the codebase over time, conditional on its structural and contextual covariates. Crucially, our framework distinguishes three change topologies: migrations (lines relocated across files), modifications (semantically rewritten lines matched via composite Sørensen–Dice + Ratcliff/Obershelp similarity), and true deaths (permanent deletions without a semantic successor). Only true deaths constitute the event of interest; migrations and modifications are treated as censored observations, preserving the line’s survival identity. Empirically, we analyze 32.5 million line birth events from 120 active TypeScript repositories on GitHub, building a deterministic sample of 350,000 lines for multivariate modeling. TypeScript was selected for its rich AST node taxonomy and the large number of active open-source projects it hosts, providing a representative spectrum of domains and project scales. Our main contributions are as follows: 1. 5-Stage Semantic Alignment Pipeline: We introduce a bipartite matching algorithm that isolates true line deletions from refactoring noise through five progressive stages: intra-file exact structural matching, global AST-equivalent detection, Hungarian algorithm–based lexico-semantic assignment [2], cross-file similarity matching, and high-confidence ASTagnostic intra-file matching. The pipeline prevents 8.3 million false deaths in the full population — a prerequisite for unbiased survival estimation at line granularity. 2. Time-Stratified Three-Regime Analysis: We discover that covariate effects are not merely time-varying but follow an interpretable three-regime structure (< 90 days, 90–365 days, 365+ days). Line Shannon entropy transitions from moderate protection in new code (HR = 0.843) to extreme protection in mature code (HR = 0.359). in_condition reverses direction 2

after 90 days. These findings reframe PH violations as mechanistically meaningful signals rather than statistical nuisances. 3. Repository Frailty Quantification: We fit a shared gamma frailty Cox model (R survival package) and estimate frailty variance θ = 1.449 across the analyzed repositories (clustering restricted to those with ≥ 30 events; LRT χ2 = 36,280, p ≈ 0), confirming that repository-level heterogeneity is the dominant source of survival variance and improving C-index from 0.586 to 0.666. 4. Line-level Survival Modeling at Statement Granularity: We are the first to apply survival analysis at individual line granularity — a finer unit than the file [6] or open-source project [3] level used in prior MSR survival studies — enabling per-statement hazard estimates that are computable statically from a single file snapshot — from AST structure and lexical features such as line entropy — without historical bug data. We show that ast_group_expression and in_function are the most stable structural predictors across all sensitivity models. 5. AST-Aware Structural Context Features: We introduce two binary AST-derived covariates — in_condition and in_function — whose survival effects are robust across marginal Cox, frailty Cox, AFT, and timestratified models. Two additional covariates (in_loop, in_try_catch) are shown to be repository-level proxies rather than genuine line-level predictors, a distinction requiring the frailty model to detect [1]. The remainder of the paper is organized as follows. §2 reviews related work. §3 formalizes the survival problem. §4 states research questions. §5 describes the data collection and statistical methodology, including the three-regime timestratified design. §6 presents empirical results. §7 discusses practical implications. §8 addresses threats to validity. §9 concludes.

2. Background and Related Work 2.1 Mining Software Repositories & Code Change Analysis The MSR community has extensively studied code churn and file-level evolution to inform defect prediction [6] and refactoring scheduling [7]. Nagappan and Ball [8] demonstrated that code churn metrics are strong predictors of defect density. Hassan [9] introduced the concept of “entropy of changes” as a complexity proxy. However, most existing works aggregate changes at the file or method level using traditional git diff heuristics. These macro-approaches often mask the underlying statement-level risk dynamics. Tools like PyDriller [4] have revolutionized commit traversal, but moving down to accurate line-level tracking requires mitigating the severe noise inherent to spatial line shifting. Hattori and Lanza [10] categorized commit types but did not model individual line survival.

3

The most influential line-level blame technique in MSR is the SZZ algorithm [22] (Śliwerski, Zimmermann, and Zeller, 2005), which propagates a bug-fix commit backward through git blame to identify the change that introduced the fault. Kim et al. [23] later automated and scaled SZZ across large repositories. CLSA differs from SZZ in three fundamental respects: (i) direction — SZZ traces history backward from a known defect; CLSA models the forward survival trajectory of every line from birth onward; (ii) trigger — SZZ is event-driven (applied only when a bug fix is committed); CLSA is population-wide (applied continuously, for every line); (iii) objective — SZZ produces a deterministic fault-origin attribution; CLSA produces a probabilistic survival estimate. Where SZZ asks “who introduced this bug?”, CLSA asks “how long will this line exist?” Both approaches depend critically on accurate line-level identity tracking across commits — the challenge addressed by our 5-stage matching pipeline (§5.2). 2.2 Survival Analysis in Software Engineering Survival analysis encompasses statistical procedures where the outcome variable of interest is the time until an event occurs. Samoladas et al. [3] applied survival analysis to study the longevity of open-source projects, demonstrating the utility of Kaplan–Meier and Cox models in SE contexts. Shahzad et al. [11] used survival models to analyze vulnerability life cycles in software systems. Raemaekers et al. [5] applied similar techniques to study semantic versioning compliance and breaking changes in Maven libraries. Bavota et al. [12] empirically studied how test smells affect maintenance effort and test-suite quality across software evolution, documenting longitudinal change patterns in open-source test code. Crucially, survival analysis naturally handles right-censored data—cases where the study ends before the outcome event occurs (e.g., active code still present at the time of the latest commit). Correct handling of censored observations is essential: treating all lines as “dead” would severely bias survival estimates downward and produce misleading hazard ratios [13]. Across all of these studies, however, the unit of analysis has remained coarse — the open-source project [3], the library or API [5], the vulnerability [11], or the class [17]. To our knowledge, no prior MSR study has treated the individual source line as a survival subject with its own birth, censoring, and event semantics. CLSA fills this granularity gap, modeling time-to-deletion at a unit two to three orders of magnitude finer than the file- and project-level subjects of prior work. 2.3 AST-Based Code Analysis Recent advances in tree-sitter and similar incremental parsers allow for structural, rather than purely textual, analysis of code. GumTree [1] introduced fine-grained AST differencing that maps individual node-level changes, enabling precise classification of code modifications. Fluri et al. [14] proposed ChangeDistiller, which extracts fine-grained source code changes from AST diffs. Combining AST-derived structural features with revision history is known to be superior to simple grep-based heuristics [1], allowing us to categorize nodes directly from the 4

syntactic topology. Our approach extends this line of work by using tree-sitter AST node types as survival covariates. 2.4 Code Complexity and Change-Proneness Several studies have linked code complexity metrics to change frequency. Gil and Lalouche [15] comprehensively evaluated complexity metrics, finding that cyclomatic complexity and nesting depth correlate with change-proneness. Munson and Elbaum [16] showed that code complexity metrics serve as predictors of fault-prone modules. Khomh et al. [17] applied survival analysis specifically to study the relationship between code smells and change-proneness, finding that classes with certain anti-patterns exhibit higher hazard rates—a finding conceptually parallel to our line-level analysis. 2.5 Technical Debt and Code Decay The concept of “code decay” has been studied through the lens of technical debt [18], and behavioral code analysis using version control history has been proposed to identify high-risk code regions [19]. Our work complements this perspective by directly modeling the time-to-event dynamics of individual code lines, providing quantitative survival estimates rather than qualitative risk labels.

3. Problem Definition 3.1 Line as a Survival Subject We rigorously define each source code line i as a random variable experiencing time-to-event dynamics: - Birth time (tbi ): The commit timestamp where the line first naturally appears. - Death time (tdi ): The commit where the line is permanently removed from the codebase. - Observed duration: Ti = min(tdi − tbi , C − tbi ), where C is the censoring time (the last commit date per repository). - Event indicator: δi = ⊮[tdi ≤ C] Lines without an explicitly observed death are right-censored. In our dataset, 66.1% of observations are right-censored, indicating that the majority of code lines remain alive at the end of the observation period. 3.2 Event Types and Change Topologies A naïve git diff-based approach treats every textual deletion as a death event, severely inflating hazard estimates. To mitigate this refactoring noise, we classify every observed change into one of three topologies: • Migration: A line disappears from its original file path but reappears with identical content and matching AST node type in another file (or at a different location after a file rename). The line retains its original identity (UUID) and continues to accumulate survival time. Migration ̸= death. 5

• Modification: A line is textually altered but remains semantically continuous—matched via composite similarity (Sørensen–Dice + Ratcliff/Obershelp, threshold ≥ 0.6) with the same AST node type. A new identity (UUID) is created and linked to the original via an evolution record (line_evolution table). The original line is treated as right-censored at the modification commit, not as dead. The new identity begins its own independent survival trajectory. • True Death: A line is permanently removed from the codebase without any semantic successor in the same commit. Only hard deletions (hard_delete) and file-level deletions (file_delete) constitute the event of interest (δi = 1). This three-way classification ensures that the survival model captures genuine code extinction rather than refactoring artifacts [2].

4. Research Questions To structure our investigation, we formulate the following research questions: - RQ1 (Baseline Survival): What is the baseline survival distribution of source code lines in active TypeScript projects? - RQ2 (Syntax Role): How does the AST role of a line (e.g., declaration vs. expression) affect its hazard rate? - RQ3 (Structural Complexity): How does structural complexity (such as nesting depth and enclosing scope type) influence hazard rates? - RQ4 (Temporal Context): Does the time of writing (e.g., weekend vs. weekday, day vs. night) affect the stability of the code? - RQ5 (Global Uniqueness): How does the global uniqueness (LIDF) of a line correlate with its stability? - RQ6 (Change-Type Awareness): How do different change types (hard deletion vs. semantic rewrite vs. migration) influence observed survival behavior?

5. Data Collection and Analytical Methodology The core challenge of MSR in time-to-event analysis is false positives: a line merely changing its indentation or moving to another file appears as a standard Git deletion, skewing survival metrics heavily downward. To solve this, we implemented a sophisticated analytical framework. 5.1 Repository Extraction and Syntactic Filtering Using PyDriller [4], we iterate over the repository’s entire commit history, restricting to .ts and .tsx file types. Generated and vendor files are excluded before any line-level processing: paths containing the segments dist/, build/, .next/, out/, or node_modules/, TypeScript declaration files (.d.ts), and files whose first non-empty line begins with a standard generated-code marker

6

(// @generated, // Code generated, /* eslint-disable */) are skipped entirely. For each remaining modified file, we parse both source_code_before and source_code with tree-sitter, enabling precise mapping of diff line numbers to their AST nodes. Two categories of lines are additionally excluded from the event pool: 1. Comment lines: Any line whose AST node is classified as a comment by tree-sitter is discarded. This is an AST-structural filter, not a regex heuristic, ensuring robust detection of single-line (//), block (/* */), and JSDoc comments. 2. Trivial tokens (length < 5 characters): Lines consisting solely of structural punctuation—braces ({, }), parentheses, semicolons, or short keywords— are excluded. The 5-character threshold was chosen empirically to filter syntactic scaffolding (e.g., });, else, } else {) while retaining the shortest meaningful statements (e.g., i++;, break;, x = 0). These trivial tokens carry no semantic information relevant to survival analysis and would otherwise dominate the dataset with near-infinite lifespans, biasing censoring rates upward. 5.2 Multi-Stage Optimal Alignment Pipeline Lines surviving the initial AST filter undergo string cleaning (whitespace stripping). Additions and deletions are then pooled into bipartite sets. To resolve migrations and semantic rewrites from true deaths, we execute a rigorous 5-stage matching pipeline: 1. Exact Structural Match (Intra-File): Exact string content with matching AST node type within the same file (or its rename target). Handles the common case of pure line relocation or unchanged code in a modified file. 2. Global Structural Match: Exact string and AST-type equivalents migrating to any other file across the repository. Captures full-file moves and directory-level restructuring not caught by Git rename detection. 3. Linear Sum Assignment (Intra-File, AST-aware): For remaining unmatched lines within the same file path, we construct a cost matrix comparing all remaining unassigned additions to deletions. We apply the Hungarian minimum-cost assignment algorithm [24] over a composite similarity matrix. The similarity score is a weighted combination of the Sørensen–Dice coefficient on tokenized strings (70%) and the Ratcliff/Obershelp similarity on normalized text (30%) [20, 21], implemented via Python’s difflib.SequenceMatcher.ratio(). The AST node type must match between deletion and addition candidates. Any pair similarity ≥ 0.6 (cost ≤ 0.4) is classified as a “modification” lineage rather than a true death. For large file-pairs (|del| × |add| > 100,000), a greedy descending-similarity pass replaces the O(N 3 ) Hungarian step to bound memory usage. 4. Cross-File Similarity (AST-aware): Unmatched deletions and additions across different files are grouped by AST type and compared pairwise (groups exceeding 50,000 pairs are skipped). Handles directory renames and large-scale refactors not resolved by Stages 1–3. Uses the same 0.6 threshold and Sørensen–Dice + Ratcliff/Obershelp composite. 5. Intra-File AST-Agnostic Similarity

7

(high-confidence only): A final pass within each file path that removes the AST-type constraint but raises the threshold to ≥ 0.9. Resolves lines where the AST node type changed (e.g., an expression wrapped in a try-catch) but textual content is nearly identical. Conceptually aligning with the two-phase mapping approach of GumTree [1], our pipeline prioritizes exact structural AST matches (Stages 1–2). Stages 3–5 progressively relax constraints to capture increasingly complex code evolutions while controlling for false modification matches through higher thresholds and AST-type guards. 5.3 Structural Context Extraction Beyond the AST node type, we extract two categories of structural features for each line by traversing the tree-sitter AST from the line’s node upward to the root: Nesting depth is computed as the count of scope-creating ancestors encountered during the parent-chain traversal. The following AST node types increment the nesting counter: statement_block, class_body, function_declaration, and arrow_function. Thus, a line inside a function body at the top level has nesting depth 2 (one function_declaration + one statement_block), while a line inside a nested callback has depth 4 or higher. This metric captures the hierarchical complexity of a line’s position in the code structure. Four binary structural context flags indicate whether any ancestor in the parent chain matches specific scope types: - in_loop: Whether the line resides inside a for, for...in, while, or do loop body. - in_condition: Whether the line is within the body of an if, switch, or ternary expression. - in_try_catch: Whether the line is enclosed in a try, catch, or finally block. - in_function: Whether the line is inside a function declaration, arrow function, or method definition. Line Shannon entropy (log_entropy) quantifies the information density of each line’s character composition. For a normalized (whitespace-stripped) line with character multiset C, let pc = count(c)/|C| denote the Prelative frequency of character c. The raw Shannon entropy is H(s) = − c∈C pc log2 pc . We apply a log-transform to stabilize variance and compress the long right tail: log_entropy = ln(1 + H(s)), stored as a real-valued feature. High values correspond to information-dense lines (e.g., complex function calls, type annotations with multiple generics); low values indicate repetitive or structurally simple content (e.g., lines consisting of a single repeated character). This feature is stored as a floating-point column (line_entropy) in the ClickHouse features table. Line–TODO proximity (log_todo_distance): For each tracked line, we compute the absolute line-number distance to the nearest // TODO or // FIXME annotation in the same file at the time of the line’s birth commit. If no such

8

annotation exists in the file, the distance is set to the file length. We then apply a log-transform: log_todo_distance = ln(1 + distance_to_todo), stored as a Float32 column in the features table. The feature operationalizes proximity to acknowledged technical debt: a line directly below a TODO marker is assigned a small value; a line in a stable, annotation-free region of the file receives a large value. We include it as a continuous covariate in the Cox model to test whether proximity to known deferred-work annotations correlates with deletion risk independently of structural features. These features capture the enclosing structural scope, information density, and proximity to deferred-work markers of a line. All binary and integer features (nesting depth + four flags) are stored as UInt8 columns; log_entropy and log_todo_distance are stored as Float32 columns in the ClickHouse features table and populated during the mining phase. 5.4 Storage Architecture Processing results are stored in a ClickHouse columnar database using MergeTree engines across nine domain tables: birth events, death events, migration/modification lineage, per-line structural features, raw content, and a cross-repository global dictionary for LIDF computation. Full DDL and schema definitions are provided in the replication package. 5.5 Statistical Analysis Design Our statistical pipeline consists of five complementary components: 1. Non-parametric estimation: Kaplan–Meier survival curves with log-rank tests across stratified groups (RQ1–RQ4). All pairwise p-values are subject to Benjamini–Hochberg (BH) FDR correction. In the RQ2– RQ4 stratified log-rank analysis, 15 pairwise comparisons are performed: 10 RQ2 AST-group pairs (C(5,2) over the five most-populated AST groups — declaration, control_flow, expression, import_export, type_system; the heterogeneous other group is excluded from the KM/log-rank comparison but retained in the multivariate Cox model), 3 RQ3 nesting-tier pairs (flat vs. nested, flat vs. deep, nested vs. deep), and 2 RQ4 temporal pairs (weekday vs. weekend, day vs. night). 13 of 15 survive BH correction at α = 0.05; the two non-significant results are control_flow vs type_system (p_adj = 0.072) and weekday vs weekend (p_adj = 0.917). 2. Semi-parametric modeling: Cox Proportional Hazards regression with L2 regularization (penalizer = 0.1) and 15 covariates for multivariate assessment (RQ5). Proportional hazards assumption is explicitly tested via Schoenfeld residual diagnostics. 3. Sensitivity analysis: Four robustness checks—nested-only lines, singlerepository, exclusion of ephemeral lines (<1 day), and a per-repository stratified subsample (cap 10,000 lines per repository)—plus Weibull AFT 9

and Log-Logistic AFT models to evaluate covariate stability under distributional alternatives. 4. Time-stratified Cox analysis: Separate Cox models on three landmark time bands (0–90d, 90–365d, 365+d) to expose time-varying covariate effects and provide mechanistic interpretation of PH violations. 5. Shared frailty model: A gamma frailty Cox model with repository identity as cluster variable (Zi ∼ Gamma(1/θ, 1/θ)), fitted in R (survival package) to decompose within-project and between-project sources of hazard variation and address Simpson’s paradox observed in the marginal model. Sample sizes across analyses. Different analytical stages use different sample sizes, each motivated by a specific constraint: the Python Cox model uses n = 300,000 (subsample of 350K, drawn to manage Schoenfeld residual computation cost); the time-stratified landmark analysis uses the full sample (349,510 lines after dropping comment_like; no Schoenfeld computation required); and both R models (marginal and frailty Cox) use n = 346,808 (the full 350,000-line analytical sample after dropping comment_like lines and excluding repositories with fewer than 30 events from frailty clustering). Numerical differences in hazard ratios between Python and R models are additionally attributable to the L2 ridge penalty applied only in the Python model (λ = 0.1), which shrinks coefficients toward zero.

6. Empirical Evaluation 6.1 Dataset Summary We mined 120 active TypeScript repositories spanning a wide range of project ages, sizes, and domains. In total, the dataset contains 32.5 million line-level birth events across all repositories, of which 11.0 million (33.9%) are true deletions (hard_delete + file_delete); the remaining 21.5 million (66.1%) are rightcensored — lines that remain alive or underwent migration/modification as of the repository’s last commit. For the Cox analytical design, we sampled 350,000 lines using a deterministic hashbased sampling strategy (ORDER BY cityHash64(id) LIMIT 350000), ensuring full reproducibility. After censoring detection and quality filtering, the final dataset contains: - 350,000 total observations - 118,787 death events (33.9%) - 231,213 right-censored observations (66.1%) Table 1 presents the top 10 repositories by total lines mined. The full catalog of all 120 repositories is provided in Appendix A.

10

Repository Name microsoft/ vscode Expensify/App twentyhq/ twenty DefinitelyTyped/ DefinitelyTyped ag-grid/ag-grid microsoft/ FluidFramework remotion-dev/ remotion tamagui/ tamagui supabase/ supabase triggerdotdev/ trigger.dev

Age (Mo.)

Commits

Files

Lines Mined

Deaths

Survived

126

118,215

18,375

4,031,373

966,838

1,909,391

35 41

99,575 10,201

12,513 44,565

2,835,458 2,170,359

1,039,257 1,124,026 785,557 990,896

163

69,085

19,547

1,853,038

724,178

773,375

130 116

23,141 16,807

20,475 17,976

1,570,216 1,468,504

539,199 558,400

693,573 569,540

71

18,733

10,709

1,349,990

328,921

614,026

67

11,132

15,035

1,132,232

688,627

285,154

67

15,808

13,485

1,072,324

355,801

541,225

41

4,979

4,552

1,019,397

629,277

329,335

Table 1: Dataset Overview (top 10 by total lines mined; 120 repositories total). Note: Deaths* + Survived < Lines Mined in all rows; the gap represents lines whose identity was transformed via migration or modification (logged in line_evolution) — these are right-censored in the survival model but do not appear in either the death or survived counts. The complete repository catalog is provided in Appendix A.* 6.2 Data Cleaning & Construct Validity The pipeline operates on two parallel streams. On the birth (additions) side, the AST-aware filter removed 4,807,296 comment lines identified via tree-sitter semantics and 19,626,602 trivial structural tokens (length < 5) from the raw Git additions, yielding 32,464,566 tracked birth events across all 120 repositories. On the death (deletions) side, the multi-stage bipartite alignment prevented 8,293,504 false deaths by resolving them as semantic migrations or modifications (logged in the line_evolution table), yielding a highly purified dataset of 11,009,579 actual line-level extinctions. 6.3 Baseline Survival (RQ1) Our baseline Kaplan–Meier estimator reveals a striking result: the survival curve never crosses the 50% threshold. The Kaplan–Meier median survival time is unbounded (∞), meaning that more than half of all code lines survive the entire observation period. Among lines that are actually deleted, the median time-to-deletion is 95.7 days. This heavy-tailed distribution is consistent with a “stabilize or die” pattern: lines that survive the initial refactoring phases have a high probability of long-term

11

persistence. The empirical threshold of this early-fragile period corresponds to the median lifespan of deleted lines — 95.7 days — so code surviving past ~100 days is already outlasting the typical deleted line. The unbounded KM median is, however, partly a consequence of the finite observation window (repositories span 6–163 months) and a 66.1% right-censoring rate: with a longer observation window, the survival function would eventually cross 50%. The 95.7-day threshold is therefore more meaningful than the unbounded median as a practical stability signal.

Figure 1: Baseline Kaplan–Meier survival curve for all source code lines (solid line; shaded band shows the 95% confidence interval). The survival function asymptotes above 0.50, so more than half of all lines are never deleted within the observation window and the Kaplan–Meier median survival time is unbounded. 6.4 Stratified Group Comparisons (RQ2, RQ3, RQ4) We conducted stratified log-rank tests to differentiate hazard dynamics across structural and temporal dimensions. All reported p-values are corrected using Benjamini–Hochberg FDR. For the RQ2–RQ4 stratified log-rank tests, 15 pairwise comparisons are performed (10 RQ2 AST-group pairs over the five mostpopulated AST groups, C(5,2), excluding the heterogeneous other group from the KM comparison; 3 RQ3 nesting-tier pairs; 2 RQ4 temporal comparisons); 13 of 15 survive correction at α = 0.05 (see §5.5 for the complete breakdown). • RQ2 (Syntax Role): Pairwise log-rank tests across the five mostpopulated AST groups confirm that syntactic role is strongly associated with survival: 9 of the 10 group pairs are significant after BH correction, the only exception being control_flow vs type_system (χ2 = 3.4, 12

p_adj = 0.072); the widest separation is expression vs import_export (χ2 = 1367, p_adj ≈ 10−298 ). For per-group effect sizes we report the multivariate Cox hazard ratios (full model in §6.5, Table 2), relative to the reference category (control flow); the five non-reference groups vary substantially in magnitude and several exhibit instability under sensitivity analysis: – Import/export statements (HR = 0.66, 95% CI [0.64, 0.68]): The strongest protective effect among AST groups. Import lines are structural scaffolding—rarely modified once established. However, this effect is unstable: in the nested-only submodel, the estimate becomes unreliable (HR = 0.23, 95% CI [0.01, 3.75], ns) because nested imports are rare, yielding very few observations in that stratum. – Declaration lines (HR = 0.86, 95% CI [0.83, 0.90]): A substantial protective effect, consistent with declarations (variable/function/class signatures) serving as anchor points. This effect is unstable in sensitivity analysis: it becomes non-significant in the single-repo model (HR = 0.97, ns), suggesting partial confounding with repositorylevel coding conventions. – Expression lines (HR = 1.28, 95% CI [1.24, 1.32]): The strongest risk factor in the model—the highest hazard among all covariates. Expression statements (function calls, assignments) are the “working” lines of code, subject to frequent modification as logic evolves. This effect is stable and consistent across all sensitivity models. – Other (HR = 1.20, 95% CI [1.17, 1.22]): A moderate risk factor. Miscellaneous AST nodes (JSX, template literals, etc.) are notably more volatile than the control-flow baseline. – Type system constructs (HR = 0.91, 95% CI [0.82, 1.00]): Relative to control flow, this effect is not significant (p = 0.06); against the structurally stable control-flow baseline, type annotations do not exhibit a distinguishable hazard. It is also directionally inconsistent under AFT and in the single-repo model. The reference category is control flow (if, switch, for, while, ternary constructs)—a well-populated, interpretable structural group. We do not use block-level tokens as the baseline: statement-block and class-body lines are almost entirely short structural delimiters ({, }) removed by the trivial-token filter (§5.1), so that group is effectively empty in the modelled data. The same control_flow reference is used in the R frailty model (Table 7), making the marginal and frailty AST hazard ratios directly comparable.

13

Figure 2: Kaplan–Meier survival curves stratified by AST group — declaration, control flow, expression, import/export, and type system (shaded bands are 95% confidence intervals). Expression lines show the steepest decline and the lowest survivorship, whereas import/export lines retain the highest survival, consistent with the hazard ratios in Table 2. • RQ3 (Structural Complexity): All three nesting-tier log-rank comparisons are significant after BH correction — flat vs. nested (χ2 = 2631), flat vs. deep (χ2 = 2295), and nested vs. deep (χ2 = 62, p_adj < 10−14 ) — confirming that flat lines (nesting = 0) survive markedly less than nested or deep lines. In the multivariate Cox model, deeper nesting modestly decreases hazard (HR = 0.97 per nesting level, 95% CI [0.96, 0.97]), and the direction is consistent across all sensitivity models (see §6.7). The novel structural context covariates provide additional granularity beyond nesting depth: – in_function (HR = 0.79, 95% CI [0.78, 0.80]): Lines inside function bodies exhibit a strong and stable protective effect, consistent across all sensitivity models (HR range: 0.79–0.92). This is among the strongest structural predictors in the model. – in_condition (HR = 1.12, 95% CI [1.11, 1.14]): Lines within conditional branches face elevated hazard, consistent across all models (see §6.7). – in_loop (HR = 0.96, 95% CI [0.92, 0.99], p = 0.012): Lines inside loop bodies show a modest protective effect in the aggregate model. 14

Note: this effect loses significance (p = 0.14) under within-commit clustered sandwich SE correction (§8.2) and disappears entirely after frailty conditioning (§6.10); it should be treated as a repository-level proxy rather than a genuine line-level predictor. – in_try_catch (HR = 1.07, 95% CI [1.03, 1.12], p < 0.005): Lines within error-handling blocks face modestly elevated hazard in the aggregate model, though this effect loses significance after frailty conditioning (§6.10).

Figure 3: Kaplan–Meier survival curves by nesting tier: flat (nesting = 0), nested (nesting > 0), and deep (nesting > 2). Flat lines die fastest, while nested and deep lines survive markedly longer and track each other closely. The protective effect of nesting is modest and partly repository-dependent (see §6.7 and §6.10). • RQ4 (Temporal Context): Nocturnal commits (22:00–05:00) are associated with elevated hazard in the aggregate model (HR = 1.16, 95% CI [1.14, 1.18], p < 0.005). Note: is_night loses statistical significance (p = 0.087) under within-commit clustered sandwich SE correction (§8.2) and loses significance in the single-repository sensitivity model (§6.7), indicating that this association is partially driven by between-repository confounding rather than genuine line-level risk. Weekend commits are not significant in the aggregate model (HR = 0.99, 95% CI [0.97, 1.01], p = 0.19) and remain ns in the no-ephemeral and stratified models, though they flip to a significant risk factor (HR = 1.09) in the single-repository model — a repository-level confound discussed in §6.7. The day-versus-night log-rank comparison is highly significant (χ2 = 702, p_adj ≈ 10−154 ), while the weekday-versus-weekend comparison is not significant (χ2 = 0.01, p_adj 15

= 0.92 after FDR correction). We emphasize that this is an association, not a causal claim. Nocturnal commits may correlate with urgency-driven fixes, experimental feature branches, or timezone artifacts.

Figure 4: Kaplan–Meier survival curves stratified by commit day type — weekday vs. weekend (shaded bands are 95% confidence intervals). The two curves nearly overlap, consistent with the non-significant weekend effect in the aggregate model (HR = 0.99). The day-vs-night contrast emphasized in the text is captured by the is_night covariate in the Cox models (Table 2), not by this plot. 6.5 Multivariate Cox Proportional Hazards Model (RQ5) The 15-covariate Cox PH model identifies line Shannon entropy as the dominant protective factor (HR = 0.56) and expression-type AST nodes as the strongest risk predictor (HR = 1.28), fitted on 300,000 lines with 101,773 deletion events (subsample drawn uniformly at random, random_state=42; full summary in Table 2). Covariate

HR

95% CI

Effect

Sig.

ast_group_expression ast_group_other is_night in_condition in_try_catch log_todo_distance is_weekend lidf

1.28 1.20 1.16 1.12 1.07 1.03 0.99 0.99

[1.24, 1.32] [1.17, 1.22] [1.14, 1.18] [1.11, 1.14] [1.03, 1.12] [1.02, 1.04] [0.97, 1.01] [0.99, 1.00]

↑risk 27.9% ↑risk 19.7% ↑risk 15.8% ↑risk 12.4% ↑risk 7.4% ↑risk 2.9% ↓risk 1.2% ↓risk 0.9%

*** *** *** *** ** *** ns ***

16

Covariate

HR

95% CI

Effect

Sig.

in_loop nesting_level ast_group_type_system ast_group_declaration in_function ast_group_import_export log_entropy

0.96 0.97 0.91 0.86 0.79 0.66 0.56

[0.92, 0.99] [0.96, 0.97] [0.82, 1.00] [0.83, 0.90] [0.78, 0.80] [0.64, 0.68] [0.54, 0.59]

↓risk 4.5% ↓risk 3.4% ↓risk 9.5% ↓risk 13.8% ↓risk 20.9% ↓risk 34.0% ↓risk 43.8%

* *** ns *** *** *** ***

Table 2: Cox PH results (main model, 15 covariates). *** denotes p < 0.001, ** denotes p < 0.01, * denotes p < 0.05, ns = not significant. Reference category: ast_group = control_flow (see §6.4). The ast_group_control_flow dummy is therefore absorbed into the baseline, and comment/shebang lines (comment_like) are excluded; the model has 15 covariates. Concordance (C-index) = 0.585. Most covariates are statistically significant in the main model (13 of 15; ast_group_type_system and is_weekend are not), but the model’s discriminative power is limited. A C-index of 0.585 falls between random (0.50) and practically useful (>0.65). The pattern reflects high population heterogeneity—structural features explain some variance in code lifespan but are far from deterministic. We caution that statistical significance should not be conflated with practical significance for covariates with HR close to 1.0, particularly lidf (HR = 0.99) and in_loop (HR = 0.96) — both lose significance under frailty conditioning (§6.10), indicating they are proxies for repository-level patterns rather than genuine line-level predictors. log_todo_distance (HR = 1.03), though modest, is confirmed as a genuine within-project effect in §6.10. is_weekend is not significant in the main model (HR = 0.99, p = 0.19) and consistently ns across all sensitivity models — it should not be treated as a reliable predictor.

17

Figure 5: Forest plot of log(HR) with 95% confidence intervals for all 15 covariates of the main Cox model (vertical dashed line marks the null at log(HR) = 0; markers to the right indicate elevated hazard, to the left reduced hazard). ast_group_expression is the strongest risk factor, while log_entropy and ast_group_import_export are the strongest protective factors. Key findings: 1. Expression-type lines are the dominant risk factor (HR = 1.28, ↑27.9%). Lines containing function calls and assignments are the most volatile AST group, with an effect that is stable across all sensitivity models. Nocturnal commits are also a significant risk factor (HR = 1.16, ↑15.8%), comparable in magnitude to ast_group_other (HR = 1.20). The is_night effect is consistent across main and no-ephemeral models but loses significance in the single-repo model (see §6.7). 2. Line entropy is the dominant protective factor. Lines with high line Shannon entropy (log_entropy; complex, information-dense constructs) are 43.8% less likely to die at any given time compared to low-entropy lines. This effect is robust across all sensitivity checks (see §6.7). 3. in_function shows a strong and stable protective effect (HR = 0.79, ↓20.9%), consistent across all sensitivity models. LIDF (Line Inverse Document Frequency) shows only a marginal protective effect (HR = 0.99, ↓0.9%), substantially weaker than previously estimated, suggesting that line-level uniqueness adds little predictive value beyond entropy. 4. log_todo_distance is a modest but significant risk factor (HR = 1.03, ↑2.9%): lines further from TODO comments face slightly higher hazard. This effect is confirmed as a genuine within-project signal under frailty conditioning (see §6.10), where it 18

remains significant in both marginal (HR = 1.033) and frailty (HR = 1.039) R models. 6.6 Change-Type Awareness (RQ6) The three-way change classification (migration, modification, true death) described in §5.2 prevents 8.3 million false deaths from inflating hazard estimates. KM curves stratified by first change type (Figure 6) confirm that migrations occur earliest, followed by modifications, while true hard-deletion events exhibit the heaviest right tail. Migrations and modifications are treated as right-censored in all multivariate models. A formal competing risks analysis (Fine–Gray subdistribution hazard) is deferred to future work; potential informative censoring from this treatment is discussed in §8.1.

Figure 6: Kaplan–Meier curves of time to first change, stratified by change type: hard deletion (true death), semantic rewrite (modification), and migration (relocation). The y-axis is the probability of not having yet undergone that change type. Migrations and modifications occur almost entirely within the first weeks, whereas hard deletions have a much heavier right tail. In the survival models only hard deletions count as events; migrations and modifications are right-censored. 6.7 Sensitivity Analysis 6.7.1 Cox Models on Data Subsets To evaluate the robustness of findings, we fit four additional Cox models on subsets of the data: 1. Nested-only (nesting > 0): 205,836 lines, 63,915 events. 2. Single repository (largest repo, repo_id = 490315865): 43,844 lines, 10,512 events. 3. No ephemeral 19

(duration > 1 day): 331,926 lines → subsampled to 300,000, 91,344 events. 4. Stratified sample (cap 10,000 lines per repository): 247,572 lines, 84,974 events. To address the sampling non-stratification concern (§8.2), we re-drew the sample with a per-repository cap using the same cityHash64 ordering for reproducibility, preventing large repositories (e.g., microsoft/vscode: ∼43K proportional share → capped at 10K) from disproportionately influencing aggregate estimates; 13 of 120 repositories were capped. Table 3 compares hazard ratios across models. We classify covariates as stable (consistent direction and significance across all models) or unstable (direction reversal or significance loss). Covariate

Main

Single

NoEphem

Stratified

Stability

log_entropy in_condition ast_group_ expression in_function nesting_level is_night

0.56*** 0.44*** 1.12*** 1.15*** 1.28*** 1.26***

0.39*** 1.10*** 1.32***

0.55*** 1.15*** 1.30***

0.56*** 1.17*** 1.26***

✓ Stable ✓ Stable ✓ Stable

0.79*** 0.84*** 0.97*** 0.98*** 1.16*** 1.11***

0.92*** 0.99** 1.03 ns

0.84*** 0.98*** 1.11***

0.79*** 0.96*** 1.09***

log_todo_distance

1.03*** 1.00 ns

0.98*

1.02***

1.02***

lidf

0.99*** 0.99 ns

0.99 ns

1.00 ns

0.99**

ast_group_import_ export

0.66*** 0.23 ns

0.63***

0.70***

0.67***

is_weekend

0.99 0.96*** ns 0.86*** 0.95*

1.09*

1.01 ns

1.01 ns

0.97 ns

0.91***

0.88***

✓ Stable ✓ Stable × Unstable (ns in single) × Unstable (reversal in single) × Unstable × Unstable (ns/wide CI nested) × Unstable × Unstable (ns in single)

ast_group_ declaration

Nested

Table 3: Sensitivity analysis (selected covariates — those with at least one noteworthy stability pattern). *** = p < 0.001, ** = p < 0.01, * = p < 0.05, ns = not significant. The four omitted covariates (ast_group_other, ast_group_type_system, in_try_catch, in_loop) are all stable in direction across the first three sensitivity models (nested, single, no-ephemeral) and are discussed individually in §6.5 and §6.10. Full per-covariate tables are available in the replication package. Stable covariates: log_entropy, in_condition, ast_group_expression, in_function, and nesting_level maintain consistent direction and significance across all five models. The stratified-sample model confirms stability for all five 20

covariates with HR estimates within 4% of main model values, indicating that the non-stratified hash sampling does not materially distort the primary findings. Notably, in_function is now among the stable predictors—a change from prior estimates—and nesting_level maintains a consistent modest protective direction throughout. Unstable covariates: is_night loses significance in the single-repository model (HR = 1.03, ns) but remains significant elsewhere, indicating residual repositorylevel confounding addressed by the frailty model (§6.10). log_todo_distance is inconsistent: significant and risk-increasing in the main and no-ephemeral models but slightly protective and significant in the single-repo model. lidf loses significance across three of five sensitivity checks. import_export is unreliable in the nested-only submodel due to the rarity of nested import statements. Simpson’s paradox: is_weekend is consistently not significant (main p = 0.19) but reverses direction to risk-increasing in the single-repo model, reflecting strong confounding by repository-specific commit timing patterns. In the stratified model, is_weekend shows a marginal direction flip (HR = 1.01 ns), which is not meaningful given non-significance in both the no-ephemeral and stratified models (consistently ns outside the single-repo stratum). The C-index decreases slightly in the single-repo model (C = 0.57 vs. 0.585 in main), consistent with the reduced variance available within a single project. 6.7.2 AFT Model Sensitivity Check To directly address the PH assumption violations identified in §6.8, we fitted two Accelerated Failure Time (AFT) models — Weibull AFT and Log-Logistic AFT — on the same 300,000-row sample (ridge penalizer λ = 0.1). AFT models make no proportional hazards assumption: instead of modeling the hazard, they model the logarithm of survival time as a linear function of covariates. Table 4 reports the resulting time ratios alongside the Cox hazard ratios, and Table 5 summarizes model fit. Interpretation note: In Cox PH, HR < 1 indicates reduced hazard (longer survival). In AFT, TR > 1 indicates longer survival. The scales are inverted — a directionally consistent result means HR < 1 and TR > 1, or HR > 1 and TR < 1. Covariate

Cox HR

Weibull TR

Log-Logistic TR

Consistent?

Nesting level

0.966 [0.963, 0.970]*** 0.955 [0.921, 0.990]* 1.124 [1.105, 1.144]*** 1.074 [1.029, 1.121]** 0.791 [0.780, 0.801]*** 0.991 [0.986, 0.996]***

1.048 [1.044, 1.053]*** 1.103 [1.043, 1.167]*** 0.928 [0.904, 0.954]*** 0.953 [0.890, 1.020]ns 1.323 [1.298, 1.347]*** 1.034 [1.026, 1.042]***

1.050 [1.045, 1.055]*** 1.096 [1.034, 1.162]** 0.953 [0.927, 0.979]*** 0.971 [0.906, 1.042]ns 1.326 [1.301, 1.352]*** 1.032 [1.023, 1.040]***

In loop In condition In try/catch In function LIDF (uniqueness)

21

✓ ✓ ✓ ✓ ✓

Covariate

Cox HR

Weibull TR

Log-Logistic TR

Consistent?

Log entropy

0.562 [0.536, 0.588]*** 1.029 [1.023, 1.035]*** 0.988 [0.970, 1.006]ns 1.158 [1.140, 1.176]*** 0.862 [0.828, 0.898]*** 1.279 [1.239, 1.319]*** 0.660 [0.641, 0.678]*** 1.197 [1.173, 1.221]*** 0.905 [0.817, 1.004]ns

2.219 [2.070, 2.380]*** 0.958 [0.949, 0.967]*** 1.018 [0.987, 1.049]ns 0.829 [0.807, 0.851]*** 1.287 [1.212, 1.366]*** 0.800 [0.764, 0.838]*** 1.597 [1.540, 1.657]*** 0.789 [0.769, 0.809]*** 1.091 [0.927, 1.283]ns

1.983 [1.845, 2.132]*** 0.966 [0.957, 0.976]*** 0.990 [0.960, 1.022]ns 0.812 [0.789, 0.835]*** 1.280 [1.203, 1.362]*** 0.820 [0.781, 0.860]*** 1.590 [1.531, 1.651]*** 0.785 [0.764, 0.805]*** 1.095 [0.926, 1.296]ns

Log TODO distance Weekend commit Night commit AST: declaration AST: expression AST: import/export AST: other AST: type system

✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓

Table 4: Cox HR vs AFT Time Ratios (n = 300,000; ridge penalizer λ = 0.1; AST reference = control_flow). *** p < 0.001, ** p < 0.01, * p < 0.05, ns = not significant. Consistent: HR and TR agree on survival direction (HR < 1 ↔ TR > 1). in_try_catch is directionally consistent but loses significance in both AFT models; ast_group_type_system is non-significant against the control-flow baseline in the Cox model and in both AFT models. Model

AIC

C-index

Weibull AFT Log-Logistic AFT

1,569,731 1,565,700

0.583 0.583

Table 5: AFT model fit. Log-Logistic AFT achieves lower AIC. C-index is comparable to the marginal Cox (0.585). BIC values are omitted: the lifelines library reports BIC < AIC for both models (a known issue with BIC computation for parametric AFT), making them unreliable for comparison.

22

Figure 7: Forest plot comparing Cox hazard ratios (circles) with Weibull AFT (squares) and Log-Logistic AFT (triangles) time ratios, with 95% confidence intervals, across all 15 covariates (vertical dashed line at 1.0). Note the inverted scale between the two model families: a Cox HR < 1 and an AFT TR > 1 both indicate longer survival. Result: All 15 of 15 covariates are directionally consistent between Cox PH and both AFT models. Notably, log_todo_distance (Cox HR = 1.029, riskincreasing) is confirmed as a risk factor in both AFT models (Weibull TR = 0.958, Log-Logistic TR = 0.966, both p < 0.001), confirming it as a consistent risk factor. in_try_catch and ast_group_type_system are directionally consistent but lose statistical significance under AFT (and ast_group_type_system is already non-significant against the control-flow baseline in the Cox model), suggesting weaker effects that may be sensitive to distributional assumptions. The Cox PH conclusions are robust to distributional assumptions despite pervasive PH violations. 6.8 Proportional Hazards Diagnostics Eleven of 15 covariates violate the proportional hazards assumption in the main model (Schoenfeld residual test, p < 0.05), confirming that most reported hazard ratios are time-averaged effects — a limitation resolved mechanistically via landmark analysis in §6.9. Model

Covariates Violating PH (p < 0.05)

Main

11 / 15 (73%)

23

Model

Covariates Violating PH (p < 0.05)

Nested-only Single repo No ephemeral

10 / 15 6 / 15 9 / 15

In the main model, the most severe violations occur for log_entropy (χ2 = 474, p ≈ 10−105 ), nesting_level (χ2 = 159, p ≈ 10−36 ), is_night (χ2 = 130, p ≈ 10−30 ), and in_function (χ2 = 118, p ≈ 10−27 ). The four covariates that do not violate PH are ast_group_other (p = 0.29), ast_group_type_system (p = 0.93), in_try_catch (p = 0.90), and lidf (p = 0.95). Note that ast_group_expression now exhibits a mild violation (χ2 = 7.4, p = 0.006) under the control-flow reference — far weaker than the dominant entropy and nesting violations. This indicates that most hazard ratios are not constant over time—they represent time-averaged effects that may overstate or understate the true impact at specific periods in a line’s lifecycle. We interpret Cox results as average effects over the observation period. As a direct sensitivity check, we fit Weibull AFT and Log-Logistic AFT models on the same sample (§6.7.2); their conclusions are directionally consistent with Cox for all 15 of 15 covariates, confirming that PH violation does not materially distort the reported findings. The mechanisms of the two dominant PH violations are resolved in §6.9 via time-stratified analysis. 6.9 Time-Varying Effects: Landmark Time-Stratified Cox To provide a mechanistic explanation for the PH violations identified in §6.8 (Proportional Hazards Diagnostics), we fitted separate Cox models on three landmark time bands: 0–90 days (N = 349,510, 58,172 events), 90–365 days (N = 260,725, 29,904 events), and 365+ days (N = 180,751, 30,408 events). Unlike the main Cox model (§6.5, n = 300,000 subsample), these landmark models use the full 349,510-line sample (350,000 minus comment_like lines); HR estimates are therefore not directly numerically comparable to Table 2. Each band uses all lines still at risk at the band’s start, with the time origin shifted to the band boundary and the event indicator re-censored at the band end. Table 6 reports the per-band hazard ratios for the seven covariates with the strongest time dynamics. Covariate

HR 0–90d

log_entropy

0.843***

ast_group_ expression in_function

1.161***

in_condition

0.977*

0.800***

HR 90–365d

95% CI [0.800, 0.889] [1.120, 1.203] [0.788, 0.811] [0.957, 0.997]

0.583*** 1.200*** 0.911*** 1.207***

24

95% CI [0.545, 0.624] [1.148, 1.253] [0.895, 0.928] [1.178, 1.237]

HR 365+d 0.359*** 1.215*** 0.826*** 1.119***

95% CI [0.333, 0.387] [1.157, 1.275] [0.810, 0.843] [1.089, 1.149]

Covariate

HR 0–90d

is_night

1.247***

nesting_level

0.958***

lidf

0.996 ns

HR 90–365d

95% CI [1.224, 1.271] [0.954, 0.962] [0.990, 1.002]

1.013 ns 0.990*** 0.989**

95% CI [0.987, 1.040] [0.985, 0.994] [0.982, 0.997]

HR 365+d 1.085*** 0.984*** 0.973***

95% CI [1.056, 1.114] [0.979, 0.989] [0.965, 0.981]

Table 6: Time-stratified Cox — HR by landmark band (ridge λ = 0.1). *** p < 0.001, ** p < 0.01, * p < 0.05, ns = not significant.

Figure 8: Hazard ratios (with 95% confidence intervals) for seven key covariates across the three landmark time bands — 0–90 days (circles), 90–365 days (squares), and 365+ days (triangles); the vertical dashed line marks HR = 1. log_entropy becomes progressively more protective as code ages, while in_condition reverses from mildly protective to risk-increasing after 90 days. Key findings: 1. log_entropy — strengthening protective effect. The HR decreases from 0.843 in the early period to 0.359 for code that has survived 365+ days (≈16% → 64% hazard reduction at the same entropy level). This monotonic trend is the primary driver of the Schoenfeld violation for entropy (χ2 = 474 in §6.8): entropy is not proportionally protective — it becomes increasingly so as code matures. Interpretation: high-entropy 25

lines that survive the early fragile period are structurally entrenched; they resist change precisely because their information density makes them hard to replace. 2. in_condition — direction reversal. In the 0–90-day band this covariate is mildly protective (HR = 0.977), but it reverses to a risk factor in both the 90–365-day (HR = 1.207) and 365+day (HR = 1.119) bands. The early apparent protection may reflect the short observation window of freshly born conditional blocks; once these survive past 90 days, they enter featurecritical paths where they accumulate complexity and become refactoring targets. This time-reversal explains the PH violation for in_condition. 3. ast_group_expression — near-time-invariant risk. HRs across the three bands are 1.161, 1.200, and 1.215 — a mild monotonic increase, all p < 0.001. Expression-type lines carry a roughly 16–22% hazard increase that strengthens only slightly with age. The corresponding Schoenfeld violation is weak (χ2 = 7.4, p = 0.006 in §6.8) — orders of magnitude smaller than entropy or in_condition — so expression is best read as an approximately time-stable risk factor. 4. is_night — early-period phenomenon. The night-commit risk is concentrated in the 0–90-day band (HR = 1.247) and becomes non-significant in the 90–365-day band (HR = 1.013, p = 0.330). For lines that survive past one year, a modest effect resurfaces (HR = 1.085). This pattern indicates that hastily committed code is most likely to be revised quickly, but survivors are largely similar to daytime code. These time-resolved estimates provide a mechanistic interpretation of the Schoenfeld violations and sharpen the §7 practical implications: risk scoring should apply a time-conditional entropy adjustment — new code with high entropy carries moderate protection (HR = 0.843), but the same code surviving 365 days is extremely unlikely to be removed (HR = 0.359). This three-regime structure (< 90d, 90–365d, 365+d) is the primary empirical contribution of the time-stratified analysis. 6.10 Shared Frailty Model: Repository Random Effects Motivation. Two findings from the preceding analysis motivate a repositorylevel frailty model: (1) the marginal C-index of 0.586 (R coxph, n = 346,808 — the base for the frailty comparison; consistent with the Python lifelines estimate of 0.585 reported in §6.5) is low, suggesting substantial unexplained heterogeneity; and (2) is_night (HR = 1.158 in the Python marginal model, §6.5, vs. HR = 1.028 ns single-repo), is_weekend, and in_try_catch lose significance or shift when conditioning on a single project (§6.7). Both phenomena are consistent with strong between-repository confounding: each project carries its own baseline hazard that, if unmodeled, distorts aggregate covariate estimates. Model specification. We fit a shared gamma frailty Cox model with all 15

26

fixed-effect covariates and a latent multiplicative cluster effect per repository: hi (t | Zi ) = Zi · h0 (t) · exp(xi⊤ β) where Zi ∼ Gamma(1/θ, 1/θ) is the frailty term for repository i, with E[Zi ] = 1 and Var[Zi ] = θ. Estimation uses the EM algorithm with Breslow baseline hazard (R survival package, coxph with frailty(repo_id, distribution="gamma")). Repositories with fewer than 30 events are excluded from the frailty clustering, and comment/shebang lines (comment_like) are dropped (§6.4). The final sample comprises n = 346,808 observations, 118,138 events. Frailty variance. The estimated frailty variance θ̂ = 1.449 (frailty term LRT: χ2 = 36,280, df = 84.64, p ≈ 0) confirms that repositories are highly heterogeneous in their baseline hazard. A θ̂ substantially greater than zero indicates that between-repository variation is a dominant driver of observed survival differences, validating the concerns raised under Simpson’s paradox (§6.7) and Internal Validity (§8.2). Discriminative power. The concordance index improves from 0.586 (marginal Cox) to 0.666 (frailty model), a gain of +0.080. This C-index is estimated with known frailty values; for truly out-of-sample repositories, the effective concordance would be lower. Covariate comparison. Table 7 presents hazard ratios from both R models. Both R models use the same ast_group = control_flow reference as Table 2 (§6.4), so the AST hazard ratios in Table 7 are directly comparable to the main Cox model. All within-table (marginal vs frailty) comparisons are likewise valid. Coefficient scale difference. The primary source of HR discrepancy between Table 2 (Python lifelines) and Table 7 (R) is the L2 ridge penalty applied only in the Python model (λ = 0.1), which shrinks coefficients toward zero (e.g., log_entropy: Python HR = 0.562 vs R HR = 0.493). Both R models are unpenalized, so the ∆ HR column in Table 7 reflects genuine frailty conditioning rather than a regularization artifact. Covariate

Marginal HR [95% CI]

Frailty HR [95% CI]

∆ HR

Note

is_night

1.186 [1.167, 1.206]***

−5.8%

in_condition in_try_catch

1.205 [1.182, 1.229]*** 1.141 [1.090, 1.195]***

ast_group: expression ast_group: other nesting_level in_loop

1.461 [1.395, 1.530]***

1.117 [1.098, 1.137]* 1.143 [1.119, 1.167]*** 1.038 [0.991, 1.087] ns 1.361 [1.299, 1.426]***

Simpson’s ↓ attenuated repo proxy attenuated

1.273 [1.225, 1.323]*** 0.964 [0.959, 0.968]*** 0.947 [0.910, 0.985]**

27

1.203 [1.158, 1.251]*** 0.967 [0.962, 0.971]*** 1.022 [0.982, 1.063] ns

−5.1% LOST −6.8% −5.5% +0.3% LOST

attenuated stable repo proxy

Covariate

Marginal HR [95% CI]

Frailty HR [95% CI]

∆ HR

Note

in_function log_entropy

0.723 [0.711, 0.735]*** 0.493 [0.467, 0.519]***

+9.5% −7.1%

weaker stronger

log_todo_distance

1.034 [1.027, 1.040]***

lidf

0.999 [0.993, 1.004] ns

is_weekend

0.996 [0.977, 1.016] ns

0.792 [0.778, 0.806]*** 0.458 [0.434, 0.483]* 1.039 [1.033, 1.046]* 1.016 [1.010, 1.023]* 0.985 [0.965, 1.005] ns

ast_group: declaration ast_group: import_export ast_group: type_system

0.871 [0.824, 0.922]***

0.872 [0.824, 0.923]***

+0.1%

both ns stable

0.570 [0.544, 0.599]***

0.556 [0.529, 0.583]***

−2.5%

stronger

0.875 [0.777, 0.986]*

0.932 [0.827, 1.050] ns

LOST

weaker

MAINTAINED remains sig. ns→risk FLIP —

Table 7: Marginal Cox vs. Shared Frailty Cox hazard ratios (R, unpenalized). Reference: ast_group = control_flow (same as Table 2). *** p < 0.001, ** p < 0.01, * p < 0.05, ns = not significant. LOST = significance lost after conditioning; FLIP = sign change from ns to significant; MAINTAINED = remains significant in both models.

28

Figure 9: Forest plot of hazard ratios (95% confidence intervals, log-scaled x-axis) for all 15 covariates under four model variants: the Python marginal Cox (marginal), the R marginal Cox (marginal_R), the R marginal Cox with withincommit clustered sandwich standard errors (clustered_R), and the shared gamma frailty Cox (frailty). The inset reports the frailty variance (θ = 1.449) and the concordance gain from 0.586 (marginal) to 0.666 (frailty). Risk-side AST groups and is_night attenuate toward the null under frailty conditioning, while in_try_catch and in_loop lose significance entirely. Key findings from frailty conditioning: 1. is_night — partial resolution of Simpson’s paradox. The nocturnal commit effect is attenuated from HR = 1.186 to HR = 1.117 (−5.8%) after conditioning on repository-level baseline hazard. The effect remains significant, confirming a genuine within-project association; the aggregate marginal estimate was partially inflated by between-repository confounding. 2. in_try_catch and in_loop — confirmed repository proxies. Both lose significance entirely under frailty conditioning (in_try_catch: HR = 1.038, ns; in_loop: HR = 1.022, ns). Their marginal effects reflected between-repository variation in coding style, not genuine line-level risk. They should not be used as individual line-level predictors. 29

3. log_todo_distance — maintained significance. Significant in both marginal (HR = 1.034) and frailty (HR = 1.039) models — a genuine within-project effect independent of repository-level culture. 4. log_entropy strengthens. HR 0.493 → 0.458 under frailty conditioning, confirming it as the most robust within-project protective predictor. lidf (HR = 0.999 ns → 1.016 significant) shows a small sign change after conditioning that is likely a large-sample artifact; the effect size is negligible. 5. AST risk groups attenuate; protective groups hold. Relative to the control-flow baseline, the risk-side groups move toward the null under frailty conditioning — expression (1.461 → 1.361) and other (1.273 → 1.203) — indicating part of their aggregate effect reflects repository composition. The protective groups are stable (declaration 0.871 → 0.872) or marginally stronger (import_export 0.570 → 0.556), while type_system loses significance (0.875* → 0.932 ns). Summary. The shared frailty model confirms that repository-level heterogeneity (θ̂ = 1.449) is a dominant source of variance in code survival. The conditional hazard ratios — particularly for log_entropy (HR = 0.458), is_night (HR = 1.117), and in_function (HR = 0.792) — represent more reliable within-project effect estimates than their marginal counterparts.

7. Practical Implications and Discussion The empirical findings of CLSA carry concrete implications for software engineering practice, tool development, and future research. We organize them around three themes. 7.1 IDE Risk Scoring The strongest and most stable predictors identified in our study — log_entropy (HR = 0.458, frailty model), ast_group_expression (HR = 1.28, main Cox model), in_function (HR = 0.792, frailty model), and in_condition (HR = 1.143, frailty model) — are all derivable statically from a single source file — ast_group_expression, in_function, and in_condition directly from the AST, and log_entropy from the line’s character composition — without any git history. This has an important practical consequence: these features can be computed at edit time in an IDE, enabling live survival scoring for code being written. Concretely, an IDE plugin could use tree-sitter to extract structural features for each code block and pass them to a survival model trained on our dataset, displaying an inline risk indicator. For existing lines with known age from git blame, conditional survival S(t | age=T) = S(t+T)/S(T) could adjust the estimate upward for code that has already survived past the early fragile period

30

(the ~95.7-day median lifespan of deleted lines identified in §6.3). We leave the implementation and empirical evaluation of such a tool to future work. Such a tool operationalizes the “stabilize or die” pattern: it gives developers an actionable risk signal at the moment when it is cheapest to act — before the code is committed and reviewed. 7.2 Repository-Aware Baseline Calibration The dominant predictive signal in our analysis is not any structural covariate but the repository frailty term (θ̂ = 1.449), which accounts for the C-index lift from 0.586 to 0.666. Any practical risk tool that ignores repository context will be systematically mis-calibrated: high-turnover projects like tamagui/tamagui (61% of mined lines permanently deleted; 71% among lines with a resolved outcome) will appear safer than they are when evaluated against a populationaverage baseline. A lightweight calibration approach may be feasible without re-training the model: a cheap repository-level deletion-rate statistic — for example, the share of recently changed lines that are deletions, obtainable from a shallow git log scan — could serve as a proxy for the project’s frailty level and be used to scale the model’s baseline cumulative hazard H0 (t) before computing survival probabilities, preserving the universally-trained structural coefficients while adapting the absolute risk level to the current project. We have not validated this proxy against the estimated frailty terms; such a calibration study is left to future work. 7.3 Code Review and CI/CD Integration In continuous integration workflows, reviewers face a triage problem: which changed lines deserve the most scrutiny? Our model provides a direct answer. Lines with high predicted hazard — expression-type AST nodes, low entropy, and in_condition context — are statistically more likely to be refactored within the next quarter. An automated pull-request annotator could flag such lines for focused review, reducing the cognitive load on human reviewers who currently must apply this judgment heuristically. This framing is distinct from defect prediction (which requires historical bug data): survival scoring requires only static features of the code being submitted, making it applicable to any new codebase without a pre-existing fault history.

8. Threats to Validity 8.1 Construct Validity • Semantic equivalence: Our 5-stage matching pipeline uses composite textual similarity (Sørensen–Dice + Ratcliff/Obershelp, threshold ≥ 0.6) 31

constrained by AST node type agreement (relaxed to ≥ 0.9 in Stage 5) to approximate semantic equivalence. This is a necessary heuristic: a line classified as “migrated” may represent a semantically distinct construct that happens to share textual similarity, while a genuinely new line may coincidentally match a deleted line’s normalized form, producing a false negative in death detection. Threshold sensitivity. To quantify the effect of the 0.6 choice, we re-ran the full matching pipeline (stages 1–5) on three held-out repositories (markedjs/marked, piotrwitek/react-reduxtypescript-guide, unform/unform; 275 commits total) at T = 0.50, 0.60, and 0.70. Results are shown in Table 8. Repository

T = 0.50 deaths

T = 0.60 deaths

T = 0.70 deaths

440 391 1,283

480 458 1,362

537 535 1,442

markedjs/marked piotrwitek/react-redux-typescript-guide unform/unform

Table 8. Death event counts under three similarity thresholds. Rows are held-out repositories not used in main model fitting. Lowering the threshold to 0.50 reduces death counts by 6–15% (avg. −9.6%) relative to T = 0.60; raising it to 0.70 increases death counts by 6–17% (avg. +11.5%). Manual inspection of the 30 borderline pairs (0.55 ≤ sim ≤ 0.70) that flip classification between thresholds confirms that the T = 0.60 boundary is well-placed: pairs promoted to “modification” only at T = 0.50 are semantically distinct (e.g., import { defineConfig } from 'tsup' matched against import type { ResultCallback } from './Instance.ts', sim = 0.58), while pairs reclassified as “death” only at T = 0.70 share clear semantic intent (e.g., let ret = hooksFunc.apply(hooks, args) vs. let ret = pack.renderer![prop].apply(renderer, args), sim = 0.67). The ±10% swing in death event volume, on a full-population sample of 350,000 lines, would produce at most a sub-percent change in Cox hazard ratios through pure dilution of the event pool; directional conclusions are therefore robust to this threshold choice. • Death vs. refactoring: Despite the multi-stage matching pipeline, some genuine line evolutions may be misclassified as deaths (or vice versa). Our manual validation of 200 stratified lines (§8.1) provides empirical evidence of pipeline reliability (precision = 1.000, F1 = 0.870). • Line as unit of analysis: We treat individual lines as independent subjects, but lines within the same function or file are not statistically independent. Block-level deletions (e.g., removing an entire function) cause correlated deaths that violate the independence assumption. Frailty models or clustered survival approaches could address this. • Censoring mechanism: We use the repository’s last commit date as the censoring time. For lines born near the end of the observation window, 32

this produces short follow-up times that may systematically differ from lines with longer observation periods (informative censoring). We partially address this by excluding ephemeral lines (<1 day) in sensitivity analysis. • Informative censoring from modification and migration: Lines classified as modifications (similarity ≥ 0.6) or migrations are right-censored at the moment of their transformation rather than at the repository’s last commit. Standard survival analysis requires that censoring be noninformative (independent of the hazard of the true event). However, if modified or migrated lines systematically differ in their structural characteristics from lines that undergo true deletion — which is likely, since high-entropy, deeply-nested lines may be more prone to in-place modification than outright removal — then this censoring is informative. Table 1 shows that the migration/modification gap (Lines Mined − Deaths − Survived) reaches 28.7% for microsoft/vscode and is non-trivial across most large repositories. Quantifying the direction and magnitude of this bias would require a formal competing risks analysis (Fine–Gray model), which is deferred to future work. • Structural context extraction: The four binary structural context features (in_loop, in_condition, in_try_catch, in_function) are derived from tree-sitter’s parent-chain traversal. In languages with complex scoping (e.g., nested arrow functions inside conditionals), these features may not perfectly capture the programmer’s intended structural context. • Robustness of Survival Constructs (Manual Validation): To evaluate construct validity, we manually inspected a stratified random sample of 200 lines: 70 hard_delete deaths, 30 file_delete deaths, and 100 censored (surviving) lines. For each line, one author inspected the corresponding GitHub commit diff and recorded a ground-truth verdict (TP/FP/TN/FN).

Human: dead Human: alive

Pipeline: DEAD

Pipeline: ALIVE

TP = 100 FP = 0

FN = 30 TN = 70

Metric

Value

Precision Recall F1 Accuracy Oracle agreement

1.000 0.769 0.870 0.850 0.700

The pipeline achieves precision of 1.000 (0 false positives among 100 predicted deaths) and recall of 0.769 (F1 = 0.870, accuracy = 0.850). We additionally report an oracle-agreement rate of 0.700, computed as the 33

fraction of the 100 censored (pipeline-alive) observations for which the pipeline verdict matches the human verdict (TN / total_censored = 70/100 = 0.700). Note: the overall accuracy across all 200 lines is (TP + TN)/200 = 170/200 = 0.850, reported separately in the Accuracy row above. Cohen’s κ in its canonical form requires two independent human raters and does not apply here since a single author performed all annotations. All 30 false negatives originate from the censored stratum. Inspection of annotator notes reveals the following breakdown: 14 cases where the tracked file no longer exists at HEAD, 6 cases where the file exists but the specific line content was absent, 5 cases where the string content could not be matched, 2 cases of missing parent directories, and 2 cases of explicit file renames not propagated into file_state; one case lacked annotator notes. In total, 18 of 30 FN cases are attributable to the tracked path (file or directory) no longer existing at HEAD — predominantly because Git’s rename heuristic failed to detect directory-level restructuring, leaving lines alive in file_state under a stale path. These findings are consistent with the matching pipeline design (§5.2) and motivated the cross-file structural matching (Stage 4) added to mitigate this class of errors. The zero falsepositive rate confirms that the pipeline’s conservative design — preferring to leave a line alive when a plausible match exists — does not produce spurious deaths. Bias direction from recall = 0.769. The 30.0% false-negative rate among censored observations implies a systematic upward bias in the Kaplan–Meier survival estimate: lines that are truly dead but recorded as censored inflate the apparent survivorship at every time point. The consequence for Cox hazard ratios is an attenuation toward HR = 1.0 — covariates associated with higher deletion risk will appear weaker than their true effect, because a fraction of their “events” are absorbed into the censored pool. The five most robust covariates in Table 3 (log_entropy, in_condition, ast_group_expression, in_function, nesting_level) are therefore conservative estimates; the true hazard ratios for these features are likely further from 1.0 than reported. 8.2 Internal Validity • Within-commit correlation. Lines removed in the same commit (e.g., bulk function deletion) share a death event, violating the Cox independence assumption. We addressed this by fitting a marginal Cox model with clustered sandwich standard errors by commit_id (107,920 unique commits; R coxph with cluster(commit_id)). CI widening is substantial — 10.0× for log_entropy, 9.26× for in_condition, 8.33× for in_function, and 4.14× for nesting_level — reflecting high within-commit correlation. Nonetheless, all five stable predictors remain statistically significant under sandwich SE (log_entropy p = 0.006, in_condition p = 0.041, in_function p 34

< 0.001, nesting_level p < 0.001, ast_group_expression p < 0.001). is_night (p = 0.088) and in_loop (p = 0.14) lose significance under clustering and should be considered unreliable for within-commit inference. Directional conclusions for the main predictors are robust to this correction. • Proportional Hazards assumption violation: 11 of 15 covariates violate the PH assumption in the main model (Schoenfeld test). The reported hazard ratios represent time-averaged effects. The most severe violations occur for log_entropy (χ2 = 474) and nesting_level (χ2 = 159). We address this via AFT sensitivity analysis (§6.7.2) — all 15 covariates are directionally consistent with Cox PH — and via landmark time-stratified Cox analysis (§6.9), which reveals the mechanistic trajectories of the two dominant violations: log_entropy (HR 0.843 → 0.583 → 0.359 across 0– 90/90–365/365+ day bands) and in_condition (direction reversal: 0.977 → 1.207 → 1.119). • Simpson’s paradox: Several covariates lose significance or shift direction in sensitivity analysis, indicating repository-level confounding. We address this in §6.10 via a shared gamma frailty Cox model (θ̂ = 1.449, LRT χ2 = 36,280, p ≈ 0). in_try_catch and in_loop lose significance entirely under frailty conditioning and are confirmed as proxies for repository-level patterns rather than genuine line-level predictors. • C-index and practical significance: The limited discriminative power (C = 0.585) indicates that structural features alone are insufficient to predict code survival. The frailty model C-index (0.666) confirms that repository-level information is the dominant predictive signal. All reported covariates with HR close to 1.0 (e.g., lidf, in_try_catch) should be interpreted with caution. • Temporal confounding: The is_night and is_weekend covariates are derived from commit timestamps. In cases involving cloud IDEs, remote servers, or misconfigured clocks, the timestamp may not reflect the committer’s actual timezone. We treat this as non-systematic noise. • Sampling strategy: Our deterministic hash-based sampling (ORDER BY cityHash64(id) LIMIT N) produces a reproducible simple random sample but does not stratify by repository. Large projects (vscode: 4M lines) are proportionally overrepresented in the 350K sample, potentially amplifying repository-level confounding already noted under Simpson’s paradox. We address this directly in §6.7 via a stratified sensitivity model (cap 10,000 lines per repository, N = 247,572), which confirms that all five primary findings are robust to this sampling choice (HR estimates within 4% of main model values). 8.3 External Validity • Language scope: Results are constrained to TypeScript, a dynamicallytyped language with rapid ecosystem evolution. Strongly-typed, compiled languages (C++, Rust, Java) with stricter type systems and longer release cycles may exhibit fundamentally different survival dynamics. The non35

significance of type_system AST nodes in the expanded model may be specific to TypeScript’s gradual typing paradigm. • Repository selection bias: We exclusively mined active open-source repositories from GitHub. Dead or archived repositories, private/corporate codebases, and projects hosted on other platforms (GitLab, Bitbucket) are not represented. The survival characteristics of code in corporate monorepos with structured code review processes may differ significantly. • Temporal scope: Our repositories span 6 to 163 months of history. The TypeScript ecosystem evolved substantially over this period (e.g., introduction of strict mode, template literal types, satisfies operator). Cohort effects—where lines born in different eras face different hazard environments—are not explicitly modeled. Furthermore, the observation window heterogeneity creates a truncation bias: lines in 6-month-old repositories cannot exhibit survival durations beyond 6 months, making their censoring rate structurally higher than in mature repositories. This systematically inflates the apparent survivorship contributed by short-lived repositories. Future analyses should apply a minimum repository age filter (e.g., ≥ 24 months) and verify that key findings hold within that restricted cohort. • Project domain: Our repository selection spans diverse domains but is biased toward web development and tooling (the natural habitat of TypeScript). Results may not generalize to other software domains. 8.4 Statistical Validity • Multiple testing: Benjamini–Hochberg FDR correction is applied to all reported log-rank p-values. We distinguish raw from adjusted significance throughout. Cox model p-values are reported as-is from the partial likelihood ratio test. Two comparisons (control_flow vs type_system, weekday vs weekend) lose significance after FDR correction. • Large-sample significance: With 300,000+ observations, even trivially small effects achieve statistical significance. We report effect sizes (HR) and confidence intervals alongside p-values, and explicitly note covariates with HR close to 1.0 (e.g., in_loop HR = 0.96, lidf HR = 0.99, is_weekend HR = 0.99) as statistically negligible. • L2 regularization: We apply an L2 penalty (0.1) to the Cox model to prevent overfitting. While this shrinks coefficients toward zero and may attenuate true effects, it guards against spurious associations in highdimensional settings. The penalty was not tuned via cross-validation. • Borderline covariates: 13 of the 15 covariates are statistically significant (p < 0.05) in the main model; ast_group_type_system (p = 0.06, against the control-flow baseline) and is_weekend (p = 0.19) are not. Of the significant ones, in_loop (p = 0.012) would not survive Bonferroni correction for 15 comparisons (α/15 ≈ 0.003) and should be treated as borderline; it also loses significance under both clustered SE and frailty conditioning. 36

8.5 Reproducibility • All analysis scripts, database schemas (ClickHouse DDL), and raw output files are included in the supplementary material. The sampling strategy uses deterministic hashes, ensuring exact reproducibility given the same database state. The Git mining pipeline (PyDriller + tree-sitter) is deterministic given fixed repository snapshots. We provide SHA hashes for all repository snapshots used.

9. Conclusion In the present work, we establish that survival analysis provides a statistically coherent and empirically productive framework for modeling the persistence of individual source code lines. Our primary findings, ordered by novelty and practical significance, are: 1. Code survival follows a time-varying three-regime structure: Landmark time-stratified Cox analysis (§6.9) reveals that covariate effects are not merely time-varying but organize into three interpretable regimes (< 90d, 90–365d, 365+d). Line Shannon entropy is the most striking example: moderately protective for new code (HR = 0.843, 0–90d), strongly protective for established code (HR = 0.583, 90–365d), and extremely protective for mature code (HR = 0.359, 365+d). in_condition reverses direction: mildly protective early (HR = 0.977), a risk factor thereafter (HR = 1.207 at 90–365d). This three-regime structure is not a diagnostic artifact — it is the mechanism behind PH violations and the empirical basis for time-conditional risk scoring. 2. Repository heterogeneity is the dominant predictive signal: The shared gamma frailty model (§6.10) estimates θ̂ = 1.449 (LRT χ2 = 36,280, p ≈ 0), confirming that between-repository variation dominates crossproject survival differences. C-index improves from 0.586 (marginal Cox) to 0.666 (frailty). Any risk model that ignores project-level context will be systematically mis-calibrated. Frailty-conditional hazard ratios should be preferred for within-project applications. 3. Line entropy is the most robust individual predictor: High-entropy lines (complex, information-dense constructs) show a 43.8% hazard reduction (HR = 0.56, marginal model), stable across all sensitivity checks, all three time bands, and both AFT models. High-entropy lines that survive the initial 95.7-day fragile period become structurally entrenched and are extremely unlikely to be removed. 4. Structural context features are stable and actionable: in_function is a strong, time-stable protective predictor (HR = 0.723–0.792 across marginal and frailty models). ast_group_expression is the most stable risk factor (HR = 1.161–1.215 across all three time bands). Both are 37

computable statically from the AST without git history, enabling realtime structural risk scoring. By contrast, in_try_catch and in_loop are confirmed as repository-level proxies with no genuine line-level predictive value after frailty conditioning. 5. The 5-stage pipeline is a prerequisite, not a preprocessing detail: The bipartite matching pipeline prevented 8.3 million false deaths — 43% of all pipeline-processed deletion events (8.3M false + 11.0M confirmed = 19.3M total observed by the pipeline) — in the full population. Without it, aggregate hazard estimates would be severely inflated and covariate effects distorted. The pipeline’s conservative design (precision = 1.000 in manual validation) ensures that reported hazard ratios are biased toward null rather than away from it. 6. PH violations are mechanistically resolved, not merely acknowledged: 11 of 15 covariates violate the proportional hazards assumption (Schoenfeld test). Rather than treating this as a limitation, the timestratified analysis (§6.9) converts each violation into a mechanistic finding. Weibull and Log-Logistic AFT models confirm directional consistency for all 15 covariates, establishing that the violations affect the magnitude and shape of effects over time, but not their direction. We strictly avoid causality claims. CLSA delivers an infrastructure for quantifying code evolution patterns empirically — a foundation for time-conditional risk scoring tools and a reusable analytical pipeline for future MSR studies extending beyond TypeScript. Full reproduction scripts, database schemas, and raw output are available in the supplementary material.

Declarations Data Availability Statement The datasets generated and/or analyzed during the current study, including the ClickHouse database schema, Python data extraction scripts (PyDriller and tree-sitter configurations), and full replication pipelines, are openly available on Zenodo at https://doi.org/10.5281/zenodo.20367615. A curated random sample used for manual validation is also provided alongside the analysis scripts to ensure full reproducibility. Acknowledgments The author thanks the open-source maintainers whose repositories constitute the CLSA dataset. No external funding was received for this work. Conflict of Interest The author declares that they have no competing interests.

38

References [1] J. R. Falleri, F. Morandat, X. Blanc, M. Martinez, and M. Monperrus, “Finegrained and accurate source code differencing,” in Proc. 29th ACM/IEEE Int. Conf. on Automated Software Engineering (ASE), 2014, pp. 313–324. [2] D. Silva and M. T. Valente, “RefDiff: Detecting Refactorings in Version Histories,” in Proc. MSR, 2017, pp. 269–279. [3] E. N. Samoladas, L. Angelis, and I. Stamelos, “Survival analysis on the duration of open source projects,” Information and Software Technology, vol. 52, no. 9, pp. 902–922, 2010. [4] D. Spadini, M. Aniche, and A. Bacchelli, “PyDriller: Python framework for mining software repositories,” in Proc. ESEC/FSE, 2018, pp. 908–911. [5] S. Raemaekers, A. van Deursen, and J. Visser, “Semantic versioning versus breaking changes: A study of the maven repository,” in SCAM, 2014, pp. 215–224. [6] T. Zimmermann, R. Premraj, and A. Zeller, “Predicting defects for Eclipse,” in Proc. PROMISE, 2007, pp. 9–20. [7] E. Murphy-Hill, C. Parnin, and A. P. Black, “How we refactor, and how we know it,” IEEE Trans. Softw. Eng., vol. 38, no. 1, pp. 5–18, 2012. [8] N. Nagappan and T. Ball, “Use of relative code churn measures to predict system defect density,” in Proc. ICSE, 2005, pp. 284–292. [9] A. E. Hassan, “Predicting faults using the complexity of code changes,” in Proc. ICSE, 2009, pp. 78–88. [10] L. P. Hattori and M. Lanza, “On the nature of commits,” in Proc. ASE Workshops, 2008, pp. 63–71. [11] M. Shahzad, M. Z. Shafiq, and A. X. Liu, “A Large Scale Exploratory Analysis of Software Vulnerability Life Cycles,” in Proc. ICSE, 2012, pp. 771– 781. [12] G. Bavota, A. Qusef, R. Oliveto, A. De Lucia, and D. W. Binkley, “Are test smells really harmful? An empirical study,” Empir. Softw. Eng., vol. 20, no. 4, pp. 1052–1094, 2015. [13] D. G. Kleinbaum and M. Klein, Survival Analysis: A Self-Learning Text, 3rd ed. Springer, 2012. [14] B. Fluri, M. Wuersch, M. Pinzger, and H. C. Gall, “Change distilling: Tree differencing for fine-grained source code change extraction,” IEEE Trans. Softw. Eng., vol. 33, no. 11, pp. 725–743, 2007. [15] J. Y. Gil and G. Lalouche, “When do software complexity metrics mean nothing? — When examined out of context,” J. Object Technology, vol. 15, no. 1, 2016.

39

[16] J. C. Munson and S. G. Elbaum, “Code churn: A measure for estimating the impact of code change,” in Proc. ICSM, 1998, pp. 24–31. [17] F. Khomh, M. Di Penta, Y.-G. Guéhéneuc, and G. Antoniol, “An exploratory study of the impact of antipatterns on class change- and fault-proneness,” Empir. Softw. Eng., vol. 17, no. 3, pp. 243–275, 2012. [18] P. Kruchten, R. L. Nord, and I. Ozkaya, “Technical debt: From metaphor to theory and practice,” IEEE Software, vol. 29, no. 6, pp. 18–21, 2012. [19] A. Tornhill, Software Design X-Rays: Fix Technical Debt with Behavioral Code Analysis. Pragmatic Bookshelf, 2018. [20] J. W. Ratcliff and D. E. Metzener, “Pattern Matching: The Gestalt Approach,” Dr. Dobb’s Journal, vol. 13, no. 7, pp. 46–51, 1988. (Implemented in Python’s standard library as difflib.SequenceMatcher.ratio().) [21] L. R. Dice, “Measures of the Amount of Ecologic Association Between Species,” Ecology, vol. 26, no. 3, pp. 297–302, 1945. [22] J. Śliwerski, T. Zimmermann, and A. Zeller, “When do changes induce fixes?” in Proc. MSR Workshop at ICSE, 2005, pp. 1–5. [23] S. Kim, T. Zimmermann, K. Pan, and E. J. Whitehead Jr., “Automatic identification of bug-introducing changes,” in Proc. 21st IEEE/ACM Int. Conf. on Automated Software Engineering (ASE), 2006, pp. 81–90. [24] H. W. Kuhn, “The Hungarian Method for the Assignment Problem,” Naval Research Logistics Quarterly, vol. 2, no. 1–2, pp. 83–97, 1955.

Appendix A. Full Repository Catalog Table A1. All 120 GitHub repositories included in the CLSA dataset, sorted by total lines mined in descending order. Age = months between the first and last observed commit; Lines Mined = TypeScript lines added during the observation period; Deaths = permanently deleted lines (hard delete + file delete); Survived = lines still alive at the snapshot date. Deaths + Survived < Lines Mined for most repositories; the remainder are lines transformed via migration or modification (line_evolution) and are right-censored in the survival model. #

Repository

1 2 3 4 5 6 7 8

microsoft/vscode Expensify/App twentyhq/twenty DefinitelyTyped/DefinitelyTyped ag-grid/ag-grid microsoft/FluidFramework remotion-dev/remotion tamagui/tamagui

Age (Mo.) 126 35 41 163 130 116 71 67

40

Lines Commits Mined 118,215 99,575 10,201 69,085 23,141 16,807 18,733 11,132

Deaths

Survived

4,031,373 966,838 1,909,391 2,835,458 1,039,257 1,124,026 2,170,359 785,557 990,896 1,853,038 724,178 773,375 1,570,216 539,199 693,573 1,468,504 558,400 569,540 1,349,990 328,921 614,026 1,132,232 688,627 285,154

#

Repository

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

supabase/supabase triggerdotdev/trigger.dev calcom/cal.com novuhq/novu medusajs/medusa RocketChat/Rocket.Chat signalapp/Signal-Desktop baidu/amis apache/superset formatjs/formatjs invoke-ai/InvokeAI langchain-ai/langchainjs Chocobozzz/PeerTube cypress-io/cypress chakra-ui/chakra-ui scalar/scalar pnpm/pnpm angular/angular-cli chakra-ui/ark dbeaver/cloudbeaver gitpod-io/gitpod outline/outline remix-run/react-router withastro/astro streamlabs/desktop bitpay/bitcore vuetifyjs/vuetify nestjs/nest openkraken/kraken colinhacks/zod freeCodeCamp/freeCodeCamp ConsenSys-archive/truffle Kanaries/Rath docmost/docmost VSCodeVim/Vim chatboxai/chatbox honojs/hono xuejianxianzun/ PixivBatchDownloader react-hook-form/react-hook-form rjsf-team/react-jsonschema-form radix-ui/primitives verdaccio/verdaccio kysely-org/kysely jitsi/jitsi-meet apollographql/apollo-server video-dev/hls.js discordjs/discord.js alibaba/lowcode-engine material-components/materialcomponents-web konvajs/konva xyflow/xyflow nanbingxyz/5ire kanbn/kan

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

Age (Mo.)

41

Lines Commits Mined

Deaths

Survived

67 41 62 57 64 74 97 80 91 83 44 39 122 108 81 34 116 132 43 73 67 54 72 62 102 107 105 112 31 74 60 61 78 33 125 37 52 80

15,808 4,979 11,836 10,841 5,638 7,003 6,464 8,605 5,501 1,755 7,573 4,113 6,943 4,078 5,407 2,707 5,701 8,932 2,117 3,765 4,763 4,593 2,744 7,425 3,796 3,944 4,944 3,371 1,489 1,459 2,672 3,016 1,062 725 3,573 712 1,739 1,463

1,072,324 355,801 1,019,397 629,277 1,018,977 489,734 1,013,499 346,998 996,357 332,859 716,970 152,812 644,055 132,745 608,391 98,661 511,131 100,488 481,811 359,459 445,050 198,009 426,748 164,586 385,050 77,413 380,500 141,923 352,584 149,979 347,071 99,504 282,313 51,632 270,373 131,817 261,237 77,226 241,048 69,158 239,729 88,651 234,788 37,591 226,901 71,253 213,448 93,000 203,891 59,700 190,961 41,883 147,520 49,036 127,051 24,219 120,970 15,239 120,755 53,009 115,248 29,261 109,911 23,941 102,454 47,825 98,072 11,992 97,979 22,830 97,363 18,879 96,910 30,393 94,863 19,925

541,225 329,335 385,490 479,665 557,847 448,592 356,162 431,140 345,305 49,517 135,826 226,707 193,259 186,742 135,123 210,573 155,069 90,461 130,846 101,436 107,528 163,326 123,253 79,477 103,844 120,175 69,644 72,235 93,066 51,065 69,556 62,897 38,874 74,783 43,825 66,965 50,454 52,063

86 80 65 82 62 49 119 94 113 24 99

2,533 534 950 682 1,003 2,009 2,001 1,374 2,672 579 716

91,821 89,148 87,511 84,750 82,445 82,154 81,388 80,341 73,397 70,172 65,544

29,984 19,354 33,537 31,712 14,102 7,246 47,825 11,688 14,132 4,470 10,730

43,306 54,360 34,849 36,699 50,790 63,134 19,591 52,546 45,367 58,376 45,161

135 79 17 30

732 2,327 1,207 560

65,479 62,053 49,551 48,634

21,623 20,406 10,931 6,846

38,112 25,021 30,118 35,186

Age (Mo.)

#

Repository

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90

clauderic/dnd-kit yangshun/tech-interview-handbook Koenkk/zigbee2mqtt rrweb-io/rrweb shuding/nextra dexie/Dexie.js adonisjs/core whyour/qinglong Yoctol/bottender gitbrent/PptxGenJS gajus/slonik vadimdemedes/ink preactjs/signals jd-opensource/taro-ui soybeanjs/soybean-admin vercel/swr typestack/routing-controllers sismo-core/sismo-badges lokalise/i18n-ally streamich/react-use conventional-changelog/commitlint nestjsx/crud seek-oss/playroom steven-tey/novel algolia/docsearch pmndrs/zustand Lissy93/web-check slab/quill Authenticator-Extension/ Authenticator appwrite/appwrite Molunerfinn/PicGo fkhadra/react-toastify iptv-org/iptv shadcn-ui/taxonomy astriaai/headshots-starter nomcopter/react-mosaic vercel/next-learn postcss/postcss saltyshiomix/nextron Tencent/wujie haishanh/yacd improbable-eng/grpc-web chanind/hanzi-writer fastmail/Squire unform/unform airbnb/react-sketchapp unjs/magic-regexp piotrwitek/react-redux-typescriptguide markedjs/marked formkit/auto-animate cruip/tailwind-landing-page-template alexjoverm/typescript-library-starter unplugin/unplugin-icons

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114

42

Lines Commits Mined

Deaths

Survived

66 44 58 89 53 132 88 62 27 83 67 86 45 93 58 76 114 7 66 74 84 55 87 22 73 85 47 37 80

761 587 698 796 710 983 764 1,254 255 1,107 476 267 511 358 714 565 360 213 830 708 220 225 134 347 305 326 220 212 340

47,312 40,731 40,325 38,904 37,259 36,085 35,834 33,088 26,580 23,696 23,099 23,070 23,035 23,024 22,603 22,398 21,451 19,457 19,206 18,229 17,461 15,154 14,078 13,549 12,648 12,015 11,909 11,820 10,883

17,571 9,471 5,545 4,697 13,976 6,710 19,563 7,596 2,099 8,566 5,526 1,766 3,900 882 10,736 5,335 5,662 4,720 3,230 2,448 1,072 5,359 2,699 6,442 1,430 2,789 2,602 691 2,227

20,664 23,756 22,415 29,249 14,760 21,546 10,990 18,817 21,411 6,394 10,618 18,794 16,296 20,513 6,537 13,151 7,029 12,874 10,553 11,852 10,290 7,556 9,210 4,342 9,708 5,930 6,511 9,731 5,753

71 76 102 32 6 19 109 67 128 94 47 42 66 59 40 23 28 44 60

46 183 438 165 82 196 93 126 359 313 163 132 91 16 81 78 58 86 96

8,904 8,535 8,056 7,533 7,221 7,197 7,006 6,555 6,346 5,965 5,533 5,522 4,934 4,864 4,786 3,788 3,485 2,940 2,788

5,073 1,342 3,418 2,458 765 1,234 1,605 1,573 596 2,523 423 978 787 31 101 1,362 387 349 644

3,808 5,864 2,839 2,848 5,258 4,949 4,100 3,566 4,188 1,831 4,561 3,750 3,019 4,751 4,519 1,376 2,657 1,899 1,301

34 46 22 24 61

101 106 10 80 179

2,623 2,550 2,155 2,024 1,923

480 208 464 1,274 522

1,568 2,020 1,232 201 963

# 115 116 117 118 119 120

Age (Mo.)

Repository danilowoz/react-content-loader Nutlope/restorePhotos niklashigi/apk-mitm babaohuang/GeminiProChat catppuccin/catppuccin SamKirkland/FTP-Deploy-Action

84 17 54 20 40 26

Lines Commits Mined 32 100 93 78 29 22

1,811 1,739 1,419 1,256 627 320

Deaths

Survived

358 356 249 163 167 108

1,162 802 863 637 364 135

Total: 120 repositories; 32,464,566 lines mined; 11,009,579 deaths; 14,990,228 survived.

43

Related documents

Record · ID 259557 · SHA-256 cdbcc0194f6cdcc8
Retrieved via Conceptio — every document is proof-bundled with source, license, and retrieval metadata.