@maccesar/aiskills 1.15.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,336 @@
1
+ # The four files
2
+
3
+ Read this when installing the convention in a project or migrating one that keeps
4
+ its notes somewhere else.
5
+
6
+ ## Layout
7
+
8
+ ```
9
+ docs/project/
10
+ status.md VOLATILE — never imported, read on demand
11
+ requirements.md STABLE — imported at startup
12
+ decisions.md STABLE — imported at startup
13
+ context.md STABLE — imported at startup
14
+
15
+ CLAUDE.md ┐
16
+ AGENTS.md ├─ each gets the same short pointer block
17
+ GEMINI.md ┘
18
+
19
+ CHANGELOG.md untouched — that's the release record, not the session record
20
+ ```
21
+
22
+ Same names in every project. That's what makes them findable without asking.
23
+
24
+ ## The pointer block
25
+
26
+ Identical in every context file. Keep it this short — duplicated prose drifts,
27
+ three lines don't.
28
+
29
+ ```markdown
30
+ ## Project state
31
+
32
+ - `docs/project/requirements.md` — what the system must do
33
+ - `docs/project/context.md` — architecture and conventions
34
+ - `docs/project/decisions.md` — what was decided and why
35
+ - `docs/project/status.md` — where the work stands right now
36
+
37
+ Read `status.md` when resuming work. Do not import it at startup: it changes
38
+ constantly, and loading it invalidates the cached prefix behind it.
39
+ ```
40
+
41
+ Where the tool supports imports, import the three stable files:
42
+
43
+ ```markdown
44
+ @docs/project/requirements.md
45
+ @docs/project/context.md
46
+ @docs/project/decisions.md
47
+ ```
48
+
49
+ Never `@docs/project/status.md`. That single line is the difference between a
50
+ cache that survives and one that gets thrown away on every update.
51
+
52
+ ## Two variants
53
+
54
+ ### One repo, several packages
55
+
56
+ A monorepo takes the opposite answer from two sibling repos: **one `docs/project/`
57
+ at the root**, with a heading per package.
58
+
59
+ ```
60
+ docs/project/
61
+ status.md ## apps/api ## apps/web ## packages/ui
62
+ requirements.md same headings
63
+ ```
64
+
65
+ Sibling repos get their own files because each has its own branch, its own deploy
66
+ state and its own history — three things that go stale independently. A monorepo has
67
+ one of each. Splitting the notes per package there would invent a boundary git
68
+ doesn't have, and the cross-package work — the half that actually goes wrong, the
69
+ API change that breaks the web build — would have no obvious home.
70
+
71
+ The vocabulary rule is unchanged: `apps/api` is a heading, not a directory of notes.
72
+
73
+ ### More than one person writing
74
+
75
+ `status.md` is rewritten whole, by whoever is working, every session. Two people or
76
+ two live branches means merge conflicts in it, reliably. That's a fact to plan for
77
+ rather than a flaw to design around, because both obvious fixes are worse:
78
+
79
+ | Tempting fix | What it costs |
80
+ | --- | --- |
81
+ | A file per person (`status-cesar.md`) | Scattered notes again, with extra steps |
82
+ | `.gitignore` it | The notes never reach the person they were written for |
83
+ | Only the lead updates it | It goes stale the first week the lead is busy |
84
+
85
+ Resolve conflicts by **keeping both sides and merging by section** — two people's
86
+ "In flight" entries are both true, and whichever loses a conflict is information
87
+ nobody gets back. If the friction is constant rather than occasional, the team wants
88
+ a heading per workstream inside the file. Still one file.
89
+
90
+ ## Templates
91
+
92
+ ### `docs/project/status.md`
93
+
94
+ The only file that changes every session. Keep it short enough that someone
95
+ actually reads it.
96
+
97
+ ```markdown
98
+ # Status — <YYYY-MM-DD>
99
+
100
+ **Phase:** <proposal · requirements · design · build · testing · live>
101
+ **Deployed:** <what's in production and since when — or "nothing yet">
102
+ **Branch:** <branch, and whether it's pushed>
103
+ **Sibling:** <other repo of this same project, and what it's waiting on — omit
104
+ when the project is a single repo>
105
+
106
+ ## Where things stand
107
+ <Two or three sentences. Outcomes, not a file list.>
108
+
109
+ ## In flight
110
+ - <What's half-done, and which half works.>
111
+
112
+ ## Blocked by others
113
+ - <Waiting on a client, a store review, a provider. Who, on what, since when.>
114
+ <Omit this section entirely when nothing is blocked.>
115
+
116
+ ## Requirements
117
+ <One line per requirement with its state, referencing requirements.md by number.
118
+ This is where "how much is left" gets answered.>
119
+
120
+ ## Next step
121
+ <The exact route, symbol or file to create or change — not an area.>
122
+
123
+ ## Verified vs. assumed
124
+ - Verified: <what actually ran, with the result>
125
+ - Assumed: <what was not checked>
126
+
127
+ ## Known pending
128
+ - <Things spotted but not started. Delete them as they get picked up.>
129
+ ```
130
+
131
+ Absolute dates, never "yesterday" — the file outlives the session that wrote it.
132
+
133
+ The three header lines exist because they're the questions asked first and
134
+ answered worst. **Deployed is not the same as committed**: on a project that
135
+ deploys by file sync, a change can be live and uncommitted, or committed and never
136
+ uploaded. Write what you know and mark what you don't; a confident wrong answer
137
+ here sends someone debugging the wrong copy of the code.
138
+
139
+ ### `docs/project/requirements.md`
140
+
141
+ The contract: what the system must do and how you'd know it does. Stable — it
142
+ changes when scope changes, not when work happens. **Progress lives in
143
+ `status.md`**, not here.
144
+
145
+ ```markdown
146
+ # Requirements
147
+
148
+ Source: <path to the PRD, proposal or checklist this indexes — or "this file"
149
+ if nothing else exists>
150
+
151
+ ## <Area — module, phase, whatever this project calls its parts>
152
+
153
+ | # | Must do | Accepted when |
154
+ | --- | --- | --- |
155
+ | 1 | <capability, in the client's terms> | <a checkable condition> |
156
+ | 2 | <…> | <…> |
157
+
158
+ ## <Next area>
159
+
160
+ | # | Must do | Accepted when |
161
+ | --- | --- | --- |
162
+ | 3 | <…> | <…> |
163
+
164
+ ## Invariants
165
+ - <A property that must not break, and what breaking it would look like.>
166
+
167
+ ## Out of scope
168
+ - <What was explicitly agreed as not included. Prevents the argument later.>
169
+
170
+ ## Unspecified
171
+ - <Things known to be needed but not yet pinned down. A requirement with no
172
+ acceptance criterion belongs here, not in the table above.>
173
+ ```
174
+
175
+ **Invariants** are for projects where the risk isn't forgetting a feature — it's
176
+ breaking a property while improving something else. Offline-first, no polling, a
177
+ storage schema other code depends on, a latency budget. They read like
178
+ conventions but they're stronger: a convention is how the team writes code, an
179
+ invariant is a promise the system makes. Write what breaking it would look like,
180
+ not just the rule, so it's recognizable when someone is about to do it.
181
+
182
+ Not every project has them. Skip the section when the honest answer is that
183
+ nothing here is that load-bearing.
184
+
185
+ **When the requirements live in another repo**, this file is an index pointing
186
+ outward rather than a self-contained contract — half its rows may reference
187
+ `../other-repo/…`. That's correct: copying the spec across creates a second copy
188
+ that drifts. Say plainly at the top which repo owns the contract.
189
+
190
+ Write acceptance criteria you could hand to someone else to check. "Payments
191
+ work" is not one; "charging a member writes a Payment row and the receipt shows
192
+ the folio" is. If you can't write one, the requirement isn't specified — say so
193
+ in **Unspecified** rather than pretending the table is complete.
194
+
195
+ The **Out of scope** section earns its place on client work: it's the cheapest
196
+ insurance against a disagreement six weeks later about what was included.
197
+
198
+ ### `docs/project/decisions.md`
199
+
200
+ Append-only. Old entries stay even when superseded; a decision that was reversed
201
+ is more informative than one that was deleted.
202
+
203
+ ```markdown
204
+ ## <YYYY-MM-DD> — <the decision in one line>
205
+
206
+ **Chose:** <what>
207
+ **Over:** <the alternatives considered>
208
+ **Because:** <the reasoning, including the constraints that mattered>
209
+ **Reverses:** <link to an earlier entry, when applicable>
210
+ ```
211
+
212
+ **When the date isn't knowable**, don't invent one. A repo with a single commit,
213
+ or everything still under `[Unreleased]`, has real decisions with no traceable
214
+ date — and stamping them with the commit date is a fabrication that later reads
215
+ as fact. Put them in a separate section that says why:
216
+
217
+ ```markdown
218
+ ## Decisions without a traceable date
219
+
220
+ These predate any usable history (single commit / nothing released yet). The
221
+ reasoning is recovered from the code and the docs; the dates are not known.
222
+
223
+ ### <the decision in one line>
224
+ **Chose / Over / Because:** <as above>
225
+ ```
226
+
227
+ These are usually the most valuable entries in the file, because they're the ones
228
+ that explain why the code doesn't match the spec. Losing them to keep the template
229
+ tidy is the wrong trade.
230
+
231
+ **Archiving.** Append-only and imported-at-startup is a combination with a shelf
232
+ life: every session pays for the whole file, and most of what it's paying for is a
233
+ decision from two years ago that nobody is about to revisit.
234
+
235
+ Past roughly two hundred lines, split it:
236
+
237
+ ```
238
+ docs/project/decisions.md current year — imported
239
+ docs/project/decisions-archive.md everything older — NOT imported
240
+ ```
241
+
242
+ Move entries oldest-first, keep them verbatim, and leave a line at the top of
243
+ `decisions.md` saying where the rest went. Then check the import chain again — the
244
+ archive must not be pulled in by any `@` line, or the split bought nothing.
245
+
246
+ Two rules keep the archive honest. A superseded entry stays with its reverser, even
247
+ if that means keeping an old entry in the current file — a reversal that outlives
248
+ the decision it reversed reads as if the original never happened. And an entry the
249
+ project still argues about is current by definition, whatever its date.
250
+
251
+ Two hundred lines is a prompt to look, not a threshold to enforce. A project with
252
+ twelve decisions in four years never needs this.
253
+
254
+ ### `docs/project/context.md`
255
+
256
+ How the project is put together, and what a newcomer would get wrong on day one.
257
+ Anything derivable from reading the code doesn't belong here — this is for what
258
+ the code *doesn't* say.
259
+
260
+ ```markdown
261
+ # Context
262
+
263
+ ## Documentation map
264
+ | Document | What it covers | When you need it |
265
+ | --- | --- | --- |
266
+ | `docs/<file>.md` | <one line> | <before doing X> |
267
+
268
+ ## Architecture
269
+ <How the pieces fit. Where things go and why.>
270
+
271
+ ## Conventions
272
+ - <Rule.> — <why it exists; a rule without a reason gets ignored>
273
+
274
+ ## Traps
275
+ - <The thing that cost someone a day, and how to avoid it.>
276
+ ```
277
+
278
+ The map goes first because it's what someone new needs first: knowing what exists
279
+ saves them from rewriting it. List every document you found, including the ones
280
+ that turned out to be stale — marked as stale. A document omitted from the map is
281
+ a document nobody will open again.
282
+
283
+ ## Migrating an existing project
284
+
285
+ Projects that already keep notes somewhere — `.claude/memory/`, a roadmap under
286
+ `docs/`, a planning doc — get migrated rather than duplicated. Two locations is
287
+ the problem this convention exists to solve.
288
+
289
+ 1. **Read what's there** and sort it: is this line status, a decision, or context?
290
+ Most existing notes are a mix, and that's exactly why they're hard to use.
291
+ 2. **Split it into the four files.** Status goes to `status.md` even if it was
292
+ living in an imported file — especially then.
293
+ 3. **Delete the old location** and update anything that referenced it, including
294
+ `@import` lines in context files.
295
+ 4. **Add the pointer block** to every context file.
296
+ 5. **Tell the person what moved where**, concretely. They need to be able to check
297
+ that nothing was lost, and a migration they can't audit is one they won't trust.
298
+
299
+ If the project has a planning doc with real structure — a numbered checklist, a
300
+ PRD — don't flatten it into `status.md`. Leave it where it is and reference it
301
+ from `status.md`. The convention is about knowing where to look, not about
302
+ destroying work that already has a shape.
303
+
304
+ ### Upgrading an earlier version of this convention
305
+
306
+ Repos installed before the four-file layout settled look almost right and aren't:
307
+ a lone `docs/status/current.md`, a `docs/project/` holding three files named by
308
+ hand, an `estado-actual.md` next to a `decisiones.md`. This is an upgrade, not a
309
+ migration, and the difference matters — the content was written by someone who was
310
+ there, so it's correct until the repo contradicts it.
311
+
312
+ 1. **`git mv` into the fixed names**, so the history follows the file. Copying and
313
+ deleting loses the one thing that made the old file trustworthy.
314
+ 2. **Split by volatility, not by topic.** The usual finding is a single file mixing
315
+ a stable architecture description with three lines of "where I left off". The
316
+ stable half goes to `context.md` or `requirements.md`; only the volatile half
317
+ ends up in `status.md`.
318
+ 3. **Update every pointer**, including `@import` lines and any reference from
319
+ `README.md` or a sibling repo's header. A pointer to the old path is worse than
320
+ no pointer: it resolves to nothing and looks maintained.
321
+ 4. **Say what moved where**, path by path. An upgrade someone can't audit is one
322
+ they won't trust, and this one moves files they wrote.
323
+
324
+ ## Sizing
325
+
326
+ A repo with one commit doesn't need four files with nothing in them. Start with
327
+ whichever ones have content — often `requirements.md` and `status.md` early on,
328
+ `context.md` and `decisions.md` once the thing exists — and add the rest when
329
+ there's something real to put in them. A `decisions.md` whose only entry is the decision to keep decisions is a
330
+ file that exists to look organized.
331
+
332
+ **The pointer block lists the files that exist.** Listing all four from the start is
333
+ tempting — it shows the shape — but three of the four lines then point at nothing,
334
+ and a pointer that resolves to a missing file trains the next reader to distrust the
335
+ block. Add the line when the file arrives; it's one line, at the moment it becomes
336
+ true.
@@ -0,0 +1,173 @@
1
+ # Verifying that work actually exists
2
+
3
+ Read this before marking anything as done. The goal is narrow: turn "I finished
4
+ X" into "I found the artifacts X would have produced."
5
+
6
+ ## What "done" is allowed to mean
7
+
8
+ Be careful with the word — these are different claims, and a record that collapses
9
+ them into one checkmark loses the distinction exactly when someone needs it:
10
+
11
+ | Claim | What it means |
12
+ | --- | --- |
13
+ | Implemented | The code exists — you found it |
14
+ | Verified | Tests or a build passed, and you saw the output |
15
+ | Reviewed | A human looked at it |
16
+ | Shipped | It's deployed or released |
17
+
18
+ Use the distinction to be *more* precise, not to avoid answering. "Implemented,
19
+ not yet verified — no test covers it" is a useful record. Marking nothing at all
20
+ because verification was impossible is not.
21
+
22
+ ## Three ways records go bad
23
+
24
+ **Percentages the repo can't support.** A percentage needs a fixed denominator —
25
+ a checklist with a known number of items. Without one, any number is invented.
26
+ Count what's enumerable or describe status in words.
27
+
28
+ **Duplicating what the repo already records.** Git history, the CHANGELOG and the
29
+ code are better sources than a note paraphrasing them. Record what they *can't*
30
+ say: why an approach was abandoned, what failed, what looks wrong but is deliberate.
31
+
32
+ **Padding.** A handoff nobody reads is a handoff that failed. Three specific lines
33
+ beat a page of headers. Length is not thoroughness.
34
+
35
+ ## The method
36
+
37
+ Someone's claim is about behavior. The repo holds artifacts. Verification is
38
+ translating between the two:
39
+
40
+ 1. **Name the artifacts before searching.** "Finished the payments module" should
41
+ produce a concrete list first — a service class, a route, a migration, a test.
42
+ Writing that list before you look is what stops you from accepting whatever
43
+ you happen to find as sufficient.
44
+ 2. **Search for those specific things**, not for the feature name. Grepping for
45
+ "payment" finds comments, TODOs, and unrelated strings. Grepping for the route
46
+ registration or the class definition finds the thing itself.
47
+ 3. **Distinguish existence from completeness.** A file that exists but contains a
48
+ stub is not the feature. Open what you find when the claim is substantial.
49
+ 4. **Report the gap, not just the verdict.** "Found the service and the routes;
50
+ no tests and no migration" is useful. "Not done" is not.
51
+
52
+ ## What to search for, by stack
53
+
54
+ The artifact names differ; the reasoning doesn't. Use the closest row and adapt.
55
+
56
+ ### Laravel / PHP
57
+
58
+ | Claim involves | Look for |
59
+ | --- | --- |
60
+ | Web route | Registration in `routes/web.php` |
61
+ | API endpoint | Registration in `routes/api.php` |
62
+ | Controller | `app/Http/Controllers/**/*.php` |
63
+ | Livewire component | `app/Livewire/**/*.php` plus its Blade view under `resources/views/livewire/` |
64
+ | Model | `app/Models/*.php` |
65
+ | Migration | `database/migrations/*.php` — and whether it has been run |
66
+ | Service / action | `app/Services/`, `app/Actions/` |
67
+ | Job / queue work | `app/Jobs/` |
68
+ | Test | `tests/Feature/`, `tests/Unit/` |
69
+
70
+ A Livewire feature that has a class but no Blade view is not done. Check both.
71
+
72
+ ### Titanium SDK / Alloy
73
+
74
+ | Claim involves | Look for |
75
+ | --- | --- |
76
+ | Screen | Matching files in `app/controllers/` **and** `app/views/` |
77
+ | Styling | `app/styles/` — note `app.tss` is generated, so hand edits there mean nothing |
78
+ | Business logic | `app/lib/` — helpers, services, repositories |
79
+ | Localized text | Matching keys in every `app/i18n/*/strings.xml`, not just one |
80
+ | Native module | Declared in `tiapp.xml` under `<modules>` **and** present in `modules/` |
81
+ | Platform config | `tiapp.xml` |
82
+
83
+ A controller without its view compiles to nothing usable. A string added to one
84
+ locale and not the others ships as a raw key in the missing language.
85
+
86
+ ### Node / TypeScript
87
+
88
+ | Claim involves | Look for |
89
+ | --- | --- |
90
+ | Endpoint | Route registration — framework-specific, follow the app entry point |
91
+ | Module | The file plus its export from the package or barrel index |
92
+ | Type / interface | `*.d.ts` or the declaring source file |
93
+ | Test | `*.test.ts`, `*.spec.ts`, or the configured test directory |
94
+ | Dependency | `package.json` **and** the lockfile |
95
+
96
+ ### Python
97
+
98
+ | Claim involves | Look for |
99
+ | --- | --- |
100
+ | Module | The `.py` file plus its import from wherever it's used |
101
+ | Endpoint | Router or URL configuration — framework-specific |
102
+ | Model / schema | The declaring class, plus a migration if the project has them |
103
+ | Test | `test_*.py` or `*_test.py` |
104
+ | Dependency | `pyproject.toml`, `requirements.txt`, or the lockfile |
105
+
106
+ ### Rails
107
+
108
+ | Claim involves | Look for |
109
+ | --- | --- |
110
+ | Route | `config/routes.rb` |
111
+ | Controller / model | `app/controllers/`, `app/models/` |
112
+ | Migration | `db/migrate/` — and whether `schema.rb` reflects it |
113
+ | Job | `app/jobs/` |
114
+ | Test / spec | `test/`, `spec/` |
115
+
116
+ ### Go
117
+
118
+ | Claim involves | Look for |
119
+ | --- | --- |
120
+ | Handler | The handler function plus its route registration |
121
+ | Package | The directory plus its import path in use |
122
+ | Test | `*_test.go` |
123
+ | Dependency | `go.mod` **and** `go.sum` |
124
+
125
+ ## Claims in a status file you didn't write
126
+
127
+ Resuming work means reading claims written weeks ago by someone — possibly you —
128
+ who is no longer available to ask. The method above applies unchanged, with one
129
+ addition: an old record has a **direction of error**. It says what was true when it
130
+ was written, so its claims rot toward being *understated* about what exists and
131
+ *overstated* about what's blocked.
132
+
133
+ - "Not started" from three weeks ago may well be finished. Check the artifacts
134
+ before repeating it — this is the most common way a resumed session redoes work.
135
+ - "Blocked on the client" has a date attached to a person who has probably answered
136
+ since. Flag it as needing a human check rather than carrying it forward as fact.
137
+ - "Next step: X" may be stale in a way the file cannot know. If X is already in the
138
+ code, say so instead of proposing it again.
139
+
140
+ The safe form is attribution: "the file says the payments module was left half-done
141
+ on 2026-07-14; the routes and the service exist now, so part of that landed after it
142
+ was written". That gives the person both the record and the correction.
143
+
144
+ ## Claims that can't be verified from the repo
145
+
146
+ Some are legitimate and simply live elsewhere: work in another repository, a
147
+ deploy, a conversation with a client, a design decision.
148
+
149
+ Record them. Label them. The pattern that keeps the log trustworthy is:
150
+
151
+ ```markdown
152
+ - Payments service implemented — verified: `app/Services/PaymentGateway.php`,
153
+ routes `payments.store` and `payments.show`
154
+ - Staging deploy completed — unverified, reported by the user
155
+ ```
156
+
157
+ The distinction costs one word and preserves the whole point of the record.
158
+
159
+ ## Deployment is not git state
160
+
161
+ A change can be live on a server without being committed, and committed without
162
+ being live. Repos with file-sync deployment (SFTP-on-save watchers, rsync hooks)
163
+ break the assumption that git reflects production entirely.
164
+
165
+ Never infer deployment state from git. When it matters, check the deployment
166
+ configuration in the repo, or ask.
167
+
168
+ ## Tests: the output is the evidence
169
+
170
+ "Tests pass" is a claim like any other. If you ran them, quote the count and the
171
+ result. If you didn't, say so. A log that records passing tests nobody ran is
172
+ worse than one that records nothing, because it stops the next session from
173
+ running them.