cans-spec 0.1.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.
- package/LICENSE +21 -0
- package/README.md +339 -0
- package/package.json +38 -0
- package/src/cli.ts +48 -0
- package/src/commands/budget.ts +238 -0
- package/src/commands/check.ts +422 -0
- package/src/commands/done.ts +171 -0
- package/src/commands/export.ts +223 -0
- package/src/commands/import.ts +436 -0
- package/src/commands/init.ts +184 -0
- package/src/commands/new.ts +138 -0
- package/src/commands/status.ts +152 -0
- package/src/converters/index.ts +4 -0
- package/src/converters/logseq.ts +42 -0
- package/src/converters/obsidian.ts +95 -0
- package/src/converters/opml.ts +143 -0
- package/src/converters/shared.ts +268 -0
- package/src/core/args.ts +79 -0
- package/src/core/fs.ts +309 -0
- package/src/core/index.ts +10 -0
- package/src/core/outline.ts +237 -0
- package/src/core/output.ts +300 -0
- package/src/core/overflow.ts +75 -0
- package/src/core/redundancy.ts +261 -0
- package/src/core/refs.ts +275 -0
- package/src/core/rules.ts +483 -0
- package/src/core/structure.ts +86 -0
- package/src/core/style.ts +75 -0
- package/src/core/token-budget.ts +284 -0
- package/src/types.ts +284 -0
- package/templates/AGENTS.md +209 -0
- package/templates/_rules.yaml +46 -0
- package/templates/adr-template.md +28 -0
- package/templates/task-template.md +15 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# CANS Agent Instructions
|
|
2
|
+
|
|
3
|
+
You are working in a CANS project. Specs live in `cans/`.
|
|
4
|
+
|
|
5
|
+
## Reading
|
|
6
|
+
|
|
7
|
+
Find concept → read canonical home → follow `see:` ONE hop. Never chain.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
# GOOD: read canonical, then one ref
|
|
11
|
+
cans/02-authentication.md → "Sessions" node
|
|
12
|
+
cans/04-api.md → "Session rules: see 02-authentication.md#Sessions"
|
|
13
|
+
|
|
14
|
+
# FORBIDDEN: following a see: inside the referenced file
|
|
15
|
+
04-api.md → see 02-auth.md → see 06-ops.md ← DEEP HOP, stop at 02-auth.md
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Read surrounding hierarchy for context, not just the leaf:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
# You need "Refresh allowed for 30 days"
|
|
22
|
+
# Read the parent chain:
|
|
23
|
+
- Authentication ← context
|
|
24
|
+
- Sessions ← parent
|
|
25
|
+
- Expire after 24 hours
|
|
26
|
+
- Refresh allowed for 30 days ← target
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Writing
|
|
30
|
+
|
|
31
|
+
One canonical home per concept. Reference, don't duplicate.
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
# GOOD: 04-api.md references the canonical home
|
|
35
|
+
- Authentication
|
|
36
|
+
- Session rules: see 02-authentication.md#Sessions
|
|
37
|
+
|
|
38
|
+
# BAD: duplicating session rules in 04-api.md
|
|
39
|
+
- Authentication
|
|
40
|
+
- Sessions expire after 24 hours ← DUPLICATE, use see: instead
|
|
41
|
+
- Refresh allowed for 30 days ← DUPLICATE
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Preserve real identifiers exactly:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
# GOOD
|
|
48
|
+
- POST /users
|
|
49
|
+
- packages/api
|
|
50
|
+
- users.created_at
|
|
51
|
+
|
|
52
|
+
# BAD
|
|
53
|
+
- post-users
|
|
54
|
+
- packages-api
|
|
55
|
+
- users-created-at
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Mark unknowns as TBD. Don't guess:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
# GOOD
|
|
62
|
+
- Rate limit: TBD (waiting on infra decision)
|
|
63
|
+
|
|
64
|
+
# BAD
|
|
65
|
+
- Rate limit: 1000 req/min ← invented, no source
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
If a level adds no meaning, don't create it:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
# BAD (filler)
|
|
72
|
+
- Authentication
|
|
73
|
+
- Capability
|
|
74
|
+
- Behavior
|
|
75
|
+
- Sign up
|
|
76
|
+
|
|
77
|
+
# GOOD (dense)
|
|
78
|
+
- Authentication
|
|
79
|
+
- Sign up
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Changing
|
|
83
|
+
|
|
84
|
+
Find canonical home → update there → check references → verify affected code.
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
# Changing session expiry from 24h to 48h:
|
|
88
|
+
1. Edit cans/02-authentication.md → "Expire after 48 hours"
|
|
89
|
+
2. Run: cans check --refs-only
|
|
90
|
+
3. Verify back-pointers still valid
|
|
91
|
+
4. Do NOT edit 04-api.md (it only has see:, not the value)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Never silently resolve conflicts. Report them:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
# If you disagree with a spec:
|
|
98
|
+
- Add to _collab/conflicts.md
|
|
99
|
+
- Format: - status: unresolved | file: 04-api.md | issue: <description>
|
|
100
|
+
- Do NOT overwrite the spec
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Smallest correct change. Don't restructure what isn't broken.
|
|
104
|
+
|
|
105
|
+
## ADRs
|
|
106
|
+
|
|
107
|
+
Decisions get an ADR. ADRs record WHY. Specs are the truth.
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
cans new adr "postgres-over-mysql"
|
|
111
|
+
# Creates: _adr/003-postgres-over-mysql.md
|
|
112
|
+
# Fill: Context → Decision → Alternatives → Consequences
|
|
113
|
+
# Reference spec: see 03-data.md#Storage
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Tasks
|
|
117
|
+
|
|
118
|
+
Implementation tracking via task files:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
cans new task "add-dark-mode"
|
|
122
|
+
# Creates: _tasks/add-dark-mode.md
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Task file structure:
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
# add-dark-mode
|
|
129
|
+
- Owner: agent-1
|
|
130
|
+
- ADR: _adr/001-css-variables-over-tailwind.md
|
|
131
|
+
- Tasks
|
|
132
|
+
- [x] Add ThemeContext provider ← agent-1
|
|
133
|
+
- [ ] Create toggle component ← agent-1
|
|
134
|
+
- [ ] Test: no FOUC ← agent-2
|
|
135
|
+
- Review
|
|
136
|
+
- [ ] Spec approved ← @human
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
When done: `cans done add-dark-mode`
|
|
140
|
+
Blocks if `← @human` gates unchecked. Always.
|
|
141
|
+
|
|
142
|
+
## Collaboration
|
|
143
|
+
|
|
144
|
+
One owner per task file. Claim before editing.
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
# If task has ← agent-3, do NOT edit it
|
|
148
|
+
# If you need to hand off, add to _collab/handoffs.md:
|
|
149
|
+
- from: agent-1 → to: agent-3 | task: add-dark-mode | context: color audit pending
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Token Budget
|
|
153
|
+
|
|
154
|
+
Before reading:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
cans budget read "sessions" --json
|
|
158
|
+
# Returns scored plan. Read ONLY listed files, in order.
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Before writing:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
cans budget write "sessions" --json
|
|
165
|
+
# Returns canEdit[] and mustNotEdit[].
|
|
166
|
+
# ONLY edit files in canEdit. Never touch mustNotEdit.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Example budget read output:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"plan": [
|
|
174
|
+
{ "file": "02-authentication.md", "anchor": "Sessions", "score": 100 },
|
|
175
|
+
{ "file": "04-api.md", "anchor": null, "score": 60 }
|
|
176
|
+
],
|
|
177
|
+
"skipped": ["00-overview.md", "03-data.md"],
|
|
178
|
+
"totalTokens": 180,
|
|
179
|
+
"budgetLimit": 4096
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Read files in plan order. Stop at budgetLimit.
|
|
184
|
+
|
|
185
|
+
## Machine Output
|
|
186
|
+
|
|
187
|
+
Use `--json` for structured output. Parse JSON, never human text.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
cans check --json # structured issues
|
|
191
|
+
cans status --json # workspace state
|
|
192
|
+
cans done add-dark-mode --json # gate results
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
All JSON has `ok: boolean` and `exitCode: number` at top level.
|
|
196
|
+
|
|
197
|
+
## Quality Checklist
|
|
198
|
+
|
|
199
|
+
Before finalizing any change:
|
|
200
|
+
|
|
201
|
+
- [ ] Is each concept in exactly one place?
|
|
202
|
+
- [ ] Does indentation add meaning? (No filler levels)
|
|
203
|
+
- [ ] Can anything be simpler?
|
|
204
|
+
- [ ] Did I duplicate an authoritative rule? (Use `see:` instead)
|
|
205
|
+
- [ ] Did I invent anything? (Mark TBD if unsure)
|
|
206
|
+
- [ ] Is ambiguity visible? (Don't hide unknowns)
|
|
207
|
+
- [ ] Did I create a deep hop? (FORBIDDEN: A→B→C)
|
|
208
|
+
- [ ] Did I preserve real identifiers exactly?
|
|
209
|
+
- [ ] Did I run `cans check` after editing?
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
structure:
|
|
2
|
+
node_length: { min: 3, max: 120 }
|
|
3
|
+
siblings: { min: 1, max: 12 }
|
|
4
|
+
depth: { min: 1, max: 5 }
|
|
5
|
+
single_child_collapse: true
|
|
6
|
+
empty_nodes: false
|
|
7
|
+
|
|
8
|
+
style:
|
|
9
|
+
prefer: sibling
|
|
10
|
+
force_nested_above: 6
|
|
11
|
+
force_sibling_below: 3
|
|
12
|
+
shared_prefix_detection: true
|
|
13
|
+
|
|
14
|
+
content:
|
|
15
|
+
tbd_allowed: true
|
|
16
|
+
max_tbd_per_file: 5
|
|
17
|
+
|
|
18
|
+
references:
|
|
19
|
+
mode: pointer
|
|
20
|
+
back_pointers: true
|
|
21
|
+
max_hops: 1
|
|
22
|
+
orphan_check: true
|
|
23
|
+
duplicate_home_check: true
|
|
24
|
+
|
|
25
|
+
redundancy:
|
|
26
|
+
enabled: true
|
|
27
|
+
word_frequency_threshold: 4
|
|
28
|
+
phrase_overlap_threshold: 0.7
|
|
29
|
+
cross_file_threshold: 2
|
|
30
|
+
stopwords: [the, a, an, of, to, in, for, and, or, with, must, shall, requires]
|
|
31
|
+
synonyms:
|
|
32
|
+
- [postgres, postgresql, pg]
|
|
33
|
+
- [auth, authentication, sign-in, signin]
|
|
34
|
+
- [api, endpoint, route]
|
|
35
|
+
- [frontend, client, ui]
|
|
36
|
+
- [db, database, storage]
|
|
37
|
+
|
|
38
|
+
token_budget:
|
|
39
|
+
enabled: true
|
|
40
|
+
default_limit: 4096
|
|
41
|
+
estimate_chars_per_token: 3.5
|
|
42
|
+
warn_threshold: 0.8
|
|
43
|
+
|
|
44
|
+
overflow:
|
|
45
|
+
max_node_chars: 200
|
|
46
|
+
force_file_for: [code_block, table, diagram]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ADR-{NNN}: {Title}
|
|
2
|
+
|
|
3
|
+
- Status: proposed
|
|
4
|
+
- Date: {YYYY-MM-DD}
|
|
5
|
+
- Decided by:
|
|
6
|
+
- Supersedes: none
|
|
7
|
+
|
|
8
|
+
- Context
|
|
9
|
+
- {Why this decision is needed}
|
|
10
|
+
- {Constraints and drivers}
|
|
11
|
+
|
|
12
|
+
- Decision
|
|
13
|
+
- {What was decided}
|
|
14
|
+
- {How it applies}
|
|
15
|
+
|
|
16
|
+
- Alternatives considered
|
|
17
|
+
- {Option A}
|
|
18
|
+
- Rejected: {reason}
|
|
19
|
+
- {Option B}
|
|
20
|
+
- Rejected: {reason}
|
|
21
|
+
|
|
22
|
+
- Consequences
|
|
23
|
+
- {What changes}
|
|
24
|
+
- {Trade-offs accepted}
|
|
25
|
+
|
|
26
|
+
- Review
|
|
27
|
+
- [ ] Spec impact approved ← @human
|
|
28
|
+
- [ ] Design approved ←
|