diff --git a/GOALS-archive.md b/GOALS-archive.md index 551eb9e5..fa599534 100644 --- a/GOALS-archive.md +++ b/GOALS-archive.md @@ -222,3 +222,7 @@ Acceptance: a merged payload carrying a wrong-arch binary outside any platform-d ### G-126 [achieved 2026-07-27] punkzip as a vendored zip accelerator: zig 0.16 port, reproducible build into bin/, punk::zip fast path → detail: goals/archive/G-126-punkzip-accelerator.md Scope: src/tools/punkzip/ (vendored punkzip source tree - root name settled in the work - with provenance and licence records); src/make.tcl (tool build step); bin/tools/zig* (pinned toolchain as consumed); bin/punkzip.exe (untracked build output); src/modules/punk/zip-999999.0a1.0.tm (accelerator detection + fast path behind the G-124 pure-Tcl floor); src/tests/modules/punk/zip/ (parity suite - accelerated and pure-Tcl paths must agree); upstream maintained checkout c:/repo/jn/zig/punkzip (re-vendor source, read-only from this repo) Acceptance: the vendored source builds under the repo's pinned zig 0.16 toolchain with 'zig build test' green (the port's own 10 test modules), driven by a make.tcl step that produces bin/punkzip.exe reproducibly on a clean checkout - and zig stays OPTIONAL: a tclsh-only clean checkout completes packages + bake unchanged, with the step's absence reported rather than fatal; punkzip gains an explicit extract-to-directory argument and a machine-readable listing mode whose format is pinned by a test (the current fixed-width table stays the human default); punk::zip detects the accelerator and uses it, with a parity suite proving accelerated and pure-Tcl paths return identical listings and produce byte-identical extraction trees over the G-124 fixture set including the file-relative prefixed executable, and proving the pure-Tcl path is still taken when the binary is absent; a recorded benchmark on a representative kit payload states the speedup and the entry count at which it becomes material; the vendored tree records its upstream origin, the commit or state it was taken from, the re-vendor procedure, and its licensing (public-domain hwzip lineage plus MIT musl time.zig) per G-063 and the G-026 provenance direction. + +### G-135 [achieved 2026-07-28] Asset provenance records: a verifiable master-to-derived icon chain with a platform-neutral generator → detail: goals/archive/G-135-asset-provenance-records.md +Scope: src/assets/logo/ (per-asset *.assetorigin.toml sidecars, masters and generated icons); src/assets/logo/make-ico.ps1 (replaced in place by a Tcl generator, then removed); scriptlib/developer/ (provenance checker, sibling to goals_lint and architecture_lint); checker home revisited if it becomes a bake step (a punk:: module rather than scriptlib, which make.tcl must not depend on); src/runtime/punkshell.ico and src/vfs/_vfscommon.vfs/punkshell.ico (recorded as derived copies, not relocated) +Acceptance: the `.assetorigin.toml` sidecar format is documented with a `schema` key, the recorded asset bound by the sidecar's own filename (suffix stripped, same directory) and the source reference relative to that directory, files ending in the suffix being records, never assets; a reader tolerates a missing sidecar, unknown keys and an unrecognised schema version without erroring; a checker written in plain Tcl - no rasterizer, no external binary, runnable under any punkshell runtime - classifies each asset it examines as exactly one of `unrecorded` (no sidecar), `verified`, `artifact-absent` (a sidecar whose paired asset is gone), `source-absent`, `replaced` or `stale` per the state table in this file, where `verified` requires every hash the sidecar records to match, so a sidecar carrying only the artifact hash is verified on that alone, demonstrably distinguishing `stale` (source changed since the artifact was generated) from `replaced` (artifact changed since recording) and from `artifact-absent` on constructed fixtures, and is advisory only, never failing a build, in the manner of the G-133 payload checks; the icon generator is reimplemented with no Windows-only component (`System.Drawing` in particular), regenerating every generated `.ico` under `src/assets/logo/` byte-identically to the current `make-ico.ps1` under the invocation profile that produced it before that script is removed, and (re)writing the sidecar of each artifact it produces - artifact and source hashes plus the invocation options - so regeneration cannot leave a stale record; and sidecars exist and verify for every generated artifact under `src/assets/logo/`, `alternative/`, `web/` and `project-default/`. diff --git a/GOALS.md b/GOALS.md index 544ddec4..b86db4f6 100644 --- a/GOALS.md +++ b/GOALS.md @@ -411,10 +411,6 @@ Detail: goals/G-132-tcl-windows-errno-catchall-report.md Scope: src/make.tcl (post-assembly offset-style probe at the G-133 advisory-check seam, recapped reporting); src/modules/punkboot/utils-999999.0a1.0.tm (probe predicate beside the G-133 scan helpers, guarded require; bootsupport copies via established sync channels); src/tests/modules/punkboot/utils/ + src/tests/shell/testsuites/punkexe/ (characterization); src/AGENTS.md (what the pin does and does not guarantee) Detail: goals/G-134-baked-kits-pinned-archive-relative.md -### G-135 [active] Asset provenance records: a verifiable master-to-derived icon chain with a platform-neutral generator -Scope: src/assets/logo/ (per-asset *.assetorigin.toml sidecars, masters and generated icons); src/assets/logo/make-ico.ps1 (replaced in place by a Tcl generator, then removed); scriptlib/developer/ (provenance checker, sibling to goals_lint and architecture_lint); checker home revisited if it becomes a bake step (a punk:: module rather than scriptlib, which make.tcl must not depend on); src/runtime/punkshell.ico and src/vfs/_vfscommon.vfs/punkshell.ico (recorded as derived copies, not relocated) -Detail: goals/G-135-asset-provenance-records.md - ### G-136 [proposed] Generated projects are seeded with a default icon from a single punkshell-held master Scope: src/assets/logo/project-default/ (the single held seed artwork); src/modules/punk/mix/commandset/project-999999.0a1.0.tm (generation-time asset injection beside bootsupport_inject); src/project_layouts/ (per-layout icon-slot declaration with no artwork stored in layout trees); src/modules/punkcheck-999999.0a1.0.tm (install records for injected assets) Detail: goals/G-136-generated-project-icon-seeding.md diff --git a/goals/G-057-kit-icon-embedding.md b/goals/G-057-kit-icon-embedding.md index 9a70e065..8302714d 100644 --- a/goals/G-057-kit-icon-embedding.md +++ b/goals/G-057-kit-icon-embedding.md @@ -129,12 +129,22 @@ delete-then-write). Requirements sketch agreed 2026-07-10: - Related: G-127 - once one vfs definition bakes for several targets, "which kits get an icon" becomes a target question; that is what prompted the 2026-07-26 decision recorded in the Acceptance that the override is shared across a kit definition's targets. -- Related: G-135 - the source-tree provenance records this goal's sidecar can read. The - sidecar is emitted per kit at bake time and describes what got embedded; G-135's - per-asset assetorigin sidecars are committed and describe a derivation. Populating the sidecar's - "source .ico identity and provenance" from those records closes the gap where this - goal's provenance otherwise stops at the .ico bytes, one tier short of the SVG master - they were generated from. +- Related: G-135 (achieved 2026-07-28, archived - see + goals/archive/G-135-asset-provenance-records.md) - the source-tree provenance + records this goal's sidecar can read. The sidecar is emitted per kit at bake + time and describes what got embedded; G-135's per-asset assetorigin sidecars + are committed and describe a derivation. Populating the sidecar's "source + .ico identity and provenance" from those records closes the gap where this + goal's provenance otherwise stops at the .ico bytes, one tier short of the + SVG master they were generated from. +- G-135 (archived) delivered concrete inputs for this goal: the record format + (src/assets/logo/AGENTS.md "Provenance records"), the checker + (scriptlib/developer/assetorigin_check.tcl), and a verified derived-copy + sidecar beside this goal's default icon at src/runtime/punkshell.ico (hash + equals source_hash, source ../assets/logo/punk-mark.ico). Its notes also + carry the still-open user call this goal will meet at bake time: whether the + _vfscommon.vfs / per-kit vfs punkshell.ico copies get sidecars, which would + ship inside every baked kit. - The sidecar is the natural reconciliation point for the three provenance surfaces this file already flags (G-025's kit stamp, G-117's embedded artifact record, the parked RT_VERSION follow-on) - one text record per kit, on every platform. diff --git a/goals/G-135-asset-provenance-records.md b/goals/G-135-asset-provenance-records.md index 4175dcf3..f62781d6 100644 --- a/goals/G-135-asset-provenance-records.md +++ b/goals/G-135-asset-provenance-records.md @@ -1,6 +1,6 @@ # G-135 Asset provenance records: a verifiable master-to-derived icon chain with a platform-neutral generator -Status: active +Status: achieved 2026-07-28 Scope: src/assets/logo/ (per-asset *.assetorigin.toml sidecars, masters and generated icons); src/assets/logo/make-ico.ps1 (replaced in place by a Tcl generator, then removed); scriptlib/developer/ (provenance checker, sibling to goals_lint and architecture_lint); checker home revisited if it becomes a bake step (a punk:: module rather than scriptlib, which make.tcl must not depend on); src/runtime/punkshell.ico and src/vfs/_vfscommon.vfs/punkshell.ico (recorded as derived copies, not relocated) Goal: Any committed icon in the tree can state what it was derived from and be checked against that claim on any platform, and regenerating one from its master needs no Windows-only tooling - while an icon carrying no record stays a fully supported and silent case. Acceptance: the `.assetorigin.toml` sidecar format is documented with a `schema` key, the recorded asset bound by the sidecar's own filename (suffix stripped, same directory) and the source reference relative to that directory, files ending in the suffix being records, never assets; a reader tolerates a missing sidecar, unknown keys and an unrecognised schema version without erroring; a checker written in plain Tcl - no rasterizer, no external binary, runnable under any punkshell runtime - classifies each asset it examines as exactly one of `unrecorded` (no sidecar), `verified`, `artifact-absent` (a sidecar whose paired asset is gone), `source-absent`, `replaced` or `stale` per the state table in this file, where `verified` requires every hash the sidecar records to match, so a sidecar carrying only the artifact hash is verified on that alone, demonstrably distinguishing `stale` (source changed since the artifact was generated) from `replaced` (artifact changed since recording) and from `artifact-absent` on constructed fixtures, and is advisory only, never failing a build, in the manner of the G-133 payload checks; the icon generator is reimplemented with no Windows-only component (`System.Drawing` in particular), regenerating every generated `.ico` under `src/assets/logo/` byte-identically to the current `make-ico.ps1` under the invocation profile that produced it before that script is removed, and (re)writing the sidecar of each artifact it produces - artifact and source hashes plus the invocation options - so regeneration cannot leave a stale record; and sidecars exist and verify for every generated artifact under `src/assets/logo/`, `alternative/`, `web/` and `project-default/`. @@ -143,7 +143,9 @@ container assembly downstream is pure `binary format`. checker runs during `make.tcl bake` or only as an explicit verification subcommand. `stale` is a design-time mistake rather than a build-time one, which argues for a subcommand plus an opportunistic check only when a bake actually - consumes an icon. + consumes an icon. Unresolved at achievement: the checker shipped as a + standalone scriptlib tool only; bake integration, if ever wanted, moves it + to a `punk::` module per Scope (make.tcl must not depend on scriptlib). - Override behaviour in baked kits (recorded 2026-07-28): a kit .vfs that overrides a common asset without shipping its own sidecar produces a kit where the travelled common sidecar classifies the override as `replaced` - @@ -152,13 +154,60 @@ container assembly downstream is pure `binary format`. pair by same-path replacement with no new machinery. - The sidecar shape eases the checker's parsing posture: each record is one small flat toml table, so a self-contained subset reader stays defensible if - the tomlish dependency is unwanted in the scriptlib context - the checker's - toml/hash dependency posture is still an open decision for the work - (pre-activation review 2026-07-28). -- Open (pre-activation review 2026-07-28): whether sidecars for the - build-consumed `punkshell.ico` copies are acceptance-required - Scope names - two of the four (`src/runtime/`, `_vfscommon.vfs`; `mkzipfix.vfs` and - `punk8_statictwapi.vfs` carry byte-identical copies too) - and the explicit - decision that a sidecar committed in `_vfscommon.vfs` ships inside every - baked kit (the per-asset shape makes that collision-free; the shipping - intent itself is the open call). + the tomlish dependency is unwanted in the scriptlib context. RESOLVED at + implementation (2026-07-28): the checker embeds a self-contained flat-toml + subset reader (root table only, stops at the first table header) and its + own sha256, as does the generator - no tomlish, no tcllib; each script runs + standalone under stock tclsh 8.6+. +- Open at pre-activation review, resolved 2026-07-28 for one of the four + build-consumed `punkshell.ico` copies: `src/runtime/punkshell.ico` carries a + hand-authored derived-copy sidecar (hash equals source_hash, source + `../assets/logo/punk-mark.ico`) - it is a passive file no build step copies + onward, so nothing ships. Still open (user call): sidecars for the + `_vfscommon.vfs`, `mkzipfix.vfs` and `punk8_statictwapi.vfs` copies - a + sidecar committed in `_vfscommon.vfs` ships inside every baked kit (the + per-asset shape makes that collision-free; the shipping intent itself is + the open call). Those three copies stay deliberately unrecorded (silent, + fully supported) until the user decides. + +## Progress + +Achieved 2026-07-28, all work landed that day in three increments +(activation bcf6625d; generator + sidecars + ps1 removal + format docs +f529f44e; checker de5a27a4). Verification evidence: + +- Byte-identity (generator clause): `make-ico.tcl all -check` regenerates all + seven manifest artifacts (punk-mark.ico, alternative/punk-mark-solid.ico and + project-default/icon.ico on the 16/24/32/48/64/128-DIB + 256-PNG profile; + web/favicon.ico 16/32/48 all-PNG; web rasters 180/192/512 from + icon-opaque.svg) byte-identical to the make-ico.ps1-era committed files, + under both mingw tclsh 8.6.11 and native Tcl 9.0.3 with rsvg-convert 2.62.0 + (the version that produced the committed artifacts) - proven BEFORE + make-ico.ps1 was removed in the same change-set. rsvg-convert determinism + separately confirmed by matching the PNG payloads extracted from committed + icos against fresh renders. +- Embedded sha256 validated against the three NIST vectors (empty string, + "abc", the 448-bit vector) and cross-checked against PowerShell + Get-FileHash on real artifacts. Identical implementation embedded in + generator and checker; each script standalone. +- Checker state model: selftest constructs 13 fixtures demonstrating all six + states, the rule-3 precedence (replaced wins regardless of source state, + proven with a missing source) and every tolerance rule (unrecognised + schema ignored; unknown keys skipped; root table ends at the first table + header; hash-only record verifies on the artifact hash alone; source named + without source_hash is presence-only; unrecognised hash-algorithm prefix + treated as not recorded; record without a usable artifact hash ignored) - + 16/16 PASS under mingw tclsh 8.6.11, native Tcl 9.0.3 and the punk91 kit + runtime (the "runnable under any punkshell runtime" clause). +- Live tree: `assetorigin_check.tcl check` reports 8 records, 8 verified + (the seven generated artifacts plus the src/runtime/punkshell.ico + derived-copy record); default scan (src minus buildsuites, scriptlib, + goals) 2.2s. +- favicon source pinned empirically: committed payloads byte-match renders of + both web/icon.svg and punk-mark.svg (identical output at 16/32/48); + recorded as web/icon.svg - same directory, the primary web icon. + +Remaining manual items: none for this goal's acceptance. The open user call +on vfs-copy sidecars (kit shipping) is carried in Notes above; the +bake-vs-subcommand workflow question likewise, both deliberately outside the +Acceptance. diff --git a/goals/G-136-generated-project-icon-seeding.md b/goals/G-136-generated-project-icon-seeding.md index 3b72363b..5ca2ac79 100644 --- a/goals/G-136-generated-project-icon-seeding.md +++ b/goals/G-136-generated-project-icon-seeding.md @@ -71,10 +71,18 @@ unbranded so it reads "replace me" rather than as a product identity. ## Notes -- Related: G-135 - depends on. Consumes the sidecar record format and the - checker, and relies specifically on the record being a per-asset sidecar - with directory-relative references so it survives injection unchanged (and - a single asset re-injected travels with its record as a pair). +- Related: G-135 (achieved 2026-07-28, archived - see + goals/archive/G-135-asset-provenance-records.md) - depends on, now + satisfied. Consumes the sidecar record format and the checker, and relies + specifically on the record being a per-asset sidecar with + directory-relative references so it survives injection unchanged (and a + single asset re-injected travels with its record as a pair). The dependency + is concrete: `src/assets/logo/project-default/icon.ico.assetorigin.toml` + exists and verifies (source `icon.svg`, same directory), so the verbatim + copy this goal's Approach describes is exactly the committed pair; the + checker is `scriptlib/developer/assetorigin_check.tcl` (format spec: + src/assets/logo/AGENTS.md "Provenance records"; regeneration: + `tclsh src/assets/logo/make-ico.tcl all`). - Related: G-027 - consumer. Pull-based infrastructure updates for derived projects would later refresh seeded assets, and both goals record their installs through punkcheck. diff --git a/src/assets/logo/AGENTS.md b/src/assets/logo/AGENTS.md index 36cb7591..8e08b13b 100644 --- a/src/assets/logo/AGENTS.md +++ b/src/assets/logo/AGENTS.md @@ -21,7 +21,8 @@ elsewhere in the tree is a derived copy or a build input, never an original. repeat from here. The `src/runtime/` copy carries an assetorigin sidecar recording the derivation (hash equals source_hash: a byte-identical copy); the three vfs copies stay deliberately unrecorded pending the user call on - shipping sidecars inside baked kits (G-135 notes). + shipping sidecars inside baked kits (recorded in + goals/archive/G-135-asset-provenance-records.md notes). ## Local Contracts @@ -72,7 +73,8 @@ elsewhere in the tree is a derived copy or a build input, never an original. ## Provenance records (assetorigin sidecars) -Canonical format documentation for `*.assetorigin.toml` sidecars (G-135). +Canonical format documentation for `*.assetorigin.toml` sidecars (G-135, +achieved 2026-07-28 - see goals/archive/G-135-asset-provenance-records.md). - `.assetorigin.toml` beside an asset records what that asset was derived from. The recorded asset is bound by the sidecar's own filename -