* You have to use LAB colorspace to obtain brightness measurements of the colors in the base and target ramps. Otherwise, you FUBAR the brightness in inconsistent and unpredictable ways.
* This method is best thought of as sampling over a 2d color-grid, where X is brightness, Y is color, and
colors may repeat on some scanlines (where less colors than base ramp length are used)
The method I was working on for CGing would allow sampling at fractional coordinates (ie. between colors / color ramps). What you describe only allows integer coordinates.
* the 'two lightsources' trick can be thought of as a third (albeit binary) dimension to the sampling.
So you have something like a 17bit format here
. Of course, typically it'd be more like 3 + 3 + 1 = 7 bits (ramp of <= 8 brightnesses, <= 8 different ramps, 1 bit for palette toggle)
Which leads me to think that this kind of thing might be doable as mainly an adjunct to palette editing.
recoloring mode could just look at base ramp length and current drawing color to recolor pixels.
essentially:
targetramp = int (FGcolorindex / baserampsize)
sourceramp = int (pixel[y][x] / baserampsize)
pixel[y][x] = (pixel[y][x] - (sourceramp * baserampsize)) + (targetramp * baserampsize)
You might not like the duplicate palette entries that occur for ramps shorter than baserampsize,
but IMO that is the job of either the saving code or external optimization software to fix
(you might not want to optimize them out anyway, if you want realtime ramp swapping)
I never really thought about it in the sense that we'd extrapolate the exact brightness trough lab colorspace X/Z cordinates or something like that...mostly because I am an artist and I've never been able to stand coding..so I dont have that thought set...I think your skillset gives you the capability to understand it with better metaphores in color theory and coding, but you tend to understimate the usefullness of just letting the end user customize things

Ideally, I think it should just be a way of handling palletes that is ramp-oriented. That is so that when as you said there are ramps of diferent length than the "baserampsize" it is the user that decides how exactly they match up...because no matter how accurate LAB or whatever is it just doesnt know what you're going for.
Say you have the sprite's clothes, then you have his metal armor...and his hair or whatever.

You know that his hair has two extra shadow tones, while the armor has two extra highlight tones...you just scroll the two ramps so they overlap in the way you know they should (excuse the hideous pallete....:p)
In practice I guess the program would handle the tones from ramps with greater length as duplicate pallete entries (anything past the brightest red color will still be handled as the brightest red) but the idea would be that the program would only do it in a internal file format which would 'know' which are the duplicate entries, and you'd be able to export the file with clean single entries.
Now, suppose you wanted to add the extra shadow tones to the metal as well, but you dont want to add any extra tones

you just tell the program to use the two hair shadow tones for that, we already do that but we've no way of recording that those two entries in the ramp although the same tone as the ones in the hair one, are from the metal ramp. The idea would be to fix that...so that if suddenly it turns out that your game is going to a new platform that allows 2 more shades (or more likely you just decide to feck the limitations) it isnt a mess to recolor.
The whole third dimension view to it when adding multiple light sources ( I wonder if light sources is correct..more like chromatic filters..heh) sounds very smart.
And you are totally right about the 2bit fuck up. Although familiar with the term and the concept, I dont often use it so I fucked up even though I knew 1 bit is 0s and 1s

should just man up and say two colors lol.