fix: agent tidy up
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
# Domain Docs
|
||||||
|
|
||||||
|
How to consume this repo's domain documentation when exploring the codebase.
|
||||||
|
|
||||||
|
## Before exploring, read these
|
||||||
|
|
||||||
|
- **`CONTEXT.md`** at the repo root - the domain glossary and orientation.
|
||||||
|
- **`.agents/adr/`** - read the Architecture Decision Records that touch the area you're about to work in.
|
||||||
|
|
||||||
|
If any of these files don't exist, proceed silently. Don't flag their absence or suggest creating them upfront; they are created lazily when terms or decisions actually get resolved.
|
||||||
|
|
||||||
|
## File structure
|
||||||
|
|
||||||
|
```
|
||||||
|
/
|
||||||
|
├── CONTEXT.md
|
||||||
|
├── .agents/
|
||||||
|
│ ├── adr/
|
||||||
|
│ │ ├── 0001-<decision-slug>.md
|
||||||
|
│ │ └── 0002-<decision-slug>.md
|
||||||
|
│ ├── docs/
|
||||||
|
│ └── skills/
|
||||||
|
└── src/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the glossary's vocabulary
|
||||||
|
|
||||||
|
When your output names a domain concept (an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `CONTEXT.md`. Don't drift to synonyms the glossary avoids.
|
||||||
|
|
||||||
|
If the concept you need isn't in the glossary yet, that's a signal - either you're inventing language the project doesn't use (reconsider), or there's a real gap (note it).
|
||||||
|
|
||||||
|
## Flag ADR conflicts
|
||||||
|
|
||||||
|
If your output contradicts an existing ADR, surface it explicitly rather than silently overriding:
|
||||||
|
|
||||||
|
> _Contradicts ADR-0001 (...) - but worth reopening because..._
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Issue tracker: Local Markdown
|
||||||
|
|
||||||
|
Issues and specs (you may know a spec as a PRD) for this repo live as markdown files in `.scratch/`.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- One feature per directory: `.scratch/<feature-slug>/`
|
||||||
|
- The spec is `.scratch/<feature-slug>/spec.md`
|
||||||
|
- Implementation issues are one file per ticket at `.scratch/<feature-slug>/issues/<NN>-<slug>.md`, numbered from `01` - never a single combined tickets file
|
||||||
|
- Triage state is recorded as a `Status:` line near the top of each issue file
|
||||||
|
- Comments and conversation history append to the bottom of the file under a `## Comments` heading
|
||||||
|
|
||||||
|
## When a skill says "publish to the issue tracker"
|
||||||
|
|
||||||
|
Create a new file under `.scratch/<feature-slug>/` (creating the directory if needed).
|
||||||
|
|
||||||
|
## When a skill says "fetch the relevant ticket"
|
||||||
|
|
||||||
|
Read the file at the referenced path. The user will normally pass the path or the issue number directly.
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
---
|
||||||
|
name: add-feed-post
|
||||||
|
description: Add a new Feed post (short announcement / social-style update) to the Data Controller marketing site. Use when the user wants to publish a Feed post, add a /feed/ entry, or create a short announcement that also goes out via RSS.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Add a Feed post
|
||||||
|
|
||||||
|
The **Feed** section (`/feed/`) is for short announcements and social-media style updates - things that don't warrant a full `content/blog/` article but are still worth publishing and syndicating via RSS. Feed posts work exactly like blog posts (one markdown file per post, in its own directory) but live under `content/feed/` and publish under `/feed/`.
|
||||||
|
|
||||||
|
Both Blog and Feed share a single combined RSS feed at `/rss.xml` (via `gatsby-plugin-feed` in `gatsby-config.js`), so a new Feed post appears in RSS automatically on the next build - no extra config.
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
### 1. Create the post directory
|
||||||
|
|
||||||
|
Create a folder under `content/feed/`, named after the post slug (this becomes the URL):
|
||||||
|
|
||||||
|
```
|
||||||
|
content/feed/my-new-announcement/index.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Pick a short, hyphenated, lowercase slug.
|
||||||
|
|
||||||
|
### 2. Write the front matter + content
|
||||||
|
|
||||||
|
```md
|
||||||
|
---
|
||||||
|
title: 'My New Announcement'
|
||||||
|
description: A one or two sentence summary used for SEO and RSS.
|
||||||
|
date: '2024-06-01 09:00:00'
|
||||||
|
author: 'Your Name'
|
||||||
|
authorLink: https://www.linkedin.com/in/yourprofile/
|
||||||
|
tags:
|
||||||
|
- Announcements
|
||||||
|
---
|
||||||
|
|
||||||
|
Your announcement content goes here, written in regular Markdown.
|
||||||
|
```
|
||||||
|
|
||||||
|
Front matter fields:
|
||||||
|
|
||||||
|
| Field | Required | Notes |
|
||||||
|
| ------------- | -------- | --------------------------------------------------------------------- |
|
||||||
|
| `title` | Yes | Used on the page, in the sidebar and in the RSS item. |
|
||||||
|
| `description` | Yes | Short summary for SEO meta tags and the RSS item description. |
|
||||||
|
| `date` | Yes | Format `'YYYY-MM-DD HH:MM:SS'`. Controls sort order and the archive. |
|
||||||
|
| `author` | Yes | Displayed under the post title. |
|
||||||
|
| `authorLink` | No | If set, the author name links out (e.g. to a LinkedIn profile). |
|
||||||
|
| `tags` | Yes | One or more tags. Drives the sidebar category list and RSS category. |
|
||||||
|
| `previewImg` | No | Relative path to an image in the same folder (e.g. `'./cover.png'`). Feed posts usually omit this since they're short-form. |
|
||||||
|
|
||||||
|
Use regular dashes (`-`) in content, not em-dashes.
|
||||||
|
|
||||||
|
### 3. Add images (optional)
|
||||||
|
|
||||||
|
If you set `previewImg` or reference images in the body, place the image files in the same post directory and reference them with a relative path.
|
||||||
|
|
||||||
|
### 4. Build / preview
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm run develop
|
||||||
|
```
|
||||||
|
|
||||||
|
The post will be available at `/my-new-announcement/` and will appear on the `/feed/` listing page, in the site search index, and in `/rss.xml` alongside blog posts.
|
||||||
|
|
||||||
|
## How Feed differs from Blog
|
||||||
|
|
||||||
|
| Aspect | Blog | Feed |
|
||||||
|
| ----------------- | ----------------------------- | --------------------------------- |
|
||||||
|
| Content directory | `content/blog/` | `content/feed/` |
|
||||||
|
| Listing page | `/blog/` | `/feed/` |
|
||||||
|
| Year archive | `/{year}/` | `/feed/{year}/` |
|
||||||
|
| Category page | `/category/{tag}/` | `/feed/category/{tag}/` |
|
||||||
|
| Template | `src/templates/blog-post.tsx`, `src/templates/blog-list.tsx` | `src/templates/feed-post.tsx`, `src/templates/feed-list.tsx` |
|
||||||
|
| RSS | Included in `/rss.xml` | Included in `/rss.xml` |
|
||||||
|
|
||||||
|
Feed archive/category routes are prefixed with `/feed/` to avoid colliding with the equivalent Blog routes, since both are rendered by the shared `src/templates/sidebar.tsx` component (via its `basePath` prop).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- To add a **blog** post instead, follow the same steps but use `content/blog/` and the `/blog/` routes.
|
||||||
|
- The canonical human-readable version of this guide is `docs/adding-feed-posts.md`.
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
name: grill-with-docs
|
|
||||||
description: A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
|
|
||||||
disable-model-invocation: true
|
|
||||||
---
|
|
||||||
|
|
||||||
Run a `/grilling` session, using the `/domain-modeling` skill.
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
interface:
|
|
||||||
display_name: "Grill with Docs"
|
|
||||||
short_description: "Grill a design and write its docs"
|
|
||||||
policy:
|
|
||||||
allow_implicit_invocation: false
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
---
|
|
||||||
name: setup-matt-pocock-skills
|
|
||||||
description: Configure this repo for the engineering skills — set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.
|
|
||||||
disable-model-invocation: true
|
|
||||||
---
|
|
||||||
|
|
||||||
# Setup Matt Pocock's Skills
|
|
||||||
|
|
||||||
Scaffold the per-repo configuration that the engineering skills assume:
|
|
||||||
|
|
||||||
- **Issue tracker** — where issues live (GitHub by default; local markdown is also supported out of the box)
|
|
||||||
- **Triage labels** — the strings used for the five canonical triage roles
|
|
||||||
- **Domain docs** — where `CONTEXT.md` and ADRs live, and the consumer rules for reading them
|
|
||||||
|
|
||||||
This is a prompt-driven skill, not a deterministic script. Explore, present what you found, confirm with the user, then write.
|
|
||||||
|
|
||||||
## Process
|
|
||||||
|
|
||||||
### 1. Explore
|
|
||||||
|
|
||||||
Look at the current repo to understand its starting state. Read whatever exists; don't assume:
|
|
||||||
|
|
||||||
- `git remote -v` and `.git/config` — is this a GitHub repo? Which one?
|
|
||||||
- `AGENTS.md` and `CLAUDE.md` at the repo root — does either exist? Is there already an `## Agent skills` section in either?
|
|
||||||
- `CONTEXT.md` and `CONTEXT-MAP.md` at the repo root
|
|
||||||
- `docs/adr/` and any `src/*/docs/adr/` directories
|
|
||||||
- `docs/agents/` — does this skill's prior output already exist?
|
|
||||||
- `.scratch/` — sign that a local-markdown issue tracker convention is already in use
|
|
||||||
- Is the `triage` skill installed? (a `triage` skill folder alongside this one, or `triage` in your available skills.) This decides whether Section B runs at all.
|
|
||||||
- Monorepo signals — a `pnpm-workspace.yaml`, a `workspaces` field in `package.json`, or a populated `packages/*` with its own `src/`. Present only in a genuinely large multi-package repo; their absence means single-context, which is almost every repo.
|
|
||||||
|
|
||||||
### 2. Present findings and ask
|
|
||||||
|
|
||||||
Summarise what's present and what's missing. Then take the sections in order — one section, one answer, then the next.
|
|
||||||
|
|
||||||
Lead each section with the recommended answer so the user can accept it in a word. Give a one-line explainer only when the choice genuinely branches; skip the section entirely when exploration already settled it (Section B when `triage` isn't installed, Section C when there's no monorepo).
|
|
||||||
|
|
||||||
**Section A — Issue tracker.**
|
|
||||||
|
|
||||||
> Explainer: The "issue tracker" is where issues live for this repo. Skills like `to-tickets`, `triage`, `to-spec`, and `qa` read from and write to it — they need to know whether to call `gh issue create`, write a markdown file under `.scratch/`, or follow some other workflow you describe. Pick the place you actually track work for this repo.
|
|
||||||
|
|
||||||
Default posture: these skills were designed for GitHub. If a `git remote` points at GitHub, propose that. If a `git remote` points at GitLab (`gitlab.com` or a self-hosted host), propose GitLab. Otherwise (or if the user prefers), offer:
|
|
||||||
|
|
||||||
- **GitHub** — issues live in the repo's GitHub Issues (uses the `gh` CLI)
|
|
||||||
- **GitLab** — issues live in the repo's GitLab Issues (uses the [`glab`](https://gitlab.com/gitlab-org/cli) CLI)
|
|
||||||
- **Local markdown** — issues live as files under `.scratch/<feature>/` in this repo (good for solo projects or repos without a remote)
|
|
||||||
- **Other** (Jira, Linear, etc.) — ask the user to describe the workflow in one paragraph; the skill will record it as freeform prose
|
|
||||||
|
|
||||||
Record the choice in `docs/agents/issue-tracker.md`. The GitHub and GitLab templates carry a "PRs as a request surface" flag, defaulted **off** — leave it off and don't raise it; a user who wants external PRs in the triage queue can flip the flag in the file later.
|
|
||||||
|
|
||||||
**Section B — Triage label vocabulary.** Skip this section entirely if the `triage` skill isn't installed (exploration told you) — an uninstalled skill needs no labels.
|
|
||||||
|
|
||||||
If it is installed, ask exactly one question:
|
|
||||||
|
|
||||||
> Do you want to keep the default triage labels? (recommended: **yes**)
|
|
||||||
|
|
||||||
The defaults are the five canonical roles, each label string equal to its name: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`. On **yes**, write them as-is. Only if the user says no — usually because their tracker already uses other names (e.g. `bug:triage` for `needs-triage`) — collect the overrides so `triage` applies existing labels instead of creating duplicates.
|
|
||||||
|
|
||||||
**Section C — Domain docs.** Default to **single-context** — one `CONTEXT.md` + `docs/adr/` at the repo root. This fits almost every repo; write it without asking.
|
|
||||||
|
|
||||||
Offer **multi-context** — a root `CONTEXT-MAP.md` pointing to per-context `CONTEXT.md` files — only when exploration found monorepo signals. Then confirm which layout they want.
|
|
||||||
|
|
||||||
### 3. Confirm and edit
|
|
||||||
|
|
||||||
Show the user a draft of:
|
|
||||||
|
|
||||||
- The `## Agent skills` block to add to whichever of `CLAUDE.md` / `AGENTS.md` is being edited (see step 4 for selection rules)
|
|
||||||
- The contents of `docs/agents/issue-tracker.md`, `docs/agents/domain.md`, and `docs/agents/triage-labels.md` (the last only when `triage` is installed)
|
|
||||||
|
|
||||||
Let them edit before writing.
|
|
||||||
|
|
||||||
### 4. Write
|
|
||||||
|
|
||||||
**Pick the file to edit:**
|
|
||||||
|
|
||||||
- If `CLAUDE.md` exists, edit it.
|
|
||||||
- Else if `AGENTS.md` exists, edit it.
|
|
||||||
- If neither exists, ask the user which one to create — don't pick for them.
|
|
||||||
|
|
||||||
Never create `AGENTS.md` when `CLAUDE.md` already exists (or vice versa) — always edit the one that's already there.
|
|
||||||
|
|
||||||
If an `## Agent skills` block already exists in the chosen file, update its contents in-place rather than appending a duplicate. Don't overwrite user edits to the surrounding sections.
|
|
||||||
|
|
||||||
The block:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
## Agent skills
|
|
||||||
|
|
||||||
### Issue tracker
|
|
||||||
|
|
||||||
[one-line summary of where issues are tracked]. See `docs/agents/issue-tracker.md`.
|
|
||||||
|
|
||||||
### Triage labels
|
|
||||||
|
|
||||||
[one-line summary of the label vocabulary]. See `docs/agents/triage-labels.md`.
|
|
||||||
|
|
||||||
### Domain docs
|
|
||||||
|
|
||||||
[one-line summary of layout — "single-context" or "multi-context"]. See `docs/agents/domain.md`.
|
|
||||||
```
|
|
||||||
|
|
||||||
Include the `### Triage labels` sub-block, and write `docs/agents/triage-labels.md`, only when `triage` is installed and Section B ran. When it isn't, both are omitted.
|
|
||||||
|
|
||||||
Then write the docs files using the seed templates in this skill folder as a starting point:
|
|
||||||
|
|
||||||
- [issue-tracker-github.md](./issue-tracker-github.md) — GitHub issue tracker
|
|
||||||
- [issue-tracker-gitlab.md](./issue-tracker-gitlab.md) — GitLab issue tracker
|
|
||||||
- [issue-tracker-local.md](./issue-tracker-local.md) — local-markdown issue tracker
|
|
||||||
- [triage-labels.md](./triage-labels.md) — label mapping (only if `triage` is installed)
|
|
||||||
- [domain.md](./domain.md) — domain doc consumer rules + layout
|
|
||||||
|
|
||||||
For "other" issue trackers, write `docs/agents/issue-tracker.md` from scratch using the user's description.
|
|
||||||
|
|
||||||
### 5. Done
|
|
||||||
|
|
||||||
Tell the user the setup is complete and which engineering skills will now read from these files. Mention they can edit `docs/agents/*.md` directly later — re-running this skill is only necessary if they want to switch issue trackers or restart from scratch.
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
interface:
|
|
||||||
display_name: "Setup Matt Pocock Skills"
|
|
||||||
short_description: "Configure a repo for the skills"
|
|
||||||
policy:
|
|
||||||
allow_implicit_invocation: false
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
# Domain Docs
|
|
||||||
|
|
||||||
How the engineering skills should consume this repo's domain documentation when exploring the codebase.
|
|
||||||
|
|
||||||
## Before exploring, read these
|
|
||||||
|
|
||||||
- **`CONTEXT.md`** at the repo root, or
|
|
||||||
- **`CONTEXT-MAP.md`** at the repo root if it exists — it points at one `CONTEXT.md` per context. Read each one relevant to the topic.
|
|
||||||
- **`docs/adr/`** — read ADRs that touch the area you're about to work in. In multi-context repos, also check `src/<context>/docs/adr/` for context-scoped decisions.
|
|
||||||
|
|
||||||
If any of these files don't exist, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The `/domain-modeling` skill (reached via `/grill-with-docs` and `/improve-codebase-architecture`) creates them lazily when terms or decisions actually get resolved.
|
|
||||||
|
|
||||||
## File structure
|
|
||||||
|
|
||||||
Single-context repo (most repos):
|
|
||||||
|
|
||||||
```
|
|
||||||
/
|
|
||||||
├── CONTEXT.md
|
|
||||||
├── docs/adr/
|
|
||||||
│ ├── 0001-event-sourced-orders.md
|
|
||||||
│ └── 0002-postgres-for-write-model.md
|
|
||||||
└── src/
|
|
||||||
```
|
|
||||||
|
|
||||||
Multi-context repo (presence of `CONTEXT-MAP.md` at the root):
|
|
||||||
|
|
||||||
```
|
|
||||||
/
|
|
||||||
├── CONTEXT-MAP.md
|
|
||||||
├── docs/adr/ ← system-wide decisions
|
|
||||||
└── src/
|
|
||||||
├── ordering/
|
|
||||||
│ ├── CONTEXT.md
|
|
||||||
│ └── docs/adr/ ← context-specific decisions
|
|
||||||
└── billing/
|
|
||||||
├── CONTEXT.md
|
|
||||||
└── docs/adr/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Use the glossary's vocabulary
|
|
||||||
|
|
||||||
When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `CONTEXT.md`. Don't drift to synonyms the glossary explicitly avoids.
|
|
||||||
|
|
||||||
If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/domain-modeling`).
|
|
||||||
|
|
||||||
## Flag ADR conflicts
|
|
||||||
|
|
||||||
If your output contradicts an existing ADR, surface it explicitly rather than silently overriding:
|
|
||||||
|
|
||||||
> _Contradicts ADR-0007 (event-sourced orders) — but worth reopening because…_
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# Issue tracker: GitHub
|
|
||||||
|
|
||||||
Issues and PRDs for this repo live as GitHub issues. Use the `gh` CLI for all operations.
|
|
||||||
|
|
||||||
## Conventions
|
|
||||||
|
|
||||||
- **Create an issue**: `gh issue create --title "..." --body "..."`. Use a heredoc for multi-line bodies.
|
|
||||||
- **Read an issue**: `gh issue view <number> --comments`, filtering comments by `jq` and also fetching labels.
|
|
||||||
- **List issues**: `gh issue list --state open --json number,title,body,labels,comments --jq '[.[] | {number, title, body, labels: [.labels[].name], comments: [.comments[].body]}]'` with appropriate `--label` and `--state` filters.
|
|
||||||
- **Comment on an issue**: `gh issue comment <number> --body "..."`
|
|
||||||
- **Apply / remove labels**: `gh issue edit <number> --add-label "..."` / `--remove-label "..."`
|
|
||||||
- **Close**: `gh issue close <number> --comment "..."`
|
|
||||||
|
|
||||||
Infer the repo from `git remote -v` — `gh` does this automatically when run inside a clone.
|
|
||||||
|
|
||||||
## Pull requests as a triage surface
|
|
||||||
|
|
||||||
**PRs as a request surface: no.** _(Set to `yes` if this repo treats external PRs as feature requests; `/triage` reads this flag.)_
|
|
||||||
|
|
||||||
When set to `yes`, PRs run through the same labels and states as issues, using the `gh pr` equivalents:
|
|
||||||
|
|
||||||
- **Read a PR**: `gh pr view <number> --comments` and `gh pr diff <number>` for the diff.
|
|
||||||
- **List external PRs for triage**: `gh pr list --state open --json number,title,body,labels,author,authorAssociation,comments` then keep only `authorAssociation` of `CONTRIBUTOR`, `FIRST_TIME_CONTRIBUTOR`, or `NONE` (drop `OWNER`/`MEMBER`/`COLLABORATOR`).
|
|
||||||
- **Comment / label / close**: `gh pr comment`, `gh pr edit --add-label`/`--remove-label`, `gh pr close`.
|
|
||||||
|
|
||||||
GitHub shares one number space across issues and PRs, so a bare `#42` may be either — resolve with `gh pr view 42` and fall back to `gh issue view 42`.
|
|
||||||
|
|
||||||
## When a skill says "publish to the issue tracker"
|
|
||||||
|
|
||||||
Create a GitHub issue.
|
|
||||||
|
|
||||||
## When a skill says "fetch the relevant ticket"
|
|
||||||
|
|
||||||
Run `gh issue view <number> --comments`.
|
|
||||||
|
|
||||||
## Wayfinding operations
|
|
||||||
|
|
||||||
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
|
|
||||||
|
|
||||||
- **Map**: a single issue labelled `wayfinder:map`, holding the Notes / Decisions-so-far / Fog body. `gh issue create --label wayfinder:map`.
|
|
||||||
- **Child ticket**: an issue linked to the map as a GitHub sub-issue (`gh api` on the sub-issues endpoint). Where sub-issues aren't enabled, add the child to a task list in the map body and put `Part of #<map>` at the top of the child body. Labels: `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`). Once claimed, the ticket is assigned to the driving dev.
|
|
||||||
- **Blocking**: GitHub's **native issue dependencies** — the canonical, UI-visible representation. Add an edge with `gh api --method POST repos/<owner>/<repo>/issues/<child>/dependencies/blocked_by -F issue_id=<blocker-db-id>`, where `<blocker-db-id>` is the blocker's numeric **database id** (`gh api repos/<owner>/<repo>/issues/<n> --jq .id`, _not_ the `#number` or `node_id`). GitHub reports `issue_dependencies_summary.blocked_by` (open blockers only — the live gate). Where dependencies aren't available, fall back to a `Blocked by: #<n>, #<n>` line at the top of the child body. A ticket is unblocked when every blocker is closed.
|
|
||||||
- **Frontier query**: list the map's open children (`gh issue list --state open`, scoped to the map's sub-issues / task list), drop any with an open blocker (`issue_dependencies_summary.blocked_by > 0`, or an open issue in the `Blocked by` line) or an assignee; first in map order wins.
|
|
||||||
- **Claim**: `gh issue edit <n> --add-assignee @me` — the session's first write.
|
|
||||||
- **Resolve**: `gh issue comment <n> --body "<answer>"`, then `gh issue close <n>`, then append a context pointer (gist + link) to the map's Decisions-so-far.
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# Issue tracker: GitLab
|
|
||||||
|
|
||||||
Issues and PRDs for this repo live as GitLab issues. Use the [`glab`](https://gitlab.com/gitlab-org/cli) CLI for all operations.
|
|
||||||
|
|
||||||
## Conventions
|
|
||||||
|
|
||||||
- **Create an issue**: `glab issue create --title "..." --description "..."`. Use a heredoc for multi-line descriptions. Pass `--description -` to open an editor.
|
|
||||||
- **Read an issue**: `glab issue view <number> --comments`. Use `-F json` for machine-readable output.
|
|
||||||
- **List issues**: `glab issue list -F json` with appropriate `--label` filters.
|
|
||||||
- **Comment on an issue**: `glab issue note <number> --message "..."`. GitLab calls comments "notes".
|
|
||||||
- **Apply / remove labels**: `glab issue update <number> --label "..."` / `--unlabel "..."`. Multiple labels can be comma-separated or by repeating the flag.
|
|
||||||
- **Close**: `glab issue close <number>`. `glab issue close` does not accept a closing comment, so post the explanation first with `glab issue note <number> --message "..."`, then close.
|
|
||||||
- **Merge requests**: GitLab calls PRs "merge requests". Use `glab mr create`, `glab mr view`, `glab mr note`, etc. — the same shape as `gh pr ...` with `mr` in place of `pr` and `note`/`--message` in place of `comment`/`--body`.
|
|
||||||
|
|
||||||
Infer the repo from `git remote -v` — `glab` does this automatically when run inside a clone.
|
|
||||||
|
|
||||||
## Merge requests as a triage surface
|
|
||||||
|
|
||||||
**MRs as a request surface: no.** _(Set to `yes` if this repo treats external merge requests as feature requests; `/triage` reads this flag.)_
|
|
||||||
|
|
||||||
When set to `yes`, MRs run through the same labels and states as issues, using the `glab mr` equivalents:
|
|
||||||
|
|
||||||
- **Read an MR**: `glab mr view <number> --comments` and `glab mr diff <number>` for the diff.
|
|
||||||
- **List external MRs for triage**: `glab mr list -F json`, then keep only MRs whose author is not a project member/owner (a contributor's MR, not a maintainer's in-flight work).
|
|
||||||
- **Comment / label / close**: `glab mr note`, `glab mr update --label`/`--unlabel`, `glab mr close`.
|
|
||||||
|
|
||||||
Unlike GitHub, GitLab numbers issues and MRs separately, so `#42` is unambiguous once you know which surface the maintainer means.
|
|
||||||
|
|
||||||
## When a skill says "publish to the issue tracker"
|
|
||||||
|
|
||||||
Create a GitLab issue.
|
|
||||||
|
|
||||||
## When a skill says "fetch the relevant ticket"
|
|
||||||
|
|
||||||
Run `glab issue view <number> --comments`.
|
|
||||||
|
|
||||||
## Wayfinding operations
|
|
||||||
|
|
||||||
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
|
|
||||||
|
|
||||||
- **Map**: a single issue labelled `wayfinder:map`, holding the Notes / Decisions-so-far / Fog body. `glab issue create --label wayfinder:map`. (On GitLab tiers with native epics, an epic may hold the map instead; a labelled issue works everywhere.)
|
|
||||||
- **Child ticket**: an issue carrying `Part of #<map>` at the top of its description and labels `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`). Once claimed, the ticket is assigned to the driving dev.
|
|
||||||
- **Blocking**: GitLab's **native blocking link** — the canonical, UI-visible representation. Add it with the `/blocked_by #<n>` quick action, posted as a note (`glab issue note <child> --message "/blocked_by #<blocker>"`). Native blocking links are a Premium/Ultimate feature; on the free tier (or where unavailable) fall back to a `Blocked by: #<n>, #<n>` line at the top of the description. A ticket is unblocked when every blocker is closed.
|
|
||||||
- **Frontier query**: `glab issue list -F json` scoped to the map's children, drop any with an open blocker — a native `blocked_by` link to an open issue (`glab api projects/:id/issues/:iid/links`), or an open issue in the `Blocked by` line — or an assignee; first in map order wins.
|
|
||||||
- **Claim**: `glab issue update <n> --assignee @me` — the session's first write.
|
|
||||||
- **Resolve**: `glab issue note <n> --message "<answer>"`, then `glab issue close <n>`, then append a context pointer (gist + link) to the map's Decisions-so-far.
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
# Issue tracker: Local Markdown
|
|
||||||
|
|
||||||
Issues and specs (you may know a spec as a PRD) for this repo live as markdown files in `.scratch/`.
|
|
||||||
|
|
||||||
## Conventions
|
|
||||||
|
|
||||||
- One feature per directory: `.scratch/<feature-slug>/`
|
|
||||||
- The spec is `.scratch/<feature-slug>/spec.md`
|
|
||||||
- Implementation issues are one file per ticket at `.scratch/<feature-slug>/issues/<NN>-<slug>.md`, numbered from `01` — never a single combined tickets file
|
|
||||||
- Triage state is recorded as a `Status:` line near the top of each issue file (see `triage-labels.md` for the role strings)
|
|
||||||
- Comments and conversation history append to the bottom of the file under a `## Comments` heading
|
|
||||||
|
|
||||||
## When a skill says "publish to the issue tracker"
|
|
||||||
|
|
||||||
Create a new file under `.scratch/<feature-slug>/` (creating the directory if needed).
|
|
||||||
|
|
||||||
## When a skill says "fetch the relevant ticket"
|
|
||||||
|
|
||||||
Read the file at the referenced path. The user will normally pass the path or the issue number directly.
|
|
||||||
|
|
||||||
## Wayfinding operations
|
|
||||||
|
|
||||||
Used by `/wayfinder`. The **map** is a file with one **child** file per ticket.
|
|
||||||
|
|
||||||
- **Map**: `.scratch/<effort>/map.md` — the Notes / Decisions-so-far / Fog body.
|
|
||||||
- **Child ticket**: `.scratch/<effort>/issues/NN-<slug>.md`, numbered from `01`, with the question in the body. A `Type:` line records the ticket type (`research`/`prototype`/`grilling`/`task`); a `Status:` line records `claimed`/`resolved`.
|
|
||||||
- **Blocking**: a `Blocked by: NN, NN` line near the top. A ticket is unblocked when every file it lists is `resolved`.
|
|
||||||
- **Frontier**: scan `.scratch/<effort>/issues/` for files that are open, unblocked, and unclaimed; first by number wins.
|
|
||||||
- **Claim**: set `Status: claimed` and save before any work.
|
|
||||||
- **Resolve**: append the answer under an `## Answer` heading, set `Status: resolved`, then append a context pointer (gist + link) to the map's Decisions-so-far in `map.md`.
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
# Triage Labels
|
|
||||||
|
|
||||||
The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
|
|
||||||
|
|
||||||
| Label in mattpocock/skills | Label in our tracker | Meaning |
|
|
||||||
| -------------------------- | -------------------- | ---------------------------------------- |
|
|
||||||
| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue |
|
|
||||||
| `needs-info` | `needs-info` | Waiting on reporter for more information |
|
|
||||||
| `ready-for-agent` | `ready-for-agent` | Fully specified, ready for an AFK agent |
|
|
||||||
| `ready-for-human` | `ready-for-human` | Requires human implementation |
|
|
||||||
| `wontfix` | `wontfix` | Will not be actioned |
|
|
||||||
|
|
||||||
When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table.
|
|
||||||
|
|
||||||
Edit the right-hand column to match whatever vocabulary you actually use.
|
|
||||||
@@ -1,12 +1,33 @@
|
|||||||
## Agent skills
|
## Related repositories
|
||||||
|
|
||||||
|
This is the Data Controller **marketing site, blog and feed** (Gatsby). It has two sibling repos, usually checked out side by side:
|
||||||
|
|
||||||
|
- **`dc`** - the product source (Angular client + SAS backend). Behaviour of the product itself is defined there; see its `CONTEXT.md` for the domain glossary.
|
||||||
|
- **`docs.datacontroller.io`** - the user-facing product documentation (MkDocs), published at docs.datacontroller.io.
|
||||||
|
|
||||||
|
When writing marketing/blog/feed copy about a feature, treat `docs.datacontroller.io` and `dc` as the source of truth for how the product actually behaves.
|
||||||
|
|
||||||
|
## Content structure
|
||||||
|
|
||||||
|
- **Blog** (`content/blog/`) - long-form articles, published at `/blog/`.
|
||||||
|
- **Feed** (`content/feed/`) - short announcements, published at `/feed/`.
|
||||||
|
- Both are combined into a single RSS feed at `/rss.xml`.
|
||||||
|
- To add a feed post, use the `add-feed-post` skill (`.agents/skills/add-feed-post/SKILL.md`).
|
||||||
|
|
||||||
|
## Agent files
|
||||||
|
|
||||||
|
All agent-facing material lives under `.agents/`:
|
||||||
|
|
||||||
|
- `.agents/skills/` - pi-discovered skills (e.g. `add-feed-post`).
|
||||||
|
- `.agents/docs/` - reference docs consumed by skills and these instructions.
|
||||||
|
|
||||||
### Issue tracker
|
### Issue tracker
|
||||||
|
|
||||||
Issues live as markdown files under `.scratch/`. See `docs/agents/issue-tracker.md`.
|
Issues live as markdown files under `.scratch/`. See `.agents/docs/issue-tracker.md`.
|
||||||
|
|
||||||
### Domain docs
|
### Domain docs
|
||||||
|
|
||||||
Single-context layout - `CONTEXT.md` + `docs/adr/` at the repo root. See `docs/agents/domain.md`.
|
Single-context layout - `CONTEXT.md` at the repo root + ADRs in `.agents/adr/`. See `.agents/docs/domain.md`.
|
||||||
|
|
||||||
### Writing style
|
### Writing style
|
||||||
|
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
# Context: datacontroller.io (marketing site)
|
||||||
|
|
||||||
|
The public marketing website for Data Controller for SAS®, built with **Gatsby** (React + TypeScript, styled-components). It hosts the product's marketing pages, blog and feed. It is separate from the product itself (`dc`) and the product documentation (`docs.datacontroller.io`).
|
||||||
|
|
||||||
|
## What the product is
|
||||||
|
|
||||||
|
Data Controller for SAS® is a web application that lets users safely add, modify and delete data in SAS datasets and databases, with an edit-stage-approve workflow and full change history. It runs on SAS Viya, SAS 9 EBI and SASjs Server. For the product's own domain vocabulary (roles, load types, MPE control tables, validations, security), see `dc/CONTEXT.md`; for user-facing feature docs, see the `docs.datacontroller.io` repo. Treat those as the source of truth when writing copy about how the product behaves.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
- `content/blog/` - long-form articles (published at `/blog/`).
|
||||||
|
- `content/feed/` - short announcements (published at `/feed/`). See the `add-feed-post` skill.
|
||||||
|
- `src/pages/` - top-level pages (`index`, `about`, `contact`, `faq`, plus the markdown-driven `{MarkdownRemark.frontmatter__slug}.tsx`).
|
||||||
|
- `src/markdown-pages/` - standalone markdown pages (e.g. `pricing.md`).
|
||||||
|
- `src/templates/` - list/post/sidebar templates for blog and feed.
|
||||||
|
- `src/components/` - shared React components (layout, navibar, footer, hero, seo).
|
||||||
|
- `static/` - static assets served as-is; `gatsby-*.js` - Gatsby config (feed, node APIs, etc.).
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Use regular dashes (`-`) in content, not em-dashes.
|
||||||
|
- Blog and feed share a single combined RSS feed at `/rss.xml` (via `gatsby-plugin-feed`); new posts appear automatically on the next build.
|
||||||
|
- Lint with `npm run lint` (prettier) and typecheck with `npm run typecheck` before considering front-end changes done.
|
||||||
|
- Preview locally with `npm run develop`.
|
||||||
|
|
||||||
|
## Agent files
|
||||||
|
|
||||||
|
All agent-facing material lives under `.agents/`: skills in `.agents/skills/` (e.g. `add-feed-post`), and reference docs in `.agents/docs/` (`domain.md`, `issue-tracker.md`).
|
||||||
|
|
||||||
|
See `AGENTS.md` for agent skills, writing rules, and where these files live.
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
title: 'FSEDIT-Style Paging in the Edit Record Form'
|
||||||
|
description: Page through your data one record at a time in the Edit Record dialog - a modern take on the classic SAS PROC FSEDIT full-screen editor.
|
||||||
|
date: '2026-07-30 09:00:00'
|
||||||
|
author: 'Data Controller'
|
||||||
|
authorLink: https://www.linkedin.com/showcase/data_controller
|
||||||
|
tags:
|
||||||
|
- Announcements
|
||||||
|
---
|
||||||
|
|
||||||
|
# FSEDIT-Style Paging in the Edit Record Form
|
||||||
|
|
||||||
|
Anyone who has worked with SAS for a while will remember `PROC FSEDIT` - the full-screen editor that let you step through a dataset one observation at a time, seeing every variable for a single record laid out on screen. It was a simple, focused way to review and amend data without getting lost in a wide grid.
|
||||||
|
|
||||||
|
Data Controller's **Edit Record** dialog brings that experience into the browser. Instead of scanning across dozens of columns in the grid, you open a single row as a form - every field labelled and stacked vertically, with dropdowns, validations and formatting applied just as they are in the main editor.
|
||||||
|
|
||||||
|
Now you can **page through your records** without leaving the form. Previous and Next arrows move you one record at a time, and a **Current row** indicator shows exactly where you are in the extract. It's the fastest way to work through a set of rows methodically - reviewing, correcting and moving on - especially for wide tables where horizontal scrolling in the grid slows you down.
|
||||||
|
|
||||||
|
As always, everything flows through the standard Data Controller workflow: your changes are staged, validated and sent for approval before they reach the target table, with a full audit trail retained.
|
||||||
|
|
||||||
|
Administrators who prefer to keep the grid-only experience can still disable the dialog with the [`DC_RESTRICT_EDITRECORD`](https://docs.datacontroller.io/dcc-options/#dc_restrict_editrecord) option.
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
# Domain Docs
|
|
||||||
|
|
||||||
How the engineering skills should consume this repo's domain documentation when exploring the codebase.
|
|
||||||
|
|
||||||
## Before exploring, read these
|
|
||||||
|
|
||||||
- **`CONTEXT.md`** at the repo root, or
|
|
||||||
- **`CONTEXT-MAP.md`** at the repo root if it exists — it points at one `CONTEXT.md` per context. Read each one relevant to the topic.
|
|
||||||
- **`docs/adr/`** — read ADRs that touch the area you're about to work in. In multi-context repos, also check `src/<context>/docs/adr/` for context-scoped decisions.
|
|
||||||
|
|
||||||
If any of these files don't exist, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The `/domain-modeling` skill (reached via `/grill-with-docs` and `/improve-codebase-architecture`) creates them lazily when terms or decisions actually get resolved.
|
|
||||||
|
|
||||||
## File structure
|
|
||||||
|
|
||||||
Single-context repo (most repos):
|
|
||||||
|
|
||||||
```
|
|
||||||
/
|
|
||||||
├── CONTEXT.md
|
|
||||||
├── docs/adr/
|
|
||||||
│ ├── 0001-event-sourced-orders.md
|
|
||||||
│ └── 0002-postgres-for-write-model.md
|
|
||||||
└── src/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Use the glossary's vocabulary
|
|
||||||
|
|
||||||
When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `CONTEXT.md`. Don't drift to synonyms the glossary explicitly avoids.
|
|
||||||
|
|
||||||
If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/domain-modeling`).
|
|
||||||
|
|
||||||
## Flag ADR conflicts
|
|
||||||
|
|
||||||
If your output contradicts an existing ADR, surface it explicitly rather than silently overriding:
|
|
||||||
|
|
||||||
> _Contradicts ADR-0007 (event-sourced orders) — but worth reopening because…_
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
# Issue tracker: Local Markdown
|
|
||||||
|
|
||||||
Issues and specs (you may know a spec as a PRD) for this repo live as markdown files in `.scratch/`.
|
|
||||||
|
|
||||||
## Conventions
|
|
||||||
|
|
||||||
- One feature per directory: `.scratch/<feature-slug>/`
|
|
||||||
- The spec is `.scratch/<feature-slug>/spec.md`
|
|
||||||
- Implementation issues are one file per ticket at `.scratch/<feature-slug>/issues/<NN>-<slug>.md`, numbered from `01` — never a single combined tickets file
|
|
||||||
- Triage state is recorded as a `Status:` line near the top of each issue file (see `triage-labels.md` for the role strings)
|
|
||||||
- Comments and conversation history append to the bottom of the file under a `## Comments` heading
|
|
||||||
|
|
||||||
## When a skill says "publish to the issue tracker"
|
|
||||||
|
|
||||||
Create a new file under `.scratch/<feature-slug>/` (creating the directory if needed).
|
|
||||||
|
|
||||||
## When a skill says "fetch the relevant ticket"
|
|
||||||
|
|
||||||
Read the file at the referenced path. The user will normally pass the path or the issue number directly.
|
|
||||||
|
|
||||||
## Wayfinding operations
|
|
||||||
|
|
||||||
Used by `/wayfinder`. The **map** is a file with one **child** file per ticket.
|
|
||||||
|
|
||||||
- **Map**: `.scratch/<effort>/map.md` — the Notes / Decisions-so-far / Fog body.
|
|
||||||
- **Child ticket**: `.scratch/<effort>/issues/NN-<slug>.md`, numbered from `01`, with the question in the body. A `Type:` line records the ticket type (`research`/`prototype`/`grilling`/`task`); a `Status:` line records `claimed`/`resolved`.
|
|
||||||
- **Blocking**: a `Blocked by: NN, NN` line near the top. A ticket is unblocked when every file it lists is `resolved`.
|
|
||||||
- **Frontier**: scan `.scratch/<effort>/issues/` for files that are open, unblocked, and unclaimed; first by number wins.
|
|
||||||
- **Claim**: set `Status: claimed` and save before any work.
|
|
||||||
- **Resolve**: append the answer under an `## Answer` heading, set `Status: resolved`, then append a context pointer (gist + link) to the map's Decisions-so-far in `map.md`.
|
|
||||||
Reference in New Issue
Block a user