durable-context 1.0.0 → 1.1.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 +18 -2
- package/bin/durable-context.js +19 -0
- package/lib/installer.js +93 -17
- package/package.json +1 -1
- package/template/.agents/skills/README.md +10 -3
- package/template/.agents/skills/devils-advocate/SKILL.md +45 -0
- package/template/.agents/skills/dive-into-plan/SKILL.md +12 -6
- package/template/.agents/skills/plan-with-context/SKILL.md +18 -2
- package/template/.agents/skills/project-profile-baseline/SKILL.md +23 -0
- package/template/.agents/skills/project-profile-refresh/SKILL.md +29 -0
- package/template/AGENTS.md +3 -0
- package/template/context/README.md +8 -4
- package/template/context/_templates/initiative/README.md +2 -1
- package/template/context/_templates/initiative/decisions/ADR-0000-template.md +5 -1
- package/template/decisions/0000-template.md +6 -1
- package/template/decisions/README.md +36 -10
- package/template/decisions/indexes/README.md +8 -0
- package/template/decisions/indexes/by-area.md +5 -0
- package/template/decisions/indexes/by-origin.md +5 -0
- package/template/decisions/indexes/by-status.md +7 -0
package/README.md
CHANGED
|
@@ -8,17 +8,33 @@ Install into a project:
|
|
|
8
8
|
npx durable-context init --project-name "My App"
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Adds `context/`, `decisions/`, and
|
|
11
|
+
Adds `context/`, `decisions/`, and invocation-only skills:
|
|
12
|
+
|
|
13
|
+
- `project-profile-baseline`
|
|
14
|
+
- `project-profile-refresh`
|
|
15
|
+
- `plan-with-context`
|
|
16
|
+
- `devils-advocate`
|
|
17
|
+
- `dive-into-plan`
|
|
12
18
|
|
|
13
19
|
## Use
|
|
14
20
|
|
|
15
21
|
```text
|
|
16
22
|
Plan with durable context: <what you want to build>
|
|
23
|
+
Devil's advocate.
|
|
17
24
|
Dive into the plan.
|
|
18
25
|
```
|
|
19
26
|
|
|
20
27
|
Skills are invocation-only — they do not run automatically.
|
|
28
|
+
Use `project-profile-baseline` once to populate repo-wide commands and
|
|
29
|
+
operating facts; use `project-profile-refresh` when those stable facts change.
|
|
30
|
+
|
|
31
|
+
Update managed agent assets without replacing project work:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx durable-context@latest update
|
|
35
|
+
```
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
Commands/options: `update`, `status`, `--target`, `--dry-run`, and `--force`
|
|
38
|
+
for `init`.
|
|
23
39
|
|
|
24
40
|
For release-anchored documentation, see the `reference-docs` package.
|
package/bin/durable-context.js
CHANGED
|
@@ -14,11 +14,26 @@ const agentsStart = '<!-- durable-context:start -->';
|
|
|
14
14
|
const agentsEnd = '<!-- durable-context:end -->';
|
|
15
15
|
|
|
16
16
|
const skills = [
|
|
17
|
+
{
|
|
18
|
+
name: 'project-profile-baseline',
|
|
19
|
+
readmeEntry:
|
|
20
|
+
'- `project-profile-baseline` - invoke explicitly to populate `context/project-profile.md` from source-backed repo facts.'
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'project-profile-refresh',
|
|
24
|
+
readmeEntry:
|
|
25
|
+
'- `project-profile-refresh` - invoke explicitly to refresh stable repo-wide facts in `context/project-profile.md`.'
|
|
26
|
+
},
|
|
17
27
|
{
|
|
18
28
|
name: 'plan-with-context',
|
|
19
29
|
readmeEntry:
|
|
20
30
|
'- `plan-with-context` - invoke explicitly to draft a durable plan in an initiative `plan.md`.'
|
|
21
31
|
},
|
|
32
|
+
{
|
|
33
|
+
name: 'devils-advocate',
|
|
34
|
+
readmeEntry:
|
|
35
|
+
'- `devils-advocate` - invoke explicitly to challenge a draft plan before distribution.'
|
|
36
|
+
},
|
|
22
37
|
{
|
|
23
38
|
name: 'dive-into-plan',
|
|
24
39
|
readmeEntry:
|
|
@@ -35,7 +50,10 @@ Initiatives under [\`context/initiatives/\`](context/initiatives/) are disposabl
|
|
|
35
50
|
|
|
36
51
|
Invocation-only skills — ask by name:
|
|
37
52
|
|
|
53
|
+
- [\`.agents/skills/project-profile-baseline/SKILL.md\`](.agents/skills/project-profile-baseline/SKILL.md) — populate \`context/project-profile.md\`.
|
|
54
|
+
- [\`.agents/skills/project-profile-refresh/SKILL.md\`](.agents/skills/project-profile-refresh/SKILL.md) — refresh stable repo-wide profile facts.
|
|
38
55
|
- [\`.agents/skills/plan-with-context/SKILL.md\`](.agents/skills/plan-with-context/SKILL.md) — draft a plan in \`plan.md\`.
|
|
56
|
+
- [\`.agents/skills/devils-advocate/SKILL.md\`](.agents/skills/devils-advocate/SKILL.md) — critique a draft plan before distribution.
|
|
39
57
|
- [\`.agents/skills/dive-into-plan/SKILL.md\`](.agents/skills/dive-into-plan/SKILL.md) — interrogate gaps, distribute into per-concern docs, promote to [\`decisions/\`](decisions/).
|
|
40
58
|
|
|
41
59
|
[\`context/project-profile.md\`](context/project-profile.md) — repo-wide stack, commands, and test facts when populated.
|
|
@@ -55,6 +73,7 @@ const config = {
|
|
|
55
73
|
render: renderAgentSection
|
|
56
74
|
},
|
|
57
75
|
nextSteps: [
|
|
76
|
+
'Optional: invoke .agents/skills/project-profile-baseline/SKILL.md to populate context/project-profile.md.',
|
|
58
77
|
'Then: invoke .agents/skills/plan-with-context/SKILL.md when you start planning an initiative.'
|
|
59
78
|
]
|
|
60
79
|
};
|
package/lib/installer.js
CHANGED
|
@@ -36,12 +36,12 @@ export async function runCli(config, argv) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
if (args.command !== 'init') {
|
|
39
|
+
if (args.command !== 'init' && args.command !== 'update') {
|
|
40
40
|
throw new Error(`Unknown command "${args.command}". Run "${config.cliName} --help".`);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const targetRoot = path.resolve(args.target);
|
|
44
|
-
const projectName =
|
|
44
|
+
const projectName = await resolveProjectName(config, args, targetRoot);
|
|
45
45
|
const installer = new Installer({
|
|
46
46
|
config,
|
|
47
47
|
targetRoot,
|
|
@@ -50,7 +50,12 @@ export async function runCli(config, argv) {
|
|
|
50
50
|
dryRun: args.dryRun
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
if (args.command === 'init') {
|
|
54
|
+
await installer.init();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
await installer.update();
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
function parseArgs(argv, config) {
|
|
@@ -143,21 +148,24 @@ function printHelp(config) {
|
|
|
143
148
|
|
|
144
149
|
Usage:
|
|
145
150
|
${config.cliName} init [options]
|
|
151
|
+
${config.cliName} update [options]
|
|
146
152
|
${config.cliName} status [options]
|
|
147
153
|
|
|
148
154
|
Options:
|
|
149
155
|
--target <path> Project root to install into. Defaults to cwd.
|
|
150
156
|
--project-name <name> Name used to replace PROJECT_NAME placeholders.
|
|
151
|
-
--force Replace existing generated directories.
|
|
157
|
+
--force Replace existing generated directories during init.
|
|
152
158
|
--dry-run Show planned changes without writing files.
|
|
153
159
|
-h, --help Show help.
|
|
154
160
|
-v, --version Show package version.
|
|
155
161
|
|
|
156
162
|
Examples:
|
|
157
163
|
npx ${config.packageJson.name} init --project-name "My App"
|
|
164
|
+
npx ${config.packageJson.name}@latest update
|
|
158
165
|
npx ${config.packageJson.name}@${config.packageJson.version} init --project-name "My App"
|
|
159
166
|
npx ${config.packageJson.name} status --target ../existing-project
|
|
160
167
|
|
|
168
|
+
The update command refreshes managed agent assets without replacing project work.
|
|
161
169
|
The status command reads ${config.metadataPath} from an initialized project.
|
|
162
170
|
`);
|
|
163
171
|
}
|
|
@@ -176,6 +184,22 @@ async function inferProjectName(targetRoot) {
|
|
|
176
184
|
return path.basename(targetRoot);
|
|
177
185
|
}
|
|
178
186
|
|
|
187
|
+
async function resolveProjectName(config, args, targetRoot) {
|
|
188
|
+
if (args.projectName) {
|
|
189
|
+
return args.projectName;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (args.command === 'update') {
|
|
193
|
+
const metadata = await readOptionalJson(path.join(targetRoot, config.metadataPath));
|
|
194
|
+
|
|
195
|
+
if (typeof metadata?.projectName === 'string' && metadata.projectName.trim()) {
|
|
196
|
+
return metadata.projectName;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return inferProjectName(targetRoot);
|
|
201
|
+
}
|
|
202
|
+
|
|
179
203
|
class Installer {
|
|
180
204
|
constructor({ config, targetRoot, projectName, force, dryRun }) {
|
|
181
205
|
this.config = config;
|
|
@@ -199,6 +223,16 @@ class Installer {
|
|
|
199
223
|
this.printSummary();
|
|
200
224
|
}
|
|
201
225
|
|
|
226
|
+
async update() {
|
|
227
|
+
await this.ensureDirectory(this.targetRoot);
|
|
228
|
+
|
|
229
|
+
await this.installAgentsFile();
|
|
230
|
+
await this.updateSkills();
|
|
231
|
+
await this.writeMetadata();
|
|
232
|
+
|
|
233
|
+
this.printSummary();
|
|
234
|
+
}
|
|
235
|
+
|
|
202
236
|
async installPayloadRoots() {
|
|
203
237
|
const entries = await readdir(this.templateDir, { withFileTypes: true });
|
|
204
238
|
|
|
@@ -290,6 +324,22 @@ class Installer {
|
|
|
290
324
|
);
|
|
291
325
|
}
|
|
292
326
|
|
|
327
|
+
await this.upsertSkillsReadme();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async updateSkills() {
|
|
331
|
+
for (const skill of this.config.skills) {
|
|
332
|
+
await this.copyTemplatePath(
|
|
333
|
+
`${agentsSkillsRelative}/${skill.name}`,
|
|
334
|
+
`${agentsSkillsRelative}/${skill.name}`,
|
|
335
|
+
{ replaceExisting: true }
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
await this.upsertSkillsReadme();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async upsertSkillsReadme() {
|
|
293
343
|
const readmeTarget = await this.findExistingTargetPath(`${agentsSkillsRelative}/README.md`);
|
|
294
344
|
const readmePath = readmeTarget.exists
|
|
295
345
|
? readmeTarget.path
|
|
@@ -302,29 +352,55 @@ class Installer {
|
|
|
302
352
|
}
|
|
303
353
|
|
|
304
354
|
const current = await readFile(readmePath, 'utf8');
|
|
305
|
-
const
|
|
355
|
+
const section = this.renderSkillsReadmeSection();
|
|
356
|
+
const { start, end } = this.skillsReadmeMarkers();
|
|
357
|
+
|
|
358
|
+
if (current.includes(start) && current.includes(end)) {
|
|
359
|
+
const updated = current.replace(
|
|
360
|
+
new RegExp(`${escapeRegExp(start)}[\\s\\S]*?${escapeRegExp(end)}`),
|
|
361
|
+
section
|
|
362
|
+
);
|
|
306
363
|
|
|
307
|
-
|
|
308
|
-
|
|
364
|
+
if (updated === current) {
|
|
365
|
+
this.note(`${readmeDisplay} already has the ${this.config.summaryLabel} skills section`);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
await this.writeFile(readmePath, updated, `update ${readmeDisplay} ${this.config.summaryLabel} skills section`);
|
|
309
370
|
return;
|
|
310
371
|
}
|
|
311
372
|
|
|
312
|
-
const
|
|
313
|
-
'',
|
|
314
|
-
`## ${this.config.summaryLabel} Skills`,
|
|
315
|
-
'',
|
|
316
|
-
...missingSkills.map((skill) => skill.readmeEntry),
|
|
317
|
-
''
|
|
318
|
-
].join('\n');
|
|
373
|
+
const separator = current.endsWith('\n\n') ? '' : current.endsWith('\n') ? '\n' : '\n\n';
|
|
319
374
|
|
|
320
375
|
await this.writeFile(
|
|
321
376
|
readmePath,
|
|
322
|
-
`${current
|
|
377
|
+
`${current}${separator}${section}\n`,
|
|
323
378
|
`append ${this.config.summaryLabel} skills to ${readmeDisplay}`
|
|
324
379
|
);
|
|
325
380
|
}
|
|
326
381
|
|
|
327
|
-
|
|
382
|
+
skillsReadmeMarkers() {
|
|
383
|
+
const name = this.config.packageJson.name;
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
start: `<!-- ${name}:skills:start -->`,
|
|
387
|
+
end: `<!-- ${name}:skills:end -->`
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
renderSkillsReadmeSection() {
|
|
392
|
+
const { start, end } = this.skillsReadmeMarkers();
|
|
393
|
+
|
|
394
|
+
return [
|
|
395
|
+
start,
|
|
396
|
+
`## ${this.config.summaryLabel} Skills`,
|
|
397
|
+
'',
|
|
398
|
+
...this.config.skills.map((skill) => skill.readmeEntry),
|
|
399
|
+
end
|
|
400
|
+
].join('\n');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
async copyTemplatePath(sourceRelative, targetRelative, { replaceExisting = this.force } = {}) {
|
|
328
404
|
const sourcePath = path.join(this.templateDir, sourceRelative);
|
|
329
405
|
const targetInfo = await this.findExistingTargetPath(targetRelative);
|
|
330
406
|
|
|
@@ -337,7 +413,7 @@ class Installer {
|
|
|
337
413
|
if (targetInfo.exists) {
|
|
338
414
|
const variantNote = targetInfo.caseVariant ? ` at ${targetInfo.display}` : '';
|
|
339
415
|
|
|
340
|
-
if (!
|
|
416
|
+
if (!replaceExisting) {
|
|
341
417
|
this.note(`skip ${targetRelative} (already exists${variantNote}; use --force to replace)`);
|
|
342
418
|
return false;
|
|
343
419
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# Project Skills
|
|
2
2
|
|
|
3
|
-
Invocation-only
|
|
3
|
+
Invocation-only - ask by name.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
<!-- durable-context:skills:start -->
|
|
6
|
+
## Durable Context Skills
|
|
7
|
+
|
|
8
|
+
- `project-profile-baseline` - invoke explicitly to populate `context/project-profile.md` from source-backed repo facts.
|
|
9
|
+
- `project-profile-refresh` - invoke explicitly to refresh stable repo-wide facts in `context/project-profile.md`.
|
|
10
|
+
- `plan-with-context` - invoke explicitly to draft a durable plan in an initiative `plan.md`.
|
|
11
|
+
- `devils-advocate` - invoke explicitly to challenge a draft plan before distribution.
|
|
12
|
+
- `dive-into-plan` - invoke explicitly to interrogate a settled plan, distribute it into initiative docs, and promote decisions.
|
|
13
|
+
<!-- durable-context:skills:end -->
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devils-advocate
|
|
3
|
+
description: Critique-only adversarial review of plan-with-context plans. Use ONLY when the human explicitly asks for "devil's advocate", "challenge the plan", "red-team the plan", or adversarial planning review before dive-into-plan; rerun after dive-into-plan only when a materially new decision appears.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Devil's Advocate
|
|
7
|
+
|
|
8
|
+
Invocation-only. Challenge a draft plan before it hardens. Do not edit files
|
|
9
|
+
unless the human explicitly asks for changes.
|
|
10
|
+
|
|
11
|
+
## Workflow
|
|
12
|
+
|
|
13
|
+
1. Read the initiative `README.md`, `plan.md`, nearest `AGENTS.md`, and `context/project-profile.md` when useful.
|
|
14
|
+
2. Identify the commitment being challenged: recommendation, approach, or decision.
|
|
15
|
+
3. If there is no meaningful decision, or the current plan is the best clear alternative, say so briefly and stop.
|
|
16
|
+
4. Otherwise give a concise adversarial pass:
|
|
17
|
+
- strongest objection
|
|
18
|
+
- hidden assumption
|
|
19
|
+
- non-obvious failure mode
|
|
20
|
+
- cheaper, simpler, or more reversible alternative
|
|
21
|
+
- required plan adjustment, open question, or explicit accept-risk decision
|
|
22
|
+
|
|
23
|
+
## Output
|
|
24
|
+
|
|
25
|
+
```markdown
|
|
26
|
+
## Decision
|
|
27
|
+
[What commitment is being challenged.]
|
|
28
|
+
|
|
29
|
+
## Challenge
|
|
30
|
+
- **Strongest objection:** ...
|
|
31
|
+
- **Hidden assumption:** ...
|
|
32
|
+
- **Non-obvious failure mode:** ...
|
|
33
|
+
- **Alternative:** ...
|
|
34
|
+
- **Plan impact:** ...
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
When there is no material challenge, use:
|
|
38
|
+
|
|
39
|
+
```markdown
|
|
40
|
+
## Decision
|
|
41
|
+
[What was reviewed.]
|
|
42
|
+
|
|
43
|
+
## Challenge
|
|
44
|
+
No material challenge. The current plan appears to be the best available option because ...
|
|
45
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dive-into-plan
|
|
3
|
-
description: Interrogate a settled initiative plan for gaps, distribute into per-concern docs, and promote
|
|
3
|
+
description: Interrogate a settled initiative plan for gaps, distribute into per-concern docs, create local ADRs for active work, and promote approved implemented ADRs into decisions/. Use ONLY when the human explicitly invokes it ("dive into the plan", "distribute the plan"). Do not trigger automatically.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Dive Into Plan
|
|
@@ -9,19 +9,25 @@ Second half of durable planning, after `plan-with-context`. Requires a settled `
|
|
|
9
9
|
|
|
10
10
|
## Workflow
|
|
11
11
|
|
|
12
|
-
1. Read initiative `README.md`, `plan.md`,
|
|
13
|
-
2. **Interrogate** — ask pointed questions for surfaces the plan skipped (tests, e2e, IaC, CI/CD, config, ops, security,
|
|
12
|
+
1. Read initiative `README.md`, `plan.md`, nearest `AGENTS.md`, `context/project-profile.md` when present, root `decisions/README.md` and relevant `decisions/indexes/` when present, and relevant local `context/**/decisions/`.
|
|
13
|
+
2. **Interrogate** — ask pointed questions for surfaces the plan skipped (behavior, interface, architecture, tests, e2e, IaC, CI/CD, config, ops, rollback, security, data, ADRs, project profile impact, reference impact). Record answers in `plan.md`; note deferred surfaces with reason.
|
|
14
14
|
3. **Distribute** — move settled truth from `plan.md` into initiative files (see templates under `context/_templates/initiative/` for each file's role):
|
|
15
15
|
`spec.md`, `interface.md`, `architecture.md`, `testing.md`, `delivery.md`, `infrastructure.md`, `operations.md` (only when actionable), `backlog.md`, `release-doc-notes.md`. Mark N/A files explicitly.
|
|
16
|
-
4. **
|
|
17
|
-
5.
|
|
16
|
+
4. **Record ADRs** — create ADRs only for architecturally significant decisions: choices that cross team boundaries, have multiple credible options, or are costly to reverse. Keep proposed, recommended, planned, or in-progress ADRs under the relevant initiative `decisions/` folder.
|
|
17
|
+
5. **Promote decisions** — move ADRs to root `decisions/` only when approved and implemented/accepted, or when the human explicitly says they are ready for root history. Assign the next `NNNN`, preserve or complete metadata (`Area`, `Scope`, `Tags`, `Supersedes`, `Superseded by`), update `decisions/README.md` and relevant `decisions/indexes/*.md`, and link back from the initiative.
|
|
18
|
+
6. Update initiative `README.md` (status, decisions, implementation state).
|
|
18
19
|
|
|
19
20
|
## Boundary
|
|
20
21
|
|
|
22
|
+
Use this after the agent's native planning is settled; it does not replace the
|
|
23
|
+
agent's planning capability, but interrogates, distributes, and records durable
|
|
24
|
+
artifacts from that plan.
|
|
21
25
|
Do not edit `reference/`. Capture future reference impact in `release-doc-notes.md` only.
|
|
26
|
+
Do not create ADRs for routine daily technical choices.
|
|
22
27
|
|
|
23
28
|
## Done when
|
|
24
29
|
|
|
25
30
|
- Applicable surfaces grilled; answers in `plan.md`.
|
|
26
31
|
- Settled truth not living only in `plan.md`.
|
|
27
|
-
-
|
|
32
|
+
- ADR candidates were recorded locally, promoted to root `decisions/`, or left as normal initiative notes.
|
|
33
|
+
- Promoted ADRs have complete metadata and current indexes.
|
|
@@ -7,6 +7,13 @@ description: Draft a durable plan in an initiative plan.md covering the full cha
|
|
|
7
7
|
|
|
8
8
|
Invocation-only. Produces `plan.md` for a later `dive-into-plan` pass.
|
|
9
9
|
|
|
10
|
+
## Boundary
|
|
11
|
+
|
|
12
|
+
Use the coding agent's native planning mode or planning capabilities to reason
|
|
13
|
+
through the work. This skill does not replace that planning behavior; it
|
|
14
|
+
extends it by grounding the plan in repository context and materializing the
|
|
15
|
+
result in `context/initiatives/<slug>/plan.md`.
|
|
16
|
+
|
|
10
17
|
## Workflow
|
|
11
18
|
|
|
12
19
|
1. Read nearest `AGENTS.md` and `context/project-profile.md` when it exists.
|
|
@@ -14,14 +21,23 @@ Invocation-only. Produces `plan.md` for a later `dive-into-plan` pass.
|
|
|
14
21
|
3. Draft in `plan.md`: alignment, options, open questions. For each applicable surface, plan the work or mark N/A with reason:
|
|
15
22
|
- Application code · unit/integration tests · e2e · IaC · CI/CD · config/secrets (names only) · observability/rollback · security/data · reference impact
|
|
16
23
|
4. Ground items in real repo tooling (profile or direct inspection). Do not guess.
|
|
17
|
-
5.
|
|
24
|
+
5. For architectural decisions, consult `decisions/README.md`, relevant `decisions/indexes/`, and local `context/**/decisions/` when present. Use metadata such as Area, Scope, Tags, and supersession links to avoid loading every ADR.
|
|
25
|
+
6. Iterate with the human until direction is settled. Do not distribute yet.
|
|
26
|
+
|
|
27
|
+
## ADR Guidance
|
|
28
|
+
|
|
29
|
+
Consider an ADR only when a decision is architecturally significant: it crosses
|
|
30
|
+
team boundaries, has multiple credible options, or is costly to reverse.
|
|
31
|
+
Routine technical choices belong in `plan.md`, specs, or notes.
|
|
18
32
|
|
|
19
33
|
## Handoff
|
|
20
34
|
|
|
21
|
-
When
|
|
35
|
+
When a recommendation is ready, invoke `devils-advocate` if the human wants a
|
|
36
|
+
challenge pass. When settled, invoke `dive-into-plan`.
|
|
22
37
|
|
|
23
38
|
## Done when
|
|
24
39
|
|
|
25
40
|
- Initiative exists (or reason given why not).
|
|
26
41
|
- `plan.md` covers every applicable surface.
|
|
42
|
+
- Existing accepted and local ADRs were consulted where relevant.
|
|
27
43
|
- Open questions visible; settled truth not frozen in `plan.md` alone.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-profile-baseline
|
|
3
|
+
description: Populate context/project-profile.md from source-backed repository facts. Use ONLY when the human explicitly asks to run the project profile, create a project profile, or establish a repository operating baseline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Project Profile Baseline
|
|
7
|
+
|
|
8
|
+
Invocation-only. Populate `context/project-profile.md` with stable repo-wide
|
|
9
|
+
operating facts.
|
|
10
|
+
|
|
11
|
+
## Workflow
|
|
12
|
+
|
|
13
|
+
1. Read nearest `AGENTS.md`, `context/README.md`, and existing `context/project-profile.md`.
|
|
14
|
+
2. Inspect source-backed facts: manifests, lockfiles, runtime files, package scripts, test config, CI/CD, deploy scripts, IaC, observability config, generated-artifact owners, and documentation boundaries.
|
|
15
|
+
3. Record repository shape, stack/runtime, commands, verification, delivery, infrastructure/configuration, operations, generated artifacts, docs boundaries, and known unknowns.
|
|
16
|
+
4. Cite source paths where useful. Mark unknowns explicitly. Do not invent hidden commands or external pipeline behavior.
|
|
17
|
+
5. Keep initiative-specific details out of the profile.
|
|
18
|
+
|
|
19
|
+
## Done When
|
|
20
|
+
|
|
21
|
+
- `context/project-profile.md` is populated from source-backed facts.
|
|
22
|
+
- Unknowns and external assumptions are explicit.
|
|
23
|
+
- Future agents can choose default commands and verification layers without rediscovering the repo.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-profile-refresh
|
|
3
|
+
description: Refresh context/project-profile.md from source-backed repository changes. Use ONLY when the human explicitly asks to update the project profile, refresh the repository baseline, or when a release documentation refresh such as reference-from-tags needs profile-relevant changes checked.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Project Profile Refresh
|
|
7
|
+
|
|
8
|
+
Invocation-only except as a pre-check during release documentation refreshes.
|
|
9
|
+
Update `context/project-profile.md` only for stable repo-wide operating facts.
|
|
10
|
+
|
|
11
|
+
## Workflow
|
|
12
|
+
|
|
13
|
+
1. Read nearest `AGENTS.md`, existing `context/project-profile.md`, and `context/current.md` when present.
|
|
14
|
+
2. If release tags are known, inspect profile-relevant changes:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
git diff --name-status <base>..<target> -- <profile-relevant-paths>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
3. Check manifests, lockfiles, runtime files, package scripts, test config, CI/CD, deploy scripts, IaC, observability config, generated artifacts, and documentation boundaries.
|
|
21
|
+
4. Update only stable facts that changed. Preserve useful existing context.
|
|
22
|
+
5. Do not update the profile for initiative-specific details, transient scaffolding, or unverified guesses.
|
|
23
|
+
6. Mark unknowns explicitly and cite source paths where useful.
|
|
24
|
+
|
|
25
|
+
## Done When
|
|
26
|
+
|
|
27
|
+
- Stable repo-wide operating facts are current.
|
|
28
|
+
- Initiative-specific and speculative details remain out of the profile.
|
|
29
|
+
- Documentation refreshes can rely on the profile for source roots, commands, delivery, infrastructure, and generated artifacts.
|
package/template/AGENTS.md
CHANGED
|
@@ -10,7 +10,10 @@ Initiatives under [`context/initiatives/`](context/initiatives/) are disposable;
|
|
|
10
10
|
|
|
11
11
|
Invocation-only skills — ask by name:
|
|
12
12
|
|
|
13
|
+
- [`project-profile-baseline`](.agents/skills/project-profile-baseline/SKILL.md) — populate [`context/project-profile.md`](context/project-profile.md).
|
|
14
|
+
- [`project-profile-refresh`](.agents/skills/project-profile-refresh/SKILL.md) — refresh stable repo-wide profile facts.
|
|
13
15
|
- [`plan-with-context`](.agents/skills/plan-with-context/SKILL.md) — draft a plan in `plan.md`.
|
|
16
|
+
- [`devils-advocate`](.agents/skills/devils-advocate/SKILL.md) — critique a draft plan before distribution.
|
|
14
17
|
- [`dive-into-plan`](.agents/skills/dive-into-plan/SKILL.md) — interrogate gaps, distribute into per-concern docs, promote to [`decisions/`](decisions/).
|
|
15
18
|
|
|
16
19
|
[`context/project-profile.md`](context/project-profile.md) — repo-wide stack, commands, and test facts when populated.
|
|
@@ -13,12 +13,16 @@ Persists elsewhere: [`../decisions/`](../decisions/) (durable log); `reference/`
|
|
|
13
13
|
## Flow
|
|
14
14
|
|
|
15
15
|
```text
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
project-profile-baseline/refresh -> project-profile.md
|
|
17
|
+
plan-with-context -> initiatives/<slug>/plan.md
|
|
18
|
+
devils-advocate -> critique before distribution
|
|
19
|
+
dive-into-plan -> per-concern docs + ../decisions/
|
|
18
20
|
```
|
|
19
21
|
|
|
20
22
|
1. Copy `_templates/initiative/` to `initiatives/<slug>/`.
|
|
21
|
-
2. Invoke `
|
|
22
|
-
3.
|
|
23
|
+
2. Invoke `project-profile-baseline` when repo-wide commands and operating facts are not yet populated.
|
|
24
|
+
3. Invoke `plan-with-context` to draft `plan.md`.
|
|
25
|
+
4. Optionally invoke `devils-advocate` to challenge a meaningful recommendation.
|
|
26
|
+
5. When settled, invoke `dive-into-plan` to distribute and promote decisions.
|
|
23
27
|
|
|
24
28
|
Settled truth must not live only in `plan.md`. Do not edit `reference/` from here — use `release-doc-notes.md` for future reference impact.
|
|
@@ -14,7 +14,8 @@ Started: YYYY-MM-DD
|
|
|
14
14
|
|
|
15
15
|
## Decisions
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Keep active ADR drafts in `decisions/`. Promote only approved, implemented or
|
|
18
|
+
accepted architectural decisions to repo-wide [`decisions/`](../../../decisions/).
|
|
18
19
|
|
|
19
20
|
- None yet.
|
|
20
21
|
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Status: Proposed
|
|
4
4
|
Date: YYYY-MM-DD
|
|
5
|
+
Area: TBD
|
|
6
|
+
Scope: TBD
|
|
7
|
+
Tags: TBD
|
|
8
|
+
Supersedes: None
|
|
9
|
+
Superseded by: None
|
|
5
10
|
|
|
6
11
|
## Context
|
|
7
12
|
|
|
@@ -31,4 +36,3 @@ Negative or tradeoffs:
|
|
|
31
36
|
## Links
|
|
32
37
|
|
|
33
38
|
- Related specs, PRs, tickets, discussions, or code paths.
|
|
34
|
-
|
|
@@ -10,29 +10,55 @@ accepted decisions are promoted here where they stay findable.
|
|
|
10
10
|
|
|
11
11
|
- One file per decision: `NNNN-short-title.md`, numbered in order.
|
|
12
12
|
- Decisions are append-only. Do not rewrite history. When a decision changes,
|
|
13
|
-
add a new decision and
|
|
14
|
-
- Each decision records
|
|
15
|
-
|
|
13
|
+
add a new decision and link both directions with `Supersedes` and `Superseded by`.
|
|
14
|
+
- Each decision records status, date, area, scope, tags, supersession, context,
|
|
15
|
+
decision, consequences, alternatives, origin, and links.
|
|
16
16
|
- Copy [`0000-template.md`](0000-template.md) to start a new entry.
|
|
17
17
|
|
|
18
|
+
## When To Write An ADR
|
|
19
|
+
|
|
20
|
+
Write an ADR only for architecturally significant decisions: choices that cross
|
|
21
|
+
team boundaries, have multiple credible options, or are costly to reverse.
|
|
22
|
+
Routine implementation choices belong in initiative notes, specs, plans, or
|
|
23
|
+
code review.
|
|
24
|
+
|
|
25
|
+
## Metadata
|
|
26
|
+
|
|
27
|
+
- `Area` is the most specific stable repo path or bounded product area.
|
|
28
|
+
- `Scope` is the functional boundary affected by the decision.
|
|
29
|
+
- `Tags` are lowercase retrieval terms.
|
|
30
|
+
- `Supersedes` and `Superseded by` are explicit links or `None`.
|
|
31
|
+
|
|
18
32
|
## Statuses
|
|
19
33
|
|
|
20
|
-
- `Proposed` - drafted, not yet accepted.
|
|
21
34
|
- `Accepted` - in force.
|
|
22
35
|
- `Superseded` - replaced by a later decision; kept for history.
|
|
23
36
|
- `Deprecated` - no longer applies, with no direct replacement.
|
|
24
37
|
|
|
25
|
-
|
|
38
|
+
Use `Proposed` or `Recommended` only in local `context/**/decisions/` folders
|
|
39
|
+
while work is active or planned. To see what is currently in force, read root
|
|
40
|
+
entries with status `Accepted`.
|
|
26
41
|
|
|
27
42
|
## Promotion From Initiatives
|
|
28
43
|
|
|
29
44
|
The `dive-into-plan` skill promotes accepted decisions out of an
|
|
30
45
|
initiative's scratch `context/initiatives/<slug>/decisions/` folder into this
|
|
31
|
-
log
|
|
32
|
-
|
|
46
|
+
log when the decision is accepted and implemented, or when a human explicitly
|
|
47
|
+
says it is ready for root history. On promotion, assign the next number,
|
|
48
|
+
preserve or complete metadata, update indexes, and link back to the origin.
|
|
49
|
+
|
|
50
|
+
## Secondary Indexes
|
|
51
|
+
|
|
52
|
+
Secondary indexes are navigation aids. They do not replace ADR files or this
|
|
53
|
+
root index.
|
|
54
|
+
|
|
55
|
+
- [Index guidance](indexes/README.md)
|
|
56
|
+
- [By area](indexes/by-area.md)
|
|
57
|
+
- [By status](indexes/by-status.md)
|
|
58
|
+
- [By origin](indexes/by-origin.md)
|
|
33
59
|
|
|
34
60
|
## Index
|
|
35
61
|
|
|
36
|
-
| Number | Title | Status | Date |
|
|
37
|
-
| --- | --- | --- | --- |
|
|
38
|
-
| 0000 | (template) | - | - |
|
|
62
|
+
| Number | Title | Status | Date | Area | Scope | Origin |
|
|
63
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
64
|
+
| 0000 | (template) | - | - | - | - | - |
|