public boolean actionReassemble(Actor actor, Venue site) {
    
    final Item sample = Item.withReference(SAMPLES, ARTIFACTS) ;
    final Structure s = site.structure() ;
    final float
      AAU = s.upgradeLevel(ExcavationSite.ARTIFACT_ASSEMBLY),
      SPU = s.upgradeLevel(ExcavationSite.SAFETY_PROTOCOL) ;
    
    float success = 1 ;
    if (actor.traits.test(ASSEMBLY, 10, 1)) success++ ;
    else success-- ;
    if (actor.traits.test(ANCIENT_LORE, 5, 1)) success++ ;
    else success-- ;

    site.stocks.removeItem(Item.withAmount(sample, 1.0f)) ;
    if (success >= 0) {
      success *= 1 + (AAU / 2f) ;
      final Item result = Item.with(ARTIFACTS, null, 0.1f, success * 2) ;
      site.stocks.addItem(result) ;
    }
    if (site.stocks.amountOf(ARTIFACTS) >= 10) {
      site.stocks.removeItem(Item.withAmount(ARTIFACTS, 10)) ;
      final Item match = site.stocks.matchFor(Item.withAmount(ARTIFACTS, 1)) ;
      final float quality = (match.quality + AAU + 2) / 2f ;
      if (Rand.num() < 0.1f * match.quality / (1 + SPU)) {
        final boolean hostile = Rand.num() < 0.9f / (1 + SPU) ;
        releaseArtilect(actor, hostile, quality) ;
      }
      else createArtifact(site, quality) ;
    }
    return true ;
  }