Codex audit (Q4) flagged that the mutation gate landed in slice 3a but
the test suite only verified the three earlier gates. Add coverage:
- agree-path: mutation-gate fires with outcome=fail, rejectedCount=1,
resolvedCount=0 (the test fixture has no real ledger entry for the
decision id, so markResolved rejects it — the gate correctly surfaces
the partial failure)
- disagree-path: mutation-gate does NOT fire (apply phase skipped)
Pins the 4-gate contract end-to-end. Suite: 4/4 in this file.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add profile-aware scaffold system so SF does not lay down irrelevant
templates in infra/ops/docs repos.
## What ships
Phase 1 — data model
- scaffold-versioning.js: add 'disabled' to VALID_STATES; readScaffoldManifest
returns profile field; recordScaffoldApply preserves manifest.profile (fixes
roundtrip bug where profile was stripped on every write).
- scaffold-constants.js: PROFILES (app/library/infra/docs/minimal as Set<string>)
and PROFILE_NAMES exports.
Phase 2 — profile-aware drift detection
- scaffold-drift.js: disabled bucket in emptyCounts, resolveActiveProfileSet
integration, profile param on detectScaffoldDrift/migrateLegacyScaffold.
- doc-checker.js: filter to active profile, skip disabled-state files.
Phase 3 — auto-detection on first run
- scaffold-profiles.js: detectRepoProfile() heuristics (nix→infra,
terraform→infra, react→app, node-no-ui→library, docs-only→docs, else→app).
- agentic-docs-scaffold.js: reads profile from manifest, auto-detects on first
run, persists to manifest, filters SCAFFOLD_FILES to active profile.
Phase 4 — migrate command
- commands-scaffold-migrate.js: sf scaffold migrate --profile <name>
Re-enables pending files entering the new profile; stamps state=disabled
(or prunes with --prune) files leaving it; warns on editing/completed files.
- commands/handlers/ops.js, commands/catalog.js: registered and tab-completed.
Phase 5 — custom profiles + PREFERENCES.md frontmatter
- scaffold-profiles.js: readPreferencesProfile(), loadCustomProfileSet()
(~/.sf/profiles/<name>.yaml with extends/add/remove), resolveActiveProfileSet()
implementing full ADR-022 §6 precedence.
- All callers updated to use resolveActiveProfileSet as the single source of truth.
Tests: 28 new tests in adr-022-scaffold-profiles.test.mjs — all passing.
Pre-existing node:test stubs (3 files) unaffected.
ADR: docs/dev/ADR-022-scaffold-profiles.md
Misc: triage TODO.md dump into BACKLOG.md (phases-helpers export error T1,
/todo triage typed-handler gap T1, structured triage tiers T2, sha-track
markdown files T2, cross-repo triage T3). Reset TODO.md to empty template.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Documents every folder under .agents/, what it contains, and the
override-by-same-name pattern. Explains YOLO as a flag not a mode.
is globally ignored but the spec file under .agents/ must be tracked.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
.agents/ is an override layer. Default modes (ask/build/autonomous)
and default skills come from SF's built-in config. Project files only
exist when overriding or adding something project-specific.
- Remove modes/ask.md, modes/build.md, modes/autonomous.md (defaults)
- Remove enabled.modes from manifest (nothing project-defined)
- Policies and skills stay: they are project-specific overrides
To override a mode or skill, add a file with the same name.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add modes/autonomous.md — third SF mode (ask/build/autonomous).
Describes UOK dispatch loop, bash 120s timeout, fresh-context-per-unit,
recovery/runaway-guard, and when to use vs Build.
- Add autonomous to enabled.modes in manifest.yaml.
- Update policies/yolo.yaml description: YOLO is a flag on Build or
Autonomous, not a mode, not a Shift+Tab stop.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sf-wiki, forge-autonomous-runtime, forge-command-surface, nix-build,
and smoke-test are all present in .agents/skills/ and must be declared
in enabled.skills per the AGENTS-1 spec.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
.agents/skills/ is the documented standard for project-level skill overrides
(docs/user-docs/skills.md). .sf/skills/ is also searched but .agents/skills/
is the ecosystem-standard path used across all compatible agents.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replaces the fragmented (AGENTS.md + CLAUDE.md + .github/copilot-instructions.md
+ .sf/STYLE.md + .sf/PRINCIPLES.md + .sf/NON-GOALS.md) surface with a
single canonical .agents/ tree per https://github.com/agentsfolder/spec.
Structure:
.agents/manifest.yaml spec metadata + defaults + project info
.agents/prompts/
base.md project-agnostic base prompt
project.md SF-specific: purpose-first, DB-first,
build pipeline, Ask/Build/YOLO model
snippets/{style,principles,non-goals}.md
short pointers into .sf/{STYLE,PRINCIPLES,
NON-GOALS}.md for composition
.agents/modes/{ask,build}.md YAML front matter + human-readable body
.agents/policies/{default-safe,yolo}.yaml
conservative default + YOLO override
.agents/skills/.gitkeep empty per spec — SF's own skills not yet
migrated to agentskills.io format
.agents/scopes/.gitkeep single-tree, no scopes yet
.agents/profiles/.gitkeep no overlays yet
.agents/schemas/.gitkeep generated by validators
.agents/state/.gitignore excludes state.yaml from VCS per spec
Status: spec is pre-1.0 (specVersion 0.1.0 pinned). No agent runtime
currently reads .agents/ — this is structural adoption ahead of
ecosystem support. Legacy files (AGENTS.md, CLAUDE.md, etc.) kept
during the transition; .agents/ is now the canonical surface and they
will eventually point here.
This is the reference template; centralcloud/infra, operations-memory,
oncall-mobile-android to follow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Node 24 is the only runtime — drop bun from nix-build skill instructions
(use `npm run --workspace=...`) and from lockfile-skip globs in the secret/
base64 scanners. flake.nix dev shell already lost bun in the prior snapshot
commit. End-user-facing package-manager.ts still supports bun by design.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>