|
| 1 | +# DevLog Workflow Rules |
| 2 | + |
| 3 | +This reference holds DevLog-specific working rules that should live with the project, not in global agent memory. |
| 4 | + |
| 5 | +## Canonical source |
| 6 | + |
| 7 | +- Treat this repository's `AGENTS.md` and `.hermes/skills/devlog-architecture-harness` as the canonical DevLog working rules. |
| 8 | +- Use global memory only as historical context. If global memory conflicts with this repository, follow the repository. |
| 9 | +- Before changing architecture rules, update the repository-local rules first. |
| 10 | + |
| 11 | +## Verification |
| 12 | + |
| 13 | +- Prefer Xcode Local MCP for iOS project code changes. |
| 14 | +- If Xcode Local MCP is unavailable or fails because of session transport, state that explicitly before using a fallback. |
| 15 | +- This repository is workspace-based. Prefer workspace/scheme context over standalone project builds when dependencies cross module projects. |
| 16 | +- CI truth lives in `.github/workflows/build.yml`: `DevLog.xcworkspace`, scheme `DevLog`, simulator build, `-resolvePackageDependencies`, `-skipPackagePluginValidation`, and `-skipMacroValidation`. |
| 17 | +- CI is build validation, not a full test run, unless the workflow changes. |
| 18 | +- Avoid unrelated `Package.resolved` churn. Keep lockfile changes only when dependency resolution is the task. |
| 19 | + |
| 20 | +## Xcode project file work |
| 21 | + |
| 22 | +- Inspect Swift imports and `.xcodeproj/project.pbxproj` framework links together. |
| 23 | +- Validate touched `project.pbxproj` files with `plutil -lint`. |
| 24 | +- `plutil -lint` does not prove Xcode save behavior is healthy; for Xcode save crashes, inspect crash reports and project-reference call stacks. |
| 25 | +- Do not force a single `objectVersion` across projects. Treat Xcode's actual save output as the source of truth. |
| 26 | +- For synchronized-root cleanup, verify on copied files or a narrowed rule set before touching real project files. |
| 27 | +- When removing project-file objects, distinguish stale product references, real target links, orphan build files, and plugin churn. |
| 28 | + |
| 29 | +## PR and review handling |
| 30 | + |
| 31 | +- Write DevLog PR and review text in Korean. |
| 32 | +- Follow `.github/pull_request_template.md` for PR body structure. |
| 33 | +- If the user asks for PR content only, return the Markdown directly and do not create files. |
| 34 | +- For unresolved GitHub review threads, use thread-aware inspection such as `gh api graphql` review threads or the `gh-address-comments` skill. Flat comments are not enough. |
| 35 | +- Handle narrowed review feedback one item at a time. |
| 36 | +- Verify a review suggestion against the real code and diff before accepting it. |
| 37 | +- If a cleanup is deferred to an issue, show the issue URL visibly rather than hiding it behind an inline Markdown link when the user asks for review/PR note text. |
| 38 | + |
| 39 | +## Commit guidance |
| 40 | + |
| 41 | +- If the user says they will commit or asks only for a commit message, provide commit-message guidance instead of committing. |
| 42 | +- Before proposing a commit message, inspect the actual diff and recent `git log`. |
| 43 | +- Match the repository's current Korean style and prefix pattern. |
| 44 | +- If the user explicitly specifies a prefix or noun-phrase ending, follow it exactly. |
| 45 | +- For broad architecture refactors, split commits by layer when the user asks for staged commits. |
| 46 | + |
| 47 | +## Architecture staging |
| 48 | + |
| 49 | +- For modular refactors, state the next stage before editing when the user asks what comes next. |
| 50 | +- When the user wants explicit phases, keep phases clean even if intermediate commits temporarily break the build. |
| 51 | +- A common DevLog modularization sequence is external dependency removal, architecture application, then reattaching removed modules by layer. |
| 52 | +- Keep project-file, lockfile, and code changes separated when the task scope requires clean review. |
| 53 | +- Do not broaden architecture work into unrelated Firestore, Messaging, UI, or safety edits. |
| 54 | + |
| 55 | +## Data, Domain, and Infra boundary |
| 56 | + |
| 57 | +- Do not move domain entities to Core only because multiple modules need them. |
| 58 | +- Keep protocol location and implementation layer distinct when explaining or changing boundaries. |
| 59 | +- If a Data protocol is implemented by Infra, every type in that protocol signature must be visible to Infra. |
| 60 | +- Prefer a Data-side boundary value plus repository mapping when Infra should not import Domain. |
| 61 | +- For example, keep the app-facing Domain query separate from an Infra-facing Data query when that avoids Domain coupling in service protocols. |
| 62 | +- Firebase-specific error detection belongs in Infra; Data should handle domain-level errors after mapping. |
| 63 | + |
| 64 | +## Presentation Store |
| 65 | + |
| 66 | +- Preserve the existing `Store` shape: `@MainActor`, `State`, `Action`, `SideEffect`, `send -> reduce -> run`. |
| 67 | +- Reducers compute state and return side effects. |
| 68 | +- I/O belongs in `run` or injected services. |
| 69 | +- Do not leave reducer-era helper methods behind after moving work into `run`. |
| 70 | +- Before adding task cancellation or async wrappers, inspect whether the underlying operation is actually async. |
| 71 | + |
| 72 | +## Widget flow |
| 73 | + |
| 74 | +- Widget UI should consume snapshot data, not app/domain services. |
| 75 | +- `DevLogWidgetCore` should stay free of Domain, Data, Infra, Persistence, Presentation, and App dependencies unless the user explicitly approves a boundary change. |
| 76 | +- Prefer an app-driven snapshot flow: app/runtime data fetch, snapshot generation, App Group storage, WidgetCore model/factory, WidgetExtension rendering. |
| 77 | +- `WidgetTodoSnapshot` is a lightweight snapshot value, not a full domain `Todo`. |
| 78 | +- Do not make `Todo.number` or `WidgetTodoSnapshot.number` non-optional without a separate saved-vs-draft model decision. |
| 79 | +- If a widget sync flow needs one timestamp for multiple snapshots, capture `Date()` once and pass it through to avoid midnight or quarter-boundary drift. |
| 80 | + |
| 81 | +## Localization |
| 82 | + |
| 83 | +- For `.xcstrings`, use `jq empty` for structural validation when `plutil -lint` reports format-related false failures. |
| 84 | +- Keep `.xcstrings` cleanup surgical and inspect the diff first if the file is already dirty. |
| 85 | + |
| 86 | +## Release and private config |
| 87 | + |
| 88 | +- `release.yml` creates GitHub releases after merged PRs into `main` from `develop`; it does not upload to App Store/TestFlight by itself. |
| 89 | +- TestFlight workflow private config comes from the project-specific private config action. |
| 90 | +- Runtime/build-required private files must be restored through the documented project workflow, not guessed. |
0 commit comments