# G-117 Self-describing family runtimes: embedded artifact record + metadata schema v1 Status: proposed Scope: src/buildsuites/suite_tcl90/ (kit-family staging embeds the record; family_artifacts.tcl schema v1 fields + emission ordering; -Doriginurl/-Dpackager options), tools/family_check.tcl (embedded-record verification), src/scriptapps/bin/punk-runtime.* + bin/punk-runtime.cmd via rewrap ('info' action; schema-tolerant parsing), punkbin AGENTS.md (record relationship + schema/field documentation) Goal: every family runtime carries a copy of its artifact metadata record INSIDE the attached image (e.g /app/punkbin-artifact.toml, written at kit-family staging time - necessarily WITHOUT the final sha1, which is computed over the finished binary and lives only in the sidecar toml + sha1sums), so a runtime separated from its sidecar remains identifiable via a punk-runtime 'info' action (embedded record and sidecar shown side by side, disagreements flagged); AND the metadata record is hardened as SCHEMA v1: schema (format version), build_id (uuid stamped in embedded AND sidecar - the offline correlation key for renamed copies), origin (canonical artifact repo the artifact was built FOR - mirrors preserve it; -Doriginurl, default punkbin), packager (declared identity; -Dpackager > env > git identity > unrecorded), project/project_url, license summary, build_host_platform - so records circulating on punkbin-compatible repos from different packagers stay interpretable and attributable. Acceptance: kit-family embeds the record in all three members with the embed-then-hash ordering documented (embedded copy carries the v1 fields but no self-sha1; the sidecar + sha1sums remain the integrity authority); family_check verifies the embedded record exists and its variant/patchlevel/battery fields MATCH the probed facts for each member; 'punk-runtime info ' reports identity for (a) a fetched artifact with its sidecar and (b) a bare RENAMED copy with no sidecar - the embedded-read mechanism is decided and documented in the work (zip-central-directory read of the exe-appended archive by the host payload where available vs a cooperative probe that executes the target with a generated script, execution caveat stated) - and flags embedded-vs-sidecar disagreement; the v1 field set is documented in punkbin AGENTS.md with each field's semantics (notably origin's built-for-not-published-on meaning and packager's declarative-not-verified status, with minisign sidecars noted as the verification complement); family_artifacts emits all v1 fields with build_id present and IDENTICAL in embedded and sidecar copies, and the emitted records carry brief '#' comment lines documenting the non-obvious fields (toml-spec comments, ignored by the existing line-based consumers); punk-runtime metadata parsing tolerates unknown fields and absent schema (pre-v1 r1 records keep working); both payloads in parity with the roundtrip pin green; the next family emission after this goal lands is r2 carrying the full v1 record (r1 stays immutable as published). ## Context Drafted 2026-07-22 (user-approved wording) from two exchanges during the G-103 publication session: MOTIVATION (embedding): the published family artifacts are metadata-carrying via SIDECAR tomls only - nothing is stamped inside the executables (a deliberate G-103 naming-decision property: the metadata record is authoritative, the filename identifies, the binary stays unstamped). The implication: an exe separated from its toml (out-of-band copy, rename) is identifiable only by executing probes against it or sha1-matching it back to a repo's sha1sums. Embedding a COPY of the record in the attached image makes runtimes self-describing without changing the authority model - the sidecar + sha1sums remain the integrity authority; the embedded copy is a convenience duplicate that cannot contain its own final sha1 (embed at staging -> wrap -> hash -> sidecar; no circularity). SCHEMA v1 (user-floated fields, analysed 2026-07-22): - origin: the user's "repository url it was first published on" idea, with a semantic reframe dissolving the timing problem they spotted (emission precedes publication; publish-time sidecar mutation would permanently diverge embedded vs sidecar - the exact disagreement 'info' flags): origin = the canonical artifact repo the artifact was BUILT FOR, known at emission (-Doriginurl, default punkbin), truthful regardless of publish timing, and preserved by mirrors - an artifact found on a third-party repo still declares its home. Where-it-actually-lives is the hosting repo's own business (a repo-level identity file beside platforms.txt/defaults.txt is a separate later idea). - packager: declared identity for multi-packager punkbin-compatible ecosystems (-Dpackager > env > the building checkout's git identity > "unrecorded"). DECLARATIVE, not proof - the verifiable layer is signing, with punkbin's existing minisign practice (zig tool archives) as precedent; per-artifact .minisig sidecars are the natural future complement, deliberately outside the metadata file (a signature cannot live inside what it signs). - schema: format-version field - the most important future-proofing addition; nearly free now, impossible to retrofit onto records already circulating. - build_id: uuid stamped in BOTH embedded and sidecar copies - the offline correlation key that re-joins a renamed stray exe to its record without content hashing. - license summary + project/project_url: distribution-platform eligibility (the G-004 motivation) asks licensing first; the project pointer makes a stray artifact self-explaining beyond its origin repo. Component licenses ride inside the image (tcl_library etc). - build_host_platform: near-free now, genuinely interesting once G-105 cross-builds exist (built ON win32-x86_64 FOR linux-x86_64). - REJECTED: lifecycle fields (superseded_by, expires) - repo-level curation (defaults.txt and successors), not artifact facts; artifacts stay immutable statements of what they are. Comment lines: emitted records gain brief '#' comments documenting non-obvious fields (origin/packager semantics). Toml-spec comments; the existing line-based consumers (punk-runtime ps1 regex / bash sed per-line matching, the summary parsers from G-107, achieved - see goals/archive/G-107-buildsuite-library-tests.md) ignore them by construction - family_artifacts already emits a '#' header line today. Read-mechanism design fork (the main in-goal decision): exe-appended zips are readable from the central directory by generic zip readers (.NET System.IO.Compression for the ps1 payload, unzip for bash) WITHOUT executing the target - preferred, since identifying an untrusted stray binary by running it is what an identity mechanism should avoid; the cooperative probe (execute the target with a generated script) is the documented fallback for hosts without a zip reader. Relationships: archived G-103 (metadata shape + family staging this extends - see goals/archive/G-103-runtime-kit-family.md), G-067 (library-class artifacts should adopt the same schema + embedding pattern), G-105 (embedded target field aids cross-platform staging hygiene alongside the sidecar !TARGET-MISMATCH check), G-006/G-067 consent gates (unchanged - metadata travels with artifacts through the existing channels).