Skip to content

Latest commit

 

History

History
145 lines (98 loc) · 14.4 KB

File metadata and controls

145 lines (98 loc) · 14.4 KB

Development System

Status: Process document for the development ratchet that produced Entarium 1.0.0. That ratchet is currently idle: there is no current work item, and nothing beyond 1.0.1 is scheduled.

Entarium was built by a series of sessions that share no memory. A session may be a coding agent with an empty context window, or a human returning after a month. Either must be able to open this repository, learn where development stands, do the next correct thing, and leave the repository ready for the next session.

The repository carries that state. Conversation history does not.

This document defines the mechanism. It does not restate the architecture — docs/architecture/generalized-multi-entity-system.md is authoritative for that and defines decision precedence in its §2.

The files

A small fixed set, each with one job. Nothing here duplicates another file's authority.

File Answers Authoritative for
state.md Where are we right now? Current phase, milestone, and work item; that item's execution status; blockers; validation status. For 1.0.1: complete, idle
roadmap.md Where did this go? Historical phase sequence and exit criteria. Not an active committed plan
phases/ What exactly is the work? Work-item definitions and their plan disposition
log.md What has happened? Completed history, in order, with what each item produced
backlog.md What did we notice but not do? Unscheduled discoveries
continuation-prompt.md How does a fresh session start? The standard prompt
This file How does any of this work? The session contract and the rules below

A fresh session reads state.md first and continuation-prompt.md never — the prompt is for the human pasting it.

Hierarchy

Phase — a long-range stage with a single architectural purpose and explicit exit criteria. P1, P2, … Phases complete in order.

Milestone — a meaningful capability increment inside a phase. P1-M3. A milestone completes when its work items are done and its stated capability is demonstrable by test.

Work item — one executable unit of development, sized for one focused session. IDs are W-0001, monotonic across the whole project, allocated once and never reused, never renumbered.

Work-item IDs are deliberately independent of phase and milestone numbering. Plans get revised; items get split, dropped, and resequenced. An ID that encodes its position in the plan becomes a lie the first time the plan changes, and history that cites it becomes unreadable. An item records which milestone it belongs to; the milestone does not own its numbering.

A new ID is one above the highest that appears anywhere under docs/development/ — phase files, the log, and the backlog included. Reusing an ID, even for a dropped item, breaks history.

Work-item disposition

The phase file records exactly one disposition per item.

Disposition Meaning
planned Defined. Not yet done. Eligible or not depending on its prerequisites.
done Acceptance criteria verified. Logged. Never reopened — a later correction is a new item.
split Superseded by child items, which are listed on it. Not a failure state.
dropped No longer needed. The reason is recorded on the item.

Transient execution status — ready, in-progress, blocked, needs-decision — is not recorded in the phase file. It applies to exactly one item at a time and lives in state.md. This is the reason there is no status field to keep synchronized in two places.

in-progress is for one situation only: a session ends with partial work deliberately left in the working tree. Sessions do not claim an item on entry — a status set at the start of every session would be stale every time one died, which is exactly when it would be trusted.

Eligible means: every prerequisite is done, and the item does not depend on an unresolved blocker. Where several items qualify, state.md names the one that comes first in its phase file.

Completing the last item of a milestone is also where the milestone's stated capability gets confirmed: the session says in its log entry which test demonstrates it. Completing a phase is not implicit — every phase ends with an exit-review work item that verifies the phase exit criteria against the repository and elaborates the next phase.

A session, start to finish

  1. Orient. Read state.md. It names the current work item and its status. If the status is blocked or needs-decision, follow When something goes wrong below rather than starting work. If the current work item is none (or status is complete with no next item), the ratchet is idle: stop and report; do not invent work, and do not promote entries marked MANUAL-REACTIVATION-ONLY in backlog.md.
  2. Read the minimum. Open the work item in its phase file. Read only the architecture sections and ADRs it names. The item is written so that this is sufficient; reading the whole repository is a failure of the item, not of the reader. Report it if it happens.
  3. Confirm prerequisites. Check that each prerequisite is done in the phase file. If one is not, stop — the state pointer is wrong, and fixing that is the session's work.
  4. Inspect what exists. Read the code the item names before writing any. Match the conventions already there.
  5. Consult references only when the item says so. Work items name a reference repository when source inspection is plausibly valuable, and name none when it is not. none is a real answer and the common one. Never inspect the whole set.
  6. Implement. Build what the item scopes and nothing it declares a non-goal.
  7. Validate. Run the repository's validation command, documented in the root README.md from W-0002 onward. Every acceptance criterion must be demonstrably satisfied, and satisfaction means a test, not an inspection, wherever a test is possible. Separable commands outside that validation — today provider_suite/, scripts/consumer_smoke.py, scripts/panel_consumer.py, scripts/cross_domain_entity.py, and scripts/release.py — are run when the work item names them; they are not implied by scripts/check.py.
  8. Fix failures in scope. Failures your change caused are yours. Pre-existing unrelated failures go to backlog.md and are named in the report.
  9. Feed back. Apply the architecture feedback rules below. Most sessions change no architecture; that is the expected outcome, not a shortfall.
  10. Close. Perform the completion contract.
  11. Report. What changed, what was validated, what was decided, what was discovered, what is next. Do not commit unless the user asks.

Completion contract

A session may end successfully only when all of these are true. If any is false, the session ends with an honest non-success state instead.

  • The work item's scope is implemented and its non-goals were respected.
  • Every acceptance criterion is verified, by test where a test is possible.
  • The validation command passes, and no unrelated failure was introduced.
  • The architecture document and accepted ADRs are still accurate descriptions of the code.
  • Documentation the item requires is updated in the same change.
  • Any reference repository that materially informed the work is recorded in docs/external-references/ with the finding and the reviewed commit SHA.
  • An ADR exists for any durable decision actually made — and not for anything else.
  • The item is marked done in its phase file.
  • A log.md entry exists for it.
  • state.md advances to the next eligible item, with the reason it is next.
  • Discoveries are captured in backlog.md, or promoted to work items where they change what should be built next.
  • Nothing is committed unless the user explicitly asked.

Marking the item done, logging it, and advancing state.md are what make the system a ratchet. A session that implements perfectly and leaves the state pointer unchanged has failed, because the next session will do the work again.

When something goes wrong

The rule underneath all of these: an item is done only when its acceptance criteria are verified. Never mark an item done to record effort, progress, or good intentions. A truthful blocked state is worth more than a false completion, because the next session trusts this file.

Situation What to do
Tests fail and the fix is outside the item's scope Leave the work in place. Set the item to blocked in state.md with the failing test, what you tried, and what would unblock it. Log a blocked entry.
Implementation contradicts the architecture Stop implementing. Write an ADR with status Proposed stating the contradiction and the options. Set the item to needs-decision in state.md, naming the ADR. Do not resolve it inside the work.
The item needs a decision listed as deferred in architecture §13 Same as above, unless resolving that decision is inside the item's declared scope — some items exist precisely to settle one.
Required infrastructure, credentials, or a human choice is unavailable blocked, stating exactly what is needed from the human. Do not invent a substitute that changes semantics.
The item is larger than one session Split it. Create child items with new IDs in the phase file, set the parent to split listing them, log a split entry, and point state.md at the first child. Do not silently do half and call it done.
An unrelated bug is discovered One line in backlog.md. Keep going. Do not fix it inside this item unless it blocks the item.
Implementation proves a later part of the plan wrong Revise the future items, log a replanned entry with the evidence, and continue. Never edit completed history to match the new plan.
state.md disagrees with the phase file or the code Treat reconciling them as the session's first work. Evidence in the code and tests outranks all three planning files. Log what was wrong.

If the current item is blocked and cannot proceed, a session may take the first eligible item that does not depend on the blocker, recording the switch and the reason in state.md. If no such item exists, the session stops and reports. It does not skip ahead to more interesting work, and it does not weaken the blocked item's acceptance criteria to get past it.

Architecture feedback rules

Implementation is expected to improve the design. It is not expected to generate documentation churn. These rules separate the two.

Update docs/architecture/generalized-multi-entity-system.md when implementation shows that a stated boundary, invariant, responsibility, or concept is wrong, ambiguous, or unenforceable as written — or when the architecture is silent on something the implementation was forced to decide structurally. Revise it holistically; do not append addenda. Review AGENTS.md, .cursor/rules/, and the ADRs for consistency in the same change.

Do not update it because a data structure, module layout, file name, function signature, library, or test approach changed. Those are implementation facts. The architecture describes what must be true, not how it currently is.

Write an ADR when a decision creates a durable constraint: a foundational technology choice, a persistence-semantics commitment, a change to a core boundary, a resolution of a deferred §13 decision, or anything that would be expensive to reverse and that a future reader would otherwise have to reverse-engineer. ADRs are numbered sequentially and never rewritten after acceptance — a later ADR supersedes an earlier one and says so.

Do not write an ADR for routine implementation choices, naming, structure, or anything a future session could change freely without consulting anyone.

Update engineering policy in docs/engineering/ when the rule for making a class of decisions changed — not when one decision was made under the existing rule.

Update docs/external-references/ in the same change whenever inspecting a reference repository materially influenced the work. Record the finding, cite the upstream path, and record the reviewed commit from git -C ../references/<repo> rev-parse HEAD. An uncaptured finding is a claim the next reader cannot check.

Update the roadmap or a phase file when implementation evidence changes what should be built next, in what order, or what a future item must contain.

The test for all of these: would the next session be misled if this file stayed as it is? If yes, update it. If no, leave it alone.

History

log.md records development progression, not diffs. Git remains the source for exact code history; the log answers what was completed, in what order, which item produced it, what it decided, and what changed the plan.

One entry per state change worth remembering — completed, blocked, split, replanned, or decision. Entries are appended, newest first, and are never edited after the fact. A later entry corrects an earlier one; it does not overwrite it.

Keeping this system honest

The failure modes this structure is built to avoid, stated so they are recognizable:

  • Status recorded in several places and quietly diverging. There is one status field per item, in one file.
  • Work items whose only completion criterion is that code exists.
  • Speculative decomposition. Later phases stay coarse until implementation evidence justifies breaking them down. Inventing a hundred future items produces a plan that is wrong in a hundred places.
  • Plans specified so tightly that ordinary engineering judgment becomes a deviation. A work item constrains outcomes and boundaries; it does not dictate implementations.
  • Planning documents that silently encode a deferred architectural decision. If an item requires one, it says so and stops.
  • Advancing the state pointer past failing tests.
  • Documentation updated because a session felt productive rather than because something was learned.
  • A deliberate-break confirmation that proves less than it appears to. When a phase requires breaking an implementation to confirm a test catches it, the break goes into production code and the test that must fail is the one the phase matrix names for that row. A break caught only by some other file in the suite is a finding about the row's test, not a confirmation of it, and a break aimed at a different claim than the row states is not a confirmation of that row at all. W-0061 found both mistakes in a phase whose entries said the confirmations had been done.