Skip to content

0.2.0 — Foundation Audit + Pull Loop + Path-Based Taxonomy#30

Merged
hwesterb merged 34 commits intomainfrom
feat/foundation-audit-2026-04-17
Apr 18, 2026
Merged

0.2.0 — Foundation Audit + Pull Loop + Path-Based Taxonomy#30
hwesterb merged 34 commits intomainfrom
feat/foundation-audit-2026-04-17

Conversation

@hwesterb
Copy link
Copy Markdown
Member

Summary

  • Foundation audit — dual-LLM refinement pass across all 452 patterns. 31 new, 5 renames/collapses, 71 layer moves, 71 mechanism rewrites, 50 structural fixes, hash canonicalization bug fix.
  • Pull-loop closuresema pull now honors _meta.supersedes by default: retired handles get cleaned up from local DBs, with an orphan-guard fallback and three clearly-reported user options when cleanup is blocked. --preserve-superseded opts out.
  • Path-based taxonomy_meta.layer + _meta.category consolidated into _meta.path: list[str]. Graph uses TAXONOMY_PATH nodes + IN_PATH / PARENT_PATH edges. Supports deeper hierarchies without schema changes. sema categorize <handle> --path A/B command added.
  • Multi-release supersedes chain — full v0.1.18 + v0.1.27 predecessor population with rename-aware fixes so consumers pinned to any prior release get a clean upgrade on pull.
  • Vocabulary load-line bannersema use / apply / pull / MCP startup print the full vocabulary root hash as 📚 sema:vocab#mh:SHA-256:....
  • UI updates — path-based taxonomy visible in the 3D graph and home page; Primitives no longer look disconnected (REFERENCES shown by default); details panel renders clicks on taxonomy nodes; DB switcher hides when only one DB exists.

Scope of changes

  • 452 patterns total (same handle set as v0.1.27 + 31 new − 5 collapsed handles, net +26).
  • Vocabulary root: sema:vocab#mh:SHA-256:39ca671a4dcb3075855cb293380d1796105e2eca0de49b0537279b798b675ee6.
  • 399 of 452 pattern files differ from v0.1.27.
  • 233/233 tests pass. rebuild --check green — hashes stable across the schema migration.

Breaking changes

See CHANGELOG.md for the full list. Quick summary:

  • _meta.layer + _meta.category replaced by _meta.path. Top-level sema_layer / sema_category preserved as derived (read-only) fields for one deprecation cycle.
  • sema pull default behavior: removes local handles listed in upstream _meta.supersedes (opt out with --preserve-superseded).
  • sema_mint MCP tool flipped from opt-in to opt-out.
  • ~399 pattern hashes shifted (auto-handled via the supersedes chain for consumers).

Test plan

  • PYTHONPATH=src python3 -m pytest — 233 tests
  • PYTHONPATH=src python3 scripts/rebuild_vocabulary.py --check — hash stability
  • End-to-end sema pull round-trip from v0.1.27 → 0.2.0 against a fresh consumer DB: expect 5 superseded-removed, 1 upstream-removed (Group), 31 added
  • sema categorize <handle> --path A/B moves a pattern; graph edges re-wire; invalid paths rejected against VALID_PATHS
  • Load the 3D graph at http://localhost:3030/graph: TAXONOMY_PATH nodes grey, patterns colored by layer, hover shows leaf-only label, click opens sidebar with pattern list
  • Pattern card on home page shows layer pill (colored) + subcategory pill (neutral)

🤖 Generated with Claude Code

hwesterb and others added 30 commits April 17, 2026 12:55
Hand-edited apply of the 2026-04-17 foundation audit, including the
new §3.21 section (broad-use follow-ups + FI paper alignment + layer
principle refinement).

Highlights:
- 20 new patterns minted (Boolean, ReAttempt, FrameError, PathwayMemory,
  DecompositionGate, DocumentedOverride, Status, ConceptualDecomposition,
  PerformanceSignal, FailureTrace, ReceptivityGate, Forest, GraphOfThought,
  CollaborativeWritingProtocol, HumanEmulatorProtocol, DiscoveryProtocol,
  TemporalEnsembleForecasting, EthicalReasoningProtocol, TruthseekingProtocol,
  MetaProtocols) + PURE framework
- 4 retirements (Group, Switch, AbductiveLeap, Linear) with supersedes
- 2 renames with supersedes (SolverRoot→RootSolver, CognitiveSolver→PolymorphicSolver)
- Five-surface Solver Contract now fully patternized: Manifest→Card,
  Execute→PolymorphicSolver, Consult→SocraticLoop, Verify→Validate,
  Feedback→PerformanceSignal+FailureTrace+ReceptivityGate
- PURE framework separates general cognitive judges (Parsimony/Novelty/
  Realizable/Expansive) from the viability-evaluation protocol that
  composes them; variable-depth made definitional
- Layer-assignment principle formalized (§3.21.7): mechanism-cognition-
  sufficiency distinguishes Mind from Society; 14 patterns relocated
  Society→Mind under the refined rule (MVR, FractalIntelligence,
  RootSolver, EthicalReasoningProtocol, MetaProtocols, CommitmentDevice,
  ProblemFramer, LocalizedLearning, CapacityPressure, CiteBack,
  CurriculumReplay, HackDetect, LivedProof, WorldReversible; Realizable
  and Expansive also moved in earlier sub-wave)

Final state: 444 patterns, vocabulary root
sema:vocab#mh:SHA-256:747a1eaf8451a0921df94bb9198b23dd83d527cf1ab23ad472feb74aed4e6001
All 444 hashes valid, 0 cycles, Rule G strict and not violated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- philosophy.md §3.1: the mechanism-sufficiency test that decides which
  layer a pattern belongs in. Physics = obtains regardless of author;
  Infrastructure = authored but requires no cognition; Mind = cognition
  suffices (single party); Society = ≥2 independent parties required
  by the mechanism itself (not just by application context).
- audits/2026-04-17/layer-assignment.md: all 444 patterns grouped by
  current layer, handles only — for visual scan of misplacements.
- Clarifies the mechanism-vs-deployment distinction: adversarial
  vulnerability is compositional (harden with Society-layer guards),
  not a reason to re-layer the vulnerable pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gemini's Round 6 review flagged three patterns that survived my Society
sweep under the agent-count principle:
- EmpathySim (Society/Economics → Mind/Strategy) — theory-of-mind
  simulation is one mind imagining another; N=1.
- DogfoodFirst (Society/Economics → Mind/Strategy) — creator is the
  user; self-validation is single-agent.
- SourceEvaluate (Society/Protocols → Mind/Inference) — one agent
  judges a source's credibility; internal cognitive act.

Also regenerates audits/2026-04-17/layer-assignment.md with one-line
mechanism-sufficiency reasoning for every one of the 444 patterns,
grouped by proposed layer. 24 additional proposed moves marked with
`~` — mostly Physics→Infrastructure (authored mechanisms that were
miscategorized as substrate), plus a handful of Mind↔Infra and
Society↔Infra corrections.

Library state: 444 patterns, vocabulary root unchanged
(sema:vocab#mh:SHA-256:747a1eaf8451a0921df94bb9198b23dd83d527cf1ab23ad472feb74aed4e6001)
since layer is unhashed metadata. All 444 hashes valid.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…5 pending moves

- §3.21.10: the layer rule sharpened from "agent count" to
  "mechanism sufficiency" and lifted into docs/core/philosophy.md §3.1.
  Articulates the mechanism-vs-deployment distinction (MVR is
  Mind despite adversarial exposure in multi-agent deployment).
- §3.21.11: applies Gemini R6's three additional Society → Mind
  moves (EmpathySim, DogfoodFirst, SourceEvaluate).
- §3.21.12: records the full-sweep annotation in
  audits/2026-04-17/layer-assignment.md and the 25 additional
  proposed moves (staged for Round 7 review), including the
  TriGate correction: authored three-state gate primitive, not
  Society — belongs in Infrastructure with Gate.

Mind 178 → 181, Society 116 → 113 after the R6 follow-up moves.
Library root unchanged (unhashed metadata).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
On inspection under the user's challenge:
- Protocol is the spec (rules + formats) — a Noun artifact. One agent
  can read it without any counterparty. HTTP, TLS, OAuth, MCP, bus
  protocols are all specific instances of the general spec pattern.
  Stays Infrastructure/Data Structures.
- OathBind is cryptographic self-binding against a code/substrate-
  enforced ruleset. N=1 suffices (Ulysses pact at protocol level).
  Stays Infrastructure/Verification.

Both were drift-to-Society by "between agents" framing — the same
trap Gemini warned about (application context ≠ mechanism). Updated
audit §3.21.12 to document the retractions and the drift-trap they
exemplify.

Proposed moves: 25 → 23.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
User challenge: 'Physics are components. Basically nouns.' Earlier
tight definition ("obtains regardless of any author") was too strict
— would evict legitimate foundational components (Gate, Heartbeat,
Throttle, Branch, Route, Cooldown, Hysteresis) that are authored but
act as building-block Nouns.

Correction now in docs/core/philosophy.md §3.1:
- Layer decided by two axes: scope (primary) + shape (secondary).
- Physics = bottom of the compose-with stack, whether substrate-given
  or authored-but-foundational. Role-based definition.
- Physics Nouns live in Physics; Verbs that use substrate components
  live in Infrastructure/Primitives.
- Added heuristic: "Is this a compose-with Noun or a built-from Verb?"

Impact on the proposed moves:
- 7 Physics-Nouns retracted (Branch, Gate, Route, Heartbeat, Cooldown,
  Throttle, Hysteresis) — they stay in Physics as components.
- Only 6 Physics-Verbs (Sign, Compensate, StateAudit, ReAttempt,
  EntropyPump, Compress) still proposed for Infrastructure/Primitives.
- Proposed moves: 23 → 16.
- Projected Physics: 23 → 17 (only 6 Verbs out + StateLock to Society).

Audit §3.21.12 updated to document the refinement + retraction.
Annotated layer-assignment.md regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Flipped back from Physics-as-Nouns (too loose) to strict substrate
(things that obtain regardless of any author). Gemini R7 correctly
pushed this — "authored foundational primitives" (Gate, Heartbeat,
Throttle, Branch, Route, Cooldown, Hysteresis) belong in
Infrastructure/Primitives, not Physics.

Added the protocol-consistency test for when to mint Physics:
"mint only when agent protocols require cryptographically shared
meaning." Regular English suffices for locally-varying concepts;
content-addressing earns its cost when shared meaning is
load-bearing. Future Physics candidates (Gradient, Equilibrium,
Conservation, Distance, ...) listed as candidates, not pre-mints
— MintWhenFriction governs.

Four speculative Physics mints (Gradient/Equilibrium/Conservation/
Distance) attempted and reverted on user challenge — regular English
handles them fine, no existing pattern needs to reference them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ured thinking

User insight: the value of minting a pattern isn't only protocol
consistency (cryptographically shared meaning across agents). It is
also the cognitive discipline of specifying a mechanism — forcing
precision about a concept that English uses loosely. Writing
"Noise#<hash>" with an invariant-bearing mechanism makes you confront
what you mean in a way "there's noise in the signal" does not.

philosophy.md §3.1 now names both criteria as independently
sufficient:

1. Protocol consistency — Lock, CausalBarrier: agents must agree on
   exact semantics for distributed coordination to work.
2. Structured thinking — Decay, Noise, Dampen, Entropy, Causation:
   the pattern sharpens thinking wherever other patterns invoke the
   concept, even without a protocol pressure.

This also justifies the existing Physics patterns that don't have
strong protocol-consistency cases — they pass the structured-thinking
test. English suffices only when NEITHER criterion is met.

Future Physics candidates still subject to MintWhenFriction — mint
when either criterion binds to a concrete case, not speculatively.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…iterion

Gradient, Equilibrium, Conservation, Distance, PhaseTransition,
Attractor, MutualInformation, Measurement — all passing criterion
2 (structured thinking) per philosophy.md §3.1. Each forces precision
about a substrate concept that English otherwise uses loosely:

- Gradient: directional rate of change with three invariants
  (existence/direction/magnitude) — hill-climbing, attention flow.
- Equilibrium: stationary state with stability classification —
  dynamical systems signal "settled."
- Conservation: invariant quantity preserved under closed-system
  transformations — distinct from authored Budget constraints.
- Distance: metric-axiom function — non-negativity, identity of
  indiscernibles, symmetry, triangle inequality.
- PhaseTransition: threshold-triggered qualitative reorganization —
  not to be confused with authored StateTransition.
- Attractor: basin + convergence + confinement — substrate of
  dynamical settling patterns.
- MutualInformation: substrate info-theoretic shared-entropy measure,
  distinct from Correlation (linear only).
- Measurement: observer-effect primitive — distinct from cognitive
  Observe; substrate fact that observation perturbs.

All Ring 0, Tier 1. Zero incoming edges at mint; downstream patterns
will reference these as concrete friction emerges. Each has tight
mathematical/physical invariants that do not evolve — which is
exactly what justifies pinning them.

Library: 444 → 452 patterns. Root:
sema:vocab#mh:SHA-256:9883ef9ca48c4b7a0df23cfff63f07c6c0c594ebf5be8f9732a2e0ea8539d00b
All hashes valid, 0 cycles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ints

Captures this round's process:
- Gemini R7 pushback on Physics-as-Nouns (docs/core/philosophy.md §3.1
  reverted to strict substrate).
- Minting criterion refined to two independently-sufficient tests:
  protocol consistency OR structured thinking.
- 8 Physics primitives minted under the structured-thinking criterion
  (Gradient, Equilibrium, Conservation, Distance, PhaseTransition,
  Attractor, MutualInformation, Measurement).
- Projected final distribution after the 29 pending moves + 8 new
  mints: Physics 17, Infrastructure 151, Mind 178, Society 106.

The 8 new mints queued for Gemini R8 structured-thinking-bar review;
the 29 moves are pre-cleared from R7.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Existing patterns that invoked these concepts in English are now
template-referencing the minted patterns:

- Conservation (6 callers): Budget (Allocated + Remaining = Total),
  ChunkMerge (Information Conservation), Mutex (Conservation of Totem),
  Nucleate (Conservation of Mass), OntologyAdapt (Conservation of Data),
  FractalIntelligence (Memory Conservation).
- Gradient (4 callers): Optimize (Gradient Descent), SurprisalUpdate
  (gradient updates), Judge (gradients of quality), MemeticSeed
  (Subsidy Gradient).
- Distance (2 callers): ConceptBlend (threshold distance between
  concepts), DriftWatch (Distance(Current, Baseline)).
- PhaseTransition (2 callers): Nucleate (Phase transition complete),
  Crystallize (gloss: Phase transition from implicit resonance).
- Equilibrium (2 callers): EntropyPump (productive equilibria),
  plus Attractor (references equilibrium as a type of attractor).

Attractor, MutualInformation, Measurement retain 0 incoming — they
stand under the structured-thinking criterion alone until a concrete
pattern naturally invokes them. Per docs/core/philosophy.md §3.1, this
is acceptable: mint value accrues from the mechanism-specification,
not only from callers.

Total new edges: 16. Five of the 8 new Physics patterns earned callers
via this wiring pass.

Library: 452 patterns, root unchanged (template/ref updates don't
recompute unhashed handles, and the re-wired patterns rehashed with
new dependency sets cascade only into their own descendants).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gemini R8 refinements to the 8 new Physics mints:
- Gradient: "metric space" → "differentiable space" (metric spaces
  lack differential structure required for gradients).
- Measurement: dropped meta-invariant ("distinct from Observe" — that
  is ontology commentary, not a physical property), replaced with
  Irreversibility (information-extraction is not undoable).
- Attractor: zero-hash placeholder for equilibrium ref resolved to
  actual Equilibrium hash.

29 pre-cleared layer moves applied:

  13 Physics → Infrastructure/Primitives (authored primitives, not
     substrate): Branch, Gate, Route, Heartbeat, Cooldown, Throttle,
     Hysteresis, Compensate, Compress, EntropyPump, ReAttempt, Sign,
     StateAudit.

  1 Physics → Society/Protocols: StateLock (N=2 by mechanism).

  4 Mind → Infrastructure: Cache (keyed lookup — Data Structures),
     Rank (deterministic sort — Primitives), Decision (committed-
     choice artifact — Data Structures), Compare (CPU-instruction
     level — Primitives per Gemini R7).

  1 Infrastructure → Mind: Critique (qualitative assessment requires
     semantic understanding, not schema-matching — Gemini R7 revert
     of §3.11 move).

  1 Mind → Society: Stigmergy (marker + reader roles structurally
     distinct).

  8 Society → Infrastructure/Data Structures (Spec/Manifest cascade
     per Gemini R7): FrameSpec, ProtoPack, AcceptSpec,
     ExecutionManifest, SolverManifest, RolloutManifest, StyleSpec;
     plus TriGate → Primitives (three-state filter, N=1).

  1 Society → Mind: ManifestPlanning (cognitive planning phase).

Data-schema additions on Data-Structures-inbound patterns (Rule J):
Cache, Decision, FrameSpec, ExecutionManifest, SolverManifest,
RolloutManifest, StyleSpec each gained a minimal typed schema.

Rule G fix: Hysteresis (now Infra) had composes_with Dampen
(Physics). Since Infrastructure is Layer 0 (most fundamental) and
Physics Layer 1 above it, composes_with from Infra → Physics
violates gravity. Demoted to `references` (exempt per spec).

Final distribution matches Gemini R8 projection:
  Physics 17 (9 substrate + 8 new), Infrastructure 151,
  Mind 178, Society 106. Total 452.

Vocabulary root:
sema:vocab#mh:SHA-256:ba300539c85805ac044f7f99de0cefd97acbcaff6215293274f9bc6f846d8e23

All 452 hashes valid; 0 cycles; Rule G strict and unviolated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…HANGELOG added

- scripts/calculate_graph_stats.py now tokenizes patterns via tiktoken
  (cl100k_base) and emits per-pattern + per-layer compression macros.
  Replaces hardcoded comp_refs/comp_fulls literals.
- docs/information/audit.md regenerated.
- CHANGELOG.md (new): vocabulary-level change log following the
  foundation audit — additions, renames, relocations, mechanism rewrites,
  hash cascade note, governance updates, compatibility notes.
Sidecar (data/design_critique.json) holds motivation/tensions/tradeoffs/
critique/family-discussion per pattern; it is the single editable source
for design commentary and is keyed by handle. Generator script
(scripts/generate_design_manual.py) renders sidecar + data/vocabulary/
into docs/manuals/vocabulary-design.md. One-time migration script
(scripts/migrate_design_commentary.py) consolidated
audits/2026-04-17/layer-assignment.md and
audits/2026-04-17/2026-04-broad-use-analysis.md into the sidecar;
re-running it preserves any hand-edited analytical fields.

Covers all 452 patterns. Manual is 25,779 lines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
50 surgical fixes addressing internal defects found by systematic scans,
applied via sema apply + export so the DB, JSONs, and manual are consistent.
All fixes preserve pattern scope; no base invariants softened (descendant
territory stays with descendants).

Invariant dedup / ambiguity (5): ConfidenceCalibrate (post-calibration
disambiguation), Throttle (redundant rate-limit), HypothesisLadder (duplicate
Falsifiability), PreMortem (2 duplicate pairs), UptakeAsGround (operational +
Wittgensteinian merge).

Failure-mode dedup (4): OsmoticFilter, TieredAccess, Rally (8→6), Resonate
(9→6).

Failure-mode restructure (1): DriftWatch (mitigations folded into parent
failures, 8→4).

Jammed failure modes split (3): Proprioception, CapacityPressure,
CounterfactualAnchor.

Jammed preconditions/postconditions split (10): BackwardChain, BayesUpdate,
Compose, Decompose, Delegate, Mutex, OntologyHandshake, Quorum, Satisfice,
Eliminate (also promoted miscategorized precondition to real invariants —
Monotonic Reduction, Evidence-Required Exclusion).

Capitalization / formatting (5): Backoff, Context, ExperienceSharding,
Reframe, SemanticTabu.

Broken fragment (1): Warmup ('(e.g. cache)' split across entries reassembled).

Nested list header (1): Mutex ('Failure modes: (1)...' with numbered sub-items
flattened to atomic entries).

Bare-label invariants promoted (2): BoundedTask (Budget Enclosure / Quality
Gate now have statements), ConceptAnchor (redundant 'Immutable Reference'
removed).

FeedbackSignal invariants (1): bare adjectives 'Targeted' / 'Structured'
made specific, tied to data_schema.

Template-leak in gloss (2): Crystallize ({{phase_transition}} → plain text,
orphan dep removed), Decay ({{state}} → plain text).

SacrificialProbe (1): semicolon-jammed failure modes split.

_meta.related refs to full format (6): Entropy, Experiment, Falsification,
RecursionDive (also: SolutionNode → SolverNode rename followed), Snapshot,
Vector.

derived_from fixes (10): AdversarialProof (bare handle → full sema_id),
BoundedTask (stale), ManifestPlanning (legacy stub), OptimisticSolver
(stale), PolymorphicSolver (stale), RequestFraming (legacy stub), RigorousSolver
(all-zeros placeholder fixed), RolloutWatch (legacy stub), FractalIntelligence
(predecessor RecursiveIntelligence no longer exists — removed), RealizationProtocol
(predecessor CreationProtocol no longer exists — removed).

Also: generator script (scripts/generate_design_manual.py) is now staging-aware
— prefers data/staging/<Handle>.json when present, falls back to
data/vocabulary/. Matches the editing workflow (staging = WIP, vocabulary =
post-apply canonical).

Design commentary (data/design_critique.json) updated for every fix per the
change+commentary discipline: tense-consistent with the applied state.

Bulk of the vocabulary diff (377 JSONs) is the dependency-ref cascade-refresh
that export performs — the 940 previously-stale dep refs across 331 patterns
are now all pointing at current hashes. This is the side effect of running
apply-then-export on the full library; no hand edits to those files.

Verified: 58/58 structural checks pass, 0 regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…face

The one-time foundation audit served its purpose: its content was
consolidated into data/design_critique.json (via migrate_design_commentary.py)
and now renders as the per-pattern Design blocks in the manual. With the
manual + sidecar as the editable review surface, the raw audit markdown is
historical and no longer drives any workflow.

Also removed:
- scripts/migrate_design_commentary.py — obsolete one-shot migration
  whose source files no longer exist.
- The generator's doctext reference to `audits/` and the migration script.
- A stale `.DS_Store` sitting in audits/.

Manual regenerated to reflect the governing-principles text update.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
For every pattern whose current sema_id differs from the sema_id that
ships in the live pip-installed db (taxonomy.db from the last public
release), add the live sema_id to _meta.supersedes. This is what the
agents installed on user machines currently have — the targets
`sema pull`'s supersession cleanup needs to match against so users get
a clean upgrade.

Script: /tmp/populate_supersedes.py — reads sema_ids from the live db,
matches by handle, appends (idempotently) to each staging pattern's
supersedes list, preserves any existing entries (e.g., 0.1.28 rename
supersessions like Chain→Linear, Route→Switch, Abduction→AbductiveLeap).

Breakdown of current state:
  358 patterns — edited since v0.1.27, now carry the old sema_id in
       supersedes (main batch).
  2 patterns — rename-only inheritors (PolymorphicSolver, RootSolver),
       retain their pre-existing rename supersedes (CognitiveSolver,
       SolverRoot); no additional entry needed since these handles
       are new since v0.1.27.
  63 patterns — unchanged since v0.1.27 (sema_id matches live exactly);
       no supersede entry needed.
  31 patterns — new since v0.1.27 (not in live db); no supersede needed.
  Total: 452.

Note on hashing: _meta is excluded from SEMANTIC_FIELDS in
src/sema/core/hashing.py, so adding supersedes is cost-free —
sema_ids do not change. The bulk of the 379-file diff is the
re-export cascade, not hash churn.

Workflow: copy vocab → staging → run populate_supersedes.py →
sema apply --add staging → export_sema.py → clear staging → regen
manual.

Manual regenerated; renders the supersedes lists inline in each
pattern's entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rsedes

Covers the full 0.1.28 scope beyond the initial foundation-audit draft:
the pull-loop closure (sema_pull MCP tool, --preserve-superseded, orphan
guard), the hash canonicalization bug fix, the 50 post-audit structural
fixes, the full-library supersedes population against the v0.1.27 live
db (360 patterns), and the design manual + sidecar + staging-aware
generator as the review surface. Vocabulary root updated to reflect the
current taxonomy.db; migration transcript now matches actual pull output
(31 new, 368 updated, 53 unchanged, 5 superseded-removed, 1 orphan).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bundles the release-prep work done this session:

- Bump 0.1.28 → 0.2.0 across CHANGELOG, pyproject, and doc references
  (SKILL.md, cli.md, authoring.md, lifecycle.md). The scope of this
  release — behavioral breaks on sema pull defaults, MCP mint default
  flip, hash cascade on ~399/452 patterns — makes a minor bump the
  right semver signal, not a patch.

- Fix CATEGORY node collapse across layers (graph_store.py). The
  lookup in _add_or_update_pattern matched by text alone, so
  Physics/Primitives patterns reused the existing Infrastructure/
  Primitives node and bolted a second IN_LAYER edge onto it — producing
  12 nodes and 13 IN_LAYER edges for 13 distinct (layer, category)
  combos. Composite-key lookup now matches both text AND an IN_LAYER
  edge to the target layer; clean rebuild yields 13 nodes, 13 edges.
  Pattern sema_ids unaffected (category/layer live in _meta, not hashed).

- Doc additions: manual-driven refinement loop in authoring.md
  (7-step loop: read manual → edit staging → update sidecar →
  preview → apply → regenerate → verify). Author-side supersedes
  rules in lifecycle.md (every hash-changing edit appends prior
  release sema_id to _meta.supersedes; apply doesn't enforce —
  discipline + changelog review cover the gap for now).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Populates _meta.supersedes as an append-only chain spanning two prior
public releases (v0.1.18 and v0.1.27), not just the most recent. A
consumer pinned to either release gets clean upgrade behavior on
sema pull:
  - 5 superseded_removed (all rename-source handles)
  - 1 upstream_removed (Group, intentionally moved to experimental shelf)
  - 0 orphans

Rename-aware fix: PolymorphicSolver and RootSolver now carry BOTH the
v0.1.27 and v0.1.18 sema_ids of their absorbed predecessor handles
(CognitiveSolver, SolverRoot), which changed between those tags. Without
the v0.1.18 entries, a v0.1.18-pinned consumer would have those handles
orphaned on pull instead of redirected.

Intermediate v0.1.23 contributed zero new entries — its sema_ids
coincide with either v0.1.18 or v0.1.27 for every pattern.

Chain-length distribution: 88 patterns 0-entry, 263 one-entry,
101 two-entry. Max length: 2.

Supersedes is excluded from SEMANTIC_FIELDS (hashing.py), so populating
the chain does not cascade new sema_ids. Round-trip rebuild --check
confirms hash stability.

Note: discovered and worked around a bug in `python -m sema.cli.main apply`
that strips extra list entries in _meta.supersedes. Direct
mint_pattern() calls preserve them correctly, so the backfill used the
programmatic path. Root cause of the CLI strip is still unknown and will
be investigated in a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two compounding bugs caused RELATED_TO edges to be severely
under-populated. Before this fix, the DB carried 24-34 edges for ~117
refs in vocabulary; after, 105 edges — matching the full set of
resolvable refs.

1. Prefix-stripping: `item.split("#")[0]` for a full-format ref like
   "sema:Foo#mh:..." yields "sema:Foo", not "Foo". Lookup silently
   fails. Fixed via extract_handle_from_ref.

2. Topological-order race: apply sorts by hard deps; _meta.related is
   soft and doesn't participate. If pattern A declares `related: [B]`
   and B is minted after A, A's edge-creation check finds no B in
   _handle_to_id and skips. Fixed by adding
   GraphStore.sweep_related_edges() — a post-apply second pass —
   and calling it at the end of apply_changes.

12 refs remain unedged because they point to handles no longer on
the default shelf (ChaosDrift, GhostTrail, etc. — experimental-only
or truly retired). Silent skip is correct for those.

Pattern sema_ids unaffected: RELATED_TO is metadata, not hashed.
Vocabulary JSON reshuffling is an unrelated export-nondeterminism
issue; sema_ids verified stable via rebuild --check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-commit changelog-gate. Triggers only when pyproject.toml is
staged AND the `version = ...` line changed. Fails the commit if
CHANGELOG.md isn't also staged.

Rationale: the changelog is the release contract for downstream
consumers who pin. Letting a version bump ship without a CHANGELOG
entry guarantees drift — the hook closes that loop mechanically.

Logic lives in scripts/hooks/changelog_gate.sh (inline YAML couldn't
handle the nested quoting). Tested: version-only diff → exit 1 with
actionable message; version + CHANGELOG staged → exit 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
NetworkX successors() iteration order isn't stable across fresh graph
loads. Each rebuild shuffled the order of keys in get_dependencies_from_edges's
output, which flowed through to the exported vocabulary JSON files —
so every re-export produced a diff against git HEAD even though the
underlying data was bit-identical. Cosmetic, not a correctness issue
(hashing already sorts internally), but it made the diff noisy and
masked real changes in reviews.

Fix: sort both the outer category keys and the inner alias keys before
returning. Two consecutive rebuilds now produce identical vocabulary/
output.

No sema_id changes: dep key order didn't affect hashing (generate_sema_hash
sorts internally), and _meta.supersedes isn't touched.

Also documented (in session context, not code): the "CLI apply strips
supersedes" phantom from earlier investigation. Root cause was that
~/.config/sema/active_db pointed at a leftover test DB from an earlier
pull-test, so `sema apply` was writing supersedes correctly to that DB
while export/verification read from data/taxonomy.db. Not a code bug —
an operational trap. `sema use data/taxonomy.db` fixes the active-DB
pointer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two small additions addressing "how does an agent know the state of
the vocabulary it just opened?" and "when should an agent pull?":

1. Banner at DB-loading entry points (sema use / apply / pull, MCP
   startup). Single line:
       📚 vocabulary: 452 patterns, root 39ca671a (data/taxonomy.db)
   Root hash is the cryptographic fingerprint — two DBs with the same
   pattern sema_ids produce the same root. Changes on any pattern edit.
   Surfaces at-a-glance "which state am I on" and catches the
   active-DB-misconfiguration trap (wrong path → different root than
   expected).
   Version slot (stamped_version) left as None today; when we plumb
   a stamp through on apply, it appends inline without breaking the
   layout:  "..., root 39ca671a, v0.2.0 (...)".
   MCP prints to stderr so it doesn't pollute the stdio protocol.

2. Skill + MCP-instructions update: tell agents sema_pull is for
   updating, not for routine orientation. Do NOT pull reflexively at
   session start — pull cleans up superseded handles by default, which
   can remove patterns the user is intentionally pinned to. Reserve
   pull for: handshake HALT, user mentions upgrade, user asks to sync.

Non-goals addressed by the work (kept out of scope deliberately):
proactive drift alarms, session-start health probes, structured
handshake-HALT guidance. Reactive signals + the banner are enough at
0.2.0. Revisit if a real user reports "stuck on old vocabulary."

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The banner is for verification and cryptographic identity, not just
"glance." A stub was always a teaser — to actually compare vocab
state across machines or reference the exact root in a bug report,
you needed the full 64 chars. Now the banner surfaces the full root
on its own line, with count + path on a second indented line:

    📚 sema:vocab#mh:SHA-256:39ca671a4dcb3075855cb293380d1796105e2eca0de49b0537279b798b675ee6
       452 patterns (data/taxonomy.db)

Two-line instead of one, but each line serves a distinct job. Root
stays reparseable (full sema_ref format), context stays scannable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Re-applies all 452 patterns and exports data/vocabulary/*.json with the
alphabetical sorting now enforced in get_dependencies_from_edges (fixed
in b7caee0). Also rebuilds data/taxonomy.db from the JSON sources to
ensure DB ↔ export consistency.

All 287 vocabulary JSON changes are pure key-ordering reshuffles
(e.g. composes_with before references, inner alias keys alphabetized).
Hash-stable: rebuild --check passes, sema_ids unchanged.

Also gitignore .claude/ (Claude Code local session config).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pure binary-layout refresh: `rebuild_vocabulary.py --replace` creates
a fresh empty DB and re-applies all 452 patterns. Vocabulary root is
unchanged (39ca671a...), sema_ids unchanged, rebuild --check passes.

Only SQLite page layout + UUID regeneration. No semantic change.
Committed so the tracked DB matches what any clean rebuild produces.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements the pull-loop closure documented in the 0.2.0 CHANGELOG.

1. Supersession cleanup in update_db: for each upstream pattern's
   _meta.supersedes list, find local patterns whose sema_id matches
   and remove them. Runs BEFORE cascade (cascade rewrites user
   sema_ids, so doing cleanup after would miss dependents).

2. Orphan guard: if a user-only local pattern still depends on the
   soon-to-be-removed handle, keep the old handle and report what's
   blocking plus three action options.

3. Orphan sub-node notice: pattern deletion leaves leaf sub-nodes
   behind. Count the delta and tell the user; don't auto-GC.

New flag: sema pull --preserve-superseded.

6 new tests. Verified on a copy of experimental.db end-to-end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Primary consumer of pull output is an agent that may want to act on
every name in the report. Silent truncation at 10 loses information;
replace with full lists in all categories.

Also list the actual texts of orphan INVARIANT / PRECONDITION /
POSTCONDITION nodes left behind by supersession cleanup, so the
caller knows what's dangling without running a separate SQL query.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collapses layer + category into a single ordered list. Rationale:
categories are sub-scopes of layers, not flat labels. Physics/Primitives
and Infrastructure/Primitives share a leaf name but are distinct; the
old representation forced them onto one CATEGORY node with two IN_LAYER
edges (topology lie). The list form makes scope explicit and supports
deeper hierarchies (Society/Governance/Voting) without schema changes.

Schema (Pydantic, enforced on sema apply):
  _meta.path: list[str], length >= 1
  path[0] in {Physics, Infrastructure, Mind, Society}
  tuple(path) in VALID_PATHS
  No '/' in segments, no '/' in handle
  ring in {0,1,2}, tier in {0,1,2,3} (stricter Literal enforcement)

Graph:
  LAYER + CATEGORY node types -> TAXONOMY_PATH
  IN_LAYER + IN_CATEGORY edges -> IN_PATH (+ PARENT_PATH for hierarchy)
  Fully qualified text, no more same-named duplicates.

sema_ids unaffected: _meta is excluded from SEMANTIC_FIELDS. Verified
via rebuild --check against all 452 patterns — zero diff.

New CLI: sema categorize <handle> --path A/B atomically rewires.
Migration: scripts/migrate_taxonomy_to_path.py rewrites pattern JSONs
(idempotent, one-shot).

Backwards compat: sema_layer / sema_category top-level fields still
emitted by export (derived) for one deprecation cycle.

Tests: 233/233 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hwesterb and others added 4 commits April 18, 2026 13:44
Frontend changes matching the 0.2.0 schema migration. Breaks cleanly
into six pieces:

1. Types + default filters
   - Added TAXONOMY_PATH node type, IN_PATH + PARENT_PATH edge types.
   - Legacy LAYER / CATEGORY / IN_LAYER / IN_CATEGORY types preserved
     in the union for pre-0.2.0 DBs but removed from the default UI
     filter chips (empty on migrated DBs, confusing to expose).
   - REFERENCES now on by default — primitives are the most-referenced
     patterns in the library; hiding 1,208 edges was making the graph
     read as sparse when it is the opposite.
   - Persisted filter state versioned (v4) so stale selections from
     earlier sessions don't silently hide the new types.

2. Graph rendering (GraphCanvas.tsx)
   - TAXONOMY_PATH nodes rendered neutral grey to read as structural
     scaffolding vs. pattern content.
   - Node size scales with path depth (root layers larger than leaves).
   - Hover label on taxonomy nodes shows leaf segment only
     ("Primitives") — parent layer is already implicit in graph
     position.
   - Layer + category filters now also match on path[0] / path[-1]
     in TAXONOMY_PATH metadata.

3. Right-sidebar detail panel (DetailsPanel.tsx)
   - New TaxonomyPathDetails component renders on TAXONOMY_PATH click:
     breadcrumb header, depth label, list of patterns under the path
     prefix (clickable, flies to pattern in graph).
   - UI label reads "Taxonomy" everywhere; the TAXONOMY_PATH
     identifier stays internal.

4. Pattern cards on home page (HomePage.tsx)
   - Two-pill display: layer (colored) + subcategory (neutral grey).
     Previously only the layer was shown, so users had to click into
     every card to see whether something lived in Data Structures vs
     Primitives vs Verification.

5. Top bar (TopBar.tsx + DbSwitcher.tsx)
   - Node-type filter uses NODE_TYPE_LABEL for display names
     ("Taxonomy" instead of "TAXONOMY_PATH").
   - DB switcher hidden when there are fewer than two databases to
     choose between. Trailing divider hidden with it so the top bar
     doesn't start with a dangling vertical line.

6. Bundled static assets refreshed
   - index.html references rebuilt manifest. Generated JS/CSS is
     gitignored; only the HTML entry point and .gitkeep are tracked.

Data layer already migrated in f2300ea — this is the UI catching up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When a v0.1.27 consumer pulls to 0.2.0, their upstream-retained
user-only patterns (e.g. Group) still carry the old _meta.layer +
_meta.category schema — pull doesn't rewrite user content. Next
`sema apply` would reject them against the strict path-based schema
with a cryptic Pydantic error.

Post-pull sweep now scans retained user patterns, flags any missing
_meta.path while carrying legacy layer/category, and points the user
at scripts/migrate_taxonomy_to_path.py. Notify, don't auto-migrate —
user owns those patterns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI failed on the 'Generated docs are up-to-date' check — the audit and
vocabulary-info pages regenerated with current content differed from
the committed versions. Ran scripts/vocabulary_merkle_root.py +
scripts/audit/run_all_audits.py and committed the output.

CHANGELOG corrections:
- Remove claims about a `sema_pull` MCP tool that was documented but
  never implemented. Pull is available via the `sema pull` CLI; the
  MCP wrapper didn't land in 0.2.0 (test file exists in an unstaged
  directory but imports a symbol that doesn't exist in server.py).
  Removing three false references to avoid shipping docs that
  over-promise.
- Remove the `SEMA_DISABLE_PULL` env-var opt-out (was tied to the
  non-existent tool).
- Add the post-pull warning for stale user-owned `_meta` and the
  orphan-sub-node notice — both implemented, both user-visible,
  both worth documenting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ran scripts/update_doc_refs.py to update 417 stale pattern references
across 12 files to match 0.2.0 sema_ids. CI's 'Doc hash references are
current' gate was failing because README.md, install.md, docs/, skills/,
stdlib.py, and mcp/server.py all still quoted v0.1.27 stubs (e.g.
StateLock#774b → StateLock#5602, Consensus#7216 → Consensus#376f).

Mechanical auto-update — no prose or behavior changes, only the stub
portion of inline pattern references.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hwesterb hwesterb merged commit 318963c into main Apr 18, 2026
5 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.

1 participant