Skip to content

v1.26.0 ·

The flag meant “render this way”, not “this is ours”

A guidance layer reaches an agent because it is registered. The file on disk is inert. The entry in the guidance index is what puts a pointer into every emitted skill. Delete the file and you get a loud warning. Delete the registration and you get silence, which is the more expensive of the two.

aidlc doctor had a check for registrations belonging to a compliance pack that is no longer installed. Dropping those is right. An uninstalled pack should stop feeding its constraints to every agent. The trouble was how doctor decided an entry belonged to a pack. It used always_pointer, a rendering instruction that tells the compiler to emit a pointer to the layer file instead of pasting its text. Pack layers must set it. Doctor read that backwards, as though every layer with the flag were a pack layer.

A project can set the flag too. It is the supported way to say this guidance is long, link to it. Any project that did was told its own layer, say house-rules, belonged to a pack that was not installed.

A check that cannot clear

No pack will ever claim a file the project wrote, so doctor exited 1 on every run, forever. In CI that is a red build with one obvious remedy printed under it. Running the remedy drops the registration. The message says the files stay on disk, which is true and beside the point: at the next update the layer stops being delivered and nothing says so. The only action that turned the light green was the one that broke the thing.

A check that cannot clear except by applying its own fix has stopped being a check. It is a prompt, and it pushes in whatever direction its remedy points.

Record it, do not infer it

The tempting fix was a smarter guess: a file name that looks like a pack's, a list of known pack layers, a disclaimer sentence in the body. Each is a better guess than the original and still a guess. One piece of code knows which pack a registration came from, the installer that wrote it. So it now stamps pack: <id> on every entry it creates, and the check selects only entries carrying that key whose file no installed record owns. No key means the entry is the project's or the framework's, and out of scope. One helper serves both the check and the apply, so they cannot report one set and act on another.

Projects that installed a pack before the key existed get a migration that stamps an entry only when an installed pack's own record names its file. That is proof, not inference. Everything else stays as it was.

That leaves a gap I chose on purpose. A registration left by an old install whose config record is already gone has no provenance and nothing can establish any. That stale pointer stays. The two errors do not cost the same. Wrongly dropping a registration stops delivering guidance an agent was told to always read, and nothing announces it. Wrongly keeping one leaves a visible pointer that costs a line edit. When the evidence runs out, take the reversible error.

The worse bug underneath

Reading the compliance config deliberately turns a broken section into "no packs installed", so a mangled config cannot break unrelated commands. That is right for anything asking what governs the project, and wrong for something that acts on a record's absence. A pack record missing one key, such as version, failed validation and vanished. Doctor concluded the pack was gone and, with --yes, deregistered a layer of a pack that was still installed. I reproduced this against the shipped v1.24.1 build.

I did not make the reader strict, because that breaks what the degrading is for. A separate function, complianceSectionState(), tells absent from readable from broken. Only the two migrations that act on absence consult it, and they decline to run on a broken section.

A suggestion in the report was to lower this check below the tier that fails the build, as cosmetic. After the fix, every entry it catches genuinely claims an uninstalled pack, so it keeps its tier. I also retired a criterion mid-build. It claimed that ordering the backfill before the drop check would let one run stamp and then act. Writing its test proved that impossible, since the two select complementary sets. The comment in the registry that told the false story now says the opposite.