{
  "title": "Changelog",
  "site": "anthroposophy.ai",
  "url": "https://anthroposophy.ai/changelog",
  "generated_at": "2026-05-23T15:30:00Z",
  "format": "Keep a Changelog 1.1.0",
  "versioning": "Semantic Versioning 2.0.0",
  "versions": [
    {
      "version": "1.1.2",
      "date": "2026-05-23",
      "sections": {
        "Research workflows": [
          "**The Sources corpus is curated by Steiner-engagement, not by canon** — these are the foundational texts the GA itself takes up. A few workflows it makes practical:",
          "**From a Steiner lecture to its source text.** `find_source_chapters_for_ga_locus(\"GA 142, 1912-12-28\")` returns the Sources chapters the curator has linked to that lecture (Bhagavad Gita Discourses, Mahabharata Parvas, the Pauline epistles as the GA 142 counterpart text). `fetch_source_chapter` then quotes the verses verbatim.",
          "**From a foundational text to Steiner's treatment of it.** `fetch_source_summary` on (say) the Kaṭha Upanishad or *De Anima* Book II names the verified GA loci where Steiner engages it; `fetch_passage` returns his actual words.",
          "**Cross-corpus surveys in a single call.** `search_anthroposophy(query=..., corpus=\"all\")` fans GA + Free Man Creator (FMC) + Sources together, distinguishing hits by `[ga] / [fmc] / [sources]` tags with per-corpus totals.",
          "**Honest gap-detection.** When the curator has examined a chapter and Steiner did *not* engage it, `steiner_status: \"not_engaged\"` is the explicit sentinel — the data says so rather than inviting a fabricated bridge. Aristotle's *De Anima*, for example, carries this flag despite the structural temptations to read his hylomorphic soul-account into the threefold-body schema.",
          "**Stream-filtered comparative work.** `search_sources(stream=\"indian\")` scopes to Vedic / Upanishadic / Gita / Mahabharata material; `stream=\"greco-christian\"` to Patrologia + Aristotle + Aquinas + Hermetic Corpus; `stream=\"western-european\"` to the Beguine + Rhineland + Theosophical + Goethean strands.",
          "**Curator's cross-tradition congruences as named syntheses.** Each summary surfaces the FMC curator's explicit cross-tradition observations (e.g. *De Anima*'s tripartite soul ↔ Vedanta's *pancha-kosha* ↔ Plotinus's nous-triad ↔ Kabbalah's *nefesh / ruach / neshamah*) as paraphrase the curator owns, never as quotes from those traditions.",
          "**Discipline reminder:** only `fetch_source_chapter` is quote-safe (`quote_safe=true`). `fetch_source_summary`, `find_source_chapters_for_ga_locus`, and every `steiner_loci.statement` field are FMC-curatorial paraphrase (`quote_safe=false`) — they capture the verified loci but they never go inside quotation marks."
        ],
        "Added": [
          "`/sources/` corpus integration — Sacred, Inspired and Foundational Texts across 5 wisdom-streams (Indian, Persian, Egyptian-Hebrew, Greco-Christian, Western-European). Vedic scripture, the Greek-philosophical tradition (Aristotle, Plato, Plotinus), Patrologia (Church Fathers), Aquinas (Summa Theologiae + Summa Contra Gentiles), Beguine + Rhineland mysticism, Hermetic Corpus, Rosicrucian Manifestos, Theosophical inheritance (Isis Unveiled, Secret Doctrine, Mahatma Letters), Goethean works.",
          "Tool `search_sources`: full-text search over /sources/ chapters. Filters: `work`, `lang`, `edition`, `stream`, `tradition`, `form`, `year_from`, `year_to`. Returns ranked chapter hits with `chapter_locus`, snippet, curatorial blurb, and `summary_url` (when present) pointing at the FMC-curatorial paraphrase block.",
          "Tool `fetch_source_chapter`: retrieve verbatim chapter text by `chapter_locus` (`<work>[/<subwork>...]/<chapter>`). Returns `text_trust='verbatim'`, `quote_safe=true`, parent breadcrumbs, descriptor subtitle + blurb, and `available_versions[]`. Use to obtain quote-safe text from /sources/.",
          "Tool `fetch_source_summary`: retrieve the FMC-curatorial paraphrase block for a chapter or work — theme, soul-faculty, Steiner engagement (paraphrase + verified GA loci, or the honesty-gap sentinel \"not engaged in the GA corpus\"), cross-tradition congruences. `text_trust='paraphrase'`, `quote_safe=false`. The structural verbatim-vs-paraphrase split that prevents accidental quotation of curator-summary content.",
          "Tool `list_source_works`: discovery — enumerate /sources/ works by `stream`, `tradition`, `form`, `parent_locus`, `top_level_only`, `has_summary`. Returns work_locus, name, tradition, year_approx, chapter_count, word_count, landing_url, summary_url.",
          "Tool `find_source_chapters_for_ga_locus`: reverse cross-reference (sources → GA). Given a GA locus (`GA 142, 1912-12-28`) or volume (`142`), returns which /sources/ chapters cite that lecture, with paraphrase statements. Driven by the `sources_ga_xref` bridge, populated from chapter and work summaries.",
          "`search_anthroposophy` umbrella extended with `corpus='sources'` and `corpus='all'`. `'all'` fans GA + FMC + sources in a single call with round-robin interleave; `'both'` remains the back-compat default (GA + FMC). Response carries `sources_total` alongside `ga_total` and `fmc_total`.",
          "Tool `fetch_fmc_schema_image`: returns inline ImageContent for FMC schemas, mirror-first with upstream fallback. Resolves the image-fetch gap where MCP clients could not follow MediaWiki redirects to the upstream JPEGs."
        ],
        "Changed": [
          "Top-of-document **Quotation discipline (read first)** block in server `instructions` extended with a /sources/ paragraph. `fetch_source_chapter` returns quote-safe text (`text_trust='verbatim'`); `fetch_source_summary` returns FMC-curatorial paraphrase (`text_trust='paraphrase'`, `quote_safe=false`) — never quote, even when paraphrasing is tight. Each `steiner_loci` entry inside a summary names a verified GA locus retrievable via `fetch_passage`; the surrounding statement is the curator's paraphrase, not Steiner's words. `find_source_chapters_for_ga_locus` returns paraphrase as well.",
          "`search_anthroposophy.corpus` enum: `['ga','fmc','both']` → `['ga','fmc','sources','both','all']`. Tool description acknowledges sources as a third corpus alongside GA and FMC.",
          "MCP `tools/list` returns 14 tools (4 GA + 5 FMC + 5 sources).",
          "MCP server `version` and `SERVER_VERSION` bumped to `1.1.2`. Both were stale prior to this release (`1.1.0` and `1.0.0` respectively)."
        ],
        "Fixed": [
          "`scripts/deploy_site.sh` parity probe: added retry/backoff (8 attempts, 0.5s × attempt#) to tolerate uvicorn's multi-worker spawn window. `systemctl is-active` returned `active` before all workers had bound to port 8044, causing a false rollback on the 2026-05-22 deploy.",
          "`v2/server/main.py`: removed a stale `import sources_shared` that crashed all 4 anthro-api workers with `ModuleNotFoundError` on startup (the module is on the MCP service's path, not the API service's). The /sources/ REST endpoints remain deferred per the MCP-first pattern; the import was dead code.",
          "`find_fmc_pages_for_ga_locus.inputSchema`: removed the top-level `anyOf` that required either `ga_locus` or `ga_volume`. Anthropic's `custom` tool API rejects top-level `anyOf` / `oneOf` / `allOf` in input_schema; any agent call that included this tool in its toolset was failing with `400 tools.N.custom.input_schema: input_schema does not support oneOf, allOf, or anyOf at the top level`. The field-presence constraint is now enforced in the dispatch handler instead (which already validated the same rule and returned `error_code: \"missing_argument\"`). A regression test (`test_no_top_level_schema_combinators`) sweeps every FMC tool schema for top-level combinators."
        ]
      }
    },
    {
      "version": "1.1.1",
      "date": "2026-05-18",
      "sections": {
        "Research workflows": [
          "**This release is the discipline layer that makes corpus citations trustworthy.** With 1.1.1 in place:",
          "**Anything inside quotation marks must be byte-for-byte from a corpus retrieval.** `fetch_passage`, `fetch_source_chapter`, or a `quoted_span` record with `status=stored` — minor trimming, smoothing, or dropping a single word counts as paraphrase, even when self-labelled as quoting.",
          "**0-hit responses carry an authoritative \"do not quote\" signal.** `search_steiner` / `search_anthroposophy` / `search_sources` return `corpus_verdict: \"NO_MATCH — ...\"` in the response payload when `total == 0`. A researcher receiving a NO_MATCH answer can trust that the topic is genuinely not in the corpus rather than worry the agent gave up too early.",
          "**Bare GA-volume-and-year citations are rejected as unverified.** A claim like \"GA 26, 1924\" without a specific lecture-date or passage-number does not survive the discipline check.",
          "**Reverse-lookup questions get the dedicated tool.** \"Which FMC pages cite GA 146, 1913-06-02?\" routes to `find_fmc_pages_for_ga_locus`, not generic FTS — exact-locus questions answered by an exact-locus tool.",
          "For research this means citations in an agent's output reflect retrieval rather than training memory or hallucination, and a \"not in corpus\" answer can be trusted as authoritative."
        ],
        "Added": [
          "`corpus_verdict` field on `search_steiner` and `search_anthroposophy` responses when `total == 0`. Carries an authoritative \"do not quote\" signal in the response payload, so the agent reads it directly rather than relying only on session-level instructions."
        ],
        "Changed": [
          "New top-of-document **Quotation discipline (read first)** block in server `instructions`. Requires `search_steiner` → `fetch_passage` before opening quotation marks. 0-hit corpus results are authoritative. Bare GA-number-plus-year citations (e.g. \"GA 26, 1924\") rejected as unverified. **Byte-for-byte means byte-for-byte**: dropping a single word ('thus', 'then', 'also') or trimming for slide-readability breaks verbatim status; self-labeling a paraphrase doesn't exempt it.",
          "Additional agent-discipline blocks in server `instructions`: inline citation rendering at parity with web-source linking; section references must use `<page_slug>#<section_anchor>` form; reverse cross-reference questions must use `find_fmc_pages_for_ga_locus`; stay inside the corpus when `verify_locus` returns true; citation follow-ups must verify both page and section anchor before answering.",
          "Tool `find_fmc_pages_for_ga_locus`: description lead rewritten around the question pattern it handles (\"which FMC pages cite this lecture?\"); routes away from `search_anthroposophy` for reverse-lookup queries.",
          "Tool `search_anthroposophy`: closing \"When NOT to use this tool\" block redirects exact-locus reverse lookups to `find_fmc_pages_for_ga_locus`.",
          "Shared FMC source-discipline contract (in `search_anthroposophy` + `fetch_fmc_page` descriptions): closing **Quotation-marks discipline** sentence reserves quotation marks for `quoted_span` records with `status='stored'` or verbatim Steiner passages from `fetch_passage`."
        ],
        "Fixed": [
          "`find_fmc_pages_for_ga_locus.inputSchema` now declares `anyOf` requiring `ga_locus` or `ga_volume`. Was permissive on `{}`.",
          "Removed dead `corpus` argument from `search_steiner` / `fetch_passage` / `fetch_parallel` dispatch. Handlers pass `corpus=\"steiner\"` as a literal. `fetch_parallel.inputSchema` no longer advertises the single-value `corpus` enum."
        ]
      }
    },
    {
      "version": "1.1.0",
      "date": "2026-05-14",
      "sections": {
        "Research workflows": [
          "**This release brings the Free Man Creator (FMC) curatorial layer onto the same MCP surface as the GA.** [anthroposophy.eu](https://anthroposophy.eu) — pages, schemas, structured quoted-span records, and GA cross-references. Workflows it makes practical:",
          "**Which FMC pages cite this lecture?** `find_fmc_pages_for_ga_locus(\"1913-06-02-GA146\")` returns the reverse cross-reference with attribution class (`adjacent` / `section-inferred` / `main-body-reference`).",
          "**What does the FMC curator say about X?** `fetch_fmc_page(\"Krishna_impulse\")` returns ordered curatorial chunks (lead, sections, subsections, discussion notes) plus `quoted_span` records with provenance.",
          "**Show me schema FMC00.NNN.** `fetch_fmc_schema(\"FMC00.389A\")` returns description, image URL, linked pages, and cited GA loci.",
          "**What's the link-graph around a page?** `traverse_anthroposophy_links` runs BFS over the FMC cross-link graph (depth 1-3, configurable max-nodes).",
          "FMC content is CC-BY-SA paraphrase; `quoted_span` records carry the curator's structured provenance (`status=stored` for inline verbatim, `status=referenced` for GA pointers that resolve via `fetch_passage`). The unified `search_anthroposophy` umbrella ranks GA + FMC hits together for queries spanning both."
        ],
        "Added": [
          "FMC ([anthroposophy.eu](https://anthroposophy.eu)) corpus integration. The curatorial wiki at [anthroposophy.eu](https://anthroposophy.eu) is now retrievable through the MCP connector alongside the Gesamtausgabe. License: CC-BY-SA.",
          "Tool `search_anthroposophy`: unified full-text search across the GA and FMC corpora. Filters: `corpus`, `chunk_class`, `target_corpus`, `status`, `page_slug`. Inherits GA filters (`lang`, `edition`, `ga`, `ga_range`, `from_date`, `to_date`). Detects ranking mode from query content (`primary_seeking`, `comparative`, `curatorial`, `default`) and adjusts interleave order accordingly.",
          "Tool `fetch_fmc_page`: retrieve an FMC page by slug. Returns ordered curatorial chunks (lead, sections, subsections, discussion notes), `quoted_span` records with provenance, and the page's GA cross-references.",
          "Tool `fetch_fmc_schema`: retrieve a schema by `FMC00.NNN` id. Returns description, image URL, linked pages, and cited GA loci.",
          "Tool `traverse_anthroposophy_links`: BFS over the FMC link graph from a root page slug. Depth clamped to [1, 3]; configurable `max_nodes`.",
          "Tool `find_fmc_pages_for_ga_locus`: reverse cross-reference. Given a GA locus (`1913-06-02-GA146`) or volume (`146`), return all FMC pages that cite it with attribution class (`adjacent`, `section-inferred`, `main-body-reference`).",
          "Source-discipline contract enforced in tool response structure. `quoted_span` records with `status=referenced` carry no verbatim text; agents follow `target_locus` to the primary corpus. Records with `status=stored` carry the full `embedded_attribution` chain. All FMC retrieval results carry `primary_anchor` (corpus, page_url, curator, license) and `content_hash` for citation stability."
        ],
        "Changed": [
          "MCP `tools/list` returns 9 tools (4 GA + 5 FMC)."
        ]
      }
    },
    {
      "version": "1.0.0",
      "date": "2026-05-07",
      "sections": {
        "Research workflows": [
          "**The initial release puts the complete Gesamtausgabe behind a single MCP surface.** GA 1 through GA 354, public domain. Workflows it makes practical:",
          "**Search the full corpus by keyword.** `search_steiner` runs FTS5 with Porter stemmer + diacritic normalization. Filters: `lang`, `edition`, `ga`, `ga_range`, `from_date`, `to_date`.",
          "**Verify a GA reference exists before citing.** `verify_locus` confirms `(ga, lecture_date)` is in the corpus — useful as a citation gate before publishing or quoting.",
          "**Retrieve any passage verbatim.** `fetch_passage(ga, lecture, passage_number, lang, edition)` returns text + stable citation URL in either German original or available English translation.",
          "**View parallel translations side-by-side.** `fetch_parallel` returns multiple editions of the same locus; per-edition translator + year + basis are surfaced, and an `alignment_confidence` flag warns when paragraph counts diverge between source and translation.",
          "Multilingual support means a researcher reading the German can cross-check the English, and vice versa. Browseable HTML lives at `/v1/steiner/<lang>/ga/<vol>/<date>/p<NNN>` with content-negotiated JSON via the `.json` suffix. The MCP surface is anonymous and per-IP rate-limited at the edge — no account, no signup."
        ],
        "Added": [
          "Initial public release.",
          "Gesamtausgabe corpus (GA 1 through GA 354). Rudolf Steiner's books, lectures, and lecture cycles. Public domain.",
          "Multilingual retrieval. English translations alongside German originals. Per-edition tracking (translator, year, basis). `alignment_confidence` flag marks paragraph-count divergence between source and translation.",
          "MCP server at <https://anthroposophy.ai/mcp>. Streamable HTTP transport per MCP spec 2025-03-26. Anonymous access; per-IP rate limiting at the edge.",
          "Tool `search_steiner`: FTS5 search over the Gesamtausgabe. Porter stemmer with diacritic normalization. Filters: `lang`, `edition`, `ga`, `ga_range`, `from_date`, `to_date`, `corpus`.",
          "Tool `verify_locus`: confirm a GA reference exists in the indexed corpus before citing.",
          "Tool `fetch_passage`: retrieve a verbatim Steiner passage by `(ga, lecture, passage_number, lang, edition)`. Returns text and a stable citation URL.",
          "Tool `fetch_parallel`: retrieve the same passage across multiple translation editions side-by-side.",
          "REST API at <https://anthroposophy.ai/v1/>.",
          "Browseable passages at `/v1/steiner/<lang>/ga/<ga_volume>/<lecture_date>/p<NNN>`. Content negotiation returns HTML to browsers, JSON to agents via the `.json` suffix."
        ]
      }
    }
  ],
  "source_markdown_url": "https://anthroposophy.ai/changelog.md"
}
