@@ -7706,7 +7706,28 @@ static void try_artifact_bootstrap(const char *project_name, const char *repo_pa
77067706 project_db_path(project_name, db_buf, sizeof(db_buf));
77077707 if (cbm_file_size(db_buf) < 0 && cbm_artifact_exists(repo_path)) {
77087708 cbm_log_info("index.artifact_bootstrap", "project", project_name);
7709- cbm_artifact_import(repo_path, db_buf);
7709+ /* An imported artifact is trusted for graph CONTENT as-is — nothing
7710+ * verifies that its nodes/edges describe the code they claim to. What
7711+ * has been limiting the blast radius is mechanical, not a check: every
7712+ * imported row carries the EXPORTER's mtime, so the first incremental
7713+ * run re-parses ~everything and auto-scrubs a poisoned artifact at a
7714+ * clone time the producer cannot predict. That exposure is transient
7715+ * and self-healing.
7716+ *
7717+ * cbm_artifact_reconcile_hashes deliberately trades part of that away
7718+ * for the speed the artifact is supposed to deliver (#885): rows it
7719+ * restamps are no longer re-parsed, so poisoned nodes for those files
7720+ * persist until the file changes — a DURABLE exposure gated on a
7721+ * producer-written marker. It stays acceptable only because the marker
7722+ * alone never suffices: each restamped row must additionally be proven
7723+ * unchanged by the LOCAL git against a commit present in this clone.
7724+ * Read the trade-off note in artifact.h before widening it.
7725+ *
7726+ * Best-effort: a -1 return leaves every row foreign and falls back to
7727+ * today's behavior, so a failure here can never fail the import. */
7728+ if (cbm_artifact_import(repo_path, db_buf) == 0) {
7729+ (void)cbm_artifact_reconcile_hashes(repo_path, db_buf, project_name);
7730+ }
77107731 }
77117732}
77127733
0 commit comments