From 013668e9ae5d8456829c09b766947f293a2896b7 Mon Sep 17 00:00:00 2001 From: James Manuel Date: Mon, 10 Aug 2026 11:29:27 +0200 Subject: [PATCH 1/3] docs: check for existing Nextcloud capabilities before writing new logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Reuse before you write" only covered UI: an @nextcloud/vue component, a design token, an existing src/ pattern. It said nothing about checking whether the server already exposes the behaviour (an OCP interface, or a raw protocol feature) or whether a non-UI @nextcloud/* package already covers it — exactly the reuse that made #100's DAV orderby/limit fix a one-file request change instead of custom client-side pagination. Broaden the ladder to four steps (server capability, then the wider @nextcloud/* npm scope, then vue components/tokens, then src/ patterns), wire a partial-fit escape valve into the existing contestable-call rule so the new instruction can't be forced past a bad fit, and fold its PR-description disclosure into the existing pre-PR checklist instead of adding another scattered "say X in the description" instance. Went through an adversarial review pass before landing: an earlier version hardcoded this app's @nextcloud/* dependency list (stale the moment a dependency changes, and a direct contradiction of the token guidance two paragraphs below it, which explicitly refuses to enumerate for that same reason), gave no verifiable method for the OCP check ("say you checked" is not auditable), and used "capability" for two different things four lines apart. All three are fixed here — the OCP check now points at a real, grep-able local path, `vendor/nextcloud/ocp/OCP/`. Co-Authored-By: Claude Sonnet 5 Signed-off-by: James Manuel --- AGENTS.md | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 86a3145..be1d016 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -69,11 +69,33 @@ backstop, not a plan. ## Reuse before you write -Preference order: an existing `@nextcloud/vue` component, an existing design -token, an existing pattern in `src/`. - -Each keeps you on the design system the library already maintains; hand-rolled -equivalents drift from it and duplicate maintenance. +Preference order, before writing new logic of any kind: + +1. A feature the server already exposes. Grep `vendor/nextcloud/ocp/OCP/` + for an existing interface — OCP is Nextcloud's public server API, and + `composer require-dev` vendors the full stub tree, so it's local and + searchable even though OCP isn't a runtime dependency of this app. For + protocol-level features with no OCP interface — DAV `SEARCH`'s + `orderby`/`limit` is one, see #100 — there's nothing to grep; if you're + not sure the server already supports what you need, ask rather than + assume it doesn't. +2. An `@nextcloud/*` package for the behaviour, not just `@nextcloud/vue` + for UI. Check `package.json` for what's already a dependency, then the + wider `@nextcloud/*` npm scope (dialogs, upload, and more) for what + isn't. +3. An existing `@nextcloud/vue` component or design token, for UI + specifically. +4. An existing pattern in `src/`. + +If the closest match is a partial fit — right shape, wrong semantics, or +costs more to bend into place than it saves — that's grounds to write it +instead, not force it. That's a contestable call (see below): flag it in +the PR description rather than silently picking either way. + +Each rung down this ladder is more for us to build, test, and maintain +ourselves for something Nextcloud, or this repo, may already do correctly; +reuse also comes pre-tested, and — for UI — pre-styled, in ways a bespoke +equivalent won't. Tokens: `var(--color-...)`, `var(--border-radius)`, `var(--default-clickable-area)`, `var(--default-grid-baseline)`. Treat @@ -143,7 +165,8 @@ so check the list above by hand before the PR. Two defensible seams from the naming test, a cleanup that would grow the PR, a security attribute you can justify but a reviewer might not accept, a -dependency whose bundle cost is arguable — anywhere a reviewer could +dependency whose bundle cost is arguable, an existing feature or component +that's only a partial fit for what you need — anywhere a reviewer could reasonably want the other option, put the choice to the human driving the session before committing to it; unattended, take the narrower option — the one that's easier to reverse in review. Either way, flag the call in the PR @@ -155,6 +178,9 @@ description. git fetch origin && git log --oneline HEAD..origin/main # rebase if non-empty ``` +Say in the description which reuse option ("Reuse before you write") you +used, or that none fit and why. + If the change touches `src/` (JS/Vue/CSS): ```bash From 7d7b6f786966347f010057207d0a1d583a70f112 Mon Sep 17 00:00:00 2001 From: James Manuel Date: Mon, 10 Aug 2026 11:32:08 +0200 Subject: [PATCH 2/3] docs: drop the in-body PR reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every other rule in this file explains its motivating incident in the commit message or PR body, never inside the instructional text itself — #79, #83, #84, and #100's own diagnosis are all discussed there, not quoted in AGENTS.md. "see #100" broke that pattern and adds nothing: the DAV SEARCH orderby/limit example is already self-contained, and a bare PR number means nothing to a future reader without the context this conversation had. Co-Authored-By: Claude Sonnet 5 Signed-off-by: James Manuel --- AGENTS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index be1d016..ffdd9fc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -76,9 +76,9 @@ Preference order, before writing new logic of any kind: `composer require-dev` vendors the full stub tree, so it's local and searchable even though OCP isn't a runtime dependency of this app. For protocol-level features with no OCP interface — DAV `SEARCH`'s - `orderby`/`limit` is one, see #100 — there's nothing to grep; if you're - not sure the server already supports what you need, ask rather than - assume it doesn't. + `orderby`/`limit` is one — there's nothing to grep; if you're not sure + the server already supports what you need, ask rather than assume it + doesn't. 2. An `@nextcloud/*` package for the behaviour, not just `@nextcloud/vue` for UI. Check `package.json` for what's already a dependency, then the wider `@nextcloud/*` npm scope (dialogs, upload, and more) for what From 734a1d18d9da88432ab2656ce7eb654603fdae62 Mon Sep 17 00:00:00 2001 From: James Manuel Date: Mon, 10 Aug 2026 14:24:41 +0200 Subject: [PATCH 3/3] docs: require public-safe commit messages and dependency upkeep checks Signed-off-by: James Manuel --- AGENTS.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ffdd9fc..8442ac8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,6 +22,14 @@ only be trusted. CI checks every commit: conventional-format headline (`fix:`, `feat:`, `docs:`, ...) and DCO sign-off — `git commit -s`. +Commit messages are written for a public reviewer who has only the diff — +not for your own notes. If a sentence only makes sense with context outside +this repo, it doesn't belong in the message. + +Commits substantially written by an AI agent carry a `Co-Authored-By:` +trailer naming the tool, alongside `Signed-off-by` — use `git commit -s` +so git supplies your identity instead of guessing it. + A new unit lands with its `.spec.ts` sibling in the same commit — `src/utils/` and `src/components/` pair each unit with one; follow that. @@ -158,8 +166,10 @@ so check the list above by hand before the PR. component are removed in `onUnmounted` — see `TemplateSection.vue`. - Stream file contents; never read a whole document into memory — office files have no upper size. -- A new dependency pays its way in bundle size: check what an import drags in - before adding it. +- A new dependency pays its way in bundle size and upkeep: check what an + import drags in, that it's actively maintained (recent releases, no pile + of unanswered issues), and that its license is compatible — before adding + it. An abandoned package is a security patch nobody ships. ## When the call is contestable, ask