@miadi/ava8-atelier
v0.1.0
Published
The atelier's law, as data an agent cannot quietly ignore: a register plan whose void band is proven in a rendered score, spectral verdicts against thresholds that belong to a person, the provenance block without which a generator is not finished, and an
Downloads
131
Readme
@miadi/ava8-atelier
The atelier's law, as data an agent cannot quietly ignore. Every other package in the ava8 family writes. This one decides, and refuses.
It carries the constants that five separate files used to quote at each other, the verdicts those constants produce, the provenance block without which a generated score is not finished, and a consent ledger with exactly one reader.
ESM only. Zero runtime dependencies. No DOM, no filesystem — it runs in a browser, in a test, and on a capture device.
npm install @miadi/ava8-atelierThe one idea
A register is left empty on purpose — the band a person sings in.
Everything here exists to make that decision, defend it, and prove it held in the rendered score rather than in the generator's intention.
No default bands, and that is the point
A void band is a measurement of somebody's voice. Publishing one as an exported default would put a fact about a living person's body on a public registry, where it cannot be unpublished after seventy-two hours.
So bands are a required argument. The shape is public; the numbers stay wherever they were measured.
import { RegisterPlan } from "@miadi/ava8-atelier"
const plan = new RegisterPlan({
bass: { lo: 33, hi: 44 },
voice: { lo: 45, hi: 53, void: true }, // measured on the newest take, not inherited
pad: { lo: 54, hi: 68 },
high: { lo: 74, hi: 84 },
})
plan.assertVoidEmpty(notesReadBackFromTheRenderedMidi) // throws, with the offending pitchesnew RegisterPlan({}) throws, and says why.
What it owns
| export | what it decides |
|---|---|
| RegisterPlan | named non-overlapping bands, one empty on purpose; place, contains, assertEmpty, assertVoidEmpty |
| STRIDENCE, stridenceVerdict | the spectral thresholds and the band a measured share falls in |
| parseMode, modePurity, SCALES | a mode from "ddorian" or a bare pitch-class list; share of duration inside it |
| GM_DRUMS, FOUR_ON_THE_FLOOR, OFFBEAT_EIGHTHS | the drum numbers a generator writes |
| provenance (./provenance) | the three-section header, and a hard error when one is missing |
| readLedger, voicedBasenames, openGates (./consent) | the consent ledger, read once and correctly |
What it does not own
| | |
|---|---|
| writing ABC or MIDI | @miadi/ava8-core |
| rendering a score or playing it | @miadi/ava8-abcjs, @miadi/ava8-react |
| measuring a rendered artefact | @miadi/ava8-measure |
| recording a take | @miadi/capture |
| conducting movement into frames | @miadi/movement-conductor |
| turning a MIDI into audio | @miadi/jeremyai |
This package holds no measurement code. It holds what a measurement is judged against.
The thresholds belong to a person
STRIDENCE.reject is 0.1312; accept is 0.0598; soft is 0.03 — the share of a whole
piece's spectral energy between 2 and 5 kHz.
These are one musician's calibration on his own material, reached by ear over months. They
are exported so that tools agree with each other, never so that a tool can move them.
When nothing passes, say the number. A multi-voice piece rarely reaches accept, and that
is a property of the threshold's origin, not a failure of the piece.
Provenance
import { provenance } from "@miadi/ava8-atelier/provenance"
provenance({
title: "Opus 021 — ta cellule",
measured: ["his cell, three occurrences: +3 -8 +5", "durations 2-2-1-2, seven eighths"],
given: ["the cell, the rhythm, the contour, the tempo"],
chosen: ["the order of the stations, the octave, the two timbres"],
})All three sections are required, and the function throws when one is empty. An absent section reads as an empty one, and the section an author wants to skip is usually the third — which is the one that lets a person undo a choice they never agreed to.
The headings stay in French because they are quoted from the sessions that produced them, and a translated quote is no longer a quote.
Consent
The ledger is an append-only JSONL of acts: what was fetched off a person's device, what was measured out of it, what was destroyed afterwards, and every held gate — a thing named and deliberately not done for want of their word.
This module parses text, never a path, so it touches no filesystem. Whoever holds the file passes its contents.
import { readLedger, voicedBasenames, openGates } from "@miadi/ava8-atelier/consent"
const read = readLedger(await fs.readFile(ledgerPath, "utf8"))
const voiced = voicedBasenames(read) // null means COULD NOT LOOK, never "nothing marked"
const gates = openGates(read) // null for the same reasonTwo rules the shapes exist to keep:
Consent is not transitive. A cleared entry names a single file. A yes for one is not a
yes for the next.
A partial read is not an answer. One truncated line — the ordinary result of a crash
mid-append — used to make a gate vanish while the summary claimed none were open. Both
readers return null when the ledger could not be read whole, because a check that cannot
tell nothing is there from I could not look always returns the one that lets you keep
moving.
Why this is a package and not a convenience
Three readers of one ledger file, each with its own field convention, shipped in a working plugin. Two were silently wrong, and both failures reported safety:
- The upload guard looked for a key named
file. No writer has ever produced one. The denial that protects a person's recorded voice could never fire. - The session hook matched a release on
event === "released". A release is written as{event: "held", status: "released"}— a new entry, never an edit. Every released gate came back at the next session start.
The fix was not to teach three readers one convention. It was to delete two of them.
Provenance of the law itself
The register discipline, the thresholds and the provenance headings come from a working music session between a musician and an agent, where each was reached by first being wrong. They are cited as that musician's throughout, and the numbers that describe his voice are deliberately not shipped here.
