Skip to content

pscat 0.6.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 18:59
· 35 commits to main since this release
77f18f3

The first release published outside this repository.

Highlights

  • Install without a checkout: cargo install pscat from crates.io, or a
    prebuilt binary from the GitHub Release (macOS arm64/x86_64, Linux
    x86_64/arm64 musl, Windows x86_64). PostScript libraries (lib/) are
    embedded in the binary.
  • Font packs: pscat fonts install downloads the extras, TeX Gyre and
    CJK/Thai packs from the fonts-2026.10 release, checked against a SHA-256
    pinned in the binary.
  • Subcommands: pscat handwrite, pscat typewrite and pscat photo-etch
    are built into the binary.
  • pscat-mcp declares its MCP protocol versions, enforces timeouts and size
    limits, and confines out_path. A Claude Code plugin bundles the skills and
    the server.
  • Licensing: code is MIT OR Apache-2.0, embedded fonts are OFL-1.1, and the
    art is CC0-1.0 (THIRD_PARTY_NOTICES.md).
  • Plus paint and dry media kits, the typewriter's released-document look,
    mathkit additions, Level 3 clipsave/cliprestore, and new gallery pieces.

Fixes

  • Fix hollow centre when a tiny curve is stroked wider than its diameter (#170)
  • Fix clippath to report the true intersection of nested clips (#120) (#131)
  • Fix P2s from #103 follow-up: centered ticks, SAFER note, remove PLAN_103.md (#108)
  • Fix Codex P1s from #103 follow-up (pie arc, scatter, setdvframe) (#106)
  • Fix pkoil porad cursor corruption for multi-subpath strokes (#90)
  • Fix ShowCtx's fixed unicode_mode: re-segment per glyph on mid-show font switch (#70)
  • work-issue: fix crash-resume race + branch-name bug (#29); address #33 punch list (#34)
  • Fix silent stroke-drop in --pdf-only export; add PDF document metadata (#8) (#23)
  • Fix work-issue deadlock: crashed in-progress issues must resume, not halt

Features and changes

  • fonts: pin fonts-2026.10 (#642)
  • licence: mochi reference photo is CC0 (owner's photo, #606); owner-merge SDLC.md, work-issue, sdlcify, settings.json (#641)
  • Interp: dropping an Interp frees systemdict/userdict (Rc cycle) (#632)
  • plugin: Claude Code plugin and marketplace for the skills and pscat-mcp (#569 part a) (#634)
  • mcp: out_path takes render extensions only, no dot-directories (#627) (#628)
  • pscat-mcp: declared protocol versions, timeouts, size caps, confined out_path; skills/ for an installed pscat (#568) (#624)
  • licence: art/ is CC0-1.0 (owner decision); mochi.jpg stays NOASSERTION (#606) (#619)
  • licence: MIT OR Apache-2.0 code, OFL embedded fonts, CC0 art; notices, asset manifest, URW provenance, Cargo metadata (#608)
  • released: a copy sends the typed ribbon's colour through the copier's curve (#597)
  • typewriter: erode a copy's body by the glyph outline so thin strokes drop out (T15) (#594)
  • released: multi-page overlays for rel-page, via a /PageEnd hook for tw-type (#589)
  • typewriter: a clogged counter takes the bleed colour and the worn lane's weave (#539) (#588)
  • released: a gem paper clip with a dent and a rust ghost, not three ellipses (#587)
  • typewriter: /worn's /Ribbon is 0.55, so the worn elite weighs x0.76 of T10, not x0.66 (#520) (#586)
  • released: a copy softens its stamps, notes and redaction bars (/Soften) (#582)
  • typewriter: /MisStrike and /MisStrikeScale, the mis-strike rate and size as machine and typist traits (#584)
  • landscape cookbook: regenerate grass.png thumbnail against its snippet (#535) (#583)
  • typewriter: opt-in /BleedGap pin stripe; /WornBand and /Bleed docs say what is measured (#571)
  • typewriter: the mis-strike's y tail is 2x, not 4x (the d in restricted) (#550)
  • released: thin-stroke dropout under a photocopy (/Dropout) (#548)
  • capabilities: module docs say parameters is generic, not paintkit-so-far (#544) (#553)
  • typewriter: reference search for two-colour bleed, embossing, worn lane and electric pages (none found) (#552)
  • image/imagemask: paint the ImageMatrix⁻¹ footprint, not the unit square (#546)
  • released: a copy's haze mottle is a crumpled-paper wave, not soft blocks (#528) (#542)
  • typewriter: ribbon ink extras, a worn band and two-colour bleed (opt-in) (#540)
  • currentrgbcolor: round the readback to the f32's short decimal like gs; alpine_lake still regenerated (one pixel, one level) (#536)
  • drykit: split a chunk past dkbudget, refuse a too-wide stroke before drawing (#324) (#537)
  • released: a copy's haze grain is imagemask stencils at the scans' strength (#474) (#529)
  • artkit: scin refuses a hand-built region that carries a procedure, with no per-call walk of built ones (#503) (#533)
  • Evening Stream: the cloud bodies' wet edge asks the sky at each stroke (pkwet /PerFill) (#525)
  • Alpine Lake: notes on pulling the plane-streak re-lay into the reflection (#508 measured; invisible) (#524)
  • typewriter: elite takes the ribbon ink separately from pica (#511) (#522)
  • pscat: a Type 3 BuildChar runs in its own gsave level, so cliprestore and grestore there give back the state at show (#500) (#527)
  • pscat: currentcmykcolor, currentcolor, currentlinecap, currentlinejoin, currentmiterlimit, currentstrokeadjust, as gs does (#523)
  • Evening Stream: the clouds' light load follows the sun's glow along each cloud (#462) (#521)
  • pkwet: /Smooth calms a directional pull's across-wobble so its side edges stagger less (#517)
  • grestore/grestoreall at the bottom or a save boundary, and currentgray, as gs does (#518)
  • typewriter: a light strike thins, not only dots out (#514)
  • alpine lake: the shadow planes' streaks read through the far mist banks (#476) (#509)
  • identity_check: a file that fails identically in both trees is SKIPPED, not an ERROR (#507)
  • typewriter: lighter ribbon ink, a wider spread of strike weight (#423) (#478)
  • artkit: scatter and scarea check a hand-built region before using it (#295) (#506)
  • released: a photocopy's paper keeps a grey haze, mottle and grain (/Haze) (#466) (#475)
  • paintkit: pkwet's directional /Layers cap is 32; the canvas specimen's wet pull no longer bands (#417) (#485)
  • mathkit: \mod and \pod, \nolimits on a brace, a column's wander, alignat, mkbrace (#480)
  • paintkit: pkfan runs are cut into overlapping ribbons for pkwet /FillLength (#502)
  • pscat: Level 3 clipsave and cliprestore, scoped per gsave level as in Ghostscript (#501)
  • paintkit: pkwet /FillLength cuts a long loaded run into per-stop fills so /PerFill follows a gradient along it (#499)
  • check_md_links: a ref must end at a boundary, so blob/mainline is not main (#481) (#498)
  • pscat: .sameclip, a clip identity query; drykit sees a bound wrapper's grestore in a dkbatch (#488) (#496)
  • drykit: shadow cliprestore inside a dkbatch where the interpreter has it (#454) (#495)
  • paintkit: pkwet /PerFill asks the backdrop at each loaded-colour fill (#403) (#493)
  • drykit: document why a bound wrapper's grestore can't be seen in a dkbatch, with three workarounds (#459) (#489)
  • docs/site: recount the font catalog to 67 files (#437) (#473)
  • paintkit: pkbrushedge /Under and /Mass take a region list (#456) (#464)
  • typewriter: released-document look -- aging, photocopy loss, stamps, redactions (#214) (#452)
  • drykit: keep a plain clip inside a dkbatch, one gstate per clip change (#444) (#457)
  • paintkit: pkbrushedge /Mass, a pull-out colour that can follow the mass's gradient (#426) (#460)
  • mathkit: braces, overset/substack, style switches, \not, \pmod, align columns (#340) (#440)
  • pscat: Level 2 gstate objects, an exact clip capture (#394) (#447)
  • drycharcoal: dhsmudge and dhlift run inside a dkbatch, drawn after it (#393) (#442)
  • fonts gallery: Courier Prime and /Typewriter cards (#412) (#438)
  • typewriter: tw-type layout API, memo header, scripts/typewrite.sh, docs (#213) (#432)
  • typewriter: ribbon ink -- weave, feathered edge, clogged counters, pressure (#212) (#425)
  • drykit: /drawing paper's mottle 6 -> 1.5, so charcoal hatching breaks up in specks (#313) (#419)
  • strokeglyphs: redraw the digit 4 so it no longer reads as a lightning bolt (#351) (#411)
  • Specimen polish: canvas weave wanders, knife pulls lose the tape look, handscript 7 (#298) (#421)
  • typewriter: the /Typewriter Type 3 font with machine, line and strike variation (#211) (#409)
  • typewriter: reference board and design writeup (#210) (#341)
  • paintkit: pktrowelplane bounds its area outline by wkmaxsegs (#401); reword stale pwsrand note (#397) (#406)
  • claim.sh: move-free generation lock, no double claim in the transit window (#297) (#405)
  • paintkit: pkwet /Box and /Bands, a backdrop per band (#359) (#404)
  • paintkit: pkscanclosed carries walkpath's segment bound (pkribbon/pknib/pkfeather) (#299) (#402)
  • srand: --sweep-seed leaves an rrand restore alone, so Alpine Lake's reflection matches (#202) (#400)
  • sdlcify: quality gate matches what ci.yml runs (#216) (#398)
  • Bind drycharcoal: } bind def on every procedure, checked by libbind (#326) (#399)
  • paintkit: @summary of pkfan, pkbroad and pktrowel names the loaded colours (#291) (#396)
  • drykit: dkclip lets a dkbatch hold strokes under different clips; dhhatch joins a caller's batch (#312) (#395)
  • paintkit: pkbrushedge/pkfeather skip edges hidden inside overlapping blobs (#381) (#392)
  • tests/landscape_cookbook: give the per-recipe CPU budget CI headroom (2 s to 5 s) (#387) (#391)
  • strokeglyphs + mathkit: ASCII * in \text, \mathrm and \operatorname is a raised text asterisk (#378) (#390)
  • landscape cookbook: light the far wood's crest with pkscumblein /Light (recipe 5) (#383) (#389)
  • tests/mathkit: give the specimen's CPU budget CI headroom (2 s to 5 s) (#388)
  • paintkit: light-aware massing, a lit side on a scumbled region (pkscumblein /Light) (#345) (#385)
  • paintkit: pkbrushedge and pkfeather, a brushed edge for filled masses (#347) (#379)
  • mathkit: ASCII * is \ast, so z^* and A_* lay out (#364) (#380)
  • paintkit: pkpull /Scatter offsets each stroke start across the spine (#346) (#377)
  • mathkit: UTF-8 delimiters after \left, \right and \big (#365) (#376)
  • pktrowelplane: space the rows for the thinnest a tapering /Pressure gets (#362) (#375)
  • strokeglyphs + mathkit: subscript digits and letters, variant Greek (#366) (#374)
  • errordict: a handler per error name, so a re-raise keeps the error name (#372) (#373)
  • pscat --lint: an errored run is never reported clean (#369) (#371)
  • paintkit: /Colors and the hue keys take bare pigment names; guards point at pigcolors (#356) (#370)
  • paintkit: palette-knife plane mode, pktrowelplane (#180) (#363)
  • strokeglyphs + mathkit: glyphs for more board-math symbols (#339) (#367)
  • paintkit: pkwet /Under accepts a backdrop procedure with /At (#179) (#360)
  • paintkit: named pigment palette with paint-like (Kubelka-Munk) mixing (#185) (#357)
  • strokeglyphs: sgpath/sgwidth refuse a missing glyph by name; /Strict false opts out (#350) (#355)
  • identity_check.sh --base-bin/--head-bin for interpreter changes; bench helper (#335) (#354)
  • def/load accept non-name keys (integer, real, boolean, string) like put and Ghostscript (#338) (#344)
  • mathkit: TeX-subset math layout to stroke skeletons with board-writing irregularity (#237) (#342)
  • Interpreter: proc fetch without cloning; def without re-intern (#323) (#332)
  • Bind drychalk; drycrayon and the older kits measured and left alone (#318) (#328)
  • pdf export: 2-decimal path coordinates (-19.8% total, #320) (#327)
  • drycharcoal: vine, compressed and pencil charcoal; hatching, smudge, lift, construction lines (#241) (#315)
  • drykit board proxy re-measured after bind: 25.2s in pscat, inside 30s (#283) (#325)
  • pdf export: drop zero-length lineto from fill and clip paths (#254) (#322)
  • Bind artkit, paintkit and drykit procedures: gs 1.5 to 3x faster (#307) (#319)
  • pathbbox: user-space box of the device bbox, as gs does (#288) (#317)
  • Capabilities: a unit on every @PARAM in the tag-migrated libraries (#195) (#314)
  • drychalk: chalk preset and chalkboard dressing, tuned against real chalk (#235) (#310)
  • drycrayon: crayon preset, crayon box and child-drawing motions (#239) (#309)
  • drykit: document why dkcatch keeps its first-seen cell list (#287) (#304)
  • walkpath: bound the source-segment count in wkmeasure's pass (#110) (#302)
  • claim.sh: no more zero-winner stale reclaims; inode identity check on steals (#281) (#301)
  • hatchkit: an optional /Mark path hook on hatch (#271) (#300)
  • strokeglyphs: skeleton glyphs for board math (#236, slice G1) (#279)
  • paintkit canvas S4: specimen, docs and dpi test for pkcanvas and /Touch (#228) (#285)
  • drykit D2: dkstroke and dkbatch, specimen (#234) (#286)
  • paintkit loading L5b: the loading specimen examples/paintkit_loading_demo.ps (#227) (#292)
  • hatchkit: hatch checks its options operand and values before binding them (#259) (#296)
  • strokepath: replace the current path with the stroke outline (#264) (#289)
  • Dict forall: deterministic order for non-name keys (#277) (#290)
  • paintkit loading L5: pkdab /Colors per dab; highlight and shadow colours on pkdab and pkoil (#226) (#284)
  • paintkit canvas S3: /Touch on pkfan, pkbroad and pkliner (#225) (#280)
  • drykit D1: dksurface and the swept-band oriented catch (#234) (#278)
  • paintkit loading L4: pkfan adopts the colour load (#224) (#275)
  • Per-issue notes fragments, push-keyed main CI, /work-issue refinements (#274)
  • scripts/identity_check.sh: shared cross-tree PNG byte-identity check for paintkit slices (#268)
  • design: drykit reference board and writeup for dry media (#233) (#265)
  • svg export: fix clip-def aliasing that made --svg nondeterministic and wrong (#258, #261) (#272)
  • paintkit loading L3: pkwet publishes its pass mix, puwet grades loaded colours (#223) (#269)
  • paintkit canvas S2: /Touch on pktrowel and pkdry (#222) (#267)
  • artkit: scatter/screct/scin check operands before binding them, so a malformed procedure is rejected not run (#123) (#262)
  • paintkit loading L2: pkbroad and pktrowel adopt /Colors, /ColorMix, /Light (#221) (#260)
  • pdf export: Flate-compress page content streams (clip-sharing premise of #244 measured wrong) (#256)
  • paintkit loading L1: pu- colour resolver, /Colours spelling guard, new unit (#218) (#255)
  • paintkit canvas S1: pkcanvas, the pj- weave sampler and pjcatch (#253)
  • design: paint loading (#183) and canvas surface (#182) (#207)
  • pdf export: consecutive elements with the same clip chain share one q/clip/Q group (#219) (#245)
  • paintkit: one meaning per key (/Offset, /Cover, /Scatter, /Lean) and units on every parameter (#141) (#197)
  • paintkit: document pkspray's fine-speck regime for clouds and mist (#178) (#198)
  • tests/jersey: parenthesize nonminimal_bool rewrite (#189) (#193)
  • paintkit: brush motion generators -- criss-cross, scumble, tap, pull, zig-zag (#184) (#192)
  • paintkit: directional pkwet for pulled-down reflections, lifted mist and sweeps (#181) (#190)
  • artkit: jit accepts real arguments (#177) (#188)
  • paintkit: pkdab, the foliage / dab brush (#117) (#175)
  • pkdry: reject cusps that bypass the deposit budget (#79) (#174)
  • PS-native self-checks: %%SelfTest + strict --lint (issue #95, Phase A) (#136)
  • paintkit: pkwet, wet interaction for soft layered paint (#113) (#138)
  • paintkit: pkliner, the liner/detail brush (issue #116) (#143)
  • pkoil: apply /Pressure to ridges and impasto edge layers (#171)
  • Make the jersey graphic read as a real school/college jersey (#167) (#168)
  • Add arched team-name and player-number jersey layout (#149) (#166)
  • fillkit: lift /Resolution /device cap to 4096 for 300-dpi plasma fills (#162) (#165)
  • Keepin' it Real: Chewy + Bagel Fat One fronts with plasma fill, gallery piece (#147) (#159)
  • Add Chewy and Bagel Fat One groovy display faces (issue #155) (#158)
  • GIMP-style fill algorithms: lib/fillkit.ps and psyletter fill treatments (#154) (#156)
  • Recreate the Keepin' it Real shirt as print-ready front and back artwork (#153)
  • Two-sided apparel graphic template with optional sleeves, and --transparent export (#146) (#152)
  • Add composition helpers for expressive headline and supporting type (#150)
  • Add lib/lettering.ps: psychedelic display lettering from outline text (#148)
  • paintkit: pkbroad, the broad flat brush (#140)
  • paintkit: pkfan, the fan-brush stroke primitive (#139)
  • paintkit: pktrowel, trowel / palette-knife strokes (#137)
  • lib/pagekit.ps: give the page templates a demo on the published site (#133)
  • lib/etching.ps: honor EXIF orientation (#129)
  • Add reusable woodcut, linocut, and engraving-style mark presets (#128)
  • Halftone gallery piece: Out of Register (issue #126) (#127)
  • Add paper, canvas, and print-surface textures (surfacekit) (#125)
  • Reusable halftone screens and misregistration offsets (issue #53) (#124)
  • Add density-driven stippling and point-shading primitives (issue #50) (#122)
  • Allow gh pr merge for autonomous work-issue merges
  • Add reusable hatching and cross-hatching primitives (issue #49) (#121)
  • Deterministic scatter and distribution primitives for artkit (#48) (#119)
  • Watercolor: setalpha/setblendmode and paintkit's pkwash/pkpaper (#47) (#109)
  • Doc-comment-driven capabilities catalog (generate src/capabilities.rs from lib/*.ps tags) (#97)
  • Document, demo, and give agents a skill for graph.ps/dataviz.ps (#103) (#105)
  • Add Mochi oil portrait and reference comparison (#101)
  • Reduce PS-library-only Rust/CI/Ghostscript coupling: architecture spike (#92) (#93)
  • Watercolor rendering architecture spike (issue #46) (#91)
  • Add stylized oil-paint brush preset (pkoil) (#45) (#86)
  • Add Fugitive Pigments: a poetry broadside for the paintkit brushes (#85)
  • Add pkspray: a spray-paint deposition brush (#83)
  • Add Plum Branch in Ink to the gallery (#82)
  • Add Flying White: Reeds at Dusk to the gallery (#81)
  • Add a dry-bristle brush with deterministic broken coverage (#78)
  • Add an angled-nib calligraphy brush preset (#77)
  • Add pressure-sensitive ribbon strokes to a new paintkit library (#76)
  • Add walkpath: a centerline path sampler for procedural brushes (#75)
  • Add a machine-readable catalog of agent-usable art capabilities (#74)
  • Add /issue-summary skill: script-backed dashboard of recent issue state (#73)
  • Gate merges on a perf/memory regression check (#69)
  • Surface CI test results on the PR and issue (#67)
  • Add --sweep-seed/--sweep frame sweeps and --contact-sheet compositing (#66)
  • Add axial/radial gradient (shading) fill support (#65)
  • Add noise and flow-field procedures to artkit (issue #19) (#64)
  • Add parameterized page templates (card, letter, certificate, invitation, poster) to artkit (#60)
  • Add a self-check/lint mode for agent-driven rendering (#59)
  • Add paragraph/flowing-text layout procedures to artkit (#58)
  • Add a photo-to-line-etching/sketch utility (issue #15) (#55)
  • Add a data-visualization chart library to artkit (issue #14) (#54)
  • Add 2D/3D function-graphing procedures to artkit (#38)
  • Add fractal / self-similar-geometry procedures to artkit (#37)
  • Add hyperbolic geometry (Poincare disk) to artkit + gallery piece (#32)
  • Add a procedural jittered-stroke Hangul face (jamo composition) (#30)
  • Cross-model Codex review in work-issue + DSC-scanner metadata bug fix (#27)
  • Add a tiling/tessellation library to artkit and gallery pieces using it (#28)
  • Give work-issue merge authority per SDLC.md's agent-full policy
  • Add reusable circular/curved-text placement procedures to artkit (#22)
  • Add sdlcify skill and apply it to this repo
  • Address advisor review: verify .ttc for real, document the grid ceiling
  • Stage 23: gallery/site catch-up, .ttc, a second Korean face
  • Stage 22: Korean, Japanese, and Thai fonts via Unicode-mode catalog faces
  • Adopt an issue -> feature branch -> PR development workflow

Gallery and site

  • gallery: Released in Part, the final pass: the release apparatus, an even hand, a new blind board (#596)
  • gallery: The Man from 2026, a never-released TOP SECRET memo (typewriter showcase) (#591)
  • gallery: Lecture 14 final pass with mathkit's braces, starred step and wandering columns (#543)
  • gallery: Evening Stream's meadow fill is lit by the same glow as its edges (#471) (#510)
  • gallery: Alpine Lake far mist banks dissolve sideways at their ends (#446) (#479)
  • gallery: Evening Stream's edges pull out the meadow's light with /Mass; near banks cut the stream in by region (#455) (#472)
  • site: a View source window on every gallery image (#461) (#470)
  • gallery: Released in Part, a typed and released 1962 memo, and a blind crop grid against real scans (#215) (#469)
  • gallery: Evening Stream's cloud light, softer: no core rings, no dark contour (#433) (#463)
  • site: generated gallery from a manifest, with per-piece pages (#251) (#458)
  • gallery: Alpine Lake's far mist as banks of haze (#407) (#445)
  • gallery: Evening Stream's cloud light from pkscumblein /Light, not a shifted copy (#384) (#434)
  • gallery: Alpine Lake's shadow planes laid with pktrowelplane (#361) (#436)
  • site: Learn PostScript -- a cited history and a runnable tutorial (#252) (#430)
  • gallery: Evening Stream's mass edges brushed with pkbrushedge (#382) (#427)
  • site: new landing page, shared navigation and layout, responsive style (#250) (#424)
  • gallery: Alpine Lake polish: mist foot as haze, softer reflected snow, glints not rules (#206) (#408)
  • gallery: Evening Stream, the second wet-on-wet landscape (#187) (#348)
  • gallery: art student's charcoal portrait of Lincoln after Berger, 1864 (#242) (#343)
  • gallery: My Family and Our House, a young child's crayon drawing (#240) (#336)
  • gallery: Lecture 14, a professor's chalkboard deriving Euler's formula (#238) (#353)
  • gallery: re-render hundred_lines and varsity_backs stills (#170 stroke flattening) (#349) (#352)
  • gallery: Alpine Lake -- pull the reflection down with directional pkwet; pkcrisscross sky (#191) (#203)
  • gallery: Alpine Lake, the wet-on-wet landscape specimen (#118) (#176)

Documentation

  • docs: document paintkit in psart; describe capabilities parameters generically (#99) (#545)
  • docs: share the GitHub-URL-to-repo-path rule between the link checkers (#429) (#486)
  • docs: rebuild drycharcoal_refs_compare.png with a committed script (#418) (#482)
  • docs: move dev and historical docs out of the repo root, update every reference (#249) (#465)
  • docs: state the handwriting design intent (legible but a little sloppy) (#443) (#453)
  • docs: slim README to a front door; archive the stage log; guides; Markdown link check (#248) (#428)
  • docs: audit and proposed structure plan for the docs and site (#247) (#337)
  • docs: landscape techniques cookbook for artist agents (#186) (#368)

Build, CI and release

  • ci: pin plugin.yml actions to commit SHAs (fixes release-policy on main) (#643)
  • release: tag-driven publishing pipeline, resumable stages, release environment (#602) (#639)
  • tests: tolerate BrokenPipe when feeding stdin to a pscat that exits early (#630) (#640)
  • release: crates.io crate shape — window feature, rlib-only, documented API, packaging checks (#565) (#629)
  • release: downloadable font packs, pscat fonts, release-fonts train (#599) (#620)
  • ci: Linux/Windows tests, MSRV, packaging dry run, cargo-deny, licence checks (#601) (#612)
  • release: port handwrite/typewrite/photo_etch to pscat subcommands (#600) (#618)
  • release: resource resolver + embedded lib/, no checkout heuristics in release builds (#598) (#609)
  • release: minimum public docs: SECURITY, STABILITY, CONTRIBUTING, CODEOWNERS (#603) (#607)
  • tests: scratch paths unique per call and per process, so parallel test runs don't clobber each other (#490)
  • tests: raise the remaining 2 s CPU budgets to 5 s (#414)
  • work-issue: close without a PR, prototype and timing guidance, CI retry, green no-merge hand-over (#331) (#358)
  • tests: CPU-time budgets (thread clock, best of 3) replace wall-clock render budgets (#334)
  • work-issue round 7: no pattern kills, identity_check --loader, settling, rebase-late, won't-change path (#303) (#305)
  • work-issue: open-PR claim scan extracts full issue numbers (#293) (#294)
  • work-issue round 6: claim and heartbeat as scripts, race tests, Closes #N fallback (#276) (#282)
  • SDLC: record require-up-to-date=false in SDLC.md/sdlcify, drop the BEHIND loop from work-issue (#266)
  • work-issue: round-3 fixes -- CI pass/fail from statusCheckRollup, merge/cleanup ordering, resume paths, -D warnings in gate (#208) (#243)
  • ci: run cargo test under an optimized profile that keeps debug-assertions (#204) (#217)
  • work-issue: CI-wait recipe, pending-CI hand-back rule, hard plan-review gate (#199) (#205)
  • work-issue: 250-line core plus reference files; clear in-review on merge (#194, #151) (#196)
  • work-issue: pin Codex review to gpt-6.1-sol; note stale-login broker restart (#163) (#164)
  • work-issue: per-finding review trail + summary on the issue before merge; stale Codex broker pitfall (#160) (#161)
  • work-issue: pin the Codex review model to gpt-6-sol explicitly (#157)
  • work-issue: document the run_in_background + ScheduleWakeup Codex review hazard (#130)
  • work-issue: make the staleness check an atomic ownership claim (#35) (#71)
  • work-issue skill: require a visible demo (gallery/site/playground), not just an examples/ file (#62)

Each archive carries the licences (LICENSE-MIT, LICENSE-APACHE, LICENSE-OFL), THIRD_PARTY_NOTICES.md and the dependency notices (THIRD_PARTY_LICENSES.html). SHA256SUMS has the SHA-256 of every archive; release-manifest.json records the commit they were built from. Install guide: https://github.com/jeromebanks/postscript_interpreter/blob/main/docs/guides/getting-started.md