These limits are even more frustrating in that the InDesign user himself can very easily augment groups (or change hierarchical relationships) by simply dragging nodes in the Layer panel! As far as I know, the Scripting DOM offers no such facilities. When we need to create and/or manage nested groups, we must reconstruct the entire structure. This method involves producing each new group from the Spread level.

Suppose you have the following path to a target group:

    SPREAD => GP1 => GP2 => GP3

Say you want to add a new object in the group GP3. Here is the way to go:

1. Ungroup GP1.
2. Ungroup GP2.
3. Ungroup GP3.
4. Create a new group, GP33, based on GP3's old items and the new object.
5. Create a new group, GP22, based on GP2's old items and GP33.
6. Create a new group, GP11, based on GP1's old items and GP22.

Also, during this tedious process you will have to:
    — backup temporarily ungrouped items,
    — make sure that the respective transformations applied to both simple items and parent groups are preserved (or restored) in the proper order,
    — deal with possible z-order issues!

My Own Aggregator

Being constantly confronted with that boring topic, I decided to create a generic helper that saves me a lot of time in processing nested groups. I suspect this routine might help some of my colleagues, so here it is in its current state of development:

var aggregate = function(
    /*Group|PageItem*/target,
    /*PageItem|arr*/newItems,
    /*bool=false*/overTarget
    )
//--------------------------------------
// CS4-CS6 Group Aggregator
// (1) If <target> is a group, add <newItems> within that group
// (2) If <target> is a simple item, group it with <newItems>
// Return the resulting group
// ---
// <newItems> can be:
// (a) a singular specifier    -- e.g. mySpread.textFrames[0]
// (b) a plural specifier      -- e.g. mySpread.ovals.everyItem()
// (c) an array of specifiers  -- e.g. [myOval, myRectangle]
// ---
// If !!<overTarget>, <newItems> are z-ordered OVER the target
// Default is false => newItems are z-ordered UNDER the target
// ---
// This routine attempts to preserve:
// # The hierarchical level of <target>
//   in the case it is nested in existing group(s),
// # The z-order of the involved elements,
// # Respective item transformations.
// ---
// Limitations:
// # <newItems> must all be 'free' i.e. direct children of the Spread
// # Anchored/inline items are not supported
{
    var CS_SPREAD = CoordinateSpaces.SPREAD_COORDINATES,
        CS_ORIGIN = [[0,0],CS_SPREAD];
 
    var stack = [],
        z, p, t, o, i, a, g,
        r = null;
 
    // Feed the stack (from target to top container)
    // ---
    for (
        p=t=target, z=0 ;
        p instanceof Group ? t=p.pageItems.everyItem() : !z ;
        p=p.parent
        )
        stack[z++] = {
            items: t.getElements(),
            id: p.id,
            mx: p.transformValuesOf(CS_SPREAD)[0],
            };
 
    // Check that the top container is OK
    // ---
    if( !((p instanceof Spread)||(p instanceof MasterSpread)||(p instanceof Page)) )
        {
        (stack.length=0)||(stack=null);
        throw "Unable to aggregate page items";
        }
 
    // Normalize newItems --> array of resolved specs
    // ---
    ('getElements' in newItems) && (newItems=newItems.getElements());
 
    // Ungroup stack elems (except the target)
    // ---
    a = [];
    while( z-- )
        {
        o = stack[z];
 
        i = a.length;
        while( i-- ){ if( a[i].id==o.id ){ a.splice(i,1); break; } }
 
        t = p.pageItems.itemByID(o.id).getElements()[0];
 
        z && t.ungroup();
 
        delete o.id;
        a = o.items;
        }
 
    // Manage the z-order of newItems relative to t (==target)
    // ---
    if( 1 < newItems.length )
        {
        g = p.groups.add(newItems);
        g[overTarget?'bringToFront':'sendToBack'](t);
        g.ungroup();
        g = null;
        }
    else
        newItems[0][overTarget?'bringToFront':'sendToBack'](t);
 
    // If needed, ungroup the target
    // ---
    (t instanceof Group) && t.ungroup(); 
 
    // Append newItems to the base array
    // ---
    o.items = o.items.concat(newItems);
 
    // Recreate the whole hierarchy
    // ---
    for( z=0, t=null ; z < stack.length ; ++z )
        {
        o=stack[z];
        t && o.items[o.items.length]=t;
 
        t = p.groups.add(o.items);
        t.transform(CS_SPREAD, CS_ORIGIN, o.mx);
        t.pageItems.everyItem().transform(CS_SPREAD, CS_ORIGIN, o.mx.invertMatrix());
        t = t.getElements()[0];
 
        (o.items.length=0)||(o.items=null)||(o.mx=null);
 
        r || (r=t);
        }
 
    (stack.length=0)||(stack=null);
    t = o = p = a = null;
    return r;
};
 
 
// =====================================
// Sample code
// =====================================
 
var spd = app.activeDocument.spreads[0],
    target = spd.groups[0].groups[0],    // assumed a nested group exists
    newItems = spd.ovals.everyItem();    // assumed some ovals exist
 
var g = aggregate(target, newItems, true);
app.select(g);
 

Any feedback highly appreciated.