Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/atlas/assets/seed/catalog.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"citations":[{"path":"src/FS.GG.SDD.Commands/CommandWorkflow/OwnerSkillRefresh.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"c239e50e0a556bc602b459dc9f03373cb4de831bde3bfc8979778059cecdf112"},{"path":"tests/FS.GG.SDD.Commands.Tests/OwnerSkillRefreshTests.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"79010d02474e5e37c567012fd39c0beddd4c3de0acb6c83ac0518b361a2c5d97"}],"conflictsWith":[],"id":"sdd/legacy-version-bound-equal-version-strings-prove-nothing","kind":"lesson","recordedAt":"2026-11-02T05:53:41Z","repository":"FS-GG/FS.GG.SDD","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed in review of FS.GG.SDD `upgrade` owner-skill replacement (FS-GG/FS.GG.SDD#1155, merged as #1158); the rule below is the one merged in FS-GG/FS.GG.SDD#1161.\n\n**The rule as first merged (#1158).** A skill with no recorded owner-package version (a record that predates version tracking) was replaced when the running CLI was not older than the CLI that last wrote the workspace. Equal was allowed on purpose, so the run that finishes an interrupted refresh, or one after the user reverted an edit, is not stranded.\n\n**Why it was wrong.** An equal version string proves nothing: two builds can share it. The reviewer ran a 2.5.4 dev build carrying FS.GG.Drivers 0.97.1 against a workspace a 2.5.4 had produced with the 0.98 pack, and it replaced an untouched 0.98 skill with the older pack. A bound on the CLI's version says nothing about the PACK it carries.\n\n**The merged rule (#1161).** For a skill with no recorded version both bounds must hold. (1) A channel floor: the pack is not below the highest version the record already holds for that channel; this is a fact about the workspace and also catches the dev build. (2) A writer bound: the CLI is strictly newer than the CLI that last wrote the workspace (`upgradedBy`, recorded only by an upgrade in which every file landed, else the producing CLI), or equal to it only when `upgradedBy` names this very CLI, so a complete run of this release already vouched for the workspace and this run can finish what an edit, a link or a read-only directory blocked. A partial run does not record `upgradedBy`, or it would bar its own completion. A malformed version entry is kept and holds, never silently dropped. Measured: the same dev build now does nothing to that workspace and its `work-board` is byte-identical before and after.\n\n**Scope.** Owner-sourced skills in `upgrade`. Package versions are compared by numeric core; a prerelease suffix does not order. The cited source is the merged state at 4b54aa17; verify the current rule against OwnerSkillRefresh.fs on main.","supersedes":[],"tags":["sdd","upgrade","downgrade","version","provenance","dev-build","lesson"],"title":"A never-downgrade bound that treats an equal CLI version as safe is defeated by a dev build with an older pack"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"citations":[{"path":"src/FS.GG.SDD.Commands/CommandWorkflow/HandlersUpgrade.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"6a47e7272c00b3bd9bd55c4f46e1e8765ebb469c3ee6b986162a9e7d14e291dc"}],"conflictsWith":[],"id":"sdd/upgrade-apply-loop-stalls-when-effect-set-grows","kind":"lesson","recordedAt":"2026-11-02T05:53:41Z","repository":"FS-GG/FS.GG.SDD","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed in FS.GG.SDD `upgrade` (FS-GG/FS.GG.SDD#1156, merged as #1157).\n\n**The defect.** The apply step recomputes its effect list every tick. Its decision was: all interpreted means resolve; any planned means wait; otherwise emit everything. When the earlier effects are interpreted the list can GROW: the owner-guidance merge into AGENTS.md and CLAUDE.md can only be planned once the owner skills it requires are installed, which is a new observation. The two new writes are unplanned, but the step sees \"something is planned\" and waits for them forever. The loop goes idle and the run ends with outcome succeeded and no upgrade summary at all. It reproduced on the unmodified build as soon as the delivered payload declared owner guidance, and no test had covered a workspace with agent configuration present and the payload files absent.\n\n**The fix.** When some effects are planned, emit exactly the effects not yet planned and wait only when there are none. Any reconcile loop that recomputes its plan each tick needs the same shape: compare against what has already been emitted, never against whether anything has.\n\n**A second cost on the same loop (FS-GG/FS.GG.SDD#1161).** The driver folds one update per interpreted result, and each update re-derived the whole plan (embedded owner packs, every skill body). With the atlas skill present that is hundreds of milliseconds, so a refresh of several hundred files processed about 1.2 results per second and a second run was still going after two minutes when killed. The step now returns at once while a write, removal or mode change it already emitted is in flight and derives the plan again after the last result. Waiting is exactly what the full recomputation concluded, so behavior is unchanged and only the cost goes.\n\n**Related.** Measured while the same bump made `doctor` 36x slower (O(n) effect-log lookups per question); see sdd/driver-pin-bump-repins-goldens-and-lockfiles.\n\n**Scope.** FS.GG.SDD `HandlersUpgrade.applyStage`; the same pattern is worth checking in other handlers that emit a recomputed effect list.","supersedes":[],"tags":["sdd","upgrade","effects","reconcile","loop","stall","lesson"],"title":"An upgrade apply step that waits while anything is planned stalls forever when the effect set grows after the first effects run"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"citations":[{"path":"docs/reference/scaffold-driver-materialization.md","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"2ff9cb08c916dca498147f6c3dbc238241bf85cb34bfcde8bad804c645718233"},{"path":"tests/FS.GG.SDD.Commands.Tests/DriverSkillsTests.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"0d44cb0c0b2fb48743b820b527f2d5de01965012b96b6ddc53372fa7e90c509c"},{"path":"src/FS.GG.SDD.Commands/CommandWorkflow/Foundation.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"e02fdce2a363fb2de504230eef3c9ab3a0da2bea7957ed3710b51a6639b78b1d"}],"conflictsWith":[],"id":"sdd/driver-pin-bump-repins-goldens-and-lockfiles","kind":"lesson","recordedAt":"2026-11-02T05:53:41Z","repository":"FS-GG/FS.GG.SDD","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed moving FS.GG.Drivers 0.98.0 to 0.114.3 in FS.GG.SDD (FS-GG/FS.GG.SDD#1156, merged as #1157).\n\n**A pin bump is not one line.** The version in Directory.Packages.local.props is embedded into the CLI at build time, so the same change must (a) regenerate the seven committed packages.lock.json files with `dotnet restore --force-evaluate` under the pinned SDK, (b) re-pin the embedded-skill digest goldens in DriverSkillsTests, including the always-on skill set and each skill's file count, and (c) update fixtures that model a coherent scaffold, which must now carry the agent configuration and owner guidance the delivered payload declares, and the skill-body token pins that follow the package's wording. Earlier Renovate bumps (#1072, #1077, #1101) were closed because the bot's PR does none of this, so the update stays a reviewed PR.\n\n**It exposes defects that were latent while the pack was small.** The atlas driver skill alone ships 509 files, two roots. Three things followed: effect-log lookups that re-derived effectKey per logged effect were O(n) per question, taking `doctor` over a fresh scaffold from 0.3 s to 11.7 s (fixed by building the key set once per immutable list); `upgrade` stalled with no summary when its effect set grew mid-run (see sdd/upgrade-apply-loop-stalls-when-effect-set-grows); and a pre-existing workspace could not upgrade at all until owner skills were replaced as a unit (FS-GG/FS.GG.SDD#1155).\n\n**Staleness.** The pin had trailed its feed by 16 versions, so the atlas skill was absent from every workspace. Policy: the Drivers pin and each FS.GG.*.Skills pin may trail the feed by at most five stable versions, enforced in the release workflow's resolve-versions job by scripts/check-skills-pin-staleness.py, not as a PR gate, because the feed moves independently of a PR.\n\n**Scope.** Measured with SDK 10.0.403. Source delivery only; no release or installed-receiver acceptance is claimed.","supersedes":[],"tags":["sdd","drivers","pin","renovate","lockfile","golden","staleness","performance","lesson"],"title":"Bumping the FS.GG.Drivers pin in FS.GG.SDD also re-pins goldens and seven lockfiles, and exposes latent engine defects"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"citations":[{"path":"src/FS.GG.SDD.Commands/CommandWorkflow/HandlersUpgrade.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"6a47e7272c00b3bd9bd55c4f46e1e8765ebb469c3ee6b986162a9e7d14e291dc"},{"path":"src/FS.GG.SDD.Commands/CommandWorkflow/OwnerSkillRefresh.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"c239e50e0a556bc602b459dc9f03373cb4de831bde3bfc8979778059cecdf112"},{"path":"tests/FS.GG.SDD.Commands.Tests/OwnerSkillRefreshTests.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"79010d02474e5e37c567012fd39c0beddd4c3de0acb6c83ac0518b361a2c5d97"}],"conflictsWith":[],"id":"sdd/provenance-must-record-only-landed-writes","kind":"lesson","recordedAt":"2026-11-02T05:53:41Z","repository":"FS-GG/FS.GG.SDD","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed in review of FS.GG.SDD `upgrade` owner-skill replacement (FS-GG/FS.GG.SDD#1155, merged as #1158); the blocking defect was found by the independent reviewer, not by the author's tests.\n\n**The defect.** The provenance write was batched with the skill writes and did not depend on them. A read-only `references` directory partway through a skill let some writes fail while the provenance still recorded the new pack's digests and version for files that were never written. The next `upgrade` then compared a record that lied against the disk and failed permanently with exit 2, which also blocked the re-seed of every other skill. A write refused by the write-edge digest re-check produced the same wrong record.\n\n**The rule.** Emit the provenance write only after every file write and removal of the step has been interpreted; claim only what landed; record a replaced skill all-or-nothing (rows, dropped rows, package version, manifest digest) so one failed file leaves the whole skill's record as it was. Make the next run able to finish: a file already at the PACK's digest counts as unedited, and a desired file whose record is stale is a target even when the disk already matches, so a partial or killed run, including one whose files were all written but never recorded, completes on re-run. Name the CLI as the workspace's last writer only when every file landed, otherwise a partial run bars its own completion.\n\n**Evidence.** The reviewer killed the process at seven points and every one healed; the tests cover a read-only directory mid-skill, a killed run, a fully written but unrecorded skill, and a refused write.\n\n**Scope.** Owner-sourced skills (drivers and owner product skills) in `upgrade`; legacy scaffold provenance only.","supersedes":[],"tags":["sdd","upgrade","provenance","atomicity","crash-safety","lesson"],"title":"A provenance record is a claim about files: write it after the files, and record only what landed"}
2 changes: 1 addition & 1 deletion .claude/skills/atlas/assets/seed/catalog.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"citations":[{"path":"src/FS.GG.SDD.Commands/CommandWorkflow/OwnerSkillRefresh.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"c239e50e0a556bc602b459dc9f03373cb4de831bde3bfc8979778059cecdf112"},{"path":"tests/FS.GG.SDD.Commands.Tests/OwnerSkillRefreshTests.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"79010d02474e5e37c567012fd39c0beddd4c3de0acb6c83ac0518b361a2c5d97"}],"conflictsWith":[],"id":"sdd/legacy-version-bound-equal-version-strings-prove-nothing","kind":"lesson","recordedAt":"2026-11-02T05:53:41Z","repository":"FS-GG/FS.GG.SDD","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed in review of FS.GG.SDD `upgrade` owner-skill replacement (FS-GG/FS.GG.SDD#1155, merged as #1158); the rule below is the one merged in FS-GG/FS.GG.SDD#1161.\n\n**The rule as first merged (#1158).** A skill with no recorded owner-package version (a record that predates version tracking) was replaced when the running CLI was not older than the CLI that last wrote the workspace. Equal was allowed on purpose, so the run that finishes an interrupted refresh, or one after the user reverted an edit, is not stranded.\n\n**Why it was wrong.** An equal version string proves nothing: two builds can share it. The reviewer ran a 2.5.4 dev build carrying FS.GG.Drivers 0.97.1 against a workspace a 2.5.4 had produced with the 0.98 pack, and it replaced an untouched 0.98 skill with the older pack. A bound on the CLI's version says nothing about the PACK it carries.\n\n**The merged rule (#1161).** For a skill with no recorded version both bounds must hold. (1) A channel floor: the pack is not below the highest version the record already holds for that channel; this is a fact about the workspace and also catches the dev build. (2) A writer bound: the CLI is strictly newer than the CLI that last wrote the workspace (`upgradedBy`, recorded only by an upgrade in which every file landed, else the producing CLI), or equal to it only when `upgradedBy` names this very CLI, so a complete run of this release already vouched for the workspace and this run can finish what an edit, a link or a read-only directory blocked. A partial run does not record `upgradedBy`, or it would bar its own completion. A malformed version entry is kept and holds, never silently dropped. Measured: the same dev build now does nothing to that workspace and its `work-board` is byte-identical before and after.\n\n**Scope.** Owner-sourced skills in `upgrade`. Package versions are compared by numeric core; a prerelease suffix does not order. The cited source is the merged state at 4b54aa17; verify the current rule against OwnerSkillRefresh.fs on main.","supersedes":[],"tags":["sdd","upgrade","downgrade","version","provenance","dev-build","lesson"],"title":"A never-downgrade bound that treats an equal CLI version as safe is defeated by a dev build with an older pack"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"citations":[{"path":"src/FS.GG.SDD.Commands/CommandWorkflow/HandlersUpgrade.fs","repository":"FS-GG/FS.GG.SDD","revision":"4b54aa1710c90a6349b43af4e06ec931bb78e061","sha256":"6a47e7272c00b3bd9bd55c4f46e1e8765ebb469c3ee6b986162a9e7d14e291dc"}],"conflictsWith":[],"id":"sdd/upgrade-apply-loop-stalls-when-effect-set-grows","kind":"lesson","recordedAt":"2026-11-02T05:53:41Z","repository":"FS-GG/FS.GG.SDD","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed in FS.GG.SDD `upgrade` (FS-GG/FS.GG.SDD#1156, merged as #1157).\n\n**The defect.** The apply step recomputes its effect list every tick. Its decision was: all interpreted means resolve; any planned means wait; otherwise emit everything. When the earlier effects are interpreted the list can GROW: the owner-guidance merge into AGENTS.md and CLAUDE.md can only be planned once the owner skills it requires are installed, which is a new observation. The two new writes are unplanned, but the step sees \"something is planned\" and waits for them forever. The loop goes idle and the run ends with outcome succeeded and no upgrade summary at all. It reproduced on the unmodified build as soon as the delivered payload declared owner guidance, and no test had covered a workspace with agent configuration present and the payload files absent.\n\n**The fix.** When some effects are planned, emit exactly the effects not yet planned and wait only when there are none. Any reconcile loop that recomputes its plan each tick needs the same shape: compare against what has already been emitted, never against whether anything has.\n\n**A second cost on the same loop (FS-GG/FS.GG.SDD#1161).** The driver folds one update per interpreted result, and each update re-derived the whole plan (embedded owner packs, every skill body). With the atlas skill present that is hundreds of milliseconds, so a refresh of several hundred files processed about 1.2 results per second and a second run was still going after two minutes when killed. The step now returns at once while a write, removal or mode change it already emitted is in flight and derives the plan again after the last result. Waiting is exactly what the full recomputation concluded, so behavior is unchanged and only the cost goes.\n\n**Related.** Measured while the same bump made `doctor` 36x slower (O(n) effect-log lookups per question); see sdd/driver-pin-bump-repins-goldens-and-lockfiles.\n\n**Scope.** FS.GG.SDD `HandlersUpgrade.applyStage`; the same pattern is worth checking in other handlers that emit a recomputed effect list.","supersedes":[],"tags":["sdd","upgrade","effects","reconcile","loop","stall","lesson"],"title":"An upgrade apply step that waits while anything is planned stalls forever when the effect set grows after the first effects run"}
Loading
Loading