Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

engineering-kit

Keep a project's reasoning alive after its author has forgotten it. Three artefacts, one checker, no dependencies.

A decision log where every entry carries the condition that should reverse it. A risk register where every risk has a signal you could actually notice. A charter that says what the project refuses to do. And a checker that fails the build when any of those quietly stops being true.

pip install git+https://github.com/muhammad1502/engineering-kit

cd your-project
kit init      # writes six starter files, overwrites nothing
kit check     # fails until you have actually filled them in

Not on PyPI yet, so the install is from git. Everything also works with no install at all: clone the repo and run python -m kit ... from it.

The three failures this is against

Decisions lose their conditions. A log records what was chosen and stops. A year later nobody can tell whether the choice was load-bearing or arbitrary, so every revisit is argued from scratch. The fix is one required field: what observation should make a future reader reopen this.

Risks lose their signal. A register lists what could go wrong and rates it, but omits what you would notice first. A risk with no signal cannot be watched, only suffered. And a risk owned by "the team" is owned by nobody.

Prose drifts away from measurement. This one is the reason the kit has a checker at all, and the story is in D-005. A real project measured its implementation size, wrote the figure into its README next to a stated budget, then grew the code. The generated report was updated. The README was not, and the stale number was the first thing a reader saw. That project was scrupulous: it pre-registered its benchmarks, ran significance tests, and published results that went against its own thesis. It still shipped a stale headline number, because nothing failed when the prose and the artefact diverged. Care was not sufficient. That is what a pin is for.

Claim pinning

Attach a claim in prose to the artefact it came from:

The parser is 658 lines. <!-- kit:verify file=bench/report.md contains="658" -->

kit check fails when bench/report.md stops containing 658, and says the prose has drifted rather than that a test broke. The opposite form asserts something is gone:

The legacy path is removed. <!-- kit:verify file=src/app.py absent="legacy_handler" -->

Pins inside fenced code blocks are ignored, which is why the two examples above are safe to ship. Pin figures a reader would repeat back to you: sizes, ratios, counts, latencies. Do not pin prose that a reasonable edit would change, or the check becomes noise people learn to ignore.

What the checker enforces

Rule Level Catches
decisions error An entry missing context, options, decision, or reversal condition. Duplicate ids. Gaps warn.
risks error A row with no signal, no mitigation, or no owner. Likelihood, impact, or status outside the vocabulary.
charter error A charter with no mission, non-goals, operating rules, or kill criteria.
pin error A pinned figure whose source no longer contains it.
placeholder error Scaffolded template text nobody replaced.
claim warn A superlative with no citation, pin, or code reference on the same line. --strict promotes it.

Three label styles are accepted for decision fields, so the rules bend to your formatting rather than the reverse:

**Context.** ...        bold label
Context: ...            plain label with a delimiter
#### Context            a sub-heading

Usage

kit init                          # scaffold; never overwrites without --force
kit check                         # validate; exit 1 on any error
kit check --strict                # unsupported claims fail too
kit new decision "Short title"    # append a numbered stub with all four fields
kit new risk "Short description"  # append a row with the vocabulary pre-filled

Paths are configurable if your layout differs:

kit --decisions docs/decisions.md --risks docs/risks.md check

Everything also works as python -m kit ..., with no install, straight from a checkout.

Wiring it into CI

kit init writes .github/workflows/discipline.yml. The whole job is:

- uses: actions/setup-python@v5
  with: { python-version: "3.12" }
- run: pip install git+https://github.com/muhammad1502/engineering-kit
- run: kit check

No services, no cache, no dependency resolution. It runs in seconds.

Adopting it in a project that already exists

  1. kit init, then delete any artefact you already have in another form and point the flags at yours instead.
  2. Write the charter's non-goals first. It is the section that pays for itself, because each entry removes a category of future argument.
  3. Backfill the five decisions you would most hate to re-derive. Not all of them. Five.
  4. Sweep risks by category rather than by imagination. The register template lists eight, and the useful finding is usually that the lethal risks are not technical.
  5. Turn on kit check in CI. Leave --strict off until the existing warnings are cleared, then turn it on so new ones fail.

An hour, and step 3 is most of it.

Honest limits

  • Structure is not substance. The checker verifies that a reversal condition exists. It cannot tell whether it says anything. "If it becomes a problem" passes. This is the ceiling of the approach, it is recorded as R5 with status accepted, and no amount of additional rules would fix it.
  • The claims rule is a heuristic over English. It will flag a fine sentence and miss a careful overclaim. It warns rather than failing for that reason (D-006), and for non-English prose it reports nothing at all (R7).
  • Markdown is parsed with regexes, not a parser. That is a deliberate consequence of taking no dependencies (D-003). Unusual documents may be misread; the validators have behavioural tests covering the forms encountered so far.
  • Indented code blocks are not skipped, only fenced ones. Missing a real pin is worse than flagging an example, so the ambiguous form is not treated as code (D-008).
  • The pre-release checklist is prose, not enforced. It ships with init and nothing checks that you ran it (R9).

It runs against itself

The kit's own charter, decision log, and risk register are the fixtures its CI validates. A decision added here without a reversal condition fails the build, the same as it would in your project.

CI also asserts that a fresh scaffold fails check, and fails specifically with placeholder findings. A template that passed silently would let a project adopt the kit, show a green check, and record nothing (D-004).

Tested on Python 3.9 through 3.13.

No dependencies.

Where this came from

The method is borrowed, with thanks, from SyedSaribSultan/sarib-lang, which practises it at a level worth studying: a charter with kill criteria written before the work, decisions logged with reversal conditions, a scored risk register whose headline finding is that the lethal risks are human, and benchmarks with pre-registered grading that publish their negative results. The stale-number failure that motivated claim pinning was found in that repository, which is the least important thing about it.

Licence

MIT. See LICENSE.

About

Keep a project's decisions, risks, and claims honest. A decision log that requires reversal conditions, a risk register that requires signals, and a dependency-free checker that pins prose to the artefacts it quotes.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages