godpowers 1.6.19 → 1.6.20
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/AGENTS.md +29 -6
- package/CHANGELOG.md +36 -0
- package/README.md +6 -6
- package/RELEASE.md +34 -30
- package/SKILL.md +7 -1
- package/lib/README.md +3 -0
- package/lib/feature-awareness.js +18 -0
- package/lib/recipe-coverage-sync.js +149 -0
- package/lib/release-surface-sync.js +153 -0
- package/lib/repo-surface-sync.js +16 -4
- package/lib/route-quality-sync.js +286 -0
- package/lib/router.js +4 -1
- package/package.json +2 -2
- package/routing/god-party.yaml +4 -2
- package/routing/god-story-build.yaml +11 -2
- package/routing/recipes/automation-setup.yaml +25 -0
- package/routing/recipes/context-refresh.yaml +26 -0
- package/routing/recipes/release-maintenance.yaml +27 -0
- package/routing/recipes/story-work.yaml +29 -0
- package/skills/god-doctor.md +8 -1
- package/skills/god-sync.md +8 -4
- package/skills/god-version.md +1 -1
package/AGENTS.md
CHANGED
|
@@ -37,11 +37,34 @@ projects from raw idea to hardened production.
|
|
|
37
37
|
- Every claim must fail the substitution test (swap in a competitor, sentence must break)
|
|
38
38
|
|
|
39
39
|
<!-- pillars:begin -->
|
|
40
|
-
|
|
40
|
+
# Godpowers Project Context
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
This is a Godpowers project. Godpowers uses the Pillars standard as its native project context layer.
|
|
43
|
+
Coding agents read project context from `./agents/*.md` before changing code, while `.godpowers/` remains the Godpowers workflow state and artifact layer.
|
|
44
|
+
|
|
45
|
+
## At the start of any task
|
|
46
|
+
|
|
47
|
+
1. Load every pillar whose frontmatter has `always_load: true`.
|
|
48
|
+
2. Scan remaining pillar frontmatter and select task-relevant primaries from `triggers` and `covers`.
|
|
49
|
+
3. Add each primary pillar direct `must_read_with` dependencies, depth 1 only.
|
|
50
|
+
4. Read every pillar body in the computed load set.
|
|
51
|
+
5. Read `see_also` pillars only when the task explicitly touches that area.
|
|
52
|
+
6. Follow Rules, apply Workflows, heed Watchouts, and ask before deciding open Gaps.
|
|
53
|
+
|
|
54
|
+
## Handling missing pillars
|
|
55
|
+
|
|
56
|
+
| State | Action |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `status: present` | Load and comply. |
|
|
59
|
+
| `status: stub` | Treat the concern as acknowledged but undecided. Ask before making domain decisions. |
|
|
60
|
+
| Name in `excluded:` | Treat as intentionally not applicable. |
|
|
61
|
+
| Relevant but absent | Infer from code, state the assumption, and recommend authoring the pillar. |
|
|
62
|
+
|
|
63
|
+
If `context.md` or `repo.md` is missing, pause and create stubs before continuing.
|
|
64
|
+
|
|
65
|
+
## Excluded pillars
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
excluded: []
|
|
69
|
+
```
|
|
47
70
|
<!-- pillars:end -->
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,42 @@ All notable changes to Godpowers will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.6.20] - 2026-05-16
|
|
11
|
+
|
|
12
|
+
Automation surface closeout and release guardrails.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Added `lib/route-quality-sync.js` to detect symbolic route spawns,
|
|
16
|
+
unresolved agent targets, and unapproved contextual route exits.
|
|
17
|
+
- Added `lib/recipe-coverage-sync.js` to detect missing high-frequency intent
|
|
18
|
+
recipes for release maintenance, docs drift, context refresh, story work, and
|
|
19
|
+
automation setup.
|
|
20
|
+
- Added `lib/release-surface-sync.js` to detect release-facing drift across
|
|
21
|
+
badges, changelog, release notes, package guards, release checklist policy,
|
|
22
|
+
and package lock version.
|
|
23
|
+
- Added recipe routes for release maintenance, context refresh, story work, and
|
|
24
|
+
automation setup.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- `/god-party` routing now uses `built-in` as the primary owner and declares
|
|
28
|
+
selectable specialist personas under `parallel-spawns`.
|
|
29
|
+
- `/god-story-build` routing now uses `god-planner` as primary and declares
|
|
30
|
+
executor plus reviewer agents as secondary spawns.
|
|
31
|
+
- `lib/router.js` now includes conditional `parallel-spawns` in spawned-agent
|
|
32
|
+
resolution.
|
|
33
|
+
- Repo surface sync now includes route-quality, recipe-coverage, and
|
|
34
|
+
release-surface checks.
|
|
35
|
+
|
|
36
|
+
### Guardrails
|
|
37
|
+
- Route quality checks now block symbolic spawn tokens, unresolved specialist
|
|
38
|
+
targets, unapproved contextual exits, and durable-writing routes without
|
|
39
|
+
standards coverage.
|
|
40
|
+
- Release surface checks now require package, lockfile, README badge,
|
|
41
|
+
changelog, release notes, release checklist, and package payload guards to
|
|
42
|
+
agree before publish.
|
|
43
|
+
|
|
8
44
|
## [1.6.19] - 2026-05-16
|
|
9
45
|
|
|
10
46
|
Repository surface sync and status truth closeout.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/aihxp/godpowers/actions/workflows/ci.yml)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-
[](CHANGELOG.md)
|
|
6
6
|
[](https://www.npmjs.com/package/godpowers)
|
|
7
7
|
|
|
8
8
|
**Ship fast. Ship right. Ship everything. Ship accountably.**
|
|
@@ -12,11 +12,11 @@ idea to hardened production. It runs as **slash commands inside your AI coding
|
|
|
12
12
|
tool** (Claude Code, Codex, Cursor, etc.) that orchestrate **specialist agents**
|
|
13
13
|
in fresh contexts to do the work.
|
|
14
14
|
|
|
15
|
-
Version 1.6.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
Version 1.6.20 closes the automation surface gaps around route quality, recipe
|
|
16
|
+
coverage, and release readiness. Godpowers now checks symbolic route spawns,
|
|
17
|
+
unresolved agent targets, standards coverage for durable-writing routes, missing
|
|
18
|
+
high-frequency recipes, package payload guards, and release-facing version drift
|
|
19
|
+
before closeout.
|
|
20
20
|
|
|
21
21
|
It fuses four disciplines into one unified workflow:
|
|
22
22
|
|
package/RELEASE.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
# Godpowers 1.6.
|
|
1
|
+
# Godpowers 1.6.20 Release
|
|
2
2
|
|
|
3
3
|
Date: 2026-05-16
|
|
4
4
|
|
|
5
|
-
Godpowers 1.6.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
Godpowers 1.6.20 closes the automation gaps found after repository surface
|
|
6
|
+
sync. It adds dedicated route-quality, recipe-coverage, and release-surface
|
|
7
|
+
checks so Godpowers detects disconnected route spawns, missing intent recipes,
|
|
8
|
+
and stale release-facing documentation before declaring a project or release
|
|
9
|
+
current.
|
|
10
10
|
|
|
11
11
|
## What is stable
|
|
12
12
|
|
|
13
13
|
- 109 slash commands
|
|
14
14
|
- 40 specialist agents
|
|
15
15
|
- 13 executable workflows
|
|
16
|
-
-
|
|
16
|
+
- 40 intent recipes
|
|
17
17
|
- 15-runtime installer
|
|
18
18
|
- Codex installs with generated `god-*.toml` agent metadata files
|
|
19
19
|
- Markdown specialist agent contracts at `<runtime>/agents/god-*.md`
|
|
@@ -27,35 +27,38 @@ packs, and release policy before declaring a project run current.
|
|
|
27
27
|
- Feature awareness for existing Godpowers projects
|
|
28
28
|
- Repository documentation sync checks
|
|
29
29
|
- Repository surface sync checks
|
|
30
|
+
- Route quality, recipe coverage, and release surface sync checks
|
|
30
31
|
|
|
31
32
|
## What is new
|
|
32
33
|
|
|
33
|
-
- Added `lib/
|
|
34
|
-
- Added `
|
|
35
|
-
- Added `
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
- Added `lib/route-quality-sync.js`.
|
|
35
|
+
- Added `lib/recipe-coverage-sync.js`.
|
|
36
|
+
- Added `lib/release-surface-sync.js`.
|
|
37
|
+
- Added `scripts/test-automation-surface-sync.js`.
|
|
38
|
+
- Added release maintenance, context refresh, story work, and automation setup
|
|
39
|
+
recipes.
|
|
40
|
+
- `/god-party` now declares concrete parallel specialist personas.
|
|
41
|
+
- `/god-story-build` now declares planner, executor, and reviewer handoffs
|
|
42
|
+
without symbolic spawn tokens.
|
|
43
|
+
- Feature awareness now records route quality, recipe coverage, and release
|
|
44
|
+
surface sync as known runtime features.
|
|
45
|
+
- Package contents checks now require all three new sync helpers.
|
|
46
|
+
|
|
47
|
+
## Automation surface behavior
|
|
45
48
|
|
|
46
49
|
For a Godpowers repository, the helper checks:
|
|
47
50
|
|
|
48
|
-
- every
|
|
49
|
-
|
|
51
|
+
- every routed specialist spawn resolves to a real agent or built-in runtime
|
|
52
|
+
owner
|
|
53
|
+
- every durable-writing route declares standards coverage or an approved
|
|
54
|
+
exemption
|
|
55
|
+
- high-frequency work has discoverable intent recipes
|
|
56
|
+
- release-facing version surfaces agree with `package.json`
|
|
50
57
|
- package content checks require load-bearing runtime helper files
|
|
51
|
-
-
|
|
52
|
-
- workflows have parseable metadata
|
|
53
|
-
- recipes contain slash-command routes
|
|
54
|
-
- extension manifests, package metadata, peer dependencies, and provided files agree
|
|
55
|
-
- release docs and release policy checks name repo documentation and repo surface sync
|
|
58
|
+
- release checklist policy names the current sync guards
|
|
56
59
|
|
|
57
|
-
Detection is read-only by default. Applying sync
|
|
58
|
-
|
|
60
|
+
Detection is read-only by default. Applying sync writes logs and leaves
|
|
61
|
+
judgment-heavy rewrites to scoped specialists.
|
|
59
62
|
|
|
60
63
|
## Auto-invoke and auto-spawn policy
|
|
61
64
|
|
|
@@ -77,6 +80,7 @@ Godpowers recommends scoped specialists only when judgment is needed:
|
|
|
77
80
|
Release validation includes:
|
|
78
81
|
|
|
79
82
|
- `node scripts/test-repo-surface-sync.js`
|
|
83
|
+
- `node scripts/test-automation-surface-sync.js`
|
|
80
84
|
- `node scripts/test-repo-doc-sync.js`
|
|
81
85
|
- `node scripts/test-feature-awareness.js`
|
|
82
86
|
- `node scripts/test-dashboard.js`
|
|
@@ -87,5 +91,5 @@ Release validation includes:
|
|
|
87
91
|
- `git diff --check`
|
|
88
92
|
- `npm run release:check`
|
|
89
93
|
|
|
90
|
-
The `v1.6.
|
|
91
|
-
`godpowers@1.6.
|
|
94
|
+
The `v1.6.20` tag should point to the release commit that matches the npm
|
|
95
|
+
`godpowers@1.6.20` package.
|
package/SKILL.md
CHANGED
|
@@ -215,7 +215,7 @@ Auto-invoked:
|
|
|
215
215
|
Trigger: <what caused this automatic step>
|
|
216
216
|
Agent: <god-updater | god-context-writer | none, local runtime only>
|
|
217
217
|
Local syncs:
|
|
218
|
-
+ <feature-awareness | planning-system-import | reverse-sync | source-sync | repo-doc-sync | repo-surface-sync | pillars-sync | checkpoint-sync | context-refresh>: <result or skipped reason>
|
|
218
|
+
+ <feature-awareness | planning-system-import | reverse-sync | source-sync | repo-doc-sync | repo-surface-sync | route-quality-sync | recipe-coverage-sync | release-surface-sync | pillars-sync | checkpoint-sync | context-refresh>: <result or skipped reason>
|
|
219
219
|
Artifacts: <changed files, no-op, or deferred>
|
|
220
220
|
Log: <SYNC-LOG.md, CHECKPOINT.md, REVIEW-REQUIRED.md, or none>
|
|
221
221
|
```
|
|
@@ -247,6 +247,9 @@ Automatic steps that especially need visible reporting:
|
|
|
247
247
|
`/god-status`, or `/god-mode`
|
|
248
248
|
- repo surface sync during `/god-sync`, `/god-docs`, `/god-doctor`,
|
|
249
249
|
`/god-status`, or `/god-mode`
|
|
250
|
+
- route-quality sync, recipe-coverage sync, and release-surface sync through
|
|
251
|
+
repo-surface sync during `/god-sync`, `/god-docs`, `/god-doctor`,
|
|
252
|
+
`/god-status`, or `/god-mode`
|
|
250
253
|
|
|
251
254
|
### 13. Proactive Auto-Invoke Policy
|
|
252
255
|
Godpowers should be proactive from disk evidence, not from guesswork. Before
|
|
@@ -291,6 +294,9 @@ Run these local runtime helpers automatically when their trigger is present:
|
|
|
291
294
|
`lib/repo-surface-sync.run` during `/god-sync`, `/god-docs`, or
|
|
292
295
|
`/god-mode` when command routing, package payload, agent handoffs, workflow
|
|
293
296
|
metadata, recipe routes, extension packs, or release policy may have drifted.
|
|
297
|
+
- `lib/route-quality-sync.detect`, `lib/recipe-coverage-sync.detect`, and
|
|
298
|
+
`lib/release-surface-sync.detect` through repo-surface sync when route
|
|
299
|
+
spawns, high-frequency recipes, or release-facing surfaces may have drifted.
|
|
294
300
|
- Context refresh dry-run after `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`,
|
|
295
301
|
`.cursor/rules/`, `.windsurfrules`, `.github/copilot-instructions.md`,
|
|
296
302
|
`.clinerules`, `.roo/`, or `.continue/` changes.
|
package/lib/README.md
CHANGED
|
@@ -15,6 +15,9 @@ package-level integrations.
|
|
|
15
15
|
| `feature-awareness.js` | Detect and refresh existing-project awareness after runtime upgrades. |
|
|
16
16
|
| `repo-doc-sync.js` | Detect and refresh mechanical repository documentation surfaces. |
|
|
17
17
|
| `repo-surface-sync.js` | Detect structural drift across commands, routes, packages, agents, workflows, recipes, extensions, and release policy. |
|
|
18
|
+
| `route-quality-sync.js` | Detect symbolic route spawns, unresolved agent targets, and unapproved contextual route exits. |
|
|
19
|
+
| `recipe-coverage-sync.js` | Detect missing high-frequency intent recipe coverage. |
|
|
20
|
+
| `release-surface-sync.js` | Detect release-facing drift across badges, release notes, changelog, package checks, and release checklist policy. |
|
|
18
21
|
| `budget.js` | Read and enforce configured budget controls. |
|
|
19
22
|
| `cost-tracker.js` | Track token and cost estimates from event streams. |
|
|
20
23
|
|
package/lib/feature-awareness.js
CHANGED
|
@@ -46,6 +46,24 @@ const FEATURES = [
|
|
|
46
46
|
since: '1.6.19',
|
|
47
47
|
commands: ['/god-sync', '/god-docs', '/god-doctor', '/god-status', '/god-mode'],
|
|
48
48
|
description: 'Detect structural drift across routing, packages, agents, workflows, recipes, extensions, and release policy.'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'route-quality-sync',
|
|
52
|
+
since: '1.6.19',
|
|
53
|
+
commands: ['/god-sync', '/god-doctor', '/god-status', '/god-mode'],
|
|
54
|
+
description: 'Detect symbolic route spawns, unresolved agent targets, and unapproved contextual route exits.'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'recipe-coverage-sync',
|
|
58
|
+
since: '1.6.19',
|
|
59
|
+
commands: ['/god-sync', '/god-doctor', '/god-status', '/god-mode'],
|
|
60
|
+
description: 'Detect missing intent recipes for release, docs, context refresh, story work, and automation setup.'
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'release-surface-sync',
|
|
64
|
+
since: '1.6.19',
|
|
65
|
+
commands: ['/god-sync', '/god-docs', '/god-doctor', '/god-status', '/god-mode'],
|
|
66
|
+
description: 'Detect release-facing drift across badges, release notes, changelog, package checks, and release checklist policy.'
|
|
49
67
|
}
|
|
50
68
|
];
|
|
51
69
|
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recipe coverage sync.
|
|
3
|
+
*
|
|
4
|
+
* Keeps fuzzy user intent connected to shipped command routes for the
|
|
5
|
+
* high-frequency areas that users naturally ask for in prose.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const recipes = require('./recipes');
|
|
12
|
+
|
|
13
|
+
const LOG_PATH = '.godpowers/surface/RECIPE-COVERAGE-SYNC.md';
|
|
14
|
+
|
|
15
|
+
const REQUIRED_COVERAGE = [
|
|
16
|
+
{
|
|
17
|
+
id: 'release-maintenance',
|
|
18
|
+
description: 'release maintenance',
|
|
19
|
+
commands: ['/god-sync', '/god-docs', '/god-version']
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'docs-drift',
|
|
23
|
+
description: 'documentation drift',
|
|
24
|
+
commands: ['/god-docs']
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'context-refresh',
|
|
28
|
+
description: 'context refresh and feature awareness',
|
|
29
|
+
commands: ['/god-context', '/god-sync', '/god-status']
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'story-work',
|
|
33
|
+
description: 'story creation, build, verify, and close',
|
|
34
|
+
commands: ['/god-story', '/god-story-build', '/god-story-verify', '/god-story-close']
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'automation-setup',
|
|
38
|
+
description: 'automation setup and status',
|
|
39
|
+
commands: ['/god-automation-setup', '/god-automation-status']
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
function read(projectRoot, relPath) {
|
|
44
|
+
const file = path.join(projectRoot, relPath);
|
|
45
|
+
if (!fs.existsSync(file)) return '';
|
|
46
|
+
return fs.readFileSync(file, 'utf8');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function write(projectRoot, relPath, content) {
|
|
50
|
+
const file = path.join(projectRoot, relPath);
|
|
51
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
52
|
+
fs.writeFileSync(file, content);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function addCheck(checks, id, status, relPath, message, opts = {}) {
|
|
56
|
+
checks.push({
|
|
57
|
+
area: 'recipe-coverage',
|
|
58
|
+
id,
|
|
59
|
+
status,
|
|
60
|
+
path: relPath,
|
|
61
|
+
message,
|
|
62
|
+
severity: opts.severity || (status === 'fresh' ? 'info' : 'warning'),
|
|
63
|
+
spawn: opts.spawn || null
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function recipePath(projectRoot, name) {
|
|
68
|
+
const rel = `routing/recipes/${name}.yaml`;
|
|
69
|
+
return fs.existsSync(path.join(projectRoot, rel)) ? rel : 'routing/recipes/';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function detect(projectRoot) {
|
|
73
|
+
recipes.clearCache();
|
|
74
|
+
const checks = [];
|
|
75
|
+
const all = recipes.loadAll();
|
|
76
|
+
const recipeTexts = new Map();
|
|
77
|
+
for (const recipe of all) {
|
|
78
|
+
const name = recipe.metadata && recipe.metadata.name;
|
|
79
|
+
if (!name) continue;
|
|
80
|
+
recipeTexts.set(name, read(projectRoot, `routing/recipes/${name}.yaml`));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for (const required of REQUIRED_COVERAGE) {
|
|
84
|
+
const matched = [...recipeTexts.entries()].filter(([, text]) =>
|
|
85
|
+
required.commands.every((command) => text.includes(command))
|
|
86
|
+
);
|
|
87
|
+
addCheck(
|
|
88
|
+
checks,
|
|
89
|
+
`coverage-${required.id}`,
|
|
90
|
+
matched.length > 0 ? 'fresh' : 'stale',
|
|
91
|
+
matched.length > 0 ? `routing/recipes/${matched[0][0]}.yaml` : recipePath(projectRoot, required.id),
|
|
92
|
+
matched.length > 0
|
|
93
|
+
? `Recipe coverage exists for ${required.description}.`
|
|
94
|
+
: `No recipe covers ${required.description} with ${required.commands.join(', ')}.`,
|
|
95
|
+
{ spawn: matched.length > 0 ? null : 'god-roadmap-reconciler' }
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const stale = checks.filter((check) => check.status !== 'fresh');
|
|
100
|
+
return {
|
|
101
|
+
status: stale.length === 0 ? 'fresh' : 'stale',
|
|
102
|
+
checks,
|
|
103
|
+
stale
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function appendLog(projectRoot, before, after) {
|
|
108
|
+
const now = new Date().toISOString();
|
|
109
|
+
const lines = [];
|
|
110
|
+
if (fs.existsSync(path.join(projectRoot, LOG_PATH))) {
|
|
111
|
+
lines.push(read(projectRoot, LOG_PATH).replace(/\s*$/, ''));
|
|
112
|
+
lines.push('');
|
|
113
|
+
} else {
|
|
114
|
+
lines.push('# Recipe Coverage Sync Log');
|
|
115
|
+
lines.push('');
|
|
116
|
+
lines.push('- [DECISION] This file records recipe-coverage sync checks run by Godpowers.');
|
|
117
|
+
lines.push('');
|
|
118
|
+
}
|
|
119
|
+
lines.push(`## ${now}`);
|
|
120
|
+
lines.push('');
|
|
121
|
+
lines.push(`- [DECISION] Recipe coverage status before apply was ${before.status}.`);
|
|
122
|
+
lines.push(`- [DECISION] Recipe coverage status after apply is ${after.status}.`);
|
|
123
|
+
lines.push('');
|
|
124
|
+
write(projectRoot, LOG_PATH, lines.join('\n'));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function run(projectRoot, opts = {}) {
|
|
128
|
+
const before = detect(projectRoot);
|
|
129
|
+
const after = detect(projectRoot);
|
|
130
|
+
if (opts.log !== false) appendLog(projectRoot, before, after);
|
|
131
|
+
return {
|
|
132
|
+
before,
|
|
133
|
+
after,
|
|
134
|
+
applied: [],
|
|
135
|
+
logPath: opts.log === false ? null : LOG_PATH
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function summary(report) {
|
|
140
|
+
return report.status === 'fresh' ? 'fresh' : `${report.stale.length} stale`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = {
|
|
144
|
+
LOG_PATH,
|
|
145
|
+
REQUIRED_COVERAGE,
|
|
146
|
+
detect,
|
|
147
|
+
run,
|
|
148
|
+
summary
|
|
149
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Release surface sync.
|
|
3
|
+
*
|
|
4
|
+
* Detects whether release-facing repo surfaces agree before a package or tag
|
|
5
|
+
* is treated as ready: package metadata, lockfile, release notes, changelog,
|
|
6
|
+
* README badge, release checklist, and package payload guardrails.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const LOG_PATH = '.godpowers/surface/RELEASE-SURFACE-SYNC.md';
|
|
13
|
+
|
|
14
|
+
const REQUIRED_PACKAGE_GUARDS = [
|
|
15
|
+
'lib/route-quality-sync.js',
|
|
16
|
+
'lib/recipe-coverage-sync.js',
|
|
17
|
+
'lib/release-surface-sync.js'
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
function read(projectRoot, relPath) {
|
|
21
|
+
const file = path.join(projectRoot, relPath);
|
|
22
|
+
if (!fs.existsSync(file)) return '';
|
|
23
|
+
return fs.readFileSync(file, 'utf8');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function write(projectRoot, relPath, content) {
|
|
27
|
+
const file = path.join(projectRoot, relPath);
|
|
28
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
29
|
+
fs.writeFileSync(file, content);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function readJson(projectRoot, relPath) {
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(read(projectRoot, relPath));
|
|
35
|
+
} catch (err) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function addCheck(checks, id, status, relPath, message, opts = {}) {
|
|
41
|
+
checks.push({
|
|
42
|
+
area: 'release-surface',
|
|
43
|
+
id,
|
|
44
|
+
status,
|
|
45
|
+
path: relPath,
|
|
46
|
+
message,
|
|
47
|
+
severity: opts.severity || (status === 'fresh' ? 'info' : 'warning'),
|
|
48
|
+
spawn: opts.spawn || null
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function detect(projectRoot) {
|
|
53
|
+
const checks = [];
|
|
54
|
+
const pkg = readJson(projectRoot, 'package.json') || {};
|
|
55
|
+
const lock = readJson(projectRoot, 'package-lock.json') || {};
|
|
56
|
+
const version = pkg.version || '0.0.0';
|
|
57
|
+
|
|
58
|
+
addCheck(
|
|
59
|
+
checks,
|
|
60
|
+
'package-lock-version',
|
|
61
|
+
lock.version === version ? 'fresh' : 'stale',
|
|
62
|
+
'package-lock.json',
|
|
63
|
+
lock.version === version
|
|
64
|
+
? 'package-lock.json version matches package.json.'
|
|
65
|
+
: `package-lock.json version ${lock.version || 'missing'} does not match package.json ${version}.`
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const surfaces = [
|
|
69
|
+
['readme-version-badge', 'README.md', `version-${version}-blue`],
|
|
70
|
+
['changelog-version', 'CHANGELOG.md', `## [${version}]`],
|
|
71
|
+
['release-version', 'RELEASE.md', `Godpowers ${version}`],
|
|
72
|
+
['release-checklist-route-quality', 'docs/RELEASE-CHECKLIST.md', 'route-quality-sync'],
|
|
73
|
+
['release-checklist-recipe-coverage', 'docs/RELEASE-CHECKLIST.md', 'recipe-coverage-sync'],
|
|
74
|
+
['release-checklist-release-surface', 'docs/RELEASE-CHECKLIST.md', 'release-surface-sync']
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
for (const [id, relPath, expected] of surfaces) {
|
|
78
|
+
const ok = read(projectRoot, relPath).includes(expected);
|
|
79
|
+
addCheck(
|
|
80
|
+
checks,
|
|
81
|
+
id,
|
|
82
|
+
ok ? 'fresh' : 'stale',
|
|
83
|
+
relPath,
|
|
84
|
+
ok ? `${relPath} includes ${expected}.` : `${relPath} is missing ${expected}.`,
|
|
85
|
+
{ spawn: ok ? null : 'god-docs-writer' }
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const packageCheckText = read(projectRoot, 'scripts/check-package-contents.js');
|
|
90
|
+
for (const required of REQUIRED_PACKAGE_GUARDS) {
|
|
91
|
+
const ok = packageCheckText.includes(required);
|
|
92
|
+
addCheck(
|
|
93
|
+
checks,
|
|
94
|
+
`package-guard-${required.replace(/[^a-z0-9]+/gi, '-')}`,
|
|
95
|
+
ok ? 'fresh' : 'stale',
|
|
96
|
+
'scripts/check-package-contents.js',
|
|
97
|
+
ok
|
|
98
|
+
? `Package contents check requires ${required}.`
|
|
99
|
+
: `Package contents check does not require ${required}.`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const stale = checks.filter((check) => check.status !== 'fresh');
|
|
104
|
+
return {
|
|
105
|
+
status: stale.length === 0 ? 'fresh' : 'stale',
|
|
106
|
+
checks,
|
|
107
|
+
stale
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function appendLog(projectRoot, before, after) {
|
|
112
|
+
const now = new Date().toISOString();
|
|
113
|
+
const lines = [];
|
|
114
|
+
if (fs.existsSync(path.join(projectRoot, LOG_PATH))) {
|
|
115
|
+
lines.push(read(projectRoot, LOG_PATH).replace(/\s*$/, ''));
|
|
116
|
+
lines.push('');
|
|
117
|
+
} else {
|
|
118
|
+
lines.push('# Release Surface Sync Log');
|
|
119
|
+
lines.push('');
|
|
120
|
+
lines.push('- [DECISION] This file records release-surface sync checks run by Godpowers.');
|
|
121
|
+
lines.push('');
|
|
122
|
+
}
|
|
123
|
+
lines.push(`## ${now}`);
|
|
124
|
+
lines.push('');
|
|
125
|
+
lines.push(`- [DECISION] Release surface status before apply was ${before.status}.`);
|
|
126
|
+
lines.push(`- [DECISION] Release surface status after apply is ${after.status}.`);
|
|
127
|
+
lines.push('');
|
|
128
|
+
write(projectRoot, LOG_PATH, lines.join('\n'));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function run(projectRoot, opts = {}) {
|
|
132
|
+
const before = detect(projectRoot);
|
|
133
|
+
const after = detect(projectRoot);
|
|
134
|
+
if (opts.log !== false) appendLog(projectRoot, before, after);
|
|
135
|
+
return {
|
|
136
|
+
before,
|
|
137
|
+
after,
|
|
138
|
+
applied: [],
|
|
139
|
+
logPath: opts.log === false ? null : LOG_PATH
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function summary(report) {
|
|
144
|
+
return report.status === 'fresh' ? 'fresh' : `${report.stale.length} stale`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module.exports = {
|
|
148
|
+
LOG_PATH,
|
|
149
|
+
REQUIRED_PACKAGE_GUARDS,
|
|
150
|
+
detect,
|
|
151
|
+
run,
|
|
152
|
+
summary
|
|
153
|
+
};
|
package/lib/repo-surface-sync.js
CHANGED
|
@@ -13,6 +13,9 @@ const path = require('path');
|
|
|
13
13
|
const { parseSimpleYaml } = require('./intent');
|
|
14
14
|
const extensions = require('./extensions');
|
|
15
15
|
const repoDocSync = require('./repo-doc-sync');
|
|
16
|
+
const routeQualitySync = require('./route-quality-sync');
|
|
17
|
+
const recipeCoverageSync = require('./recipe-coverage-sync');
|
|
18
|
+
const releaseSurfaceSync = require('./release-surface-sync');
|
|
16
19
|
|
|
17
20
|
const LOG_PATH = '.godpowers/surface/REPO-SURFACE-SYNC.md';
|
|
18
21
|
|
|
@@ -38,6 +41,9 @@ const REQUIRED_PACKAGE_CHECKS = [
|
|
|
38
41
|
'lib/feature-awareness.js',
|
|
39
42
|
'lib/repo-doc-sync.js',
|
|
40
43
|
'lib/repo-surface-sync.js',
|
|
44
|
+
'lib/route-quality-sync.js',
|
|
45
|
+
'lib/recipe-coverage-sync.js',
|
|
46
|
+
'lib/release-surface-sync.js',
|
|
41
47
|
'routing/god-export-otel.yaml'
|
|
42
48
|
];
|
|
43
49
|
|
|
@@ -204,9 +210,12 @@ function agentChecks(projectRoot) {
|
|
|
204
210
|
|
|
205
211
|
for (const route of routes) {
|
|
206
212
|
const parsed = parseRoute(projectRoot, route);
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
: []
|
|
213
|
+
const execution = parsed && parsed.execution ? parsed.execution : {};
|
|
214
|
+
const spawns = [
|
|
215
|
+
...(Array.isArray(execution.spawns) ? execution.spawns : []),
|
|
216
|
+
...(Array.isArray(execution['secondary-spawns']) ? execution['secondary-spawns'] : []),
|
|
217
|
+
...(Array.isArray(execution['parallel-spawns']) ? execution['parallel-spawns'] : [])
|
|
218
|
+
].map((spawn) => (spawn && typeof spawn === 'object' && spawn.agent) ? spawn.agent : spawn);
|
|
210
219
|
for (const spawn of spawns) {
|
|
211
220
|
if (!String(spawn).startsWith('god-')) continue;
|
|
212
221
|
if (!/^god-[a-z0-9-]+$/.test(String(spawn))) continue;
|
|
@@ -384,7 +393,10 @@ function detect(projectRoot) {
|
|
|
384
393
|
...agentChecks(projectRoot),
|
|
385
394
|
...workflowRecipeChecks(projectRoot),
|
|
386
395
|
...extensionChecks(projectRoot),
|
|
387
|
-
...releasePolicyChecks(projectRoot)
|
|
396
|
+
...releasePolicyChecks(projectRoot),
|
|
397
|
+
...routeQualitySync.detect(projectRoot).checks,
|
|
398
|
+
...recipeCoverageSync.detect(projectRoot).checks,
|
|
399
|
+
...releaseSurfaceSync.detect(projectRoot).checks
|
|
388
400
|
];
|
|
389
401
|
const stale = checks.filter((check) => check.status !== 'fresh');
|
|
390
402
|
const byArea = {};
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route quality sync.
|
|
3
|
+
*
|
|
4
|
+
* Detects disconnected route automation surfaces: symbolic spawn tokens,
|
|
5
|
+
* unresolved agent targets, contextual exits without an approved reason, and
|
|
6
|
+
* composite flows that should be represented as primary plus secondary or
|
|
7
|
+
* parallel spawns.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
const { parseSimpleYaml } = require('./intent');
|
|
14
|
+
|
|
15
|
+
const LOG_PATH = '.godpowers/surface/ROUTE-QUALITY-SYNC.md';
|
|
16
|
+
|
|
17
|
+
const CONTEXTUAL_NEXT_ALLOWED = new Set([
|
|
18
|
+
'/god',
|
|
19
|
+
'/god-agent-audit',
|
|
20
|
+
'/god-budget',
|
|
21
|
+
'/god-cache-clear',
|
|
22
|
+
'/god-check-todos',
|
|
23
|
+
'/god-context-scan',
|
|
24
|
+
'/god-cost',
|
|
25
|
+
'/god-discuss',
|
|
26
|
+
'/god-doctor',
|
|
27
|
+
'/god-extension-add',
|
|
28
|
+
'/god-extension-info',
|
|
29
|
+
'/god-extension-list',
|
|
30
|
+
'/god-extension-remove',
|
|
31
|
+
'/god-graph',
|
|
32
|
+
'/god-help',
|
|
33
|
+
'/god-lifecycle',
|
|
34
|
+
'/god-list-assumptions',
|
|
35
|
+
'/god-locate',
|
|
36
|
+
'/god-logs',
|
|
37
|
+
'/god-metrics',
|
|
38
|
+
'/god-next',
|
|
39
|
+
'/god-redo',
|
|
40
|
+
'/god-resume-work',
|
|
41
|
+
'/god-test-extension',
|
|
42
|
+
'/god-thread',
|
|
43
|
+
'/god-trace',
|
|
44
|
+
'/god-workstream'
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
const STANDARDS_EXEMPT_COMMANDS = new Set([
|
|
48
|
+
'/god-archaeology',
|
|
49
|
+
'/god-audit',
|
|
50
|
+
'/god-automation-setup',
|
|
51
|
+
'/god-debug',
|
|
52
|
+
'/god-discuss',
|
|
53
|
+
'/god-explore',
|
|
54
|
+
'/god-feature',
|
|
55
|
+
'/god-hotfix',
|
|
56
|
+
'/god-hygiene',
|
|
57
|
+
'/god-init',
|
|
58
|
+
'/god-org-context',
|
|
59
|
+
'/god-party',
|
|
60
|
+
'/god-pause-work',
|
|
61
|
+
'/god-preflight',
|
|
62
|
+
'/god-reconstruct',
|
|
63
|
+
'/god-roadmap-check',
|
|
64
|
+
'/god-smite',
|
|
65
|
+
'/god-tech-debt'
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
function read(projectRoot, relPath) {
|
|
69
|
+
const file = path.join(projectRoot, relPath);
|
|
70
|
+
if (!fs.existsSync(file)) return '';
|
|
71
|
+
return fs.readFileSync(file, 'utf8');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function write(projectRoot, relPath, content) {
|
|
75
|
+
const file = path.join(projectRoot, relPath);
|
|
76
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
77
|
+
fs.writeFileSync(file, content);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function listFiles(projectRoot, relDir, pattern) {
|
|
81
|
+
const dir = path.join(projectRoot, relDir);
|
|
82
|
+
if (!fs.existsSync(dir)) return [];
|
|
83
|
+
return fs.readdirSync(dir)
|
|
84
|
+
.filter((name) => pattern.test(name))
|
|
85
|
+
.sort()
|
|
86
|
+
.map((name) => `${relDir}/${name}`.replace(/\\/g, '/'));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function arr(value) {
|
|
90
|
+
return Array.isArray(value) ? value : [];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function parseRoute(projectRoot, routePath) {
|
|
94
|
+
try {
|
|
95
|
+
return parseSimpleYaml(read(projectRoot, routePath)) || {};
|
|
96
|
+
} catch (err) {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function addCheck(checks, id, status, relPath, message, opts = {}) {
|
|
102
|
+
checks.push({
|
|
103
|
+
area: 'route-quality',
|
|
104
|
+
id,
|
|
105
|
+
status,
|
|
106
|
+
path: relPath,
|
|
107
|
+
message,
|
|
108
|
+
severity: opts.severity || (status === 'fresh' ? 'info' : 'warning'),
|
|
109
|
+
spawn: opts.spawn || null
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function spawnTokens(route) {
|
|
114
|
+
const execution = route.execution || {};
|
|
115
|
+
return normalizeSpawnList([
|
|
116
|
+
...arr(execution.spawns),
|
|
117
|
+
...arr(execution['secondary-spawns']),
|
|
118
|
+
...arr(execution['parallel-spawns'])
|
|
119
|
+
]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function normalizeSpawnList(tokens) {
|
|
123
|
+
return tokens
|
|
124
|
+
.map((token) => {
|
|
125
|
+
if (token && typeof token === 'object' && token.agent) return token.agent;
|
|
126
|
+
return token;
|
|
127
|
+
})
|
|
128
|
+
.filter((token) => token !== null && token !== undefined);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function isAtomicSpawn(token) {
|
|
132
|
+
return token === 'built-in' || /^god-[a-z0-9-]+$/.test(token);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function detect(projectRoot) {
|
|
136
|
+
const checks = [];
|
|
137
|
+
const routes = listFiles(projectRoot, 'routing', /^god.*\.yaml$/);
|
|
138
|
+
const agents = new Set(listFiles(projectRoot, 'agents', /^god.*\.md$/)
|
|
139
|
+
.map((file) => path.basename(file, '.md')));
|
|
140
|
+
let symbolicCount = 0;
|
|
141
|
+
let unresolvedCount = 0;
|
|
142
|
+
let contextualExitCount = 0;
|
|
143
|
+
let standardsExemptCount = 0;
|
|
144
|
+
|
|
145
|
+
for (const routePath of routes) {
|
|
146
|
+
const route = parseRoute(projectRoot, routePath);
|
|
147
|
+
const command = route.metadata && route.metadata.command
|
|
148
|
+
? route.metadata.command
|
|
149
|
+
: `/${path.basename(routePath, '.yaml')}`;
|
|
150
|
+
|
|
151
|
+
for (const token of spawnTokens(route)) {
|
|
152
|
+
if (!isAtomicSpawn(String(token))) {
|
|
153
|
+
symbolicCount++;
|
|
154
|
+
addCheck(
|
|
155
|
+
checks,
|
|
156
|
+
`symbolic-spawn-${command.replace(/[^a-z0-9]+/gi, '-')}`,
|
|
157
|
+
'stale',
|
|
158
|
+
routePath,
|
|
159
|
+
`${command} uses symbolic spawn token ${token}.`,
|
|
160
|
+
{ spawn: 'god-auditor' }
|
|
161
|
+
);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (String(token).startsWith('god-') && !agents.has(String(token))) {
|
|
165
|
+
unresolvedCount++;
|
|
166
|
+
addCheck(
|
|
167
|
+
checks,
|
|
168
|
+
`unresolved-spawn-${command.replace(/[^a-z0-9]+/gi, '-')}-${token}`,
|
|
169
|
+
'stale',
|
|
170
|
+
routePath,
|
|
171
|
+
`${command} references missing agent ${token}.`,
|
|
172
|
+
{ spawn: 'god-auditor' }
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const next = route['success-path'] && route['success-path']['next-recommended'];
|
|
178
|
+
const conditionalNext = route['success-path'] && arr(route['success-path']['conditional-next']);
|
|
179
|
+
if (next === 'varies' && conditionalNext.length === 0) {
|
|
180
|
+
if (CONTEXTUAL_NEXT_ALLOWED.has(command)) {
|
|
181
|
+
contextualExitCount++;
|
|
182
|
+
} else {
|
|
183
|
+
addCheck(
|
|
184
|
+
checks,
|
|
185
|
+
`unapproved-varies-${command.replace(/[^a-z0-9]+/gi, '-')}`,
|
|
186
|
+
'stale',
|
|
187
|
+
routePath,
|
|
188
|
+
`${command} uses next-recommended: varies without an approved contextual-exit classification.`,
|
|
189
|
+
{ spawn: 'god-roadmap-reconciler' }
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const writes = arr(route.execution && route.execution.writes);
|
|
195
|
+
const writesDurableSurface = writes.length > 0;
|
|
196
|
+
if (writesDurableSurface && !route.standards) {
|
|
197
|
+
if (STANDARDS_EXEMPT_COMMANDS.has(command)) {
|
|
198
|
+
standardsExemptCount++;
|
|
199
|
+
} else {
|
|
200
|
+
addCheck(
|
|
201
|
+
checks,
|
|
202
|
+
`missing-standards-${command.replace(/[^a-z0-9]+/gi, '-')}`,
|
|
203
|
+
'stale',
|
|
204
|
+
routePath,
|
|
205
|
+
`${command} writes durable surfaces but has no standards block or approved exemption.`,
|
|
206
|
+
{ spawn: 'god-auditor' }
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (symbolicCount === 0) {
|
|
213
|
+
addCheck(checks, 'atomic-spawn-tokens', 'fresh', 'routing/', 'All route spawn tokens are atomic.');
|
|
214
|
+
}
|
|
215
|
+
if (unresolvedCount === 0) {
|
|
216
|
+
addCheck(checks, 'resolved-spawn-targets', 'fresh', 'routing/', 'All route spawn targets resolve to shipped agents or built-in runtime work.');
|
|
217
|
+
}
|
|
218
|
+
addCheck(
|
|
219
|
+
checks,
|
|
220
|
+
'contextual-exit-policy',
|
|
221
|
+
checks.some((check) => check.id.startsWith('unapproved-varies-')) ? 'stale' : 'fresh',
|
|
222
|
+
'routing/',
|
|
223
|
+
`${contextualExitCount} contextual route exits are approved and all other next routes are explicit.`,
|
|
224
|
+
{ spawn: checks.some((check) => check.id.startsWith('unapproved-varies-')) ? 'god-roadmap-reconciler' : null }
|
|
225
|
+
);
|
|
226
|
+
addCheck(
|
|
227
|
+
checks,
|
|
228
|
+
'standards-policy',
|
|
229
|
+
checks.some((check) => check.id.startsWith('missing-standards-')) ? 'stale' : 'fresh',
|
|
230
|
+
'routing/',
|
|
231
|
+
`${standardsExemptCount} durable-writing routes have approved standards exemptions and all other writing routes declare standards.`,
|
|
232
|
+
{ spawn: checks.some((check) => check.id.startsWith('missing-standards-')) ? 'god-auditor' : null }
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
const stale = checks.filter((check) => check.status !== 'fresh');
|
|
236
|
+
return {
|
|
237
|
+
status: stale.length === 0 ? 'fresh' : 'stale',
|
|
238
|
+
checks,
|
|
239
|
+
stale
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function appendLog(projectRoot, before, after) {
|
|
244
|
+
const now = new Date().toISOString();
|
|
245
|
+
const lines = [];
|
|
246
|
+
if (fs.existsSync(path.join(projectRoot, LOG_PATH))) {
|
|
247
|
+
lines.push(read(projectRoot, LOG_PATH).replace(/\s*$/, ''));
|
|
248
|
+
lines.push('');
|
|
249
|
+
} else {
|
|
250
|
+
lines.push('# Route Quality Sync Log');
|
|
251
|
+
lines.push('');
|
|
252
|
+
lines.push('- [DECISION] This file records route-quality sync checks run by Godpowers.');
|
|
253
|
+
lines.push('');
|
|
254
|
+
}
|
|
255
|
+
lines.push(`## ${now}`);
|
|
256
|
+
lines.push('');
|
|
257
|
+
lines.push(`- [DECISION] Route quality status before apply was ${before.status}.`);
|
|
258
|
+
lines.push(`- [DECISION] Route quality status after apply is ${after.status}.`);
|
|
259
|
+
lines.push('');
|
|
260
|
+
write(projectRoot, LOG_PATH, lines.join('\n'));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function run(projectRoot, opts = {}) {
|
|
264
|
+
const before = detect(projectRoot);
|
|
265
|
+
const after = detect(projectRoot);
|
|
266
|
+
if (opts.log !== false) appendLog(projectRoot, before, after);
|
|
267
|
+
return {
|
|
268
|
+
before,
|
|
269
|
+
after,
|
|
270
|
+
applied: [],
|
|
271
|
+
logPath: opts.log === false ? null : LOG_PATH
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function summary(report) {
|
|
276
|
+
return report.status === 'fresh' ? 'fresh' : `${report.stale.length} stale`;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
module.exports = {
|
|
280
|
+
LOG_PATH,
|
|
281
|
+
CONTEXTUAL_NEXT_ALLOWED,
|
|
282
|
+
STANDARDS_EXEMPT_COMMANDS,
|
|
283
|
+
detect,
|
|
284
|
+
run,
|
|
285
|
+
summary
|
|
286
|
+
};
|
package/lib/router.js
CHANGED
|
@@ -221,7 +221,10 @@ function getSpawnedAgents(command) {
|
|
|
221
221
|
if (!routing || !routing.execution) return [];
|
|
222
222
|
const primary = routing.execution.spawns || [];
|
|
223
223
|
const secondary = routing.execution['secondary-spawns'] || [];
|
|
224
|
-
|
|
224
|
+
const parallel = routing.execution['parallel-spawns'] || [];
|
|
225
|
+
return [...primary, ...secondary, ...parallel]
|
|
226
|
+
.map(spawn => (spawn && typeof spawn === 'object' && spawn.agent) ? spawn.agent : spawn)
|
|
227
|
+
.filter(spawn => spawn !== null && spawn !== undefined);
|
|
225
228
|
}
|
|
226
229
|
|
|
227
230
|
/**
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "godpowers",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.20",
|
|
4
4
|
"description": "AI-powered development system: 109 slash commands and 40 specialist agents that take a project from raw idea to hardened production. Runs inside Claude Code, Codex, Cursor, Windsurf, Gemini, and 10+ other AI coding tools.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"godpowers": "./bin/install.js"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
-
"test": "node scripts/validate-skills.js && node scripts/test-doc-surface-counts.js && bash scripts/smoke.sh && node scripts/test-runtime.js && node scripts/test-router.js && node scripts/test-recipes.js && node scripts/test-context-writer.js && node scripts/test-pillars.js && node scripts/test-artifact-linter.js && node scripts/test-artifact-diff.js && node scripts/test-design-foundation.js && node scripts/test-linkage.js && node scripts/test-impact.js && node scripts/test-reverse-sync.js && node scripts/test-planning-systems.js && node scripts/test-feature-awareness.js && node scripts/test-repo-doc-sync.js && node scripts/test-repo-surface-sync.js && node scripts/test-integration.js && node scripts/test-cross-artifact.js && node scripts/test-awesome-design.js && node scripts/test-skillui-bridge.js && node scripts/test-runtime-verification.js && node scripts/test-agent-browser.js && node scripts/test-mode-d.js && node scripts/test-runtime-heuristics.js && node scripts/test-agent-validator.js && node scripts/test-story-validator.js && node scripts/test-state.js && node scripts/test-dashboard.js && node scripts/test-automation-providers.js && node scripts/test-intent.js && node scripts/test-events.js && node scripts/test-golden-artifacts.js && node scripts/test-install-smoke.js && node scripts/test-checkpoint.js && node scripts/test-extensions.js && node scripts/test-event-reader.js && node scripts/test-state-lock.js && node scripts/test-cost-saver.js && node scripts/test-budget-onoff.js && node scripts/test-workflow-runner.js && npm run test:e2e && node scripts/test-otel-exporter.js && node scripts/test-extensions-publish.js",
|
|
9
|
+
"test": "node scripts/validate-skills.js && node scripts/test-doc-surface-counts.js && bash scripts/smoke.sh && node scripts/test-runtime.js && node scripts/test-router.js && node scripts/test-recipes.js && node scripts/test-context-writer.js && node scripts/test-pillars.js && node scripts/test-artifact-linter.js && node scripts/test-artifact-diff.js && node scripts/test-design-foundation.js && node scripts/test-linkage.js && node scripts/test-impact.js && node scripts/test-reverse-sync.js && node scripts/test-planning-systems.js && node scripts/test-feature-awareness.js && node scripts/test-repo-doc-sync.js && node scripts/test-repo-surface-sync.js && node scripts/test-automation-surface-sync.js && node scripts/test-integration.js && node scripts/test-cross-artifact.js && node scripts/test-awesome-design.js && node scripts/test-skillui-bridge.js && node scripts/test-runtime-verification.js && node scripts/test-agent-browser.js && node scripts/test-mode-d.js && node scripts/test-runtime-heuristics.js && node scripts/test-agent-validator.js && node scripts/test-story-validator.js && node scripts/test-state.js && node scripts/test-dashboard.js && node scripts/test-automation-providers.js && node scripts/test-intent.js && node scripts/test-events.js && node scripts/test-golden-artifacts.js && node scripts/test-install-smoke.js && node scripts/test-checkpoint.js && node scripts/test-extensions.js && node scripts/test-event-reader.js && node scripts/test-state-lock.js && node scripts/test-cost-saver.js && node scripts/test-budget-onoff.js && node scripts/test-workflow-runner.js && npm run test:e2e && node scripts/test-otel-exporter.js && node scripts/test-extensions-publish.js",
|
|
10
10
|
"prepublishOnly": "npm test",
|
|
11
11
|
"validate-skills": "node scripts/validate-skills.js",
|
|
12
12
|
"test:surface": "node scripts/test-doc-surface-counts.js",
|
package/routing/god-party.yaml
CHANGED
|
@@ -9,9 +9,11 @@ prerequisites:
|
|
|
9
9
|
required: []
|
|
10
10
|
|
|
11
11
|
execution:
|
|
12
|
-
spawns: [
|
|
12
|
+
spawns: [built-in]
|
|
13
13
|
context: fresh
|
|
14
|
-
|
|
14
|
+
parallel-spawns: [god-pm, god-architect, god-executor, god-quality-reviewer, god-harden-auditor, god-launch-strategist]
|
|
15
|
+
writes:
|
|
16
|
+
- .godpowers/party/*.md
|
|
15
17
|
|
|
16
18
|
success-path:
|
|
17
19
|
next-recommended: /god-next
|
|
@@ -10,9 +10,18 @@ prerequisites:
|
|
|
10
10
|
- .godpowers/stories/STORY-*.md
|
|
11
11
|
|
|
12
12
|
execution:
|
|
13
|
-
spawns: [god-planner
|
|
13
|
+
spawns: [god-planner]
|
|
14
14
|
context: fresh
|
|
15
|
-
|
|
15
|
+
secondary-spawns: [god-executor, god-spec-reviewer, god-quality-reviewer]
|
|
16
|
+
writes:
|
|
17
|
+
- .godpowers/stories/STORY-*.md
|
|
18
|
+
- source code
|
|
19
|
+
|
|
20
|
+
standards:
|
|
21
|
+
substitution-test: true
|
|
22
|
+
three-label-test: true
|
|
23
|
+
have-nots: [B-01, B-02, B-03, B-04, B-05, B-06, B-07, B-08, B-09, B-10, B-11, B-12]
|
|
24
|
+
gate-on-failure: pause-for-user
|
|
16
25
|
|
|
17
26
|
success-path:
|
|
18
27
|
next-recommended: /god-story-verify
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
apiVersion: godpowers/v1
|
|
2
|
+
kind: Recipe
|
|
3
|
+
metadata:
|
|
4
|
+
name: automation-setup
|
|
5
|
+
category: maintaining
|
|
6
|
+
description: "Set up and verify native Godpowers automations"
|
|
7
|
+
|
|
8
|
+
triggers:
|
|
9
|
+
intent-keywords:
|
|
10
|
+
- "create automation"
|
|
11
|
+
- "set up automation"
|
|
12
|
+
- "recurring godpowers"
|
|
13
|
+
- "weekly automation"
|
|
14
|
+
- "automation status"
|
|
15
|
+
|
|
16
|
+
sequences:
|
|
17
|
+
default:
|
|
18
|
+
description: "Set up and verify native Godpowers automations"
|
|
19
|
+
steps:
|
|
20
|
+
- command: "/god-automation-setup"
|
|
21
|
+
why: "Create approved host-native automation"
|
|
22
|
+
- command: "/god-automation-status"
|
|
23
|
+
why: "Confirm configured providers and active templates"
|
|
24
|
+
|
|
25
|
+
default-sequence: default
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
apiVersion: godpowers/v1
|
|
2
|
+
kind: Recipe
|
|
3
|
+
metadata:
|
|
4
|
+
name: context-refresh
|
|
5
|
+
category: knowledge
|
|
6
|
+
description: "Refresh agent context after repo, docs, or workflow changes"
|
|
7
|
+
|
|
8
|
+
triggers:
|
|
9
|
+
intent-keywords:
|
|
10
|
+
- "context refresh"
|
|
11
|
+
- "update agent context"
|
|
12
|
+
- "make agents aware"
|
|
13
|
+
- "new godpowers features"
|
|
14
|
+
|
|
15
|
+
sequences:
|
|
16
|
+
default:
|
|
17
|
+
description: "Refresh agent context after repo, docs, or workflow changes"
|
|
18
|
+
steps:
|
|
19
|
+
- command: "/god-context"
|
|
20
|
+
why: "Refresh portable agent context files"
|
|
21
|
+
- command: "/god-sync"
|
|
22
|
+
why: "Apply feature-awareness and Pillars sync checks"
|
|
23
|
+
- command: "/god-status"
|
|
24
|
+
why: "Confirm proactive checks are fresh"
|
|
25
|
+
|
|
26
|
+
default-sequence: default
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
apiVersion: godpowers/v1
|
|
2
|
+
kind: Recipe
|
|
3
|
+
metadata:
|
|
4
|
+
name: release-maintenance
|
|
5
|
+
category: maintaining
|
|
6
|
+
description: "Release closeout, package, docs, and published-surface maintenance"
|
|
7
|
+
|
|
8
|
+
triggers:
|
|
9
|
+
intent-keywords:
|
|
10
|
+
- "create release"
|
|
11
|
+
- "publish npm"
|
|
12
|
+
- "update readme badge"
|
|
13
|
+
- "release notes"
|
|
14
|
+
- "package release"
|
|
15
|
+
|
|
16
|
+
sequences:
|
|
17
|
+
default:
|
|
18
|
+
description: "Release closeout, package, docs, and published-surface maintenance"
|
|
19
|
+
steps:
|
|
20
|
+
- command: "/god-sync"
|
|
21
|
+
why: "Refresh project artifacts and repo surface checks before release work"
|
|
22
|
+
- command: "/god-docs"
|
|
23
|
+
why: "Verify README, release notes, badges, and public docs against code"
|
|
24
|
+
- command: "/god-version"
|
|
25
|
+
why: "Confirm installed runtime and package version visibility"
|
|
26
|
+
|
|
27
|
+
default-sequence: default
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
apiVersion: godpowers/v1
|
|
2
|
+
kind: Recipe
|
|
3
|
+
metadata:
|
|
4
|
+
name: story-work
|
|
5
|
+
category: feature-addition
|
|
6
|
+
description: "Create, build, verify, and close a scoped story"
|
|
7
|
+
|
|
8
|
+
triggers:
|
|
9
|
+
intent-keywords:
|
|
10
|
+
- "create story"
|
|
11
|
+
- "build story"
|
|
12
|
+
- "implement story"
|
|
13
|
+
- "verify story"
|
|
14
|
+
- "close story"
|
|
15
|
+
|
|
16
|
+
sequences:
|
|
17
|
+
default:
|
|
18
|
+
description: "Create, build, verify, and close a scoped story"
|
|
19
|
+
steps:
|
|
20
|
+
- command: "/god-story"
|
|
21
|
+
why: "Create or select a runtime-testable story"
|
|
22
|
+
- command: "/god-story-build"
|
|
23
|
+
why: "Plan and implement the selected story with reviewers"
|
|
24
|
+
- command: "/god-story-verify"
|
|
25
|
+
why: "Runtime-test the story acceptance criteria"
|
|
26
|
+
- command: "/god-story-close"
|
|
27
|
+
why: "Close the story only after verification passes"
|
|
28
|
+
|
|
29
|
+
default-sequence: default
|
package/skills/god-doctor.md
CHANGED
|
@@ -131,7 +131,8 @@ security prose needs judgment.
|
|
|
131
131
|
For initialized projects, `/god-doctor` calls `lib/repo-surface-sync.detect`
|
|
132
132
|
as a read-only diagnostic. It reports structural drift across command routing,
|
|
133
133
|
package payload rules, agent spawn targets, workflow metadata, recipe command
|
|
134
|
-
routes, extension packs,
|
|
134
|
+
routes, extension packs, route quality, recipe coverage, release surfaces, and
|
|
135
|
+
release policy checks.
|
|
135
136
|
|
|
136
137
|
`/god-doctor --fix` may call
|
|
137
138
|
`lib/repo-surface-sync.run(projectRoot, { fixRouting: true })` to create
|
|
@@ -149,6 +150,12 @@ Built-in, no spawned agent. Reads:
|
|
|
149
150
|
- `lib/repo-doc-sync.detect(projectRoot)` for repo documentation freshness
|
|
150
151
|
- `lib/repo-surface-sync.detect(projectRoot)` for structural repo surface
|
|
151
152
|
freshness
|
|
153
|
+
- `lib/route-quality-sync.detect(projectRoot)` through repo surface sync for
|
|
154
|
+
atomic spawn and contextual route exit freshness
|
|
155
|
+
- `lib/recipe-coverage-sync.detect(projectRoot)` through repo surface sync for
|
|
156
|
+
high-frequency intent recipe coverage freshness
|
|
157
|
+
- `lib/release-surface-sync.detect(projectRoot)` through repo surface sync for
|
|
158
|
+
release-facing surface freshness
|
|
152
159
|
- `bin/install.js` VERSION constant
|
|
153
160
|
|
|
154
161
|
## Exit codes
|
package/skills/god-sync.md
CHANGED
|
@@ -41,9 +41,10 @@ User runs `/god-sync` after manual changes. Useful for:
|
|
|
41
41
|
Narrative drift should recommend or spawn `god-docs-writer`.
|
|
42
42
|
5. Call `lib/repo-surface-sync.run(projectRoot)` so command routing, package
|
|
43
43
|
payload, agent handoffs, workflow metadata, recipe routes, extension packs,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
`god-coordinator
|
|
44
|
+
route quality, recipe coverage, release surfaces, and release policy are
|
|
45
|
+
checked before sync closes. Structural drift should recommend scoped agents
|
|
46
|
+
such as `god-auditor`, `god-roadmap-reconciler`, `god-coordinator`, or
|
|
47
|
+
`god-docs-writer`.
|
|
47
48
|
6. If repo documentation changed durable project truth, plan or apply Pillars
|
|
48
49
|
updates through `lib/pillars.planArtifactSync` or
|
|
49
50
|
`lib/pillars.applyArtifactSync` under the active Pillars policy.
|
|
@@ -63,7 +64,7 @@ Auto-invoked:
|
|
|
63
64
|
Trigger: <manual /god-sync, recipe closeout, /god-mode final sync, or other source>
|
|
64
65
|
Agent: god-updater
|
|
65
66
|
Local syncs:
|
|
66
|
-
- pending: feature-awareness, reverse-sync, source-sync, repo-doc-sync, repo-surface-sync, pillars-sync, checkpoint-sync, context-refresh
|
|
67
|
+
- pending: feature-awareness, reverse-sync, source-sync, repo-doc-sync, repo-surface-sync, route-quality-sync, recipe-coverage-sync, release-surface-sync, pillars-sync, checkpoint-sync, context-refresh
|
|
67
68
|
Artifacts: pending
|
|
68
69
|
Log: .godpowers/SYNC-LOG.md
|
|
69
70
|
```
|
|
@@ -92,6 +93,9 @@ Sync status:
|
|
|
92
93
|
+ source-sync: <written GSD/BMAD/Superpowers companion files, no-op, or skipped>
|
|
93
94
|
+ repo-doc-sync: <refreshed README badges/counts, recommended god-docs-writer, or no-op>
|
|
94
95
|
+ repo-surface-sync: <checked routes/package/agents/workflows/extensions, recommended scoped agents, or no-op>
|
|
96
|
+
+ route-quality-sync: <checked atomic spawns and contextual exits, no-op, or recommended god-auditor>
|
|
97
|
+
+ recipe-coverage-sync: <checked high-frequency intent recipes, no-op, or recommended god-roadmap-reconciler>
|
|
98
|
+
+ release-surface-sync: <checked badges/changelog/release/package guards, no-op, or recommended god-docs-writer>
|
|
95
99
|
+ pillars-sync: <updated N pillar files, no-op, or proposed>
|
|
96
100
|
+ checkpoint-sync: <CHECKPOINT.md updated or skipped>
|
|
97
101
|
+ context-refresh: <updated AGENTS.md/tool pointers, no-op, or skipped by setting>
|
package/skills/god-version.md
CHANGED
|
@@ -16,7 +16,7 @@ Print version and a short capability summary.
|
|
|
16
16
|
```
|
|
17
17
|
Godpowers v1.6.19
|
|
18
18
|
Install: /Users/.../.claude/ (matches package.json)
|
|
19
|
-
Surface: 109 skills, 40 agents, 13 workflows,
|
|
19
|
+
Surface: 109 skills, 40 agents, 13 workflows, 40 recipes
|
|
20
20
|
Schema: intent.v1, state.v1, events.v1, workflow.v1, routing.v1, recipe.v1
|
|
21
21
|
External integrations available: impeccable, agent-browser (others lazy)
|
|
22
22
|
Feature awareness: planning-system migration, source-system sync-back, context refresh, dashboard status labels, repo documentation sync, repo surface sync
|