The mapping is redundant: every filed record (T-1038..T-1071, Q-110..Q-122,
D-225/D-241 amendments) cites its audit stub ID in its own body, and the
ledger itself remains in history at d23d54b3d if ever needed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
T2: background agent / lead writes are confined to the session root, so an
out-of-root sibling worktree (.worktrees/<branch>) is unwritable — the
agent could design but not write, and there's no permission to grant. Fix
options for clide noted. Plus a positive: clide image show works first-try.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Architecture diagram for D-239: inputs -> three-carrier refinement chain
(RegionProfile -> ChunkContext -> VoxelColumn), the district-temperature
climate primitive + derived freeze/snow, the 8 gated morphology families
over the frozen 17-zone vocabulary, and the anti-squaring domain warp.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hand-off material for the clide team. Headline: team mode works at the
Claude layer but is invisible in clide's UI — teammates ran in-process
(no pane), the Team Chat view stayed inert, no `clide team` verb. Captured
live during the Q-101 workshop; suggested fixes included.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The migration shipped (Phases 0-5 in PR #154; phases-as-hierarchy + Phase-6 SQLite
retirement in PR #155), so the plan is done. Moved pql-migration.md from the repo root
to docs/architecture/, flipped status approved -> completed, and added a header pointing
to the current-usage docs (CLAUDE.md, ticket-cli.md, governance/README.md) and the
tooling/pql-migrate/ transforms. Kept as a why/how record of the move off the binary
SQLite DB. pql-requirements.md stays at root — still-open feedback for the pql team.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hoshe (QA): docs/DEVOPS.md Repository Layout still listed `decisions/` — corrected to
`governance/` (the DQR tree) and added a `.pql/` entry for the planning store.
Tyre (architecture, non-blocking): tooling/db/common.py docstring named deleted scripts
as consumers and `resolve_db_path`/`load_config`/`get_connection` were dead settledreach.db
code. Trimmed common.py to just `ensure_venv` (the only symbol any kept connector imports)
and rewrote the docstring to name the real consumers.
ruff clean; common.py parses; ensure_venv intact.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The pql cutover is stable, so remove the superseded SQLite planning tooling. Surgical
— only the ticket/decision/raw-SQL scripts (all settledreach.db-bound and replaced by
pql) are deleted; the asset/audio/wiki connectors and shared common.py stay.
Removed:
- tooling/db/{ticket,decision,decisions-sync,decisions_sync.py,sqlite-query,sqlite-exec,
sqlite-init,sqlite-seed,sqlite_connector.py}
- tooling/{db-backup,db-install} + docs/backups/settledreach.db.backup (the binary-DB
backup ritual; tickets now live in the git-tracked .pql/changelog/)
- tooling/check-decision-ids (dead stub, superseded by `pql decisions validate`)
- Makefile db-backup/db-install targets; SR_DB_PATH + tooling/db/{ticket,sqlite-*,
decision*} entries from .claude/settings.json (audio entries kept)
Updated docs to pql: DEVOPS.md (SQLite Access + Decisions System → pql), project
structure, ticket-cli closing note, asset-pipeline raw-SQL warning.
Kept (verified still imported by the asset connectors via common.ensure_venv): common.py,
config.json, audio/image/trellis/wiki connectors. The live settledreach.db file
(gitignored, repo-parent) is left on disk as a cold rollback only.
ruff clean; pql decisions validate ok (357 decisions / 1013 tickets).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Workshop -> decision provenance was prose-only. Adds a `decision_refs:` YAML
frontmatter list (the confirmed D-records each workshop-outcomes.md touches,
filtered against the governance decision set) to all 17 workshop outcomes; the two
that lacked frontmatter (commodity-catalog, system-economic-specialization) get a
minimal block. pql indexes the list and `SELECT fm.decision_refs` round-trips it, so
"which workshops touch D-NNN" is answerable via SELECT + filter or `pql search`.
decision_refs is a relevance signal (decisions a workshop discusses/produces), not a
strict authorship claim — historical bare refs aren't disambiguated. Generated wiki
read-only sections are left untouched.
Noted in pql-requirements #5: 1.6.2 has no working DSL operator for frontmatter
list-membership (`~`/`contains` error, `in` matches nothing), so membership queries
need a client-side filter for now.
Reproducible via tooling/pql-migrate/add_workshop_provenance.py (idempotent).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review fixes for the #1016 cultural pass (Hoshe/Paula/Miri):
- Kruger 60 (GJ 860A) xhosa -> cosmopolitan (Miri): GTTR describes an
Afrikaner/Xhosa/Zulu founding "without mapping cleanly onto any of
them" — the textbook genuinely-fused case, which taxonomy rule 4
resolves to cosmopolitan rather than one of the three. Commented.
- Altmark (GJ 357) financial_technocratic -> cosmopolitan (Paula):
reverts to the original shipped value; the GTTR reads as commercial
non-alignment, not credential-based technocracy.
- Kampala Gate (GJ 667B) + Moyale (GJ 1292) keep swahili but add inline
comments documenting that these are East-African-INTERIOR founders
(Baganda; Kenyan/Ethiopian Borana-Oromo) for which the taxonomy has no
dedicated token — swahili is the nearest available, NULL would fall to
the wrong corridor default. Gap logged for a follow-up taxonomy value.
Mwangaza (693) swahili is literally correct (coastal) — untouched.
- heritage-taxonomy-draft.md: stale "(38)" subheadings -> "(47)" to match
the actual canonical count (Hoshe/Miri doc typo).
Retracted: Pedra Seca (GJ 421B) xhosa — reviewer thought it lacked
authored backing, but its gttr.md explicitly states "Afrikaans and Xhosa
heritage"; pin kept.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review fixes for the #1019 heritage rebalance:
- Marib's farm world Ghouta -> Ghawr (Miri): "Ghouta" carries strong
modern associations (2013 Damascus attack); Ghawr (the Jordan Rift
Valley, an irrigated lowland farming region) keeps the water-fed-
drylands sense without the resonance.
- Add dominant_faction = "independent" to GJ 914A / 508A / 1245B (Hoshe)
— all five rebalanced systems are self-governing independent
communities; uniform with siblings GJ 722 / 680 and clears V-FAC-01.
- catalog.md: fill GJ 914A -> Marib and GJ 722 -> Sığınak (Hoshe) — the
two anchor systems still showed em-dash placeholders.
- Marib gttr: name the second aperture neighbour Sığınak instead of the
bare "GJ 722" (Miri).
Pre-existing Golestan aperture/spur wording (reviewers split on whether
it is even wrong) is left for a separate content pass — not introduced
by this rename.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The pre-execution conversion plan and shipped-state addendum for the
South-African heritage rebalance: per-system field maps, the worked
gttr rewrites, the cross-reference cleanup list, and the rationale for
keeping load-bearing mystery systems out of scope.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The corridor over-represented southern-African heritage (afrikaans on 15
systems; arab=2, persian/turkic=0) as an artifact of the earlier
name-balancing overcorrecting. Convert five genuinely-thin afrikaans
systems — whose distinctive threads are heritage-agnostic — into
Arab/Persian/Turkic founders so the cultural cascade is built on a
balanced set. Load-bearing mystery systems (Eerste Wacht / Helderoog /
Brandpunt etc.) are left untouched.
Droëland (GJ 914A) -> Marib (arab)
Stilwater (GJ 508A) -> Sawad (arab)
Koeberg (GJ 1245B) -> Akhgar (persian)
Skuilplek (GJ 722) -> Siginak (turkic)
Carnarvon (GJ 680) -> Golestan (persian; Mostert dynasty -> Farahani)
Result: afrikaans 15->10; arab 0->2, persian 0->2, turkic 0->1.
Full narrative retouch (not just names): gttr.md + index.md prose,
body/station proper_names, cultural_specialization, gttr_hook,
atlas_city_names, and the four brand-corps named after the converted
systems (corp IDs kept stable; only display names + products renamed).
Cross-references in neighbour systems, the catalog, the aggregate
drifter guides, and the atlas proposals are updated to match.
arab/persian/turkic added to _CULTURAL_HERITAGE so the values validate;
the full canonical 47-value migration remains #1016.
Also fixes a pre-existing canon bug: Sawad (GJ 508A) no longer claims
GJ 914A is "unsettled" — it is Marib, a three-century settlement.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reconciles the ~30 inconsistent heritage proposals from the 6-sector #1016
content pass into one canonical cultural_specialization heritage vocabulary
(47 values). Key reconciliations: norse_compact->nordic (un-fuses people from
faction), spanish_iberian+spanish_hispanic->spanish, brazilian_portuguese+
lusophone_frontier->brazilian, italian_northern->italian, afrikaans_cape->
afrikaans, french_provencal+french_canadian->french. No compound values; one
token per system (blends take dominant heritage or the cosmopolitan activity
value).
Maintainer decisions (2026-06-01): keep ALL values distinct (no lumping —
welsh/afro_brazilian/cape_malay/xhosa/luxembourgish/konkan all retained);
keep empty-but-complete slots (yoruba/hausa/hungarian/persian/turkic). Fills
the Middle-East gap the pass exposed: arab/persian/turkic added even at near-
zero current usage so the canon is complete.
Logs the southern-African overrepresentation (~25/300, afrikaans=15) as a DLC
content-rewrite rebalancing task (#1019) rather than lumping the taxonomy.
Migration note included: 4 already-shipped hero cultural values use old suffix
forms (afrikaans_cape, french_provencal, italian_northern, norse_compact) and
will be renamed in the culture-write pass when _CULTURAL_HERITAGE is replaced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three-round design workshop (Miri, Burnelli-Sheldon, Paula; documented by
Qatux, ticketed by SI) that produced D-237. Includes per-agent round
outputs, round notes, the independent scout critique, and the final
workshop-outcomes.md with the consolidated schema, 27-value economic
vocabulary, cultural + faction vocabularies, deterministic-varied fallback
spec, must-pin table, and CI guardrails.
Clerk-Skip: workshop discussion docs, no D-record surface (D-237 filed separately)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add D-237: each inhabited system carries three authored, static (t=0),
deterministic per-system identity fields sourced from
wiki/economics/system_specialization.toml — economic_specialization
(27-value vocabulary, scale encoded in the value), cultural_specialization
(unified activity + heritage vocabulary), and dominant_faction (populate
the existing system_factions column, 8 values, lattice_commission dropped).
Authored lore wins; a deterministic-varied seed-hashed weighted draw is the
fallback for unnamed systems so they don't read identically.
Re-amend D-233 to source dominant_bulk_class x dominant_production_ubiquity
from this authored layer (heuristic becomes fallback). Groombridge encodes
as a financial_hub Specialist district with the GSH clearing house as a
D-222/D-232 landmark rather than a composite vocabulary value.
Add the specialization-layer d2 diagram (3 fields -> D-233/D-232/D-214
consumers). Produced by the system-economic-specialization workshop.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- settings.json: add Read(repo/**), Read(/tmp/**), Grep, Glob to the
allowlist. Teammates inherit settings.json (not settings.local.json),
which had no Read rule — so every teammate file read escalated to the
lead as a per-file prompt. This closes that gap.
- Add the system-economic-specialization workshop brief (lore-authored
per-system dominant-commodity field + within-system weighted variation;
Q5 covers adding a small identity field set in the same 300-system pass).
Note: agent memory-strip (6c93b698f) + this read-allow reach teammates
only after a Claude Code restart (settings/agent-def snapshot is taken at
lead startup).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Stage-2 workshop brief and the consolidated three-scan coverage map (per-step decided-vs-open across the 4-step built-world pipeline) that became round 2's foundation.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Planet-down cascade workshop (3 rounds, 5 agents): layer-by-layer
generation from empty world through population overlay, city planning,
and street rendering. Includes consultant review by Troblum.
Also commits: pre-Sprint-35 DB backup, Claude Code team-mode tmux
test log (team-test.md).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Four-round workshop (Gestalt, Tyre, Paula, Burnelli-Sheldon, Miri)
mapping the full generation pipeline from planetary heightmap to
walkable tile. 25 D-records produced. Ticket dependency chain for
Tier 0-4 implementation identified.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sprint-based workflow (38 sprints) replaced by kanban + milestones.
Milestones are many-to-many with tickets and can block each other.
New: /whats-next skill (dependency-driven batch selection with Si
refinement review), /pr-process skill (renamed from pr-push, adds
review comment pickup), clerk agent + pre-push hook for D-record
consistency checks.
Deleted: sprint CLI, sprint-start/sprint-plan/sprint-status skills,
team-scoped file restrictions. Si rewritten as refinement manager.
All 19 agent briefings updated from stale PROJECT_STATE.md reference
to live ticket milestone queries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implementation audit of the full generation pipeline from planetary
heightmaps to walkable tiles. 3-round workshop with Gestalt, Tyre,
Miri to map what exists vs. stubs vs. missing, produce D-records,
and create formal ticket dependency chain blocking character/apartment
work behind the complete pipeline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Generation pipeline focus — map all layers from planetary heightmaps to
walkable tile environments, build bare-minimum free camera viewer, close
Sprint 37 test/infra debt. Character and apartment work formally parked
behind the full generation cascade.
13 tickets across 5 teams (planning: 1, server: 4, client: 5, copy: 1, ci: 2).
Added Write(docs/sprints/*) and Bash(mkdir) permissions for sprint planning.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses Tyre, Hoshe, and lead review comments on PR #137:
- **Audit doc amendment** (Tyre E1 / Hoshe H1 / Lead): add "Lead override
(2026-04-21)" section at top of docs/architecture/sprint-37-878-audit.md.
Rewrites the conclusion to "DECISION: STRIP" with the cascade-based
rationale. Preserves the original audit body as the pre-override record.
- **Regression tests** (Lead 2a-2b / Hoshe H2 / H3): add POSITIVE
assertions of the new uniform behavior so silent reintroduction fails.
- `phase2_container_verb_labels_uniform_regardless_of_player_state` —
two trials (empty KG, POI-bearing KG) assert container verb labels
equal Phase-1 defaults.
- `monologue_pool_selection_uniform_no_archetype_key` — two observers
with divergent MonologueState both draw from OBSERVE_NPC_LINES.
- **Decision record amendments** (Lead 3 / Tyre S2): D-032, D-035, and
D-057 amended with Phase 6 deferral wording. "Retired pending Phase 6,
not deferred with scaffolding." Reintroduction gate: a confirmed
Phase 6 character-model design.
- **types.rs doc fixes** (Tyre S1 / Hoshe H5): StartupMessage protocol-
flow comment updated to reflect no-version handshake (D-192).
ObserverSnapshot version-history block grows a "Sprint 37 wire-format
shifts" section documenting D-192 + #878 schema drops.
- **observer/tests.rs:944 comment** (Hoshe H6): rewritten to cite
cascade rationale instead of the stale D-032-SUPERSEDED premise.
- **tests/run-atlas-determinism exit** (Hoshe H7): exit 0 when EXIT_CODE=2
(venv/DB missing = skip, not fail). Preserves skip semantics for
tests/run-all on machines without the Python venv.
Follow-up tickets filed:
- #895 (server, low): expand check-systems-db-stamp GENERATOR_SOURCES
to cover gemma_naming.py + naming_core.py (Tyre S3).
- #896 (planning, low): add CLAUDE.md carveout for server wiki writes
closing coverage gates (Tyre S4 / Hoshe H8).
H4 investigation: v01_integration_playthrough.rs was not the only E2E
handshake→tick→snapshot test; coverage preserved by bridge_ipc.rs,
bridge_tcp.rs, and game_loop.rs (the latter is pre-existing-broken
per #885). No replacement test needed.
1142/1142 lib tests pass. cargo clippy -- -D warnings clean.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tyre's trace of every live consumer of CharacterArchetype across server
and client, with the cascade-based rationale for full removal. Captured
so future audits don't repeat the same investigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds Serialize/Deserialize to SelectedBookmark and wires it into
SaveStateV1 so a loaded game remembers which bookmark and starting
location the player picked. Replaces the TODO at bookmark/mod.rs:95
(originally deferred to Sprint 37 alongside #614).
Also refactors BookmarkPlugin to accept an injected BookmarkRegistry
via BookmarkPlugin::new(registry) (#862). The Default constructor
still wires the canonical tycoon registry — injection is for tests
and future TOML loading. Flagged in PR #132 review as a follow-up.
Updates bookmark spec §4.4 to remove the v0.2-deferred scope note.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds `.claude/rules/asset-pipeline.md` describing the full pipeline —
generators, meta stamp, pre-push hook, how to make DB/schema changes,
and why direct systems.db edits are forbidden. CLAUDE.md and DEVOPS.md
point at the rules file; sprint-start template now reminds teammates
to read it before touching DB sources.
CLAUDE.md also gains the missing `decision show` row in the CLI tool
table (companion to #723's `decision show` subcommand).
Refs: #859#723
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- tooling/planet-gen/earth_blocklist.txt: document GJ0d (Earth body) as
blocklist-exempt so Brussels (and other Earth-canonical city names) are
not flagged on next sol_import.py run (R2 issue 1)
- wiki/star-systems/GJ-380/bodies/GJ380c/markers.json: rename Selet Basin
→ Subin Basin (Kumasi river namesake). Brings Akan register on GJ380c
to 3/29 features distributed across river, mountain, lake — credible
multi-generational trade corridor read instead of minimum-viable patch
(R2 issue 2)
- server/data/systems.db: atlas_oceans resynced for GJ380c
- docs/atlas/hand-refine-log.md:119: corrected stale log entry — Aldren
Pass was subsequently renamed Randalfoss to eliminate the cross-system
Aldren stem collision with GJ380c (R2 nit 3)
- tooling/planet-gen/refine_log_849.md: Groombridge cross-corridor
addendum updated to reflect 3/29 Akan register distribution
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Documents the ImplantApp lifecycle ordering and the nav-stack state
guarantee at each hook:
- Class-level docstring on implant_app.gd describes on_install,
on_open, on_close, and on_insert_deactivated: when each fires,
what nav state subclasses can rely on, and what is safe to do
(construct + register_screen in on_install; data refresh + read
nav.current() in on_open; pause timers in on_close; no close_app
manual call in on_insert_deactivated — call super or replicate
the guard).
- Arch doc gains a "Lifecycle hooks" subsection under ImplantApp
base class with a four-row contract table plus explanatory notes
on two load-bearing invariants: why on_install sees an empty
stack (bottom-up _ready order, no open signal yet); why on_close
must not push/pop (would destroy preserved position on reopen).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reflects the final shape of the ImplantApp pattern after PR #131
review rounds:
- Manifest: schema_version field, default_mode as String, drop
display_name / icon_path (no callers). Documents the tiered
schema_version behavior and the default_mode string-to-enum resolution.
- ImplantApp base class: add register_screen, current_screen_id,
default _on_screen_changed with has_method tolerance + same-screen-
replace detection. Drop the unused insert_deactivated signal;
on_insert_deactivated() default closes if active in INSERT mode.
- Screens paragraph: rewrite to describe subclass-constructs-then-
registers flow; base owns add_child, visibility, enter/leave dispatch.
- Phasing: promote "Lands this PR" to "Landed — Sprint 36 #844 and
review rounds" with concrete surface of the full shipped API
(instantiate_all, get_app_instance, get_resolved_mode, schema_version).
- Review checklist: rewrite as a per-app PR checklist for future apps
entering the pattern (manifest shape, on_install contract, no direct
instantiation in hud.tscn, no KEY_* literals in main.gd).
Draft by Tyre; committed by team lead per the team-lead-commits rule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Seven nit-level fixes from PR review:
- Remove dead signal insert_deactivated from ImplantApp; the hook method
on_insert_deactivated() is the actual contract.
- Rewrite _on_atlas_economics_link comment in main.gd to reflect the
actual flow (AtlasApp closes as a consequence of HudGroups single-
active-app, not before emitting anything).
- Document the "pop never empties below default" invariant on
ImplantNavStack.pop() with a pointer to reset_to_default.
- Add _mutating re-entrancy guard on ImplantNavStack mutation methods.
push_error + early return if called during a screen_changed emission.
- main.gd registry loop now uses typed ImplantAppManifest property
access (manifest.app_path, manifest.default_key) instead of
dictionary-style .get() calls. Empty app_path triggers push_warning.
- Document the economics [/] hotkey exception in main.gd and reference
the planned handle_global_key lifecycle hook. Arch doc Follow-up
section gains a bullet for the new hook.
- Comment the independent-version-read rationale above client_ver and
proto_ver in loading_screen.gd.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Finalizes #849 core-world atlas cohesion: GJ0d (Earth/Sol) markers.json
cleaned of erroneous data, refine_log updated with Sol body gap notes,
atlas_quality_analysis.py added for ongoing metric tracking.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Systematic sweep eliminated all city name cross-body collisions across the
273 inhabited bodies. Started from Forum Veritas/Jade Harbor/Fort Iron
clusters identified during the #849 analysis pass.
Strategy: use world proper_name as capital city name wherever unique.
For worlds sharing a proper_name, author corridor-appropriate alternates.
All edits synced to atlas_cities via generate_atlas.py --body.
Before: 119+ cross-body city collisions, worst-case ×20 (Jade Harbor)
After: 0 cross-body city collisions
Clusters eliminated: Forum Veritas ×10, Jade Harbor ×19, Fort Iron ×10,
Eisenstadt ×7, Fjordheim/Fjordholm ×6 each, Eisenberg/Eisenfels/Hanseong ×5
each, Ridge Marker ×5, plus 20+ smaller clusters down to ×2.
River/ocean collisions (Rio Grande ×23 rivers, Steinbruch ×19, etc.)
remain — these affect uninhabited secondary bodies at scale and require a
dedicated batch-script pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CultureResolver with Arc<Mutex<Connection>> over systems.db (SQLITE_OPEN_READ_ONLY).
3-pass lookup: system_id → body_id (COALESCE parent fallback) → station_id.
CultureResolverResource registered in main.rs with graceful warn-on-missing.
BookmarkRegistry.build_catalog() uses resolver for allowed_locations_cultures.
8 unit tests including concurrent safety. SQLite fixture at
server/src/knowledge/fixtures/culture_test.db.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>