waypoint-codex 0.7.0 → 0.8.1
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.
- package/README.md +16 -7
- package/dist/src/cli.js +14 -3
- package/dist/src/core.js +71 -6
- package/dist/src/track-index.js +107 -0
- package/dist/src/upgrade.js +100 -0
- package/package.json +1 -1
- package/templates/.agents/skills/code-guide-audit/SKILL.md +2 -0
- package/templates/.agents/skills/planning/SKILL.md +2 -0
- package/templates/.agents/skills/work-tracker/SKILL.md +110 -0
- package/templates/.agents/skills/workspace-compress/SKILL.md +3 -0
- package/templates/.waypoint/agent-operating-manual.md +5 -4
- package/templates/.waypoint/docs/README.md +2 -0
- package/templates/.waypoint/scripts/build-track-index.mjs +169 -0
- package/templates/.waypoint/scripts/prepare-context.mjs +24 -0
- package/templates/.waypoint/track/README.md +38 -0
- package/templates/.waypoint/track/_template.md +44 -0
- package/templates/WORKSPACE.md +5 -1
- package/templates/managed-agents-block.md +2 -0
- package/templates/.agents/skills/error-audit/SKILL.md +0 -69
- package/templates/.agents/skills/error-audit/references/error-patterns.md +0 -37
- package/templates/.agents/skills/observability-audit/SKILL.md +0 -67
- package/templates/.agents/skills/observability-audit/references/observability-patterns.md +0 -35
- package/templates/.agents/skills/ux-states-audit/SKILL.md +0 -63
- package/templates/.agents/skills/ux-states-audit/references/ux-patterns.md +0 -34
|
@@ -33,8 +33,9 @@ Do not skip this sequence.
|
|
|
33
33
|
The repository should contain the context the next agent needs.
|
|
34
34
|
|
|
35
35
|
- `.waypoint/WORKSPACE.md` is the live operational record: in progress, current state, next steps
|
|
36
|
+
- `.waypoint/track/` is the durable execution-tracking layer for active long-running work
|
|
36
37
|
- `.waypoint/docs/` is the durable project memory: architecture, decisions, integration notes, debugging knowledge, and durable plans
|
|
37
|
-
- `.waypoint/context/` is the generated session context bundle: current git/PR/doc index state
|
|
38
|
+
- `.waypoint/context/` is the generated session context bundle: current git/PR/doc/track index state
|
|
38
39
|
|
|
39
40
|
If something important lives only in your head or in the chat transcript, the repo is under-documented.
|
|
40
41
|
|
|
@@ -43,8 +44,10 @@ If something important lives only in your head or in the chat transcript, the re
|
|
|
43
44
|
- Read code before editing it.
|
|
44
45
|
- Follow the repo's documented patterns when they are healthy.
|
|
45
46
|
- Update `.waypoint/WORKSPACE.md` as live execution state when progress meaningfully changes. In multi-topic sections, prefix new or materially revised bullets with a local timestamp like `[2026-03-06 20:10 PST]`.
|
|
47
|
+
- For large multi-step work, create or update a tracker in `.waypoint/track/`, keep detailed execution state there, and point at it from `## Active Trackers` in `.waypoint/WORKSPACE.md`.
|
|
46
48
|
- Update `.waypoint/docs/` when durable knowledge changes, and refresh each changed routable doc's `last_updated` field.
|
|
47
49
|
- Rebuild `.waypoint/DOCS_INDEX.md` whenever routable docs change.
|
|
50
|
+
- Rebuild `.waypoint/TRACKS_INDEX.md` whenever tracker files change.
|
|
48
51
|
- Use the repo-local skills and optional reviewer agents instead of improvising from scratch.
|
|
49
52
|
- Do not kill long-running subagents or reviewer agents just because they are slow. Wait unless they are clearly stuck, failed, or the user redirects the work.
|
|
50
53
|
|
|
@@ -64,9 +67,7 @@ Do not document every trivial implementation detail. Document the non-obvious, d
|
|
|
64
67
|
## When to use Waypoint skills
|
|
65
68
|
|
|
66
69
|
- `planning` for non-trivial changes
|
|
67
|
-
- `
|
|
68
|
-
- `observability-audit` when production debugging signals look weak
|
|
69
|
-
- `ux-states-audit` when async/data-driven UI likely lacks loading, empty, or error states
|
|
70
|
+
- `work-tracker` when large multi-step work needs durable progress tracking in `.waypoint/track/`
|
|
70
71
|
- `docs-sync` when routed docs may be stale, missing, or inconsistent with the codebase
|
|
71
72
|
- `code-guide-audit` when a specific feature or file set needs a targeted coding-guide compliance check
|
|
72
73
|
- `break-it-qa` when a browser-facing feature should be attacked with invalid inputs, refreshes, repeated clicks, wrong action order, or other adversarial manual QA
|
|
@@ -13,6 +13,8 @@ Put the durable context here that the next agent will need to continue the work:
|
|
|
13
13
|
|
|
14
14
|
These are **project docs**, not Waypoint internals.
|
|
15
15
|
|
|
16
|
+
Do not use `.waypoint/docs/` as the execution tracker layer for active long-running work. That belongs under `.waypoint/track/`.
|
|
17
|
+
|
|
16
18
|
Every routable doc needs YAML frontmatter:
|
|
17
19
|
|
|
18
20
|
```yaml
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const VALID_TRACK_STATUSES = new Set(["active", "blocked", "paused", "done", "archived"]);
|
|
8
|
+
const ACTIVE_TRACK_STATUSES = new Set(["active", "blocked", "paused"]);
|
|
9
|
+
const SKIP_NAMES = new Set(["README.md", "CHANGELOG.md", "LICENSE.md"]);
|
|
10
|
+
|
|
11
|
+
export function findProjectRoot(startDir) {
|
|
12
|
+
let current = path.resolve(startDir);
|
|
13
|
+
while (true) {
|
|
14
|
+
if (existsSync(path.join(current, ".waypoint", "config.toml"))) {
|
|
15
|
+
return current;
|
|
16
|
+
}
|
|
17
|
+
const parent = path.dirname(current);
|
|
18
|
+
if (parent === current) {
|
|
19
|
+
return path.resolve(startDir);
|
|
20
|
+
}
|
|
21
|
+
current = parent;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function detectProjectRoot() {
|
|
26
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
const scriptBasedRoot = findProjectRoot(path.resolve(scriptDir, "../.."));
|
|
28
|
+
if (existsSync(path.join(scriptBasedRoot, ".waypoint", "config.toml"))) {
|
|
29
|
+
return scriptBasedRoot;
|
|
30
|
+
}
|
|
31
|
+
return findProjectRoot(process.cwd());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function shouldSkipTrackFile(entry) {
|
|
35
|
+
return SKIP_NAMES.has(entry) || entry.startsWith("_");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseFrontmatter(filePath) {
|
|
39
|
+
const text = readFileSync(filePath, "utf8");
|
|
40
|
+
if (!text.startsWith("---\n")) {
|
|
41
|
+
return { summary: "", lastUpdated: "", readWhen: [], status: "" };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const endIndex = text.indexOf("\n---\n", 4);
|
|
45
|
+
if (endIndex === -1) {
|
|
46
|
+
return { summary: "", lastUpdated: "", readWhen: [], status: "" };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const frontmatter = text.slice(4, endIndex);
|
|
50
|
+
let summary = "";
|
|
51
|
+
let lastUpdated = "";
|
|
52
|
+
let status = "";
|
|
53
|
+
const readWhen = [];
|
|
54
|
+
let collectingReadWhen = false;
|
|
55
|
+
|
|
56
|
+
for (const rawLine of frontmatter.split("\n")) {
|
|
57
|
+
const line = rawLine.trim();
|
|
58
|
+
if (line.startsWith("summary:")) {
|
|
59
|
+
summary = line.slice("summary:".length).trim().replace(/^['"]|['"]$/g, "");
|
|
60
|
+
collectingReadWhen = false;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (line.startsWith("last_updated:")) {
|
|
64
|
+
lastUpdated = line.slice("last_updated:".length).trim().replace(/^['"]|['"]$/g, "");
|
|
65
|
+
collectingReadWhen = false;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (line.startsWith("status:")) {
|
|
69
|
+
status = line.slice("status:".length).trim().replace(/^['"]|['"]$/g, "").toLowerCase();
|
|
70
|
+
collectingReadWhen = false;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (line.startsWith("read_when:")) {
|
|
74
|
+
collectingReadWhen = true;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (collectingReadWhen && line.startsWith("- ")) {
|
|
78
|
+
readWhen.push(line.slice(2).trim());
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (collectingReadWhen && line.length > 0) {
|
|
82
|
+
collectingReadWhen = false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return { summary, lastUpdated, readWhen, status };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function walkTracks(projectRoot, currentDir, output, invalid) {
|
|
90
|
+
for (const entry of readdirSync(currentDir)) {
|
|
91
|
+
const fullPath = path.join(currentDir, entry);
|
|
92
|
+
const stat = statSync(fullPath);
|
|
93
|
+
if (stat.isDirectory()) {
|
|
94
|
+
walkTracks(projectRoot, fullPath, output, invalid);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!entry.endsWith(".md") || shouldSkipTrackFile(entry)) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const { summary, lastUpdated, readWhen, status } = parseFrontmatter(fullPath);
|
|
103
|
+
if (!summary || !lastUpdated || readWhen.length === 0 || !VALID_TRACK_STATUSES.has(status)) {
|
|
104
|
+
invalid.push(path.relative(projectRoot, fullPath));
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
output.push({
|
|
109
|
+
path: path.relative(projectRoot, fullPath),
|
|
110
|
+
summary,
|
|
111
|
+
readWhen,
|
|
112
|
+
status,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function renderTracksIndex(projectRoot) {
|
|
118
|
+
const trackDir = path.join(projectRoot, ".waypoint", "track");
|
|
119
|
+
const entries = [];
|
|
120
|
+
const invalidTracks = [];
|
|
121
|
+
|
|
122
|
+
if (existsSync(trackDir)) {
|
|
123
|
+
walkTracks(projectRoot, trackDir, entries, invalidTracks);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const lines = [
|
|
127
|
+
"# Tracks Index",
|
|
128
|
+
"",
|
|
129
|
+
"Auto-generated by `.waypoint/scripts/build-track-index.mjs`. Read active trackers when resuming long-running work.",
|
|
130
|
+
"",
|
|
131
|
+
"## .waypoint/track/",
|
|
132
|
+
"",
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
if (entries.length === 0) {
|
|
136
|
+
lines.push("No tracker files found.");
|
|
137
|
+
} else {
|
|
138
|
+
entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
139
|
+
for (const entry of entries) {
|
|
140
|
+
lines.push(`- **${entry.path}** — [${entry.status}] ${entry.summary}`);
|
|
141
|
+
lines.push(` Read when: ${entry.readWhen.join("; ")}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
lines.push("");
|
|
146
|
+
return {
|
|
147
|
+
content: `${lines.join("\n")}\n`,
|
|
148
|
+
invalidTracks,
|
|
149
|
+
activeTracks: entries
|
|
150
|
+
.filter((entry) => ACTIVE_TRACK_STATUSES.has(entry.status))
|
|
151
|
+
.map((entry) => entry.path)
|
|
152
|
+
.sort((a, b) => a.localeCompare(b)),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function writeTracksIndex(projectRoot) {
|
|
157
|
+
const outputPath = path.join(projectRoot, ".waypoint", "TRACKS_INDEX.md");
|
|
158
|
+
const rendered = renderTracksIndex(projectRoot);
|
|
159
|
+
writeFileSync(outputPath, rendered.content, "utf8");
|
|
160
|
+
return { outputPath, activeTracks: rendered.activeTracks, invalidTracks: rendered.invalidTracks };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const isDirectExecution = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
164
|
+
|
|
165
|
+
if (isDirectExecution) {
|
|
166
|
+
const projectRoot = detectProjectRoot();
|
|
167
|
+
const { outputPath } = writeTracksIndex(projectRoot);
|
|
168
|
+
console.log(`Wrote ${outputPath}`);
|
|
169
|
+
}
|
|
@@ -7,6 +7,7 @@ import path from "node:path";
|
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
|
|
9
9
|
import { findProjectRoot, writeDocsIndex } from "./build-docs-index.mjs";
|
|
10
|
+
import { writeTracksIndex } from "./build-track-index.mjs";
|
|
10
11
|
|
|
11
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
13
|
const __dirname = path.dirname(__filename);
|
|
@@ -437,6 +438,21 @@ function writeContextFile(contextDir, name, title, body) {
|
|
|
437
438
|
return filePath;
|
|
438
439
|
}
|
|
439
440
|
|
|
441
|
+
function writeActiveTrackers(contextDir, projectRoot, activeTracks) {
|
|
442
|
+
return writeContextFile(
|
|
443
|
+
contextDir,
|
|
444
|
+
"ACTIVE_TRACKERS.md",
|
|
445
|
+
"Active Trackers",
|
|
446
|
+
activeTracks.length === 0
|
|
447
|
+
? "No active tracker files found."
|
|
448
|
+
: [
|
|
449
|
+
"These trackers should be read when resuming long-running work:",
|
|
450
|
+
"",
|
|
451
|
+
...activeTracks.map((trackPath) => `- \`${trackPath}\``),
|
|
452
|
+
].join("\n"),
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
|
|
440
456
|
function main() {
|
|
441
457
|
const projectRoot = detectProjectRoot();
|
|
442
458
|
const contextDir = path.join(projectRoot, ".waypoint", "context");
|
|
@@ -448,6 +464,7 @@ function main() {
|
|
|
448
464
|
: null;
|
|
449
465
|
|
|
450
466
|
const docsIndexPath = writeDocsIndex(projectRoot);
|
|
467
|
+
const { outputPath: tracksIndexPath, activeTracks } = writeTracksIndex(projectRoot);
|
|
451
468
|
|
|
452
469
|
const currentDatetimePath = writeContextFile(
|
|
453
470
|
contextDir,
|
|
@@ -590,6 +607,7 @@ function main() {
|
|
|
590
607
|
].join("\n")
|
|
591
608
|
);
|
|
592
609
|
const recentThreadPath = writeRecentThread(contextDir, projectRoot, threadIdOverride);
|
|
610
|
+
const activeTrackersPath = writeActiveTrackers(contextDir, projectRoot, activeTracks);
|
|
593
611
|
|
|
594
612
|
const manifestPath = path.join(contextDir, "MANIFEST.md");
|
|
595
613
|
const manifestLines = [
|
|
@@ -606,6 +624,8 @@ function main() {
|
|
|
606
624
|
`- \`${path.relative(projectRoot, prsPath)}\` — open and recently merged pull requests`,
|
|
607
625
|
`- \`${path.relative(projectRoot, recentThreadPath)}\` — latest meaningful turns from the local Codex session for this repo`,
|
|
608
626
|
`- \`${path.relative(projectRoot, docsIndexPath)}\` — current docs index`,
|
|
627
|
+
`- \`${path.relative(projectRoot, tracksIndexPath)}\` — current tracker index`,
|
|
628
|
+
`- \`${path.relative(projectRoot, activeTrackersPath)}\` — active tracker summary`,
|
|
609
629
|
"",
|
|
610
630
|
"## Stable source-of-truth files to read before this manifest",
|
|
611
631
|
"",
|
|
@@ -613,6 +633,10 @@ function main() {
|
|
|
613
633
|
"- `.waypoint/agent-operating-manual.md`",
|
|
614
634
|
"- `.waypoint/WORKSPACE.md`",
|
|
615
635
|
"",
|
|
636
|
+
"## Active tracker files to read after this manifest",
|
|
637
|
+
"",
|
|
638
|
+
...(activeTracks.length > 0 ? activeTracks.map((trackPath) => `- \`${trackPath}\``) : ["- None."]),
|
|
639
|
+
"",
|
|
616
640
|
`Generated by: \`${path.relative(projectRoot, fileURLToPath(import.meta.url))}\``,
|
|
617
641
|
"",
|
|
618
642
|
];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Waypoint Trackers
|
|
2
|
+
|
|
3
|
+
This directory holds active execution trackers for long-running work.
|
|
4
|
+
|
|
5
|
+
Use `.waypoint/track/` when the work is too large to fit safely in `WORKSPACE.md`, especially for:
|
|
6
|
+
|
|
7
|
+
- multi-session implementation campaigns
|
|
8
|
+
- broad audits followed by remediation
|
|
9
|
+
- large fix lists or rollout work
|
|
10
|
+
- verification or review loops that will take time to close
|
|
11
|
+
|
|
12
|
+
Tracker files are **execution state**, not general project memory.
|
|
13
|
+
|
|
14
|
+
- Keep durable architecture, decisions, and long-term reference material in `.waypoint/docs/`.
|
|
15
|
+
- Keep `WORKSPACE.md` short and current.
|
|
16
|
+
- Put detailed checklists, per-item status, blockers, and verification progress in `.waypoint/track/`.
|
|
17
|
+
|
|
18
|
+
Every tracker needs YAML frontmatter:
|
|
19
|
+
|
|
20
|
+
```yaml
|
|
21
|
+
---
|
|
22
|
+
summary: One-line description
|
|
23
|
+
last_updated: "2026-03-13 11:38 PDT"
|
|
24
|
+
status: active
|
|
25
|
+
read_when:
|
|
26
|
+
- resuming the workstream
|
|
27
|
+
---
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Valid tracker statuses:
|
|
31
|
+
|
|
32
|
+
- `active`
|
|
33
|
+
- `blocked`
|
|
34
|
+
- `paused`
|
|
35
|
+
- `done`
|
|
36
|
+
- `archived`
|
|
37
|
+
|
|
38
|
+
`WORKSPACE.md` should point at the active tracker file under `## Active Trackers`.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: One-line description of the workstream
|
|
3
|
+
last_updated: "2026-03-13 11:38 PDT"
|
|
4
|
+
status: active
|
|
5
|
+
read_when:
|
|
6
|
+
- resuming this workstream
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Tracker Title
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
|
|
13
|
+
What outcome this tracker is trying to reach.
|
|
14
|
+
|
|
15
|
+
## Source
|
|
16
|
+
|
|
17
|
+
- User request, audit, plan, or review thread that kicked off the work.
|
|
18
|
+
|
|
19
|
+
## Current State
|
|
20
|
+
|
|
21
|
+
- [2026-03-13 11:38 PDT] Current truth about the work.
|
|
22
|
+
|
|
23
|
+
## Next
|
|
24
|
+
|
|
25
|
+
- [2026-03-13 11:38 PDT] The next concrete action.
|
|
26
|
+
|
|
27
|
+
## Workstreams
|
|
28
|
+
|
|
29
|
+
### 1. Stream Name
|
|
30
|
+
|
|
31
|
+
- [ ] First task
|
|
32
|
+
- [ ] Second task
|
|
33
|
+
|
|
34
|
+
## Verification
|
|
35
|
+
|
|
36
|
+
- [ ] Verification step
|
|
37
|
+
|
|
38
|
+
## Decisions
|
|
39
|
+
|
|
40
|
+
- [2026-03-13 11:38 PDT] Decision and rationale.
|
|
41
|
+
|
|
42
|
+
## Notes
|
|
43
|
+
|
|
44
|
+
- Useful details that do not belong in `WORKSPACE.md`.
|
package/templates/WORKSPACE.md
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# Workspace
|
|
2
2
|
|
|
3
|
-
Timestamp discipline: Prefix new or materially revised bullets in `Current State`, `In Progress`, `Next`, `Parked`, and `Done Recently` with `[YYYY-MM-DD HH:MM TZ]`.
|
|
3
|
+
Timestamp discipline: Prefix new or materially revised bullets in `Active Trackers`, `Current State`, `In Progress`, `Next`, `Parked`, and `Done Recently` with `[YYYY-MM-DD HH:MM TZ]`.
|
|
4
4
|
|
|
5
5
|
## Active Goal
|
|
6
6
|
|
|
7
7
|
Describe the main thing currently being built or changed.
|
|
8
8
|
|
|
9
|
+
## Active Trackers
|
|
10
|
+
|
|
11
|
+
List any active tracker docs under `.waypoint/track/`, with the current phase or next step.
|
|
12
|
+
|
|
9
13
|
## Current State
|
|
10
14
|
|
|
11
15
|
What is already true right now?
|
|
@@ -32,8 +32,10 @@ This is mandatory, not optional.
|
|
|
32
32
|
|
|
33
33
|
Working rules:
|
|
34
34
|
- Keep `.waypoint/WORKSPACE.md` current as the live execution state, with timestamped new or materially revised entries in multi-topic sections
|
|
35
|
+
- For large multi-step work, create or update `.waypoint/track/<slug>.md`, keep detailed execution state there, and point to it from `## Active Trackers` in `.waypoint/WORKSPACE.md`
|
|
35
36
|
- Update `.waypoint/docs/` when behavior or durable project knowledge changes, and refresh `last_updated` on touched routable docs
|
|
36
37
|
- Use the repo-local skills Waypoint ships for structured workflows when relevant
|
|
38
|
+
- Use `work-tracker` when a long-running implementation, remediation, or verification campaign needs durable progress tracking
|
|
37
39
|
- Use `docs-sync` when the docs may be stale or a change altered shipped behavior, contracts, routes, or commands
|
|
38
40
|
- Use `code-guide-audit` for a targeted coding-guide compliance pass on a specific feature, file set, or change slice
|
|
39
41
|
- Use `break-it-qa` for browser-facing features that should be tested against invalid inputs, refreshes, repeated clicks, wrong navigation, and other adversarial user behavior
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: error-audit
|
|
3
|
-
description: Audit code for silent error swallowing, fallbacks to degraded alternatives, backwards compatibility shims, and UI that fails to show errors to the user. Finds and fixes all occurrences in the specified scope.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Error Audit
|
|
7
|
-
|
|
8
|
-
The core principle: **every error belongs to the user**. Not to a catch block, not to a console, not to a null return. Scan the specified code, fix every violation, report what changed.
|
|
9
|
-
|
|
10
|
-
## Read First
|
|
11
|
-
|
|
12
|
-
1. Read `.waypoint/SOUL.md`
|
|
13
|
-
2. Read `.waypoint/agent-operating-manual.md`
|
|
14
|
-
3. Read `WORKSPACE.md`
|
|
15
|
-
4. Read `.waypoint/context/MANIFEST.md`
|
|
16
|
-
5. Read every file listed in the manifest
|
|
17
|
-
6. Read `references/error-patterns.md`
|
|
18
|
-
|
|
19
|
-
## Step 0: Understand the app's error mechanisms
|
|
20
|
-
|
|
21
|
-
Before fixing anything, identify how this app surfaces errors to users — toast notifications, error banners, error boundaries, returned error states, alert dialogs, inline messages. Use these patterns exclusively. Don't invent a new one.
|
|
22
|
-
|
|
23
|
-
## Anti-patterns to find and fix
|
|
24
|
-
|
|
25
|
-
**Silent error swallowing — backend/logic layer:**
|
|
26
|
-
- Empty catch blocks: `catch(e) {}`
|
|
27
|
-
- Log-and-continue with execution proceeding normally
|
|
28
|
-
- `.catch(() => {})` on promises
|
|
29
|
-
- Functions returning `null`, `undefined`, or empty defaults on failure instead of throwing
|
|
30
|
-
|
|
31
|
-
**Silent error swallowing — UI layer:**
|
|
32
|
-
- Data fetching catches an error and returns null/empty -> component renders blank with no explanation
|
|
33
|
-
- Error boundaries that catch but show nothing (or a generic "something went wrong" with no recovery path)
|
|
34
|
-
- `try/catch` in a loader or server action that swallows the error and returns partial/empty data
|
|
35
|
-
- Async operations where the UI has no error state at all — success renders fine, failure renders identical to loading or empty
|
|
36
|
-
|
|
37
|
-
**Fallbacks to degraded alternatives:**
|
|
38
|
-
- Catch -> silently switch to a worse model, API, or service
|
|
39
|
-
- Catch -> return cached or stale data without telling the user
|
|
40
|
-
- Catch -> offline/degraded mode with no visible indication
|
|
41
|
-
|
|
42
|
-
**Backwards compatibility shims:**
|
|
43
|
-
- `if (legacyFormat)` or `if (oldVersion)` branches
|
|
44
|
-
- Deprecated fields still being populated alongside new ones
|
|
45
|
-
- Old code paths running in parallel with new ones
|
|
46
|
-
|
|
47
|
-
**Config defaults that hide misconfiguration:**
|
|
48
|
-
- `process.env.X || 'fallback'` for required values — missing required config is a startup crash, not a default
|
|
49
|
-
- Optional environment variables that should be required
|
|
50
|
-
|
|
51
|
-
**Optional chaining hiding missing required data:**
|
|
52
|
-
- `user?.profile?.name ?? 'Guest'` when profile must always exist — the absence is a bug, not an edge case to handle silently
|
|
53
|
-
|
|
54
|
-
## Fix principles
|
|
55
|
-
|
|
56
|
-
- Throw or re-throw rather than catch-and-continue
|
|
57
|
-
- In the UI: every error path must render something visible — use the app's established error display mechanism
|
|
58
|
-
- Required config missing at startup -> log a clear message and exit
|
|
59
|
-
- Delete fallback branches — don't comment them out
|
|
60
|
-
- When unsure if a fallback was intentional, flag it in your report rather than guessing
|
|
61
|
-
|
|
62
|
-
## Reference files
|
|
63
|
-
|
|
64
|
-
- `references/error-patterns.md` — Concrete anti-patterns with structural descriptions, examples, and false positive notes. Read this before starting the audit.
|
|
65
|
-
|
|
66
|
-
## Report
|
|
67
|
-
|
|
68
|
-
After fixing, summarize by file: what was found, what the fix was. Be specific — file paths and the pattern removed.
|
|
69
|
-
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# Error Anti-Patterns Reference
|
|
2
|
-
|
|
3
|
-
Patterns to identify when auditing error handling. Each section describes the anti-pattern structurally — what the code does, not just what keywords to grep for.
|
|
4
|
-
|
|
5
|
-
## Silent error swallowing
|
|
6
|
-
|
|
7
|
-
- empty catch blocks
|
|
8
|
-
- `.catch(() => {})`
|
|
9
|
-
- broad exception handlers that return defaults
|
|
10
|
-
- ignored Go errors via `_`
|
|
11
|
-
|
|
12
|
-
## Log-and-continue
|
|
13
|
-
|
|
14
|
-
An error gets logged, but execution continues as if the operation succeeded.
|
|
15
|
-
|
|
16
|
-
## Return-null-on-failure
|
|
17
|
-
|
|
18
|
-
The function converts a real operational failure into what looks like a normal "empty" result.
|
|
19
|
-
|
|
20
|
-
## Invisible degradation
|
|
21
|
-
|
|
22
|
-
The code silently falls back to a worse model, API, cache, or degraded mode with no visible signal.
|
|
23
|
-
|
|
24
|
-
## Config defaults hiding misconfiguration
|
|
25
|
-
|
|
26
|
-
Required settings should fail loudly, not silently pick a fallback.
|
|
27
|
-
|
|
28
|
-
## UI error blindness
|
|
29
|
-
|
|
30
|
-
Failure should not render the same as loading or empty.
|
|
31
|
-
|
|
32
|
-
Quality bar:
|
|
33
|
-
|
|
34
|
-
- confirm the issue is real in context
|
|
35
|
-
- prefer concrete fixes over broad rewrites
|
|
36
|
-
- use existing repo patterns for user-visible error handling
|
|
37
|
-
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: observability-audit
|
|
3
|
-
description: Audit code for observability gaps — debug logs left in, errors caught without being logged, missing context on log entries, and untracked slow operations. Uses the app's existing observability tooling exclusively.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Observability Audit
|
|
7
|
-
|
|
8
|
-
Code that works locally but is impossible to debug in production. This skill finds and fixes observability gaps using whatever tools the app already has.
|
|
9
|
-
|
|
10
|
-
## Read First
|
|
11
|
-
|
|
12
|
-
1. Read `.waypoint/SOUL.md`
|
|
13
|
-
2. Read `.waypoint/agent-operating-manual.md`
|
|
14
|
-
3. Read `WORKSPACE.md`
|
|
15
|
-
4. Read `.waypoint/context/MANIFEST.md`
|
|
16
|
-
5. Read every file listed in the manifest
|
|
17
|
-
6. Read `references/observability-patterns.md`
|
|
18
|
-
|
|
19
|
-
## Step 0: Research existing observability tooling
|
|
20
|
-
|
|
21
|
-
Before anything else, explore the codebase to understand what's already in use:
|
|
22
|
-
|
|
23
|
-
- Error tracking
|
|
24
|
-
- Logging
|
|
25
|
-
- APM / metrics
|
|
26
|
-
- Analytics
|
|
27
|
-
- Any custom logger or telemetry utilities
|
|
28
|
-
|
|
29
|
-
Read how they're configured and how they're used. All fixes must use these — never introduce a new observability dependency or pattern.
|
|
30
|
-
|
|
31
|
-
## What to look for
|
|
32
|
-
|
|
33
|
-
**Debug artifacts left in production code**
|
|
34
|
-
|
|
35
|
-
**Errors that disappear**
|
|
36
|
-
|
|
37
|
-
**Missing context on log entries**
|
|
38
|
-
|
|
39
|
-
**Untracked slow or critical operations**
|
|
40
|
-
|
|
41
|
-
See `references/observability-patterns.md` for concrete patterns.
|
|
42
|
-
|
|
43
|
-
## Process
|
|
44
|
-
|
|
45
|
-
1. Research existing tooling
|
|
46
|
-
2. Identify the scope
|
|
47
|
-
3. Find every instance of the anti-patterns
|
|
48
|
-
4. Fix using the existing tooling and patterns
|
|
49
|
-
5. Remove debug artifacts, add context to thin logs, add tracking where missing
|
|
50
|
-
6. Report changes
|
|
51
|
-
|
|
52
|
-
## Fix principles
|
|
53
|
-
|
|
54
|
-
- Every caught error should be logged with enough context to reproduce the problem
|
|
55
|
-
- Use the existing logger/tracker — never introduce a second one
|
|
56
|
-
- Debug `console.log` goes away entirely — no conversion to structured log, just deleted
|
|
57
|
-
- Log context should include: what operation, what failed, relevant IDs
|
|
58
|
-
- Don't add logging to every function — focus on boundaries and critical paths
|
|
59
|
-
|
|
60
|
-
## Reference files
|
|
61
|
-
|
|
62
|
-
- `references/observability-patterns.md` — Detection patterns, bad/fix examples for debug artifacts, missing logging, missing context, untracked operations. Read before starting the audit.
|
|
63
|
-
|
|
64
|
-
## Report
|
|
65
|
-
|
|
66
|
-
Summarize by file: what was removed, what was added or improved, what context was missing and is now included.
|
|
67
|
-
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Observability Anti-Patterns Reference
|
|
2
|
-
|
|
3
|
-
Use this file to guide observability audits.
|
|
4
|
-
|
|
5
|
-
## Debug artifacts
|
|
6
|
-
|
|
7
|
-
- `console.log`, `console.debug`, `print`, `fmt.Printf` in non-CLI production paths
|
|
8
|
-
- commented-out debug statements
|
|
9
|
-
- `debugger` and focused tests left behind
|
|
10
|
-
|
|
11
|
-
## Errors without useful traces
|
|
12
|
-
|
|
13
|
-
- catch/except blocks that rethrow or return without logging context
|
|
14
|
-
- tracker calls with no metadata
|
|
15
|
-
- logs that say "failed" without saying what failed
|
|
16
|
-
|
|
17
|
-
## Missing context
|
|
18
|
-
|
|
19
|
-
- no user, entity, request, or job identifiers
|
|
20
|
-
- no operation name
|
|
21
|
-
- no correlation/request ID at service boundaries
|
|
22
|
-
|
|
23
|
-
## Slow paths with no timing
|
|
24
|
-
|
|
25
|
-
- external API calls
|
|
26
|
-
- critical database queries
|
|
27
|
-
- background jobs without start/complete/fail visibility
|
|
28
|
-
- webhook handlers with no event-level logging
|
|
29
|
-
|
|
30
|
-
Quality bar:
|
|
31
|
-
|
|
32
|
-
- use the existing observability stack
|
|
33
|
-
- improve debugging value, not log volume
|
|
34
|
-
- focus on boundaries and critical paths
|
|
35
|
-
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ux-states-audit
|
|
3
|
-
description: Audit UI code for missing loading states, empty states, and error states. Every async operation and data-driven UI must handle all three. Finds gaps and implements the missing states using the app's existing patterns.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# UX States Audit
|
|
7
|
-
|
|
8
|
-
Every piece of UI that fetches data or triggers async work has three states beyond the happy path: **loading**, **empty**, and **error**. LLMs implement the happy path and leave the rest blank. This skill finds and fills those gaps.
|
|
9
|
-
|
|
10
|
-
This is distinct from `error-audit`: `error-audit` finds errors that are suppressed. This finds states that were never implemented.
|
|
11
|
-
|
|
12
|
-
## Read First
|
|
13
|
-
|
|
14
|
-
1. Read `.waypoint/SOUL.md`
|
|
15
|
-
2. Read `.waypoint/agent-operating-manual.md`
|
|
16
|
-
3. Read `WORKSPACE.md`
|
|
17
|
-
4. Read `.waypoint/context/MANIFEST.md`
|
|
18
|
-
5. Read every file listed in the manifest
|
|
19
|
-
6. Read `references/ux-patterns.md`
|
|
20
|
-
|
|
21
|
-
## Step 0: Understand existing patterns
|
|
22
|
-
|
|
23
|
-
Before touching anything, read the codebase to understand how it currently handles these states:
|
|
24
|
-
|
|
25
|
-
- loading components or primitives
|
|
26
|
-
- empty state patterns
|
|
27
|
-
- error display patterns
|
|
28
|
-
|
|
29
|
-
Use these patterns exclusively. Don't introduce a new loading spinner if one already exists.
|
|
30
|
-
|
|
31
|
-
## What to look for
|
|
32
|
-
|
|
33
|
-
**Missing loading state**
|
|
34
|
-
|
|
35
|
-
**Missing empty state**
|
|
36
|
-
|
|
37
|
-
**Missing error state**
|
|
38
|
-
|
|
39
|
-
See `references/ux-patterns.md` for concrete patterns.
|
|
40
|
-
|
|
41
|
-
## Process
|
|
42
|
-
|
|
43
|
-
1. Identify the scope
|
|
44
|
-
2. Find every component that fetches data or triggers async work
|
|
45
|
-
3. For each: check whether loading, empty, and error states are handled
|
|
46
|
-
4. Implement missing states using the patterns found in Step 0
|
|
47
|
-
5. Report what was added, by component
|
|
48
|
-
|
|
49
|
-
## Fix principles
|
|
50
|
-
|
|
51
|
-
- Loading states should be immediate
|
|
52
|
-
- Empty states should explain the situation and, where appropriate, offer an action
|
|
53
|
-
- Error states should say what went wrong and what the user can do
|
|
54
|
-
- Don't invent new UI primitives — use what already exists
|
|
55
|
-
|
|
56
|
-
## Reference files
|
|
57
|
-
|
|
58
|
-
- `references/ux-patterns.md` — Detection patterns and examples for missing loading, empty, and error states. Read before starting the audit.
|
|
59
|
-
|
|
60
|
-
## Report
|
|
61
|
-
|
|
62
|
-
Summarize by component: which states were missing, what was added.
|
|
63
|
-
|