Repository navigation
distill: perforce -Mj mirror, unity OpenSSH/schtasks and Hub 3.x learnings - #11
Open
butterstack[bot] wants to merge 4 commits into
Open
butterstack[bot] wants to merge 4 commits into
butterstack[bot] wants to merge 4 commits into
Conversation
The private repo's agent instructions for perforce learned that tagged-JSON mode (p4 -Mj) writes every record, including errors, to stdout and leaves stderr empty - so an agent that classifies failures by reading stderr gets nothing but a bare exit status. Mirrors that guidance into the public perforce agent instructions verbatim, including the parse recipe, the two traps in the JSON stream, and a new row in the failure-class table for the "exit status N and nothing else" symptom. This is an instruction-file change (agents/perforce.md), not a LEARNINGS.md entry, so it is mirrored per DISTILLING.md section (f) rather than compressed: no step or table row was dropped. The private source names an internal connector by name; this generalizes it to "a real webhook-ingestion connector," consistent with how the same validation story is already described elsewhere in this file's LEARNINGS.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…learnings The private repo validated the fix for the OpenSSH process-tree-kill trap already noted in this file: a one-shot scheduled task launched via schtasks runs outside the SSH session's process tree and survives it, verified end to end with a cold import and a WebGL build on Unity 6000.3.22f1. Also records the two mechanisms that look like fixes and are not (cmd start hangs the session, Start-Process without -Wait dies at session exit anyway), Hub 3.53's headless install behavior (CDN rate cap, per-component progress text that isn't proof of a finished install, real cold-import/build timings), and the narrow provider list on Hub's "Add project from repository" flow. Mirrored (not compressed, per DISTILLING.md section f): unity-build SKILL.md gains section 8 with the wrapper/schtasks recipe verbatim, and agents/unity.md gains the matching symptom-table row. The private source's numbered LEARNINGS.md cross-reference (B8/B10/B12) is rewritten to the public file's unnumbered convention (LEARNINGS.md paragraph B), consistent with how unity-pipeline/SKILL.md already references this file. Sanitization: the private source names the rig `beast` in the Hub-install example; genericized to "a wired gigabit test machine," consistent with how the existing "primary test rig" bullet in this file already anonymizes the same machine. Final grep sweep on the changed lines: zero hits. No secrets or credential values were present in the source material. Excluded from this pass: the private repo also added two entirely new plugins, teamcity and buildkite, since the last distillation. Per the rationale already recorded on this PR, bringing a new plugin into this repo needs more than the skills/agents/commands/LEARNINGS files this job is scoped to (plugin.json, hooks.json, the guard script, README, and marketplace registration all need to land together, plus a security review of the guard scripts) - recommend a separate, deliberate distillation pass for those once reviewed. Line counts: unity/LEARNINGS.md 170 -> 199, unity/agents/unity.md 231 -> 232, unity/skills/unity-build/SKILL.md 260 -> 306. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…orker, and workspace/firewall learnings The private repo validated three new findings since the last distillation pass landed on this branch: standing up a deliberately empty Helix Core replacement server in a container (change-counter collisions with existing backend records, daemon-uid file ownership, a trust entry keyed by server address, and a setup script that can't read `*_FILE` secrets under an environment-stripping runner), moving an Unreal build agent from a home PC to a cloud Windows worker (streaming the engine install as `tar.xz`, `-warp` for GPU-less screenshots, writable-engine-tree permissions, and the .NET Framework SDK/VS Build Tools modify-mode trap), and porting scripts into a Lore repo plus standing up a Lore server on a cloud host (the `--scan` gap for externally-copied files, a firewall-reachability false negative, and GitHub-mirror lag). Excluded two new private-repo plugins, teamcity and buildkite, consistent with the rationale already on this PR: a new plugin needs its full scaffolding (plugin.json, hooks, guard script, README, marketplace registration, security review) to land together, not a partial copy through the routine learnings pass. Rewrote one dangling cross-reference: the private unreal entry pointed at "the Buildkite learnings" for keeping credentials out of the bundle; since buildkite isn't published here yet, that became a self-contained instruction instead. Line counts: lore/LEARNINGS.md 44 -> 56, perforce/LEARNINGS.md 87 -> 108, unreal/LEARNINGS.md 179 -> 204. Final grep sweep on the diff: zero unexplained hits. No secrets or credential values were present in the source material. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ings The private repo added a 2026-09-24 LEARNINGS.md entry from mirroring a 107-commit git repository into Lore across two branches and relaying pushes from a live loreserver 0.9.0 via the notification stream, plus two short 2026-09-25 addenda on push recovery and using the revision signature instead of the revision number as a build key. Distilled five of the entry's eight findings (per-branch revision numbering and the matching per-branch relay-state fix, resolving a push notification's branch id, lore sync versus branch reset for the local pointer, the no-import/no-author-override mirror recipe, and the empty-commit-produces-no- revision gap) plus both addenda. Cut the relay-staleness and blank-submitter findings: both are real but narrower to this relay's own architecture and less load-bearing than the other five, which matches the earlier pass's compression precedent on this file. The source commit also touched buildkite/LEARNINGS.md, which is excluded for the same reason already recorded on this PR: buildkite is not a published plugin in this repo yet. Sanitization: no internal identifiers, personal names, or hostnames were present in the source material; the private entry's reference to the mirrored repo as an "Unreal game repository" was generalized to "git repository" since the engine detail doesn't change the lesson. Grep sweep on the file: zero hits. No secrets or credential values were present in the source material. Line count: lore/LEARNINGS.md 56 -> 100. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pass covers everything new in the private working repo's in-scope files since the last distillation (perforce, godot, jenkins, lore, unity, unreal all checked; teamcity and buildkite are new plugins, see the note at the bottom).
Mirrored (not compressed, per DISTILLING.md section f):
perforce/agents/perforce.mdgained the-Mjstdout-not-stderr instruction - in tagged-JSON mode p4 writes every record, error records included, to stdout and leaves stderr empty, so an agent reading stderr alone to classify a failure gets nothing but a bare exit status. Carried across the parse recipe (data field of the first record at severity >= 3), the two traps in that stream (successful records can precede the error record; severity is a number in some p4 versions and a quoted string in others), and the new failure-class table row for the "exit status N and nothing else" symptom. Line count: 219 -> 238 lines.At the time of that first commit, no LEARNINGS.md or NOTES.md entries needed distilling - every plugin's private LEARNINGS.md/NOTES.md was checked against what was already reflected in the public files and everything then in the private repo was either already distilled or, for jenkins, a reverse-seed copy of content that originated in this repo.
Sanitization (first commit): the private source named an internal connector by name; genericized to "a real webhook-ingestion connector," matching how the same underlying validation story (p4 trigger -> webhook -> changelist ingestion) is already phrased elsewhere in this plugin's LEARNINGS.md. Final grep sweep on the changed file: one hit, pre-existing and unrelated to this change (line 238, "Internal - don't surface these in user-facing help," describing an undocumented skill note, not a leaked internal identifier). No secrets or credential values were present in the source material.
Update: unity schtasks/OpenSSH and Hub 3.x learnings
A later private-repo commit (landed 2026-09-23, after this PR was first opened) validated the fix for the Windows-OpenSSH process-tree-kill trap this file already flagged, and added Hub 3.x headless-install findings. Distilled into
unity/LEARNINGS.md: the working fix (a one-shotschtasks-launched scheduled task, verified end to end with a cold import and a WebGL build on Unity 6000.3.22f1), the two mechanisms that look like fixes and are not (cmd /c starthangs the SSH session;Start-Processwithout-Waitdies at session exit anyway), a-logFile -pipe-close trap, Hub 3.53's headless-install behavior (CDN rate cap, per-component progress text that is not proof of a finished install, real cold-import/build timings versus the "up to an hour" folklore), and the narrow three-provider list on Hub's "Add project from repository" flow. Line count: 170 -> 199 lines.Mirrored (not compressed, per DISTILLING.md section f):
unity/skills/unity-build/SKILL.mdgained section 8 with the wrapper/schtasks recipe verbatim (260 -> 306 lines), andunity/agents/unity.mdgained the matching symptom-table row (231 -> 232 lines). The private source's numbered LEARNINGS.md cross-reference (its B8/B10/B12) was rewritten to this repo's unnumbered convention (LEARNINGS.mdparagraph B), consistent with howunity-pipeline/SKILL.mdalready references this file.Sanitization (this commit): the private source names the test rig
beastin the Hub-install example; genericized to "a wired gigabit test machine," consistent with how the existing "primary test rig" bullet in this file already anonymizes the same machine. Final grep sweep on the added lines: zero hits. No secrets or credential values were present in the source material.Excluded from this pass: the private repo also added two entirely new plugins,
teamcityandbuildkite(agents, commands, and SKILL.md files plus plugin.json/hooks/guard scripts/README for each - roughly 1,600 lines total). Bringing a new plugin into this repo needs more than the skills/agents/commands files this job is scoped to (plugin.json, hooks.json, the guard script, README, and marketplace registration all need to land together for the plugin to actually work and passscripts/lint-plugins.sh), and the existing precedent in this repo (godot's v0.1.0 landed as its own dedicated distillation PR, #4, separate from the routine weekly learnings cadence) treats a new-plugin launch as a distinct, larger action rather than something a scheduled pass should do partially and silently. Recommend a separate, deliberate distillation pass for teamcity and buildkite once someone reviews the full plugin content (including the guard scripts, which need the same security review godot's and perforce's got before publication).Update: empty-replacement-server, cloud Windows worker, and Lore workspace/firewall learnings
A later private-repo push (landed 2026-10-02/03, after the last update above) added LEARNINGS.md entries to perforce, unreal, lore, buildkite, and teamcity. The buildkite and teamcity entries are excluded from this commit for the same new-plugin reason already recorded above; this commit distills the remaining three.
Distilled into
perforce/LEARNINGS.md(87 -> 108 lines): standing up a deliberately empty Helix Core replacement server in a container while CI and an observability backend still held records from the old one. Four load-bearing findings, all kept at near-full detail since each is a distinct, concrete trap: an empty server restarts change numbers at 1 and collides with anything keyed by change number (fix: raise the counter past the old maximum before the first submit), a file the daemon reads must be owned by the daemon's uid rather than root, the trust entry is keyed by the server's resolved address so it has to be regenerated per host, and a setup script that reads passwords from*_FILEenvironment variables breaks under a runner that strips the environment (AWS SSM Run Command is one) - fixed by prependingexportlines to a throwaway copy of the script rather than ever passing secrets as arguments.Distilled into
unreal/LEARNINGS.md(179 -> 204 lines), as item 16 under section B: moving an Unreal build agent from an always-on home PC to a cloud Windows worker. Kept the strongest four findings (streaming the ~10 GB engine install as a pipedtar | xzinstead of reinstalling per worker,-warpfor offscreen screenshots on a GPU-less host plus polling instead of sleeping for the output files, granting the agent user write access to the engine tree before the cook'sUnauthorizedAccessExceptionshows up, and the .NET Framework SDK / VS Build Tools modify-mode trap for UnrealBuildTool) and cut two narrower, more generic ones (gating the GPU driver install on hardware presence; a standalone callout for the screenshot poll, folded into the-warpbullet instead).Distilled into
lore/LEARNINGS.md(44 -> 56 lines): porting scripts into a Lore repo and standing up a Lore server on a cloud host - the--scanflag is also needed for files copied in from outside the workspace (not just drifted edits to tracked files), a TCP test from an allowlisted address proves a firewalled port is reachable from that address only, and the GitHub mirror of a Lore repo can lag the source of truth.Sanitization (this commit): the private unreal entry pointed to "the Buildkite learnings" for keeping credentials out of the engine bundle; since buildkite isn't published in this repo yet, that cross-reference was rewritten as a self-contained instruction ("keep credentials out of the bundle entirely") instead of left dangling. No other internal identifiers, personal names, or hostnames were present in the three source entries. Final grep sweep on the diff: zero hits. No secrets or credential values were present in the source material.
Compression: lore's new entry cut 18 private lines to 12 public lines (33%) and unreal's cut 40 to 25 (37.5%), both within the 30-50% target. Perforce's new entry cut 26 to 21 (19%), short of the target - each of its four findings is already stated almost entirely in technical specifics (exact flags, exact ownership/uid behavior, exact command forms) with very little narration to trim, and DISTILLING.md section (b) is explicit that technical specifics are never cut for compression's sake; the entry was tightened wherever prose allowed without dropping any of the four findings or their specifics.
Update: git-to-Lore mirror, push-relay, and build-key learnings
A later private-repo push (landed 2026-10-19, after the last update above) added a 2026-09-24 LEARNINGS.md entry to lore (and a same-day entry to buildkite, excluded for the new-plugin reason already recorded above) plus two short 2026-09-25 addenda to lore on push recovery and build keys.
Distilled into
lore/LEARNINGS.md(56 -> 100 lines): mirroring a 107-commit git repository into Lore across two branches and relaying pushes from a live loreserver 0.9.0 via the notification stream. Kept five of the private entry's eight findings as the strongest, most generalizable ones: revision numbers are per branch so relay state has to be kept per branch too, a push notification's branch field is a 32-hex id that needs resolving vialore branch list,lore syncmoves the working copy but not the branch's local pointer (lore branch resetdoes), there is no import command and no author/date override onlore commit(with the working git-archive mirror recipe), and a git commit with no tree change produces no Lore revision at all. Cut two narrower, more relay-architecture-specific findings (a relay's local clone going stale behind the notification stream, and blank submitters under an auth-off server) that are real but don't generalize as cleanly as the other five. Also carried both 2026-09-25 addenda (push-refused recovery steps, and using the 64-hex revision signature rather than the per-branch revision number as a build key) with only light tightening, since they were already short and specific.Compression note: measured by raw line count the new entry looks like it grew (28 private lines to 44 public lines) because the private source's 2026-09-24 entry is written as eight very long unwrapped lines, one per bullet, while this file (and the rest of this repo) wraps prose at roughly 85-90 characters; raw line count isn't a fair comparator here. By word count, the main entry went from 884 words across 8 findings to 288 words across 5 findings (a 67% cut), beyond the usual 30-50% target because three distinct findings were cut outright rather than tightened in place - consistent with DISTILLING.md section (b)'s guidance to keep the strongest stories and cut narrower ones, rather than pad to hit a percentage. The two addenda were already tight and changed only 136 to 127 words (7%).
Sanitization (this commit): no internal identifiers, personal names, or hostnames were present in the source material. The private entry described the mirrored repository as an "Unreal game repository"; generalized to "git repository" since the engine detail doesn't change the lesson and isn't needed to understand it. Final grep sweep on the diff: zero hits. No secrets or credential values were present in the source material.
🤖 Generated with Claude Code