F1: put the generated table on the AGENTS.md 1.1 closed list

Isolated so it can be reverted on its own.

AGENTS.md 1.1 keeps a closed list of Adobe-authored non-visual technical data,
and adding to it needs the owner's explicit approval, which was given on
2026-10-08. The item itself -- the standard-14 font metrics and encoding tables
from the PDF specification -- was already on that list; what is new is holding
a copy first-party rather than only through hayro, which is what lets generated
appearances measure with it and what survives hayro being retired in M2.8.

The gate only understood the list for dependency-bundled files, and rejected
adobe_data on a repository file outright. It now accepts it for a closed list
of first-party paths, so crates/fonts/src/std14.rs carries an ATTRIBUTION entry
with its SHA-256: regenerating the table fails the gate until the entry is
updated, which makes a change to Adobe-derived data a deliberate act rather
than an ordinary edit.

Worth noting that .rs is not an asset extension, so the table would never have
been scanned at all. Entering it on the list is a choice to be checked, not a
requirement the gate imposed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Tanish Manku
2026-10-12 13:57:43 -07:00
co-authored by Claude Opus 5
parent d0d1ad8192
commit aaa19d87af
4 changed files with 44 additions and 3 deletions
+29 -1
View File
@@ -43,6 +43,12 @@ pub const BRAND_LICENCE: &str = "LicenseRef-Storyteller-Trademark";
pub const ADOBE_DATA_ALLOWED: &[(&str, &str)] = &[("hayro-cmap", "assets/cmaps.brotli"), ("hayro-interpret", "src/font/generated/metrics.rs")];
/// First-party files on that same closed list: generated tables of Adobe-authored non-visual
/// technical data we hold ourselves rather than through a dependency. Each still needs an
/// `[[asset]]` entry with `adobe_data = true`, so its SHA-256 is checked and any change to the
/// table has to be re-attested deliberately.
pub const ADOBE_DATA_FILES: &[&str] = &["crates/fonts/src/std14.rs"];
/// File extensions that count as assets wherever they appear in the repository.
const ASSET_EXTENSIONS: &[&str] = &[
"png", "jpg", "jpeg", "gif", "svg", "ico", "icns", "webp", "bmp", "tif", "tiff", "avif", "heic", "ttf", "otf", "ttc", "woff", "woff2", "pfb",
@@ -245,7 +251,7 @@ pub fn check(root: &Path, m: &Manifest, repo_files: &[String], lock: &BTreeSet<(
if visual(&a.kind) && (mentions_adobe(&a.author) || mentions_adobe(&a.source) || mentions_adobe(&a.title)) {
problems.push(format!("{}: {} from Adobe is forbidden (AGENTS.md §1.1)", a.path, a.kind));
}
if a.adobe_data {
if a.adobe_data && !(ADOBE_DATA_FILES.contains(&a.path.as_str()) && a.kind == "data") {
problems.push(format!("{}: adobe_data is only allowed for the closed list in AGENTS.md §1.1", a.path));
}
match std::fs::read(root.join(&a.path)) {
@@ -570,6 +576,28 @@ mod tests {
assert!(check(&root(), &font, &[], &l).iter().any(|p| p.contains("forbidden")));
}
#[test]
fn first_party_adobe_data_only_on_the_closed_list() {
let l = lock(&[]);
// The generated standard-14 table is on the list, as `kind = "data"`.
let mut ok = asset("crates/fonts/src/std14.rs", "Adobe (Core14 AFM metrics); tables by the PdfCraft contributors", "data", "MIT");
ok.adobe_data = true;
let m = Manifest { asset: vec![ok], ..Default::default() };
assert!(check(&root(), &m, &[], &l).is_empty(), "{:?}", check(&root(), &m, &[], &l));
// Any other first-party file claiming it is refused.
let mut sneaky = asset("Cargo.toml", "Adobe", "data", "MIT");
sneaky.adobe_data = true;
let m = Manifest { asset: vec![sneaky], ..Default::default() };
assert!(check(&root(), &m, &[], &l).iter().any(|p| p.contains("closed list")));
// Even on the list, it may only be data — never a typeface.
let mut wrong_kind = asset("crates/fonts/src/std14.rs", "Adobe", "font", "MIT");
wrong_kind.adobe_data = true;
let m = Manifest { asset: vec![wrong_kind], ..Default::default() };
assert!(!check(&root(), &m, &[], &l).is_empty());
}
#[test]
fn dependency_upgrade_forces_reaudit() {
let m = Manifest { bundled: vec![bundled("other", "a.ttf", "Someone", "font", false)], ..Default::default() };