Repository navigation
Feat/charter rebrand - #9
Merged
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Keystone 4.0 — the agent charter framework
Rebrands the framework from harness → charter, makes framework events extensible signals, retires the
hookkind, and adds operator surfaces across CLI, dashboard, and MCP. Ships as 4.0.0 with a migration.Breaking
keystone migrate upcarries a 3.0 install to 4.0:.harness/ → .charter/,HARNESS.md → CHARTER.mdhooks/intosensors/(kind: hook → sensor,event: → on:, frontmatter only — the body is never touched)id: hooks/… → sensors/…context.json, rebuilds the indexIdempotent (safe to re-run);
Downreverses the root rename.event:still parses as a back-compat alias foron:.Highlights
.charter/root; one canonicalCHARTER.mdentrypoint, every host file a thin pointer to it — Claude Code via native@CHARTER.mdimport, others via an imperative "read CHARTER.md" + a per-host capability delta (subagents / slash commands / skills / hooks).GLOSSARY.mdships the charter/harness authorship-test lexicon.value is a signal, soprojects define their own (keystone.json signals:,keystone signal fire|list). Thehookkind is retired — reac: asensorchecks (verdict), atoolfires a side-effect (transportcli|http|mcp|plugin), anagentreviews. - **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.md(roles, decision-making, the learn → synthesize →ratify amendment flywheel, prR 0009 recording the 4.0amendments.
Changed / removed
gains anhttptransport +on:`.harness-changed→charter-changed); stale pre-3.0.keystone/runtime paths.Verification
go build ./...·go vet ./...·go test ./...— all greenkeystone verify+keystorter conformance→CONFORMANTevent:rewrite; stale foldeed by testsCHANGELOG.mdhas the full 4.0.0 entry15 commits; see
CHANGELOG.mdanddocs/adr/0009-charter-rebrand-and-signals.md.