Project records for coding tools
Coding tools rewrite the repository to match whatever they can see. On NRTR they could see the files in the prompt and nothing about why those files look that way. Generated changes then took weeks to bring back in line with the design. About 1,900 records now sit on a codebase of about 500,000 lines, each tied to a file or a function. After tools had to read those records before editing, the generated code we threw away fell by about 90 percent.
What was going wrong
A tool asked to “add validation” will invent a validation style. NRTR already had one: a fixed error code, a list of fields, and a rule that the client does not guess types. The tool could not see that rule unless someone pasted it. People pasted different slices. The tool satisfied the slice and broke the rule next to it.
The same gap showed up in the move off hosted data. The old system was more than 100 stores and about 30 workflows. We could rebuild it with two people in about two days only because those stores and workflows were already described, and the descriptions pointed at the code. Without that, the rebuild would have been archaeology.
What one record contains
A record that does not name a file is deleted or attached. Advice that floats free gets pulled into the wrong task.
| Field | Write this | Do not write this |
|---|---|---|
| Path | The file or symbol this record describes. | A folder, a theme, or “the backend.” |
| Job | One sentence on what this code owns. | A tour of the file. |
| Rules | Names, error shapes, and boundaries an edit has to keep. | A style preference with no consequence. |
| May call | The parts it is allowed to use. | A list of every import, restated from the source. |
| Must not call | The boundary it keeps breaking if you do not say so. | Nothing. If you leave this empty, the tool will cross the boundary. |
| Decision | The constraint you cannot see from the code alone. | A restatement of the function name. |
Example, shortened:
path: services/observations/validate.py
job: Reject an observation that breaks the code, value, unit, or time rules.
rules: error code is validation_failed. Fields are a list of name and reason. Do not coerce types.
must not call: vendor clients. Unit conversion.
decision: The stored row must match what the caller sent. Conversion is a different operation.
The loop
Source change → records whose paths overlap that change are stale → tool asks for records by path → if none return, the tool stops → edit → update only the records the edit touched
Python jobs mark a record stale when the source it names changes. A person or a tool then rewrites the record from the new source. The tool is instructed to read before it writes. “Instructed” is not the control. The control is: no records, no edit.
Procedure: change observation validation
This is a procedure for a change we have actually made. Use it as the pattern.
- Name the files. For a validation change, that is the validator and the place the error body is built.
- Retrieve the records for those paths, plus the record that states the error shape for the whole boundary.
- If retrieval returns nothing, stop. Write the record from the current source, then start again. Do not let the tool guess.
- Change the rule in the validator. Keep
validation_failedand thefieldslist unless the task explicitly changes the contract. A contract change updates Record a health observation in the same change. - Run one known bad body and one known good body. Bad returns 400 and names the field. Good returns 201 and echoes value, unit, and time.
- Update the validator’s record so it states the new rule. Leave unrelated records alone.
When the records are wrong
| What you see | Likely cause | What you do |
|---|---|---|
| The tool “fixes” new code back to an old design. | The record is stale. Source moved and the record did not. | Regenerate that record from the current file. Do not argue with the tool. |
| The tool satisfies one rule and breaks another. | Two records describe one job and disagree. | Merge them. One job, one record. |
| The tool edits a file the task did not name. | A record has no path, so retrieval was broad. | Delete it or attach it to a file. |
| The edit is fine and the next session undoes it. | You did not update the record after the edit. | Update it now. The next session trusts the record over your memory. |
Rules that stay in force
- Every record names a path. A prompt with no path is how the earlier rewrites happened.
- When the record and the file disagree, the file wins. Rewrite the record from the file.
- The checks in the procedure still run, by a person or by a test.