Imported from LrWm3/ancient-world (
AGENTS.md). Install upstream withnpx skills add LrWm3/ancient-world. Copyright stays with the author.
Repository artifact policy
Keep commits source-only: source code, editable catalogs, tests, documentation and
human-readable Markdown test summaries. Do not commit experiment binaries,
compressed results, raw logs, trajectories, generated images, or run manifests.
Write generated experiment outputs under ignored output/ and summarize settings,
results, failures and limitations in Markdown. Existing experiment scripts can
produce local artifacts but those artifacts must not be added to Git.
Run python3 scripts/check_repository_artifacts.py before committing.
Continue committing and pushing normal work as requested by the user. The
single-commit history rewrite was a one-time cleanup; do not routinely rewrite
published history.
Tools for developing simulation systems
Use the existing monthly scheduler and explicit allocation policies to integrate systems. Treat timing and allocation as separate design choices; do not introduce a scheduler rewrite merely to change which competing claim receives resources.
Monthly history phases
Read the monthly schedule and the relevant phase in
src/civilization.rs before adding or moving monthly work. The coordinator uses
five stages:
| Phase | Integration responsibility |
|---|---|
| Open | Apply due arrivals and policies, establish current observations and availability. State which inputs describe this month versus a previously completed interval. |
| Reserve | Forecast requests, resolve competing claims, and commit bounded work/resources. Pass dated plans to execution rather than recomputing them after other claimants spend capacity. |
| Execute/settle | Execute granted work and settle actual use, outputs and shortfalls. Keep requested, allocated, reserved and completed work distinct. |
| Respond | React to completed outcomes and schedule subsequent actions. Preserve explicit same-month exceptions and causal event visibility; decisions cannot retroactively change completed production. |
| Close | Refresh derived summaries, reconcile and validate the completed boundary, and record history using the existing frozen/living-history rules. |
These are the existing timing contracts, not a requirement to move every legacy operation into an idealized phase. When changing a subsystem, identify its input boundary, reservation point, execution/settlement point and when its outputs become visible. Follow the actual coordinator for due deliveries, prior-month crew funding and living ecological returns. Events remain attached to committed actions; do not defer all event creation to Close.
Run each monthly operation once per simulated month, independent of batch size. Do not reuse stale grants, count transfers twice or backdate released work into production. For timing changes, add focused boundary tests and check monthly, batched and checkpoint-resumed execution where relevant. Reordering independent actors can test accidental iteration dependence; shuffling causally dependent phases changes the model's rules.
Explicit allocation policies
Use the service allocation pilot and
src/service_allocation.rs as a pattern for competing claims:
- Identify the resource pool, its scope and the allocation boundary.
- Collect feasible requests before either claimant consumes the shared pool.
- Apply an explicit policy to obtain demand-capped allocations.
- Match eligible participants and enforce money, material and capacity limits before committing actual reservations.
- Retain receipts showing requests, allocations and reservations; use existing work receipts for actual completion and release.
The current pilot covers research and cultural work only. Configure it through
History.service_allocation.policy: ResearchFirst preserves existing priority;
Weighted { research, culture } provides positive relative weights and redistributes
entitlement above demand. Research-first is the default, including old archives;
weighted sharing is opt-in. Policies and latest boundary receipts persist with
history and appear in the service-work report.
Do not infer that all services now share fairly: care and committed crews still precede this window, workshops/additional crews follow it, and individual matching retains ordering effects. Site entitlement cannot create a qualified teacher, available worker, money or materials. The service pool is only a bounded part of total labor, not the entire workforce.
Extend this pattern selectively. Before applying it to a different pool, define eligibility, joint funding/resource requirements, minimum useful grants and what happens to unfillable allocations. Do not force the two-claim implementation onto unrelated resources or change execution order to express a sharing preference.
For allocation changes, compare policies against identical opening requests, include inactive-demand and unavailable-participant controls, and verify finite budgets and continuation consistency. Inspect completed work as well as grants: more even shares can fail to complete indivisible tasks. Record results and limits in Markdown; conservation and determinism alone do not establish good balance.
For indivisible work, see institutional election requests in
src/culture/work_requests.rs: check the request's minimum useful grant against
both the shared allowance and an eligible participant's availability before
reserving. An unfundable election should leave capacity for divisible upkeep;
reserving and later expiring a known-unusable partial grant needlessly starves
other work. Execution still rechecks eligibility and the required grant.
Culture.institution_priority is a second scoped allocation example: Stable or
Rotating priority within election, upkeep and administration requests. Dated plans capture the
policy and order; execution consumes their grants. Keep the same opening requests
and total allowance when comparing policies. The controlled comparison in
docs/institution-allocation-balance.md shows why equal turns do not by themselves
guarantee viable outcomes under severe scarcity.
Culture.institution_work_policy separates priority between institutional duties
from member ordering within a duty. The opt-in EssentialFirst policy grants
basic upkeep and named administration before adding repair time to the same
upkeep member's commitment. It uses the original request and shared allowance;
execution order is unchanged. See WorkPlan::reserve_institution_work and
institutional operating budgets. Preserve
minimum useful grants and live participant limits when extending this pattern.
Council money has another scoped example in
src/household_economy/council_allocation.rs and
the administration allowance.
ProtectAdministration caps household relief against a current administrative
forecast; it does not escrow funds or guarantee Respond-phase payment. Keep
forecast, grant and actual transfer separate, and compare household food access
with completed service payments. The allowance-only century comparison is mixed;
do not assume protecting a reserve improves outcomes.
Annual town support is a different claim: Society.town_support_policy can
request either the legacy hunger-triggered ceiling or the gap to a working-cash
target. It retains annual timing and shared council money. Tax/support observations
record the actual boundary, rather than treating ending treasury as evidence of
revenue adequacy. These policies do not establish universal council allocation.
Named simulation parameters
Keep meaningful rates, thresholds, durations and costs as UPPER_SNAKE_CASE
constants immediately after imports in the owning file. Include units where useful
(e.g. TRAVEL_KM_PER_MONTH). Leave trivial numeric identities, indexing and
independent test fixtures inline. Editable catalog values remain catalog data.
If several files implement the same policy, define its constant once in their
shared subsystem module; do not create a project-wide consts.rs. Equal numeric
values do not necessarily represent the same policy. During extraction, preserve
numeric types, values and arithmetic order; balance changes belong in a separate
change. Track the ongoing file-by-file cleanup in
the constants cleanup record.