Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
"name": "forgekit",
"version": "0.25.0",
"description": "One config, every AI coding tool — cognitive substrate, MCP tools, guards, atlas, recall, and routing from one source.",
"author": { "name": "CodeWithJuber", "url": "https://github.com/CodeWithJuber" },
"author": {
"name": "CodeWithJuber",
"url": "https://github.com/CodeWithJuber"
},
"homepage": "https://github.com/CodeWithJuber/forgekit#readme",
"repository": "https://github.com/CodeWithJuber/forgekit",
"license": "MIT",
Expand All @@ -24,6 +27,6 @@
"Predict impact for this symbol.",
"Route this task to the right model tier."
],
"brandColor": "#137A72"
"brandColor": "#f26430"
}
}
66 changes: 64 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ on:
tags: ["v*"]
workflow_dispatch: # dispatched by bump.yml with --ref vX.Y.Z; must target a tag

# A tag can arrive twice for the same version — the push (tags: v*) AND bump.yml's
# explicit `gh workflow run release.yml --ref vX.Y.Z` dispatch. Serialize per-ref so
# the two never race a double publish; the loser queues (never cancels a mid-publish).
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

Expand Down Expand Up @@ -56,9 +63,19 @@ jobs:
fi
- name: Publish to npm (with provenance)
if: env.HAS_NPM_TOKEN == 'true'
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# Idempotent: skip when the version is already on the registry, so re-running a
# wedged release (or the serialized second tag event) never dies on "cannot
# publish over the previously published version".
run: |
PKG=$(node -p "require('./package.json').name")
VER=$(node -p "require('./package.json').version")
if npm view "$PKG@$VER" version >/dev/null 2>&1; then
echo "::notice::$PKG@$VER is already on npm — skipping publish (idempotent re-run)."
else
npm publish --provenance --access public
fi
- name: Skip npm publish (NPM_TOKEN not set)
if: env.HAS_NPM_TOKEN != 'true'
run: |
Expand All @@ -69,4 +86,49 @@ jobs:
TAG: ${{ github.ref_name }}
# --generate-notes builds notes from merged PRs/commits since the previous tag,
# so it works with lightweight OR annotated tags (unlike --notes-from-tag).
run: gh release create "$TAG" --title "$TAG" --generate-notes --verify-tag
# Idempotent: skip if the Release already exists (re-run recovery).
run: |
if gh release view "$TAG" >/dev/null 2>&1; then
echo "::notice::GitHub Release $TAG already exists — skipping creation."
else
gh release create "$TAG" --title "$TAG" --generate-notes --verify-tag
fi
- name: Verify the release loop closed (fail loudly on a wedge)
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
# H1 closed-loop check: a tag must produce BOTH a GitHub Release and (when
# publishing is enabled) an npm version. Historically release.yml could wedge
# after the tag landed and nothing alerted — orphan tags v0.22.2/v0.23.2/v0.24.0.
# This step turns that silent wedge into a red, notified job failure; re-running
# the workflow (steps above are idempotent) then completes whatever is missing.
run: |
fail=0
if gh release view "$TAG" >/dev/null 2>&1; then
echo "GitHub Release $TAG: present."
else
echo "::error::No GitHub Release exists for $TAG after the release job."
fail=1
fi
if [ "$HAS_NPM_TOKEN" = "true" ]; then
PKG=$(node -p "require('./package.json').name")
VER=$(node -p "require('./package.json').version")
ok=0
for _ in 1 2 3 4 5 6; do
if npm view "$PKG@$VER" version >/dev/null 2>&1; then ok=1; break; fi
sleep 10 # let the registry reflect a just-published version
done
if [ "$ok" = "1" ]; then
echo "npm $PKG@$VER: present."
else
echo "::error::npm does not serve $PKG@$VER after publish (registry wedge?)."
fail=1
fi
else
echo "::warning::NPM_TOKEN not set — verified the GitHub Release only, not npm."
fi
if [ "$fail" != "0" ]; then
echo "::error::Release loop did NOT close for $TAG — do not treat it as shipped. Re-run this workflow to complete the missing artifact."
exit 1
fi
echo "Release loop verified for $TAG."
26 changes: 0 additions & 26 deletions .gitlab-ci.yml

This file was deleted.

37 changes: 37 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,43 @@ the series and a sustained alarm rides the gate's block reason. Proceeding under
assumptions appends a record the advisory names and the next handoff surfaces — a guess
can never silently become a fact.

**Commit-boundary gate (`src/commit_gate.js`, `forge precommit`).** The commit rung of
the gate lattice (turn ⊂ commit ⊂ PR): the Stop hook gates the turn and CI's `docs check`
gates the PR, so this runs the SAME registry-derived completeness classifier
(`classifyPath` from `gate.js`) plus `hasSecret` over staged added lines at the commit
boundary — code staged without its doc/state artifact, or a staged secret, is caught
while the fix is still one `git add` away. Each rung is an independent catch layer, so
the silent-miss probability falls multiplicatively.

**Deep verification (`src/consensus.js`, `forge verify --deep`).** Where plain `verify`
asks one oracle (the tests) plus one heuristic, this runs a table of independent lenses
and aggregates them with the same noisy-OR risk score `lessons.js` uses, behind a
cross-family gate so correlated structural signals can't block alone. Deep `ok` is a
conjunction: the core verifier must PASS **and** the lens consensus must not block; an
unconfigured core can never yield `ok:true`. The score is a calibrated heuristic, not a
proof.

**Knowledge routing (`src/knowledge_router.js`).** The third routing leg beside `route.js`
(model tiers) and `intent.js` (intent classes), using the same exemplar k-NN math: a fact
is routed to its storage home (decisions vs. the ledger vs. …) tuned by adding example
rows, never regexes. It is TOTAL by construction — a fact resembling nothing falls back to
the ledger (whose decay semantics make an unsure placement safe), never "nowhere".

**Anti-repetition memory (`src/deja.js`).** Closes the "why do I keep re-solving solved
tasks" gap: a clean first-try success used to leave no durable trace (cortex only mints on
correction). At Stop it mints one `summary` claim (a deterministic, secret-redacted gist),
attaching a `test.run` confirm when the session's tests passed; `dejaLookup` then ranks
prior summary/lesson/diagnosis claims for a new task with the same `retrieve()` (rel × rec
× val) the ledger query uses. No new protocol — it reuses the shipped PCM machinery.

**The documentation-impact graph (`src/docs_impact.js`, `forge docs impact`).** Where
`docs check` reconciles fixed registries and `docs sync` scans a diff for identifiers,
this answers "I changed X — which documented surfaces mention X and are now potentially
stale?" via a data-driven `EXTRACTORS` registry (commands, flags, env vars, MCP tools,
exported symbols, brand tokens, version, package.json fields) reused from `docs_check.js`,
an inverted entity → `file:line` index over every doc surface, and a diff-scoped impact
query ranked by confidence. Advisory by default; `--strict` exits non-zero for CI.

**Deliberately not wired:** `checkpointCadence` (optimal-stopping check spacing) still
has no runtime step-loop to consume it — wiring it would mean inventing one. It stays
library math with tests until a real consumer exists.
Expand Down
51 changes: 51 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,57 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **`problem-solver` skill** (`global/tools/problem-solver/`) — a universal,
framework-driven problem-solving cycle (Clarify → Classify → Diagnose → Generate →
Decide → Act & Sustain) bundled through the plugin's `skills` directory. Ships a
frameworks reference (5 Whys, Fishbone, First Principles, TRIZ, Cynefin, DMAIC/PDCA/8D/
A3, Design Thinking, Nine Windows, weighted decision matrix, pre-mortem), a disciplines
reference, and a fill-in canvas.

### Fixed

- **Broke a static ESM import cycle in the memory layer.** `lessons_store.js`,
`cortex_distill.js`, and `adjudicate.js` now import `hasSecret` directly from its
source of truth (`secrets.js`) instead of a re-export in `recall.js`, eliminating the
`recall → ledger_read → lessons_store → recall` cycle (a top-level-eval TDZ hazard).
- **Importing the package as a library no longer executes the CLI.** The package root
(`exports["."] → src/cli.js`) now guards its top-level `run()` behind a main-module
check (symlink-resolving, so the global `forge` bin still runs), and exports `run`.
`package.json` `sideEffects` now names the CLI entry accurately instead of `false`.
- **Hermetic tests.** `test/init.test.js` no longer merges hook guards into the
developer's real `~/.claude/settings.json`; it pins `settingsPath` under a temp dir.
- **The unimplemented-command stub now exits non-zero**, so scripts and CI no longer
read a "not wired yet" command as success.
- Replaced literal NUL bytes with `\0` escapes in the `reuse.js`/`diagnose.js`
content-hash separators (byte-identical runtime output; the source is now clean text).

### Changed

- **The release pipeline is now closed-loop.** `release.yml` gains a per-ref
`concurrency` group, makes npm publish and GitHub Release creation idempotent (so a
wedged release can simply be re-run), and adds a final verification step that FAILS the
job when a tag did not produce both a GitHub Release and (when publishing is enabled) an
npm version — the silent wedge that orphaned tags v0.22.2/v0.23.2/v0.24.0 now surfaces
as a red, notified failure. See `docs/RELEASING.md` for the orphan-tag note.
- **Consolidated duplicated helpers into `src/util.js`.** One read-only, trimmed `git()`
replaces four byte-identical copies (session/handoff/update/docs_check); a shared
`readJsonSafe()` replaces the ledger store's local copy. Deliberately-divergent git
helpers (verify.js's arg order + `FORGE_DEBUG` logging; the un-trimmed docs-sync
variants) are documented rather than force-merged.
- Removed the dead `plugin` entry from `package.json` `files`, the vestigial
`.gitlab-ci.yml`, and the dangling `@AGENTS.md` import in `CLAUDE.md`; fixed the
off-palette Codex plugin `brandColor`.
- **Broke a layering cycle in `repo_config.js`.** `applyPrimaryTool` no longer reaches
back into the sync compiler via a dynamic `import("./sync.js")`; the sync runner is now
injected by the caller (`cli.js`), keeping the config leaf acyclic.
- `ledger_store.js`'s `git cat-file -e` ref resolver now passes `--` before the ref
(defense in depth against a ref that begins with `-`).
- **Refreshed `ARCHITECTURE.md`** for the v0.20–v0.24 modules that were missing from the
reference: `commit_gate` (`forge precommit`), `consensus` (`forge verify --deep`),
`knowledge_router`, `deja`, and `docs_impact` (`forge docs impact`).

## [0.25.0] - 2026-07-20

### Changed
Expand Down
5 changes: 3 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
@AGENTS.md

# forgekit — contributor instructions

## Stack

- Node.js >=20, pure ESM (`"type": "module"`), zero runtime dependencies.
- Linter/formatter: Biome 2.5.2 (dev dependency).
- Types: TypeScript via JSDoc annotations — no `.ts` files, checked by `tsc`.

## Commands

- Install: `npm ci`
- Test: `npm test` (node:test, 600+ tests)
- Lint + format: `npx biome check` (or `npm run check`)
- Typecheck: `npm run typecheck`
- Build pages: `npm run pages:build`

## Rules

- **Zero runtime dependencies** — CI enforces this. Everything uses Node.js built-ins.
- ESM only — use `import`, never `require`.
- Match existing patterns: dynamic `await import()` for optional modules, brand
Expand Down
13 changes: 13 additions & 0 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ git push origin master "$V"
- `scripts/bump.mjs` refuses to rotate the CHANGELOG onto a version that already has a
section. When `auto` finds nothing shippable it exits `3` (a graceful skip the
auto-release workflow keys off), not a hard error — so a no-op merge never fails CI.
- **Closed-loop verification**: `release.yml`'s final step asserts the tag produced BOTH
a GitHub Release and (when `NPM_TOKEN` is set) an npm version, and **fails the job** if
either is missing. The publish and release-create steps are idempotent, so recovering a
wedged release is just re-running the workflow on the tag.

## Orphan tags (v0.22.2, v0.23.2, v0.24.0)

These three tags were cut before the closed-loop guard above existed and have **no
GitHub Release and no npm version** — the release workflow wedged after the tag landed
and nothing alerted. They are recorded here for transparency. To resolve one, either
re-run `release.yml` on the tag (the idempotent steps will backfill the missing Release
and, if `NPM_TOKEN` is set, the npm version) or delete the tag and note it here. This is
a repo-admin action, intentionally not automated.

## Related workflow secrets

Expand Down
108 changes: 108 additions & 0 deletions global/tools/problem-solver/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
name: problem-solver
description: Universal problem-solving engine that fuses proven frameworks (ASQ 4-step cycle, DMAIC/PDCA, 5 Whys, Fishbone, First Principles, TRIZ, Cynefin, Design Thinking, weighted decision matrix) into one staged loop. Use when the user asks to solve, analyze, or break down a problem, find root causes, choose between options, innovate, make a hard decision, handle a crisis, or wants structured/step-by-step problem solving.
---

# Problem Solver

This skill solves any problem — technical, business, personal, or complex — through a
staged loop. Each analytical stage carries a discipline that keeps the analysis honest
(e.g. verify facts before diagnosing root cause). Match depth to the problem: a trivial
problem gets two sentences of method, not all six stages.

## Core Workflow: The Problem-Solving Cycle

Run these 6 stages in order. Loop back when a stage fails its exit check. Always state
which stage you are in.

```
[Problem] --> 1. CLARIFY -> Define + verify facts
--> 2. CLASSIFY -> Pick the right mode of attack (Cynefin)
--> 3. DIAGNOSE -> Root cause, not symptoms
--> 4. GENERATE -> Multiple options, wide consultation
--> 5. DECIDE -> Weighted choice + ethics screen
--> 6. ACT & SUSTAIN -> Plan, pilot, review, persist
```

### Stage 1 — CLARIFY

- Separate **fact from opinion**: verify information before acting on it.
- Answer 5W2H: What happened? Where? When? How much/many? Who detected it? Why is it a
problem? (Who is for detection only, never blame — blame corrupts the data.)
- Write a one-sentence problem statement. Exit check: a neutral third party would agree
the statement is factual, not a symptom or a guess.

### Stage 2 — CLASSIFY (Cynefin)

Classify the problem's context to choose the strategy:

- **Clear/Obvious** -> apply best practice directly; skip to Stage 6.
- **Complicated** -> expert analysis needed; go to Stage 3 with analytical tools (5 Whys,
Fishbone, First Principles).
- **Complex** -> cause-and-effect only visible in retrospect; probe with small
safe-to-fail experiments (PDCA loops) instead of one big plan.
- **Chaotic** -> act first to stabilize (stop the bleeding), then reclassify.
- **Disorder** -> gather more information; return to Clarify.
Never apply linear fixes to complex systems.

### Stage 3 — DIAGNOSE (root cause)

- Use **5 Whys** for linear chains, **Fishbone (6M)** for multi-cause problems, **First
Principles** to strip assumptions to unarguable truths, **TRIZ** when the problem is a
contradiction ("improving X worsens Y").
- Reflect deeply: reconcile apparent contradictions before concluding; reject
surface-level answers.
- Exit check: fixing this cause prevents recurrence. If the "root cause" is a person, dig
one level deeper — it's usually a system or process.

### Stage 4 — GENERATE (options + consultation)

- Generate **at least 3** genuinely different options before evaluating. Never run with
the first idea.
- Consult diverse perspectives deliberately — frontline people, skeptics, domain experts,
and those affected. Ask the user who should be consulted.
- Use brainstorming, working backward, Nine Windows (past/present/future ×
sub/system/supersystem), or analogy from other domains. If stuck, recommend "sleep on
it" — incubation is a legitimate step, not delay.

### Stage 5 — DECIDE (weighted matrix + ethics screen)

- Build a **weighted decision matrix**: effectiveness, feasibility, cost, risk,
reversibility, alignment with goals — plus a mandatory **ethics column** (does it harm
anyone? is it honest? does it betray a trust?).
- Screen out any option that fails the ethical screen regardless of score: the ends never
justify unjust means, and no option may be built on deceit or wrongful gain.
- After due diligence, commit with calm and stay unattached to the ego's preferred option.
Document the decision and its rationale.

### Stage 6 — ACT & SUSTAIN

- Plan with who/what/when; run a **small pilot** first when stakes are high (PDCA:
Plan-Do-Check-Act).
- Do everything within your power, then stay calm about the outcome — this kills both
paralysis and recklessness.
- Monitor with leading indicators and feedback channels. If targets are missed: bad
execution -> redo Stage 6; poor solution -> redo Stages 4-5; wrong cause -> redo Stage 3.
- Persist through slow results; do not abandon a sound plan at the first setback.
- Standardize and document the fix so the problem cannot recur; extract lessons learned.

## Reference Files

Load only when needed:

- **references/frameworks.md** — Detailed tool guide: 5 Whys, Fishbone, First Principles,
TRIZ (40 principles + contradiction method), Cynefin, DMAIC, PDCA, 8D, A3, Design
Thinking, Nine Windows, decision matrix, potential problem analysis. Read when a stage
needs a specific tool's full procedure.
- **references/principles.md** — The disciplines behind each stage (verify, reflect,
consult, screen ethics, effort-then-acceptance, persist) with application prompts and
boundaries. Read when a problem is ethical, personal, or high-stakes.
- **assets/problem-solving-canvas.md** — Fill-in canvas template covering all 6 stages.
Offer to fill it for substantial problems.

## Behavior Rules

- Match depth to problem size: a trivial problem gets 2 sentences of method, not 6 stages.
- Be generic: the same cycle serves code bugs, business strategy, relationship conflict,
or research blockers — only the tools per stage change.
- Prefer evidence over assertion at every stage; a confident guess is still a guess.
Loading
Loading