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
1 change: 1 addition & 0 deletions .agents/skills/agent-guidelines-audit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Review the actual change rather than only checking whether files exist:
- Check tests for the required framework, mirrored paths, shared tags, Given/When/Then structure, deterministic seams, and coverage of changed behavior and failure paths.
- Trace every new or changed stateful, asynchronous, fallible, or lifecycle-oriented behavior and verify that its owning artifact emits privacy-safe AppLogger events for the meaningful success, failure, cancellation, recovery, and state-transition outcomes needed to diagnose it. Dependency declaration and target linkage alone do not establish logging coverage. Accept silence for pure values or utilities only when there is no meaningful event boundary and the implementation handoff records that deliberate decision.
- Check logging ownership, subsystem, categories, emoji, privacy, severity, metadata stability, noise controls, and focused formatter or sink tests when logging changed.
- For every in-scope package that emits logs, resolve its canonical emoji from local instructions or documentation and the package list on the current `main` branch of the [ThatFactory Swift Package Collection](https://github.com/thatfactory/swift-package-collection). Enumerate the registered package entries and require each canonical emoji to identify exactly one package, treating visually identical presentation-selector variants as a collision. Confirm the package documentation, package-local logging gateway, and registry entry use the same emoji. When creating a package or assigning or changing its emoji, verify the intended emoji is unused before accepting it and require the registry update in the publication work. A collision, a missing registry entry for a published package, an unreachable current registry, or disagreement among these sources blocks audit completion and release readiness.
- For every Apple-platform application or Swift package in scope, except the AppLogger provider repository itself, verify integration with the shared [Logging guide](../../../Guidelines/Logging.md): confirm the AppLogger dependency is declared, the `AppLogger` library product is linked to every target that emits diagnostics, and any new project has it available in its primary runtime target before its first log call. Search the actual package or Xcode dependency graph rather than relying on an `import` alone, and treat `print`, direct `Logger` instances, or duplicate logging backends as incomplete integration when they emit project diagnostics. When implementation is authorized, add or repair the dependency and target linkage and migrate affected calls while preserving the guide's ownership, subsystem, category, emoji, privacy, severity, and noise rules; report an exact blocker when target or platform constraints make safe integration ambiguous.
- Inspect dependency manifests, resolver or lock files, Xcode package references, vendored source or binary frameworks, and equivalent dependency declarations. Compare the change with the baseline and identify every new third-party dependency or expansion of an existing third-party dependency into a new target or runtime role. Apply the shared [external dependency policy](../../../Guidelines/Development.md#external-dependencies): require explicit repository-owner approval before the dependency is introduced and require the durable exception record in repository documentation. Do not infer approval merely from an execution plan, pull-request description, implementation convenience, package popularity, or the dependency already appearing in the diff. Treat an unapproved or undocumented third-party dependency as a blocker to completion. Do not flag Apple system frameworks, the Swift standard library, ThatFactory-owned packages, or guideline-mandated tooling used only for its documented tooling role. If a newly resolved transitive third-party package will be linked into or shipped with the product, verify that its owning direct dependency is covered by an approved exception rather than dismissing it solely because it is transitive.
- Search dependency manifests, generated directories, project files, and documentation for CocoaPods or Carthage adoption. The shared [external dependency policy](../../../Guidelines/Development.md#external-dependencies) forbids both without an exception path and requires Swift Package Manager for package dependencies. When implementation is authorized, remove newly introduced adoption and its generated or configuration files; report pre-existing adoption as a completion blocker when safe migration is outside the task scope.
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project are documented in this file.

## [0.0.34] - 2026-09-20

### Changed

- Required every ThatFactory package emoji to be unique in the Swift Package Collection and synchronized across package documentation, the logging gateway, and the collection registry.
- Extended the completion audit to block package publication when emoji uniqueness cannot be verified or the registered and emitted identities disagree.

## [0.0.33] - 2026-09-19

### Added
Expand Down
4 changes: 4 additions & 0 deletions Guidelines/Packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ Accept a deviation only when the nearest applicable `AGENTS.md`, or durable docu

Packages own any diagnostics emitted by their implementation. Follow the shared [logging guide](Logging.md) for AppLogger usage, subsystem identity, package emoji prefixes, domain-owned categories, concise messages, privacy, and test coverage. A consuming application must not reproduce package-internal logs.

Before assigning or changing a package's canonical emoji, inspect the package list on the current `main` branch of the [ThatFactory Swift Package Collection](https://github.com/thatfactory/swift-package-collection) and confirm that no other package uses it. Each package emoji must be unique across ThatFactory so a log prefix identifies one package unambiguously. Treat visually identical emoji spellings that differ only by presentation selectors as the same emoji; do not use an encoding variation to create an apparent distinction.

Declare the selected emoji in the package's local instructions or documentation, use that exact emoji in its package-local logging gateway, and add or update the matching Swift Package Collection entry as part of the package's publication work. An existing collision, a missing registry entry for a published package, or disagreement among the registry, documentation, and emitted prefix blocks release readiness until reconciled.

## Development workflow

1. Read the package's local `AGENTS.md`, README, DocC, and public API before changing behavior.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ From the consumer repository root, install a tagged release:
git subtree add \
--prefix=AgentGuidelines \
https://github.com/thatfactory/agent-guidelines.git \
0.0.33 \
0.0.34 \
--squash
```

Expand Down Expand Up @@ -147,7 +147,7 @@ Review the target release's changelog, then pull it deliberately:
git subtree pull \
--prefix=AgentGuidelines \
https://github.com/thatfactory/agent-guidelines.git \
0.0.33 \
0.0.34 \
--squash
```

Expand Down
12 changes: 12 additions & 0 deletions Scripts/validate_guidelines.swift
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,14 @@ func validatePackageCompilerSettingsGuideline(_ errors: inout [String]) {
for feature in packageUpcomingFeatures where !contents.contains(".enableUpcomingFeature(\"\(feature)\")") {
errors.append("Guidelines/Packages.md: missing required SwiftPM upcoming feature '\(feature)'")
}
let emojiRequired = [
"Each package emoji must be unique across ThatFactory": "uniqueness policy",
"visually identical emoji spellings": "presentation-selector collision policy",
"matching Swift Package Collection entry": "registry synchronization",
]
for (value, description) in emojiRequired where !contents.contains(value) {
errors.append("Guidelines/Packages.md: missing package emoji \(description): '\(value)'")
}
}

/// Validates the shared App Store metadata workflow.
Expand Down Expand Up @@ -679,6 +687,10 @@ func validateAuditSkill(_ errors: inout [String]) {
"AppLogger": "AppLogger integration audit",
"Logging.md": "shared Logging guide reference",
"Dependency declaration and target linkage alone": "lifecycle observability coverage audit",
"Enumerate the registered package entries": "package emoji registry enumeration",
"visually identical presentation-selector variants as a collision":
"package emoji presentation-selector collision audit",
"blocks audit completion and release readiness": "package emoji audit stopping rule",
"## Audit documentation consistency": "documentation drift audit",
"Known stale documentation blocks completion": "stale documentation stopping rule",
"## Audit documentation formatting": "documentation formatting audit",
Expand Down
38 changes: 38 additions & 0 deletions Tests/run_tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,25 @@ let tests: [(String, () throws -> Void)] = [
}
}
),
(
"repository validator rejects missing package emoji uniqueness policy",
{
try withTemporaryDirectory { temporary in
let fixture = temporary.appendingPathComponent("repository")
try copyRepositoryFixture(to: fixture)
let guideline = fixture.appendingPathComponent("Guidelines/Packages.md")
var contents = try String(contentsOf: guideline, encoding: .utf8)
contents = contents.replacingOccurrences(
of: "Each package emoji must be unique across ThatFactory",
with: "Package emojis should be recognizable"
)
try write(contents, to: guideline)
let result = try run([fixture.appendingPathComponent("Scripts/validate_guidelines.swift").path])
try require(!result.succeeded, "missing package emoji uniqueness policy unexpectedly passed")
try require(result.output.contains("missing package emoji uniqueness policy"), result.output)
}
}
),
(
"repository validator rejects missing package audit section",
{
Expand Down Expand Up @@ -326,6 +345,25 @@ let tests: [(String, () throws -> Void)] = [
}
}
),
(
"repository validator rejects package emoji audit drift",
{
try withTemporaryDirectory { temporary in
let fixture = temporary.appendingPathComponent("repository")
try copyRepositoryFixture(to: fixture)
let skill = fixture.appendingPathComponent(".agents/skills/agent-guidelines-audit/SKILL.md")
var contents = try String(contentsOf: skill, encoding: .utf8)
contents = contents.replacingOccurrences(
of: "Enumerate the registered package entries",
with: "Inspect the package registry"
)
try write(contents, to: skill)
let result = try run([fixture.appendingPathComponent("Scripts/validate_guidelines.swift").path])
try require(!result.succeeded, "package emoji audit drift unexpectedly passed")
try require(result.output.contains("missing package emoji registry enumeration"), result.output)
}
}
),
(
"repository validator rejects missing observability adoption guidance",
{
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.33
0.0.34