@jamie-tam/forge 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -59
- package/agents/dreamer.md +10 -7
- package/agents/gotcha-hunter.md +1 -1
- package/agents/prototype-codifier.md +2 -2
- package/commands/{forge.md → discover.md} +13 -9
- package/commands/dream.md +71 -0
- package/commands/feature.md +57 -10
- package/commands/{evolve.md → forge-evolve.md} +3 -3
- package/commands/greenfield.md +5 -5
- package/commands/note.md +64 -0
- package/commands/{task-force.md → parallel.md} +15 -15
- package/commands/resume.md +2 -2
- package/commands/setup.md +18 -17
- package/commands/status.md +2 -2
- package/commands/wrap.md +130 -0
- package/dist/__tests__/hooks.test.js +334 -0
- package/dist/__tests__/init.test.js +110 -0
- package/dist/__tests__/work-manifest.test.js +48 -14
- package/dist/cli.js +0 -0
- package/dist/hooks.js +88 -6
- package/dist/init.js +39 -1
- package/dist/uninstall.js +11 -5
- package/dist/work-manifest.js +63 -24
- package/hooks/config/gate-requirements.json +1 -1
- package/hooks/hooks.json +14 -1
- package/hooks/scripts/gate-enforcer.sh +51 -6
- package/hooks/scripts/pre-compact.sh +120 -55
- package/hooks/scripts/session-start.sh +43 -4
- package/hooks/scripts/telemetry.sh +32 -2
- package/hooks/templates/CLAUDE.md.template +6 -3
- package/package.json +1 -1
- package/references/common/phases.md +8 -6
- package/references/common/skill-authoring.md +1 -1
- package/rules/common/forge-system.md +64 -6
- package/rules/common/quality-gates.md +2 -0
- package/skills/build-prototype/SKILL.md +4 -4
- package/skills/build-tdd/SKILL.md +14 -0
- package/skills/concept-slides/SKILL.md +11 -11
- package/skills/deliver-deploy/SKILL.md +10 -1
- package/skills/harden/SKILL.md +22 -8
- package/skills/iterate-prototype/SKILL.md +22 -0
- package/skills/quality-test-execution/SKILL.md +26 -1
- package/skills/quality-test-plan/SKILL.md +21 -1
- package/skills/support-debug/SKILL.md +1 -1
- package/skills/support-dream/SKILL.md +8 -7
- package/skills/support-gotcha/SKILL.md +3 -3
- package/skills/{support-task-force → support-parallel}/SKILL.md +22 -22
- package/skills/{support-task-force → support-parallel}/references/dispatch-pattern.md +10 -10
- package/skills/{support-task-force → support-parallel}/references/synthesis-template.md +10 -10
- package/skills/support-skill-validator/SKILL.md +5 -5
- package/skills/support-skill-validator/references/validation-checks.md +1 -1
- package/skills/support-system-guide/SKILL.md +4 -3
- package/skills/support-wiki-lint/scripts/lint.mjs +52 -0
- package/templates/README.md +1 -1
- package/templates/aiwiki/CLAUDE.md.template +48 -22
- package/templates/aiwiki/schemas/session.md +134 -49
- package/templates/manifests/bugfix.yaml +1 -1
- package/templates/manifests/feature.yaml +1 -1
- package/templates/manifests/greenfield.yaml +1 -1
- package/templates/manifests/hotfix.yaml +1 -1
- package/templates/manifests/refactor.yaml +1 -1
- package/templates/manifests/v5/SCHEMA.md +14 -17
- package/templates/manifests/v5/feature.yaml +1 -1
- package/templates/manifests/v6/SCHEMA.md +14 -10
- package/commands/abort.md +0 -25
- package/dist/__tests__/active-manifest.test.js +0 -272
- package/dist/__tests__/gate-check.test.js +0 -384
- package/dist/active-manifest.js +0 -229
- package/dist/gate-check.js +0 -326
|
@@ -63,6 +63,31 @@ Now that the test plan is parsed and files are verified, run the Codex consent f
|
|
|
63
63
|
- **Takeover:** Dispatch Codex with the test plan to execute tests and produce the results report. Claude reviews test quality and coverage.
|
|
64
64
|
- **Verify** or **Skip / Codex unavailable:** Proceed with the steps below. The Codex Verify note in Step 9 will dispatch Codex to review test quality (Verify only).
|
|
65
65
|
|
|
66
|
+
### Step 1.6: Oracle Coverage Check
|
|
67
|
+
|
|
68
|
+
Before any test runs, verify that every oracle in `aiwiki/oracles/` for this work item is mapped to a test in the plan. Oracles are the Phase 5 (harden) contract — production code must reproduce the prototype's verified behavior. This is the load-bearing closure of the mock-pass / real-break wiring gap; running tests without checking oracle coverage re-creates the gap.
|
|
69
|
+
|
|
70
|
+
1. Enumerate `aiwiki/oracles/*.md`. Filter to oracles whose `prototype_path` is within this work item's scope (typically `pocs/{name}-prototype/`).
|
|
71
|
+
2. For each in-scope oracle, find the matching test ID(s) in the test plan's "Map Oracles to Tests" table (produced by `quality-test-plan` Step 2.3).
|
|
72
|
+
3. **If any in-scope oracle is unmapped, halt:**
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
ORACLE COVERAGE FAILURE:
|
|
76
|
+
Unmapped oracle: aiwiki/oracles/auth-login-success.md
|
|
77
|
+
Type: interaction
|
|
78
|
+
prototype_path: pocs/myapp-prototype/src/auth/Login.tsx
|
|
79
|
+
No test in test-plan.md cites this oracle.
|
|
80
|
+
|
|
81
|
+
Cannot execute the test plan. Mock-heavy tests pass while real integration
|
|
82
|
+
breaks (the wiring gap) — the chain closes only when every oracle has a
|
|
83
|
+
test. Resolve by:
|
|
84
|
+
(a) Returning to quality-test-plan and adding a test that satisfies the
|
|
85
|
+
oracle, OR
|
|
86
|
+
(b) Re-running harden if the oracle is stale or out of scope.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
4. **Skip condition:** If no oracles exist for this work item (the test plan recorded "No oracles in scope" in Step 2.3, or `aiwiki/oracles/` is empty for the scope), record "No oracles in scope" in the results and proceed. The check is non-blocking when oracle capture wasn't part of the lifecycle.
|
|
90
|
+
|
|
66
91
|
### Step 2: External Service Availability Check
|
|
67
92
|
|
|
68
93
|
Before executing any tests, determine which external services are available for real testing.
|
|
@@ -393,7 +418,7 @@ Do not execute only unit tests and declare success. All test types from the plan
|
|
|
393
418
|
|
|
394
419
|
| Field | Value |
|
|
395
420
|
|---|---|
|
|
396
|
-
| **Requires** | Test plan (`.forge/work/{type}/{name}/test-plan.md`) + implementation code (from `build-tdd`) + architecture artifacts (`.forge/work/{type}/{name}/architecture/api-contract.md` for external service verification) |
|
|
421
|
+
| **Requires** | Test plan (`.forge/work/{type}/{name}/test-plan.md`) + implementation code (from `build-tdd`) + architecture artifacts (`.forge/work/{type}/{name}/architecture/api-contract.md` for external service verification) + oracle pages (`aiwiki/oracles/*.md` from harden Step 2.5) when codify ran |
|
|
397
422
|
| **Produces** | `.forge/work/{type}/{name}/test-results.md` |
|
|
398
423
|
| **Feeds into** | `deliver-deploy` (via quality gate -- zero failures required) |
|
|
399
424
|
| **Updates manifest** | `artifacts.test-results: test-results.md`, `phases.quality.test-execution: { status: complete, gate-passed: true }` |
|
|
@@ -96,6 +96,26 @@ Create a traceability matrix:
|
|
|
96
96
|
|
|
97
97
|
**Rule:** Every acceptance criterion MUST have at least one test. If a criterion has no test, the plan is incomplete.
|
|
98
98
|
|
|
99
|
+
### Step 2.3: Map Oracles to Tests
|
|
100
|
+
|
|
101
|
+
If `aiwiki/oracles/` contains oracle pages for slices in this work item, every in-scope oracle MUST appear in the traceability matrix with at least one mapped test. Oracles are the prototype-derived behavioral contract from Phase 5 (harden); production code is not "tested" if oracles are unverified. This is the load-bearing closure of the mock-pass / real-break wiring gap (Flux/REACH dogfood signal).
|
|
102
|
+
|
|
103
|
+
For each `aiwiki/oracles/{slug}.md` whose `prototype_path` is within this work item's scope (typically `pocs/{name}-prototype/`):
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
| Oracle | Type | Setup → Trigger → Assertions cite | Mapped tests |
|
|
107
|
+
|---|---|---|---|
|
|
108
|
+
| `auth-login-success` | interaction | `pocs/myapp-prototype/src/auth/Login.tsx:42` | IT-003, E2E-001 |
|
|
109
|
+
| `dashboard-renders-empty-state` | render | `pocs/myapp-prototype/src/Dashboard.tsx:18` | IT-005 |
|
|
110
|
+
| `checkout-applies-discount-code` | golden-trace | `pocs/myapp-prototype/src/checkout/apply.ts:67` | IT-012, CONTRACT-004 |
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Rule:** Every in-scope oracle MUST have at least one test that exercises its `Setup → Trigger → Assertions`. Unmapped oracles fail this step — either add tests to cover them, or surface to the user that harden's oracle capture missed a slice.
|
|
114
|
+
|
|
115
|
+
The mapped test SHOULD be an integration or E2E test (oracles describe boundary behavior; unit tests with mocks at the boundary don't satisfy them). A pure-unit test mapping is acceptable only when the oracle is itself a unit-level invariant (rare).
|
|
116
|
+
|
|
117
|
+
**Skip condition:** If `phase_plan.codify: skipped` for this work item or `aiwiki/oracles/` is empty for the work scope, record "No oracles in scope" in the plan and proceed. The check is non-blocking when oracle capture wasn't part of the lifecycle (e.g. trivial bugfix routed past harden).
|
|
118
|
+
|
|
99
119
|
### Step 2.5: Map User Journeys to E2E Scenarios
|
|
100
120
|
|
|
101
121
|
If the requirements document includes a User Journeys section, create a business flow traceability table. Every journey MUST map to an E2E test scenario. Gaps are flagged before test execution.
|
|
@@ -237,7 +257,7 @@ If the critic identifies coverage gaps or missing scenarios, address them before
|
|
|
237
257
|
|
|
238
258
|
| Field | Value |
|
|
239
259
|
|---|---|
|
|
240
|
-
| **Requires** | Implementation code (from `build-tdd`), architecture artifacts (`.forge/work/{type}/{name}/architecture/`), requirements (`.forge/work/{type}/{name}/requirements.md`) |
|
|
260
|
+
| **Requires** | Implementation code (from `build-tdd`), architecture artifacts (`.forge/work/{type}/{name}/architecture/`), requirements (`.forge/work/{type}/{name}/requirements.md`), oracle pages (`aiwiki/oracles/*.md` from harden Step 2.5) when codify ran |
|
|
241
261
|
| **Produces** | `.forge/work/{type}/{name}/test-plan.md` |
|
|
242
262
|
| **Feeds into** | `quality-test-execution` (test plan drives execution) |
|
|
243
263
|
| **Updates manifest** | `artifacts.test-plan: test-plan.md` |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: support-debug
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when a bug, test failure, error, crash, or unexpected behavior needs systematic investigation — triggered by phrases like 'debug this', 'why is X failing', 'trace this error', 'figure out what's wrong', 'investigate the failure', 'this is broken', 'help me debug'. Enforces a four-phase process (fact-check → root-cause investigation → hypothesis testing → implementation) with a 3-fix threshold that stops the random-fix spiral. Skip when the user is asking a design or architecture question (not a failure to investigate), when the failure is a known limitation already documented, or when the work is prototype iteration where the lightweight feedback loop in iterate-prototype is the right shape."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Support: Debug
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: support-dream
|
|
3
|
-
description: "Use when the user asks to 'consolidate the wiki', 'clean up aiwiki', 'merge duplicate notes', 'prune stale gotchas', or when /evolve runs maintenance.
|
|
3
|
+
description: "Use when the user asks to 'consolidate the wiki', 'clean up aiwiki', 'merge duplicate notes', 'prune stale gotchas', or when /forge-evolve runs maintenance. Auto-fires via /dream slash command (manual), hooks/scripts/pre-compact.sh (PreCompact, ~85% context — writes a 'Status: unconsumed' Checkpoints entry to aiwiki/sessions/{date}-{session_id}.md that the post-compact agent acts on), and phase-close skills (iterate-prototype Step 9, harden Step 4, feature.md Step 8.5 per-slice, deliver-deploy Phase 5.4 retrospective) which dispatch this skill after writing their respective artifacts.{phase}.locked_at. Merges aiwiki duplicates, resolves contradictions, refines the active session file. Output goes to aiwiki/proposed/ for user review — input is never modified."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Support: Dream (Wiki Consolidation)
|
|
@@ -22,7 +22,7 @@ Three triggers, distinct intents:
|
|
|
22
22
|
| Trigger | Intent | Scope |
|
|
23
23
|
|---|---|---|
|
|
24
24
|
| **Phase close** (Phase 4 (iterate) lock, Phase 5 (codify) lock, Phase 6 (production-build) per-slice close, Phase 7 (deliver) retrospective) | Promote phase outputs into curated wiki state | Subfolders touched by the phase |
|
|
25
|
-
| **PreCompact hook fire** (~85% context utilization) | Consolidate
|
|
25
|
+
| **PreCompact hook fire** (~85% context utilization) | Consolidate signal into durable form before lossy compaction | `aiwiki/raw/` + recently-touched typed pages. Also refines the active session file (`aiwiki/sessions/{date}-{session_id_short}.md`) — pre-compact creates it lazily on first fire; dream consolidates its `## Checkpoints` event log if it grows beyond ~10 entries. |
|
|
26
26
|
| **Manual `/dream`** | User-driven cleanup (after major refactor, branch merge, accumulated noise) | User-specified |
|
|
27
27
|
|
|
28
28
|
**Do NOT skip when:**
|
|
@@ -55,14 +55,15 @@ Fired by phase-close hooks (after user emits the phase-lock signal):
|
|
|
55
55
|
|
|
56
56
|
### PreCompact trigger
|
|
57
57
|
|
|
58
|
-
Fired
|
|
58
|
+
Fired indirectly via the pre-compact hook (`hooks/scripts/pre-compact.sh`). The hook itself cannot dispatch a subagent — instead it writes a `**Dream directive (unconsumed)**` block to the active session file's `## Checkpoints` section. The post-compact agent reads the session file, finds the unconsumed directive, and invokes this skill.
|
|
59
59
|
|
|
60
|
-
1.
|
|
61
|
-
2. **
|
|
60
|
+
1. Skill is invoked by the post-compact agent acting on the directive. Scope from directive: `aiwiki/raw/` + recently-touched typed pages, plus the active session file itself (`aiwiki/sessions/{date}-{session_id_short}.md`).
|
|
61
|
+
2. **Session file is always present at PreCompact time** — pre-compact.sh creates it lazily on first fire and appends the checkpoint. Dream refines the session file's `## Checkpoints` section if it has grown unwieldy (>10 entries) and may pre-populate the index sections (`## Files touched`, etc.) from git diff and aiwiki writes, leaving `/wrap` to finalize.
|
|
62
62
|
3. Dispatches `dreamer` subagent
|
|
63
63
|
4. Output to `aiwiki/proposed/{dream_id}/`
|
|
64
64
|
5. LINT runs on proposed output
|
|
65
|
-
6. Native compaction
|
|
65
|
+
6. Native compaction does not wait for user review — the consolidated raw/typed pages and session-file proposal are already on disk
|
|
66
|
+
7. **Mark the directive consumed** — after dispatch returns, the agent changes the originating entry's header from `**Dream directive (unconsumed):**` to `**Dream directive (consumed at {ISO-timestamp}):**`. Header-flip is what `session-start.sh` counts. Appending a separate "Status: consumed" line leaves the original unconsumed-marked header in place and the next session-start will still surface it as a HARD-INTERRUPT (dogfood-validated 2026-05-18).
|
|
66
67
|
|
|
67
68
|
### Manual /dream trigger
|
|
68
69
|
|
|
@@ -176,7 +177,7 @@ This skill operates the dream side; the user-facing CLI is separate but document
|
|
|
176
177
|
| Mistake | Fix |
|
|
177
178
|
|---|---|
|
|
178
179
|
| Modifying `aiwiki/` directly during consolidation | All writes go to `aiwiki/proposed/{dream_id}/`; the swap is the user's action |
|
|
179
|
-
| Writing
|
|
180
|
+
| Writing a new file in `aiwiki/sessions/` instead of refining the active session file | The active session file is `aiwiki/sessions/{date}-{session_id_short}.md` — created by pre-compact, /wrap, /dream, or harden. Dream refines that file in place (via the proposed-output path); it does not produce a separate sessions file. |
|
|
180
181
|
| Running dream when there's no signal to consolidate | Skip the dream entirely; record nothing |
|
|
181
182
|
| Skipping LINT on proposed output | LINT MUST run; lint warnings go into the manifest, surface during review |
|
|
182
183
|
| Promoting raw entries without reading the target schema | Read `aiwiki/schemas/{type}.md` first; the raw entry must satisfy required sections + frontmatter |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: support-gotcha
|
|
3
|
-
description: "Use when a
|
|
3
|
+
description: "Use when a reproducible failure mode, hard-won lesson, or surprising behavior with a concrete trigger emerges and is worth preventing next time — triggered by phrases like 'record this gotcha', 'save this lesson', 'capture this finding', 'we should remember this', 'this is a gotcha', 'log this for future', or automatically after support-debug closes a non-trivial bug. Writes a typed page to aiwiki/gotchas/{date}-{slug}.md with reproduction steps, root cause, and concrete fix; promotes to a rule when the same pattern recurs (N=3). Skip for speculation or half-formed thoughts (use /note for those); skip if the failure mode is not reproducible — a gotcha needs a concrete trigger, not a vibe."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Support: Gotcha
|
|
@@ -43,7 +43,7 @@ Every bug fixed, every failed approach, every "I wish I'd known that earlier" mo
|
|
|
43
43
|
| **Requires** | Concrete lesson: what broke, why, how to prevent |
|
|
44
44
|
| **Produces** | Gotcha page in `aiwiki/gotchas/{YYYY-MM-DD}-{slug}.md` (project) or `~/.claude/gotchas/{YYYY-MM-DD}-{slug}.md` (global) |
|
|
45
45
|
| **Schema** | `aiwiki/schemas/gotcha.md` — LINT validates frontmatter + sections on write |
|
|
46
|
-
| **Feeds into** | Future sessions (prevention), `gotcha-hunter` agent (surfaces relevant entries to reviewers), `/evolve` (skill improvement) |
|
|
46
|
+
| **Feeds into** | Future sessions (prevention), `gotcha-hunter` agent (surfaces relevant entries to reviewers), `/forge-evolve` (skill improvement) |
|
|
47
47
|
|
|
48
48
|
### Storage tiers
|
|
49
49
|
|
|
@@ -234,7 +234,7 @@ When no pending promotions exist, `gotcha-hunter` (separate agent) reads `aiwiki
|
|
|
234
234
|
| `gotcha-hunter` (agent) | Reads `aiwiki/gotchas/` and surfaces diff-relevant entries to reviewers; never writes |
|
|
235
235
|
| `support-wiki-lint` | Validates frontmatter + sections on every write |
|
|
236
236
|
| `support-dream` | At phase-close / PreCompact: consolidates raw entries, may merge similar gotchas, prunes retired entries (writes proposals to `aiwiki/proposed/{dream_id}/` for user review) |
|
|
237
|
-
| `/evolve` command | Reads gotchas to identify skill improvement opportunities |
|
|
237
|
+
| `/forge-evolve` command | Reads gotchas to identify skill improvement opportunities |
|
|
238
238
|
|
|
239
239
|
## Quick reference
|
|
240
240
|
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: support-
|
|
3
|
-
description: "Use when the user prompts a punch list of independent tasks (numbered or bulleted, ≥3 items) OR explicitly invokes /
|
|
2
|
+
name: support-parallel
|
|
3
|
+
description: "Use when the user prompts a punch list of independent tasks (numbered or bulleted, ≥3 items) OR explicitly invokes /parallel. Classifies each task by type, assembles the right specialist team per task, dispatches all in parallel, aggregates results. Phase-aware: light teams during prototype phases (fast iteration), full crew during harden/production (no shortcuts). Optional Codex adversarial pairing when consent is on. REFUSES command-shaped work — routes feature/bugfix/refactor items to their owning commands instead."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Parallel
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
10
|
Users don't always invoke `/feature` or `/bugfix`. The daily reality is a paste-in punch list: "do these 10 things: 1. update README; 2. explore option X; 3. add a test for Y; 4. ...". Doing those in series in one context window is slow, conflict-prone, and skips the Codex second-opinion that catches real bugs.
|
|
11
11
|
|
|
12
|
-
This skill assembles a **
|
|
12
|
+
This skill assembles a **team per item** — sized for the task's type and the project's current phase — and dispatches them in parallel. Each team has a Claude reviewer/builder paired with a Codex sibling (when the task is non-trivial). The skill REFUSES to swallow command-shaped work; items that look like features/bugfixes/refactors get routed to their owning commands.
|
|
13
13
|
|
|
14
14
|
**Core principle:** match team size to task complexity AND to the project's current phase. Prototype phases iterate fast with light teams. Production phases demand the full crew.
|
|
15
15
|
|
|
16
|
-
**Announce at start:** "I'm using support-
|
|
16
|
+
**Announce at start:** "I'm using support-parallel to dispatch N teams in parallel — M routed to commands, K running in light mode, L running in full mode." If `!max` / `--full-power` detected: "...running in `!max` mode — production teams enforced regardless of phase."
|
|
17
17
|
|
|
18
18
|
## When to Use
|
|
19
19
|
|
|
20
20
|
Fire when **any** of:
|
|
21
|
-
- User types `/
|
|
21
|
+
- User types `/parallel` explicitly
|
|
22
22
|
- User prompt contains a numbered list (`1. xxx 2. xxx 3. xxx`) with ≥3 items
|
|
23
23
|
- User prompt contains a bulleted list (`- xxx / - xxx / - xxx`) with ≥3 items AND items look like work-tasks (not casual mentions)
|
|
24
24
|
|
|
25
|
-
Confirm with user before dispatching if auto-detected (one-line: "Detected a 5-item task list; dispatching
|
|
25
|
+
Confirm with user before dispatching if auto-detected (one-line: "Detected a 5-item task list; dispatching teams — say 'no' to cancel").
|
|
26
26
|
|
|
27
27
|
Do NOT use for:
|
|
28
28
|
- A single task (use the appropriate command or skill directly)
|
|
@@ -33,7 +33,7 @@ Do NOT use for:
|
|
|
33
33
|
|
|
34
34
|
### Step 0: Codex consent (per `protocols/codex.md`)
|
|
35
35
|
|
|
36
|
-
Run the Codex consent flow ONCE for the whole
|
|
36
|
+
Run the Codex consent flow ONCE for the whole parallel run. The choice (Verify / Takeover / Skip / Never) propagates to every per-task dispatch. Record in `.forge/parallel/{run-id}/codex.yaml`.
|
|
37
37
|
|
|
38
38
|
### Step 1: Detect repo phase (or honor full-power override)
|
|
39
39
|
|
|
@@ -100,7 +100,7 @@ For each task, apply this classifier in order — first match wins:
|
|
|
100
100
|
| ≥4 subsystems touched OR ≥3 verbs combined | **complex** |
|
|
101
101
|
| Anything else | **ambiguous** (ask user) |
|
|
102
102
|
|
|
103
|
-
Command-shaped items get **routed out** — they do NOT get a
|
|
103
|
+
Command-shaped items get **routed out** — they do NOT get a team. Surface them to the user with: "Item X looks like a `/feature` — running it as a forge command instead. The remaining items continue as teams." User can override.
|
|
104
104
|
|
|
105
105
|
### Step 4: Assemble team per task
|
|
106
106
|
|
|
@@ -136,20 +136,20 @@ Apply both the **task type** AND the **phase mode**:
|
|
|
136
136
|
|
|
137
137
|
Ask the user: "Is this a prototype or production task list?" Then proceed with the matching template.
|
|
138
138
|
|
|
139
|
-
### Step 5: Dispatch all
|
|
139
|
+
### Step 5: Dispatch all teams in parallel
|
|
140
140
|
|
|
141
141
|
For each non-routed task:
|
|
142
142
|
1. Compose the prompt: include the task text, the detected type, phase mode, the team composition.
|
|
143
143
|
2. Fire each agent in the team as a background subagent (`run_in_background: true`).
|
|
144
144
|
3. For tasks whose team includes "dispatch X skill", spawn ONE agent that invokes that skill (the skill handles its own internal multi-agent chain).
|
|
145
|
-
4. Tag each agent with `
|
|
145
|
+
4. Tag each agent with `parallel/{run-id}/{task-n}/{role}` for telemetry.
|
|
146
146
|
|
|
147
147
|
Batched dispatch ceiling: 20-25 agents per `<function_calls>` block. For 10 tasks × 4 agents = 40 agents, plan 2 dispatch rounds.
|
|
148
148
|
|
|
149
149
|
### Step 6: Accumulate
|
|
150
150
|
|
|
151
151
|
Background notifications arrive asynchronously:
|
|
152
|
-
- Save each agent's result to `.forge/
|
|
152
|
+
- Save each agent's result to `.forge/parallel/{run-id}/task-{n}/{role}.md`
|
|
153
153
|
- Maintain a per-task status line: `Task 3 of 10: 2 of 3 agents complete (1 pending)`
|
|
154
154
|
- DO NOT narrate every individual agent completion to the user — batch updates every ≥3 returns
|
|
155
155
|
|
|
@@ -161,14 +161,14 @@ When all agents for a task return, synthesize:
|
|
|
161
161
|
- If only one returned (other failed/timeout) → mark `complete-single-source`, flag for user attention
|
|
162
162
|
- If both failed → mark `failed`, recommend retry or single-task fallback
|
|
163
163
|
|
|
164
|
-
Per-task output goes to `.forge/
|
|
164
|
+
Per-task output goes to `.forge/parallel/{run-id}/task-{n}/verdict.md`.
|
|
165
165
|
|
|
166
166
|
### Step 8: Run summary
|
|
167
167
|
|
|
168
168
|
After all tasks finish (or hit batch limit), produce one consolidated report:
|
|
169
169
|
|
|
170
170
|
```
|
|
171
|
-
|
|
171
|
+
Parallel Run {run-id} — {N} tasks, {M} routed to commands
|
|
172
172
|
|
|
173
173
|
| # | Task | Type | Team size | Status | Conflicts |
|
|
174
174
|
|---|------|------|-----------|--------|-----------|
|
|
@@ -186,7 +186,7 @@ Followups:
|
|
|
186
186
|
- Run /feature for item 4 when ready
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
Write the summary to `.forge/
|
|
189
|
+
Write the summary to `.forge/parallel/{run-id}/run-summary.md` and surface to user.
|
|
190
190
|
|
|
191
191
|
### Step 9: Stop
|
|
192
192
|
|
|
@@ -197,8 +197,8 @@ This skill does ONE run per invocation. If the user wants to iterate on findings
|
|
|
197
197
|
| Field | Value |
|
|
198
198
|
|---|---|
|
|
199
199
|
| Requires | A user-provided task list (parsed in Step 2); optionally an active manifest for phase detection |
|
|
200
|
-
| Produces | `.forge/
|
|
201
|
-
| Updates manifest | If a feature/bugfix manifest is active, append `phases.{phase}.
|
|
200
|
+
| Produces | `.forge/parallel/{run-id}/codex.yaml`, `.forge/parallel/{run-id}/tasks.yaml` (classification), `.forge/parallel/{run-id}/task-{n}/{role}.md` per agent, `.forge/parallel/{run-id}/task-{n}/verdict.md` per task, `.forge/parallel/{run-id}/run-summary.md` |
|
|
201
|
+
| Updates manifest | If a feature/bugfix manifest is active, append `phases.{phase}.parallel-runs: [{run-id}]`. Otherwise no manifest update — parallel runs are not phase-gated. |
|
|
202
202
|
| Feeds into | `/feature`, `/bugfix`, `/refactor` (for routed items); `support-gotcha` (for recurring patterns surfaced across tasks) |
|
|
203
203
|
|
|
204
204
|
## Agent Dispatch
|
|
@@ -224,11 +224,11 @@ Raw agents it dispatches directly:
|
|
|
224
224
|
| Step | Skill / Command | Why |
|
|
225
225
|
|---|---|---|
|
|
226
226
|
| Pre-dispatch consent | `protocols/codex.md` | Codex pairing requires consent ONCE per run |
|
|
227
|
-
| Task routing-out | `/feature`, `/bugfix`, `/refactor`, `/greenfield`, `/hotfix` | Command-shaped items must use commands, not
|
|
227
|
+
| Task routing-out | `/feature`, `/bugfix`, `/refactor`, `/greenfield`, `/hotfix` | Command-shaped items must use commands, not teams |
|
|
228
228
|
| Per-task dev | `quality-code-review` skill | Production dev tasks get the full review chain |
|
|
229
229
|
| Per-task debug | `support-debug` skill | Debug tasks get tracer + gotcha-hunter |
|
|
230
230
|
| Per-task security | `quality-security-audit` skill | Security tasks get the OWASP-aware audit chain |
|
|
231
|
-
| Post-run gotcha | `support-gotcha` | Patterns surfaced across multiple
|
|
231
|
+
| Post-run gotcha | `support-gotcha` | Patterns surfaced across multiple teams deserve a recorded lesson |
|
|
232
232
|
|
|
233
233
|
## Red Flags
|
|
234
234
|
|
|
@@ -239,12 +239,12 @@ Raw agents it dispatches directly:
|
|
|
239
239
|
| Codex consent skipped silently | Means no second-opinion across the whole run — for production-mode tasks this is a regression |
|
|
240
240
|
| 0 conflicts across all tasks | Either every task was trivial OR Claude+Codex are echoing each other; sample-check |
|
|
241
241
|
| Complex tasks in prototype mode | Probably should be a /feature; warn user before proceeding |
|
|
242
|
-
| Run-id directories never get cleaned | Add a periodic prune; aiwiki/dream or /evolve should handle it |
|
|
242
|
+
| Run-id directories never get cleaned | Add a periodic prune; aiwiki/dream or /forge-evolve should handle it |
|
|
243
243
|
| Soft cap warning ignored repeatedly | User has misframed work — recommend splitting into milestones |
|
|
244
244
|
|
|
245
245
|
## Anti-Patterns
|
|
246
246
|
|
|
247
|
-
**Swallowing command-shaped work.** If the user types "add a payment feature, then audit security, then ship", DO NOT
|
|
247
|
+
**Swallowing command-shaped work.** If the user types "add a payment feature, then audit security, then ship", DO NOT dispatch a parallel run — that's three workflows pretending to be three tasks. Route them: `/feature` → `quality-security-audit` → `/feature` deploy phase. `/parallel` is for items that DON'T fit a workflow.
|
|
248
248
|
|
|
249
249
|
**Phase-blind sizing.** Spawning the full crew on a Phase-4 prototype task wastes tokens AND violates the prototype-throwaway principle. Always read phase first.
|
|
250
250
|
|
|
@@ -252,7 +252,7 @@ Raw agents it dispatches directly:
|
|
|
252
252
|
|
|
253
253
|
**Ignoring divergent verdicts.** Claude+Codex disagreement is a SIGNAL, not noise. Surface it. Let the user adjudicate.
|
|
254
254
|
|
|
255
|
-
**Letting `.forge/
|
|
255
|
+
**Letting `.forge/parallel/` grow forever.** Each run leaves a directory. Add to `support-dream` consolidation scope, or document a cleanup pattern.
|
|
256
256
|
|
|
257
257
|
**Auto-dispatching without confirmation when auto-detected.** Numbered lists in user prose aren't always task lists (could be a survey of options, a sequence diagram, etc.). Confirm before firing 40 agents.
|
|
258
258
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Parallel Dispatch Pattern
|
|
2
2
|
|
|
3
3
|
Operational recipes for spawning per-task Claude+Codex teams.
|
|
4
4
|
|
|
@@ -101,7 +101,7 @@ complex → architect + tracer + builder + dispatch quality-code-review + spe
|
|
|
101
101
|
## Per-agent prompt template
|
|
102
102
|
|
|
103
103
|
```
|
|
104
|
-
You are agent {role} in
|
|
104
|
+
You are agent {role} in parallel-run task {n} of {N}, run-id {run-id}.
|
|
105
105
|
|
|
106
106
|
Task type: {dev|research|debug|docs|review|security|quick|complex}
|
|
107
107
|
Phase mode: {prototype|production}
|
|
@@ -120,10 +120,10 @@ Your scope: {paths, subsystem, or "whole repo"}
|
|
|
120
120
|
|
|
121
121
|
OUTPUT:
|
|
122
122
|
- Result of doing the task (code diffs, findings, document, etc.)
|
|
123
|
-
- One-line verdict for the
|
|
124
|
-
- Hand off any followups by writing them to .forge/
|
|
123
|
+
- One-line verdict for the parallel-run aggregator: PASS / CONCERNS / FAIL
|
|
124
|
+
- Hand off any followups by writing them to .forge/parallel/{run-id}/task-{n}/followups.md
|
|
125
125
|
|
|
126
|
-
Cap your output at {N} words. Save artifacts under .forge/
|
|
126
|
+
Cap your output at {N} words. Save artifacts under .forge/parallel/{run-id}/task-{n}/{role}.{ext}.
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
## Batched dispatch ceiling
|
|
@@ -155,7 +155,7 @@ else:
|
|
|
155
155
|
| Codex sandbox can't write | "operation blocked in sandbox" | Codex outputs uncommitted; Claude commits or main session commits |
|
|
156
156
|
| Two agents touch same file | Edit tool conflict | Partition more aggressively |
|
|
157
157
|
| Classifier picks command-shaped but rest heterogeneous | Some routed, some not | Surface routing decisions, continue with remainder |
|
|
158
|
-
| User cancels mid-run | Receives interrupt |
|
|
158
|
+
| User cancels mid-run | Receives interrupt | Stop in-flight tasks; preserve completed outputs |
|
|
159
159
|
|
|
160
160
|
## Sizing examples
|
|
161
161
|
|
|
@@ -172,7 +172,7 @@ else:
|
|
|
172
172
|
|
|
173
173
|
## Cleanup
|
|
174
174
|
|
|
175
|
-
`.forge/
|
|
176
|
-
- `/evolve` (include
|
|
177
|
-
- Manual: `find .forge/
|
|
178
|
-
- `support-dream` could consolidate
|
|
175
|
+
`.forge/parallel/{run-id}/` accumulates per-run. Prune via:
|
|
176
|
+
- `/forge-evolve` (include parallel-run cleanup as a step)
|
|
177
|
+
- Manual: `find .forge/parallel -maxdepth 1 -mtime +30 -exec rm -rf {} +`
|
|
178
|
+
- `support-dream` could consolidate parallel runs into aiwiki summary entries before prune
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Parallel Run Output Templates
|
|
2
2
|
|
|
3
3
|
Use these for per-task verdicts (Step 7) and run summaries (Step 8).
|
|
4
4
|
|
|
@@ -31,20 +31,20 @@ Use these for per-task verdicts (Step 7) and run summaries (Step 8).
|
|
|
31
31
|
|
|
32
32
|
## Artifacts
|
|
33
33
|
|
|
34
|
-
- `.forge/
|
|
35
|
-
- `.forge/
|
|
36
|
-
- `.forge/
|
|
37
|
-
- `.forge/
|
|
34
|
+
- `.forge/parallel/{run-id}/task-{n}/builder.md`
|
|
35
|
+
- `.forge/parallel/{run-id}/task-{n}/code-reviewer-claude.md`
|
|
36
|
+
- `.forge/parallel/{run-id}/task-{n}/code-reviewer-codex.md`
|
|
37
|
+
- `.forge/parallel/{run-id}/task-{n}/followups.md` (if any)
|
|
38
38
|
|
|
39
39
|
## Followups (if any)
|
|
40
40
|
|
|
41
|
-
- <item> — owner: <user | next
|
|
41
|
+
- <item> — owner: <user | next parallel run | /forge-evolve>
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
## Run summary
|
|
45
45
|
|
|
46
46
|
```markdown
|
|
47
|
-
#
|
|
47
|
+
# Parallel Run {run-id}
|
|
48
48
|
|
|
49
49
|
**Started:** {ISO-8601}
|
|
50
50
|
**Completed:** {ISO-8601}
|
|
@@ -95,9 +95,9 @@ Use these for per-task verdicts (Step 7) and run summaries (Step 8).
|
|
|
95
95
|
|
|
96
96
|
## Next steps
|
|
97
97
|
|
|
98
|
-
If divergence > 30%, sample-check a few
|
|
98
|
+
If divergence > 30%, sample-check a few team outputs — your classifier or team-assembly might be miscalibrated.
|
|
99
99
|
|
|
100
|
-
If all tasks PASSED with no divergence, run a `/evolve` to consider whether patterns recurred enough to warrant capturing as a gotcha or rule.
|
|
100
|
+
If all tasks PASSED with no divergence, run a `/forge-evolve` to consider whether patterns recurred enough to warrant capturing as a gotcha or rule.
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
## Severity / verdict definitions
|
|
@@ -123,4 +123,4 @@ After run summary, if any task is `complete-divergent` AND the divergence is ove
|
|
|
123
123
|
- Debug task with divergent verdicts → `support-debug` skill standalone
|
|
124
124
|
- Research task with divergent verdicts → user adjudication required
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
`/parallel` is for parallel speed. When agreement breaks down, the right tool is depth, not parallelism.
|
|
@@ -16,7 +16,7 @@ As the forge harness grows -- skills added, rules promoted from gotchas, command
|
|
|
16
16
|
| Trigger | Validation Scope | Performance Target |
|
|
17
17
|
|---|---|---|
|
|
18
18
|
| `/validate` command | Full scan (all 5 checks) | Under 30 seconds |
|
|
19
|
-
| `/evolve` modifies a skill | Pre-apply check (modified skill vs all others) | Under 10 seconds |
|
|
19
|
+
| `/forge-evolve` modifies a skill | Pre-apply check (modified skill vs all others) | Under 10 seconds |
|
|
20
20
|
| Session start | Lightweight I/O graph check only | Under 3 seconds |
|
|
21
21
|
| Manual request | Full scan or targeted check | Depends on scope |
|
|
22
22
|
| After gotcha promotion | Promoted rule vs existing rules and skills | Under 10 seconds |
|
|
@@ -32,7 +32,7 @@ As the forge harness grows -- skills added, rules promoted from gotchas, command
|
|
|
32
32
|
|---|---|
|
|
33
33
|
| **Requires** | All `SKILL.md` files + all `rules/*.md` files + all `commands/*.md` files |
|
|
34
34
|
| **Produces** | Validation report (structured, actionable) |
|
|
35
|
-
| **Feeds into** | `/evolve` command (fix contradictions before applying changes) |
|
|
35
|
+
| **Feeds into** | `/forge-evolve` command (fix contradictions before applying changes) |
|
|
36
36
|
| **Updates** | Nothing directly -- produces a report for human/AI action |
|
|
37
37
|
|
|
38
38
|
### Input Files
|
|
@@ -127,9 +127,9 @@ No blocking errors. System is consistent.
|
|
|
127
127
|
Warnings should be reviewed when convenient.
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
### /evolve Command (Pre-Apply Check)
|
|
130
|
+
### /forge-evolve Command (Pre-Apply Check)
|
|
131
131
|
|
|
132
|
-
Before `/evolve` applies any skill modification:
|
|
132
|
+
Before `/forge-evolve` applies any skill modification:
|
|
133
133
|
|
|
134
134
|
1. Receive the proposed change
|
|
135
135
|
2. Apply the change to a temporary copy
|
|
@@ -139,7 +139,7 @@ Before `/evolve` applies any skill modification:
|
|
|
139
139
|
6. If clean: ALLOW the change
|
|
140
140
|
|
|
141
141
|
```
|
|
142
|
-
/evolve proposes modifying build-tdd...
|
|
142
|
+
/forge-evolve proposes modifying build-tdd...
|
|
143
143
|
|
|
144
144
|
Pre-apply validation:
|
|
145
145
|
[PASS] No directive conflicts
|
|
@@ -267,7 +267,7 @@ Only escalate to WARNING/ERROR when you can name the downstream skill that fails
|
|
|
267
267
|
```
|
|
268
268
|
DRIFT:
|
|
269
269
|
|
|
270
|
-
[ERROR] D-001: New Contradiction After /evolve
|
|
270
|
+
[ERROR] D-001: New Contradiction After /forge-evolve
|
|
271
271
|
Modified: support-debug (added "ALWAYS verify with context7 before debugging")
|
|
272
272
|
Conflicts with: rules/common/verification.md ("verify when UNCERTAIN, not always")
|
|
273
273
|
Analysis: New directive is stricter than existing rule.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: support-system-guide
|
|
3
|
-
description: "Use when the user opens a fresh session, asks 'what should I run', 'where do I start', 'which command for X', 'is this a /feature or /greenfield', or describes intent without naming a command. Routes them to the right command (/feature, /greenfield, /
|
|
3
|
+
description: "Use when the user opens a fresh session, asks 'what should I run', 'where do I start', 'which command for X', 'is this a /feature or /greenfield', or describes intent without naming a command. Routes them to the right command (/feature, /greenfield, /parallel, /harden, etc.) and explains the phase model. Skip if the user has already invoked a specific command."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<EXTREMELY-IMPORTANT>
|
|
@@ -71,13 +71,14 @@ When the user describes what they want to do, route them to the correct command.
|
|
|
71
71
|
|
|
72
72
|
| User Intent | Command | What It Does |
|
|
73
73
|
|---|---|---|
|
|
74
|
-
| "What does this project have?" / "Show me forge" / "What can I run?" | `/
|
|
74
|
+
| "What does this project have?" / "Show me forge" / "What can I run?" | `/discover` | One-screen discovery — installed capabilities, active work, suggested next |
|
|
75
|
+
| "Capture this thought" / "Note this for later" / "Save this research" | `/note <text>` | Append to `aiwiki/raw/{date}.md` — for Phase 1-2 research, ad-hoc brainstorm, anything not yet a typed page |
|
|
75
76
|
| "Add a feature" / "Implement X" / "Build Y" | `/feature` | Full lifecycle: discover -> plan -> build -> quality -> deliver |
|
|
76
77
|
| "New project" / "Start from scratch" / "Greenfield" | `/greenfield` | Scaffold + full lifecycle for a new project |
|
|
77
78
|
| "Fix this bug" / "Something is broken" / "Error when..." | `/bugfix` | Debug -> fix -> test -> PR |
|
|
78
79
|
| "Clean up" / "Refactor" / "Improve code quality" | `/refactor` | Analyze -> refactor -> review -> PR |
|
|
79
80
|
| "Production is down" / "Emergency fix" / "Critical bug" | `/hotfix` | Emergency: debug -> fix -> test -> deploy (expedited gates) |
|
|
80
|
-
| "Improve the skills" / "Update a skill" / "System enhancement" | `/evolve` | Self-improvement: review skills, propose changes, validate |
|
|
81
|
+
| "Improve the skills" / "Update a skill" / "System enhancement" | `/forge-evolve` | Self-improvement: review skills, propose changes, validate |
|
|
81
82
|
| "Check consistency" / "Validate skills" / "Run validator" | `/validate` | Validate all skills/rules for contradictions and gaps |
|
|
82
83
|
|
|
83
84
|
### Command vs. Direct Skill Use
|
|
@@ -23,8 +23,23 @@ const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
|
|
|
23
23
|
const CITATION_HASHED_RE = /([\w./@~-]+\.\w+):(\d+)@([0-9a-f]{7})\b/g;
|
|
24
24
|
const CITATION_BARE_RE = /([\w./@~-]+\.\w+):(\d+)(?!@?[0-9a-f]{7})\b/g;
|
|
25
25
|
const ACK_STALE_RE = /\/\/\s*ack-stale\s*:|#\s*ack-stale\s*:/;
|
|
26
|
+
const ACK_SECRET_RE = /\back-secret\s*:/;
|
|
26
27
|
const SECTION_RE = /^##\s+(.+?)\s*$/gm;
|
|
27
28
|
|
|
29
|
+
// Possible-secret patterns. Advisory only — emitted as warnings, not errors.
|
|
30
|
+
// Lint hook is non-blocking (`hooks/scripts/wiki-lint.sh` returns continue:true
|
|
31
|
+
// unconditionally), so these never block a write — they surface on stderr so
|
|
32
|
+
// the next edit can address them. False positives are downgraded to info if
|
|
33
|
+
// the same line carries an `ack-secret: <reason>` annotation.
|
|
34
|
+
const SECRET_PATTERNS = [
|
|
35
|
+
{ name: 'aws_access_key', re: /AKIA[0-9A-Z]{16}/g },
|
|
36
|
+
{ name: 'private_key_block', re: /-----BEGIN (?:[A-Z ]+ )?PRIVATE KEY-----/g },
|
|
37
|
+
{ name: 'password_assignment', re: /\b(?:password|passwd|pwd)\s*[=:]\s*['"][^'"\s$][^'"\s]{3,}['"]/gi },
|
|
38
|
+
{ name: 'api_key_assignment', re: /\b(?:api[_-]?key|apikey|secret[_-]?key|access[_-]?token|bearer[_-]?token)\s*[=:]\s*['"][^'"\s$][^'"\s]{7,}['"]/gi },
|
|
39
|
+
{ name: 'jwt_token', re: /\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
|
|
40
|
+
{ name: 'url_credentials', re: /\b[a-z][a-z0-9+.-]*:\/\/[^\s/:@]+:[^\s/@]+@/gi },
|
|
41
|
+
];
|
|
42
|
+
|
|
28
43
|
// ---- Minimal YAML parser ---------------------------------------------------
|
|
29
44
|
// Handles only what our schema + frontmatter files use:
|
|
30
45
|
// - Top-level mapping
|
|
@@ -389,6 +404,43 @@ export function lint({ file, schemasDir, root }) {
|
|
|
389
404
|
fs.writeFileSync(absFile, newContent, 'utf8');
|
|
390
405
|
}
|
|
391
406
|
|
|
407
|
+
// Secrets scan — advisory only, never an error. The wiki-lint hook is
|
|
408
|
+
// non-blocking; these warnings surface on stderr so the next edit can
|
|
409
|
+
// address them. Scan the FINAL post-backfill content (after citation hash
|
|
410
|
+
// updates). Skip lines annotated with `ack-secret: <reason>`.
|
|
411
|
+
const finalContent = updates.length > 0
|
|
412
|
+
? `---\n${modifiedFm}\n---\n${modifiedBody}`
|
|
413
|
+
: original;
|
|
414
|
+
const finalLines = finalContent.split('\n');
|
|
415
|
+
const finalLineOffsets = computeLineOffsets(finalContent);
|
|
416
|
+
for (const { name, re } of SECRET_PATTERNS) {
|
|
417
|
+
re.lastIndex = 0;
|
|
418
|
+
let m;
|
|
419
|
+
while ((m = re.exec(finalContent)) !== null) {
|
|
420
|
+
const matchOffset = m.index;
|
|
421
|
+
// Find the line number (1-based).
|
|
422
|
+
let lineNum = 1;
|
|
423
|
+
for (let i = 0; i < finalLineOffsets.length; i++) {
|
|
424
|
+
if (finalLineOffsets[i] > matchOffset) break;
|
|
425
|
+
lineNum = i + 1;
|
|
426
|
+
}
|
|
427
|
+
const lineText = finalLines[lineNum - 1] || '';
|
|
428
|
+
const ackedOnSameLine = ACK_SECRET_RE.test(lineText);
|
|
429
|
+
const finding = {
|
|
430
|
+
kind: 'possible_secret',
|
|
431
|
+
type: name,
|
|
432
|
+
line: lineNum,
|
|
433
|
+
preview: m[0].slice(0, 40),
|
|
434
|
+
message: `Possible ${name} on line ${lineNum} (preview: ${m[0].slice(0, 40)}). If this is an intentional example or test fixture, add an \`ack-secret: <reason>\` annotation on the same line to downgrade to info.`,
|
|
435
|
+
};
|
|
436
|
+
if (ackedOnSameLine) {
|
|
437
|
+
warnings.push({ ...finding, kind: 'possible_secret_acked' });
|
|
438
|
+
} else {
|
|
439
|
+
warnings.push(finding);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
392
444
|
return {
|
|
393
445
|
ok: errors.length === 0,
|
|
394
446
|
file,
|
package/templates/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Installed into the target project by `npx @jamie-tam/forge init` (or kept in-syn
|
|
|
12
12
|
|
|
13
13
|
## Legacy
|
|
14
14
|
|
|
15
|
-
Kept on-disk so older manifests still parse and so `/evolve` can migrate them forward. Not installed into new projects.
|
|
15
|
+
Kept on-disk so older manifests still parse and so `/forge-evolve` can migrate them forward. Not installed into new projects.
|
|
16
16
|
|
|
17
17
|
- **`manifests/v5/`** — v5 schema (`SCHEMA.md` plus a `feature.yaml` reference). v5 manifests still parse against the v6 reader (see `manifests/v6/SCHEMA.md` §4). v4 manifests also still parse but no template is retained — the reader synthesizes the missing fields.
|
|
18
18
|
|