Skip to content

Feat/charter rebrand - #9

Merged
tacoda merged 15 commits into
mainfrom
feat/charter-rebrand
Jul 1, 2026
Merged

tacoda merged 15 commits into
mainfrom
feat/charter-rebrand

Conversation

@tacoda

@tacoda tacoda commented Jul 1, 2026 •

Copy link
Copy Markdown
Owner

Keystone 4.0 — the agent charter framework

Rebrands the framework from harness → charter, makes framework events extensible signals, retires the hook kind, and adds operator surfaces across CLI, dashboard, and MCP. Ships as 4.0.0 with a migration.

Framing. A harness is the engine that runs the model (Claude Code, the orchestrator, the runner). A charter is the standards you author to constrain it. Keystone is the agent charter framework — charter / constraint engineering at the repository level. "harness" survives in the code only where it means the engine.

Breaking

keystone migrate up carries a 3.0 install to 4.0:

  • .harness/ → .charter/, HARNESS.md → CHARTER.md
  • folds hooks/ into sensors/ (kind: hook → sensor, event: → on:, frontmatter only — the body is never touched)
  • repoints folded id: hooks/… → sensors/…
  • drops the vestigial context.json, rebuilds the index

Idempotent (safe to re-run); Down reverses the root rename. event: still parses as a back-compat alias for on:.

Highlights

  • Charter rebrand. .charter/ root; one canonical CHARTER.md entrypoint, every host file a thin pointer to it — Claude Code via native @CHARTER.md import, others via an imperative "read CHARTER.md" + a per-host capability delta (subagents / slash commands / skills / hooks). GLOSSARY.md ships the charter/harness authorship-test lexicon.
  • Signals. Host phases aron: value is a signal, soprojects define their own (keystone.json signals:, keystone signal fire|list). The hook kind is retired — reac: a sensor checks (verdict), a tool fires a side-effect (transport cli|http|mcp|plugin), an agent reviews. - **Operator surfaces (CLI + charter coverage(unchartedterritory),charter show --effective(post-cascade roster),charter conformance(a **rubric**: cascade / validitORMANT | DRIFTING |NON-CONFORMANT — not a vanity number),explain (activation + links + projection, flags uncommitted changes). Dnals pages; MCP gainskeystone_signal_list, keystone_charter_coverage, keystone_charter_conformance, keystone_explain`.
  • Governance. GOVERNANCE.md (roles, decision-making, the learn → synthesize →
    ratify amendment flywheel, prR 0009 recording the 4.0amendments.

Changed / removed

  • Positioning → "the agent charter framework" (README, CLI, MCP, dashboard, templates).
  • Primitive kinds: 13 (wagains anhttp transport +on:`.
  • Fixed: dashboard nav 404s (ad SSE (harness-changed →charter-changed); stale pre-3.0 .keystone/ runtime paths.

Verification

  • go build ./... · go vet ./... · go test ./... — all green
  • keystone verify + keystorter conformance →CONFORMANT
  • CodeScene branch review: nossions
  • Pre-release adversarial review caught two migration bugs (body-corruption on the
    event: rewrite; stale foldeed by tests
  • CHANGELOG.md has the full 4.0.0 entry

15 commits; see CHANGELOG.md and docs/adr/0009-charter-rebrand-and-signals.md.

tacoda added 15 commits July 1, 2026 12:12
Keystone is the coding-agent charter manager, not a harness. A harness
is the engine that runs the model (Claude Code, orchestrator, runner);
the charter is the authored standards that constrain it. Rename the
artifact everywhere it meant Keystone's own tree; keep "harness" only
where it means the engine.

- .harness/ → .charter/ (dir, docs, code, templates); HARNESS.md → CHARTER.md
- config.DefaultCharterRoot; --charter-root flag; keystone_charter_bootstrap
  MCP tool; keystone://charter/status resource
- harness-content → charter-content; harness-debt → charter-debt
- new GLOSSARY.md ships the charter/harness authorship-test lexicon
- README/CONTRIBUTING/docs lead with "charter manager"

Fixes surfaced during the pass:
- freeze v3_0 migration + migrate.go legacy detection to literal historical
  paths (they must not follow the renamed const)
- topics.go: lockfile now under .charter/ was shadowed by the generic
  charter case and never triggered prune — reordered
- route stale pre-3.0 .keystone runtime refs (mcp INDEX path, audit dir,
  snapshot target, fs watchers) through config.DefaultCharterRoot
- remove vestigial context.json; .keystone-snapshots → .charter-snapshots

Breaking: installed bases move .harness/ → .charter/ via the 4.0 migration
(added next). keystone.json's deprecated harness_root key still reads.
`keystone project`/`init`/`watch` now emit one canonical root CHARTER.md
(the full agent orientation: index how-to, activation table, iron laws,
lifecycle) and every host file becomes a thin pointer to it.

- agnostic.CharterBody + ProjectCharterMD: the single source of truth
- HostProfile + RenderPointer: per-host capability delta (subagents,
  slash commands, skills, hooks) so each host states what it can invoke
- Claude Code uses native @CHARTER.md import; other hosts get an
  imperative "you MUST read CHARTER.md" so the iron laws + ambient rules
  apply even without file-import
- cursor + continue emit an always-apply keystone-charter pointer rule
- all 11 targets/* seed templates converted to thin pointers
- writeCharterSurface / printProjectionResults / writeCharterPointer
  helpers extracted (keeps runProject/indexAndProject/ProjectRules
  within Code Health thresholds; runProject 31→30)

Primitive projection (skills/commands/agents → native dirs) unchanged —
going thin touches only the orientation file. Tests added; build, vet,
test green; pre-commit Code Health gate passed.
The 4.0 layout move: the single root directory becomes .charter/ (the
name describes the charter, not the engine). Up renames .harness/ →
.charter/, drops the vestigial context.json, and rebuilds INDEX* at the
new root. Down reverses the rename. Paths are frozen literals so the
migration reproduces its own era's layout regardless of the current
default. Idempotent; fresh 4.0 installs are a no-op. Tested (up, down,
idempotent, fresh-noop).
Apply the 4.0 rename to this repo's own charter:

- git mv .harness/ → .charter/; drop vestigial context.json
- rename harness-content/ guides+corpus → charter-content/, and the
  harness-debt sensor+ledger → charter-debt
- sweep 116 .charter/**/*.md for harness→charter (authored-artifact
  sense; engine-sense would stay, none found), fix stale globs
  (.keystone/harness → .charter, internal/framework/templates →
  internal/framework/scaffold/templates)
- regenerate INDEX + all host projections; drop orphaned projected
  files from the renamed sources
- root CLAUDE.md managed block → thin @CHARTER.md pointer
- record 4.0 in the lockfile (keystone migrate up)

keystone verify clean; build, vet, test green.
Framework events become **signals** — the extensible, higher-level
counterpart to host hook phases — and the `hook` primitive kind is
retired. Reactions now self-subscribe via `on:` (like a skill declares
`triggers:`), so the wiring middleman is gone.

Model: signal (WHEN) → the reacting primitive (WHAT), each self-subscribing:
- sensor  — a check; computational (run: → exit/HTTP status verdict) or
            inferential (agent review → schema); gates. Inferential
            sensors must declare returns: (structured feedback).
- tool    — an external callable (transport: cli|http|mcp|plugin);
            on-demand, or a side-effect when it declares on:. An MCP tool
            is just the `mcp` transport — "tool" is no longer overloaded.
- agent   — inferential review.

Signals:
- classifier inverted: host phases are the closed set; ANY other `on:`
  value is a signal, so projects define their own (no more "custom name
  misread as a host phase")
- built-in lifecycle signals (on-spec/plan/review/commit/... + task/
  command/playbook/verify/gate/phase pairs)
- custom signals declared in keystone.json `signals:`
- `keystone signal fire|list`; `keystone hook fire` kept as an alias

Field: `on:` is canonical; `event:` still parses (back-compat alias).

Migration: v4.0 now also folds installed `hooks/` → `sensors/`
(kind: hook → sensor, event: → on:). Dogfood + all templates folded.
Docs: 14 → 13 kinds; README gains a Signals section.

build, vet, test green; keystone verify clean; Code Health gate passed.
`keystone charter coverage` reports which project files a guide governs
and which are uncharted (matched by no guide's globs), grouped by
top-level region. Surfaces where the agent runs with no ambient rule —
a charter has jurisdiction; this shows where it's silent.

- primitive.MatchPath: proper doublestar (`**`) glob matcher (stdlib
  filepath.Match per segment; `*` never crosses `/`), with tests. The
  eval package's prefix-fallback matchGlob is left as-is (static evals).
- charter command group (coverage today; `show --effective` next).
- walks project source, skipping hidden/generated/vendored trees.

Code Health: bumpy-road + deep-nesting cleared. The String Heavy
Arguments finding on charter.go is accepted — inherent to CLI path code
(consistent with every other cmd/ file); the real complexity smells were
fixed, and forcing the ratio down would bundle paths into structs for no
gain.
`keystone charter show` renders the charter roster grouped by kind. With
--effective it resolves the cascade — one winning primitive per id
(project wins over policy, first-seen among policies) — and annotates
what each winner overrides, using the Provenance the walker already
tags. `--kind K` filters. Built on primitive.Walk (which classifies
project vs policy/<name>), not the stub loader.

Tests cover the cascade merge (project wins + shadow recorded), the
non-effective list-all path, and the kind filter. Code Health gate
passed (coverage results bundled into a struct to shed primitive-
obsession/string-heavy).
The Go web routes moved to /charter/ but the HTML templates still linked
to /harness/ (nav 404s) and listened for the old `harness-changed` SSE
topic while the watcher now emits `charter-changed` (live updates dead).
Swept all templates: /harness/ → /charter/, harness-changed →
charter-changed, and stale harness prose/paths → charter.

MCP: removed the retired `hook` from the new-primitive kind lists and the
list/get filter descriptions.

build, vet, full test suite green.
Extract the read-side charter views into internal/framework/charter so
the CLI, dashboard, and MCP share one implementation:
- charter.Coverage / CoverageResult (uncharted-territory report)
- charter.Effective (post-cascade resolved roster, project over policy)
- charter.Signals (built-in + custom, deduped/sorted)
cmd/keystone/charter.go becomes a thin wrapper over it.

Dashboard: new Coverage and Signals pages (+ nav) — coverage KPIs +
uncharted regions; signals with their `on:` subscribers and the bridged
host phases. Bug fixes from the prior commit (routes/SSE) already landed.

MCP: new read tools keystone_signal_list + keystone_charter_coverage;
instructions now describe signals and the sensor/tool/agent reaction
model. Removed the retired hook kind from kind lists.

Tests for coverage, effective cascade, signals, and the new routes.
Code Health: complexity/excess-args/nesting cleared; the charter
package's String-Heavy-Arguments finding is accepted (inherent to
path/glob code) — cmd/charter.go's ratio actually improved.
GOVERNANCE.md formalizes project governance (roles, decision-making,
maintainer path, growth path) and the charter-amendment model: the
learn → synthesize → ratify → record flywheel, and provenance —
path-derived layer (project vs policy/<name>), version+hash-pinned
policies, strict locks, and amendment records. Complements the
existing Provenance field + `keystone charter show --effective`.

ADR 0009 records the 4.0 charter amendments (harness→charter,
signals, hook-kind retirement) as the first first-class amendment
record — dogfooding the process. README links GOVERNANCE.md.

Serves the AAIF-submission governance requirement.
`keystone explain <id> [--kind K]` explains any primitive — its kind,
how/when it activates (a guide's globs, a sensor's on:+mode, a skill's
triggers, a tool's transport, an agent's spawn, a command's phase, …),
what it links to (corpus/deps/includes), and where it projects — then
flags whether the file has uncommitted changes vs the last commit.

- charter.Explain / Explanation + a kind→activation renderer map (covers
  all 13 kinds); charter.Matches shared by CLI + MCP lookup.
- MCP keystone_explain tool so host agents can explain a primitive
  without reading its whole body; instructions updated.
- Tests for activation-by-kind + links.

Code Health: complex conditionals extracted to charter.Matches; the
explain.go String-Heavy-Arguments finding is accepted (inherent to CLI
id/path arg handling).
`keystone charter conformance` scores a rubric — objective PASS/PARTIAL/
FAIL per criterion, not a vanity number:
- Cascade integrity — no strict-policy violations (loader.Verify).
- Frontmatter validity — primitives lint clean (PASS 0 · PARTIAL <5%).
- Guide↔corpus pairing — idiom guides paired with corpus by parallel
  topic or explicit corpus: (PASS ≥90% · PARTIAL ≥60%). Scoped to
  idioms; process/principle/domain guides + READMEs are exempt.
- Coverage — source governed (PASS ≥80% · PARTIAL ≥50%).

Verdict: any FAIL → NON-CONFORMANT; any PARTIAL → DRIFTING; else
CONFORMANT. charter.Conformance is shared by CLI + MCP
(keystone_charter_conformance). Dogfood scores CONFORMANT.

Guide↔sensor pairing was considered but dropped — no objective link
exists today (deps retired); backlinks would be the future mechanism.

Tests cover a conformant charter + an unpaired-guide FAIL. Code Health:
complexity/bumpy-road cleared; cmd/charter.go String-Heavy accepted
(CLI dispatch args; the charter package logic is clean).
Pre-release review caught two correctness bugs in the hook→sensor fold:
- the `event:` → `on:` regex was line-anchored, not frontmatter-scoped,
  so it rewrote `event:` in the markdown body (prose + example YAML) —
  data corruption. Now splits frontmatter via primitive.SplitFrontmatter
  and rewrites only that block.
- a folded hook kept its `id: hooks/…`, violating the id=path-slug
  invariant. Now repoints `id: hooks/… → sensors/…`.

Also: the clobber guard is idempotent on a byte-identical dst (finishes
a crashed move instead of erroring); Down documents that it reverses the
root rename only (fold + context.json are not reversed, matching 3.0).

Test pins both: body `event:` survives verbatim; frontmatter kind/id/on
are rewritten.
- CHANGELOG: 4.0.0 entry (rebrand, signals, hook retirement, coverage/
  show/conformance/explain, GOVERNANCE, migration; breaking notes).
- Positioning: "the agent charter framework" is the brand (not
  "charter manager" — it manages the charter, but that's descriptive
  prose). Description carries both framings — charter engineering /
  constraint engineering — at the repository level.
- GLOSSARY: 13 kinds (hook dropped) + a Signals entry.
- CONTRIBUTING: taxonomy note refreshed (13 kinds, hook retired,
  sensor/tool/agent reactions via on:).
- ADR 0009 + GOVERNANCE reflect the framework framing.
@tacoda tacoda self-assigned this Jul 1, 2026
@tacoda
tacoda merged commit 62ccdac into main Jul 1, 2026
1 check passed
@tacoda
tacoda deleted the feat/charter-rebrand branch July 1, 2026 22:14
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.

1 participant