PR-only. Never push to main.
This is the core. SCHEMA.md is the contract. README.md is the short
explainer. This file is the ops checklist, and the tenets live here.
Prefer it over the README when adding a company, changing the schema,
or previewing locally.
No em dashes in repo copy or docs.
MIT. Copyright (c) 2026 Kindel, LLC. Keep the copyright notice and permission notice in all copies.
All derivatives must link to https://kindel.com as part of attribution. A LICENSE file alone is not enough. Forks, ports, hosted copies, and generated apps that ship this work must include a visible link to https://kindel.com.
On kindel.com, these are Apps (canonical /apps/; /tools/ is an alias).
This repo owns the tenets. Before any change in this repo, and before any work that changes the model, schema, or data, study the Tenets section below. Do not start from memory.
- The explainer is
README.md. - The tenets are in this file.
- The schema is
SCHEMA.md. - The data is
data/index.json,data/facets.json,data/<company>/<slug>.json,data/teaching/<company>/, anddata/maps/generic-amazon.json(which universal principle an Amazon wording maps onto).
Downstream apps consume this and must not fork a private copy.
No UI lives here. Passing validate.py means the records are well formed. It
does not mean anyone can see them.
-
A Principle is a Tenet About People. A leadership principle is a tenet whose endeavor is an organization and whose subject is human behavior, so we hold it to the tenet bar: one idea and a trade-off a person can act on. A set that reads as slogans is a set we have not finished modeling.
-
Behavior is the Unit. A principle earns its place by decomposing into behavior a person can observe, teach, and live with the appropriate balance. A behavior we cannot show under indexed, balanced, and over done is a slogan, and we model it or drop it.
-
Facets Compose, Wordings Differ. Companies carve the same behavior into different principles, so their sets rarely line up one to one. The facet is the granular piece that does line up, and we compose principles from facets rather than re-authoring one behavior per company.
-
Level and Role Change What Counts, Not What Good Looks Like. Over doing it looks the same for a junior and an exec, so calibration does not move with level or role. What moves is which behaviors carry weight and the scope expected, and the behavior is written once and projected, because an app that keeps its own copy per level cannot be compared with the app beside it.
-
The Core Owns the Model, Apps Own the Experience. The core holds the lexicon, the taxonomy, the composition rules, and the code that enforces them. Apps hold questions, prompts, manuals, and pages, and an app that reimplements the model has forked it.
-
Company is a Parameter, Never a Constant. No code branches on a company's name, and every lookup, path, and cache key carries the company. A bare id fails silently, because
dive-deepis four different principles. -
The Check is the Contract. A new rule ships with the check that fails on it, or it is a suggestion. A rule only a human enforces is already broken somewhere in the tree.
-
Break in the Open. The core changes shape when the model demands it, and apps follow. A breaking change ships with the issues and pull requests that fix each app, so we accept the breakage and never the silence.
-
A Copy is Generated and Verified, or It Does Not Exist. An app that must serve the model from its own origin generates its copy from a pin and fails its build on drift. A copy a human keeps in step is drift with a delay.
Unless you know better ones.
.kindel/consumers.txt is the list. The cascade pings those repos when
data/** lands on main. Today that is:
kindel/porridge, the user's manual. Hugo mounts this module'sdata/and renders it. Teaching prose isdata/teaching/<company>/when that company has it. Amazon is required. A new company needs one content stub per principle undercontent/porridge/<company>/, whichscripts/sync_from_principles.pyin porridge writes.kindel/biq, the interview question bank. It keeps a fixed set of questions. Each question maps to one or more facets. A new company does not get new questions written. Mapping the company's principles onto facets is what makes the existing questions (and their generated example packs) appear.scripts/sync_from_principles.pyin biq adds shells and facet ids; it does not author questions.kindel/kindelwww, the host. It mounts both as Hugo modules. A local preview that only replacesgithub.com/kindel/principleswill show porridge and still miss BIQ.
The cascade notifies. It does not write porridge stubs or the BIQ bank. Someone still has to run those syncs.
SCHEMA.md says claiming the next id block is the whole of adding a
company. That is true of identity. It is not true of shipping. A company
that exists only here is not in the apps.
Do all of this, in this repo first:
- Claim the next free
blockinscripts/companies.py. - Write
data/<company>/<slug>.jsonrecords. Definitions are quotations. Calibration rows are authored unless the company published them, in which case markwords: "quoted". A set that is definitions only setscalibrationtounpublishedinscripts/companies.pyand shipsrows: []. Do not invent rows to clear that flag. - If the company publishes lenses, add
groupand an entry inGROUP_BY_COMPANYinscripts/validate.py. - Every principle needs generated calibration rows on a facet. Map an
existing facet only when its rows fit the principle's text. Otherwise
author a new facet. A stretch onto the wrong table is not a map.
Record rows stay empty when calibration is
unpublished. Do not invent record rows to clear that flag. Classify every principle intests/fixtures/facet-audit.json. The decision for a facet that exists ismap. Every company needsdata/teaching/<company>/index.jsonand a teaching file per principle. Reading-only files (id,slug,blog) are enough when full prose is not written. Further reading must be official sources that resolve. - Update the company list and block in
SCHEMA.md. Tests fail if you skip this. - A new company's name and source belong in
scripts/companies.pyandSCHEMA.md. Change the README only when the explainer's picture of the model changes. python3 scripts/build_index.pythenpython3 -m unittest discover -s tests.
Then the apps, before calling it done:
- Sync porridge stubs from this worktree's
data/index.json. - Sync BIQ shells from the same index.
- Preview both on a kindelwww worktree that replaces both modules. Porridge-only is a miss.
# in a kindelwww worktree
replace github.com/kindel/principles => ../principles-<n>
replace github.com/kindel/biq => ../biq-<n>
Hit /porridge/?c=<id> and /biq/?c=<id>. On BIQ, a principle with no
facet map shows no questions. A principle that shares a facet with the
fixed bank shows those questions, and the Examples button uses the
existing pack id. Do not author a parallel question list per company.
Use git worktrees so main checkouts stay clean. kindelwww is often
already serving on 1313 from another worktree; pick a free port.
On Windows, a Hugo process watching a parent of this tree can lock
files under public/. --renderToMemory avoids that.
Porridge singles 404 until the stubs exist, even when the index list
renders. Overlay stubs in the kindelwww worktree under
content/porridge/<company>/ if you are not committing them to porridge
yet.
Authored strings: no em dash, no ---, Oxford commas, numbers under 10
spelled out. Quoted definition and words: "quoted" rows keep the
company's grammar except those two dash checks.