Šķîþ ţö ḿàîñ çöñţéñţ

Çöñţéẋţ àţļàš

Ţĥé çöñţéẋţ àţļàš îš à šîñĝļé đöçüḿéñţ ţĥàţ ĥöļđš àļļ öƒ à þŕöĵéçţ'š çöñţéẋţ ŕéçöŕđš. Éàçĥ ŕéçöŕđ šîţš àţ îţš þöîñţ öñ ţĥé þŕöĵéçţ'š àẋéš àñđ çàŕŕîéš ţĥé šţàţüšéš îţ ĥàš ĥéļđ öṽéŕ ţîḿé. Éàçĥ éṽéñţ çàŕŕîéš à ŕéçöŕđéđ ţîḿé àñđ, ŵĥéŕé îţ đéŕš, àñ 郃éçţîṽé ţîḿé. host.App.ContextAtlas ƃüîļđš ţĥé đöçüḿéñţ, kapi context atlas --json þŕîñţš îţ, àñđ ţĥé đéšķţöþ'š Éẋþļöŕé ṽîéŵ đŕàŵš îţ. Ţĥé ƒîéļđ ñàḿéš ƃéļöŵ àŕé ţĥé çöñţŕàçţ ƃéţŵééñ ţĥéšé ţĥŕéé. Šéé Ç-11 ƒöŕ ĥöŵ ţĥé àţļàš ŕéļàţéš ţö ţĥé öţĥéŕ çöñţéẋţ öþéŕàţîöñš, Ç-02 ƒöŕ ţýþéđ àẋéš, àñđ Ç-12 ƒöŕ ţĥé þļàçéš à ĝéö àẋîš ĥöļđš.

Ŕéǫüéšţ​

type ContextAtlasRequest struct {
Project string // recipe path or workspace key; empty resolves as every command does
AllProjects bool // every project in the workspace; content cells and terms are omitted
Content bool // include content cells (unit counts by collection, locale and state)
Limit int // cap on records and on events; 0 is 5000
}

kapi context atlas šéţš Content üñļéšš --no-content öŕ --all-projects îš ĝîṽéñ. Ŵĥéñ Limit ţŕüñçàţéš ţĥé ŕéçöŕđš öŕ ţĥé éṽéñţš, ţĥé ĥöšţ àđđš àñ éñţŕý ţö notes ŵîţĥ ţĥé çöüñţš.

Đöçüḿéñţ​

type ContextAtlas struct {
Format string `json:"format"` // "kapi-context-atlas"
Version int `json:"version"` // 1
Project string `json:"project,omitempty"`
GeneratedAt time.Time `json:"generated_at"`
Span AtlasSpan `json:"span"` // earliest..latest instant across records and events
Axes []AtlasAxis `json:"axes"`
Places []AtlasPlace `json:"places"` // the gazetteer the map draws from
Records []AtlasRecord `json:"records"`
Events []AtlasEvent `json:"events"`
Notes []string `json:"notes"` // scope of the read, truncation, data not read
}

type AtlasSpan struct {
From time.Time `json:"from"`
To time.Time `json:"to"`
}

axes, places, records, events àñđ notes àŕé àļŵàýš ĴŠÖÑ àŕŕàýš. Àñ éḿþţý öñé îš ŵŕîţţéñ àš [].

Àẋéš​

type AtlasAxis struct {
ID string `json:"id"`
Label string `json:"label,omitempty"` // the recipe's label; empty when the recipe sets none
Kind string `json:"kind"` // category | geo | range | ordered
Source string `json:"source"` // structural | declared | derived
Values []AtlasValue `json:"values"` // display order
}

type AtlasValue struct {
ID string `json:"id"`
Label string `json:"label,omitempty"` // the recipe's label, or a place's name
}

À ĝéö ṽàļüé çàŕŕîéš öñļý àñ îđ àñđ à ļàƃéļ. Ţĥé þļàçé'š çöñţàîñḿéñţ, ḿéḿƃéŕš àñđ öüţļîñé àŕé îñ places, üñđéŕ ţĥé šàḿé îđ.

ŠöüŕçéÀẋéšṼàļüéš
structuralproduct, channelţĥé þŕöƒîļéš àñđ çĥàññéļš ţĥé ŕéçîþé đéçļàŕéš, àñđ àñý à ŕéçöŕđ üšéš
declaredéṽéŕý àẋîš axes: ţýþéš öŕ à çööŕđîñàţé ñàḿéš, àñđ àñý öţĥéŕ àẋîš à ŕéçöŕđ çàŕŕîéšà çļöšéđ öŕ öŕđéŕéđ àẋîš ļîšţš îţš đéçļàŕéđ ṽàļüéš îñ öŕđéŕ, ţĥéñ àñý öţĥéŕ üšéđ; à ĝéö àẋîš ļîšţš ţĥé þļàçéš ţĥé ŕéçöŕđš üšé àñđ éṽéŕý đéçļàŕéđ þļàçé, þļàçéš ḿàđé öƒ þļàçéš ƒîŕšţ, ţĥéñ ƃý ţýþé ƒŕöḿ ţĥé ŵîđéšţ ķîñđ ţö ţĥé ñàŕŕöŵéšţ (place.Type.Rank), ţĥéñ ƃý ñàḿé; à ŕàñĝé àẋîš ļîšţš üšéđ îñţéŕṽàļš ƃý ļöŵéŕ ƃöüñđ
derivedfamily, actor, project (ŵîţĥ all_projects), locale, regionţĥé ṽàļüéš ţĥé ŕéçöŕđš üšé; region îš à ĝéö àẋîš ĥöļđîñĝ ţĥé þļàçé éàçĥ ļöçàļé ñàḿéš (place.OfLocale): ţĥé šüƃđîṽîšîöñ öƒ à -u-sd- éẋţéñšîöñ, éļšé ţĥé çöüñţŕý öŕ Ḿ49 ŕéĝîöñ öƒ îţš ŕéĝîöñ šüƃţàĝ

Ţĥé ṽîéŵ çöḿþüţéš ƒöüŕ ƒüŕţĥéŕ àẋéš ƒŕöḿ ţĥé ŕéçöŕđš, àñđ ţĥé đöçüḿéñţ đöéš ñöţ çàŕŕý ţĥéḿ. Ţĥéý àŕé ţĥé šţàţüš àţ ţĥé šţàŕţ öƒ ţĥé ţîḿé ŵîñđöŵ, ţĥé šţàţüš àţ ţĥé šñàþšĥöţ, ţĥé ļîƒéţîḿé (üþçöḿîñĝ, îñ ƒöŕçé, éẋþîŕéđ öŕ öþéñ àţ ţĥé šñàþšĥöţ) àñđ ţĥé ţîḿé šîñçé ţĥé ŕéçöŕđ ŵàš ŕéçöŕđéđ.

Þļàçéš​

type AtlasPlace struct {
ID string `json:"id"`
Name string `json:"name"`
Names map[string]string `json:"names,omitempty"` // a declared place's names per locale
Type string `json:"type"` // world | region | country | subdivision | a declared type
Within []string `json:"within,omitempty"`
Of []string `json:"of,omitempty"`
Centroid *[2]float64 `json:"centroid,omitempty"` // [lat, lon], rounded to two decimals
Refs []string `json:"refs,omitempty"`
Shape string `json:"shape,omitempty"` // a declared place's GeoJSON file
Geometry *AtlasGeometry `json:"geometry,omitempty"` // the polygon that file holds
Declared bool `json:"declared,omitempty"`
}

type AtlasGeometry struct {
Type string `json:"type"` // Polygon | MultiPolygon
Coordinates any `json:"coordinates"` // [lon, lat] positions in rings, as the file writes them
}

places îš ţĥé þàŕţ öƒ ţĥé þŕöĵéçţ'š ĝàžéţţééŕ à ḿàþ ñééđš, šöŕţéđ ƃý îđ. Ţĥé ĥöšţ çöļļéçţš:

  1. éṽéŕý þļàçé à ŕéçöŕđ ñàḿéš öñ à ĝéö àẋîš, ţĥé đéŕîṽéđ region àẋîš îñçļüđéđ;
  2. éṽéŕý þļàçé ţĥàţ çöñţàîñš öñé öƒ ţĥöšé (Gazetteer.Ancestors), àñđ ţĥé ḿéḿƃéŕš öƒ éàçĥ þļàçé ḿàđé öƒ þļàçéš, ŕéçüŕšîṽéļý;
  3. éṽéŕý þļàçé ţĥé ŕéçîþé đéçļàŕéš, ŵîţĥ ŵĥàţ çöñţàîñš îţ àñđ ŵĥàţ îţ îš ḿàđé öƒ;
  4. ţĥéñ, ƒöŕ éàçĥ çöüñţŕý àñđ šüƃđîṽîšîöñ îñ ţĥàţ šéţ, ţĥé þļàçéš đîŕéçţļý ƃéļöŵ îţ (Gazetteer.Children), àñđ ƒöŕ éàçĥ ŕéĝîöñ, ţĥé çöüñţŕîéš îţ ĥöļđš ţĥŕöüĝĥ îţš šüƃŕéĝîöñš.

Ţĥé ļàšţ šţéþ ļéţš à ḿàþ đŕîļļ đöŵñ ƃý ñàḿé. À ḿàþ öþéñéđ àţ Ñöŕŵàý ļîšţš éṽéŕý Ñöŕŵéĝîàñ çöüñţý, îñçļüđîñĝ çöüñţîéš ŵîţĥ ñö ŕéçöŕđš.

within àñđ of çàŕŕý ţĥé đéçļàŕàţîöñš üñçĥàñĝéđ. À ṽîéŵ ţĥàţ àþþļîéš ţĥé çöñţàîñḿéñţ ŕüļéš öƒ Ç-12 ţö ţĥéḿ ĝéţš ţĥé šàḿé ŕéšüļţš àš ţĥé éñĝîñé. @neokapi/context-atlas îḿþļéḿéñţš ţĥöšé ŕüļéš îñ model/places.ts. Ţĥé šĥàŕéđ ƒîẋţüŕé core/place/testdata/containment.json ţéšţš ţĥé Ĝö àñđ ţĥé ŢýþéŠçŕîþţ îḿþļéḿéñţàţîöñš àĝàîñšţ ţĥé šàḿé çàšéš.

À đéçļàŕéđ þļàçé ŵîţĥ shape: çàŕŕîéš geometry. Ţĥé ĥöšţ ŕéàđš ţĥé ƒîļé ƒŕöḿ ţĥé çĥéçķöüţ àñđ ŕéđüçéš îţ ţö öñé Þöļýĝöñ öŕ ḾüļţîÞöļýĝöñ ĝéöḿéţŕý. Îţ àççéþţš à ƃàŕé ĝéöḿéţŕý, à Ƒéàţüŕé ĥöļđîñĝ öñé, öŕ à ƑéàţüŕéÇöļļéçţîöñ öƒ à šîñĝļé šüçĥ Ƒéàţüŕé. Ţĥé ĥöšţ öḿîţš ţĥé ĝéöḿéţŕý ŵĥéñ ţĥé ƒîļé çàññöţ ƃé ŕéàđ, îš ļàŕĝéŕ ţĥàñ 1 ḾîƂ (atlasMaxShape), öŕ ĥöļđš àñý öţĥéŕ ĜéöĴŠÖÑ. Îţ ţĥéñ àđđš à ñöţé ţĥàţ ñàḿéš ţĥé ŕéçîþé ķéý, šüçĥ àš places.bergen.shape: places/bergen.geojson is larger than 1 MiB, so the place has no outline. Ŵĥéñ ţĥé þŕöĵéçţ ĥàš ñö çĥéçķöüţ öñ ţĥîš ḿàçĥîñé, ñö þļàçé çàŕŕîéš ĝéöḿéţŕý, àñđ ţĥé ĥöšţ àđđš à ñöţé ƒöŕ éàçĥ šĥàþé ƒîļé îţ đîđ ñöţ ŕéàđ.

Ŕéçöŕđš​

type AtlasRecord struct {
ID string `json:"id"`
Family string `json:"family"` // rule | note | memory | term | content | import
Label string `json:"label"`
Weight int `json:"weight"` // 1, or the unit count of a content cell
Coordinates map[string]string `json:"coordinates"`
Recorded time.Time `json:"recorded"` // zero when unknown
ValidFrom *time.Time `json:"valid_from,omitempty"`
ValidTo *time.Time `json:"valid_to,omitempty"`
History []AtlasState `json:"history"` // time order
Short string `json:"short,omitempty"`
Actor *contextop.Actor `json:"actor,omitempty"`
Evidence []contextop.Evidence `json:"evidence,omitempty"`
Text string `json:"text,omitempty"`
Scope string `json:"scope,omitempty"`
ContestedBy []string `json:"contested_by,omitempty"`
}

type AtlasState struct {
At time.Time `json:"at"`
State string `json:"state"`
}

Ţĥé šţàţé öƒ à ŕéçöŕđ àţ àñ îñšţàñţ îš ţĥé ļàšţ history éñţŕý àţ öŕ ƃéƒöŕé ţĥàţ îñšţàñţ. Ƃéƒöŕé ţĥé ƒîŕšţ éñţŕý, ţĥé ŕéçöŕđ đöéš ñöţ éẋîšţ.

ƑàḿîļýŠöüŕçéidŠţàţéš
ruleàñ öþéŕàţîöñ çàŕŕýîñĝ à ţéŕḿ ŕüļéţĥé öþéŕàţîöñ îđsuggested, established, contested, withdrawn, dropped, reset
noteàñ öþéŕàţîöñ çàŕŕýîñĝ þŕöšéţĥé öþéŕàţîöñ îđàš àƃöṽé
memoryàñ öþéŕàţîöñ çàŕŕýîñĝ à çöñţéñţ-ḿéḿöŕý þàîŕţĥé öþéŕàţîöñ îđàš àƃöṽé
termà çöñçéþţ îñ ţĥé ţéŕḿš šţöŕéterm:<concept> (à çöñçéþţ îđ ţĥàţ šţàŕţš term: îš üšéđ àš îţ îš)established
contentà çéļļ öƒ kapi status çöṽéŕàĝécontent:<collection>:<locale>:<state>not-started, draft, translated, established, stale

Ĥöŵ éàçĥ þàŕţ îš ƃüîļţ:

  • Öþéŕàţîöñš. Éṽéŕý öþéŕàţîöñ ţĥàţ çàŕŕîéš à šüƃĵéçţ ƃéçöḿéš à ŕéçöŕđ, öļđéšţ ƒîŕšţ. Ţĥé šüƃĵéçţ šéţš ţĥé ƒàḿîļý: rule ƒöŕ à ţéŕḿ ŕüļé, memory ƒöŕ à çöñţéñţ-ḿéḿöŕý þàîŕ, note ƒöŕ þŕöšé. Àñ import öþéŕàţîöñ ĥàš ţĥé ƒàḿîļý import. Ţĥé ŕöŵš öƒ ţĥé îḿþöŕţéđ ƒîļé ƃéçöḿé ţéŕḿ àñđ çöñţéñţ-ḿéḿöŕý ŕéçöŕđš, àñđ ţĥé îḿþöŕţ ŕéçöŕđ îš ţĥéîŕ þŕöṽéñàñçé. Ţĥé ĥîšţöŕý çöḿéš ƒŕöḿ Ledger.Histories. Îţ šţàŕţš ŵîţĥ ţĥé îñîţîàļ šţàţüš àţ ţĥé öþéŕàţîöñ'š öŵñ îñšţàñţ àñđ àđđš éàçĥ çĥàñĝé àţ ţĥé îñšţàñţ öƒ ţĥé öþéŕàţîöñ ţĥàţ ḿàđé îţ. Ŵĥéñ ţĥé ļöĝ ĥöļđš ḿöŕé ţĥàñ contextop.HistoryLimit îñšţàñţš, éàçĥ ĥîšţöŕý ĥöļđš öñļý ţĥé ƒîŕšţ šţàţüš àñđ ţĥé çüŕŕéñţ öñé, àñđ ţĥé ĥöšţ àđđš à ñöţé. À çöŕŕéçţîöñ ŕéçöŕđéđ ŵîţĥöüţ à ŕüļé çàŕŕîéš ñö šüƃĵéçţ, šö îţ àþþéàŕš öñļý àš àñ éṽéñţ.
  • Ţéŕḿš. Éàçĥ çöñçéþţ ƃéçöḿéš öñé ŕéçöŕđ àţ ţĥé çööŕđîñàţéš ţĥé çöñçéþţ îš šçöþéđ ţö. Ŵĥéñ ţĥöšé çööŕđîñàţéš öḿîţ product, ţĥé ĥöšţ šéţš îţ ƒŕöḿ ţĥé çöñçéþţ'š þŕöƒîļé. Ţĥé ļàƃéļ îš ţĥé ĥéàđ ţéŕḿ ƒöļļöŵéđ ƃý ţĥé ƒöŕḿš îţ đîšçöüŕàĝéš. Ţĥé ŵîñđöŵ îš ţĥàţ öƒ ţĥé ƒîŕšţ đîšçöüŕàĝéđ ƒöŕḿ ţĥàţ ĥàš öñé, öŕ éļšé ţĥàţ öƒ ţĥé ƒîŕšţ ţéŕḿ ţĥàţ ĥàš öñé. À ŕüļé à þéŕšöñ ķéþţ þŕöđüçéš ţŵö ŕéçöŕđš ŵîţĥ đîšţîñçţ îđš: à rule ŕéçöŕđ ƒöŕ ţĥé ļöĝ éñţŕý àñđ à term ŕéçöŕđ ƒöŕ ţĥé çöñçéþţ îñ ţĥé ţéŕḿš šţöŕé.
  • Çöñţéñţ çéļļš. Ţĥé ĥöšţ ḿéàšüŕéš ţĥé þŕöĵéçţ ŵîţĥ ţĥé šàḿé ţàļļý àš kapi status (ProjectCoverageTally), öñé ƒîļé àţ à ţîḿé. Îţ àđđš öñé ŕéçöŕđ þéŕ çöļļéçţîöñ, ļöçàļé àñđ šţàţé, ŵéîĝĥţéđ ƃý îţš üñîţ çöüñţ. À šţàļé üñîţ îš çöüñţéđ üñđéŕ stale àñđ éẋçļüđéđ ƒŕöḿ draft. Ţĥé ţàļļý ĥöļđš öñļý ţĥé çüŕŕéñţ šţàţé öƒ éàçĥ üñîţ. Éàçĥ çéļļ ţĥéŕéƒöŕé ĥàš öñé ĥîšţöŕý éñţŕý, àţ generated_at, àñđ à ñöţé šţàţéš ţĥàţ éàŕļîéŕ šţàţéš àŕé üñķñöŵñ.

Éṽéŕý ŕéçöŕđ'š coordinates ĥöļđš ţĥé ŕéçöŕđ'š þöîñţ àñđ ţĥé đéŕîṽéđ àẋéš. family îš àļŵàýš šéţ. Àñ öþéŕàţîöñ àļšö çàŕŕîéš actor (à þéŕšöñ, àñ àĝéñţ öŕ à ţööļ). project îš šéţ ŵĥéñ ţĥé àţļàš çöṽéŕš éṽéŕý þŕöĵéçţ. À çöñţéñţ-ḿéḿöŕý þàîŕ, à ţéŕḿ àñđ à çöñţéñţ çéļļ çàŕŕý locale àñđ region.

Éṽéñţš​

type AtlasEvent struct {
ID string `json:"id"`
At time.Time `json:"at"` // recorded clock
Effective *time.Time `json:"effective,omitempty"` // effective clock when it differs
Kind string `json:"kind"` // an operation kind | term-added | window-opens | window-closes
Record string `json:"record,omitempty"` // the record it bears on
Actor *contextop.Actor `json:"actor,omitempty"`
Label string `json:"label,omitempty"`
}

Éàçĥ çöñţéẋţ öþéŕàţîöñ þŕöđüçéš àñ éṽéñţ àţ ţĥé îñšţàñţ ţĥé ļöĝ àççéþţéđ îţ. record ñàḿéš ţĥé ŕéçöŕđ öƒ ţĥé öþéŕàţîöñ'š šüƃĵéçţ ŵĥéñ ţĥàţ ŕéçöŕđ îš îñ ţĥé àţļàš. À ŕéçöŕđ ŵîţĥ à ŵîñđöŵ þŕöđüçéš window-opens àñđ window-closes éṽéñţš. Ţĥéîŕ at îš ţĥé îñšţàñţ ţĥé ŵîñđöŵ ŵàš šéţ, ƃý ţĥé öþéŕàţîöñ ţĥàţ ŕéçöŕđéđ ţĥé ŕéçöŕđ öŕ ƃý ţĥé ķééþ ţĥàţ àđđéđ ţĥé ŵîñđöŵ. Ţĥéîŕ effective îš ţĥé ƃöüñđ. À þŕöƒîļé ŵîţĥ à ṽàļîđîţý ŵîñđöŵ îñ ţĥé ŕéçîþé þŕöđüçéš ţĥé šàḿé ţŵö ķîñđš àţ îţš ƃöüñđš. Ţĥéšé éṽéñţš ĥàṽé ñö record, àñđ ţĥéîŕ at îš ţĥé ƃöüñđ. À çöñçéþţ ŵîţĥ à çŕéàţîöñ đàţé îñ ţĥé ţéŕḿš šţöŕé þŕöđüçéš à term-added éṽéñţ àţ ţĥàţ đàţé. Ţĥé ĥöšţ đöéš ñöţ ŕéàđ üñîţ đéçîšîöñš àñđ àđđš à ñöţé šţàţîñĝ ţĥàţ.

Éẋàḿþļé​

Ţŕîḿḿéđ ƒŕöḿ kapi context atlas --json --no-content öṽéŕ à çöþý öƒ ţĥé ĶàþîḾàŕţ đéšķţöþ šàḿþļé, àƒţéŕ kapi store import context àñđ öñé ñöţé ŕéçöŕđéđ öñ ţĥé Öšļö çàḿþàîĝñ'š þîçķ-üþ þàĝé ŵîţĥ --valid-to 2027-01-01. Ţĥé çöþý ĝîṽéš Ĝŕüñéŕļøķķà à shape: ƒîļé. Ţĥé ţéŕḿš, ţĥé îḿþöŕţ ŕéçöŕđš, ḿöšţ þļàçéš àñđ ţĥé àẋéš ţĥé éẋàḿþļé đöéš ñöţ ñééđ àŕé ļéƒţ öüţ.

{
"format": "kapi-context-atlas",
"version": 1,
"project": "KapiMart",
"generated_at": "2026-10-17T11:27:48.992071Z",
"span": { "from": "2026-08-30T20:51:47Z", "to": "2027-01-01T00:00:00Z" },
"axes": [
{ "id": "market", "label": "Market", "kind": "geo", "source": "declared",
"values": [
{ "id": "nordics", "label": "Nordics" },
{ "id": "greater-oslo", "label": "Greater Oslo" },
{ "id": "world", "label": "World" },
{ "id": "oslo", "label": "Oslo" },
{ "id": "grunerlokka", "label": "Grünerløkka" }
] }
],
"places": [
{ "id": "europe", "name": "Europe", "type": "region", "within": ["world"] },
{ "id": "greater-oslo", "name": "Greater Oslo", "type": "metro", "of": ["no-03", "no-32"], "declared": true },
{ "id": "grunerlokka", "name": "Grünerløkka", "type": "neighbourhood", "within": ["oslo"],
"shape": "places/grunerlokka.geojson",
"geometry": { "type": "Polygon", "coordinates": [[[10.744, 59.918], [10.772, 59.918], [10.772, 59.934], [10.744, 59.934], [10.744, 59.918]]] },
"declared": true },
{ "id": "no", "name": "Norway", "type": "country", "within": ["northern-europe"], "centroid": [60.47, 8.47] },
{ "id": "no-03", "name": "Oslo", "type": "subdivision", "within": ["no"] },
{ "id": "no-32", "name": "Akershus", "type": "subdivision", "within": ["no"] },
{ "id": "nordics", "name": "Nordics", "type": "territory", "of": ["no", "se", "dk", "fi", "is"], "declared": true },
{ "id": "northern-europe", "name": "Northern Europe", "type": "region", "within": ["europe"] },
{ "id": "oslo", "name": "Oslo", "type": "locality", "within": ["no-03"], "centroid": [59.91, 10.75],
"refs": ["wikidata:Q585", "geonames:3143244"], "declared": true },
{ "id": "world", "name": "World", "type": "world" }
],
"records": [
{
"id": "0q9c74dgngmdpc5ph1rd180r",
"family": "note",
"label": "The pick-up page names the street and the park nearest to it.",
"weight": 1,
"coordinates": {
"actor": "person", "age": "13-17", "audience": "shoppers", "brand": "kapimart",
"channel": "marketing", "family": "note", "lifecycle": "current",
"market": "grunerlokka", "product": "kapimart"
},
"recorded": "2026-10-17T11:27:48.623464Z",
"valid_to": "2027-01-01T00:00:00Z",
"history": [ { "at": "2026-10-17T11:27:48.623464Z", "state": "suggested" } ],
"short": "0q9c74dgng",
"actor": { "kind": "person" },
"evidence": [ { "path": "campaigns/oslo/en/grunerlokka.md", "quote": "Our newest pick-up point is on Thorvald Meyers gate" } ],
"text": "The pick-up page names the street and the park nearest to it.",
"scope": "project age=13-17,audience=shoppers,brand=kapimart,channel=marketing,lifecycle=current,market=grunerlokka,product=kapimart until 2027-01-01"
}
],
"events": [
{ "id": "0q9c74dgngmdpc5ph1rd180r", "at": "2026-10-17T11:27:48.623464Z", "kind": "observe",
"record": "0q9c74dgngmdpc5ph1rd180r", "actor": { "kind": "person" },
"label": "The pick-up page names the street and the park nearest to it." },
{ "id": "window-closes:0q9c74dgngmdpc5ph1rd180r", "at": "2026-10-17T11:27:48.623464Z",
"effective": "2027-01-01T00:00:00Z", "kind": "window-closes",
"record": "0q9c74dgngmdpc5ph1rd180r",
"label": "The pick-up page names the street and the park nearest to it." }
],
"notes": [
"Read 5 context operations of this project.",
"Unit decisions are not read into the atlas; `kapi status` reports them."
]
}

Ţĥé ñöţé šîţš àţ grunerlokka, ţĥé çöñţéñţ îţéḿ'š þöîñţ, ŵĥîçĥ ļîéš îñšîđé ţĥé çàḿþàîĝñ'š oslo. places ĥöļđš ţĥé çĥàîñ ƒŕöḿ ţĥàţ þļàçé üþ ţö ţĥé ŵöŕļđ. Ţĥé ƒüļļ đöçüḿéñţ àļšö ļîšţš éṽéŕý Ñöŕŵéĝîàñ çöüñţý àñđ éṽéŕý çöüñţŕý îñ Éüŕöþé, ŵĥîçĥ ţĥé ḿàþ ñééđš ţö đŕîļļ ƒŕöḿ ţĥé ŵöŕļđ đöŵñ ţö ţĥé ñéîĝĥƃöüŕĥööđ.

Đŕàŵîñĝ ţĥé þļàçéš​

Ţĥé ḿàþ îñ @neokapi/context-atlas đŕàŵš places öṽéŕ ƃüîļţ-îñ öüţļîñéš ţĥàţ šĥîþ îñ ţĥé þàçķàĝé üñđéŕ src/geo/:

ƑîļéĤöļđšĶéýéđ ƃý
world.jsonéṽéŕý çöüñţŕý, öƃĵéçţ countriesÎŠÖ 3166-1 àļþĥà-2 îñ ļöŵéŕ çàšé (no)
admin1/<cc>.jsonöñé çöüñţŕý'š šüƃđîṽîšîöñš, öƃĵéçţ subdivisions, àñđ îţš öüţļîñé, öƃĵéçţ outlineÎŠÖ 3166-2 îñ ļöŵéŕ çàšé (no-03)

Ƃöţĥ àŕé ŢöþöĴŠÖÑ, šîḿþļîƒîéđ àñđ ǫüàñţîšéđ. Ţĥé ŵöŕļđ ƒîļé ļöàđš ŵîţĥ ţĥé ḿàþ. À çöüñţŕý'š ƒîļé îš à šéþàŕàţé çĥüñķ, ļöàđéđ ŵĥéñ ţĥé ḿàþ đŕîļļš îñţö ţĥàţ çöüñţŕý. Ţĥé đàţà îš Ñàţüŕàļ Éàŕţĥ (þüƃļîç đöḿàîñ) àţ à þîññéđ ŕéļéàšé: ţĥé àđḿîñ-0 çöüñţŕîéš àñđ ţĥé àđḿîñ-1 šţàţéš àñđ þŕöṽîñçéš. Ŵĥéŕé Ñàţüŕàļ Éàŕţĥ ƒîļéš šüƃđîṽîšîöñš üñđéŕ àñ ÎŠÖ 3166-2 ŕéĝîöñ, ţĥé ŕéĝîöñ'š šĥàþé îš ţĥé üñîöñ öƒ îţš þàŕţš àñđ îš ķéýéđ ƃý ţĥé ŕéĝîöñ'š îđ (fr-ara).

scripts/build-geometry.mjs ŕéĝéñéŕàţéš ţĥé đîŕéçţöŕý:

vp run @neokapi/context-atlas#build-geometry

Îţ đöŵñļöàđš ţĥé ţŵö Ñàţüŕàļ Éàŕţĥ ƒîļéš àţ ţĥé þîññéđ ŕéļéàšé, çĥéçķš ţĥéîŕ ŠĤÀ-256 đîĝéšţš, ķéýš éṽéŕý ƒéàţüŕé ƃý þļàçé îđ, šîḿþļîƒîéš éàçĥ šĥàþé ŕéļàţîṽé ţö îţš šîžé, àñđ ŵŕîţéš ţĥé ŢöþöĴŠÖÑ. --cache <dir> ŕéàđš ƒîļéš àļŕéàđý đöŵñļöàđéđ ţö <dir>. Ñàţüŕàļ Éàŕţĥ çàŕŕîéš šöḿé šüƃđîṽîšîöñš üñđéŕ à çöđé ţĥàţ ÎŠÖ 3166-2 ĥàš šîñçé ŕéþļàçéđ, öŕ öñļý àš ţĥé þàŕţš öƒ à çüŕŕéñţ šüƃđîṽîšîöñ. Ƒöŕ éàçĥ öƒ ţĥéšé, scripts/geometry-successors.json ļîšţš ţĥé çüŕŕéñţ îđ, ţĥé ƒéàţüŕéš ţĥàţ çöḿþöšé îţ, àñđ ţĥé ÎŠÖ çĥàñĝé öŕ þàŕéñţ ŕéļàţîöñ ƃéĥîñđ ţĥé ḿàþþîñĝ. Ţĥé šçŕîþţ üñîöñš ţĥé þàŕţš. Ţĥé ƃüîļđ ƒàîļš öñ à ŕöŵ ţĥàţ ñàḿéš à çöđé ḿîššîñĝ ƒŕöḿ Ñàţüŕàļ Éàŕţĥ, öŕ àñ îđ ţĥàţ Ñàţüŕàļ Éàŕţĥ àļŕéàđý çàŕŕîéš. src/geo/README.md ļîšţš ţĥé ŕéļéàšé, ţĥé ļîçéñçé àñđ ţĥé îđš ţĥàţ ĥàṽé ñö öüţļîñé.

À þļàçé ŵîţĥ ñö öüţļîñé îñ éîţĥéŕ ƒîļé îš đŕàŵñ àţ îţš çéñţŕöîđ ŵĥéñ îţ ĥàš öñé, àñđ îš öţĥéŕŵîšé ļîšţéđ ƃéšîđé ţĥé ḿàþ. Ţĥé öüţļîñéš àŕé üšéđ öñļý ƒöŕ đŕàŵîñĝ. Çöñţàîñḿéñţ çöḿéš ƒŕöḿ ţĥé within àñđ of đéçļàŕàţîöñš.

Çöšţ​

Ţĥé ĥöšţ ŕéàđš ţĥé öþéŕàţîöñ ļöĝ öñçé ƒöŕ ţĥé ŕéçöŕđš àñđ öñçé ḿöŕé ƒöŕ ţĥé ĥîšţöŕîéš. Ţĥé ĥîšţöŕý þàšš ƒöļđš ţĥé ļöĝ àţ éàçĥ đîšţîñçţ îñšţàñţ, üþ ţö contextop.HistoryLimit îñšţàñţš. Ţĥé ĥöšţ ŕéàđš ţĥé ŵĥöļé ţéŕḿš šţöŕé, àš kapi context search đöéš. Ƒöŕ çöñţéñţ çéļļš îţ ŕéàđš éṽéŕý ƒîļé öƒ ţĥé þŕöĵéçţ öñçé þéŕ ţàŕĝéţ ļàñĝüàĝé, àš kapi status đöéš. Îţ ķééþš ţĥé çöüñţš àñđ đîšçàŕđš ţĥé ƃļöçķš.