Skip to content

release: v0.5.0 — seams closed, one-click releases, measured benchmarks, security hardening#31

Merged
CodeWithJuber merged 18 commits into
masterfrom
claude/whitepaper-implementation-plan-x8f7bh
Jul 7, 2026
Merged

release: v0.5.0 — seams closed, one-click releases, measured benchmarks, security hardening#31
CodeWithJuber merged 18 commits into
masterfrom
claude/whitepaper-implementation-plan-x8f7bh

Conversation

@CodeWithJuber

Copy link
Copy Markdown
Owner

What & why

The v0.5.0 milestone: seven parallel worktree agents, integrated. This closes every follow-up seam the substrate-v2 phases flagged, fixes the release machinery, adds real measured benchmarks, and hardens the repo's security posture.

Release readiness (the "release not working" fix)

  • Root cause: release.yml fires only on v* tags and nothing ever created one — plus a second, subtler defect: tags pushed with the default GITHUB_TOKEN never trigger other workflows (GitHub's recursion guard), so even a bump wouldn't have released. Now: scripts/bump.mjs (stdlib-only, 14 tests) bumps all 7 version fields in one shot + rotates the CHANGELOG; .github/workflows/bump.yml makes a release one click from the Actions tab (test → commit → tag → explicit dispatch of release.yml); release.yml soft-skips npm publish with a loud warning when NPM_TOKEN is absent instead of failing; CI gains a version-drift guard and drops EOL Node 18 (engines say >=20); repo-settings.yml soft-skips with a clear message naming the ADMIN_TOKEN PAT it needs instead of a guaranteed 403.
  • Version cut to 0.5.0 everywhere (package.json, lockfile ×2, both plugin manifests, CITATION.cff, landing) — node scripts/bump.mjs check verifies agreement in CI.

Docs — README gains the full new command surface + "Team memory in three commands" + expanded honest limits; ARCHITECTURE adds the PCM ledger as the convergent store; GUIDE gets worked examples for every new command; ONBOARDING gets the "day two" ledger loop; CHANGELOG compare links repaired.

Measured benchmarks (npm run benchreports/benchmarks.md, committed real run): atlas full build 131 ms (145 files / 2,777 symbols), impact query 0.43 ms, ledger mint+put ~1,200 claims/s, CRDT merge of 2×500-claim replicas 158 ms, val() ~3.5 M/s, near-lookup via LSH at 1,000 artifacts 107 ms, full substrate gate 118 ms. Impact quality on a hand-labeled set from this repo's real import graph: P 0.90 / R 0.97 / F1 0.92 (one known-miss alias case kept in deliberately), reported beside — never blended with — the paper prototype's mutation-derived numbers. Plus a structural, source-checkable uniqueness table vs note-store memories / LLM gateways / plain RAG, including what those tools have that forgekit doesn't.

Seams closed

  • forge imagine --run: the sandboxed dry-run runner — ephemeral git worktree at HEAD, TAP-parsed per-file verdicts, verified cleanup; live: the 8-test selected suite ran in 1.3 s vs ~60 s for the full suite. (Found + fixed a real nested-runner bug: NODE_TEST_CONTEXT must be stripped from the child env.)
  • UI fingerprints now resolve CSS var() indirection — the dashboard fingerprints as its real 6-value 4 px scale; five taste-profile constraint JSONs wired into forge uicheck design --taste <name> with DESIGN.md auto-pickup.
  • forge ledger ratify | retract + dashboard POST twins (append-only; ratify = human-only ḥikma promotion minting a linked decision claim; same content → same decision id across dash and CLI).
  • Route metering joins gate metering, so forge cost --stages accumulates real route events.

Security/OSS — CodeQL, gitleaks (full 74-commit history scanned clean, blocking), OSSF Scorecard, hardened SECURITY.md (supported 0.5.x; documents the ledger's forgery resistance), 19 discoverability topics staged (needs ADMIN_TOKEN to apply), Dependabot/CODEOWNERS/issue templates verified present.

Checklist

  • npm test passes (401/401 — 38 new across the seven branches; every branch green in isolation and the union green after integration)
  • npm run check passes on changed files; node scripts/bump.mjs check → "version fields agree: 0.5.0"
  • New public functions have a test
  • Conventional commits per branch; merge commits for integration
  • CHANGELOG.md: [0.5.0] - 2026-07-07 cut with all bullets; fresh [Unreleased]
  • No new runtime dependency
  • Substrate/docs updated

Risk & rollback

  • Risk level: low-medium — mostly new files + docs; behavior-touching changes (imagine --run, ledger writes, metering) are opt-in flags or append-only
  • Rollback plan: revert the merge commits

Extra checks (tick if applicable)

  • npm run typecheck passes (0 errors)
  • Input validated at boundaries (dash POST body capped at 64 KiB + 400s; dirty-tree refusal on --run; usage errors on every new subcommand)
  • Logs contain no secrets/PII (gitleaks full-history clean)
  • If AI-assisted: I understand it, verified the package APIs, and it has tests

After merging: run the new bump workflow from the Actions tab (choice: auto) to cut the actual v0.5.0 tag + GitHub Release; add NPM_TOKEN (npm Automation token) to publish to npm, and ADMIN_TOKEN (fine-grained PAT, administration scope) then run repo-settings to apply the topics/description.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs


Generated by Claude Code

claude added 17 commits July 7, 2026 19:22
…de, honest limits

- README: new commands in the command list (ledger, reuse, context, imagine,
  diagnose, dash; uicheck + cost lines extended), a 'Team memory in three
  commands' section, and honest-limits additions (MinHash short-spec weakness,
  CSS var() indirection, measured-stages-only cost report, regex-approximate atlas)
- ARCHITECTURE: PCM ledger documented as the convergent store for all memory
  subsystems (ADR-0006 cited); new modules added to the repo layout
- docs/GUIDE: worked examples for ledger, reuse, context, diagnose, imagine,
  uicheck fingerprint/design, dash, and cost --stages; honest limits extended
- ONBOARDING: 'Day two: the ledger is learning' subsection
- CHANGELOG: [Unreleased] cut as [0.5.0] - 2026-07-07; footer compare links
  updated (missing 0.4.0 link added)
- Version 0.4.0 -> 0.5.0 in package.json, package-lock.json,
  .claude-plugin/plugin.json, .codex-plugin/plugin.json, CITATION.cff
  (+ date-released), landing/index.html footer

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
…ITY.md; refresh repo topics

- .github/workflows/codeql.yml: javascript-typescript analysis on push/PR + weekly
  cron; security-events: write only on the job; actions pinned to major tags like
  the rest of the workflows.
- .github/workflows/security.yml: gitleaks full-history secret scan on push/PR,
  blocking on a hit. Verified clean locally (gitleaks 8.16, 74 commits + working
  tree) — the runtime-.join() fixtures in test/_fixtures.js leave nothing for
  scanners to match, so no .gitleaks.toml allowlist is needed.
- .github/workflows/scorecard.yml: weekly OSSF Scorecard + default-branch push,
  publish_results: true, id-token + security-events write scoped to the job.
- SECURITY.md: supported-versions table (0.5.x), published-npm-package scope, and
  a ledger forgery-resistance section (verify recomputes content hashes; oracle
  weights re-read from the ORACLES table, never trusted from records) pointing at
  docs/plans/substrate-v2/01-pcm-protocol.md; maintainer hardening now references
  the shipped workflows.
- repo-settings.yml: topics refreshed (adds llm, memory, agent-memory,
  cost-optimization, code-quality, zero-dependency, crdt, team-memory; keeps the
  still-accurate existing set — 19 of GitHub's 20 max).
- CHANGELOG.md: one bullet under [Unreleased] / Added.

Dependabot (npm + github-actions, weekly), issue templates, config.yml with
Discussions contact link, CODEOWNERS, and PULL_REQUEST_TEMPLATE.md already
existed and are unchanged.

Signed-off-by: CodeWithJuber <weummat@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
…iles wired into the design gate

- uifingerprint: resolveCssVars() substitutes --name declarations into
  var(--name[, fallback]) before extraction (one nesting level, bounded
  loop so declaration cycles terminate; unresolvable var() left as-is).
  Token-driven stylesheets now fingerprint their full scale: src/dash.html
  went from spacing [8] to [4,8,12,16,24,32] on a 4px base.
- global/taste/<name>.json for all five prose profiles (spec 07 section 3):
  palette/space/type/shape constraint sets + per-profile gate thresholds,
  each with a "why" documenting the derivation from its .md (chroma is an
  HSL saturation/100 proxy, 0-1).
- loadTasteProfile/activeTasteStyle/profileChecks: `forge uicheck design
  <files> [--taste <name>]` uses the profile's tau_slop/tau_conform and
  adds taste-palette/type/radius/shadow/spacing-base checks; when --taste
  is absent the style pinned by a forge-taste-managed DESIGN.md is picked
  up automatically (unmanaged DESIGN.md pins nothing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
…e metering

The P7 follow-up named in 08-dashboard-ux.md §2 — the dashboard's only two
writes, both append-only so the lens can never corrupt the ledger:

- ledger_store.ratify(dir, idPrefix, {author, t}): resolve the claim by
  prefix, mint a `decision` claim ({ratifies: <full id>, note: ""}) with the
  HUMAN as author (nothing auto-ratifies), putClaim it. Content-addressed,
  so re-ratifying converges on the same decision ({existed: true}).
- CLI twins in the `forge ledger` block: `ratify <id-prefix>` and
  `retract <id-prefix> --reason "<why>"`, both stamped with gitAuthor() +
  epochDay(); retract without --reason is a usage error. Unknown-subcommand
  usage string updated.
- dash.js: POST /api/ratify and POST /api/retract (capped JSON body reader,
  400 on bad JSON/missing id, 404 on unknown prefix, POST-only on exactly
  those two paths — everything else stays GET-only/404). dash.html grows a
  per-row actions column (ratify ▸ / retract ✕ with a prompt()ed reason)
  that POSTs and re-reads /api/data; same ember/4px/two-radii style, still
  self-contained.
- P8 route metering: route.meterRoute(root, task, rec) appends one best-
  effort "route" metrics event (chosen tier + short task hash, never the
  task text) — called from the explicit `forge route` CLI path and the
  explicit substrate gate only; routeTask itself and ambient hook paths
  stay write-free, same contract as recordGate.

Tests: 363 → 368 (ratify mint/refuse/idempotent, dash POST round-trip over
an ephemeral port, meterRoute event lands with the tier; existing GET-only
test now asserts POST-to-other-paths is 404 and substrate's explicit-path
metering test also checks the route event). Typecheck 0 errors, biome clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
…low settings

Releases never happened because nothing created v* tags (release.yml is
tag-triggered only) and, even with a tag, a missing NPM_TOKEN hard-failed
the whole job. Fixes:

- scripts/bump.mjs (node stdlib only, unit-tested): bumps every version
  field in one shot (package.json, package-lock.json x2, .claude-plugin/
  plugin.json, .codex-plugin/plugin.json, CITATION.cff version+date,
  landing page footer), rotates CHANGELOG [Unreleased] under a dated
  heading with compare links, prints the new version. auto mode derives
  the bump from conventional commits since the last tag (BREAKING->major,
  feat->minor, else patch) with a CHANGELOG fallback. `npm run bump`.
  Plus a `check` subcommand asserting all version fields agree.
- .github/workflows/bump.yml: workflow_dispatch choice (auto/patch/minor/
  major) -> test -> bump -> commit "chore(release): vX.Y.Z" -> tag ->
  push -> explicitly dispatch release.yml (GITHUB_TOKEN pushes never
  trigger workflows, so the tag alone would silently do nothing).
- release.yml: accept workflow_dispatch on a tag ref, assert tag ==
  package.json version, and SKIP npm publish with a loud warning when
  NPM_TOKEN is unset (GitHub Release still cut) instead of failing.
- ci.yml: drop EOL Node 18 from the matrix (engines is ">=20"); add a
  version-drift guard job (node scripts/bump.mjs check).
- package-lock.json: sync stale engines ">=18" -> ">=20".
- repo-settings.yml: soft-skip with a clear ADMIN_TOKEN message instead
  of 403-failing on the fallback GITHUB_TOKEN.
- stale.yml: allow manual runs (workflow_dispatch).
- CHANGELOG.md: release-automation bullet; add the missing [0.4.0]
  compare link and repoint [Unreleased] at v0.4.0.
- docs/RELEASING.md: rewritten around the one-click flow, NPM_TOKEN
  setup, soft-skip behavior, and local dry-runs.
- biome.json/tsconfig.json: lint+typecheck now cover scripts/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
… suite

dryRun(root, {tests, timeoutMs}) completes the imagination loop (spec 06 §2.2):
check HEAD out into an ephemeral git worktree under tmp, run the selected suite
there with a forced TAP reporter, parse the # pass/# fail summary (+ per-file
verdicts attributed via failure location diagnostics), and ALWAYS remove the
worktree in a finally — the returned worktree field is verified, not assumed.
ok:true with failed>0 is a successful RUN whose verdict is "these tests fail";
ok:false is reserved for the run itself failing (no repo, empty suite, timeout,
runner crash). Never throws.

CLI: forge imagine "<task>" --run measures the static prediction; a dirty tree
is refused (the sandbox runs HEAD, so uncommitted changes are invisible) unless
--allow-dirty. Records a best-effort imagine stage metrics event
(outcome clean/breaks, ref, durationMs) for the cost model.

Notable: the spawned node --test must strip NODE_TEST_CONTEXT from its env, or a
dryRun invoked from inside a test runner speaks the runner's internal child
protocol instead of TAP.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
…results doc

npm run bench (bench/bench.mjs, node stdlib only) measures the substrate
primitives as medians of N runs after warmup and writes the tables plus an
environment JSON block (node, CPU, platform, commit) into reports/benchmarks.md
between generated-section markers:

- atlas: full build / incremental rebuild / impact query latency on this repo
- ledger: mint+put throughput, loadClaims, mergeDirs of two 500-claim replicas,
  val() over 1k claims (seeded synthetic fixtures in os.tmpdir, cleaned up)
- reuse: fingerprint throughput; exact + near-LSH lookup at 100 and 1000
  artifacts, sketch cache stripped per run (fresh-process behavior)
- context: assemble() on this repo; substrate: full substrateCheck (llm off)

The same run scores impact() precision/recall/F1 via the existing evalImpact()
harness against a committed, hand-labeled case set derived from this repo's
real import graph (bench/impact_cases.mjs — every reference cited per file;
one known-miss alias-binding case kept in on purpose). Measured: precision
0.90 / recall 0.97 / F1 0.92 over 6 cases, reported next to — never blended
with — the paper prototype's mutation-derived 0.63 / 1.00 / 0.75.

reports/benchmarks.md carries methodology (what each number does and doesn't
mean, incl. the disk-bound variance caveat) and a uniqueness section of purely
structural, source-checkable contrasts with adjacent tools per the ecosystem
map: note stores vs validity-anchored claims, LLM gateways vs the transparent
routing rubric, plain RAG vs proof-carrying reuse — each table's last row
states what the adjacent tools have that forgekit does not.

test/bench.test.js smoke-tests the pure helpers (median/p95/fmt/table/timeIt/
seeded fixtures) without running the bench; biome now covers bench/**.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
…d by its own tests)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Comment thread scripts/bump.mjs Fixed
…ncomplete-sanitization)

The version reaching this path is semver-validated in main(), but
rotateChangelog is an exported function — escape every regex
metacharacter, not just dots, so a direct caller cannot smuggle a
pattern into the duplicate-section check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
@CodeWithJuber CodeWithJuber marked this pull request as ready for review July 7, 2026 19:47
@CodeWithJuber CodeWithJuber merged commit d6f2581 into master Jul 7, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants