@@ -3891,8 +3891,45 @@ public List<SubProject> getSubProjects() {
38913891 * </ul>
38923892 * <p>
38933893 * The API-based optimization helps prevent rebuild cascades in dependent
3894- * projects when only internal implementation changes occur.
3894+ * projects when only internal implementation changes occur. *
3895+ * <h2>Timestamp Preservation Strategy</h2>
3896+ * <p>
3897+ * To avoid unnecessary cascade rebuilds when only non-API changes occur,
3898+ * this implementation preserves the output JAR's timestamp when:
3899+ * </p>
3900+ * <ul>
3901+ * <li>Content digest matches (byte-identical), OR</li>
3902+ * <li>API digest matches (exported API unchanged)</li>
3903+ * </ul>
3904+ * <h3>Mechanism</h3>
3905+ * <p>
3906+ * The system computes content and API digests <strong>before</strong>
3907+ * writing the JAR, compares them against previously stored digests, and if
3908+ * a match is found, restores the old timestamp after the JAR is written.
3909+ * This prevents downstream projects from seeing a "new" dependency based on
3910+ * file timestamp alone.
3911+ * </p>
3912+ * <h3>Limitations</h3>
3913+ * <p>
3914+ * This pragmatic approach trades perfect accuracy for simplicity:
3915+ * </p>
3916+ * <ul>
3917+ * <li>Timestamps are preserved by directly setting {@code lastModified()}.
3918+ * This works well in most incremental build scenarios but may not perfectly
3919+ * reflect semantic changes in all edge cases.</li>
3920+ * <li>Attempting to perfectly distinguish between "this JAR actually
3921+ * changed" vs. "this build cycle recomputed the same thing" across multiple
3922+ * asynchronous build tool invocations is complex and fragile.</li>
3923+ * <li><strong>Not recommended for:</strong> highly dynamic build
3924+ * environments, complex classpath interdependencies, or scenarios requiring
3925+ * perfect timestamp accuracy for external build tools.</li>
3926+ * </ul>
3927+ * <p>
3928+ * In practice, this approach provides substantial benefits by preventing
3929+ * most unnecessary rebuilds while maintaining reliability.
38953930 * </p>
3931+ *
3932+ * @see RebuildTriggerPolicy#doRebuildTriggerPolicy(Workspace, Jar, File)
38963933 */
38973934 static class RebuildTriggerPolicy {
38983935
0 commit comments