peaks-loop 4.0.38 → 4.0.39
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/CHANGELOG.md +19 -0
- package/README-en.md +1 -1
- package/README.md +1 -1
- package/dist/cli/commands/code-review-commands.js +43 -1
- package/dist/cli/commands/code-runtime-commands.js +16 -4
- package/dist/cli/commands/core/skill-command.d.ts +44 -0
- package/dist/cli/commands/core/skill-command.js +67 -3
- package/dist/cli/commands/dispatch-commands.js +42 -12
- package/dist/services/code/auto-compact-orchestrator.js +2 -2
- package/dist/services/context/auto-compact-dispatcher.js +3 -1
- package/dist/services/hooks/auto-compact-hook-install.d.ts +14 -1
- package/dist/services/hooks/auto-compact-hook-install.js +39 -15
- package/dist/services/lint/detect-ocr-18.d.ts +7 -1
- package/dist/services/lint/detect-ocr-18.js +81 -8
- package/dist/services/lint/ocr-18-acquire.d.ts +113 -0
- package/dist/services/lint/ocr-18-acquire.js +350 -0
- package/dist/services/lint/ocr-multilang-adapter.js +3 -0
- package/dist/services/web/playwright-loader.js +5 -24
- package/dist/services/workflow/provision-dispatch-node.d.ts +42 -0
- package/dist/services/workflow/provision-dispatch-node.js +66 -0
- package/dist/services/workspace/workspace-claude-settings-materializer.js +65 -6
- package/dist/shared/npm-cache.d.ts +2 -0
- package/dist/shared/npm-cache.js +31 -0
- package/package.json +5 -5
- package/skills/bee/peaks-perf-audit/SKILL.md +24 -0
- package/skills/bee/peaks-prd/SKILL.md +24 -0
- package/skills/bee/peaks-qa/SKILL.md +24 -0
- package/skills/bee/peaks-rd/SKILL.md +24 -0
- package/skills/bee/peaks-reviewer/SKILL.md +24 -0
- package/skills/bee/peaks-sc/SKILL.md +24 -0
- package/skills/bee/peaks-security-audit/SKILL.md +24 -0
- package/skills/bee/peaks-txt/SKILL.md +24 -0
- package/skills/bee/peaks-ui/SKILL.md +24 -0
- package/skills/peaks-audit/SKILL.md +24 -0
- package/skills/peaks-code/SKILL.md +24 -0
- package/skills/peaks-content/SKILL.md +24 -0
- package/skills/peaks-doctor/SKILL.md +24 -0
- package/skills/peaks-final-review/SKILL.md +24 -0
- package/skills/peaks-ide/SKILL.md +24 -0
- package/skills/peaks-issue-fix-orchestrator/SKILL.md +24 -0
- package/skills/peaks-resume/SKILL.md +24 -0
- package/skills/peaks-slice-decompose/SKILL.md +24 -0
- package/skills/peaks-solo/SKILL.md +24 -0
- package/skills/peaks-sop/SKILL.md +24 -0
- package/skills/peaks-status/SKILL.md +24 -0
- package/skills/peaks-test/SKILL.md +24 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ProvisionedDispatchNode {
|
|
2
|
+
readonly nodeId: string;
|
|
3
|
+
readonly workflowId: string;
|
|
4
|
+
readonly graphRef: string;
|
|
5
|
+
/** True when this call created the graph; false when it appended to one. */
|
|
6
|
+
readonly graphCreated: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Bind a dispatch to a graph node, creating the graph and the node when
|
|
10
|
+
* they do not exist yet.
|
|
11
|
+
*
|
|
12
|
+
* Why this exists. `--graph-node` was a `.requiredOption`, and the failure
|
|
13
|
+
* message told the caller to "Prepare a graph node via
|
|
14
|
+
* `peaks workflow node prepare` and re-run dispatch". That instruction was
|
|
15
|
+
* unwalkable:
|
|
16
|
+
*
|
|
17
|
+
* - `workflow node prepare` never calls `writeGraph`, so the node it
|
|
18
|
+
* reports is never persisted — it is printed into the envelope's
|
|
19
|
+
* `graph` field (which is a single NODE, not a graph) and dropped;
|
|
20
|
+
* - the graph that command reads must already exist, and no CLI verb
|
|
21
|
+
* creates one.
|
|
22
|
+
*
|
|
23
|
+
* So the documented three-step ritual had no viable first step anywhere
|
|
24
|
+
* outside peaks-loop's own tree, while the flag itself guaranteed nothing:
|
|
25
|
+
* `dispatch-record-writer` treats the graph transition as best-effort and
|
|
26
|
+
* silently returns when the node is absent, and `PEAKS_GRAPH_NODE_NOT_PREPARED`
|
|
27
|
+
* is imported but never thrown on this path. A required parameter that is
|
|
28
|
+
* never validated, blocking every consumer project, is pure friction.
|
|
29
|
+
*
|
|
30
|
+
* Provisioning makes the binding cheap and real instead: the node exists
|
|
31
|
+
* from the first dispatch, so the transition in the record writer has
|
|
32
|
+
* something to find.
|
|
33
|
+
*/
|
|
34
|
+
export declare function provisionDispatchNode(input: {
|
|
35
|
+
readonly projectRoot: string;
|
|
36
|
+
readonly sessionId: string;
|
|
37
|
+
readonly role: string;
|
|
38
|
+
readonly workflowId?: string | undefined;
|
|
39
|
+
readonly graphRef?: string | undefined;
|
|
40
|
+
/** Injectable for tests; defaults to `Date.now()`. */
|
|
41
|
+
readonly now?: (() => number) | undefined;
|
|
42
|
+
}): ProvisionedDispatchNode;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { emptyGraph, readGraph, writeGraph, PEAKS_GRAPH_NOT_FOUND } from './workflow-graph-store.js';
|
|
2
|
+
import { WORKFLOW_ID_REGEX } from './workflow-graph-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Bind a dispatch to a graph node, creating the graph and the node when
|
|
5
|
+
* they do not exist yet.
|
|
6
|
+
*
|
|
7
|
+
* Why this exists. `--graph-node` was a `.requiredOption`, and the failure
|
|
8
|
+
* message told the caller to "Prepare a graph node via
|
|
9
|
+
* `peaks workflow node prepare` and re-run dispatch". That instruction was
|
|
10
|
+
* unwalkable:
|
|
11
|
+
*
|
|
12
|
+
* - `workflow node prepare` never calls `writeGraph`, so the node it
|
|
13
|
+
* reports is never persisted — it is printed into the envelope's
|
|
14
|
+
* `graph` field (which is a single NODE, not a graph) and dropped;
|
|
15
|
+
* - the graph that command reads must already exist, and no CLI verb
|
|
16
|
+
* creates one.
|
|
17
|
+
*
|
|
18
|
+
* So the documented three-step ritual had no viable first step anywhere
|
|
19
|
+
* outside peaks-loop's own tree, while the flag itself guaranteed nothing:
|
|
20
|
+
* `dispatch-record-writer` treats the graph transition as best-effort and
|
|
21
|
+
* silently returns when the node is absent, and `PEAKS_GRAPH_NODE_NOT_PREPARED`
|
|
22
|
+
* is imported but never thrown on this path. A required parameter that is
|
|
23
|
+
* never validated, blocking every consumer project, is pure friction.
|
|
24
|
+
*
|
|
25
|
+
* Provisioning makes the binding cheap and real instead: the node exists
|
|
26
|
+
* from the first dispatch, so the transition in the record writer has
|
|
27
|
+
* something to find.
|
|
28
|
+
*/
|
|
29
|
+
export function provisionDispatchNode(input) {
|
|
30
|
+
// A caller-supplied workflowId is honoured only when it is well-formed;
|
|
31
|
+
// the option was previously ignored outright, so falling back is strictly
|
|
32
|
+
// additive, and the effective id is returned so the choice is visible.
|
|
33
|
+
const workflowId = typeof input.workflowId === 'string' && WORKFLOW_ID_REGEX.test(input.workflowId)
|
|
34
|
+
? input.workflowId
|
|
35
|
+
: `dispatch-${input.sessionId}`;
|
|
36
|
+
const graphRef = input.graphRef ?? `graphs/${workflowId}.json`;
|
|
37
|
+
let graph;
|
|
38
|
+
let graphCreated = false;
|
|
39
|
+
try {
|
|
40
|
+
graph = readGraph({ projectRoot: input.projectRoot, sessionId: input.sessionId, graphRef, workflowId });
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err.code !== PEAKS_GRAPH_NOT_FOUND)
|
|
44
|
+
throw err;
|
|
45
|
+
// `emptyGraph` supplies the one terminal node `validateGraph` requires.
|
|
46
|
+
graph = emptyGraph({ workflowId, rootSkill: 'peaks-code' });
|
|
47
|
+
graphCreated = true;
|
|
48
|
+
}
|
|
49
|
+
const stamp = (input.now ?? Date.now)().toString(36);
|
|
50
|
+
const nodeId = `dispatch-${input.role}-${stamp}`;
|
|
51
|
+
const node = {
|
|
52
|
+
id: nodeId,
|
|
53
|
+
kind: 'dispatch',
|
|
54
|
+
label: `${input.role} dispatch`,
|
|
55
|
+
status: 'prepared',
|
|
56
|
+
dependsOn: [],
|
|
57
|
+
};
|
|
58
|
+
writeGraph({
|
|
59
|
+
projectRoot: input.projectRoot,
|
|
60
|
+
sessionId: input.sessionId,
|
|
61
|
+
graphRef,
|
|
62
|
+
workflowId,
|
|
63
|
+
graph: { ...graph, nodes: [...graph.nodes, node] },
|
|
64
|
+
});
|
|
65
|
+
return { nodeId, workflowId, graphRef, graphCreated };
|
|
66
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* and behaviour are unchanged (verbatim move).
|
|
11
11
|
*/
|
|
12
12
|
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
13
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
14
14
|
import { join } from 'node:path';
|
|
15
15
|
import { withExternalGateExemptions } from '../skills/hooks-codegate-superpowers.js';
|
|
16
16
|
import { buildClaudeSettingsLocalJson, CLAUDE_SETTINGS_LOCAL_FILENAME, templateContentMatches } from './claude-settings-template.js';
|
|
@@ -59,6 +59,8 @@ const PEAKS_GITIGNORE_SNIPPET = [
|
|
|
59
59
|
'# Gitignored so the init flow\'s drift-driven refresh does not show up as',
|
|
60
60
|
'# "modified" in `git status` on every release bump. Recovery path: re-run',
|
|
61
61
|
'# `peaks workspace init` to regenerate; or copy from peaks-loop source.',
|
|
62
|
+
'# Both patterns below are PROJECT-ROOT-relative, so this snippet must land',
|
|
63
|
+
'# in the root .gitignore — see `upsertPeaksGitignoreSnippet`.',
|
|
62
64
|
'.peaks/.claude-settings-template.json',
|
|
63
65
|
PEAKS_GITIGNORE_FOOTER,
|
|
64
66
|
''
|
|
@@ -194,13 +196,70 @@ async function writeOfflineTemplateCopy(projectRoot, serialized) {
|
|
|
194
196
|
return action;
|
|
195
197
|
}
|
|
196
198
|
/**
|
|
197
|
-
* Append the peaks-managed
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
199
|
+
* Append the peaks-managed snippet to the consumer project's ROOT
|
|
200
|
+
* `.gitignore`. Preserves any user-managed entries above the snippet.
|
|
201
|
+
* Idempotent: re-running on a project that already has the snippet is a
|
|
202
|
+
* no-op.
|
|
203
|
+
*
|
|
204
|
+
* Root, not `.peaks/.gitignore`. A gitignore pattern containing a slash is
|
|
205
|
+
* anchored to the directory of the .gitignore that holds it, and both
|
|
206
|
+
* patterns here are project-root-relative. Written into `.peaks/.gitignore`
|
|
207
|
+
* they resolved to `.peaks/.claude/settings.local.json` and
|
|
208
|
+
* `.peaks/.peaks/.claude-settings-template.json` — matching nothing, in
|
|
209
|
+
* every project. The root-level `settings.local.json` entry could not be
|
|
210
|
+
* expressed from inside `.peaks/` at all, since gitignore has no `..`.
|
|
211
|
+
*/
|
|
212
|
+
/**
|
|
213
|
+
* The snippet's former home. Projects initialized before the move carry a
|
|
214
|
+
* managed block there that now matches nothing and is maintained by nobody —
|
|
215
|
+
* yet still announces itself as "do not edit by hand", which is worse than
|
|
216
|
+
* absent: a reader takes it for live configuration.
|
|
201
217
|
*/
|
|
218
|
+
const LEGACY_PEAKS_GITIGNORE_PATH = ['.peaks', '.gitignore'];
|
|
219
|
+
/**
|
|
220
|
+
* Strip the managed block from its legacy home, preserving every line the
|
|
221
|
+
* user wrote. Idempotent; a no-op on projects that never had one.
|
|
222
|
+
*
|
|
223
|
+
* The file is deleted only when nothing remains. An empty `.peaks/.gitignore`
|
|
224
|
+
* left behind reads as "peaks put something here and stopped", which invites
|
|
225
|
+
* the next reader to guess.
|
|
226
|
+
*
|
|
227
|
+
* A malformed block (header without footer) is left untouched rather than
|
|
228
|
+
* guessed at — deleting a user's file to tidy our own mess is not a trade
|
|
229
|
+
* worth making.
|
|
230
|
+
*/
|
|
231
|
+
async function stripLegacyPeaksGitignoreSnippet(projectRoot) {
|
|
232
|
+
const legacyPath = join(projectRoot, ...LEGACY_PEAKS_GITIGNORE_PATH);
|
|
233
|
+
if (!existsSync(legacyPath))
|
|
234
|
+
return;
|
|
235
|
+
let existing;
|
|
236
|
+
try {
|
|
237
|
+
existing = await readFile(legacyPath, 'utf8');
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const start = existing.indexOf(PEAKS_GITIGNORE_HEADER);
|
|
243
|
+
if (start === -1)
|
|
244
|
+
return;
|
|
245
|
+
const footerAt = existing.indexOf(PEAKS_GITIGNORE_FOOTER, start);
|
|
246
|
+
if (footerAt === -1)
|
|
247
|
+
return;
|
|
248
|
+
const remainder = (existing.slice(0, start) + existing.slice(footerAt + PEAKS_GITIGNORE_FOOTER.length))
|
|
249
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
250
|
+
.trim();
|
|
251
|
+
if (remainder.length === 0) {
|
|
252
|
+
await rm(legacyPath, { force: true });
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
await writeFile(legacyPath, `${remainder}\n`, 'utf8');
|
|
256
|
+
}
|
|
202
257
|
async function upsertPeaksGitignoreSnippet(projectRoot) {
|
|
203
|
-
|
|
258
|
+
// Migration first: the snippet used to live in `.peaks/.gitignore`, where
|
|
259
|
+
// its patterns silently matched nothing. Strip that copy before writing the
|
|
260
|
+
// one that works.
|
|
261
|
+
await stripLegacyPeaksGitignoreSnippet(projectRoot);
|
|
262
|
+
const gitignorePath = join(projectRoot, '.gitignore');
|
|
204
263
|
await mkdir(join(projectRoot, '.peaks'), { recursive: true });
|
|
205
264
|
let existing = '';
|
|
206
265
|
if (existsSync(gitignorePath)) {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where npm puts its per-user exec (`npx`) cache.
|
|
3
|
+
*
|
|
4
|
+
* This list lives in exactly ONE place on purpose: whoever resolves a package
|
|
5
|
+
* out of that cache (the Playwright loader `import()`s what it finds, the OCR
|
|
6
|
+
* probe reports it as installed) is answering the same question — "is this
|
|
7
|
+
* package already here?" — and a second copy of the roots is a second answer
|
|
8
|
+
* that would drift from this one.
|
|
9
|
+
*
|
|
10
|
+
* `npm_config_cache` / `NPM_CONFIG_CACHE` are deliberately NOT honoured: under
|
|
11
|
+
* `npm run`, npm exports the value a repo's own `.npmrc` chose, so trusting
|
|
12
|
+
* them lets a committed `.npmrc` select the tree that gets executed. The
|
|
13
|
+
* default roots below are where npm actually puts an `npx` cache.
|
|
14
|
+
*/
|
|
15
|
+
import { homedir } from 'node:os';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
/** `<npm cache>/_npx` candidates: the per-user defaults, and nothing else. */
|
|
18
|
+
export function npmExecCacheRoots() {
|
|
19
|
+
// Resolved per call, never at module load: callers that relocate the home
|
|
20
|
+
// (tests, and any future sandboxed run) must see the relocation.
|
|
21
|
+
const roots = [join(homedir(), '.npm', '_npx')];
|
|
22
|
+
if (process.platform === 'win32') {
|
|
23
|
+
for (const key of ['LOCALAPPDATA', 'APPDATA']) {
|
|
24
|
+
const base = process.env[key];
|
|
25
|
+
if (base !== undefined && base.length > 0) {
|
|
26
|
+
roots.push(join(base, 'npm-cache', '_npx'));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return roots;
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "peaks-loop",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.39",
|
|
4
4
|
"description": "Loop Engineering CLI — workflow primitive / loop guards / evaluators / slice orchestration",
|
|
5
5
|
"author": "SquabbyZ",
|
|
6
6
|
"keywords": [
|
|
@@ -101,10 +101,10 @@
|
|
|
101
101
|
"fzf": "^0.5.2",
|
|
102
102
|
"yaml": "^2.9.0",
|
|
103
103
|
"zod": "^4.4.3",
|
|
104
|
-
"peaks-loop-internal-runtime": "0.0.
|
|
105
|
-
"peaks-loop-shared": "0.0.
|
|
106
|
-
"peaks-loop-
|
|
107
|
-
"peaks-loop-
|
|
104
|
+
"peaks-loop-internal-runtime": "0.0.24",
|
|
105
|
+
"peaks-loop-shared-channel": "0.0.41",
|
|
106
|
+
"peaks-loop-shared": "0.0.73",
|
|
107
|
+
"peaks-loop-mut": "0.1.37"
|
|
108
108
|
},
|
|
109
109
|
"devDependencies": {
|
|
110
110
|
"@changesets/cli": "2.31.1",
|
|
@@ -12,6 +12,30 @@ metadata:
|
|
|
12
12
|
- schema: .peaks/project-scan/audit-output-schema.md
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
16
|
+
|
|
17
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
18
|
+
|
|
19
|
+
**Skill header.** While this skill is active, open every turn with
|
|
20
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
21
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
22
|
+
|
|
23
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
24
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
25
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
26
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
27
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
28
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
29
|
+
|
|
30
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
31
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
32
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
33
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
34
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
35
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
36
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
37
|
+
<!-- /peaks:loop-hygiene -->
|
|
38
|
+
|
|
15
39
|
# peaks-perf-audit
|
|
16
40
|
|
|
17
41
|
> **Independent performance audit skill** — separate from `peaks-rd`'s
|
|
@@ -7,6 +7,30 @@ description: |
|
|
|
7
7
|
acceptance criteria, product change proposals, or user-confirmable product artifacts.
|
|
8
8
|
visibility: internal
|
|
9
9
|
---
|
|
10
|
+
|
|
11
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
12
|
+
|
|
13
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
14
|
+
|
|
15
|
+
**Skill header.** While this skill is active, open every turn with
|
|
16
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
17
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
18
|
+
|
|
19
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
20
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
21
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
22
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
23
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
24
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
25
|
+
|
|
26
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
27
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
28
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
29
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
30
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
31
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
32
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
33
|
+
<!-- /peaks:loop-hygiene -->
|
|
10
34
|
---
|
|
11
35
|
|
|
12
36
|
# Peaks-Loop PRD
|
|
@@ -7,6 +7,30 @@ description: |
|
|
|
7
7
|
baseline reports, validation reports, acceptance checks, or refactor verification gates.
|
|
8
8
|
visibility: internal
|
|
9
9
|
---
|
|
10
|
+
|
|
11
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
12
|
+
|
|
13
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
14
|
+
|
|
15
|
+
**Skill header.** While this skill is active, open every turn with
|
|
16
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
17
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
18
|
+
|
|
19
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
20
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
21
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
22
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
23
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
24
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
25
|
+
|
|
26
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
27
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
28
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
29
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
30
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
31
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
32
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
33
|
+
<!-- /peaks:loop-hygiene -->
|
|
10
34
|
---
|
|
11
35
|
|
|
12
36
|
## Single-scope-axis naming convention
|
|
@@ -8,6 +8,30 @@ description: |
|
|
|
8
8
|
Always use this for Peaks-Loop refactor workflows.
|
|
9
9
|
visibility: internal
|
|
10
10
|
---
|
|
11
|
+
|
|
12
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
13
|
+
|
|
14
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
15
|
+
|
|
16
|
+
**Skill header.** While this skill is active, open every turn with
|
|
17
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
18
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
19
|
+
|
|
20
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
21
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
22
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
23
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
24
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
25
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
26
|
+
|
|
27
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
28
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
29
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
30
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
31
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
32
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
33
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
34
|
+
<!-- /peaks:loop-hygiene -->
|
|
11
35
|
---
|
|
12
36
|
|
|
13
37
|
## Single-scope-axis naming convention
|
|
@@ -4,6 +4,30 @@ visibility: internal
|
|
|
4
4
|
description: Third-party independent code-review skill for Peaks. Use as a parallel reviewer to karpathy-reviewer when a workflow needs an out-of-band (non-RD-model) review pass to mitigate single-LLM self-dogfood blind spots. Emits a schema-validated ReviewerEnvelope (no free-form LLM JSON). v2.14.0 G4.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
8
|
+
|
|
9
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
10
|
+
|
|
11
|
+
**Skill header.** While this skill is active, open every turn with
|
|
12
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
13
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
14
|
+
|
|
15
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
16
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
17
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
18
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
19
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
20
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
21
|
+
|
|
22
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
23
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
24
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
25
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
26
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
27
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
28
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
29
|
+
<!-- /peaks:loop-hygiene -->
|
|
30
|
+
|
|
7
31
|
## Single-scope-axis naming convention
|
|
8
32
|
|
|
9
33
|
> **Read once at the top of this file; the rest of the skill is written against it.**
|
|
@@ -7,6 +7,30 @@ description: |
|
|
|
7
7
|
GitHub artifact repository pointers, sync state, or rollback evidence.
|
|
8
8
|
visibility: internal
|
|
9
9
|
---
|
|
10
|
+
|
|
11
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
12
|
+
|
|
13
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
14
|
+
|
|
15
|
+
**Skill header.** While this skill is active, open every turn with
|
|
16
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
17
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
18
|
+
|
|
19
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
20
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
21
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
22
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
23
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
24
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
25
|
+
|
|
26
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
27
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
28
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
29
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
30
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
31
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
32
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
33
|
+
<!-- /peaks:loop-hygiene -->
|
|
10
34
|
---
|
|
11
35
|
|
|
12
36
|
# Peaks-Loop SC
|
|
@@ -12,6 +12,30 @@ metadata:
|
|
|
12
12
|
- schema: .peaks/project-scan/audit-output-schema.md
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
16
|
+
|
|
17
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
18
|
+
|
|
19
|
+
**Skill header.** While this skill is active, open every turn with
|
|
20
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
21
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
22
|
+
|
|
23
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
24
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
25
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
26
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
27
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
28
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
29
|
+
|
|
30
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
31
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
32
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
33
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
34
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
35
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
36
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
37
|
+
<!-- /peaks:loop-hygiene -->
|
|
38
|
+
|
|
15
39
|
# peaks-security-audit
|
|
16
40
|
|
|
17
41
|
> **Independent security audit skill** — separate from `peaks-rd`'s
|
|
@@ -7,6 +7,30 @@ description: |
|
|
|
7
7
|
assumptions, discarded options, staleness checks, lessons, or reusable project memory.
|
|
8
8
|
visibility: internal
|
|
9
9
|
---
|
|
10
|
+
|
|
11
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
12
|
+
|
|
13
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
14
|
+
|
|
15
|
+
**Skill header.** While this skill is active, open every turn with
|
|
16
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
17
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
18
|
+
|
|
19
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
20
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
21
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
22
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
23
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
24
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
25
|
+
|
|
26
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
27
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
28
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
29
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
30
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
31
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
32
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
33
|
+
<!-- /peaks:loop-hygiene -->
|
|
10
34
|
---
|
|
11
35
|
|
|
12
36
|
# Peaks-Loop TXT
|
|
@@ -7,6 +7,30 @@ description: |
|
|
|
7
7
|
frontend page behavior, high-fidelity HTML prototypes, or UI regression seeds.
|
|
8
8
|
visibility: internal
|
|
9
9
|
---
|
|
10
|
+
|
|
11
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
12
|
+
|
|
13
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
14
|
+
|
|
15
|
+
**Skill header.** While this skill is active, open every turn with
|
|
16
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
17
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
18
|
+
|
|
19
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
20
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
21
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
22
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
23
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
24
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
25
|
+
|
|
26
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
27
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
28
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
29
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
30
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
31
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
32
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
33
|
+
<!-- /peaks:loop-hygiene -->
|
|
10
34
|
---
|
|
11
35
|
|
|
12
36
|
# Peaks-Loop UI
|
|
@@ -3,6 +3,30 @@ name: peaks-audit
|
|
|
3
3
|
description: Gate autonomous LLM work on a 6-dimension audit + user-accepted goal. Use IMMEDIATELY after a need is expressed, BEFORE any PRD/RD/QA work starts.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
7
|
+
|
|
8
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
9
|
+
|
|
10
|
+
**Skill header.** While this skill is active, open every turn with
|
|
11
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
12
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
13
|
+
|
|
14
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
15
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
16
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
17
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
18
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
19
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
20
|
+
|
|
21
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
22
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
23
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
24
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
25
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
26
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
27
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
28
|
+
<!-- /peaks:loop-hygiene -->
|
|
29
|
+
|
|
6
30
|
## Single-scope-axis naming convention
|
|
7
31
|
|
|
8
32
|
> **Read once at the top of this file; the rest of the skill is written against it.**
|
|
@@ -3,6 +3,30 @@ name: peaks-code
|
|
|
3
3
|
description: Code-domain loop engineering orchestrator for the Peaks-Loop skill family. Use when the user asks Peaks-Loop to handle a code-repo workflow end-to-end (端到端/全流程/需求开发), especially from a product document (PRD/飞书文档/Feishu doc) through implementation and validation. Coordinates peaks-prd, peaks-rd, peaks-qa, peaks-ui, peaks-sc, and peaks-txt while preserving user confirmation gates. Triggers on `/peaks-code`, "peaks code", "全流程开发", "端到端迭代". General primitives (peaks-resume / peaks-status / peaks-test) are sibling skills, not children.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
7
|
+
|
|
8
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
9
|
+
|
|
10
|
+
**Skill header.** While this skill is active, open every turn with
|
|
11
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
12
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
13
|
+
|
|
14
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
15
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
16
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
17
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
18
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
19
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
20
|
+
|
|
21
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
22
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
23
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
24
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
25
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
26
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
27
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
28
|
+
<!-- /peaks:loop-hygiene -->
|
|
29
|
+
|
|
6
30
|
> **Detached sub-agent mode (Phase A, slice 2026-08-10).** When the orchestrator requires true parallelism with isolated context windows and survives orchestrator session exit, dispatch sub-agents with `--mode detached --vendor <claude|codex|copilot>`. The CLI spawns a real OS process via `ProcessSupervisor` (Windows `DETACHED_PROCESS` + `CREATE_NEW_PROCESS_GROUP`, POSIX `setsid` + `nohup`); the child vendor LLM receives a 5–8KB minimum prompt slice (no orchestrator session history) and self-compacts at 0.85 / 0.95 against the vendor window via the `<peaks-auto-compact>` marker (G8 — unlimited spend authorized). Orchestrator MUST emit one line of prose before every detached dispatch: `⏳ Spawning detached sub-agent via <vendor>: rid=<rid> (ETA ~60s)`. Status is read from `.peaks/_runtime/<sid>/detached/<rid>/status.json`; `LifecycleOwner` enforces 100% cleanup of `pid` / `log.txt` / `status.json` / `owner-session` on every exit path. `--no-throttle --max-concurrent <N>` bypasses `ResourceBudgetGuard` (user accepts risk; default max=8). See `references/sub-agent-dispatch.md` §"Detached Mode" for the full contract. Default mode remains `in-process` for backward compat (existing 106+ dispatch tests untouched).
|
|
7
31
|
---
|
|
8
32
|
|
|
@@ -3,6 +3,30 @@ name: peaks-content
|
|
|
3
3
|
description: Non-code orchestrator for content workflows (draft / edit / publish / archive). Use when a user wants to drive an end-to-end content-production loop (blog post, newsletter, marketing copy, social thread, doc page) where the LLM must coordinate draft / edit / tone / publish / archive stages with explicit gates between them, and where the user only wants to speak natural language and pick options. NOT for free-form chatting; NOT for code review. Reuses the peaks-loop Loop Engineering primitives (Loop Engineering Asset, Bee Asset, Workflow Trace, Evolution Evaluation) but does NOT import peaks-code internals. Triggers on `/peaks-content`, "peaks content", "content workflow", "publish this to <channel>", "edit the draft", "archive the previous version".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<!-- peaks:loop-hygiene — generated block; keep byte-identical in every SKILL.md -->
|
|
7
|
+
|
|
8
|
+
## Loop hygiene (every turn — MANDATORY)
|
|
9
|
+
|
|
10
|
+
**Skill header.** While this skill is active, open every turn with
|
|
11
|
+
`Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`.
|
|
12
|
+
Every turn, not only the first — it is how the user knows which skill is driving.
|
|
13
|
+
|
|
14
|
+
**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
|
|
15
|
+
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
|
|
16
|
+
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
|
|
17
|
+
ratio in one line if it helps, but never hand them the compaction step: asking the user to
|
|
18
|
+
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
|
|
19
|
+
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.
|
|
20
|
+
|
|
21
|
+
**Read before you edit.** Read a file BEFORE your first `Edit` / `Write` / `MultiEdit` on
|
|
22
|
+
it — for every path outside `.peaks/**` (source, tests, docs, config); `.peaks/**` writes
|
|
23
|
+
are exempt. Skipping that read trips a `PreToolUse` gate (ECC's "Fact-Forcing Gate"),
|
|
24
|
+
which denies the edit. **A denial is not a failure and the tool is not broken — your edit
|
|
25
|
+
was not applied.** Read the file, state the facts the gate asks for (importers, affected
|
|
26
|
+
API, data schemas if any, the user's verbatim instruction), then retry the same operation.
|
|
27
|
+
Do not switch tools, do not give up, do not retry blindly.
|
|
28
|
+
<!-- /peaks:loop-hygiene -->
|
|
29
|
+
|
|
6
30
|
# peaks-content
|
|
7
31
|
|
|
8
32
|
`peaks-content` is the **content-domain** orchestrator for peaks-loop. It drives an end-to-end content-production loop — draft, edit, publish, archive — through LLM-mediated sub-agents (the "bees") so a non-technical user can produce a polished, channel-ready piece of writing by speaking natural language and picking from multi-choice options. The user never types a CLI verb; the user never hand-authors markdown or JSON; the LLM runs every structured operation on the user's behalf.
|