94 lines
10 KiB
TypeScript
94 lines
10 KiB
TypeScript
// VERSIONED DATA-only candidate. Never installation policy, enrollment or writer permission.
|
|
import {BUILD44_PROVENANCE,FIXED44_ROLE_TEMPLATE} from './fixed44-build-definition.js'
|
|
import {fixedCatalogueParentPeriodData} from './application-writer-profile-catalogue-parent-policy.js'
|
|
import {GROUPS,type Inventory} from './catalogue-projection.js'
|
|
export const EXPANDED44_POLICY_VERSION='source44-managed-leaves-3000-data-v1' as const
|
|
const PLANNED=2000,EXPIRED=1000,PER_PARENT=1000,LEAVES=PLANNED+EXPIRED
|
|
const source=FIXED44_ROLE_TEMPLATE
|
|
const baseNames=new Set(source.tables.map(row=>String(row.relname)))
|
|
const parents=[...baseNames].filter(name=>fixedCatalogueParentPeriodData(name)!==undefined)
|
|
const perRelation=new Map([...baseNames].map(name=>[name,Object.fromEntries(GROUPS.map(group=>[group,source[group].filter(row=>(group==='inheritance'?row.child:row.relname)===name).length])) as Record<typeof GROUPS[number],number>]))
|
|
const base=Object.freeze(Object.fromEntries(GROUPS.map(group=>[group,source[group].length])) as Record<typeof GROUPS[number],number>)
|
|
const leafMax=Object.freeze(Object.fromEntries(GROUPS.map(group=>[group,group==='inheritance'?1:Math.max(...parents.map(name=>perRelation.get(name)![group]))])) as Record<typeof GROUPS[number],number>)
|
|
if(baseNames.size!==104||source.tables.length!==104||parents.length!==12||leafMax.columns!==18||leafMax.constraints!==17||leafMax.triggers!==5||leafMax.indexes!==2||leafMax.roleGrants!==4)throw Error('Exact reviewed source44 topology changed; rederive policy')
|
|
for(const row of source.constraints)if(parents.includes(String(row.relname))&&!['n','c','p','f'].includes(String(row.contype)))throw Error('Unreviewed parent constraint semantics')
|
|
const total=Object.freeze(Object.fromEntries(GROUPS.map(group=>[group,base[group]+LEAVES*leafMax[group]])) as Record<typeof GROUPS[number],number>)
|
|
export const EXPANDED44_DATA_POLICY=Object.freeze({version:EXPANDED44_POLICY_VERSION,baseRelations:baseNames.size,parents:parents.length,maxPlannedLeaves:PLANNED,maxExpiredBacklog:EXPIRED,maxManagedLeaves:LEAVES,maxPerParent:PER_PARENT,maxRelations:baseNames.size+LEAVES,maxWeightedPlan:2000,baseRows:base,maxLeafRows:leafMax,maxRows:total,definitionSha256:BUILD44_PROVENANCE.templateSha256,authority:false,productionInstallationPolicyApproved:false,settingsAdmissionAuthorized:false,readyAuthorized:false})
|
|
export const expanded44ParentRowCountsData=()=>Object.freeze(Object.fromEntries(parents.map(name=>[name,Object.freeze({...perRelation.get(name)!})])))
|
|
export interface ManagedLeafData {readonly parent:string;readonly name:string}
|
|
export function validateManagedLeafNameData(input:ManagedLeafData):void {
|
|
if(!input||Object.keys(input).sort().join(',')!=='name,parent'||typeof input.parent!=='string'||typeof input.name!=='string')throw Error('Exact managed leaf DATA shape required')
|
|
const period=fixedCatalogueParentPeriodData(input.parent)
|
|
if(!period||!input.name.startsWith(input.parent+'_'+period+'_'))throw Error('Unknown/cross-parent managed leaf')
|
|
const stamp=input.name.slice(input.parent.length+3)
|
|
if(!new RegExp('^[0-9]{'+(period==='m'?6:8)+'}$').test(stamp))throw Error('Managed leaf name shape refused')
|
|
const iso=stamp.slice(0,4)+'-'+stamp.slice(4,6)+'-'+(period==='m'?'01':stamp.slice(6,8)),start=new Date(iso+'T00:00:00Z'),end=new Date(start)
|
|
if(!Number.isFinite(+start)||start.toISOString().slice(0,10)!==iso||period==='w'&&start.getUTCDay()!==1)throw Error('Managed leaf calendar refused')
|
|
if(period==='m')end.setUTCMonth(end.getUTCMonth()+1);else end.setUTCDate(end.getUTCDate()+(period==='w'?7:1))
|
|
if(start.getUTCFullYear()<100||end.getUTCFullYear()>9998)throw Error('Managed leaf bounded calendar refused')
|
|
}
|
|
/** Only exact template-validated relation counts enter this sticky cumulative DATA budget. */
|
|
export class Expanded44TopologyBudgetData {
|
|
private readonly names=new Set<string>();private readonly perParent=new Map<string,number>();private readonly rows=Object.fromEntries(GROUPS.map(g=>[g,0])) as Record<typeof GROUPS[number],number>
|
|
private bases=0;private leaves=0;private failed=false;private closed=false
|
|
acceptRelation(kind:'base'|'leaf',name:string,groups:Inventory,parent?:string):void {
|
|
try{
|
|
if(this.failed||this.closed||this.names.has(name)||this.names.size>=EXPANDED44_DATA_POLICY.maxRelations)throw Error('Closed/duplicate/total relation DATA envelope')
|
|
const expected=kind==='base'&&parent===undefined?perRelation.get(name):kind==='leaf'&&parent!==undefined&&parents.includes(parent)?{...perRelation.get(parent)!,inheritance:1}:undefined
|
|
if(!expected)throw Error('Unknown source44 base/parent')
|
|
if(kind==='leaf'){
|
|
validateManagedLeafNameData({name,parent:parent!})
|
|
if(this.leaves>=LEAVES||(this.perParent.get(parent!)??0)>=PER_PARENT)throw Error('Managed leaf total/per-parent DATA envelope')
|
|
}
|
|
for(const group of GROUPS){if(!Array.isArray(groups[group])||groups[group].length!==expected[group]||this.rows[group]+groups[group].length>total[group])throw Error('Exact source44 '+group+' DATA row envelope')}
|
|
this.names.add(name);for(const group of GROUPS)this.rows[group]+=groups[group].length
|
|
if(kind==='base')this.bases++;else{this.leaves++;this.perParent.set(parent!,1+(this.perParent.get(parent!)??0))}
|
|
}catch(error){this.failed=true;throw error}
|
|
}
|
|
finish(){if(this.failed||this.closed||this.bases!==104)throw Error('Incomplete/refused expanded topology DATA');this.closed=true;return Object.freeze({baseRelations:this.bases,leafRelations:this.leaves,rows:Object.freeze({...this.rows}),perParent:Object.freeze(Object.fromEntries(this.perParent)),authority:false})}
|
|
}
|
|
/** Proposed projected admission DATA, not a trusted expiry observation or permission.
|
|
* Genuine host must classify current leaves and bind same-session maintenance/settings separately.
|
|
* Planned can include future leaves not present yet. Unclassified current leaves refuse.
|
|
*/
|
|
export function validateExpanded44AdmissionData(input:Readonly<{current:readonly ManagedLeafData[];planned:readonly ManagedLeafData[];expiredBacklog:readonly ManagedLeafData[]}>){
|
|
if(!input||Object.keys(input).sort().join(',')!=='current,expiredBacklog,planned')throw Error('Exact admission DATA fields required')
|
|
const parse=(values:readonly ManagedLeafData[],cap:number)=>{if(!Array.isArray(values)||values.length>cap)throw Error('Admission DATA list envelope');const map=new Map<string,ManagedLeafData>();for(const row of values){validateManagedLeafNameData(row);if(map.has(row.name))throw Error('Duplicate admission leaf');map.set(row.name,row)}return map}
|
|
const current=parse(input.current,LEAVES),planned=parse(input.planned,PLANNED),expired=parse(input.expiredBacklog,EXPIRED)
|
|
let weighted=0;for(const row of planned.values())weighted+=['flow_hour_facts','flow_daily_facts'].includes(row.parent)?2:1
|
|
if(weighted>2000)throw Error('Source weighted planned budget exceeded')
|
|
const projected=new Map(planned)
|
|
for(const [name,row]of expired){if(projected.has(name)||!current.has(name))throw Error('Overlapping/noncurrent expired DATA');projected.set(name,row)}
|
|
for(const [name,row]of current){const classified=projected.get(name);if(!classified||classified.parent!==row.parent)throw Error('Unclassified/cross-parent current leaf DATA')}
|
|
if(projected.size>LEAVES)throw Error('Projected managed leaves DATA envelope')
|
|
const perParent=new Map<string,number>();for(const row of projected.values()){const count=1+(perParent.get(row.parent)??0);if(count>PER_PARENT)throw Error('Projected per-parent DATA envelope');perParent.set(row.parent,count)}
|
|
return Object.freeze({version:EXPANDED44_POLICY_VERSION,currentLeaves:current.size,plannedLeaves:planned.size,expiredBacklog:expired.size,projectedLeaves:projected.size,weightedPlan:weighted,perParent:Object.freeze(Object.fromEntries(perParent)),authority:false,expiryClassificationAuthenticated:false,settingsAdmissionAuthorized:false,readyAuthorized:false})
|
|
}
|
|
|
|
/** Exact query meaning, not deparser-byte guesses. Unknown internal tree sizes
|
|
* remain the unchanged actual SQL scalar preflight's obligation. */
|
|
export const EXPANDED44_SOURCE_SIZE_SEMANTICS_DATA=Object.freeze({
|
|
function_bytes:'sum pg_proc.prosrc UTF8 bytes; fixed global functions, no per-leaf routine copy',
|
|
default_bytes:'sum pg_attrdef.adbin::text pg_node_tree bytes; NOT default_expression deparser bytes',
|
|
check_bytes:'sum pg_constraint.conbin::text pg_node_tree bytes; NOT pg_get_constraintdef bytes',
|
|
trigger_bytes:'sum octet_length(tgqual::text)+octet_length(tgargs); NULL qualifier terms are ignored by SQL sum; NOT trigger definition bytes',
|
|
unchangedEachSourceScalarLimitBytes:2097152,internalTreeSizesDerived:false,actualSqlRequired:true,authority:false
|
|
})
|
|
export const expanded44LeafSourceShapeFactsData=()=>Object.freeze(Object.fromEntries(parents.map(parent=>{
|
|
const columns=source.columns.filter(row=>row.relname===parent),constraints=source.constraints.filter(row=>row.relname===parent),triggers=source.triggers.filter(row=>row.relname===parent)
|
|
return [parent,Object.freeze({defaultExpressionRows:columns.filter(row=>row.default_expression!==null).length,checkExpressionRows:constraints.filter(row=>row.contype==='c').length,qualifierRows:triggers.filter(row=>row.unconditional!==true).length,argumentBytes:triggers.reduce((sum,row)=>sum+Number(row.arg_bytes),0),routineCopiesPerLeaf:0,internalTreeBytesKnown:false})]
|
|
})))
|
|
|
|
/** Exact extremum of expression ROW COUNTS, not an invented pg_node_tree byte cap.
|
|
* Unit leaf costs +1000 capacity/parent +3000 total => top3 source costs.
|
|
* Different scalar extrema may require different valid topologies.
|
|
*/
|
|
export function expanded44SourceShapeExtremaData(){
|
|
const facts=expanded44LeafSourceShapeFactsData()
|
|
const maximize=(field:'defaultExpressionRows'|'checkExpressionRows')=>{
|
|
const selected=Object.entries(facts).sort((a,b)=>b[1][field]-a[1][field]||(a[0]<b[0]?-1:1)).slice(0,3)
|
|
return Object.freeze({perLeafRows:selected.reduce((sum,[,value])=>sum+value[field]*PER_PARENT,0),cohorts:Object.freeze(selected.map(([parent,value])=>Object.freeze({parent,leaves:PER_PARENT,rowsPerLeaf:value[field]})))})
|
|
}
|
|
return Object.freeze({baseDefaultExpressionRows:source.columns.filter(row=>row.default_expression!==null).length,baseCheckExpressionRows:source.constraints.filter(row=>row.contype==='c').length,baseQualifiedTriggerRows:source.triggers.filter(row=>row.unconditional!==true).length,maxAddedDefaultExpressionRows:maximize('defaultExpressionRows'),maxAddedCheckExpressionRows:maximize('checkExpressionRows'),perLeafQualifiedTriggerRows:0,perLeafRoutineCopies:0,internalTreeByteUpperBoundKnown:false,actualSqlSourceScalarGateRequired:true,authority:false})
|
|
}
|